Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 11 additions & 4 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,21 @@ pub fn sig_scheme_to_type_nid(scheme: SignatureScheme) -> Option<c_int> {
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 +150,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
14 changes: 14 additions & 0 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,20 @@ 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(|group| named_group_to_nid(group.name()) == Some(id))
.map(|group| group.name())
.and_then(crate::TlsGroupInfo::find_by_id)
.map(|group| group.tls_name.as_ptr())
.unwrap_or_else(ptr::null)
}
}

entry! {
pub fn _SSL_version(ssl: *const SSL) -> c_int {
try_clone_arc!(ssl)
Expand Down
166 changes: 164 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ 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};
use rustls::server::{Accepted, Acceptor, ProducesTickets};
use rustls::{
AlertDescription, CipherSuite, ClientConfig, ClientConnection, Connection, HandshakeKind,
ProtocolVersion, ServerConfig, SignatureScheme, SupportedProtocolVersion,
NamedGroup, ProtocolVersion, ServerConfig, SignatureScheme, SupportedProtocolVersion,
};

use not_thread_safe::NotThreadSafe;
Expand Down Expand Up @@ -239,6 +240,158 @@ static TLS13_CHACHA20_POLY1305_SHA256: SslCipher = SslCipher {
description: c"TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD\n",
};

#[allow(dead_code)]
struct TlsGroupInfo {
pub tls_name: &'static CStr,
pub standard_name: &'static CStr,
pub algorithm: &'static CStr,
pub secbits: usize,
pub group_id: NamedGroup,
}

impl TlsGroupInfo {
pub fn find_by_id(id: NamedGroup) -> Option<&'static Self> {
match id {
NamedGroup::secp256r1 => Some(&SECP256R1),
NamedGroup::secp384r1 => Some(&SECP384R1),
NamedGroup::secp521r1 => Some(&SECP521R1),
NamedGroup::X25519 => Some(&X25519),
NamedGroup::X448 => Some(&X448),
NamedGroup::FFDHE2048 => Some(&FFDHE2048),
NamedGroup::FFDHE3072 => Some(&FFDHE3072),
NamedGroup::FFDHE4096 => Some(&FFDHE4096),
NamedGroup::FFDHE6144 => Some(&FFDHE6144),
NamedGroup::FFDHE8192 => Some(&FFDHE8192),
NamedGroup::MLKEM512 => Some(&MLKEM512),
NamedGroup::MLKEM768 => Some(&MLKEM768),
NamedGroup::MLKEM1024 => Some(&MLKEM1024),
NamedGroup::X25519MLKEM768 => Some(&X25519MLKEM768),
NamedGroup::secp256r1MLKEM768 => Some(&SECP256R1_MLKEM768),
_ => None,
}
}
}

static SECP256R1: TlsGroupInfo = TlsGroupInfo {
tls_name: c"secp256r1",
standard_name: c"prime256v1",
algorithm: c"EC",
secbits: 128,
group_id: NamedGroup::secp256r1,
};

static SECP384R1: TlsGroupInfo = TlsGroupInfo {
tls_name: c"secp384r1",
standard_name: c"secp384r1",
algorithm: c"EC",
secbits: 192,
group_id: NamedGroup::secp384r1,
};

static SECP521R1: TlsGroupInfo = TlsGroupInfo {
tls_name: c"secp521r1",
standard_name: c"secp521r1",
algorithm: c"EC",
secbits: 256,
group_id: NamedGroup::secp521r1,
};

static X25519: TlsGroupInfo = TlsGroupInfo {
tls_name: c"x25519",
standard_name: c"X25519",
algorithm: c"X25519",
secbits: 128,
group_id: NamedGroup::X25519,
};

static X448: TlsGroupInfo = TlsGroupInfo {
tls_name: c"x448",
standard_name: c"X448",
algorithm: c"X448",
secbits: 224,
group_id: NamedGroup::X448,
};

static FFDHE2048: TlsGroupInfo = TlsGroupInfo {
tls_name: c"ffdhe2048",
standard_name: c"ffdhe2048",
algorithm: c"DH",
secbits: 112,
group_id: NamedGroup::FFDHE2048,
};

static FFDHE3072: TlsGroupInfo = TlsGroupInfo {
tls_name: c"ffdhe3072",
standard_name: c"ffdhe3072",
algorithm: c"DH",
secbits: 128,
group_id: NamedGroup::FFDHE3072,
};

static FFDHE4096: TlsGroupInfo = TlsGroupInfo {
tls_name: c"ffdhe4096",
standard_name: c"ffdhe4096",
algorithm: c"DH",
secbits: 128,
group_id: NamedGroup::FFDHE4096,
};

static FFDHE6144: TlsGroupInfo = TlsGroupInfo {
tls_name: c"ffdhe6144",
standard_name: c"ffdhe6144",
algorithm: c"DH",
secbits: 128,
group_id: NamedGroup::FFDHE6144,
};

static FFDHE8192: TlsGroupInfo = TlsGroupInfo {
tls_name: c"ffdhe8192",
standard_name: c"ffdhe8192",
algorithm: c"DH",
secbits: 192,
group_id: NamedGroup::FFDHE8192,
};

static MLKEM512: TlsGroupInfo = TlsGroupInfo {
tls_name: c"MLKEM512",
standard_name: c"",
algorithm: c"ML-KEM-512",
secbits: 128,
group_id: NamedGroup::MLKEM512,
};

static MLKEM768: TlsGroupInfo = TlsGroupInfo {
tls_name: c"MLKEM768",
standard_name: c"",
algorithm: c"ML-KEM-768",
secbits: 192,
group_id: NamedGroup::MLKEM768,
};

static MLKEM1024: TlsGroupInfo = TlsGroupInfo {
tls_name: c"MLKEM1024",
standard_name: c"",
algorithm: c"ML-KEM-1024",
secbits: 256,
group_id: NamedGroup::MLKEM1024,
};

static X25519MLKEM768: TlsGroupInfo = TlsGroupInfo {
tls_name: c"X25519MLKEM768",
standard_name: c"",
algorithm: c"X25519MLKEM768",
secbits: 192,
group_id: NamedGroup::X25519MLKEM768,
};

static SECP256R1_MLKEM768: TlsGroupInfo = TlsGroupInfo {
tls_name: c"SecP256r1MLKEM768",
standard_name: c"",
algorithm: c"SecP256r1MLKEM768",
secbits: 192,
group_id: NamedGroup::secp256r1MLKEM768,
};

/// Backs a server-side SSL_SESSION object
///
/// Note that this has equality and ordering entirely based on the `id` field.
Expand Down Expand Up @@ -459,6 +612,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 +645,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 +676,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 +1039,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 Expand Up @@ -1098,7 +1261,6 @@ impl Ssl {
if let ConnMode::Unknown = self.mode {
self.set_client_mode();
}

if matches!(self.conn, ConnState::Nothing) {
self.init_client_conn()?;
}
Expand Down