From 787027cbf96c19a440a401512f9b351b340632e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20CORTIER?= Date: Mon, 19 Aug 2024 20:23:29 +0200 Subject: [PATCH] fix(dgw): update cryptography dependencies We keep using ring as our crypto provider for now. --- Cargo.lock | 76 ++++-------- devolutions-agent/Cargo.toml | 7 +- devolutions-agent/src/main.rs | 4 +- devolutions-agent/src/remote_desktop/tls.rs | 2 +- devolutions-gateway/Cargo.toml | 6 +- devolutions-gateway/src/config.rs | 52 +++++--- devolutions-gateway/src/main.rs | 2 + devolutions-gateway/src/rdp_extension.rs | 4 +- devolutions-gateway/src/service.rs | 5 +- devolutions-gateway/src/tls.rs | 124 ++++++++++++++------ 10 files changed, 156 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12b30a79e..61fce6c92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1003,8 +1003,7 @@ dependencies = [ "parking_lot", "rand", "reqwest", - "rustls 0.23.11", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "serde", "serde_json", "sha2", @@ -1085,7 +1084,7 @@ dependencies = [ "thiserror", "time", "tokio 1.38.1", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.0", "tokio-test", "tower 0.4.13", "tower-http", @@ -1997,7 +1996,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", - "rustls 0.23.11", + "rustls 0.23.12", "rustls-native-certs", "rustls-pki-types", "tokio 1.38.1", @@ -3776,7 +3775,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.11", + "rustls 0.23.12", "thiserror", "tokio 1.38.1", "tracing", @@ -3792,7 +3791,7 @@ dependencies = [ "rand", "ring 0.17.8", "rustc-hash", - "rustls 0.23.11", + "rustls 0.23.12", "slab", "thiserror", "tinyvec", @@ -4019,9 +4018,9 @@ dependencies = [ "percent-encoding", "pin-project-lite 0.2.14", "quinn", - "rustls 0.23.11", + "rustls 0.23.12", "rustls-native-certs", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", "serde_json", @@ -4216,18 +4215,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -4237,37 +4224,36 @@ dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.5", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.11" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.5", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-cng" -version = "0.3.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3612780e9bada1c1f6cf3ad98604c86f403947a78e91943bbec58f690f77ce09" +checksum = "b9fca9fde2952812503b9ebe9656b5497d0c33f562c6240f238ffff63f14241c" dependencies = [ - "rustls 0.21.12", + "rustls 0.23.12", "sha2", - "thiserror", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4277,7 +4263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "schannel", "security-framework", @@ -4294,9 +4280,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -4310,19 +4296,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - -[[package]] -name = "rustls-webpki" -version = "0.102.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "aws-lc-rs", "ring 0.17.8", @@ -5069,16 +5045,6 @@ dependencies = [ "tokio 1.38.1", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio 1.38.1", -] - [[package]] name = "tokio-rustls" version = "0.25.0" @@ -5096,7 +5062,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.11", + "rustls 0.23.12", "rustls-pki-types", "tokio 1.38.1", ] diff --git a/devolutions-agent/Cargo.toml b/devolutions-agent/Cargo.toml index 4ebb87d15..3931839c2 100644 --- a/devolutions-agent/Cargo.toml +++ b/devolutions-agent/Cargo.toml @@ -20,17 +20,14 @@ ctrlc = "3.4" devolutions-agent-shared = { path = "../crates/devolutions-agent-shared" } devolutions-gateway-task = { path = "../crates/devolutions-gateway-task" } devolutions-log = { path = "../crates/devolutions-log" } -# TODO(@pacmancoder): This should point to IronRDP repo after `now-proto-pdu` code is merged to `IronRDP` codebase -# now-proto-pdu = { path = "../crates/now-proto-pdu" } futures = "0.3" parking_lot = "0.12" rand = "0.8" # FIXME(@CBenoit): maybe we don’t need this crate -rustls = "0.23" rustls-pemfile = "2.1" # FIXME(@CBenoit): maybe we don’t need this crate serde_json = "1" serde = { version = "1", features = ["derive"] } tap = "1.0" -tokio-rustls = "0.26" +tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "ring"] } tracing = "0.1" [dependencies.ironrdp] @@ -38,7 +35,7 @@ git = "https://github.com/Devolutions/IronRDP" rev = "2e1a9ac88e38e7d92d893007bc25d0a05c365861" default-features = false features = [ - "server", + "server", # FIXME(@CBenoit): this is enabling AWS LC unconditionnally. "acceptor", ] diff --git a/devolutions-agent/src/main.rs b/devolutions-agent/src/main.rs index fbe46ac47..070946f85 100644 --- a/devolutions-agent/src/main.rs +++ b/devolutions-agent/src/main.rs @@ -4,8 +4,8 @@ // Used by devolutions-agent library. use { anyhow as _, async_trait as _, camino as _, devolutions_agent_shared as _, devolutions_gateway_task as _, - devolutions_log as _, futures as _, ironrdp as _, parking_lot as _, rand as _, rustls as _, rustls_pemfile as _, - serde as _, serde_json as _, tap as _, tokio as _, tokio_rustls as _, + devolutions_log as _, futures as _, ironrdp as _, parking_lot as _, rand as _, rustls_pemfile as _, serde as _, + serde_json as _, tap as _, tokio as _, tokio_rustls as _, }; #[macro_use] diff --git a/devolutions-agent/src/remote_desktop/tls.rs b/devolutions-agent/src/remote_desktop/tls.rs index a728873eb..439fb81ea 100644 --- a/devolutions-agent/src/remote_desktop/tls.rs +++ b/devolutions-agent/src/remote_desktop/tls.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use anyhow::Context as _; use camino::Utf8Path; use rustls::ServerConfig; -use tokio_rustls::TlsAcceptor; +use tokio_rustls::{rustls, TlsAcceptor}; pub(crate) fn acceptor(cert_path: &Utf8Path, key_path: &Utf8Path) -> anyhow::Result { let cert_file = File::open(cert_path).with_context(|| format!("failed to open {cert_path}"))?; diff --git a/devolutions-gateway/Cargo.toml b/devolutions-gateway/Cargo.toml index ac457fd72..508da6032 100644 --- a/devolutions-gateway/Cargo.toml +++ b/devolutions-gateway/Cargo.toml @@ -65,8 +65,8 @@ tracing = "0.1" # Async, futures… tokio = { version = "1.38", features = ["signal", "net", "io-util", "time", "rt", "rt-multi-thread", "sync", "macros", "parking_lot", "fs"] } -tokio-rustls = { version = "0.24", features = ["dangerous_configuration", "tls12"] } -reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots", "json"] } # TODO: directly use hyper in subscriber module +tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "ring"] } +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots", "json"] } futures = "0.3" async-trait = "0.1" tower = { version = "0.4", features = ["timeout"] } @@ -104,7 +104,7 @@ etherparse = "0.15" portpicker = "0.1" [target.'cfg(windows)'.dependencies] -rustls-cng = "0.3" +rustls-cng = { version = "0.5", default-features = false, features = ["logging", "tls12", "ring"] } [target.'cfg(windows)'.build-dependencies] embed-resource = "2.4" diff --git a/devolutions-gateway/src/config.rs b/devolutions-gateway/src/config.rs index 4499884fc..d8ed2d766 100644 --- a/devolutions-gateway/src/config.rs +++ b/devolutions-gateway/src/config.rs @@ -14,7 +14,7 @@ use std::io::BufReader; use std::sync::Arc; use tap::prelude::*; use tokio::sync::Notify; -use tokio_rustls::rustls; +use tokio_rustls::rustls::pki_types; use url::Url; use uuid::Uuid; @@ -569,7 +569,10 @@ fn default_hostname() -> Option { fn read_pfx_file( path: &Utf8Path, password: Option<&dto::Password>, -) -> anyhow::Result<(Vec, rustls::PrivateKey)> { +) -> anyhow::Result<( + Vec>, + pki_types::PrivateKeyDer<'static>, +)> { use picky::pkcs12::{ Pfx, Pkcs12AttributeKind, Pkcs12CryptoContext, Pkcs12ParsingParams, SafeBagKind, SafeContentsKind, }; @@ -665,19 +668,19 @@ fn read_pfx_file( let private_key = private_key.context("leaf private key not found")?.clone(); let private_key = private_key .to_pkcs8() - .map(rustls::PrivateKey) + .map(|der| pki_types::PrivateKeyDer::Pkcs8(der.into())) .context("invalid private key")?; let certificates = certificates .into_iter() - .map(|(cert, _)| cert.to_der().map(rustls::Certificate)) + .map(|(cert, _)| cert.to_der().map(pki_types::CertificateDer::from)) .collect::>() .context("invalid certificate")?; Ok((certificates, private_key)) } -fn read_rustls_certificate_file(path: &Utf8Path) -> anyhow::Result> { +fn read_rustls_certificate_file(path: &Utf8Path) -> anyhow::Result>> { read_rustls_certificate(Some(path), None) .transpose() .expect("a path is provided, so it’s never None") @@ -686,7 +689,7 @@ fn read_rustls_certificate_file(path: &Utf8Path) -> anyhow::Result, data: Option<&dto::ConfData>, -) -> anyhow::Result>> { +) -> anyhow::Result>>> { use picky::pem::{read_pem, PemError}; match (path, data) { @@ -709,7 +712,7 @@ fn read_rustls_certificate( ); } - x509_chain.push(rustls::Certificate(pem.into_data().into_owned())); + x509_chain.push(pki_types::CertificateDer::from(pem.into_data().into_owned())); } Err(e @ PemError::HeaderNotFound) => { if x509_chain.is_empty() { @@ -734,7 +737,7 @@ fn read_rustls_certificate( let value = data.decode_value()?; match data.format { - dto::CertFormat::X509 => Ok(Some(vec![rustls::Certificate(value)])), + dto::CertFormat::X509 => Ok(Some(vec![pki_types::CertificateDer::from(value)])), } } (None, None) => Ok(None), @@ -771,7 +774,7 @@ fn read_pub_key( } } -fn read_rustls_priv_key_file(path: &Utf8Path) -> anyhow::Result { +fn read_rustls_priv_key_file(path: &Utf8Path) -> anyhow::Result> { read_rustls_priv_key(Some(path), None) .transpose() .expect("path is provided, so it’s never None") @@ -780,8 +783,8 @@ fn read_rustls_priv_key_file(path: &Utf8Path) -> anyhow::Result, data: Option<&dto::ConfData>, -) -> anyhow::Result> { - let data = match (path, data) { +) -> anyhow::Result>> { + let private_key = match (path, data) { (Some(path), _) => { let pem: Pem<'_> = normalize_data_path(path, &get_data_dir()) .pipe_ref(std::fs::read_to_string) @@ -789,20 +792,31 @@ fn read_rustls_priv_key( .pipe_deref(str::parse) .context("couldn't parse pem document")?; - if PRIVATE_KEY_LABELS.iter().all(|&label| pem.label() != label) { - anyhow::bail!( - "bad pem label (got {}, expected one of {PRIVATE_KEY_LABELS:?})", - pem.label(), - ); + match pem.label() { + "PRIVATE KEY" => pki_types::PrivateKeyDer::Pkcs8(pem.into_data().into_owned().into()), + "RSA PRIVATE KEY" => pki_types::PrivateKeyDer::Pkcs1(pem.into_data().into_owned().into()), + "EC PRIVATE KEY" => pki_types::PrivateKeyDer::Sec1(pem.into_data().into_owned().into()), + _ => { + anyhow::bail!( + "bad pem label (got {}, expected one of {PRIVATE_KEY_LABELS:?})", + pem.label(), + ); + } } + } + (None, Some(data)) => { + let value = data.decode_value()?; - pem.into_data().into_owned() + match data.format { + dto::PrivKeyFormat::Pkcs8 => pki_types::PrivateKeyDer::Pkcs8(value.into()), + dto::PrivKeyFormat::Pkcs1 => pki_types::PrivateKeyDer::Pkcs1(value.into()), + dto::PrivKeyFormat::Ec => pki_types::PrivateKeyDer::Sec1(value.into()), + } } - (None, Some(data)) => data.decode_value()?, (None, None) => return Ok(None), }; - Ok(Some(rustls::PrivateKey(data))) + Ok(Some(private_key)) } fn read_priv_key( diff --git a/devolutions-gateway/src/main.rs b/devolutions-gateway/src/main.rs index 05d2dd3ac..a9c148ee8 100644 --- a/devolutions-gateway/src/main.rs +++ b/devolutions-gateway/src/main.rs @@ -2,6 +2,8 @@ #![allow(clippy::print_stdout)] // Used by devolutions-gateway library. +#[cfg(windows)] +use rustls_cng as _; #[cfg(feature = "openapi")] use utoipa as _; use { diff --git a/devolutions-gateway/src/rdp_extension.rs b/devolutions-gateway/src/rdp_extension.rs index 24a714d31..b76436d08 100644 --- a/devolutions-gateway/src/rdp_extension.rs +++ b/devolutions-gateway/src/rdp_extension.rs @@ -294,7 +294,7 @@ pub async fn handle( .peer_certificates() .context("no peer certificate found in TLS transport")? .iter() - .map(|cert| cert.0.clone()); + .map(|cert| cert.to_vec()); trace!("Sending RDCleanPath response"); @@ -352,7 +352,7 @@ fn io_to_rdcleanpath_err(err: &io::Error) -> RDCleanPathPdu { .get_ref() .and_then(|e| e.downcast_ref::()) { - RDCleanPathPdu::new_tls_error(tls_alert.get_u8()) + RDCleanPathPdu::new_tls_error(u8::from(*tls_alert)) } else { RDCleanPathPdu::new_wsa_error(WsaError::from(err).as_u16()) } diff --git a/devolutions-gateway/src/service.rs b/devolutions-gateway/src/service.rs index 6b28baf03..738f37c3f 100644 --- a/devolutions-gateway/src/service.rs +++ b/devolutions-gateway/src/service.rs @@ -73,13 +73,16 @@ impl GatewayService { ); } + devolutions_gateway::tls::install_default_crypto_provider(); + if let Some(path) = conf.get_lib_xmf_path() { // SAFETY: No initialisation or termination routine in the XMF library we should worry about for preconditions. let result = unsafe { cadeau::xmf::init(path.as_str()) }; match result { - Ok(_) => info!("XMF native library loaded and installed"), + Ok(_) => info!(%path, "XMF native library loaded and installed"), Err(error) => warn!( + %path, %error, "Failed to load XMF native library, video processing features are disabled" ), diff --git a/devolutions-gateway/src/tls.rs b/devolutions-gateway/src/tls.rs index ba190f882..9686fa93b 100644 --- a/devolutions-gateway/src/tls.rs +++ b/devolutions-gateway/src/tls.rs @@ -4,7 +4,9 @@ use std::sync::Arc; use anyhow::Context as _; use tokio::net::TcpStream; use tokio_rustls::client::TlsStream; -use tokio_rustls::rustls; +use tokio_rustls::rustls::{self, pki_types}; + +static DEFAULT_CIPHER_SUITES: &[rustls::SupportedCipherSuite] = rustls::crypto::ring::DEFAULT_CIPHER_SUITES; lazy_static::lazy_static! { // rustls doc says: @@ -16,8 +18,8 @@ lazy_static::lazy_static! { // We’ll reuse the same TLS client config for all proxy-based TLS connections. // (TlsConnector is just a wrapper around the config providing the `connect` method.) static ref TLS_CONNECTOR: tokio_rustls::TlsConnector = { - let mut tls_client_config = rustls::client::ClientConfig::builder() - .with_safe_defaults() + let mut config = rustls::client::ClientConfig::builder() + .dangerous() .with_custom_certificate_verifier(Arc::new(danger::NoCertificateVerification)) .with_no_client_auth(); @@ -26,18 +28,16 @@ lazy_static::lazy_static! { // > The CredSSP Protocol does not extend the TLS wire protocol. TLS session resumption is not supported. // // source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cssp/385a7489-d46b-464c-b224-f7340e308a5c - tls_client_config.resumption = rustls::client::Resumption::disabled(); + config.resumption = rustls::client::Resumption::disabled(); - tokio_rustls::TlsConnector::from(Arc::new(tls_client_config)) + tokio_rustls::TlsConnector::from(Arc::new(config)) }; } pub async fn connect(dns_name: &str, stream: TcpStream) -> io::Result> { use tokio::io::AsyncWriteExt as _; - let dns_name = dns_name - .try_into() - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + let dns_name = pki_types::ServerName::try_from(dns_name.to_owned()).map_err(io::Error::other)?; let mut tls_stream = TLS_CONNECTOR.connect(dns_name, stream).await?; @@ -54,8 +54,8 @@ pub async fn connect(dns_name: &str, stream: TcpStream) -> io::Result, - private_key: rustls::PrivateKey, + certificates: Vec>, + private_key: pki_types::PrivateKeyDer<'static>, }, SystemStore { cert_subject_name: String, @@ -65,12 +65,7 @@ pub enum CertificateSource { } pub fn build_server_config(cert_source: CertificateSource) -> anyhow::Result { - let builder = rustls::ServerConfig::builder() - .with_cipher_suites(rustls::DEFAULT_CIPHER_SUITES) // = with_safe_default_cipher_suites, but explicit, just to show we are using rustls's default cipher suites - .with_safe_default_kx_groups() - .with_protocol_versions(rustls::DEFAULT_VERSIONS) // = with_safe_default_protocol_versions, but explicit as well - .context("couldn't set supported TLS protocol versions")? - .with_no_client_auth(); + let builder = rustls::ServerConfig::builder().with_no_client_auth(); match cert_source { CertificateSource::External { @@ -97,6 +92,13 @@ pub fn build_server_config(cert_source: CertificateSource) -> anyhow::Result anyhow::Result> { + fn resolve(&self, client_hello: ClientHello<'_>) -> anyhow::Result> { trace!(server_name = ?client_hello.server_name(), "Received ClientHello"); let request_server_name = client_hello @@ -150,14 +153,22 @@ pub mod windows { ) } - // Look up certificate by subject - // TODO(perf): the resolution result could probably be cached + // Look up certificate by subject. + // TODO(perf): the resolution result could probably be cached. let contexts = self .store .find_by_subject_str(&self.subject_name) .context("failed to find server certificate from system store")?; - // Attempt to acquire a private key and construct CngSigningKey + anyhow::ensure!( + !contexts.is_empty(), + "no certificate found for `{}` in system store", + self.subject_name + ); + + trace!(subject_name = %self.subject_name, count = contexts.len(), "Found certificate contexts"); + + // Attempt to acquire a private key and construct CngSigningKey. let (context, key) = contexts .into_iter() .find_map(|ctx| { @@ -169,24 +180,23 @@ pub mod windows { trace!(key_algorithm_group = ?key.key().algorithm_group()); trace!(key_algorithm = ?key.key().algorithm()); - // attempt to acquire a full certificate chain + // Attempt to acquire a full certificate chain. let chain = context .as_chain_der() .context("certification chain is not available for this certificate")?; - let certs = chain.into_iter().map(Certificate).collect(); + let certs = chain.into_iter().map(CertificateDer::from).collect(); - // return CertifiedKey instance + // Return CertifiedKey instance. Ok(Arc::new(CertifiedKey { cert: certs, key: Arc::new(key), ocsp: None, - sct_list: None, })) } } impl ResolvesServerCert for ServerCertResolver { - fn resolve(&self, client_hello: ClientHello) -> Option> { + fn resolve(&self, client_hello: ClientHello<'_>) -> Option> { match self.resolve(client_hello) { Ok(certified_key) => Some(certified_key), Err(error) => { @@ -203,7 +213,7 @@ pub mod sanity { macro_rules! check_cipher_suite { ( $name:ident ) => {{ - if !rustls::DEFAULT_CIPHER_SUITES.contains(&rustls::cipher_suite::$name) { + if !crate::tls::DEFAULT_CIPHER_SUITES.contains(&rustls::crypto::ring::cipher_suite::$name) { anyhow::bail!(concat!(stringify!($name), " cipher suite is missing from default array")); } }}; @@ -224,7 +234,7 @@ pub mod sanity { } pub fn check_default_configuration() -> anyhow::Result<()> { - trace!("TLS cipher suites: {:?}", rustls::DEFAULT_CIPHER_SUITES); + trace!("TLS cipher suites: {:?}", crate::tls::DEFAULT_CIPHER_SUITES); trace!("TLS protocol versions: {:?}", rustls::DEFAULT_VERSIONS); // Make sure we have a few TLS 1.2 cipher suites in our build. @@ -248,21 +258,59 @@ pub mod sanity { } mod danger { - use tokio_rustls::rustls; + use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; + use tokio_rustls::rustls::pki_types; + use tokio_rustls::rustls::{DigitallySignedStruct, Error, SignatureScheme}; + #[derive(Debug)] pub(super) struct NoCertificateVerification; - impl rustls::client::ServerCertVerifier for NoCertificateVerification { + impl ServerCertVerifier for NoCertificateVerification { fn verify_server_cert( &self, - _end_entity: &rustls::Certificate, - _intermediates: &[rustls::Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, - _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> Result { - Ok(rustls::client::ServerCertVerified::assertion()) + _: &pki_types::CertificateDer<'_>, + _: &[pki_types::CertificateDer<'_>], + _: &pki_types::ServerName<'_>, + _: &[u8], + _: pki_types::UnixTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _: &[u8], + _: &pki_types::CertificateDer<'_>, + _: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _: &[u8], + _: &pki_types::CertificateDer<'_>, + _: &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, + ] } } }