net_wire/tls/extensions/
alpn.rs1use super::layout::v16;
2use crate::tls::error::TlsParseError;
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct AlpnProtocol<'a>(&'a [u8]);
7impl<'a> AlpnProtocol<'a> {
8 pub const fn as_bytes(self) -> &'a [u8] {
10 self.0
11 }
12 pub const fn is_grease(self) -> bool {
14 self.0.len() == 2 && self.0[0] == self.0[1] && self.0[0] & 15 == 10
15 }
16}
17#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct AlpnProtocolList<'a> {
20 bytes: &'a [u8],
21}
22impl<'a> AlpnProtocolList<'a> {
23 pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
24 let x = v16(b, 1, false)?;
25 protocols_ok(x)?;
26 Ok(Self { bytes: x })
27 }
28 pub fn iter(&self) -> AlpnProtocolIter<'a> {
30 AlpnProtocolIter { bytes: self.bytes }
31 }
32}
33#[derive(Clone, Debug)]
35pub struct AlpnProtocolIter<'a> {
36 bytes: &'a [u8],
37}
38impl<'a> Iterator for AlpnProtocolIter<'a> {
39 type Item = Result<AlpnProtocol<'a>, TlsParseError>;
40 fn next(&mut self) -> Option<Self::Item> {
41 if self.bytes.is_empty() {
42 return None;
43 }
44 let n = usize::from(self.bytes[0]);
45 if n == 0 {
46 self.bytes = &[];
47 return Some(Err(TlsParseError::InvalidValue));
48 }
49 if self.bytes.len() < n + 1 {
50 let a = self.bytes.len();
51 self.bytes = &[];
52 return Some(Err(TlsParseError::Incomplete {
53 required: n + 1,
54 available: a,
55 }));
56 }
57 let x = AlpnProtocol(&self.bytes[1..n + 1]);
58 self.bytes = &self.bytes[n + 1..];
59 Some(Ok(x))
60 }
61}
62fn protocols_ok(mut b: &[u8]) -> Result<(), TlsParseError> {
63 while !b.is_empty() {
64 let n = usize::from(b[0]);
65 if n == 0 {
66 return Err(TlsParseError::InvalidValue);
67 }
68 if b.len() < n + 1 {
69 return Err(TlsParseError::Incomplete {
70 required: n + 1,
71 available: b.len(),
72 });
73 }
74 b = &b[n + 1..]
75 }
76 Ok(())
77}
78#[derive(Clone, Copy, Debug, Eq, PartialEq)]
80pub struct ServerSelectedAlpn<'a>(AlpnProtocol<'a>);
81impl<'a> ServerSelectedAlpn<'a> {
82 pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
83 let x = AlpnProtocolList::parse(b)?;
84 let mut i = x.iter();
85 let p = i.next().expect("nonempty")?;
86 if i.next().is_some() {
87 return Err(TlsParseError::TrailingBytes);
88 }
89 Ok(Self(p))
90 }
91 pub const fn protocol(self) -> AlpnProtocol<'a> {
93 self.0
94 }
95}