net_wire/tls/extensions/
key_share.rs1use super::layout::{len, v16};
2use crate::tls::{error::TlsParseError, types::TlsNamedGroup};
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct ClientKeyShare<'a> {
7 bytes: &'a [u8],
8}
9impl<'a> ClientKeyShare<'a> {
10 pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
11 let x = v16(b, 0, false)?;
12 shares_ok(x)?;
13 Ok(Self { bytes: x })
14 }
15 pub fn iter(&self) -> KeyShareIter<'a> {
17 KeyShareIter { bytes: self.bytes }
18 }
19}
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub struct KeyShareEntry<'a> {
23 group: TlsNamedGroup,
24 key_exchange: &'a [u8],
25}
26impl<'a> KeyShareEntry<'a> {
27 pub const fn group(self) -> TlsNamedGroup {
29 self.group
30 }
31 pub const fn key_exchange(self) -> &'a [u8] {
33 self.key_exchange
34 }
35}
36#[derive(Clone, Debug)]
38pub struct KeyShareIter<'a> {
39 bytes: &'a [u8],
40}
41impl<'a> Iterator for KeyShareIter<'a> {
42 type Item = Result<KeyShareEntry<'a>, TlsParseError>;
43 fn next(&mut self) -> Option<Self::Item> {
44 if self.bytes.is_empty() {
45 return None;
46 }
47 match share(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 share(b: &[u8]) -> Result<(KeyShareEntry<'_>, usize), TlsParseError> {
60 if b.len() < 4 {
61 return Err(TlsParseError::Incomplete {
62 required: 4,
63 available: b.len(),
64 });
65 }
66 let n = usize::from(u16::from_be_bytes([b[2], b[3]]));
67 if n == 0 {
68 return Err(TlsParseError::InvalidValue);
69 }
70 if b.len() < n + 4 {
71 return Err(TlsParseError::Incomplete {
72 required: n + 4,
73 available: b.len(),
74 });
75 }
76 Ok((
77 KeyShareEntry {
78 group: TlsNamedGroup::new(u16::from_be_bytes([b[0], b[1]])),
79 key_exchange: &b[4..n + 4],
80 },
81 n + 4,
82 ))
83}
84fn shares_ok(mut b: &[u8]) -> Result<(), TlsParseError> {
85 while !b.is_empty() {
86 let (_, n) = share(b)?;
87 b = &b[n..]
88 }
89 Ok(())
90}
91#[derive(Clone, Copy, Debug, Eq, PartialEq)]
93pub struct ServerKeyShare<'a>(KeyShareEntry<'a>);
94impl<'a> ServerKeyShare<'a> {
95 pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
96 let (x, n) = share(b)?;
97 if n != b.len() {
98 return Err(TlsParseError::TrailingBytes);
99 }
100 Ok(Self(x))
101 }
102 pub const fn entry(self) -> KeyShareEntry<'a> {
104 self.0
105 }
106}
107#[derive(Clone, Copy, Debug, Eq, PartialEq)]
109pub struct HrrKeyShare(TlsNamedGroup);
110impl HrrKeyShare {
111 pub(super) fn parse(b: &[u8]) -> Result<Self, TlsParseError> {
112 if b.len() != 2 {
113 return Err(len(2, b.len()));
114 }
115 Ok(Self(TlsNamedGroup::new(u16::from_be_bytes([b[0], b[1]]))))
116 }
117 pub const fn group(self) -> TlsNamedGroup {
119 self.0
120 }
121}