diff --git a/impl-rustls/Cargo.toml b/impl-rustls/Cargo.toml index 979ab07..1780c24 100644 --- a/impl-rustls/Cargo.toml +++ b/impl-rustls/Cargo.toml @@ -15,9 +15,9 @@ bench = false travis-ci = { repository = "https://github.com/stepancheg/rust-tls-api/", branch = "master" } [dependencies] -rustls = { version = "0.20.0", features = ["dangerous_configuration"] } +rustls = { version = "0.23.5" } webpki = "0.22.0" -webpki-roots = "0.22.0" +webpki-roots = "0.26.1" tokio = { version = "1.2.0", features = [], optional = true } async-std = { version = "1.9.0", features = ["attributes"], optional = true } anyhow = "1.0.44" diff --git a/impl-rustls/src/acceptor.rs b/impl-rustls/src/acceptor.rs index c389a83..7f057ba 100644 --- a/impl-rustls/src/acceptor.rs +++ b/impl-rustls/src/acceptor.rs @@ -1,3 +1,4 @@ +use std::convert::TryFrom; use std::sync::Arc; use rustls::StreamOwned; @@ -79,11 +80,13 @@ impl tls_api::TlsAcceptor for TlsAcceptor { } fn builder_from_der_key(cert: &[u8], key: &[u8]) -> anyhow::Result { - let cert = rustls::Certificate(cert.to_vec()); + let cert = rustls::pki_types::CertificateDer::from(cert.to_vec()); let config = rustls::ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() - .with_single_cert(vec![cert], rustls::PrivateKey(key.to_vec())) + .with_single_cert( + vec![cert], + rustls::pki_types::PrivateKeyDer::try_from(key.to_vec()).map_err(|x| anyhow::anyhow!(x))? + ) .map_err(anyhow::Error::new)?; Ok(TlsAcceptorBuilder(config)) } diff --git a/impl-rustls/src/connector.rs b/impl-rustls/src/connector.rs index 9c9b24c..6732c9b 100644 --- a/impl-rustls/src/connector.rs +++ b/impl-rustls/src/connector.rs @@ -1,6 +1,10 @@ use std::convert::TryFrom; use std::sync::Arc; +use rustls::crypto::aws_lc_rs; +use rustls::crypto::verify_tls12_signature; +use rustls::crypto::verify_tls13_signature; +use rustls::crypto::WebPkiSupportedAlgorithms; use rustls::StreamOwned; use tls_api::async_as_sync::AsyncIoAsSyncIo; @@ -39,25 +43,56 @@ impl tls_api::TlsConnectorBuilder for TlsConnectorBuilder { fn set_verify_hostname(&mut self, verify: bool) -> anyhow::Result<()> { if !verify { - struct NoCertificateVerifier; + #[derive(Debug)] + struct NoCertificateServerVerifier { + supported: WebPkiSupportedAlgorithms, + } - impl rustls::client::ServerCertVerifier for NoCertificateVerifier { + impl rustls::client::danger::ServerCertVerifier for NoCertificateServerVerifier { fn verify_server_cert( &self, - _end_entity: &rustls::Certificate, - _intermediates: &[rustls::Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, + _end_entity: &rustls::pki_types::CertificateDer<'_>, + _intermediates: &[rustls::pki_types::CertificateDer<'_>], + _server_name: &rustls::pki_types::ServerName<'_>, _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> Result { - Ok(rustls::client::ServerCertVerified::assertion()) + _now: rustls::pki_types::UnixTime, + ) -> Result + { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result + { + verify_tls12_signature(message, cert, dss, &self.supported) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result + { + verify_tls13_signature(message, cert, dss, &self.supported) + } + + fn supported_verify_schemes(&self) -> Vec { + self.supported.supported_schemes() } } + let no_cert_verifier = NoCertificateServerVerifier { + supported: aws_lc_rs::default_provider().signature_verification_algorithms, + }; + self.config .dangerous() - .set_certificate_verifier(Arc::new(NoCertificateVerifier)); + .set_certificate_verifier(Arc::new(no_cert_verifier)); self.verify_hostname = false; } else { if !self.verify_hostname { @@ -69,8 +104,8 @@ impl tls_api::TlsConnectorBuilder for TlsConnectorBuilder { } fn add_root_certificate(&mut self, cert: &[u8]) -> anyhow::Result<()> { - let cert = rustls::Certificate(cert.to_vec()); - self.root_store.add(&cert).map_err(anyhow::Error::new)?; + let cert = rustls::pki_types::CertificateDer::from(cert); + self.root_store.add(cert).map_err(anyhow::Error::new)?; Ok(()) } @@ -78,14 +113,12 @@ impl tls_api::TlsConnectorBuilder for TlsConnectorBuilder { let mut config = self.config; if !self.root_store.is_empty() { let mut new_config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(self.root_store) .with_no_client_auth(); new_config.alpn_protocols = config.alpn_protocols; - new_config.session_storage = config.session_storage; + new_config.resumption = config.resumption; new_config.max_fragment_size = config.max_fragment_size; new_config.client_auth_cert_resolver = config.client_auth_cert_resolver; - new_config.enable_tickets = config.enable_tickets; new_config.enable_sni = config.enable_sni; new_config.key_log = config.key_log; new_config.enable_early_data = config.enable_early_data; @@ -106,10 +139,10 @@ impl TlsConnector { where S: AsyncSocket, { - let dns_name = rustls::ServerName::try_from(domain); - let dns_name = match dns_name.map_err(|_| anyhow::Error::new(webpki::InvalidDnsNameError)) { - Ok(dns_name) => dns_name, - Err(e) => return BoxFuture::new(async { Err(e) }), + let dns_name = rustls::pki_types::ServerName::try_from(domain); + let dns_name = match dns_name { + Ok(dns_name) => dns_name.to_owned(), + Err(e) => return BoxFuture::new(async { Err(anyhow::anyhow!(e)) }), }; let conn = rustls::ClientConnection::new(self.config.clone(), dns_name); let conn = match conn.map_err(|e| anyhow::Error::new(e)) { @@ -145,15 +178,8 @@ impl tls_api::TlsConnector for TlsConnector { fn builder() -> anyhow::Result { let mut roots = rustls::RootCertStore::empty(); - roots.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned()); let config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(roots) .with_no_client_auth(); Ok(TlsConnectorBuilder { diff --git a/impl-rustls/tests/test.rs b/impl-rustls/tests/test.rs index 1c3fa8b..4191187 100644 --- a/impl-rustls/tests/test.rs +++ b/impl-rustls/tests/test.rs @@ -10,9 +10,7 @@ fn connect_bad_hostname() { .downcast_ref() .expect("rustls::TLSError"); match err { - rustls::Error::InvalidCertificateData(e) => { - assert_eq!(e, "invalid peer certificate: CertNotValidForName"); - } + rustls::Error::InvalidCertificate(rustls::CertificateError::NotValidForName) => {}, err => panic!("wrong error: {:?}", err), } });