tls_parser/
tls_message.rs1use alloc::{vec, vec::Vec};
2use nom::bytes::streaming::take;
3use nom::combinator::verify;
4use nom::error::{make_error, ErrorKind};
5use nom::number::streaming::{be_u16, be_u8};
6use nom::{Err, IResult};
7use nom_derive::Parse;
8
9use crate::tls_alert::*;
10use crate::tls_handshake::*;
11
12#[derive(Clone, Debug, PartialEq)]
16pub enum TlsMessage<'a> {
17 Handshake(TlsMessageHandshake<'a>),
18 ChangeCipherSpec,
19 Alert(TlsMessageAlert),
20 ApplicationData(TlsMessageApplicationData<'a>),
21 Heartbeat(TlsMessageHeartbeat<'a>),
22}
23
24#[derive(Clone, Debug, PartialEq)]
29pub struct TlsMessageApplicationData<'a> {
30 pub blob: &'a [u8],
31}
32
33#[derive(Clone, Debug, PartialEq)]
38pub struct TlsMessageHeartbeat<'a> {
39 pub heartbeat_type: TlsHeartbeatMessageType,
40 pub payload_len: u16,
41 pub payload: &'a [u8],
42}
43
44pub fn parse_tls_message_changecipherspec(i: &[u8]) -> IResult<&[u8], TlsMessage> {
47 let (i, _) = verify(be_u8, |&tag| tag == 0x01)(i)?;
48 Ok((i, TlsMessage::ChangeCipherSpec))
49}
50
51pub fn parse_tls_message_alert(i: &[u8]) -> IResult<&[u8], TlsMessage> {
54 let (i, alert) = TlsMessageAlert::parse(i)?;
55 Ok((i, TlsMessage::Alert(alert)))
56}
57
58pub fn parse_tls_message_applicationdata(i: &[u8]) -> IResult<&[u8], TlsMessage> {
62 let msg = TlsMessage::ApplicationData(TlsMessageApplicationData { blob: i });
63 Ok((&[], msg))
64}
65
66pub fn parse_tls_message_heartbeat(
68 i: &[u8],
69 tls_plaintext_len: u16,
70) -> IResult<&[u8], Vec<TlsMessage>> {
71 let (i, heartbeat_type) = TlsHeartbeatMessageType::parse(i)?;
72 let (i, payload_len) = be_u16(i)?;
73 if tls_plaintext_len < 3 {
74 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
75 }
76 let (i, payload) = take(payload_len as usize)(i)?;
77 let v = vec![TlsMessage::Heartbeat(TlsMessageHeartbeat {
78 heartbeat_type,
79 payload_len,
80 payload,
81 })];
82 Ok((i, v))
83}