ytls_record/record/
handshake.rs1use 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 pub fn msg(&'r self) -> &'r MsgType<'r> {
61 &self.msg
62 }
63 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 _ => todo!("Handshake parsing missing {:?}", hdr.msg_type),
80 };
81
82 Ok(Self { hdr, msg })
83 }
84 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}