1use alloc::vec::Vec;
2use core::convert::TryInto;
3use core::fmt;
4use core::ops::Deref;
5use nom::branch::alt;
6use nom::bytes::streaming::take;
7use nom::combinator::{complete, cond, map, map_parser, opt, verify};
8use nom::error::{make_error, ErrorKind};
9use nom::multi::{length_count, length_data, many0};
10use nom::number::streaming::{be_u16, be_u24, be_u32, be_u8};
11use nom::{Err, IResult};
12use nom_derive::{NomBE, Parse};
13use rusticata_macros::newtype_enum;
14
15use crate::tls_ciphers::*;
16use crate::tls_ec::*;
18use crate::tls_message::TlsMessage;
19
20#[derive(Clone, Copy, PartialEq, Eq, NomBE)]
26pub struct TlsHandshakeType(pub u8);
27
28newtype_enum! {
29impl debug TlsHandshakeType {
30 HelloRequest = 0x00,
31 ClientHello = 0x01,
32 ServerHello = 0x02,
33 HelloVerifyRequest = 0x03,
34 NewSessionTicket = 0x04,
35 EndOfEarlyData = 0x05,
36 HelloRetryRequest = 0x06,
37 EncryptedExtensions = 0x08,
38 Certificate = 0x0b,
39 ServerKeyExchange = 0x0c,
40 CertificateRequest = 0x0d,
41 ServerDone = 0x0e,
42 CertificateVerify = 0x0f,
43 ClientKeyExchange = 0x10,
44 Finished = 0x14,
45 CertificateURL = 0x15,
46 CertificateStatus = 0x16,
47 KeyUpdate = 0x18,
48
49 NextProtocol = 0x43,
50}
51}
52
53impl From<TlsHandshakeType> for u8 {
54 fn from(v: TlsHandshakeType) -> u8 {
55 v.0
56 }
57}
58
59#[derive(Clone, Copy, Default, PartialEq, Eq, NomBE)]
64pub struct TlsVersion(pub u16);
65
66impl TlsVersion {
67 pub const fn to_be_bytes(&self) -> [u8; 2] {
68 self.0.to_be_bytes()
69 }
70}
71
72newtype_enum! {
73impl debug TlsVersion {
74 Ssl30 = 0x0300,
75 Tls10 = 0x0301,
76 Tls11 = 0x0302,
77 Tls12 = 0x0303,
78 Tls13 = 0x0304,
79
80 Tls13Draft18 = 0x7f12,
81 Tls13Draft19 = 0x7f13,
82 Tls13Draft20 = 0x7f14,
83 Tls13Draft21 = 0x7f15,
84 Tls13Draft22 = 0x7f16,
85 Tls13Draft23 = 0x7f17,
86
87 DTls10 = 0xfeff,
88 DTls11 = 0xfefe,
89 DTls12 = 0xfefd,
90}
91}
92
93impl From<TlsVersion> for u16 {
94 fn from(v: TlsVersion) -> u16 {
95 v.0
96 }
97}
98
99impl fmt::LowerHex for TlsVersion {
100 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
101 write!(f, "{:x}", self.0)
102 }
103}
104
105#[derive(Clone, Copy, PartialEq, Eq, NomBE)]
107pub struct TlsHeartbeatMessageType(pub u8);
108
109newtype_enum! {
110impl debug TlsHeartbeatMessageType {
111 HeartBeatRequest = 0x1,
112 HeartBeatResponse = 0x2,
113}
114}
115
116impl From<TlsHeartbeatMessageType> for u8 {
117 fn from(v: TlsHeartbeatMessageType) -> u8 {
118 v.0
119 }
120}
121
122#[derive(Clone, Copy, Default, PartialEq, Eq, NomBE)]
123pub struct TlsCompressionID(pub u8);
124
125newtype_enum! {
126impl debug TlsCompressionID {
127 Null = 0x00,
128 Deflate = 0x01,
129}
130}
131
132impl From<TlsCompressionID> for u8 {
133 fn from(c: TlsCompressionID) -> u8 {
134 c.0
135 }
136}
137
138impl Deref for TlsCompressionID {
139 type Target = u8;
140 fn deref(&self) -> &Self::Target {
141 &self.0
142 }
143}
144
145impl AsRef<u8> for TlsCompressionID {
146 fn as_ref(&self) -> &u8 {
147 &self.0
148 }
149}
150
151#[derive(Clone, Copy, Default, PartialEq, Eq, NomBE)]
152pub struct TlsCipherSuiteID(pub u16);
153
154impl TlsCipherSuiteID {
155 pub fn get_ciphersuite(self) -> Option<&'static TlsCipherSuite> {
156 TlsCipherSuite::from_id(self.0)
157 }
158}
159
160impl From<TlsCipherSuiteID> for u16 {
161 fn from(c: TlsCipherSuiteID) -> u16 {
162 c.0
163 }
164}
165
166impl Deref for TlsCipherSuiteID {
167 type Target = u16;
168 fn deref(&self) -> &Self::Target {
169 &self.0
170 }
171}
172
173impl AsRef<u16> for TlsCipherSuiteID {
174 fn as_ref(&self) -> &u16 {
175 &self.0
176 }
177}
178
179impl fmt::Display for TlsCipherSuiteID {
180 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
181 write!(f, "{}", self.0)
182 }
183}
184
185impl fmt::Debug for TlsCipherSuiteID {
186 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187 match TlsCipherSuite::from_id(self.0) {
188 Some(c) => write!(f, "0x{:04x}({})", self.0, c.name),
189 None => write!(f, "0x{:04x}(Unknown cipher)", self.0),
190 }
191 }
192}
193
194impl fmt::LowerHex for TlsCipherSuiteID {
195 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196 write!(f, "{:x}", self.0)
197 }
198}
199
200pub trait ClientHello<'a> {
202 fn version(&self) -> TlsVersion;
204 fn random(&self) -> &'a [u8];
205 fn rand_time(&self) -> u32 {
207 self.random()
208 .try_into()
209 .map(u32::from_be_bytes)
210 .unwrap_or(0)
211 }
212 fn rand_bytes(&self) -> &'a [u8] {
214 self.random().get(4..).unwrap_or(&[])
215 }
216 fn session_id(&self) -> Option<&'a [u8]>;
217 fn ciphers(&self) -> &Vec<TlsCipherSuiteID>;
219 fn cipher_suites(&self) -> Vec<Option<&'static TlsCipherSuite>> {
220 self.ciphers()
221 .iter()
222 .map(|&x| x.get_ciphersuite())
223 .collect()
224 }
225 fn comp(&self) -> &Vec<TlsCompressionID>;
227 fn ext(&self) -> Option<&'a [u8]>;
228}
229
230#[derive(Clone, PartialEq)]
235pub struct TlsClientHelloContents<'a> {
236 pub version: TlsVersion,
238 pub random: &'a [u8],
239 pub session_id: Option<&'a [u8]>,
240 pub ciphers: Vec<TlsCipherSuiteID>,
242 pub comp: Vec<TlsCompressionID>,
244
245 pub ext: Option<&'a [u8]>,
246}
247
248impl<'a> TlsClientHelloContents<'a> {
249 pub fn new(
250 v: u16,
251 random: &'a [u8],
252 sid: Option<&'a [u8]>,
253 c: Vec<TlsCipherSuiteID>,
254 co: Vec<TlsCompressionID>,
255 e: Option<&'a [u8]>,
256 ) -> Self {
257 TlsClientHelloContents {
258 version: TlsVersion(v),
259 random,
260 session_id: sid,
261 ciphers: c,
262 comp: co,
263 ext: e,
264 }
265 }
266
267 pub fn get_version(&self) -> TlsVersion {
268 self.version
269 }
270
271 pub fn get_ciphers(&self) -> Vec<Option<&'static TlsCipherSuite>> {
272 self.ciphers.iter().map(|&x| x.get_ciphersuite()).collect()
273 }
274}
275
276impl<'a> ClientHello<'a> for TlsClientHelloContents<'a> {
277 fn version(&self) -> TlsVersion {
278 self.version
279 }
280
281 fn random(&self) -> &'a [u8] {
282 self.random
283 }
284
285 fn session_id(&self) -> Option<&'a [u8]> {
286 self.session_id
287 }
288
289 fn ciphers(&self) -> &Vec<TlsCipherSuiteID> {
290 &self.ciphers
291 }
292
293 fn comp(&self) -> &Vec<TlsCompressionID> {
294 &self.comp
295 }
296
297 fn ext(&self) -> Option<&'a [u8]> {
298 self.ext
299 }
300}
301
302#[derive(Clone, PartialEq)]
304pub struct TlsServerHelloContents<'a> {
305 pub version: TlsVersion,
306 pub random: &'a [u8],
307 pub session_id: Option<&'a [u8]>,
308 pub cipher: TlsCipherSuiteID,
309 pub compression: TlsCompressionID,
310
311 pub ext: Option<&'a [u8]>,
312}
313
314#[derive(Clone, PartialEq)]
316pub struct TlsServerHelloV13Draft18Contents<'a> {
317 pub version: TlsVersion,
318 pub random: &'a [u8],
319 pub cipher: TlsCipherSuiteID,
320
321 pub ext: Option<&'a [u8]>,
322}
323
324#[derive(Clone, PartialEq)]
326pub struct TlsHelloRetryRequestContents<'a> {
327 pub version: TlsVersion,
328 pub cipher: TlsCipherSuiteID,
329
330 pub ext: Option<&'a [u8]>,
331}
332
333impl<'a> TlsServerHelloContents<'a> {
334 pub fn new(
335 v: u16,
336 random: &'a [u8],
337 sid: Option<&'a [u8]>,
338 c: u16,
339 co: u8,
340 e: Option<&'a [u8]>,
341 ) -> Self {
342 TlsServerHelloContents {
343 version: TlsVersion(v),
344 random,
345 session_id: sid,
346 cipher: TlsCipherSuiteID(c),
347 compression: TlsCompressionID(co),
348 ext: e,
349 }
350 }
351
352 pub fn get_version(&self) -> TlsVersion {
353 self.version
354 }
355
356 pub fn get_cipher(&self) -> Option<&'static TlsCipherSuite> {
357 self.cipher.get_ciphersuite()
358 }
359}
360
361#[derive(Clone, Debug, PartialEq)]
363pub struct TlsNewSessionTicketContent<'a> {
364 pub ticket_lifetime_hint: u32,
365 pub ticket: &'a [u8],
366}
367
368#[derive(Clone, PartialEq)]
372pub struct RawCertificate<'a> {
373 pub data: &'a [u8],
374}
375
376#[derive(Clone, Debug, PartialEq)]
379pub struct TlsCertificateContents<'a> {
380 pub cert_chain: Vec<RawCertificate<'a>>,
381}
382
383#[derive(Clone, Debug, PartialEq)]
387pub struct TlsCertificateRequestContents<'a> {
388 pub cert_types: Vec<u8>,
389 pub sig_hash_algs: Option<Vec<u16>>,
390 pub unparsed_ca: Vec<&'a [u8]>,
393}
394
395#[derive(Clone, PartialEq)]
400pub struct TlsServerKeyExchangeContents<'a> {
401 pub parameters: &'a [u8],
402}
403
404#[derive(Clone, PartialEq)]
408pub enum TlsClientKeyExchangeContents<'a> {
409 Dh(&'a [u8]),
410 Ecdh(ECPoint<'a>),
411 Unknown(&'a [u8]),
412}
413
414#[derive(Clone, Debug, PartialEq)]
416pub struct TlsCertificateStatusContents<'a> {
417 pub status_type: u8,
418 pub blob: &'a [u8],
419}
420
421#[derive(Clone, Debug, PartialEq)]
424pub struct TlsNextProtocolContent<'a> {
425 pub selected_protocol: &'a [u8],
426 pub padding: &'a [u8],
427}
428
429#[derive(Copy, Clone, PartialEq, Eq)]
431pub struct KeyUpdateRequest(pub u8);
432
433newtype_enum! {
434impl KeyUpdateRequest {
435 NotRequested = 0x0,
436 Requested = 0x1,
437}
438}
439
440#[derive(Clone, Debug, PartialEq)]
442pub enum TlsMessageHandshake<'a> {
443 HelloRequest,
444 ClientHello(TlsClientHelloContents<'a>),
445 ServerHello(TlsServerHelloContents<'a>),
446 ServerHelloV13Draft18(TlsServerHelloV13Draft18Contents<'a>),
447 NewSessionTicket(TlsNewSessionTicketContent<'a>),
448 EndOfEarlyData,
449 HelloRetryRequest(TlsHelloRetryRequestContents<'a>),
450 Certificate(TlsCertificateContents<'a>),
451 ServerKeyExchange(TlsServerKeyExchangeContents<'a>),
452 CertificateRequest(TlsCertificateRequestContents<'a>),
453 ServerDone(&'a [u8]),
454 CertificateVerify(&'a [u8]),
455 ClientKeyExchange(TlsClientKeyExchangeContents<'a>),
456 Finished(&'a [u8]),
457 CertificateStatus(TlsCertificateStatusContents<'a>),
458 NextProtocol(TlsNextProtocolContent<'a>),
459 KeyUpdate(u8),
460}
461
462pub fn parse_tls_handshake_msg_hello_request(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
464 Ok((i, TlsMessageHandshake::HelloRequest))
465}
466
467pub fn parse_tls_handshake_client_hello(i: &[u8]) -> IResult<&[u8], TlsClientHelloContents> {
480 let (i, version) = be_u16(i)?;
481 let (i, random) = take(32usize)(i)?;
482 let (i, sidlen) = verify(be_u8, |&n| n <= 32)(i)?;
483 let (i, sid) = cond(sidlen > 0, take(sidlen as usize))(i)?;
484 let (i, ciphers_len) = be_u16(i)?;
485 let (i, ciphers) = parse_cipher_suites(i, ciphers_len as usize)?;
486 let (i, comp_len) = be_u8(i)?;
487 let (i, comp) = parse_compressions_algs(i, comp_len as usize)?;
488 let (i, ext) = opt(complete(length_data(be_u16)))(i)?;
489 let content = TlsClientHelloContents::new(version, random, sid, ciphers, comp, ext);
490 Ok((i, content))
491}
492
493pub fn parse_tls_handshake_msg_client_hello(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
510 map(
511 parse_tls_handshake_client_hello,
512 TlsMessageHandshake::ClientHello,
513 )(i)
514}
515
516pub(crate) fn parse_cipher_suites(i: &[u8], len: usize) -> IResult<&[u8], Vec<TlsCipherSuiteID>> {
517 if len == 0 {
518 return Ok((i, Vec::new()));
519 }
520 if len % 2 == 1 || len > i.len() {
521 return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
522 }
523 let v = (i[..len])
524 .chunks(2)
525 .map(|chunk| TlsCipherSuiteID((chunk[0] as u16) << 8 | chunk[1] as u16))
526 .collect();
527 Ok((&i[len..], v))
528}
529
530pub(crate) fn parse_compressions_algs(
531 i: &[u8],
532 len: usize,
533) -> IResult<&[u8], Vec<TlsCompressionID>> {
534 if len == 0 {
535 return Ok((i, Vec::new()));
536 }
537 if len > i.len() {
538 return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
539 }
540 let v = (i[..len]).iter().map(|&it| TlsCompressionID(it)).collect();
541 Ok((&i[len..], v))
542}
543
544pub(crate) fn parse_tls_versions(i: &[u8]) -> IResult<&[u8], Vec<TlsVersion>> {
545 let len = i.len();
546 if len == 0 {
547 return Ok((i, Vec::new()));
548 }
549 if len % 2 == 1 || len > i.len() {
550 return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
551 }
552 let v = (i[..len])
553 .chunks(2)
554 .map(|chunk| TlsVersion((chunk[0] as u16) << 8 | chunk[1] as u16))
555 .collect();
556 Ok((&i[len..], v))
557}
558
559fn parse_certs(i: &[u8]) -> IResult<&[u8], Vec<RawCertificate>> {
560 many0(complete(map(length_data(be_u24), |data| RawCertificate {
561 data,
562 })))(i)
563}
564
565fn parse_tls_handshake_msg_server_hello_tlsv12<const HAS_EXT: bool>(
566 i: &[u8],
567) -> IResult<&[u8], TlsMessageHandshake> {
568 map(
569 parse_tls_server_hello_tlsv12::<HAS_EXT>,
570 TlsMessageHandshake::ServerHello,
571 )(i)
572}
573
574pub(crate) fn parse_tls_server_hello_tlsv12<const HAS_EXT: bool>(
575 i: &[u8],
576) -> IResult<&[u8], TlsServerHelloContents> {
577 let (i, version) = be_u16(i)?;
578 let (i, random) = take(32usize)(i)?;
579 let (i, sidlen) = verify(be_u8, |&n| n <= 32)(i)?;
580 let (i, sid) = cond(sidlen > 0, take(sidlen as usize))(i)?;
581 let (i, cipher) = be_u16(i)?;
582 let (i, comp) = be_u8(i)?;
583 let (i, ext) = if HAS_EXT {
584 opt(complete(length_data(be_u16)))(i)?
585 } else {
586 (i, None)
587 };
588 let content = TlsServerHelloContents::new(version, random, sid, cipher, comp, ext);
589 Ok((i, content))
590}
591
592fn parse_tls_handshake_msg_server_hello_tlsv13draft18(
593 i: &[u8],
594) -> IResult<&[u8], TlsMessageHandshake> {
595 let (i, version) = TlsVersion::parse(i)?;
596 let (i, random) = take(32usize)(i)?;
597 let (i, cipher) = map(be_u16, TlsCipherSuiteID)(i)?;
598 let (i, ext) = opt(complete(length_data(be_u16)))(i)?;
599 let content = TlsServerHelloV13Draft18Contents {
600 version,
601 random,
602 cipher,
603 ext,
604 };
605 Ok((i, TlsMessageHandshake::ServerHelloV13Draft18(content)))
606}
607
608pub fn parse_tls_handshake_server_hello(i: &[u8]) -> IResult<&[u8], TlsServerHelloContents> {
621 let (_, version) = be_u16(i)?;
622 match version {
623 0x0303 => parse_tls_server_hello_tlsv12::<true>(i),
624 0x0302 => parse_tls_server_hello_tlsv12::<true>(i),
625 0x0301 => parse_tls_server_hello_tlsv12::<true>(i),
626 0x0300 => parse_tls_server_hello_tlsv12::<false>(i),
627 _ => Err(Err::Error(make_error(i, ErrorKind::Tag))),
628 }
629}
630
631pub fn parse_tls_handshake_msg_server_hello(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
657 let (_, version) = be_u16(i)?;
658 match version {
659 0x7f12 => parse_tls_handshake_msg_server_hello_tlsv13draft18(i),
660 0x0303 => parse_tls_handshake_msg_server_hello_tlsv12::<true>(i),
661 0x0302 => parse_tls_handshake_msg_server_hello_tlsv12::<true>(i),
662 0x0301 => parse_tls_handshake_msg_server_hello_tlsv12::<true>(i),
663 0x0300 => parse_tls_handshake_msg_server_hello_tlsv12::<false>(i),
664 _ => Err(Err::Error(make_error(i, ErrorKind::Tag))),
665 }
666}
667
668pub fn parse_tls_handshake_msg_newsessionticket(
671 i: &[u8],
672 len: usize,
673) -> IResult<&[u8], TlsMessageHandshake> {
674 if len < 4 {
675 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
676 }
677 let (i, ticket_lifetime_hint) = be_u32(i)?;
678 let (i, ticket) = take(len - 4)(i)?;
679 let content = TlsNewSessionTicketContent {
680 ticket_lifetime_hint,
681 ticket,
682 };
683 Ok((i, TlsMessageHandshake::NewSessionTicket(content)))
684}
685
686pub fn parse_tls_handshake_msg_hello_retry_request(
688 i: &[u8],
689) -> IResult<&[u8], TlsMessageHandshake> {
690 let (i, version) = TlsVersion::parse(i)?;
691 let (i, cipher) = map(be_u16, TlsCipherSuiteID)(i)?;
692 let (i, ext) = opt(complete(length_data(be_u16)))(i)?;
693 let content = TlsHelloRetryRequestContents {
694 version,
695 cipher,
696 ext,
697 };
698 Ok((i, TlsMessageHandshake::HelloRetryRequest(content)))
699}
700
701pub(crate) fn parse_tls_certificate(i: &[u8]) -> IResult<&[u8], TlsCertificateContents> {
702 let (i, cert_len) = be_u24(i)?;
703 let (i, cert_chain) = map_parser(take(cert_len as usize), parse_certs)(i)?;
704 let content = TlsCertificateContents { cert_chain };
705 Ok((i, content))
706}
707
708pub fn parse_tls_handshake_msg_certificate(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
710 map(parse_tls_certificate, TlsMessageHandshake::Certificate)(i)
711}
712
713pub fn parse_tls_handshake_msg_serverkeyexchange(
715 i: &[u8],
716 len: usize,
717) -> IResult<&[u8], TlsMessageHandshake> {
718 map(take(len), |ext| {
719 TlsMessageHandshake::ServerKeyExchange(TlsServerKeyExchangeContents { parameters: ext })
720 })(i)
721}
722
723pub fn parse_tls_handshake_msg_serverdone(
725 i: &[u8],
726 len: usize,
727) -> IResult<&[u8], TlsMessageHandshake> {
728 map(take(len), TlsMessageHandshake::ServerDone)(i)
729}
730
731pub fn parse_tls_handshake_msg_certificateverify(
733 i: &[u8],
734 len: usize,
735) -> IResult<&[u8], TlsMessageHandshake> {
736 map(take(len), TlsMessageHandshake::CertificateVerify)(i)
737}
738
739pub(crate) fn parse_tls_clientkeyexchange(
740 len: usize,
741) -> impl FnMut(&[u8]) -> IResult<&[u8], TlsClientKeyExchangeContents> {
742 move |i| map(take(len), TlsClientKeyExchangeContents::Unknown)(i)
743}
744
745pub fn parse_tls_handshake_msg_clientkeyexchange(
750 i: &[u8],
751 len: usize,
752) -> IResult<&[u8], TlsMessageHandshake> {
753 map(
754 parse_tls_clientkeyexchange(len),
755 TlsMessageHandshake::ClientKeyExchange,
756 )(i)
757}
758
759fn parse_certrequest_nosigalg(i: &[u8]) -> IResult<&[u8], TlsCertificateRequestContents> {
760 let (i, cert_types) = length_count(be_u8, be_u8)(i)?;
761 let (i, ca_len) = be_u16(i)?;
762 let (i, unparsed_ca) =
763 map_parser(take(ca_len as usize), many0(complete(length_data(be_u16))))(i)?;
764 let content = TlsCertificateRequestContents {
765 cert_types,
766 sig_hash_algs: None,
768 unparsed_ca,
769 };
770 Ok((i, content))
771}
772
773fn parse_certrequest_full(i: &[u8]) -> IResult<&[u8], TlsCertificateRequestContents> {
774 let (i, cert_types) = length_count(be_u8, be_u8)(i)?;
775 let (i, sig_hash_algs_len) = be_u16(i)?;
776 let (i, sig_hash_algs) =
777 map_parser(take(sig_hash_algs_len as usize), many0(complete(be_u16)))(i)?;
778 let (i, ca_len) = be_u16(i)?;
779 let (i, unparsed_ca) =
780 map_parser(take(ca_len as usize), many0(complete(length_data(be_u16))))(i)?;
781 let content = TlsCertificateRequestContents {
782 cert_types,
783 sig_hash_algs: Some(sig_hash_algs),
784 unparsed_ca,
785 };
786 Ok((i, content))
787}
788
789pub fn parse_tls_handshake_certificaterequest(
791 i: &[u8],
792) -> IResult<&[u8], TlsCertificateRequestContents> {
793 alt((
794 complete(parse_certrequest_full),
795 complete(parse_certrequest_nosigalg),
796 ))(i)
797}
798
799pub fn parse_tls_handshake_msg_certificaterequest(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
801 map(
802 parse_tls_handshake_certificaterequest,
803 TlsMessageHandshake::CertificateRequest,
804 )(i)
805}
806
807pub fn parse_tls_handshake_msg_finished(
809 i: &[u8],
810 len: usize,
811) -> IResult<&[u8], TlsMessageHandshake> {
812 map(take(len), TlsMessageHandshake::Finished)(i)
813}
814
815pub fn parse_tls_handshake_certificatestatus(
821 i: &[u8],
822) -> IResult<&[u8], TlsCertificateStatusContents> {
823 let (i, status_type) = be_u8(i)?;
824 let (i, blob) = length_data(be_u24)(i)?;
825 let content = TlsCertificateStatusContents { status_type, blob };
826 Ok((i, content))
827}
828
829pub fn parse_tls_handshake_msg_certificatestatus(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
835 map(
836 parse_tls_handshake_certificatestatus,
837 TlsMessageHandshake::CertificateStatus,
838 )(i)
839}
840
841pub fn parse_tls_handshake_next_protocol(i: &[u8]) -> IResult<&[u8], TlsNextProtocolContent> {
847 let (i, selected_protocol) = length_data(be_u8)(i)?;
848 let (i, padding) = length_data(be_u8)(i)?;
849 let next_proto = TlsNextProtocolContent {
850 selected_protocol,
851 padding,
852 };
853 Ok((i, next_proto))
854}
855
856pub fn parse_tls_handshake_msg_next_protocol(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
862 map(
863 parse_tls_handshake_next_protocol,
864 TlsMessageHandshake::NextProtocol,
865 )(i)
866}
867
868pub fn parse_tls_handshake_msg_key_update(i: &[u8]) -> IResult<&[u8], TlsMessageHandshake> {
870 map(be_u8, TlsMessageHandshake::KeyUpdate)(i)
871}
872
873pub fn parse_tls_message_handshake(i: &[u8]) -> IResult<&[u8], TlsMessage> {
875 let (i, ht) = be_u8(i)?;
876 let (i, hl) = be_u24(i)?;
877 let (i, raw_msg) = take(hl)(i)?;
878 let (_, msg) = match TlsHandshakeType(ht) {
879 TlsHandshakeType::HelloRequest => parse_tls_handshake_msg_hello_request(raw_msg),
880 TlsHandshakeType::ClientHello => parse_tls_handshake_msg_client_hello(raw_msg),
881 TlsHandshakeType::ServerHello => parse_tls_handshake_msg_server_hello(raw_msg),
882 TlsHandshakeType::NewSessionTicket => {
883 parse_tls_handshake_msg_newsessionticket(raw_msg, hl as usize)
884 }
885 TlsHandshakeType::EndOfEarlyData => Ok((raw_msg, TlsMessageHandshake::EndOfEarlyData)),
886 TlsHandshakeType::HelloRetryRequest => parse_tls_handshake_msg_hello_retry_request(raw_msg),
887 TlsHandshakeType::Certificate => parse_tls_handshake_msg_certificate(raw_msg),
888 TlsHandshakeType::ServerKeyExchange => {
889 parse_tls_handshake_msg_serverkeyexchange(raw_msg, hl as usize)
890 }
891 TlsHandshakeType::CertificateRequest => parse_tls_handshake_msg_certificaterequest(raw_msg),
892 TlsHandshakeType::ServerDone => parse_tls_handshake_msg_serverdone(raw_msg, hl as usize),
893 TlsHandshakeType::CertificateVerify => {
894 parse_tls_handshake_msg_certificateverify(raw_msg, hl as usize)
895 }
896 TlsHandshakeType::ClientKeyExchange => {
897 parse_tls_handshake_msg_clientkeyexchange(raw_msg, hl as usize)
898 }
899 TlsHandshakeType::Finished => parse_tls_handshake_msg_finished(raw_msg, hl as usize),
900 TlsHandshakeType::CertificateStatus => parse_tls_handshake_msg_certificatestatus(raw_msg),
902 TlsHandshakeType::KeyUpdate => parse_tls_handshake_msg_key_update(raw_msg),
903 TlsHandshakeType::NextProtocol => parse_tls_handshake_msg_next_protocol(raw_msg),
904 _ => Err(Err::Error(make_error(i, ErrorKind::Switch))),
905 }?;
906 Ok((i, TlsMessage::Handshake(msg)))
907}