net_wire/tls/extensions/
extension.rs1use super::{
2 alpn::{AlpnProtocolList, ServerSelectedAlpn},
3 key_share::{ClientKeyShare, HrrKeyShare, ServerKeyShare},
4 layout::{empty, len, v16},
5 psk::{ClientPreSharedKey, PskKeyExchangeModes, ServerPreSharedKey},
6 scalar_lists::{
7 CertificateCompressionAlgorithms, EcPointFormats, SignatureAlgorithms, SupportedGroups,
8 },
9 server_name::ClientServerNameList,
10 versions::{ClientSupportedVersions, ServerSupportedVersion},
11};
12use crate::tls::{
13 error::TlsParseError,
14 types::{TlsExtensionType, TlsProtocolVersion},
15};
16
17#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct TlsExtension<'a> {
20 extension_type: TlsExtensionType,
21 data: &'a [u8],
22}
23impl<'a> TlsExtension<'a> {
24 pub const fn extension_type(&self) -> TlsExtensionType {
26 self.extension_type
27 }
28 pub const fn data(&self) -> &'a [u8] {
30 self.data
31 }
32 fn ty(&self, t: TlsExtensionType) -> Result<(), TlsParseError> {
33 if self.extension_type == t {
34 Ok(())
35 } else {
36 Err(TlsParseError::InvalidValue)
37 }
38 }
39 pub fn client_server_name_list(&self) -> Result<ClientServerNameList<'a>, TlsParseError> {
41 self.ty(TlsExtensionType::SERVER_NAME)?;
42 ClientServerNameList::parse(self.data)
43 }
44 pub fn server_name_acknowledgement(&self) -> Result<(), TlsParseError> {
46 self.ty(TlsExtensionType::SERVER_NAME)?;
47 empty(self.data)
48 }
49 pub fn alpn_protocol_list(&self) -> Result<AlpnProtocolList<'a>, TlsParseError> {
51 self.ty(TlsExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION)?;
52 AlpnProtocolList::parse(self.data)
53 }
54 pub fn server_selected_alpn(&self) -> Result<ServerSelectedAlpn<'a>, TlsParseError> {
56 self.ty(TlsExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION)?;
57 ServerSelectedAlpn::parse(self.data)
58 }
59 pub fn client_supported_versions(&self) -> Result<ClientSupportedVersions<'a>, TlsParseError> {
61 self.ty(TlsExtensionType::SUPPORTED_VERSIONS)?;
62 ClientSupportedVersions::parse(self.data)
63 }
64 pub fn server_supported_version(&self) -> Result<TlsProtocolVersion, TlsParseError> {
66 Ok(self.server_supported_version_view()?.version())
67 }
68 pub fn server_supported_version_view(&self) -> Result<ServerSupportedVersion, TlsParseError> {
70 self.ty(TlsExtensionType::SUPPORTED_VERSIONS)?;
71 ServerSupportedVersion::parse(self.data)
72 }
73 pub fn supported_groups(&self) -> Result<SupportedGroups<'a>, TlsParseError> {
75 self.ty(TlsExtensionType::SUPPORTED_GROUPS)?;
76 SupportedGroups::parse(self.data)
77 }
78 pub fn signature_algorithms(&self) -> Result<SignatureAlgorithms<'a>, TlsParseError> {
80 self.ty(TlsExtensionType::SIGNATURE_ALGORITHMS)?;
81 SignatureAlgorithms::parse(self.data)
82 }
83 pub fn signature_algorithms_cert(&self) -> Result<SignatureAlgorithms<'a>, TlsParseError> {
85 self.ty(TlsExtensionType::SIGNATURE_ALGORITHMS_CERT)?;
86 SignatureAlgorithms::parse(self.data)
87 }
88 pub fn ec_point_formats(&self) -> Result<EcPointFormats<'a>, TlsParseError> {
90 self.ty(TlsExtensionType::EC_POINT_FORMATS)?;
91 EcPointFormats::parse(self.data)
92 }
93 pub fn client_key_share(&self) -> Result<ClientKeyShare<'a>, TlsParseError> {
95 self.ty(TlsExtensionType::KEY_SHARE)?;
96 ClientKeyShare::parse(self.data)
97 }
98 pub fn server_key_share(&self) -> Result<ServerKeyShare<'a>, TlsParseError> {
100 self.ty(TlsExtensionType::KEY_SHARE)?;
101 ServerKeyShare::parse(self.data)
102 }
103 pub fn hrr_key_share(&self) -> Result<HrrKeyShare, TlsParseError> {
105 self.ty(TlsExtensionType::KEY_SHARE)?;
106 HrrKeyShare::parse(self.data)
107 }
108 pub fn psk_key_exchange_modes(&self) -> Result<PskKeyExchangeModes<'a>, TlsParseError> {
110 self.ty(TlsExtensionType::PSK_KEY_EXCHANGE_MODES)?;
111 PskKeyExchangeModes::parse(self.data)
112 }
113 pub fn client_pre_shared_key(&self) -> Result<ClientPreSharedKey<'a>, TlsParseError> {
115 self.ty(TlsExtensionType::PRE_SHARED_KEY)?;
116 ClientPreSharedKey::parse(self.data)
117 }
118 pub fn server_pre_shared_key(&self) -> Result<ServerPreSharedKey, TlsParseError> {
120 self.ty(TlsExtensionType::PRE_SHARED_KEY)?;
121 ServerPreSharedKey::parse(self.data)
122 }
123 pub fn certificate_compression_algorithms(
125 &self,
126 ) -> Result<CertificateCompressionAlgorithms<'a>, TlsParseError> {
127 self.ty(TlsExtensionType::COMPRESS_CERTIFICATE)?;
128 CertificateCompressionAlgorithms::parse(self.data)
129 }
130 pub fn cookie(&self) -> Result<Cookie<'a>, TlsParseError> {
132 self.ty(TlsExtensionType::COOKIE)?;
133 Cookie::parse(self.data)
134 }
135 pub fn early_data_marker(&self) -> Result<(), TlsParseError> {
137 self.ty(TlsExtensionType::EARLY_DATA)?;
138 empty(self.data)
139 }
140 pub fn early_data_max_size(&self) -> Result<u32, TlsParseError> {
142 self.ty(TlsExtensionType::EARLY_DATA)?;
143 if self.data.len() != 4 {
144 return Err(len(4, self.data.len()));
145 }
146 Ok(u32::from_be_bytes(self.data.try_into().expect("checked")))
147 }
148}
149#[derive(Clone, Debug)]
151pub struct TlsExtensions<'a> {
152 bytes: &'a [u8],
153}
154impl<'a> TlsExtensions<'a> {
155 pub const fn new(bytes: &'a [u8]) -> Self {
159 Self { bytes }
160 }
161}
162impl<'a> Iterator for TlsExtensions<'a> {
163 type Item = Result<TlsExtension<'a>, TlsParseError>;
164 fn next(&mut self) -> Option<Self::Item> {
165 if self.bytes.is_empty() {
166 return None;
167 }
168 let a = self.bytes.len();
169 if a < 4 {
170 self.bytes = &[];
171 return Some(Err(TlsParseError::Incomplete {
172 required: 4,
173 available: a,
174 }));
175 }
176 let n = usize::from(u16::from_be_bytes([self.bytes[2], self.bytes[3]]));
177 let total = 4 + n;
178 if a < total {
179 self.bytes = &[];
180 return Some(Err(TlsParseError::Incomplete {
181 required: total,
182 available: a,
183 }));
184 }
185 let x = TlsExtension {
186 extension_type: TlsExtensionType::new(u16::from_be_bytes([
187 self.bytes[0],
188 self.bytes[1],
189 ])),
190 data: &self.bytes[4..total],
191 };
192 self.bytes = &self.bytes[total..];
193 Some(Ok(x))
194 }
195}
196#[derive(Clone, Copy, Debug, Eq, PartialEq)]
198pub struct Cookie<'a>(&'a [u8]);
199impl<'a> Cookie<'a> {
200 pub(super) fn parse(b: &'a [u8]) -> Result<Self, TlsParseError> {
201 Ok(Self(v16(b, 1, false)?))
202 }
203 pub const fn as_bytes(self) -> &'a [u8] {
205 self.0
206 }
207}