diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fda05..aa1d7d0 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 diff --git a/src/dtls13/message/wrapped.rs b/src/dtls13/message/wrapped.rs index 6d39103..6221d5b 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 36aa598..2fd1a4b 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)); } }