diff --git a/Cargo.lock b/Cargo.lock index 9a1081b80a..501060c682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1358,7 +1358,6 @@ dependencies = [ "ratelimit", "regex", "rusqlite", - "rustls-pki-types", "sanitize-filename", "sdp", "serde", diff --git a/Cargo.toml b/Cargo.toml index dd30a4627e..93b01f46d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,6 @@ rand-old = { package = "rand", version = "0.8" } rand = { workspace = true } regex = { workspace = true } rusqlite = { workspace = true, features = ["sqlcipher"] } -rustls-pki-types = "1.12.0" sanitize-filename = { workspace = true } sdp = "0.10.0" serde_json = { workspace = true } diff --git a/src/net/tls.rs b/src/net/tls.rs index d339f3b2ba..cca4e918f5 100644 --- a/src/net/tls.rs +++ b/src/net/tls.rs @@ -7,8 +7,12 @@ use anyhow::Result; use crate::net::session::SessionStream; +use tokio_rustls::rustls; use tokio_rustls::rustls::client::ClientSessionStore; +mod danger; +use danger::NoCertificateVerification; + pub async fn wrap_tls<'a>( strict_tls: bool, hostname: &str, @@ -82,14 +86,13 @@ impl TlsSessionStore { .lock() .entry((port, alpn.to_string())) .or_insert_with(|| { - Arc::new(tokio_rustls::rustls::client::ClientSessionMemoryCache::new( + Arc::new(rustls::client::ClientSessionMemoryCache::new( TLS_CACHE_SIZE, )) }), ) } } - pub async fn wrap_rustls<'a>( hostname: &str, port: u16, @@ -98,10 +101,10 @@ pub async fn wrap_rustls<'a>( stream: impl SessionStream + 'a, tls_session_store: &TlsSessionStore, ) -> Result { - let mut root_cert_store = tokio_rustls::rustls::RootCertStore::empty(); + let mut root_cert_store = rustls::RootCertStore::empty(); root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned()); - let mut config = tokio_rustls::rustls::ClientConfig::builder() + let mut config = rustls::ClientConfig::builder() .with_root_certificates(root_cert_store) .with_no_client_auth(); config.alpn_protocols = if alpn.is_empty() { @@ -118,13 +121,19 @@ pub async fn wrap_rustls<'a>( // and are not worth increasing // attack surface: . let resumption_store = tls_session_store.get(port, alpn); - let resumption = tokio_rustls::rustls::client::Resumption::store(resumption_store) - .tls12_resumption(tokio_rustls::rustls::client::Tls12Resumption::Disabled); + let resumption = rustls::client::Resumption::store(resumption_store) + .tls12_resumption(rustls::client::Tls12Resumption::Disabled); config.resumption = resumption; config.enable_sni = use_sni; + if hostname.starts_with("_") { + config + .dangerous() + .set_certificate_verifier(Arc::new(NoCertificateVerification::new())); + } + let tls = tokio_rustls::TlsConnector::from(Arc::new(config)); - let name = rustls_pki_types::ServerName::try_from(hostname)?.to_owned(); + let name = tokio_rustls::rustls::pki_types::ServerName::try_from(hostname)?.to_owned(); let tls_stream = tls.connect(name, stream).await?; Ok(tls_stream) } diff --git a/src/net/tls/danger.rs b/src/net/tls/danger.rs new file mode 100644 index 0000000000..bd0267ddc0 --- /dev/null +++ b/src/net/tls/danger.rs @@ -0,0 +1,55 @@ +//! Dangerous TLS implementation of accepting invalid certificates for Rustls. + +use rustls::pki_types::{CertificateDer, ServerName, UnixTime}; +use tokio_rustls::rustls; + +#[derive(Debug)] +pub(super) struct NoCertificateVerification(); + +impl NoCertificateVerification { + pub(super) fn new() -> Self { + Self() + } +} + +impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification { + fn verify_server_cert( + &self, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp_response: &[u8], + _now: UnixTime, + ) -> Result { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + message: &[u8], + cert: &CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let provider = rustls::crypto::ring::default_provider(); + let supported_schemes = &provider.signature_verification_algorithms; + rustls::crypto::verify_tls12_signature(message, cert, dss, supported_schemes) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let provider = rustls::crypto::ring::default_provider(); + let supported_schemes = &provider.signature_verification_algorithms; + rustls::crypto::verify_tls13_signature(message, cert, dss, supported_schemes) + } + + fn supported_verify_schemes(&self) -> Vec { + let provider = rustls::crypto::ring::default_provider(); + provider + .signature_verification_algorithms + .supported_schemes() + } +}