1use crate::tls_ec::{parse_named_groups, NamedGroup};
10use crate::tls_handshake::{parse_tls_versions, TlsCipherSuiteID, TlsVersion};
11use alloc::{vec, vec::Vec};
12use nom::bytes::streaming::{tag, take};
13use nom::combinator::{complete, cond, map, map_parser, opt, verify};
14use nom::error::{make_error, ErrorKind};
15use nom::multi::{length_data, many0};
16use nom::number::streaming::{be_u16, be_u32, be_u8};
17use nom::{Err, IResult};
18use nom_derive::{NomBE, Parse};
19use rusticata_macros::newtype_enum;
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq, NomBE)]
26pub struct TlsExtensionType(pub u16);
27
28newtype_enum! {
29impl display TlsExtensionType {
30 ServerName = 0, MaxFragmentLength = 1,
32 ClientCertificate = 2,
33 TrustedCaKeys = 3,
34 TruncatedHMac = 4,
35 StatusRequest = 5, UserMapping = 6,
37 ClientAuthz = 7,
38 ServerAuthz = 8,
39 CertType = 9,
40 SupportedGroups = 10, EcPointFormats = 11, Srp = 12, SignatureAlgorithms = 13, UseSrtp = 14,
45 Heartbeat = 15, ApplicationLayerProtocolNegotiation = 16, StatusRequestv2 = 17,
48 SignedCertificateTimestamp = 18,
49 ClientCertificateType = 19,
50 ServerCertificateType = 20,
51 Padding = 21, EncryptThenMac = 22, ExtendedMasterSecret = 23, TokenBinding = 24,
55 CachedInfo = 25,
56
57 RecordSizeLimit = 28, SessionTicketTLS = 35,
60
61 KeyShareOld = 40, PreSharedKey = 41, EarlyData = 42, SupportedVersions = 43, Cookie = 44, PskExchangeModes = 45, TicketEarlyDataInfo = 46, CertificateAuthorities = 47,
69 OidFilters = 48, PostHandshakeAuth = 49, SigAlgorithmsCert = 50, KeyShare = 51, NextProtocolNegotiation = 13172,
75
76 Grease = 0xfafa,
77
78 RenegotiationInfo = 0xff01, EncryptedServerName = 0xffce, }
81}
82
83impl TlsExtensionType {
84 pub fn from_u16(t: u16) -> TlsExtensionType {
85 TlsExtensionType(t)
86 }
87}
88
89impl From<TlsExtensionType> for u16 {
90 fn from(ext: TlsExtensionType) -> u16 {
91 ext.0
92 }
93}
94
95#[derive(Clone, PartialEq)]
98pub enum TlsExtension<'a> {
99 SNI(Vec<(SNIType, &'a [u8])>),
100 MaxFragmentLength(u8),
101 StatusRequest(Option<(CertificateStatusType, &'a [u8])>),
102 EllipticCurves(Vec<NamedGroup>),
103 EcPointFormats(&'a [u8]),
104 SignatureAlgorithms(Vec<u16>),
105 RecordSizeLimit(u16),
106 SessionTicket(&'a [u8]),
107 KeyShareOld(&'a [u8]),
108 KeyShare(&'a [u8]),
109 PreSharedKey(&'a [u8]),
110 EarlyData(Option<u32>),
111 SupportedVersions(Vec<TlsVersion>),
112 Cookie(&'a [u8]),
113 PskExchangeModes(Vec<u8>),
114 Heartbeat(u8),
115 ALPN(Vec<&'a [u8]>),
116
117 SignedCertificateTimestamp(Option<&'a [u8]>),
118 Padding(&'a [u8]),
119 EncryptThenMac,
120 ExtendedMasterSecret,
121
122 OidFilters(Vec<OidFilter<'a>>),
123 PostHandshakeAuth,
124
125 NextProtocolNegotiation,
126
127 RenegotiationInfo(&'a [u8]),
128 EncryptedServerName {
129 ciphersuite: TlsCipherSuiteID,
130 group: NamedGroup,
131 key_share: &'a [u8],
132 record_digest: &'a [u8],
133 encrypted_sni: &'a [u8],
134 },
135
136 Grease(u16, &'a [u8]),
137
138 Unknown(TlsExtensionType, &'a [u8]),
139}
140
141impl<'a> From<&'a TlsExtension<'a>> for TlsExtensionType {
142 #[rustfmt::skip]
143 fn from(ext: &TlsExtension) -> TlsExtensionType {
144 match *ext {
145 TlsExtension::SNI(_) => TlsExtensionType::ServerName,
146 TlsExtension::MaxFragmentLength(_) => TlsExtensionType::MaxFragmentLength,
147 TlsExtension::StatusRequest(_) => TlsExtensionType::StatusRequest,
148 TlsExtension::EllipticCurves(_) => TlsExtensionType::SupportedGroups,
149 TlsExtension::EcPointFormats(_) => TlsExtensionType::EcPointFormats,
150 TlsExtension::SignatureAlgorithms(_) => TlsExtensionType::SignatureAlgorithms,
151 TlsExtension::SessionTicket(_) => TlsExtensionType::SessionTicketTLS,
152 TlsExtension::RecordSizeLimit(_) => TlsExtensionType::RecordSizeLimit,
153 TlsExtension::KeyShareOld(_) => TlsExtensionType::KeyShareOld,
154 TlsExtension::KeyShare(_) => TlsExtensionType::KeyShare,
155 TlsExtension::PreSharedKey(_) => TlsExtensionType::PreSharedKey,
156 TlsExtension::EarlyData(_) => TlsExtensionType::EarlyData,
157 TlsExtension::SupportedVersions(_) => TlsExtensionType::SupportedVersions,
158 TlsExtension::Cookie(_) => TlsExtensionType::Cookie,
159 TlsExtension::PskExchangeModes(_) => TlsExtensionType::PskExchangeModes,
160 TlsExtension::Heartbeat(_) => TlsExtensionType::Heartbeat,
161 TlsExtension::ALPN(_) => TlsExtensionType::ApplicationLayerProtocolNegotiation,
162 TlsExtension::SignedCertificateTimestamp(_) => TlsExtensionType::SignedCertificateTimestamp,
163 TlsExtension::Padding(_) => TlsExtensionType::Padding,
164 TlsExtension::EncryptThenMac => TlsExtensionType::EncryptThenMac,
165 TlsExtension::ExtendedMasterSecret => TlsExtensionType::ExtendedMasterSecret,
166 TlsExtension::OidFilters(_) => TlsExtensionType::OidFilters,
167 TlsExtension::PostHandshakeAuth => TlsExtensionType::PostHandshakeAuth,
168 TlsExtension::NextProtocolNegotiation => TlsExtensionType::NextProtocolNegotiation,
169 TlsExtension::RenegotiationInfo(_) => TlsExtensionType::RenegotiationInfo,
170 TlsExtension::EncryptedServerName{..} => TlsExtensionType::EncryptedServerName,
171 TlsExtension::Grease(_,_) => TlsExtensionType::Grease,
172 TlsExtension::Unknown(x,_) => x
173 }
174 }
175}
176
177#[derive(Clone, Debug, PartialEq)]
178pub struct KeyShareEntry<'a> {
179 pub group: NamedGroup, pub kx: &'a [u8], }
182
183#[derive(Clone, Copy, Debug, PartialEq, Eq, NomBE)]
184pub struct PskKeyExchangeMode(pub u8);
185
186newtype_enum! {
187impl PskKeyExchangeMode {
188 Psk = 0,
189 PskDhe = 1,
190}
191}
192
193#[derive(Clone, Copy, Debug, PartialEq, Eq, NomBE)]
194pub struct SNIType(pub u8);
195
196newtype_enum! {
197impl display SNIType {
198 HostName = 0,
199}
200}
201
202#[derive(Clone, Copy, PartialEq, Eq, NomBE)]
203pub struct CertificateStatusType(pub u8);
204
205newtype_enum! {
206impl debug CertificateStatusType {
207 OCSP = 1,
208}
209}
210
211#[derive(Clone, Debug, PartialEq)]
212pub struct OidFilter<'a> {
213 pub cert_ext_oid: &'a [u8],
214 pub cert_ext_val: &'a [u8],
215}
216
217pub fn parse_tls_extension_sni_hostname(i: &[u8]) -> IResult<&[u8], (SNIType, &[u8])> {
230 let (i, t) = SNIType::parse(i)?;
231 let (i, v) = length_data(be_u16)(i)?;
232 Ok((i, (t, v)))
233}
234
235pub fn parse_tls_extension_sni_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
239 if i.is_empty() {
240 return Ok((i, TlsExtension::SNI(Vec::new())));
242 }
243 let (i, list_len) = be_u16(i)?;
244 let (i, v) = map_parser(
245 take(list_len),
246 many0(complete(parse_tls_extension_sni_hostname)),
247 )(i)?;
248 Ok((i, TlsExtension::SNI(v)))
249}
250
251pub fn parse_tls_extension_sni(i: &[u8]) -> IResult<&[u8], TlsExtension> {
252 let (i, _) = tag([0x00, 0x00])(i)?;
253 map_parser(length_data(be_u16), parse_tls_extension_sni_content)(i)
254}
255
256pub fn parse_tls_extension_max_fragment_length_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
258 map(be_u8, TlsExtension::MaxFragmentLength)(i)
259}
260
261pub fn parse_tls_extension_max_fragment_length(i: &[u8]) -> IResult<&[u8], TlsExtension> {
263 let (i, _) = tag([0x00, 0x01])(i)?;
264 map_parser(
265 length_data(be_u16),
266 parse_tls_extension_max_fragment_length_content,
267 )(i)
268}
269
270fn parse_tls_extension_status_request_content(
272 i: &[u8],
273 ext_len: u16,
274) -> IResult<&[u8], TlsExtension> {
275 match ext_len {
276 0 => Ok((i, TlsExtension::StatusRequest(None))),
277 _ => {
278 let (i, status_type) = be_u8(i)?;
279 let (i, request) = take(ext_len - 1)(i)?;
280 Ok((
281 i,
282 TlsExtension::StatusRequest(Some((CertificateStatusType(status_type), request))),
283 ))
284 }
285 }
286}
287
288pub fn parse_tls_extension_status_request(i: &[u8]) -> IResult<&[u8], TlsExtension> {
289 let (i, _) = tag([0x00, 0x05])(i)?;
290 let (i, ext_len) = be_u16(i)?;
291 map_parser(take(ext_len), move |d| {
292 parse_tls_extension_status_request_content(d, ext_len)
293 })(i)
294}
295
296pub fn parse_tls_extension_elliptic_curves_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
298 map_parser(
299 length_data(be_u16),
300 map(parse_named_groups, TlsExtension::EllipticCurves),
301 )(i)
302}
303
304pub fn parse_tls_extension_elliptic_curves(i: &[u8]) -> IResult<&[u8], TlsExtension> {
305 let (i, _) = tag([0x00, 0x0a])(i)?;
306 map_parser(
307 length_data(be_u16),
308 parse_tls_extension_elliptic_curves_content,
309 )(i)
310}
311
312pub fn parse_tls_extension_ec_point_formats_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
313 map(length_data(be_u8), TlsExtension::EcPointFormats)(i)
314}
315
316pub fn parse_tls_extension_ec_point_formats(i: &[u8]) -> IResult<&[u8], TlsExtension> {
317 let (i, _) = tag([0x00, 0x0a])(i)?;
318 map_parser(
319 length_data(be_u16),
320 parse_tls_extension_ec_point_formats_content,
321 )(i)
322}
323
324pub fn parse_tls_extension_signature_algorithms_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
326 let (i, l) = map_parser(length_data(be_u16), many0(complete(be_u16)))(i)?;
327 Ok((i, TlsExtension::SignatureAlgorithms(l))) }
329
330pub fn parse_tls_extension_signature_algorithms(i: &[u8]) -> IResult<&[u8], TlsExtension> {
331 let (i, _) = tag([0x00, 13])(i)?;
332 map_parser(
333 length_data(be_u16),
334 parse_tls_extension_signature_algorithms_content,
335 )(i)
336}
337
338pub fn parse_tls_extension_heartbeat_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
340 map(be_u8, TlsExtension::Heartbeat)(i)
341}
342
343pub fn parse_tls_extension_heartbeat(i: &[u8]) -> IResult<&[u8], TlsExtension> {
344 let (i, _) = tag([0x00, 0x0d])(i)?;
345 let (i, ext_len) = verify(be_u16, |&n| n == 1)(i)?;
346 map_parser(take(ext_len), parse_tls_extension_heartbeat_content)(i)
347}
348
349fn parse_protocol_name(i: &[u8]) -> IResult<&[u8], &[u8]> {
350 length_data(be_u8)(i)
351}
352
353pub fn parse_tls_extension_alpn_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
355 let (i, v) = map_parser(length_data(be_u16), many0(complete(parse_protocol_name)))(i)?;
356 Ok((i, TlsExtension::ALPN(v)))
357}
358
359fn parse_tls_extension_padding_content(i: &[u8], ext_len: u16) -> IResult<&[u8], TlsExtension> {
361 map(take(ext_len), TlsExtension::Padding)(i)
362}
363
364pub fn parse_tls_extension_signed_certificate_timestamp_content(
366 i: &[u8],
367) -> IResult<&[u8], TlsExtension> {
368 map(
369 opt(complete(length_data(be_u16))),
370 TlsExtension::SignedCertificateTimestamp,
371 )(i)
372}
373
374fn parse_tls_extension_encrypt_then_mac_content(
376 i: &[u8],
377 ext_len: u16,
378) -> IResult<&[u8], TlsExtension> {
379 if ext_len != 0 {
380 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
381 }
382 Ok((i, TlsExtension::EncryptThenMac))
383}
384
385pub fn parse_tls_extension_encrypt_then_mac(i: &[u8]) -> IResult<&[u8], TlsExtension> {
387 let (i, _) = tag([0x00, 0x16])(i)?;
388 let (i, ext_len) = be_u16(i)?;
389 map_parser(take(ext_len), move |d| {
390 parse_tls_extension_encrypt_then_mac_content(d, ext_len)
391 })(i)
392}
393
394fn parse_tls_extension_extended_master_secret_content(
396 i: &[u8],
397 ext_len: u16,
398) -> IResult<&[u8], TlsExtension> {
399 if ext_len != 0 {
400 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
401 }
402 Ok((i, TlsExtension::ExtendedMasterSecret))
403}
404
405pub fn parse_tls_extension_extended_master_secret(i: &[u8]) -> IResult<&[u8], TlsExtension> {
407 let (i, _) = tag([0x00, 0x17])(i)?;
408 let (i, ext_len) = be_u16(i)?;
409 map_parser(take(ext_len), move |d| {
410 parse_tls_extension_extended_master_secret_content(d, ext_len)
411 })(i)
412}
413
414fn parse_tls_extension_record_size_limit(i: &[u8]) -> IResult<&[u8], TlsExtension> {
416 map(be_u16, TlsExtension::RecordSizeLimit)(i)
417}
418
419fn parse_tls_extension_session_ticket_content(
420 i: &[u8],
421 ext_len: u16,
422) -> IResult<&[u8], TlsExtension> {
423 map(take(ext_len), TlsExtension::SessionTicket)(i)
424}
425
426pub fn parse_tls_extension_session_ticket(i: &[u8]) -> IResult<&[u8], TlsExtension> {
427 let (i, _) = tag([0x00, 0x23])(i)?;
428 let (i, ext_len) = be_u16(i)?;
429 map_parser(take(ext_len), move |d| {
430 parse_tls_extension_session_ticket_content(d, ext_len)
431 })(i)
432}
433
434fn parse_tls_extension_key_share_old_content(
435 i: &[u8],
436 ext_len: u16,
437) -> IResult<&[u8], TlsExtension> {
438 map(take(ext_len), TlsExtension::KeyShareOld)(i)
439}
440
441fn parse_tls_extension_key_share_content(i: &[u8], ext_len: u16) -> IResult<&[u8], TlsExtension> {
442 map(take(ext_len), TlsExtension::KeyShare)(i)
443}
444
445pub fn parse_tls_extension_key_share(i: &[u8]) -> IResult<&[u8], TlsExtension> {
446 let (i, _) = tag([0x00, 0x33])(i)?;
447 let (i, ext_len) = be_u16(i)?;
448 map_parser(take(ext_len), move |d| {
449 parse_tls_extension_key_share_content(d, ext_len)
450 })(i)
451}
452
453fn parse_tls_extension_pre_shared_key_content(
454 i: &[u8],
455 ext_len: u16,
456) -> IResult<&[u8], TlsExtension> {
457 map(take(ext_len), TlsExtension::PreSharedKey)(i)
458}
459
460pub fn parse_tls_extension_pre_shared_key(i: &[u8]) -> IResult<&[u8], TlsExtension> {
461 let (i, _) = tag([0x00, 0x28])(i)?;
462 let (i, ext_len) = be_u16(i)?;
463 map_parser(take(ext_len), move |d| {
464 parse_tls_extension_pre_shared_key_content(d, ext_len)
465 })(i)
466}
467
468fn parse_tls_extension_early_data_content(i: &[u8], ext_len: u16) -> IResult<&[u8], TlsExtension> {
469 map(cond(ext_len > 0, be_u32), TlsExtension::EarlyData)(i)
470}
471
472pub fn parse_tls_extension_early_data(i: &[u8]) -> IResult<&[u8], TlsExtension> {
473 let (i, _) = tag([0x00, 0x2a])(i)?;
474 let (i, ext_len) = be_u16(i)?;
475 map_parser(take(ext_len), move |d| {
476 parse_tls_extension_early_data_content(d, ext_len)
477 })(i)
478}
479
480fn parse_tls_extension_supported_versions_content(
493 i: &[u8],
494 ext_len: u16,
495) -> IResult<&[u8], TlsExtension> {
496 if ext_len == 2 {
497 map(be_u16, |x| {
498 TlsExtension::SupportedVersions(vec![TlsVersion(x)])
499 })(i)
500 } else {
501 let (i, _) = be_u8(i)?;
502 if ext_len == 0 {
503 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
504 }
505 let (i, l) = map_parser(take(ext_len - 1), parse_tls_versions)(i)?;
506 Ok((i, TlsExtension::SupportedVersions(l)))
507 }
508}
509
510pub fn parse_tls_extension_supported_versions(i: &[u8]) -> IResult<&[u8], TlsExtension> {
511 let (i, _) = tag([0x00, 0x2b])(i)?;
512 let (i, ext_len) = be_u16(i)?;
513 map_parser(take(ext_len), move |d| {
514 parse_tls_extension_supported_versions_content(d, ext_len)
515 })(i)
516}
517
518fn parse_tls_extension_cookie_content(i: &[u8], ext_len: u16) -> IResult<&[u8], TlsExtension> {
519 map(take(ext_len), TlsExtension::Cookie)(i)
520}
521
522pub fn parse_tls_extension_cookie(i: &[u8]) -> IResult<&[u8], TlsExtension> {
523 let (i, _) = tag([0x00, 0x2c])(i)?;
524 let (i, ext_len) = be_u16(i)?;
525 map_parser(take(ext_len), move |d| {
526 parse_tls_extension_cookie_content(d, ext_len)
527 })(i)
528}
529
530pub fn parse_tls_extension_psk_key_exchange_modes_content(
531 i: &[u8],
532) -> IResult<&[u8], TlsExtension> {
533 let (i, v) = length_data(be_u8)(i)?;
534 Ok((i, TlsExtension::PskExchangeModes(v.to_vec())))
535}
536
537pub fn parse_tls_extension_psk_key_exchange_modes(i: &[u8]) -> IResult<&[u8], TlsExtension> {
538 let (i, _) = tag([0x00, 0x2d])(i)?;
539 let (i, ext_len) = be_u16(i)?;
540 map_parser(
541 take(ext_len),
542 parse_tls_extension_psk_key_exchange_modes_content,
543 )(i)
544}
545
546fn parse_tls_extension_npn_content(i: &[u8], ext_len: u16) -> IResult<&[u8], TlsExtension> {
548 if ext_len != 0 {
549 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
550 }
551 Ok((i, TlsExtension::NextProtocolNegotiation))
552}
553
554pub fn parse_tls_extension_renegotiation_info_content(i: &[u8]) -> IResult<&[u8], TlsExtension> {
556 map(length_data(be_u8), TlsExtension::RenegotiationInfo)(i)
557}
558
559pub fn parse_tls_extension_encrypted_server_name(i: &[u8]) -> IResult<&[u8], TlsExtension> {
561 let (i, ciphersuite) = map(be_u16, TlsCipherSuiteID)(i)?;
562 let (i, group) = NamedGroup::parse(i)?;
563 let (i, key_share) = length_data(be_u16)(i)?;
564 let (i, record_digest) = length_data(be_u16)(i)?;
565 let (i, encrypted_sni) = length_data(be_u16)(i)?;
566 let esn = TlsExtension::EncryptedServerName {
567 ciphersuite,
568 group,
569 key_share,
570 record_digest,
571 encrypted_sni,
572 };
573 Ok((i, esn))
574}
575
576fn parse_tls_oid_filter(i: &[u8]) -> IResult<&[u8], OidFilter> {
577 let (i, cert_ext_oid) = length_data(be_u8)(i)?;
578 let (i, cert_ext_val) = length_data(be_u16)(i)?;
579 let filter = OidFilter {
580 cert_ext_oid,
581 cert_ext_val,
582 };
583 Ok((i, filter))
584}
585
586fn parse_tls_extension_oid_filters(i: &[u8]) -> IResult<&[u8], TlsExtension> {
588 let (i, v) = map_parser(length_data(be_u16), many0(complete(parse_tls_oid_filter)))(i)?;
589 Ok((i, TlsExtension::OidFilters(v)))
590}
591
592fn parse_tls_extension_post_handshake_auth_content(
594 i: &[u8],
595 ext_len: u16,
596) -> IResult<&[u8], TlsExtension> {
597 if ext_len != 0 {
598 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
599 }
600 Ok((i, TlsExtension::PostHandshakeAuth))
601}
602
603pub fn parse_tls_extension_unknown(i: &[u8]) -> IResult<&[u8], TlsExtension> {
604 let (i, ext_type) = be_u16(i)?;
605 let (i, ext_data) = length_data(be_u16)(i)?;
606 Ok((
607 i,
608 TlsExtension::Unknown(TlsExtensionType(ext_type), ext_data),
609 ))
610}
611
612pub fn parse_tls_client_hello_extension(i: &[u8]) -> IResult<&[u8], TlsExtension> {
614 let (i, ext_type) = be_u16(i)?;
615 let (i, ext_data) = length_data(be_u16)(i)?;
616 if ext_type & 0x0f0f == 0x0a0a {
617 return Ok((i, TlsExtension::Grease(ext_type, ext_data)));
618 }
619 let ext_len = ext_data.len() as u16;
620 let (_, ext) = match ext_type {
621 0 => parse_tls_extension_sni_content(ext_data),
622 1 => parse_tls_extension_max_fragment_length_content(ext_data),
623 5 => parse_tls_extension_status_request_content(ext_data, ext_len),
624 10 => parse_tls_extension_elliptic_curves_content(ext_data),
625 11 => parse_tls_extension_ec_point_formats_content(ext_data),
626 13 => parse_tls_extension_signature_algorithms_content(ext_data),
627 15 => parse_tls_extension_heartbeat_content(ext_data),
628 16 => parse_tls_extension_alpn_content(ext_data),
629 18 => parse_tls_extension_signed_certificate_timestamp_content(ext_data), 21 => parse_tls_extension_padding_content(ext_data, ext_len),
631 22 => parse_tls_extension_encrypt_then_mac_content(ext_data, ext_len),
632 23 => parse_tls_extension_extended_master_secret_content(ext_data, ext_len),
633 28 => parse_tls_extension_record_size_limit(ext_data),
634 35 => parse_tls_extension_session_ticket_content(ext_data, ext_len),
635 41 => parse_tls_extension_pre_shared_key_content(ext_data, ext_len),
636 42 => parse_tls_extension_early_data_content(ext_data, ext_len),
637 43 => parse_tls_extension_supported_versions_content(ext_data, ext_len),
638 44 => parse_tls_extension_cookie_content(ext_data, ext_len),
639 45 => parse_tls_extension_psk_key_exchange_modes_content(ext_data),
640 48 => parse_tls_extension_oid_filters(ext_data),
641 49 => parse_tls_extension_post_handshake_auth_content(ext_data, ext_len),
642 51 => parse_tls_extension_key_share_content(ext_data, ext_len), 13172 => parse_tls_extension_npn_content(ext_data, ext_len), 0xff01 => parse_tls_extension_renegotiation_info_content(ext_data),
645 0xffce => parse_tls_extension_encrypted_server_name(ext_data),
646 _ => Ok((
647 i,
648 TlsExtension::Unknown(TlsExtensionType(ext_type), ext_data),
649 )),
650 }?;
651 Ok((i, ext))
652}
653
654pub fn parse_tls_server_hello_extension(i: &[u8]) -> IResult<&[u8], TlsExtension> {
656 let (i, ext_type) = be_u16(i)?;
657 let (i, ext_data) = length_data(be_u16)(i)?;
658 if ext_type & 0x0f0f == 0x0a0a {
659 return Ok((i, TlsExtension::Grease(ext_type, ext_data)));
660 }
661 let ext_len = ext_data.len() as u16;
662 let (_, ext) = match ext_type {
663 0 => parse_tls_extension_sni_content(ext_data), 1 => parse_tls_extension_max_fragment_length_content(ext_data),
665 5 => parse_tls_extension_status_request_content(ext_data, ext_len), 11 => parse_tls_extension_ec_point_formats_content(ext_data), 13 => parse_tls_extension_signature_algorithms_content(ext_data), 15 => parse_tls_extension_heartbeat_content(ext_data),
669 16 => parse_tls_extension_alpn_content(ext_data), 18 => parse_tls_extension_signed_certificate_timestamp_content(ext_data),
671 21 => parse_tls_extension_encrypt_then_mac_content(ext_data, ext_len),
672 23 => parse_tls_extension_extended_master_secret_content(ext_data, ext_len),
673 28 => parse_tls_extension_record_size_limit(ext_data),
674 35 => parse_tls_extension_session_ticket_content(ext_data, ext_len),
675 41 => parse_tls_extension_pre_shared_key_content(ext_data, ext_len),
676 42 => parse_tls_extension_early_data_content(ext_data, ext_len),
677 43 => parse_tls_extension_supported_versions_content(ext_data, ext_len), 44 => parse_tls_extension_cookie_content(ext_data, ext_len),
679 51 => parse_tls_extension_key_share_content(ext_data, ext_len), 13172 => parse_tls_extension_npn_content(ext_data, ext_len),
681 0xff01 => parse_tls_extension_renegotiation_info_content(ext_data),
682 _ => Ok((
683 i,
684 TlsExtension::Unknown(TlsExtensionType(ext_type), ext_data),
685 )),
686 }?;
687 Ok((i, ext))
688}
689
690pub fn parse_tls_extension(i: &[u8]) -> IResult<&[u8], TlsExtension> {
692 let (i, ext_type) = be_u16(i)?;
693 let (i, ext_data) = length_data(be_u16)(i)?;
694 if ext_type & 0x0f0f == 0x0a0a {
695 return Ok((i, TlsExtension::Grease(ext_type, ext_data)));
696 }
697 let ext_len = ext_data.len() as u16;
698 let (_, ext) = match ext_type {
699 0 => parse_tls_extension_sni_content(ext_data),
700 1 => parse_tls_extension_max_fragment_length_content(ext_data),
701 5 => parse_tls_extension_status_request_content(ext_data, ext_len),
702 10 => parse_tls_extension_elliptic_curves_content(ext_data),
703 11 => parse_tls_extension_ec_point_formats_content(ext_data),
704 13 => parse_tls_extension_signature_algorithms_content(ext_data),
705 15 => parse_tls_extension_heartbeat_content(ext_data),
706 16 => parse_tls_extension_alpn_content(ext_data),
707 18 => parse_tls_extension_signed_certificate_timestamp_content(ext_data),
708 21 => parse_tls_extension_padding_content(ext_data, ext_len),
709 22 => parse_tls_extension_encrypt_then_mac_content(ext_data, ext_len),
710 23 => parse_tls_extension_extended_master_secret_content(ext_data, ext_len),
711 28 => parse_tls_extension_record_size_limit(ext_data),
712 35 => parse_tls_extension_session_ticket_content(ext_data, ext_len),
713 40 => parse_tls_extension_key_share_old_content(ext_data, ext_len),
714 41 => parse_tls_extension_pre_shared_key_content(ext_data, ext_len),
715 42 => parse_tls_extension_early_data_content(ext_data, ext_len),
716 43 => parse_tls_extension_supported_versions_content(ext_data, ext_len),
717 44 => parse_tls_extension_cookie_content(ext_data, ext_len),
718 45 => parse_tls_extension_psk_key_exchange_modes_content(ext_data),
719 48 => parse_tls_extension_oid_filters(ext_data),
720 49 => parse_tls_extension_post_handshake_auth_content(ext_data, ext_len),
721 51 => parse_tls_extension_key_share_content(ext_data, ext_len),
722 13172 => parse_tls_extension_npn_content(ext_data, ext_len),
723 0xff01 => parse_tls_extension_renegotiation_info_content(ext_data),
724 0xffce => parse_tls_extension_encrypted_server_name(ext_data),
725 _ => Ok((
726 i,
727 TlsExtension::Unknown(TlsExtensionType(ext_type), ext_data),
728 )),
729 }?;
730 Ok((i, ext))
731}
732
733pub fn parse_tls_client_hello_extensions(i: &[u8]) -> IResult<&[u8], Vec<TlsExtension>> {
735 many0(complete(parse_tls_client_hello_extension))(i)
736}
737
738pub fn parse_tls_server_hello_extensions(i: &[u8]) -> IResult<&[u8], Vec<TlsExtension>> {
740 many0(complete(parse_tls_server_hello_extension))(i)
741}
742
743pub fn parse_tls_extensions(i: &[u8]) -> IResult<&[u8], Vec<TlsExtension>> {
745 many0(complete(parse_tls_extension))(i)
746}