From db564ae0db869d93f14dd13fc34b125223d2d1a9 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Fri, 8 Dec 2023 10:46:20 +0100 Subject: [PATCH] Bump to rustls 0.22 --- Cargo.lock | 126 +++++++++++++++-------- crates/directory/Cargo.toml | 5 +- crates/directory/src/imap/tls.rs | 4 +- crates/imap/Cargo.toml | 4 +- crates/managesieve/Cargo.toml | 4 +- crates/smtp/Cargo.toml | 5 +- crates/smtp/src/inbound/milter/client.rs | 6 +- crates/smtp/src/outbound/dane/verify.rs | 4 +- crates/store/Cargo.toml | 7 +- crates/store/src/backend/postgres/tls.rs | 7 +- crates/utils/Cargo.toml | 5 +- crates/utils/src/config/certificate.rs | 19 ++-- crates/utils/src/config/listener.rs | 41 ++++---- crates/utils/src/lib.rs | 67 +++++++++--- crates/utils/src/listener/listen.rs | 3 +- tests/Cargo.toml | 5 +- tests/src/directory/mod.rs | 15 ++- tests/src/imap/managesieve.rs | 4 +- tests/src/smtp/outbound/dane.rs | 4 +- 19 files changed, 210 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc678230..dc68e572 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -630,9 +630,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf617fabf5cdbdc92f774bfe5062d870f228b80056d41180797abf48bed4056e" +checksum = "9897ef0f1bd2362169de6d7e436ea2237dc1085d7d1e4db75f4be34d86f309d1" dependencies = [ "borsh-derive", "cfg_aliases", @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f404657a7ea7b5249e36808dff544bc88a28f26e0ac40009f674b7a009d14be3" +checksum = "478b41ff04256c5c8330f3dfdaaae2a5cc976a8e75088bafa4625b0d0208de8c" dependencies = [ "once_cell", "proc-macro-crate 2.0.0", @@ -1107,9 +1107,9 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" dependencies = [ "generic-array", "subtle", @@ -1414,14 +1414,15 @@ dependencies = [ "pbkdf2 0.12.2", "pwhash", "regex", - "rustls 0.21.9", + "rustls 0.22.0", + "rustls-pki-types", "scrypt", "sha1", "sha2 0.10.8", "smtp-proto", "store", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "utils", ] @@ -2220,7 +2221,7 @@ dependencies = [ "thiserror", "tinyvec", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", "url", ] @@ -2244,7 +2245,7 @@ dependencies = [ "smallvec", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", ] @@ -2424,7 +2425,7 @@ dependencies = [ "hyper 0.14.27", "rustls 0.21.9", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", ] [[package]] @@ -2539,11 +2540,11 @@ dependencies = [ "nlp", "parking_lot", "rand", - "rustls 0.21.9", + "rustls 0.22.0", "rustls-pemfile 2.0.0", "store", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "utils", ] @@ -2908,7 +2909,7 @@ dependencies = [ "rustls-native-certs", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-stream", "tokio-util", "url", @@ -3090,16 +3091,17 @@ dependencies = [ [[package]] name = "mail-send" -version = "0.4.2" -source = "git+https://github.com/stalwartlabs/mail-send#09981bceec74b2da9522c3aaadcd675e612d1653" +version = "0.4.3" +source = "git+https://github.com/stalwartlabs/mail-send#d776716289b02ef43efd49354b1720abc8cc8be1" dependencies = [ "base64 0.21.5", "gethostname", "md5", - "rustls 0.21.9", + "rustls 0.22.0", + "rustls-pki-types", "smtp-proto", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "webpki-roots 0.26.0", ] @@ -3135,12 +3137,12 @@ dependencies = [ "mail-send", "md5", "parking_lot", - "rustls 0.21.9", + "rustls 0.22.0", "rustls-pemfile 2.0.0", "sieve-rs", "store", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "utils", ] @@ -3330,7 +3332,7 @@ dependencies = [ "socket2 0.5.5", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "twox-hash", "url", @@ -3540,9 +3542,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -4456,7 +4458,7 @@ dependencies = [ "serde_urlencoded", "system-configuration", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -4776,10 +4778,24 @@ checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring 0.17.7", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc238b76c51bbc449c55ffbc39d03772a057cc8cf783c49d4af4c2537b74a8b" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-pki-types", + "rustls-webpki 0.102.0", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -4827,6 +4843,17 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" +dependencies = [ + "ring 0.17.7", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -5293,8 +5320,9 @@ dependencies = [ "rayon", "regex", "reqwest", - "rustls 0.21.9", + "rustls 0.22.0", "rustls-pemfile 2.0.0", + "rustls-pki-types", "serde", "serde_json", "sha1", @@ -5303,7 +5331,7 @@ dependencies = [ "smtp-proto", "store", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "unicode-security", "utils", @@ -5461,12 +5489,13 @@ dependencies = [ "rocksdb", "rusqlite", "rust-s3", - "rustls 0.21.9", + "rustls 0.22.0", + "rustls-pki-types", "serde", "serde_json", "tokio", "tokio-postgres", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "utils", "xxhash-rust", @@ -5514,9 +5543,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -5673,8 +5702,9 @@ dependencies = [ "num_cpus", "rayon", "reqwest", - "rustls 0.21.9", + "rustls 0.22.0", "rustls-pemfile 2.0.0", + "rustls-pki-types", "serde", "serde_json", "serial_test", @@ -5683,7 +5713,7 @@ dependencies = [ "smtp-proto", "store", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "tracing-subscriber", "utils", @@ -5858,6 +5888,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.0", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -5879,7 +5920,7 @@ dependencies = [ "log", "rustls 0.21.9", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tungstenite", "webpki-roots 0.25.3", ] @@ -6091,9 +6132,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "try_map" @@ -6173,9 +6214,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -6286,12 +6327,13 @@ dependencies = [ "opentelemetry_sdk", "privdrop", "rand", - "rustls 0.21.9", + "rustls 0.22.0", "rustls-pemfile 2.0.0", + "rustls-pki-types", "serde", "smtp-proto", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tracing", "tracing-appender", "tracing-journald", @@ -6759,9 +6801,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.25" +version = "0.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e87b8dfbe3baffbe687eef2e164e32286eff31a5ee16463ce03d991643ec94" +checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" dependencies = [ "memchr", ] diff --git a/crates/directory/Cargo.toml b/crates/directory/Cargo.toml index 11af5e9f..6f9d5d26 100644 --- a/crates/directory/Cargo.toml +++ b/crates/directory/Cargo.toml @@ -12,8 +12,9 @@ mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = mail-send = { git = "https://github.com/stalwartlabs/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } mail-builder = { git = "https://github.com/stalwartlabs/mail-builder", features = ["ludicrous_mode"] } tokio = { version = "1.23", features = ["net"] } -tokio-rustls = { version = "0.24.0"} -rustls = "0.21.0" +tokio-rustls = { version = "0.25.0"} +rustls = "0.22" +rustls-pki-types = { version = "1" } ldap3 = { version = "0.11.1", default-features = false, features = ["tls-rustls"] } deadpool = { version = "0.10.0", features = ["managed"] } parking_lot = "0.12" diff --git a/crates/directory/src/imap/tls.rs b/crates/directory/src/imap/tls.rs index 5940ce8c..cba300d4 100644 --- a/crates/directory/src/imap/tls.rs +++ b/crates/directory/src/imap/tls.rs @@ -23,7 +23,7 @@ use std::time::Duration; -use rustls::ServerName; +use rustls_pki_types::ServerName; use smtp_proto::IntoString; use tokio::net::{TcpStream, ToSocketAddrs}; use tokio_rustls::{client::TlsStream, TlsConnector}; @@ -60,7 +60,7 @@ impl ImapClient { Ok(ImapClient { stream: tls_connector .connect( - ServerName::try_from(tls_hostname) + ServerName::try_from(tls_hostname.to_string()) .map_err(|_| ImapError::TLSInvalidName)?, self.stream, ) diff --git a/crates/imap/Cargo.toml b/crates/imap/Cargo.toml index a14b6d5a..79305da7 100644 --- a/crates/imap/Cargo.toml +++ b/crates/imap/Cargo.toml @@ -14,10 +14,10 @@ nlp = { path = "../nlp" } utils = { path = "../utils" } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "ludicrous_mode"] } mail-send = { git = "https://github.com/stalwartlabs/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } -rustls = "0.21.0" +rustls = "0.22" rustls-pemfile = "2.0" tokio = { version = "1.23", features = ["full"] } -tokio-rustls = { version = "0.24.0"} +tokio-rustls = { version = "0.25.0"} parking_lot = "0.12" tracing = "0.1" ahash = { version = "0.8" } diff --git a/crates/managesieve/Cargo.toml b/crates/managesieve/Cargo.toml index df918b6d..7920e74f 100644 --- a/crates/managesieve/Cargo.toml +++ b/crates/managesieve/Cargo.toml @@ -15,10 +15,10 @@ utils = { path = "../utils" } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "ludicrous_mode"] } mail-send = { git = "https://github.com/stalwartlabs/mail-send", default-features = false, features = ["cram-md5", "skip-ehlo"] } sieve-rs = { git = "https://github.com/stalwartlabs/sieve" } -rustls = "0.21.0" +rustls = "0.22" rustls-pemfile = "2.0" tokio = { version = "1.23", features = ["full"] } -tokio-rustls = { version = "0.24.0"} +tokio-rustls = { version = "0.25.0"} parking_lot = "0.12" tracing = "0.1" ahash = { version = "0.8" } diff --git a/crates/smtp/Cargo.toml b/crates/smtp/Cargo.toml index 7c3790fc..64d5697a 100644 --- a/crates/smtp/Cargo.toml +++ b/crates/smtp/Cargo.toml @@ -23,10 +23,11 @@ mail-builder = { git = "https://github.com/stalwartlabs/mail-builder", features smtp-proto = { git = "https://github.com/stalwartlabs/smtp-proto" } sieve-rs = { git = "https://github.com/stalwartlabs/sieve" } ahash = { version = "0.8" } -rustls = "0.21.0" +rustls = "0.22" rustls-pemfile = "2.0" +rustls-pki-types = { version = "1" } tokio = { version = "1.23", features = ["full"] } -tokio-rustls = { version = "0.24.0"} +tokio-rustls = { version = "0.25.0"} webpki-roots = { version = "0.26"} hyper = { version = "1.0.1", features = ["server", "http1", "http2"] } hyper-util = { version = "0.1.1", features = ["tokio"] } diff --git a/crates/smtp/src/inbound/milter/client.rs b/crates/smtp/src/inbound/milter/client.rs index bca82543..1daa3c1b 100644 --- a/crates/smtp/src/inbound/milter/client.rs +++ b/crates/smtp/src/inbound/milter/client.rs @@ -21,7 +21,7 @@ * for more details. */ -use rustls::ServerName; +use rustls_pki_types::ServerName; use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, net::TcpStream, @@ -88,7 +88,9 @@ impl MilterClient { Ok(MilterClient { stream: tls_connector .connect( - ServerName::try_from(tls_hostname).map_err(|_| Error::TLSInvalidName)?, + ServerName::try_from(tls_hostname) + .map_err(|_| Error::TLSInvalidName)? + .to_owned(), self.stream, ) .await?, diff --git a/crates/smtp/src/outbound/dane/verify.rs b/crates/smtp/src/outbound/dane/verify.rs index 7487283e..6fe64316 100644 --- a/crates/smtp/src/outbound/dane/verify.rs +++ b/crates/smtp/src/outbound/dane/verify.rs @@ -21,7 +21,7 @@ * for more details. */ -use rustls::Certificate; +use rustls_pki_types::CertificateDer; use sha1::Digest; use sha2::{Sha256, Sha512}; use x509_parser::prelude::{FromDer, X509Certificate}; @@ -35,7 +35,7 @@ impl Tlsa { &self, span: &tracing::Span, hostname: &str, - certificates: Option<&[Certificate]>, + certificates: Option<&[CertificateDer<'_>]>, ) -> Result<(), Status<(), Error>> { let certificates = if let Some(certificates) = certificates { certificates diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index d93f9678..c256361d 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -30,8 +30,9 @@ tracing = "0.1" lz4_flex = { version = "0.11" } deadpool-postgres = { version = "0.11.0", optional = true } tokio-postgres = { version = "0.7.10", optional = true } -tokio-rustls = { version = "0.24.0", optional = true } -rustls = { version = "0.21.0", optional = true } +tokio-rustls = { version = "0.25.0", optional = true } +rustls = { version = "0.22.0", optional = true } +rustls-pki-types = { version = "1", optional = true } ring = { version = "0.17", optional = true } bytes = { version = "1.0", optional = true } mysql_async = { version = "0.33", default-features = false, features = ["default-rustls"], optional = true } @@ -48,7 +49,7 @@ tokio = { version = "1.23", features = ["full"] } [features] rocks = ["rocksdb", "rayon", "num_cpus"] sqlite = ["rusqlite", "rayon", "r2d2", "num_cpus", "lru-cache"] -postgres = ["tokio-postgres", "deadpool-postgres", "tokio-rustls", "rustls", "ring", "futures", "bytes"] +postgres = ["tokio-postgres", "deadpool-postgres", "tokio-rustls", "rustls", "ring", "rustls-pki-types", "futures", "bytes"] elastic = ["elasticsearch", "serde_json"] mysql = ["mysql_async"] s3 = ["rust-s3"] diff --git a/crates/store/src/backend/postgres/tls.rs b/crates/store/src/backend/postgres/tls.rs index 76805aeb..e723865b 100644 --- a/crates/store/src/backend/postgres/tls.rs +++ b/crates/store/src/backend/postgres/tls.rs @@ -34,7 +34,8 @@ use std::{ use futures::future::{FutureExt, TryFutureExt}; use ring::digest; -use rustls::{ClientConfig, ServerName}; +use rustls::ClientConfig; +use rustls_pki_types::ServerName; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_postgres::tls::{ChannelBinding, MakeTlsConnect, TlsConnect}; use tokio_rustls::{client::TlsStream, TlsConnector}; @@ -61,7 +62,7 @@ where type Error = io::Error; fn make_tls_connect(&mut self, hostname: &str) -> io::Result { - ServerName::try_from(hostname) + ServerName::try_from(hostname.to_string()) .map(|dns_name| { RustlsConnect(Some(RustlsConnectData { hostname: dns_name, @@ -75,7 +76,7 @@ where pub struct RustlsConnect(Option); struct RustlsConnectData { - hostname: ServerName, + hostname: ServerName<'static>, connector: TlsConnector, } diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 913874fe..742ce018 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -5,10 +5,11 @@ edition = "2021" resolver = "2" [dependencies] -rustls = { version = "0.21", features = ["tls12", "dangerous_configuration"]} +rustls = { version = "0.22", features = ["tls12"]} rustls-pemfile = "2.0" +rustls-pki-types = { version = "1" } tokio = { version = "1.23", features = ["net", "macros"] } -tokio-rustls = { version = "0.24.0"} +tokio-rustls = { version = "0.25.0"} serde = { version = "1.0", features = ["derive"]} tracing = "0.1" mail-auth = { git = "https://github.com/stalwartlabs/mail-auth" } diff --git a/crates/utils/src/config/certificate.rs b/crates/utils/src/config/certificate.rs index 94d4d28b..2972795a 100644 --- a/crates/utils/src/config/certificate.rs +++ b/crates/utils/src/config/certificate.rs @@ -27,15 +27,17 @@ use rustls::{ server::{ClientHello, ResolvesServerCert, ResolvesServerCertUsingSni}, sign::CertifiedKey, version::{TLS12, TLS13}, - Certificate, PrivateKey, SupportedProtocolVersion, + SupportedProtocolVersion, }; use rustls_pemfile::{certs, read_one, Item}; +use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use super::Config; pub static TLS13_VERSION: &[&SupportedProtocolVersion] = &[&TLS13]; pub static TLS12_VERSION: &[&SupportedProtocolVersion] = &[&TLS12]; +#[derive(Debug)] pub struct CertificateResolver { pub resolver: Option, pub default_cert: Option>, @@ -51,7 +53,7 @@ impl ResolvesServerCert for CertificateResolver { } impl Config { - pub fn rustls_certificate(&self, cert_id: &str) -> super::Result> { + pub fn rustls_certificate(&self, cert_id: &str) -> super::Result>> { let certs = certs(&mut Cursor::new(self.file_contents(( "certificate", cert_id, @@ -63,10 +65,7 @@ impl Config { })?; if !certs.is_empty() { - Ok(certs - .into_iter() - .map(|cert| Certificate(cert.as_ref().to_vec())) - .collect()) + Ok(certs) } else { Err(format!( "No certificates found in \"certificate.{cert_id}.cert\"." @@ -74,7 +73,7 @@ impl Config { } } - pub fn rustls_private_key(&self, cert_id: &str) -> super::Result { + pub fn rustls_private_key(&self, cert_id: &str) -> super::Result> { match read_one(&mut Cursor::new(self.file_contents(( "certificate", cert_id, @@ -86,9 +85,9 @@ impl Config { .into_iter() .next() { - Some(Item::Pkcs8Key(key)) => Ok(PrivateKey(key.secret_pkcs8_der().to_vec())), - Some(Item::Pkcs1Key(key)) => Ok(PrivateKey(key.secret_pkcs1_der().to_vec())), - Some(Item::Sec1Key(key)) => Ok(PrivateKey(key.secret_sec1_der().to_vec())), + Some(Item::Pkcs8Key(key)) => Ok(PrivateKeyDer::Pkcs8(key)), + Some(Item::Pkcs1Key(key)) => Ok(PrivateKeyDer::Pkcs1(key)), + Some(Item::Sec1Key(key)) => Ok(PrivateKeyDer::Sec1(key)), Some(_) => Err(format!( "Unsupported private keys found in \"certificate.{cert_id}.private-key\".", )), diff --git a/crates/utils/src/config/listener.rs b/crates/utils/src/config/listener.rs index ead99609..d1a0c56e 100644 --- a/crates/utils/src/config/listener.rs +++ b/crates/utils/src/config/listener.rs @@ -24,15 +24,19 @@ use std::{net::SocketAddr, sync::Arc}; use rustls::{ - cipher_suite::{ - TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + crypto::ring::{ + cipher_suite::{ + TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + }, + default_provider, + sign::any_supported_type, }, - server::{NoClientAuth, ResolvesServerCertUsingSni}, - sign::{any_supported_type, CertifiedKey}, - ServerConfig, SupportedCipherSuite, ALL_CIPHER_SUITES, ALL_KX_GROUPS, ALL_VERSIONS, + server::ResolvesServerCertUsingSni, + sign::CertifiedKey, + ServerConfig, SupportedCipherSuite, ALL_VERSIONS, }; use tokio::net::TcpSocket; @@ -89,7 +93,7 @@ impl Config { } // Parse cipher suites - let mut ciphers = Vec::new(); + let mut ciphers: Vec = Vec::new(); for (key, protocol) in self.values_or_default(("server.listener", id, "tls.ciphers"), "server.tls.ciphers") { @@ -127,7 +131,6 @@ impl Config { ) })?, ocsp: None, - sct_list: None, }, _ => CertifiedKey { cert: cert.clone(), @@ -138,7 +141,6 @@ impl Config { ) })?, ocsp: None, - sct_list: None, }, }, ) @@ -154,17 +156,16 @@ impl Config { key: any_supported_type(&pki) .map_err(|err| format!("Failed to sign certificate id {cert_id:?}: {err}"))?, ocsp: None, - sct_list: None, })); + // Build cert provider + let mut provider = default_provider(); + if !ciphers.is_empty() { + provider.cipher_suites = ciphers; + } + // Build server config - let mut config = ServerConfig::builder() - .with_cipher_suites(if !ciphers.is_empty() { - &ciphers - } else { - ALL_CIPHER_SUITES - }) - .with_kx_groups(&ALL_KX_GROUPS) + let mut config = ServerConfig::builder_with_provider(provider.into()) .with_protocol_versions(if tls_v3 == tls_v2 { ALL_VERSIONS } else if tls_v3 { @@ -173,7 +174,7 @@ impl Config { TLS12_VERSION }) .map_err(|err| format!("Failed to build TLS config: {err}"))? - .with_client_cert_verifier(NoClientAuth::boxed()) + .with_no_client_auth() .with_cert_resolver(Arc::new(CertificateResolver { resolver: if has_sni { resolver.into() } else { None }, default_cert, diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 18b96c50..b9272be5 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -41,9 +41,10 @@ use opentelemetry_sdk::{ }; use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; use rustls::{ - client::{ServerCertVerified, ServerCertVerifier}, - Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore, ServerName, + client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, + ClientConfig, RootCertStore, SignatureScheme, }; +use rustls_pki_types::TrustAnchor; use tracing_appender::non_blocking::WorkerGuard; use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, EnvFilter}; @@ -232,40 +233,76 @@ pub async fn wait_for_shutdown(message: &str) { } pub fn rustls_client_config(allow_invalid_certs: bool) -> ClientConfig { - let config = ClientConfig::builder().with_safe_defaults(); + let config = ClientConfig::builder(); if !allow_invalid_certs { let mut root_cert_store = RootCertStore::empty(); - root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject.as_ref(), - ta.subject_public_key_info.as_ref(), - ta.name_constraints.as_ref().map(|v| v.as_ref()), - ) + root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| TrustAnchor { + subject: ta.subject.clone(), + subject_public_key_info: ta.subject_public_key_info.clone(), + name_constraints: ta.name_constraints.clone(), })); + config .with_root_certificates(root_cert_store) .with_no_client_auth() } else { config + .dangerous() .with_custom_certificate_verifier(Arc::new(DummyVerifier {})) .with_no_client_auth() } } +#[derive(Debug)] struct DummyVerifier; impl ServerCertVerifier for DummyVerifier { fn verify_server_cert( &self, - _e: &Certificate, - _i: &[Certificate], - _sn: &ServerName, - _sc: &mut dyn Iterator, - _o: &[u8], - _n: std::time::SystemTime, + _end_entity: &rustls_pki_types::CertificateDer<'_>, + _intermediates: &[rustls_pki_types::CertificateDer<'_>], + _server_name: &rustls_pki_types::ServerName<'_>, + _ocsp_response: &[u8], + _now: rustls_pki_types::UnixTime, ) -> Result { Ok(ServerCertVerified::assertion()) } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &rustls_pki_types::CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &rustls_pki_types::CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + ] + } } diff --git a/crates/utils/src/listener/listen.rs b/crates/utils/src/listener/listen.rs index 583f28f0..a615b62e 100644 --- a/crates/utils/src/listener/listen.rs +++ b/crates/utils/src/listener/listen.rs @@ -23,6 +23,7 @@ use std::{net::IpAddr, sync::Arc}; +use rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256; use tokio::{ net::{TcpListener, TcpStream}, sync::watch, @@ -247,7 +248,7 @@ impl ServerInstance { context = "tls", event = "handshake", version = ?stream.get_ref().1.protocol_version().unwrap_or(rustls::ProtocolVersion::TLSv1_3), - cipher = ?stream.get_ref().1.negotiated_cipher_suite().unwrap_or(rustls::cipher_suite::TLS13_AES_128_GCM_SHA256), + cipher = ?stream.get_ref().1.negotiated_cipher_suite().unwrap_or(TLS13_AES_128_GCM_SHA256), ); Ok(stream) } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index af88585b..ee4b15ed 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -33,9 +33,10 @@ utils = { path = "../crates/utils", features = ["test_mode"] } jmap-client = { git = "https://github.com/stalwartlabs/jmap-client", features = ["websockets", "debug", "async"] } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "serde_support", "ludicrous_mode"] } tokio = { version = "1.23", features = ["full"] } -tokio-rustls = { version = "0.24.0"} -rustls = "0.21.0" +tokio-rustls = { version = "0.25.0"} +rustls = "0.22" rustls-pemfile = "2.0" +rustls-pki-types = { version = "1" } csv = "1.1" rayon = { version = "1.5.1" } flate2 = { version = "1.0.17", features = ["zlib"], default-features = false } diff --git a/tests/src/directory/mod.rs b/tests/src/directory/mod.rs index 673d10b5..5a0731f2 100644 --- a/tests/src/directory/mod.rs +++ b/tests/src/directory/mod.rs @@ -29,8 +29,9 @@ pub mod sql; use ::smtp::core::Lookup; use directory::{config::ConfigDirectory, AddressMapping, Directories}; use mail_send::Credentials; -use rustls::{Certificate, PrivateKey, ServerConfig}; +use rustls::ServerConfig; use rustls_pemfile::{certs, pkcs8_private_keys}; +use rustls_pki_types::PrivateKeyDer; use std::{borrow::Cow, io::BufReader, path::PathBuf, sync::Arc}; use store::{config::ConfigStore, LookupStore, Stores}; use tokio_rustls::TlsAcceptor; @@ -367,20 +368,16 @@ XzVV5pwOxkIDBWDIqMUfwJDChBKfpw== pub fn dummy_tls_acceptor() -> Arc { // Init server config builder with safe defaults - let config = ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth(); + let config = ServerConfig::builder().with_no_client_auth(); // load TLS key/cert files let cert_file = &mut BufReader::new(CERT.as_bytes()); let key_file = &mut BufReader::new(PK.as_bytes()); // convert files to key/cert objects - let cert_chain = certs(cert_file) - .map(|v| Certificate(v.unwrap().as_ref().to_vec())) - .collect(); - let mut keys: Vec = pkcs8_private_keys(key_file) - .map(|v| PrivateKey(v.unwrap().secret_pkcs8_der().to_vec())) + let cert_chain = certs(cert_file).map(|r| r.unwrap()).collect(); + let mut keys: Vec = pkcs8_private_keys(key_file) + .map(|v| PrivateKeyDer::Pkcs8(v.unwrap())) .collect(); // exit if no keys could be parsed diff --git a/tests/src/imap/managesieve.rs b/tests/src/imap/managesieve.rs index 6085b426..5ccf7749 100644 --- a/tests/src/imap/managesieve.rs +++ b/tests/src/imap/managesieve.rs @@ -25,7 +25,7 @@ use std::time::Duration; use imap_proto::ResponseType; use mail_send::smtp::tls::build_tls_connector; -use rustls::ServerName; +use rustls_pki_types::ServerName; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader, Lines, ReadHalf, WriteHalf}, net::TcpStream, @@ -164,7 +164,7 @@ impl SieveConnection { let (reader, writer) = tokio::io::split( build_tls_connector(true) .connect( - ServerName::try_from("imap.example.org").unwrap(), + ServerName::try_from("imap.example.org").unwrap().to_owned(), TcpStream::connect("127.0.0.1:4190").await.unwrap(), ) .await diff --git a/tests/src/smtp/outbound/dane.rs b/tests/src/smtp/outbound/dane.rs index a210765d..05bd8625 100644 --- a/tests/src/smtp/outbound/dane.rs +++ b/tests/src/smtp/outbound/dane.rs @@ -44,7 +44,7 @@ use mail_auth::{ report::tlsrpt::ResultType, Resolver, MX, }; -use rustls::Certificate; +use rustls_pki_types::CertificateDer; use utils::config::ServerProtocol; use crate::smtp::{ @@ -304,7 +304,7 @@ async fn dane_test() { let mut file = path.clone(); file.push(format!("{host}.{num}.cert")); if file.exists() { - certs.push(Certificate(fs::read(file).unwrap())); + certs.push(CertificateDer::from(fs::read(file).unwrap())); } else { break; }