use super::*;
impl Connection {
pub fn noxtls_build_server_hello_with_key_share(
version: TlsVersion,
suite: CipherSuite,
random: &[u8],
named_group: u16,
key_exchange: &[u8],
legacy_session_id_echo: Option<&[u8]>,
) -> Result<Vec<u8>> {
if random.len() != 32 {
return Err(Error::InvalidLength("server hello random must be 32 bytes"));
}
let body = noxtls_encode_server_hello_body_with_key_share(
version,
suite,
random,
Some((named_group, key_exchange)),
legacy_session_id_echo,
None,
)?;
Ok(noxtls_encode_handshake_message(
HANDSHAKE_SERVER_HELLO,
&body,
))
}
pub(super) fn noxtls_validate_tls13_hrr_retry_group_support(&self) -> Result<()> {
if !self.version.uses_tls13_handshake_semantics() || !self.tls13_hrr_seen {
return Ok(());
}
let requested_group = self.tls13_hrr_requested_group.ok_or(Error::ParseFailure(
"hello retry request is missing requested key_share group",
))?;
if !crate::protocol::keyshare::noxtls_tls13_key_share_group_supported(requested_group) {
return Err(Error::StateError(
"hello retry request requested unsupported key_share group",
));
}
Ok(())
}
pub(super) fn noxtls_prepare_client_key_share(
&mut self,
random: &[u8],
) -> Result<Tls13ClientPublicKeyShares> {
if !self.version.uses_tls13_handshake_semantics() {
return Ok(Tls13ClientPublicKeyShares::default());
}
let x25519_private =
noxtls_derive_deterministic_x25519_private(random, b"tls13 client x25519");
let x25519_public = x25519_private.clone().public_key().bytes;
noxtls_tls13_debug_log_bytes(
"tls13.client_key_share.x25519_private",
&x25519_private.to_bytes(),
);
noxtls_tls13_debug_log_bytes("tls13.client_key_share.x25519_public", &x25519_public);
self.tls13_client_x25519_private = Some(x25519_private);
let p256_private =
noxtls_derive_deterministic_p256_private(random, b"tls13 client secp256r1")?;
let p256_public = p256_private.public_key()?.to_uncompressed()?;
self.tls13_client_p256_private = Some(p256_private);
let mut mlkem_public = None;
let mut hybrid_public = None;
if self.tls13_client_offer_pq_key_shares {
let (mlkem_private, mlkem_pub) =
noxtls_derive_deterministic_mlkem768_keypair(random, b"tls13 client mlkem768")?;
self.tls13_client_mlkem768_private = Some(mlkem_private);
let mlkem_pub = mlkem_pub.as_bytes().to_vec();
let mut hybrid_pub = Vec::with_capacity(32 + mlkem_pub.len());
hybrid_pub.extend_from_slice(&mlkem_pub);
hybrid_pub.extend_from_slice(&x25519_public);
mlkem_public = Some(mlkem_pub);
hybrid_public = Some(hybrid_pub);
} else {
self.tls13_client_mlkem768_private = None;
}
Ok(Tls13ClientPublicKeyShares {
x25519: Some(x25519_public),
secp256r1_uncompressed: Some(p256_public),
mlkem768: mlkem_public,
x25519_mlkem768_hybrid: hybrid_public,
})
}
}
pub(super) fn noxtls_combine_tls13_hybrid_shared_secret(classical: &[u8], pq: &[u8]) -> Vec<u8> {
[pq, classical].concat()
}