From 8adae56ed932312352090de57b34a454f388d879 Mon Sep 17 00:00:00 2001 From: Jeff Hanson Date: Wed, 24 Jun 2026 10:23:56 -0700 Subject: [PATCH 1/2] Omit empty DTLS 1.3 certificate authorities --- src/dtls13/message/wrapped.rs | 10 ++++--- src/dtls13/server.rs | 54 +++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/dtls13/message/wrapped.rs b/src/dtls13/message/wrapped.rs index 6d39103a..6221d5ba 100644 --- a/src/dtls13/message/wrapped.rs +++ b/src/dtls13/message/wrapped.rs @@ -28,13 +28,15 @@ macro_rules! wrapped_slice { Ok((input, $name(start..end))) } - - pub fn as_slice<'a>(&self, buf: &'a [u8]) -> &'a [u8] { - &buf[self.0.clone()] - } } }; } wrapped_slice!(Asn1Cert, be_u24, 0); wrapped_slice!(DistinguishedName, be_u16, 1); + +impl Asn1Cert { + pub fn as_slice<'a>(&self, buf: &'a [u8]) -> &'a [u8] { + &buf[self.0.clone()] + } +} diff --git a/src/dtls13/server.rs b/src/dtls13/server.rs index 36aa5987..2fd1a4b5 100644 --- a/src/dtls13/server.rs +++ b/src/dtls13/server.rs @@ -45,7 +45,6 @@ use crate::dtls13::engine::Engine; use crate::dtls13::message::Body; use crate::dtls13::message::CompressionMethod; use crate::dtls13::message::ContentType; -use crate::dtls13::message::DistinguishedName; use crate::dtls13::message::Dtls13CipherSuite; use crate::dtls13::message::Extension; use crate::dtls13::message::ExtensionType; @@ -1460,16 +1459,6 @@ fn handshake_create_certificate_request(body: &mut Buf) -> Result<(), Error> { extension_data_range: sa_start..sa_end, }); - // certificate_authorities extension (empty list) - let ca_start = ext_buf.len(); - let cas: ArrayVec = ArrayVec::new(); - serialize_certificate_authorities(&cas, &[], &mut ext_buf); - let ca_end = ext_buf.len(); - extensions.push(Extension { - extension_type: ExtensionType::CertificateAuthorities, - extension_data_range: ca_start..ca_end, - }); - // Calculate total extensions length let mut extensions_len = 0usize; for ext in &extensions { @@ -1486,19 +1475,34 @@ fn handshake_create_certificate_request(body: &mut Buf) -> Result<(), Error> { Ok(()) } -/// Serialize a list of DistinguishedNames for the certificate_authorities extension. -/// -/// Format: DistinguishedName<3..2^16-1> (outer length + entries) -fn serialize_certificate_authorities( - cas: &ArrayVec, - buf: &[u8], - output: &mut Buf, -) { - let total_len: usize = cas.iter().map(|dn| 2 + dn.as_slice(buf).len()).sum(); - output.extend_from_slice(&(total_len as u16).to_be_bytes()); - for dn in cas { - let data = dn.as_slice(buf); - output.extend_from_slice(&(data.len() as u16).to_be_bytes()); - output.extend_from_slice(data); +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn certificate_request_omits_empty_certificate_authorities() { + let mut body = Buf::new(); + handshake_create_certificate_request(&mut body).expect("create CertificateRequest"); + + assert_eq!(body[0], 0, "certificate_request_context"); + let ext_len = u16::from_be_bytes([body[1], body[2]]) as usize; + assert_eq!(body.len(), 3 + ext_len); + + let mut extension_types = Vec::new(); + let mut pos = 3; + while pos < body.len() { + assert!(pos + 4 <= body.len()); + let extension_type = + ExtensionType::from_u16(u16::from_be_bytes([body[pos], body[pos + 1]])); + let extension_data_len = u16::from_be_bytes([body[pos + 2], body[pos + 3]]) as usize; + pos += 4; + assert!(pos + extension_data_len <= body.len()); + + extension_types.push(extension_type); + pos += extension_data_len; + } + + assert!(extension_types.contains(&ExtensionType::SignatureAlgorithms)); + assert!(!extension_types.contains(&ExtensionType::CertificateAuthorities)); } } From b24d07429fdaad90fca6fc8625a73e61aac09d77 Mon Sep 17 00:00:00 2001 From: Martin Algesten Date: Fri, 26 Jun 2026 15:59:56 +0200 Subject: [PATCH 2/2] Add changelog entry for certificate authorities fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fda056..aa1d7d04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased + * Omit empty DTLS 1.3 CertificateRequest certificate authorities #153 * Fix DTLS handshake defragmentation across message sequences #151 * Return `BufferTooSmall` instead of panicking on undersized poll buffers #150 * Fix DTLS 1.3 RFC 9147 conformance issues #147