ytls_record/record/
handshake.rs

1//! Handhsake Record
2
3use ytls_traits::ClientHelloProcessor;
4
5mod extensions;
6pub use extensions::Extensions;
7mod cipher_suites;
8pub use cipher_suites::CipherSuites;
9
10mod client_hello;
11pub use client_hello::ClientHello;
12
13mod client_finished;
14pub use client_finished::ClientFinished;
15
16use crate::error::RecordError;
17
18use zerocopy::byteorder::network_endian::U16 as N16;
19use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes, Unaligned};
20
21#[derive(TryFromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
22#[repr(u8)]
23#[derive(Debug, PartialEq)]
24pub enum HandshakeType {
25    ClientHello = 1,
26    ServerHello = 2,
27    NewSessionTicket = 4,
28    EndOfEarlyData = 5,
29    EncryptedExtensions = 8,
30    Certificate = 11,
31    CertificateRequest = 13,
32    CertificateVerify = 15,
33    Finished = 20,
34    KeyUpdate = 24,
35    MessageHash = 254,
36}
37
38#[derive(TryFromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
39#[repr(C)]
40#[derive(Debug, PartialEq)]
41pub struct HandshakeHdr {
42    msg_type: HandshakeType,
43    msg_length: [u8; 3],
44}
45
46#[derive(Debug, PartialEq)]
47pub enum MsgType<'r> {
48    ClientHello(ClientHello<'r>),
49    ClientFinished(ClientFinished<'r>),
50}
51
52#[derive(Debug, PartialEq)]
53pub struct HandshakeMsg<'r> {
54    pub hdr: &'r HandshakeHdr,
55    pub msg: MsgType<'r>,
56}
57
58impl<'r> HandshakeMsg<'r> {
59    /// The inner Message
60    pub fn msg(&'r self) -> &'r MsgType<'r> {
61        &self.msg
62    }
63    /// Parse Client Wrapped Record
64    pub fn client_wrapped_parse(bytes: &'r [u8]) -> Result<Self, RecordError> {
65        let (hdr, rest) =
66            HandshakeHdr::try_ref_from_prefix(bytes).map_err(|e| RecordError::from_zero_copy(e))?;
67
68        let msg = match hdr.msg_type {
69            HandshakeType::ClientHello => return Err(RecordError::NotAllowed),
70            HandshakeType::Finished => {
71                let c_finished = ClientFinished::parse_wrapped(rest)?;
72                MsgType::ClientFinished(c_finished)
73            }
74            /*
75            HandshakeType::ClientHello => {
76                let (c_hello, r_next) = ClientHello::parse(prc, rest)?;
77                (MsgType::ClientHello(c_hello), r_next)
78            } */
79            _ => todo!("Handshake parsing missing {:?}", hdr.msg_type),
80        };
81
82        Ok(Self { hdr, msg })
83    }
84    /// Parse Client Record
85    pub fn client_parse<P: ClientHelloProcessor>(
86        prc: &mut P,
87        bytes: &'r [u8],
88    ) -> Result<(Self, &'r [u8]), RecordError> {
89        let (hdr, rest) =
90            HandshakeHdr::try_ref_from_prefix(bytes).map_err(|e| RecordError::from_zero_copy(e))?;
91
92        let (msg, rest_next) = match hdr.msg_type {
93            HandshakeType::ClientHello => {
94                let (c_hello, r_next) = ClientHello::parse(prc, rest)?;
95                (MsgType::ClientHello(c_hello), r_next)
96            }
97            _ => todo!(),
98        };
99
100        Ok((Self { hdr, msg }, rest_next))
101    }
102}