Skip to main content

net_wire/tls/extensions/
psk.rs

1use super::layout::{len, take_v16, v8};
2use crate::tls::{error::TlsParseError, types::TlsPskKeyExchangeMode};
3
4/// Ordered PSK key-exchange modes from a ClientHello.
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct PskKeyExchangeModes<'a> {
7    bytes: &'a [u8],
8}
9impl<'a> PskKeyExchangeModes<'a> {
10    pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
11        Ok(Self { bytes: v8(b, 1)? })
12    }
13    /// Returns modes in their original wire order.
14    pub fn iter(&self) -> impl Iterator<Item = TlsPskKeyExchangeMode> + 'a {
15        self.bytes.iter().copied().map(TlsPskKeyExchangeMode::new)
16    }
17}
18/// Borrowed ClientHello PSK identities and binders.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub struct ClientPreSharedKey<'a> {
21    identities: &'a [u8],
22    binders: &'a [u8],
23}
24impl<'a> ClientPreSharedKey<'a> {
25    pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
26        let (i, rest) = take_v16(b, 7)?;
27        let (x, rest) = take_v16(rest, 33)?;
28        if !rest.is_empty() {
29            return Err(TlsParseError::TrailingBytes);
30        }
31        let identity_count = ids_ok(i)?;
32        let binder_count = binders_ok(x)?;
33        if identity_count != binder_count {
34            return Err(TlsParseError::InvalidValue);
35        }
36        Ok(Self {
37            identities: i,
38            binders: x,
39        })
40    }
41    /// Returns offered PSK identities in wire order.
42    pub fn identities(&self) -> PskIdentityIter<'a> {
43        PskIdentityIter {
44            bytes: self.identities,
45        }
46    }
47    /// Returns PSK binders in wire order.
48    pub fn binders(&self) -> PskBinderIter<'a> {
49        PskBinderIter {
50            bytes: self.binders,
51        }
52    }
53}
54/// One PSK identity and its obfuscated ticket age.
55#[derive(Clone, Copy, Debug, Eq, PartialEq)]
56pub struct PskIdentity<'a> {
57    identity: &'a [u8],
58    age: u32,
59}
60impl<'a> PskIdentity<'a> {
61    /// Returns the opaque identity bytes.
62    pub const fn identity(self) -> &'a [u8] {
63        self.identity
64    }
65    /// Returns the obfuscated ticket age.
66    pub const fn obfuscated_ticket_age(self) -> u32 {
67        self.age
68    }
69}
70/// A fallible iterator over PSK identities.
71#[derive(Clone, Debug)]
72pub struct PskIdentityIter<'a> {
73    bytes: &'a [u8],
74}
75impl<'a> Iterator for PskIdentityIter<'a> {
76    type Item = Result<PskIdentity<'a>, TlsParseError>;
77    fn next(&mut self) -> Option<Self::Item> {
78        if self.bytes.is_empty() {
79            return None;
80        }
81        match id(self.bytes) {
82            Ok((x, n)) => {
83                self.bytes = &self.bytes[n..];
84                Some(Ok(x))
85            }
86            Err(e) => {
87                self.bytes = &[];
88                Some(Err(e))
89            }
90        }
91    }
92}
93fn id(b: &[u8]) -> Result<(PskIdentity<'_>, usize), TlsParseError> {
94    if b.len() < 6 {
95        return Err(TlsParseError::Incomplete {
96            required: 6,
97            available: b.len(),
98        });
99    }
100    let n = usize::from(u16::from_be_bytes([b[0], b[1]]));
101    if n == 0 {
102        return Err(TlsParseError::InvalidValue);
103    }
104    if b.len() < n + 6 {
105        return Err(TlsParseError::Incomplete {
106            required: n + 6,
107            available: b.len(),
108        });
109    }
110    Ok((
111        PskIdentity {
112            identity: &b[2..n + 2],
113            age: u32::from_be_bytes([b[n + 2], b[n + 3], b[n + 4], b[n + 5]]),
114        },
115        n + 6,
116    ))
117}
118fn ids_ok(mut b: &[u8]) -> Result<usize, TlsParseError> {
119    let mut count = 0usize;
120    while !b.is_empty() {
121        let (_, n) = id(b)?;
122        b = &b[n..];
123        count += 1;
124    }
125    Ok(count)
126}
127/// A fallible iterator over PSK binder byte strings.
128#[derive(Clone, Debug)]
129pub struct PskBinderIter<'a> {
130    bytes: &'a [u8],
131}
132impl<'a> Iterator for PskBinderIter<'a> {
133    type Item = Result<&'a [u8], TlsParseError>;
134    fn next(&mut self) -> Option<Self::Item> {
135        if self.bytes.is_empty() {
136            return None;
137        }
138        let n = usize::from(self.bytes[0]);
139        if n < 32 {
140            self.bytes = &[];
141            return Some(Err(TlsParseError::InvalidValue));
142        }
143        if self.bytes.len() < n + 1 {
144            let available = self.bytes.len();
145            self.bytes = &[];
146            return Some(Err(TlsParseError::Incomplete {
147                required: n + 1,
148                available,
149            }));
150        }
151        let x = &self.bytes[1..n + 1];
152        self.bytes = &self.bytes[n + 1..];
153        Some(Ok(x))
154    }
155}
156fn binders_ok(mut b: &[u8]) -> Result<usize, TlsParseError> {
157    let mut count = 0usize;
158    while !b.is_empty() {
159        let n = usize::from(b[0]);
160        if n < 32 {
161            return Err(TlsParseError::InvalidValue);
162        }
163        if b.len() < n + 1 {
164            return Err(TlsParseError::Incomplete {
165                required: n + 1,
166                available: b.len(),
167            });
168        }
169        b = &b[n + 1..];
170        count += 1;
171    }
172    Ok(count)
173}
174/// The PSK identity index selected by a server.
175#[derive(Clone, Copy, Debug, Eq, PartialEq)]
176pub struct ServerPreSharedKey(u16);
177impl ServerPreSharedKey {
178    pub(super) fn parse(b: &[u8]) -> Result<Self, TlsParseError> {
179        if b.len() != 2 {
180            return Err(len(2, b.len()));
181        }
182        Ok(Self(u16::from_be_bytes([b[0], b[1]])))
183    }
184    /// Returns the selected client identity index.
185    pub const fn selected_identity(self) -> u16 {
186        self.0
187    }
188}