diff --git a/Cargo.toml b/Cargo.toml index 0fd565e..970287f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,9 @@ resolver = "2" [workspace.dependencies] boring = { version = "4", default-features = false } boring-sys = { version = "4", default-features = false } -rustls = { version = "=0.22.0-alpha.6", default-features = false } -rustls-pemfile = { version = "=2.0.0-alpha.2" } -rustls-pki-types = { version = "0.2.3" } -tokio-rustls = { version = "0.25.0-alpha.4" } -webpki = { package = "rustls-webpki", version = "0.102.0-alpha.7", default-features = false } -webpki-roots = { version = "=0.26.0-alpha.2" } +rustls = { version = "0.22", default-features = false } +rustls-pemfile = { version = "2" } +rustls-pki-types = { version = "1" } +tokio-rustls = { git = "https://github.com/cpu/tokio-rustls.git", branch="cpu-0.25-prep" } +webpki = { package = "rustls-webpki", version = "0.102", default-features = false } +webpki-roots = { version = "0.26" } diff --git a/boring-rustls-provider/src/lib.rs b/boring-rustls-provider/src/lib.rs index 0183125..9f39914 100644 --- a/boring-rustls-provider/src/lib.rs +++ b/boring-rustls-provider/src/lib.rs @@ -21,56 +21,49 @@ pub mod tls12; pub mod tls13; pub mod verify; -/// The boringssl-based Rustls Crypto provider -pub static PROVIDER: &'static dyn CryptoProvider = &Provider; - -#[derive(Debug)] -struct Provider; - -impl CryptoProvider for Provider { - fn fill_random(&self, bytes: &mut [u8]) -> Result<(), GetRandomFailed> { - boring::rand::rand_bytes(bytes).map_err(|e| log_and_map("rand_bytes", e, GetRandomFailed)) +pub fn provider() -> CryptoProvider { + #[cfg(feature = "fips-only")] + { + provider_with_ciphers(ALL_FIPS_CIPHER_SUITES.to_vec()) + } + #[cfg(not(feature = "fips-only"))] + { + provider_with_ciphers(ALL_CIPHER_SUITES.to_vec()) } +} - fn default_cipher_suites(&self) -> &'static [SupportedCipherSuite] { +pub fn provider_with_ciphers(ciphers: Vec) -> CryptoProvider { + CryptoProvider { + cipher_suites: ciphers, #[cfg(feature = "fips-only")] - { - ALL_FIPS_CIPHER_SUITES - } + kx_groups: ALL_FIPS_KX_GROUPS.to_vec(), #[cfg(not(feature = "fips-only"))] - { - ALL_CIPHER_SUITES - } - } - - fn default_kx_groups(&self) -> &'static [&'static dyn SupportedKxGroup] { + kx_groups: ALL_KX_GROUPS.to_vec(), #[cfg(feature = "fips-only")] - { - ALL_FIPS_KX_GROUPS - } + signature_verification_algorithms: verify::ALL_FIPS_ALGORITHMS, #[cfg(not(feature = "fips-only"))] - { - ALL_KX_GROUPS - } + signature_verification_algorithms: verify::ALL_ALGORITHMS, + secure_random: &Provider, + key_provider: &Provider, } +} +#[derive(Debug)] +struct Provider; + +impl rustls::crypto::SecureRandom for Provider { + fn fill(&self, bytes: &mut [u8]) -> Result<(), rustls::crypto::GetRandomFailed> { + boring::rand::rand_bytes(bytes).map_err(|e| log_and_map("rand_bytes", e, GetRandomFailed)) + } +} + +impl rustls::crypto::KeyProvider for Provider { fn load_private_key( &self, key_der: PrivateKeyDer<'static>, - ) -> Result, rustls::Error> { + ) -> Result, rustls::Error> { sign::BoringPrivateKey::try_from(key_der).map(|x| Arc::new(x) as _) } - - fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms { - #[cfg(feature = "fips-only")] - { - verify::ALL_FIPS_ALGORITHMS - } - #[cfg(not(feature = "fips-only"))] - { - verify::ALL_ALGORITHMS - } - } } #[allow(unused)] diff --git a/boring-rustls-provider/src/prf.rs b/boring-rustls-provider/src/prf.rs index 958992e..ca174f5 100644 --- a/boring-rustls-provider/src/prf.rs +++ b/boring-rustls-provider/src/prf.rs @@ -10,7 +10,7 @@ pub struct PrfTls1WithDigest(pub boring::nid::Nid); impl crypto::tls12::Prf for PrfTls1WithDigest { fn for_key_exchange( &self, - output: &mut [u8], + output: &mut [u8; 48], kx: Box, peer_pub_key: &[u8], label: &[u8], diff --git a/boring-rustls-provider/src/tls12.rs b/boring-rustls-provider/src/tls12.rs index faf8d12..677389e 100644 --- a/boring-rustls-provider/src/tls12.rs +++ b/boring-rustls-provider/src/tls12.rs @@ -23,7 +23,7 @@ const PRF_SHA256: prf::PrfTls1WithDigest = prf::PrfTls1WithDigest(boring::nid::N const PRF_SHA384: prf::PrfTls1WithDigest = prf::PrfTls1WithDigest(boring::nid::Nid::SHA384); pub static ECDHE_ECDSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, hash_provider: hash::SHA256, confidentiality_limit: 1 << 23, @@ -36,7 +36,7 @@ pub static ECDHE_ECDSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite { }; pub static ECDHE_RSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, hash_provider: hash::SHA256, confidentiality_limit: 1 << 23, @@ -49,7 +49,7 @@ pub static ECDHE_RSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite { }; pub static ECDHE_ECDSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, hash_provider: hash::SHA384, confidentiality_limit: 1 << 23, @@ -62,7 +62,7 @@ pub static ECDHE_ECDSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite { }; pub static ECDHE_RSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, hash_provider: hash::SHA384, confidentiality_limit: 1 << 23, @@ -75,7 +75,7 @@ pub static ECDHE_RSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite { }; pub static ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, hash_provider: hash::SHA256, confidentiality_limit: u64::MAX, @@ -88,7 +88,7 @@ pub static ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12Ci }; pub static ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, hash_provider: hash::SHA256, confidentiality_limit: u64::MAX, diff --git a/boring-rustls-provider/src/tls13.rs b/boring-rustls-provider/src/tls13.rs index 0769e5e..81bdc23 100644 --- a/boring-rustls-provider/src/tls13.rs +++ b/boring-rustls-provider/src/tls13.rs @@ -3,7 +3,7 @@ use rustls::Tls13CipherSuite; use crate::{aead, hash, hkdf}; pub static AES_128_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS13_AES_128_GCM_SHA256, hash_provider: hash::SHA256, confidentiality_limit: 1 << 23, @@ -15,7 +15,7 @@ pub static AES_128_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite { }; pub static AES_256_GCM_SHA384: Tls13CipherSuite = Tls13CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS13_AES_256_GCM_SHA384, hash_provider: hash::SHA384, confidentiality_limit: 1 << 23, @@ -27,7 +27,7 @@ pub static AES_256_GCM_SHA384: Tls13CipherSuite = Tls13CipherSuite { }; pub static CHACHA20_POLY1305_SHA256: Tls13CipherSuite = Tls13CipherSuite { - common: rustls::CipherSuiteCommon { + common: rustls::crypto::CipherSuiteCommon { suite: rustls::CipherSuite::TLS13_CHACHA20_POLY1305_SHA256, hash_provider: hash::SHA256, confidentiality_limit: u64::MAX, diff --git a/boring-rustls-provider/src/verify.rs b/boring-rustls-provider/src/verify.rs index 5de9140..15eaea0 100644 --- a/boring-rustls-provider/src/verify.rs +++ b/boring-rustls-provider/src/verify.rs @@ -1,4 +1,4 @@ -use rustls::{SignatureScheme, WebPkiSupportedAlgorithms}; +use rustls::{crypto::WebPkiSupportedAlgorithms, SignatureScheme}; pub(crate) mod ec; pub(crate) mod ed; diff --git a/boring-rustls-provider/tests/e2e.rs b/boring-rustls-provider/tests/e2e.rs index 212f1ca..36f2969 100644 --- a/boring-rustls-provider/tests/e2e.rs +++ b/boring-rustls-provider/tests/e2e.rs @@ -5,7 +5,7 @@ use tokio::{ net::TcpStream, }; -use boring_rustls_provider::{tls12, tls13, PROVIDER}; +use boring_rustls_provider::{tls12, tls13}; use rustls::{ version::{TLS12, TLS13}, ClientConfig, ServerConfig, SupportedCipherSuite, @@ -28,13 +28,13 @@ async fn test_tls13_crypto() { ]; for cipher in ciphers { - let config = ClientConfig::builder_with_provider(PROVIDER) - .with_cipher_suites(&[cipher]) - .with_safe_default_kx_groups() - .with_protocol_versions(&[&TLS13]) - .unwrap() - .with_root_certificates(root_store.clone()) - .with_no_client_auth(); + let config = ClientConfig::builder_with_provider(Arc::new( + boring_rustls_provider::provider_with_ciphers([cipher].to_vec()), + )) + .with_protocol_versions(&[&TLS13]) + .unwrap() + .with_root_certificates(root_store.clone()) + .with_no_client_auth(); do_exchange(config, server_config.clone()).await; } @@ -54,13 +54,13 @@ async fn test_tls12_ec_crypto() { ]; for cipher in ciphers { - let config = ClientConfig::builder_with_provider(PROVIDER) - .with_cipher_suites(&[cipher]) - .with_safe_default_kx_groups() - .with_protocol_versions(&[&TLS12]) - .unwrap() - .with_root_certificates(root_store.clone()) - .with_no_client_auth(); + let config = ClientConfig::builder_with_provider(Arc::new( + boring_rustls_provider::provider_with_ciphers([cipher].to_vec()), + )) + .with_protocol_versions(&[&TLS13]) + .unwrap() + .with_root_certificates(root_store.clone()) + .with_no_client_auth(); do_exchange(config, server_config.clone()).await; } @@ -80,13 +80,13 @@ async fn test_tls12_rsa_crypto() { ]; for cipher in ciphers { - let config = ClientConfig::builder_with_provider(PROVIDER) - .with_cipher_suites(&[cipher]) - .with_safe_default_kx_groups() - .with_protocol_versions(&[&TLS12]) - .unwrap() - .with_root_certificates(root_store.clone()) - .with_no_client_auth(); + let config = ClientConfig::builder_with_provider(Arc::new( + boring_rustls_provider::provider_with_ciphers([cipher].to_vec()), + )) + .with_protocol_versions(&[&TLS12]) + .unwrap() + .with_root_certificates(root_store.clone()) + .with_no_client_auth(); do_exchange(config, server_config.clone()).await; } @@ -176,11 +176,13 @@ impl TestPki { } fn server_config(self) -> Arc { - let mut server_config = ServerConfig::builder_with_provider(PROVIDER) - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(vec![self.server_cert_der], self.server_key_der) - .unwrap(); + let mut server_config = + ServerConfig::builder_with_provider(Arc::new(boring_rustls_provider::provider())) + .with_protocol_versions(&[&TLS12, &TLS13]) + .unwrap() + .with_no_client_auth() + .with_single_cert(vec![self.server_cert_der], self.server_key_der) + .unwrap(); server_config.key_log = Arc::new(rustls::KeyLogFile::new()); diff --git a/examples/src/bin/client.rs b/examples/src/bin/client.rs index 55a4cc0..f1780c1 100644 --- a/examples/src/bin/client.rs +++ b/examples/src/bin/client.rs @@ -2,18 +2,18 @@ use std::io::{stdout, Read, Write}; use std::net::TcpStream; use std::sync::Arc; -use boring_rustls_provider::PROVIDER; - fn main() { env_logger::init(); let mut root_store = rustls::RootCertStore::empty(); root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned()); - let config = rustls::ClientConfig::builder_with_provider(PROVIDER) - .with_safe_defaults() - .with_root_certificates(root_store) - .with_no_client_auth(); + let config = + rustls::ClientConfig::builder_with_provider(boring_rustls_provider::provider().into()) + .with_safe_default_protocol_versions() + .unwrap() + .with_root_certificates(root_store) + .with_no_client_auth(); let server_name = "www.rust-lang.org".try_into().unwrap(); let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name).unwrap();