Skip to main content

net_wire/tls/extensions/
scalar_lists.rs

1use super::layout::{v8, v16};
2use crate::tls::{
3    error::TlsParseError,
4    types::{TlsCertificateCompressionAlgorithm, TlsNamedGroup, TlsSignatureScheme},
5};
6
7macro_rules! list {
8    ($n:ident,$t:ty) => {
9        #[doc = concat!("An ordered TLS ", stringify!($n), " vector.")]
10        #[derive(Clone, Copy, Debug, Eq, PartialEq)]
11        pub struct $n<'a> {
12            bytes: &'a [u8],
13        }
14        impl<'a> $n<'a> {
15            pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
16                Ok(Self {
17                    bytes: v16(b, 2, true)?,
18                })
19            }
20            /// Returns values in their original wire order.
21            pub fn iter(&self) -> impl Iterator<Item = $t> + 'a {
22                self.bytes
23                    .chunks_exact(2)
24                    .map(|x| <$t>::new(u16::from_be_bytes([x[0], x[1]])))
25            }
26        }
27    };
28}
29list!(SupportedGroups, TlsNamedGroup);
30list!(SignatureAlgorithms, TlsSignatureScheme);
31/// Ordered certificate-compression algorithm identifiers.
32#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct CertificateCompressionAlgorithms<'a> {
34    bytes: &'a [u8],
35}
36impl<'a> CertificateCompressionAlgorithms<'a> {
37    pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
38        let bytes = v8(b, 2)?;
39        if !bytes.len().is_multiple_of(2) {
40            return Err(TlsParseError::InvalidValue);
41        }
42        Ok(Self { bytes })
43    }
44    /// Returns algorithms in their original wire order.
45    pub fn iter(&self) -> impl Iterator<Item = TlsCertificateCompressionAlgorithm> + 'a {
46        self.bytes.chunks_exact(2).map(|bytes| {
47            TlsCertificateCompressionAlgorithm::new(u16::from_be_bytes([bytes[0], bytes[1]]))
48        })
49    }
50}
51/// Ordered legacy EC point-format identifiers.
52#[derive(Clone, Copy, Debug, Eq, PartialEq)]
53pub struct EcPointFormats<'a> {
54    bytes: &'a [u8],
55}
56impl<'a> EcPointFormats<'a> {
57    pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
58        Ok(Self { bytes: v8(b, 1)? })
59    }
60    /// Returns raw point-format values in wire order.
61    pub fn iter(&self) -> impl Iterator<Item = u8> + 'a {
62        self.bytes.iter().copied()
63    }
64}