Skip to main content

net_wire/tls/extensions/
server_name.rs

1use super::layout::v16;
2use crate::tls::{error::TlsParseError, types::TlsServerNameType};
3
4/// An ordered ClientHello server-name list.
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct ClientServerNameList<'a> {
7    bytes: &'a [u8],
8}
9impl<'a> ClientServerNameList<'a> {
10    pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
11        let x = v16(b, 1, false)?;
12        names_ok(x)?;
13        Ok(Self { bytes: x })
14    }
15    /// Returns server names in their original wire order.
16    pub fn iter(&self) -> ServerNameIter<'a> {
17        ServerNameIter { bytes: self.bytes }
18    }
19}
20/// One raw-preserving server-name entry.
21#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub struct ServerName<'a> {
23    name_type: TlsServerNameType,
24    name: &'a [u8],
25}
26impl<'a> ServerName<'a> {
27    /// Returns the raw server-name type.
28    pub const fn name_type(self) -> TlsServerNameType {
29        self.name_type
30    }
31    /// Returns the encoded name bytes.
32    pub const fn as_bytes(self) -> &'a [u8] {
33        self.name
34    }
35}
36/// A fallible iterator over server-name entries.
37#[derive(Clone, Debug)]
38pub struct ServerNameIter<'a> {
39    bytes: &'a [u8],
40}
41impl<'a> Iterator for ServerNameIter<'a> {
42    type Item = Result<ServerName<'a>, TlsParseError>;
43    fn next(&mut self) -> Option<Self::Item> {
44        if self.bytes.is_empty() {
45            return None;
46        }
47        match name(self.bytes) {
48            Ok((x, n)) => {
49                self.bytes = &self.bytes[n..];
50                Some(Ok(x))
51            }
52            Err(e) => {
53                self.bytes = &[];
54                Some(Err(e))
55            }
56        }
57    }
58}
59fn name(b: &[u8]) -> Result<(ServerName<'_>, usize), TlsParseError> {
60    if b.len() < 3 {
61        return Err(TlsParseError::Incomplete {
62            required: 3,
63            available: b.len(),
64        });
65    }
66    let n = usize::from(u16::from_be_bytes([b[1], b[2]]));
67    if n == 0 {
68        return Err(TlsParseError::InvalidValue);
69    }
70    if b.len() < 3 + n {
71        return Err(TlsParseError::Incomplete {
72            required: 3 + n,
73            available: b.len(),
74        });
75    }
76    Ok((
77        ServerName {
78            name_type: TlsServerNameType::new(b[0]),
79            name: &b[3..3 + n],
80        },
81        3 + n,
82    ))
83}
84fn names_ok(mut b: &[u8]) -> Result<(), TlsParseError> {
85    while !b.is_empty() {
86        let (_, n) = name(b)?;
87        b = &b[n..]
88    }
89    Ok(())
90}