Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
36 changes: 32 additions & 4 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,45 @@ pub fn sig_scheme_to_type_nid(scheme: SignatureScheme) -> Option<c_int> {
}
}

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<c_int> {
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;
const NID_FFDHE3072: c_int = 1127;
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),
Expand All @@ -146,6 +171,9 @@ pub fn named_group_to_nid(group: NamedGroup) -> Option<c_int> {
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),
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1475,6 +1475,22 @@ entry! {
}
}

entry! {
pub fn _SSL_group_to_name(ssl: *const SSL, id: c_int) -> *const c_char {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have something like tests/constants.c that runs through SSL_group_to_name for some supported NIDs and prints the results so we can have a runner.rs test like constants that checks the C program's output is the same linking libssl or rustls-libssl

Copy link
Author

@kraemv kraemv Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the function. I did not add MLKEM nids as they are not implemented in older versions. I also moved the existing functionality to a separate function for a clearer structure.

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)
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down
33 changes: 32 additions & 1 deletion tests/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,41 @@

#include <openssl/ssl.h>

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;
}