From 33aac7787a3d31e8af3e5c1480a929ec899d25c5 Mon Sep 17 00:00:00 2001 From: Kornel Date: Thu, 29 Jan 2026 18:23:26 +0000 Subject: [PATCH 1/2] Add SSL_get_negotiated_group and SSL_set1_groups --- boring/src/nid.rs | 4 ++++ boring/src/ssl/mod.rs | 49 ++++++++++++++++++++++++++++++++++++++ boring/src/ssl/test/mod.rs | 8 +++++++ 3 files changed, 61 insertions(+) diff --git a/boring/src/nid.rs b/boring/src/nid.rs index 347b30f74..dd7598c1d 100644 --- a/boring/src/nid.rs +++ b/boring/src/nid.rs @@ -107,6 +107,10 @@ impl Nid { } pub const UNDEF: Nid = Nid(ffi::NID_undef); + pub const X25519: Nid = Nid(ffi::NID_X25519); + pub const X25519_KYBER768_DRAFT00: Nid = Nid(ffi::NID_X25519Kyber768Draft00); + pub const X25519_MLKEM768: Nid = Nid(ffi::NID_X25519MLKEM768); + pub const MLKEM1024: Nid = Nid(ffi::NID_ML_KEM_1024); pub const ITU_T: Nid = Nid(ffi::NID_itu_t); pub const ISO: Nid = Nid(ffi::NID_iso); pub const JOINT_ISO_ITU_T: Nid = Nid(ffi::NID_joint_iso_itu_t); diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index 8b437dbf3..aea858b76 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -1994,6 +1994,29 @@ impl SslContextBuilder { } } + /// Sets the context's supported groups (curves) by their [`Nid`]. + /// + /// The currently vendored version of BoringSSL supports: + /// + /// * `Nid::X9_62_PRIME256V1` + /// * `Nid::SECP384R1` + /// * `Nid::SECP521R1` + /// * `Nid::X25519` + /// * `Nid::X25519_KYBER768_DRAFT00` + /// * `Nid::X25519_MLKEM768` + /// * `Nid::MLKEM1024` + #[corresponds(SSL_CTX_set1_groups)] + pub fn set_group_nids(&mut self, group_nids: &[Nid]) -> Result<(), ErrorStack> { + unsafe { + cvt_0i(ffi::SSL_CTX_set1_groups( + self.as_ptr(), + group_nids.as_ptr() as *const _, + group_nids.len(), + )) + .map(|_| ()) + } + } + /// Sets the context's compliance policy. /// /// This feature isn't available in the certified version of BoringSSL. @@ -2897,6 +2920,32 @@ impl SslRef { SslOptions::from_bits_retain(bits) } + /// Returns [`Nid`] of the curve used in negotiating the most recent handshake + #[corresponds(SSL_get_negotiated_group)] + #[must_use] + pub fn group_nid(&self) -> Option { + unsafe { + Some(Nid::from_raw(ffi::SSL_get_negotiated_group(self.as_ptr()))) + .filter(|&nid| nid != Nid::UNDEF) + } + } + + /// Sets the ongoing session's supported groups by their named identifiers + /// (formerly referred to as curves). + /// + /// See also [`SslContextBuilder::set_group_nids`] + #[corresponds(SSL_set1_groups)] + pub fn set_group_nids(&mut self, group_nids: &[Nid]) -> Result<(), ErrorStack> { + unsafe { + cvt_0i(ffi::SSL_set1_groups( + self.as_ptr(), + group_nids.as_ptr() as *const _, + group_nids.len(), + )) + .map(|_| ()) + } + } + #[corresponds(SSL_set1_curves_list)] pub fn set_curves_list(&mut self, curves: &str) -> Result<(), ErrorStack> { let curves = CString::new(curves).map_err(ErrorStack::internal_error)?; diff --git a/boring/src/ssl/test/mod.rs b/boring/src/ssl/test/mod.rs index e66d0cc85..980d651bc 100644 --- a/boring/src/ssl/test/mod.rs +++ b/boring/src/ssl/test/mod.rs @@ -9,6 +9,7 @@ use std::thread; use crate::error::ErrorStack; use crate::hash::MessageDigest; +use crate::nid::Nid; use crate::pkey::PKey; use crate::srtp::SrtpProfileId; use crate::ssl::test::server::Server; @@ -1014,6 +1015,13 @@ fn sni_callback_swapped_ctx() { assert!(CALLED_BACK.load(Ordering::SeqCst)); } +#[test] +fn set_group_nids() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_group_nids(&[Nid::SECP521R1, Nid::SECP384R1, Nid::X25519, Nid::MLKEM1024]) + .expect("Failed to set curves"); +} + #[test] fn get_curve() { let server = Server::builder().build(); From 72965caa0de414a1cf7689f84d234dd211fabc85 Mon Sep 17 00:00:00 2001 From: Kornel Date: Thu, 29 Jan 2026 20:09:52 +0000 Subject: [PATCH 2/2] Back-compat for set_curves --- boring/src/ssl/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index aea858b76..eaabb3a7d 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -728,6 +728,14 @@ impl From for SslSignatureAlgorithm { } } +#[doc(hidden)] +#[deprecated(note = "use `Nid` instead")] +pub type SslCurveNid = crate::nid::Nid; + +#[doc(hidden)] +#[deprecated(note = "use `Nid` instead")] +pub type SslCurve = crate::nid::Nid; + /// A compliance policy. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct CompliancePolicy(ffi::ssl_compliance_policy_t); @@ -1994,6 +2002,12 @@ impl SslContextBuilder { } } + #[doc(hidden)] + #[deprecated(note = "Use `Self::set_group_nids()` instead")] + pub fn set_curves(&mut self, group_nids: &[Nid]) -> Result<(), ErrorStack> { + self.set_group_nids(group_nids) + } + /// Sets the context's supported groups (curves) by their [`Nid`]. /// /// The currently vendored version of BoringSSL supports: @@ -2923,6 +2937,7 @@ impl SslRef { /// Returns [`Nid`] of the curve used in negotiating the most recent handshake #[corresponds(SSL_get_negotiated_group)] #[must_use] + #[doc(alias = "curve")] pub fn group_nid(&self) -> Option { unsafe { Some(Nid::from_raw(ffi::SSL_get_negotiated_group(self.as_ptr()))) @@ -2935,6 +2950,7 @@ impl SslRef { /// /// See also [`SslContextBuilder::set_group_nids`] #[corresponds(SSL_set1_groups)] + #[doc(alias = "set_curves")] pub fn set_group_nids(&mut self, group_nids: &[Nid]) -> Result<(), ErrorStack> { unsafe { cvt_0i(ffi::SSL_set1_groups(