diff --git a/CHANGELOG.md b/CHANGELOG.md index 207ad59..dbebd63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased + * Make cipher and kx configurable #73 + # 0.4.0 * Restrict DTLS 1.2 key exchange to P-256/P-384 (for now) #70 diff --git a/src/config.rs b/src/config.rs index 892a866..22367fe 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,9 @@ use std::time::Duration; -use crate::crypto::CryptoProvider; +use crate::crypto::{CryptoProvider, SupportedDtls12CipherSuite}; +use crate::crypto::{SupportedDtls13CipherSuite, SupportedKxGroup}; +use crate::dtls12::message::Dtls12CipherSuite; +use crate::types::{Dtls13CipherSuite, NamedGroup}; use crate::Error; #[cfg(feature = "aws-lc-rs")] @@ -25,6 +28,9 @@ pub struct Config { crypto_provider: CryptoProvider, rng_seed: Option, aead_encryption_limit: u64, + dtls12_cipher_suites: Option>, + dtls13_cipher_suites: Option>, + kx_groups: Option>, } impl Config { @@ -42,6 +48,9 @@ impl Config { crypto_provider: None, rng_seed: None, aead_encryption_limit: 1 << 23, + dtls12_cipher_suites: None, + dtls13_cipher_suites: None, + kx_groups: None, } } @@ -138,6 +147,66 @@ impl Config { pub fn aead_encryption_limit(&self) -> u64 { self.aead_encryption_limit } + + /// Allowed DTLS 1.2 cipher suites, filtered by the config's allow-list. + /// + /// Returns all provider-supported DTLS 1.2 cipher suites when no filter + /// is set. When a filter is set via the builder's `dtls12_cipher_suites` + /// method, only suites in both the provider and the filter are returned. + pub fn dtls12_cipher_suites( + &self, + ) -> impl Iterator + '_ { + let filter = self.dtls12_cipher_suites.as_ref(); + self.crypto_provider + .supported_cipher_suites() + .filter(move |cs| match filter { + Some(list) => list.contains(&cs.suite()), + None => true, + }) + } + + /// Allowed DTLS 1.3 cipher suites, filtered by the config's allow-list. + /// + /// Returns all provider DTLS 1.3 cipher suites when no filter is set. + /// When a filter is set via the builder's `dtls13_cipher_suites` method, + /// only suites in both the provider and the filter are returned. + pub fn dtls13_cipher_suites( + &self, + ) -> impl Iterator + '_ { + let filter = self.dtls13_cipher_suites.as_ref(); + self.crypto_provider + .dtls13_cipher_suites + .iter() + .copied() + .filter(move |cs| match filter { + Some(list) => list.contains(&cs.suite()), + None => true, + }) + } + + /// Allowed key exchange groups, filtered by the config's allow-list. + /// + /// Returns all provider-supported key exchange groups when no filter + /// is set. When a filter is set via the builder's `kx_groups` method, + /// only groups in both the provider and the filter are returned. + pub fn kx_groups(&self) -> impl Iterator + '_ { + let filter = self.kx_groups.as_ref(); + self.crypto_provider + .supported_kx_groups() + .filter(move |kx| match filter { + Some(list) => list.contains(&kx.name()), + None => true, + }) + } + + /// Allowed key exchange groups for DTLS 1.2. + /// + /// Like [`kx_groups`](Self::kx_groups) but additionally restricted to + /// groups that DTLS 1.2 supports (currently P-256 and P-384). + pub fn dtls12_kx_groups(&self) -> impl Iterator + '_ { + self.kx_groups() + .filter(|kx| matches!(kx.name(), NamedGroup::Secp256r1 | NamedGroup::Secp384r1)) + } } /// Builder for [`Config`]. See each setter for defaults. @@ -153,6 +222,9 @@ pub struct ConfigBuilder { crypto_provider: Option, rng_seed: Option, aead_encryption_limit: u64, + dtls12_cipher_suites: Option>, + dtls13_cipher_suites: Option>, + kx_groups: Option>, } impl ConfigBuilder { @@ -261,6 +333,41 @@ impl ConfigBuilder { self } + /// Restrict which DTLS 1.2 cipher suites are offered and accepted. + /// + /// Only cipher suites present in both this list and the provider will + /// be used. Passing an empty slice disables DTLS 1.2 (as long as + /// DTLS 1.3 suites remain). + /// + /// By default all provider-supported DTLS 1.2 cipher suites are used. + pub fn dtls12_cipher_suites(mut self, suites: &[Dtls12CipherSuite]) -> Self { + self.dtls12_cipher_suites = Some(suites.to_vec()); + self + } + + /// Restrict which DTLS 1.3 cipher suites are offered and accepted. + /// + /// Only cipher suites present in both this list and the provider will + /// be used. Passing an empty slice disables DTLS 1.3 (as long as + /// DTLS 1.2 suites remain). + /// + /// By default all provider DTLS 1.3 cipher suites are used. + pub fn dtls13_cipher_suites(mut self, suites: &[Dtls13CipherSuite]) -> Self { + self.dtls13_cipher_suites = Some(suites.to_vec()); + self + } + + /// Restrict which key exchange groups are offered and accepted. + /// + /// Only groups present in both this list and the provider will be + /// used. Order determines preference (first = most preferred). + /// + /// By default all provider-supported key exchange groups are used. + pub fn kx_groups(mut self, groups: &[NamedGroup]) -> Self { + self.kx_groups = Some(groups.to_vec()); + self + } + /// Build the configuration. /// /// This validates the crypto provider before returning the configuration. @@ -307,6 +414,63 @@ impl ConfigBuilder { )); } + // Validate cipher suite filters: at least one version must have suites + let dtls12_count = { + let all = crypto_provider.supported_cipher_suites(); + match &self.dtls12_cipher_suites { + Some(list) => all.filter(|cs| list.contains(&cs.suite())).count(), + None => all.count(), + } + }; + let dtls13_count = { + let all = crypto_provider.dtls13_cipher_suites.iter(); + match &self.dtls13_cipher_suites { + Some(list) => all.filter(|cs| list.contains(&cs.suite())).count(), + None => all.count(), + } + }; + if dtls12_count + dtls13_count == 0 { + return Err(Error::ConfigError( + "No cipher suites remain after filtering. \ + At least one DTLS 1.2 or DTLS 1.3 cipher suite must be available." + .to_string(), + )); + } + + // Validate kx_groups filter: each enabled version needs compatible groups + let filtered_kx = |kx: &&'static dyn SupportedKxGroup| -> bool { + match &self.kx_groups { + Some(list) => list.contains(&kx.name()), + None => true, + } + }; + if dtls12_count > 0 { + let dtls12_kx_count = crypto_provider + .supported_dtls12_kx_groups() + .filter(|kx| filtered_kx(kx)) + .count(); + if dtls12_kx_count == 0 { + return Err(Error::ConfigError( + "DTLS 1.2 cipher suites are enabled but no compatible key exchange \ + groups remain after filtering. DTLS 1.2 requires P-256 or P-384." + .to_string(), + )); + } + } + if dtls13_count > 0 { + let kx_count = crypto_provider + .supported_kx_groups() + .filter(|kx| filtered_kx(kx)) + .count(); + if kx_count == 0 { + return Err(Error::ConfigError( + "DTLS 1.3 cipher suites are enabled but no key exchange groups \ + remain after filtering." + .to_string(), + )); + } + } + Ok(Config { mtu: self.mtu, max_queue_rx: self.max_queue_rx, @@ -319,6 +483,9 @@ impl ConfigBuilder { crypto_provider, rng_seed: self.rng_seed, aead_encryption_limit: self.aead_encryption_limit, + dtls12_cipher_suites: self.dtls12_cipher_suites, + dtls13_cipher_suites: self.dtls13_cipher_suites, + kx_groups: self.kx_groups, }) } } @@ -384,4 +551,158 @@ mod tests { .build() .expect("aead_encryption_limit 1 should be accepted"); } + + #[test] + fn filter_dtls12_cipher_suite() { + let config = Config::builder() + .dtls12_cipher_suites(&[Dtls12CipherSuite::ECDHE_ECDSA_AES128_GCM_SHA256]) + .build() + .expect("should accept single DTLS 1.2 suite"); + let suites: Vec<_> = config.dtls12_cipher_suites().map(|cs| cs.suite()).collect(); + assert_eq!(suites, &[Dtls12CipherSuite::ECDHE_ECDSA_AES128_GCM_SHA256]); + } + + #[test] + fn filter_dtls13_cipher_suite() { + let config = Config::builder() + .dtls13_cipher_suites(&[Dtls13CipherSuite::AES_256_GCM_SHA384]) + .build() + .expect("should accept single DTLS 1.3 suite"); + let suites: Vec<_> = config.dtls13_cipher_suites().map(|cs| cs.suite()).collect(); + assert_eq!(suites, &[Dtls13CipherSuite::AES_256_GCM_SHA384]); + } + + #[test] + fn filter_kx_groups() { + let config = Config::builder() + .kx_groups(&[NamedGroup::Secp256r1]) + .build() + .expect("should accept single kx group"); + let groups: Vec<_> = config.kx_groups().map(|g| g.name()).collect(); + assert_eq!(groups, &[NamedGroup::Secp256r1]); + } + + #[test] + fn empty_dtls12_filter_disables_version() { + let config = Config::builder() + .dtls12_cipher_suites(&[]) + .build() + .expect("should accept empty DTLS 1.2 when 1.3 has suites"); + assert_eq!(config.dtls12_cipher_suites().count(), 0); + assert!(config.dtls13_cipher_suites().count() > 0); + } + + #[test] + fn empty_dtls13_filter_disables_version() { + let config = Config::builder() + .dtls13_cipher_suites(&[]) + .build() + .expect("should accept empty DTLS 1.3 when 1.2 has suites"); + assert!(config.dtls12_cipher_suites().count() > 0); + assert_eq!(config.dtls13_cipher_suites().count(), 0); + } + + #[test] + fn both_empty_filters_rejected() { + match Config::builder() + .dtls12_cipher_suites(&[]) + .dtls13_cipher_suites(&[]) + .build() + { + Err(Error::ConfigError(msg)) => { + assert!( + msg.contains("No cipher suites"), + "error should mention cipher suites: {msg}" + ) + } + Err(other) => panic!("expected ConfigError, got: {other:?}"), + Ok(_) => panic!("expected error when both versions are empty"), + } + } + + #[test] + fn empty_kx_groups_filter_rejected() { + match Config::builder().kx_groups(&[]).build() { + Err(Error::ConfigError(msg)) => { + assert!( + msg.contains("key exchange"), + "error should mention key exchange: {msg}" + ) + } + Err(other) => panic!("expected ConfigError, got: {other:?}"), + Ok(_) => panic!("expected error for empty kx groups"), + } + } + + #[test] + fn x25519_only_rejected_for_dtls12() { + // X25519 is not yet supported for DTLS 1.2, so filtering to X25519-only + // while DTLS 1.2 suites are enabled should fail. + match Config::builder() + .dtls13_cipher_suites(&[]) + .kx_groups(&[NamedGroup::X25519]) + .build() + { + Err(Error::ConfigError(msg)) => { + assert!( + msg.contains("DTLS 1.2") && msg.contains("P-256 or P-384"), + "error should mention DTLS 1.2 and required groups: {msg}" + ) + } + Err(other) => panic!("expected ConfigError, got: {other:?}"), + Ok(_) => panic!("expected error for X25519-only with DTLS 1.2"), + } + } + + #[test] + fn x25519_only_accepted_for_dtls13_only() { + // X25519-only is fine when DTLS 1.2 is disabled. + let config = Config::builder() + .dtls12_cipher_suites(&[]) + .kx_groups(&[NamedGroup::X25519]) + .build() + .expect("X25519-only should be accepted for DTLS 1.3-only config"); + let groups: Vec<_> = config.kx_groups().map(|g| g.name()).collect(); + assert_eq!(groups, &[NamedGroup::X25519]); + } + + #[test] + fn dtls12_kx_groups_excludes_x25519() { + let config = Config::default(); + let dtls12_groups: Vec<_> = config.dtls12_kx_groups().map(|g| g.name()).collect(); + assert!(!dtls12_groups.contains(&NamedGroup::X25519)); + assert!(dtls12_groups.contains(&NamedGroup::Secp256r1)); + } + + #[test] + fn no_filter_returns_all() { + let config = Config::default(); + // Default provider should have at least 2 DTLS 1.2 and 2 DTLS 1.3 suites + assert!(config.dtls12_cipher_suites().count() >= 2); + assert!(config.dtls13_cipher_suites().count() >= 2); + assert!(config.kx_groups().count() >= 2); + } + + #[test] + fn filter_with_explicit_provider() { + #[cfg(feature = "aws-lc-rs")] + { + let config = Config::builder() + .with_crypto_provider(aws_lc_rs::default_provider()) + .dtls12_cipher_suites(&[Dtls12CipherSuite::ECDHE_ECDSA_AES256_GCM_SHA384]) + .dtls13_cipher_suites(&[Dtls13CipherSuite::AES_128_GCM_SHA256]) + .kx_groups(&[NamedGroup::X25519, NamedGroup::Secp256r1]) + .build() + .expect("should accept filtered config with explicit provider"); + let suites12: Vec<_> = config.dtls12_cipher_suites().map(|cs| cs.suite()).collect(); + assert_eq!( + suites12, + &[Dtls12CipherSuite::ECDHE_ECDSA_AES256_GCM_SHA384] + ); + let suites13: Vec<_> = config.dtls13_cipher_suites().map(|cs| cs.suite()).collect(); + assert_eq!(suites13, &[Dtls13CipherSuite::AES_128_GCM_SHA256]); + let groups: Vec<_> = config.kx_groups().map(|g| g.name()).collect(); + assert_eq!(groups, &[NamedGroup::X25519, NamedGroup::Secp256r1]); + } + } } diff --git a/src/detect.rs b/src/detect.rs index 752e542..5546f2b 100644 --- a/src/detect.rs +++ b/src/detect.rs @@ -25,14 +25,6 @@ use crate::dtls13::message::UseSrtpExtension; use crate::types::NamedGroup; use crate::{Config, DtlsCertificate, Error, Output, SeededRng}; -// DTLS 1.2 cipher suite values (IANA) -const ECDHE_ECDSA_AES128_GCM_SHA256: u16 = 0xC02B; -const ECDHE_ECDSA_AES256_GCM_SHA384: u16 = 0xC02C; - -// DTLS 1.3 cipher suite values (IANA) -const TLS_AES_128_GCM_SHA256: u16 = 0x1301; -const TLS_AES_256_GCM_SHA384: u16 = 0x1302; - // Extension type constants const EXT_SUPPORTED_GROUPS: u16 = 0x000A; const EXT_EC_POINT_FORMATS: u16 = 0x000B; @@ -81,12 +73,11 @@ impl HybridClientHello { pub fn new(config: &Arc) -> Result { let mut rng = SeededRng::new(config.rng_seed()); let random = Random::new(&mut rng); - let provider = config.crypto_provider(); - // Start ECDHE key exchange with the first supported group - let group = provider - .kx_groups - .first() + // Start ECDHE key exchange with the first supported group (filtered) + let group = config + .kx_groups() + .next() .ok_or_else(|| Error::CryptoError("No supported key exchange groups".into()))?; let kx_buf = Buf::new(); let key_exchange = group @@ -108,15 +99,16 @@ impl HybridClientHello { // legacy_cookie: empty (DTLS 1.3 requires zero-length) ch_body.push(0); - // cipher_suites: 1.3 suites first, then 1.2 suites - let suites: &[u16] = &[ - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - ECDHE_ECDSA_AES128_GCM_SHA256, - ECDHE_ECDSA_AES256_GCM_SHA384, - ]; + // cipher_suites: 1.3 suites first, then 1.2 suites (filtered by config) + let mut suites: ArrayVec = ArrayVec::new(); + for cs in config.dtls13_cipher_suites() { + suites.push(cs.suite().as_u16()); + } + for cs in config.dtls12_cipher_suites() { + suites.push(cs.suite().as_u16()); + } ch_body.extend_from_slice(&((suites.len() * 2) as u16).to_be_bytes()); - for &suite in suites { + for &suite in &suites { ch_body.extend_from_slice(&suite.to_be_bytes()); } @@ -137,9 +129,9 @@ impl HybridClientHello { ext_buf.extend_from_slice(&0xFEFDu16.to_be_bytes()); // DTLS 1.2 ext_entries.push((EXT_SUPPORTED_VERSIONS, start, ext_buf.len())); - // 2. supported_groups + // 2. supported_groups (filtered by config) let start = ext_buf.len(); - let groups: ArrayVec = provider.kx_groups.iter().map(|g| g.name()).collect(); + let groups: ArrayVec = config.kx_groups().map(|g| g.name()).collect(); let sg = SupportedGroupsExtension { groups }; sg.serialize(&mut ext_buf); ext_entries.push((EXT_SUPPORTED_GROUPS, start, ext_buf.len())); diff --git a/src/dtls12/client.rs b/src/dtls12/client.rs index 9c4d27d..44e5a4a 100644 --- a/src/dtls12/client.rs +++ b/src/dtls12/client.rs @@ -1079,10 +1079,10 @@ fn handshake_create_client_hello( ) -> Result<(), Error> { let client_version = ProtocolVersion::DTLS1_2; - // Get cipher suites from provider that are compatible with our key - let provider = engine.crypto_context().provider(); - let cipher_suites: CipherSuiteVec = provider - .supported_cipher_suites() + // Get cipher suites from config that are compatible with our key + let cipher_suites: CipherSuiteVec = engine + .config() + .dtls12_cipher_suites() .map(|cs| cs.suite()) .filter(|suite| engine.crypto_context().is_cipher_suite_compatible(*suite)) .take(Dtls12CipherSuite::supported().len()) @@ -1107,7 +1107,7 @@ fn handshake_create_client_hello( cipher_suites, compression_methods, ) - .with_extensions(extension_data, provider); + .with_extensions(extension_data, engine.config()); client_hello.serialize(extension_data, body); Ok(()) diff --git a/src/dtls12/engine.rs b/src/dtls12/engine.rs index e12a55f..2f1a752 100644 --- a/src/dtls12/engine.rs +++ b/src/dtls12/engine.rs @@ -166,9 +166,8 @@ impl Engine { /// Is the given cipher suite allowed by configuration pub fn is_cipher_suite_allowed(&self, suite: Dtls12CipherSuite) -> bool { - self.crypto_context - .provider() - .supported_cipher_suites() + self.config + .dtls12_cipher_suites() .any(|cs| cs.suite() == suite) } diff --git a/src/dtls12/message/client_hello.rs b/src/dtls12/message/client_hello.rs index 0638013..d70ce86 100644 --- a/src/dtls12/message/client_hello.rs +++ b/src/dtls12/message/client_hello.rs @@ -10,8 +10,8 @@ use nom::{Err, IResult}; use super::extension::ExtensionVec; use crate::buffer::Buf; -use crate::crypto::CryptoProvider; use crate::util::many1; +use crate::Config; #[derive(Debug, PartialEq, Eq)] pub struct ClientHello { @@ -45,7 +45,7 @@ impl ClientHello { } /// Add all required extensions for DTLS handshake - pub fn with_extensions(mut self, buf: &mut Buf, provider: &CryptoProvider) -> Self { + pub fn with_extensions(mut self, buf: &mut Buf, config: &Config) -> Self { // Clear the extension data buffer buf.clear(); @@ -53,12 +53,16 @@ impl ClientHello { let mut ranges = ArrayVec::<(ExtensionType, usize, usize), 8>::new(); // Check if provider has ECDH support - let has_ecdh = provider.has_ecdh(); + let has_ecdh = config.crypto_provider().has_ecdh(); // Add supported groups and EC point formats if using ECDH if has_ecdh { - // Add supported groups extension from provider - let supported_groups = SupportedGroupsExtension::from_provider(provider); + // Add supported groups extension from config (DTLS 1.2 filtered) + let mut groups = super::NamedGroupVec::new(); + for kx_group in config.dtls12_kx_groups() { + groups.push(kx_group.name()); + } + let supported_groups = SupportedGroupsExtension { groups }; let start_pos = buf.len(); supported_groups.serialize(buf); ranges.push((ExtensionType::SupportedGroups, start_pos, buf.len())); diff --git a/src/dtls12/message/extensions/supported_groups.rs b/src/dtls12/message/extensions/supported_groups.rs index d1b73b0..4746758 100644 --- a/src/dtls12/message/extensions/supported_groups.rs +++ b/src/dtls12/message/extensions/supported_groups.rs @@ -1,6 +1,5 @@ use super::super::{NamedGroup, NamedGroupVec}; use crate::buffer::Buf; -use crate::crypto::CryptoProvider; use nom::IResult; /// SupportedGroups extension as defined in RFC 8422 @@ -10,15 +9,6 @@ pub struct SupportedGroupsExtension { } impl SupportedGroupsExtension { - /// Create a SupportedGroupsExtension from a crypto provider - pub fn from_provider(provider: &CryptoProvider) -> Self { - let mut groups = NamedGroupVec::new(); - for kx_group in provider.supported_dtls12_kx_groups() { - groups.push(kx_group.name()); - } - SupportedGroupsExtension { groups } - } - pub fn parse(input: &[u8]) -> IResult<&[u8], SupportedGroupsExtension> { let (mut input, list_len) = nom::number::complete::be_u16(input)?; let mut groups = NamedGroupVec::new(); diff --git a/src/dtls13/client.rs b/src/dtls13/client.rs index 3dca271..f4a8908 100644 --- a/src/dtls13/client.rs +++ b/src/dtls13/client.rs @@ -343,11 +343,12 @@ impl State { let group = if let Some(hrr_group) = client.hrr_selected_group { hrr_group } else { - // Use the first supported group from the provider - let provider = client.engine.config().crypto_provider(); - provider - .kx_groups - .first() + // Use the first supported group from config (filtered) + client + .engine + .config() + .kx_groups() + .next() .map(|g| g.name()) .ok_or_else(|| Error::CryptoError("No supported key exchange groups".to_string()))? }; @@ -1099,11 +1100,10 @@ fn handshake_create_client_hello( // DTLS 1.3: legacy_cookie MUST be zero length let legacy_cookie = Cookie::empty(); - // Cipher suites from provider - let provider = engine.config().crypto_provider(); - let cipher_suites: ArrayVec = provider - .dtls13_cipher_suites - .iter() + // Cipher suites from config (filtered) + let cipher_suites: ArrayVec = engine + .config() + .dtls13_cipher_suites() .map(|cs| cs.suite()) .take(3) .collect(); @@ -1134,7 +1134,7 @@ fn handshake_create_client_hello( // 2. supported_groups extension let sg_start = ext_buf.len(); - let groups: ArrayVec = provider.kx_groups.iter().map(|g| g.name()).collect(); + let groups: ArrayVec = engine.config().kx_groups().map(|g| g.name()).collect(); let sg = SupportedGroupsExtension { groups }; sg.serialize(&mut ext_buf); let sg_end = ext_buf.len(); diff --git a/src/dtls13/engine.rs b/src/dtls13/engine.rs index 2ef72b5..dca03fe 100644 --- a/src/dtls13/engine.rs +++ b/src/dtls13/engine.rs @@ -302,9 +302,7 @@ impl Engine { pub fn is_cipher_suite_allowed(&self, suite: Dtls13CipherSuite) -> bool { self.config - .crypto_provider() - .dtls13_cipher_suites - .iter() + .dtls13_cipher_suites() .any(|cs| cs.suite() == suite) } @@ -2085,12 +2083,7 @@ impl Engine { &self, group: crate::types::NamedGroup, ) -> Option<&'static dyn SupportedKxGroup> { - self.config - .crypto_provider() - .kx_groups - .iter() - .find(|g| g.name() == group) - .copied() + self.config.kx_groups().find(|g| g.name() == group) } // ========================================================================= diff --git a/src/dtls13/server.rs b/src/dtls13/server.rs index de3077a..7884d8d 100644 --- a/src/dtls13/server.rs +++ b/src/dtls13/server.rs @@ -414,9 +414,12 @@ impl State { // Pre-compute whether we also need a key_share group selection, so // we can piggyback it on a cookie HRR (avoiding two sequential HRRs). - let provider = server.engine.config().crypto_provider(); - let our_groups: ArrayVec = - provider.kx_groups.iter().map(|g| g.name()).collect(); + let our_groups: ArrayVec = server + .engine + .config() + .kx_groups() + .map(|g| g.name()) + .collect(); let key_shares = client_key_shares .as_ref() .map(|v| v.as_slice()) diff --git a/tests/dtls13/handshake.rs b/tests/dtls13/handshake.rs index b0b9f51..f39b8ac 100644 --- a/tests/dtls13/handshake.rs +++ b/tests/dtls13/handshake.rs @@ -589,7 +589,6 @@ fn dtls13_handshake_secp256r1_key_exchange() { #[cfg(feature = "rcgen")] fn dtls13_handshake_x25519_key_exchange() { use dimpl::certificate::generate_self_signed_certificate; - use dimpl::crypto::aws_lc_rs; use dimpl::crypto::NamedGroup; use dimpl::Config; @@ -598,26 +597,12 @@ fn dtls13_handshake_x25519_key_exchange() { let client_cert = generate_self_signed_certificate().expect("gen client cert"); let server_cert = generate_self_signed_certificate().expect("gen server cert"); - // Build a custom provider that only offers X25519 - let default = aws_lc_rs::default_provider(); - let x25519_only: Vec<_> = default - .kx_groups - .iter() - .copied() - .filter(|g| g.name() == NamedGroup::X25519) - .collect(); - assert!(!x25519_only.is_empty(), "Provider must have X25519"); - - let x25519_static: &'static [_] = Box::leak(x25519_only.into_boxed_slice()); - - let provider = dimpl::crypto::CryptoProvider { - kx_groups: x25519_static, - ..default - }; - + // Use config filter to select only X25519 and disable DTLS 1.2 + // (X25519 is not yet supported for DTLS 1.2) let config = Arc::new( Config::builder() - .with_crypto_provider(provider) + .kx_groups(&[NamedGroup::X25519]) + .dtls12_cipher_suites(&[]) .build() .expect("build config"), );