diff --git a/MATRIX.md b/MATRIX.md index 7520420..417a0fb 100644 --- a/MATRIX.md +++ b/MATRIX.md @@ -384,7 +384,7 @@ | `SSL_get_version` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | `SSL_get_wbio` | | :white_check_mark: | :white_check_mark: | :white_check_mark: | | `SSL_get_wfd` | | | | | -| `SSL_group_to_name` | | | | | +| `SSL_group_to_name` | | | | :white_check_mark: | | `SSL_has_matching_session_id` | | | | | | `SSL_has_pending` | | | | :white_check_mark: | | `SSL_in_before` | | | | :white_check_mark: | diff --git a/build.rs b/build.rs index cf63c1c..ff8b8f6 100644 --- a/build.rs +++ b/build.rs @@ -193,6 +193,7 @@ const ENTRYPOINTS: &[&str] = &[ "SSL_get_verify_result", "SSL_get_version", "SSL_get_wbio", + "SSL_group_to_name", "SSL_has_pending", "SSL_in_before", "SSL_in_init", diff --git a/src/constants.rs b/src/constants.rs index a52dcd3..8aabec8 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -120,9 +120,33 @@ pub fn sig_scheme_to_type_nid(scheme: SignatureScheme) -> Option { } } +pub fn named_group_to_tls_name(id: NamedGroup) -> Option<&'static CStr> { + match id { + NamedGroup::secp256r1 => Some(c"secp256r1"), + NamedGroup::secp384r1 => Some(c"secp384r1"), + NamedGroup::secp521r1 => Some(c"secp521r1"), + NamedGroup::X25519 => Some(c"x25519"), + NamedGroup::X448 => Some(c"x448"), + NamedGroup::FFDHE2048 => Some(c"ffdhe2048"), + NamedGroup::FFDHE3072 => Some(c"ffdhe3072"), + NamedGroup::FFDHE4096 => Some(c"ffdhe4096"), + NamedGroup::FFDHE6144 => Some(c"ffdhe6144"), + NamedGroup::FFDHE8192 => Some(c"ffdhe8192"), + NamedGroup::MLKEM512 => Some(c"MLKEM512"), + NamedGroup::MLKEM768 => Some(c"MLKEM768"), + NamedGroup::MLKEM1024 => Some(c"MLKEM1024"), + NamedGroup::X25519MLKEM768 => Some(c"X25519MLKEM768"), + NamedGroup::secp256r1MLKEM768 => Some(c"SecP256r1MLKEM768"), + _ => None, + } +} + pub fn named_group_to_nid(group: NamedGroup) -> Option { use NamedGroup::*; + // See TLSEXT_nid_unknown from tls1.h - openssl-sys does not + // have a constant for this to import. + const TLSEXT_NID_UNKNOWN: c_int = 0x1000000; // See NID_ffhdhe* from obj_mac.h - openssl-sys does not have // constants for these to import. const NID_FFDHE2048: c_int = 1126; @@ -130,10 +154,11 @@ pub fn named_group_to_nid(group: NamedGroup) -> Option { const NID_FFDHE4096: c_int = 1128; const NID_FFDHE6144: c_int = 1129; const NID_FFDHE8192: c_int = 1130; - - // See TLSEXT_nid_unknown from tls1.h - openssl-sys does not - // have a constant for this to import. - const TLSEXT_NID_UNKNOWN: c_int = 0x1000000; + // See NID_ML_KEM_* from obj_mac.h - openssl-sys does not have + // constants for these to import. + const NID_ML_KEM_512: c_int = 1454; + const NID_ML_KEM_768: c_int = 1455; + const NID_ML_KEM_1024: c_int = 1456; match group { secp256r1 => Some(NID_X9_62_prime256v1), @@ -146,6 +171,9 @@ pub fn named_group_to_nid(group: NamedGroup) -> Option { FFDHE4096 => Some(NID_FFDHE4096), FFDHE6144 => Some(NID_FFDHE6144), FFDHE8192 => Some(NID_FFDHE8192), + MLKEM512 => Some(NID_ML_KEM_512), + MLKEM768 => Some(NID_ML_KEM_768), + MLKEM1024 => Some(NID_ML_KEM_1024), other => Some(TLSEXT_NID_UNKNOWN | u16::from(other) as c_int), } } diff --git a/src/entry.rs b/src/entry.rs index c751740..9394e92 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -22,7 +22,7 @@ use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer}; use crate::bio::{Bio, BIO, BIO_METHOD}; use crate::callbacks::SslCallbackContext; -use crate::constants::{named_group_to_nid, sig_scheme_to_type_nid}; +use crate::constants::{named_group_to_nid, named_group_to_tls_name, sig_scheme_to_type_nid}; use crate::error::{ffi_panic_boundary, Error, MysteriouslyOppositeReturnValue}; use crate::evp_pkey::EvpPkey; use crate::ex_data::ExData; @@ -1475,6 +1475,22 @@ entry! { } } +entry! { + pub fn _SSL_group_to_name(ssl: *const SSL, id: c_int) -> *const c_char { + try_clone_arc!(ssl) + .get() + .get_groups() + .iter() + .find_map(|group| match named_group_to_nid(group.name()) { + Some(nid) if nid == id => { + named_group_to_tls_name(group.name()).map(|info| info.as_ptr()) + } + _ => None, + }) + .unwrap_or_else(ptr::null) + } +} + entry! { pub fn _SSL_version(ssl: *const SSL) -> c_int { try_clone_arc!(ssl) diff --git a/src/lib.rs b/src/lib.rs index bc381d2..63075d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ use openssl_sys::{ EVP_PKEY, SSL_ERROR_NONE, SSL_ERROR_SSL, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, X509, X509_STORE, X509_V_ERR_UNSPECIFIED, }; + use rustls::client::Resumption; use rustls::crypto::{aws_lc_rs as provider, SupportedKxGroup}; use rustls::pki_types::{CertificateDer, ServerName}; @@ -459,6 +460,7 @@ pub struct SslContext { info_callback: callbacks::InfoCallbackConfig, client_hello_callback: callbacks::ClientHelloCallbackConfig, auth_keys: sign::CertifiedKeySet, + groups: Vec<&'static dyn SupportedKxGroup>, max_early_data: u32, } @@ -491,6 +493,7 @@ impl SslContext { info_callback: callbacks::InfoCallbackConfig::default(), client_hello_callback: callbacks::ClientHelloCallbackConfig::default(), auth_keys: sign::CertifiedKeySet::default(), + groups: provider::default_provider().kx_groups.clone(), max_early_data: 0, } } @@ -521,6 +524,10 @@ impl SslContext { self.raw_options } + fn get_groups(&self) -> &Vec<&'static dyn SupportedKxGroup> { + &self.groups + } + fn get_num_tickets(&self) -> usize { self.num_tickets } @@ -880,6 +887,10 @@ impl Ssl { self.raw_options } + fn get_groups(&self) -> &Vec<&'static dyn SupportedKxGroup> { + self.ctx.get().get_groups() + } + fn get_num_tickets(&self) -> usize { self.num_tickets } diff --git a/tests/constants.c b/tests/constants.c index df08867..97c278c 100644 --- a/tests/constants.c +++ b/tests/constants.c @@ -6,10 +6,41 @@ #include -int main(void) { +void print_group_to_name() { + // secp{256, 384}r1, x25519 + int supported_nids[] = {415, 715, 1034}; + SSL_CTX *ctx = SSL_CTX_new(TLS_method()); + if (!ctx) { + printf("Failed allocating SSL context\n"); + return; + } + SSL *ssl_inst = SSL_new(ctx); + if (!ssl_inst) { + printf("Failed allocating SSL struct\n"); + return; + } + + for (size_t i = 0; i < sizeof(supported_nids) / sizeof(int); i += 1) { + const char *group_name = SSL_group_to_name(ssl_inst, supported_nids[i]); + if (group_name) + printf("%d: '%s'\n", supported_nids[i], group_name); + else + printf("Unknown: %d\n", supported_nids[i]); + } + + SSL_free(ssl_inst); + SSL_CTX_free(ctx); +} + +void print_alert_desc_string() { for (int i = -1; i < 260; i++) { printf("%d: '%s' '%s'\n", i, SSL_alert_desc_string(i), SSL_alert_desc_string_long(i)); } +} + +int main(void) { + print_alert_desc_string(); + print_group_to_name(); return 0; }