ytls_record/record/
handshake.rs

1//! Handhsake Record
2
3use ytls_traits::ClientHelloProcessor;
4use ytls_traits::ServerApRecordProcessor;
5use ytls_traits::ServerRecordProcessor;
6use ytls_traits::ServerWrappedRecordProcessor;
7
8mod extensions;
9pub use extensions::Extensions;
10mod cipher_suites;
11pub use cipher_suites::CipherSuites;
12
13mod client_hello;
14pub use client_hello::ClientHello;
15
16mod server_hello;
17pub use server_hello::ServerHello;
18
19mod server_certificate;
20pub use server_certificate::ServerCertificate;
21
22mod server_certificate_verify;
23pub use server_certificate_verify::ServerCertificateVerify;
24
25mod client_finished;
26pub use client_finished::ClientFinished;
27
28mod server_finished;
29pub use server_finished::ServerFinished;
30
31use crate::error::RecordError;
32
33use zerocopy::byteorder::network_endian::U16 as N16;
34use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes, Unaligned};
35
36#[derive(Debug, PartialEq)]
37pub enum HandshakeType {
38    ClientHello,
39    ServerHello,
40    NewSessionTicket,
41    EndOfEarlyData,
42    EncryptedExtensions,
43    Certificate,
44    CertificateRequest,
45    CertificateVerify,
46    Finished,
47    KeyUpdate,
48    MessageHash,
49    Unknown(u8),
50}
51
52impl From<u8> for HandshakeType {
53    fn from(s: u8) -> HandshakeType {
54        match s {
55            1 => Self::ClientHello,
56            2 => Self::ServerHello,
57            4 => Self::NewSessionTicket,
58            5 => Self::EndOfEarlyData,
59            8 => Self::EncryptedExtensions,
60            11 => Self::Certificate,
61            13 => Self::CertificateRequest,
62            15 => Self::CertificateVerify,
63            20 => Self::Finished,
64            24 => Self::KeyUpdate,
65            254 => Self::MessageHash,
66            _ => Self::Unknown(s),
67        }
68    }
69}
70
71#[derive(Debug, PartialEq)]
72pub enum MsgType<'r> {
73    ClientHello(ClientHello<'r>),
74    ServerHello(ServerHello<'r>),
75    ClientFinished(ClientFinished<'r>),
76    EncryptedExtensions,
77    ServerCertificate,
78    ServerCertificateVerify,
79    ServerFinished,
80    NewSessionTicket,
81}
82
83#[derive(Debug, PartialEq)]
84pub struct HandshakeMsg<'r> {
85    pub req_ctx: Option<u8>,
86    pub msg: MsgType<'r>,
87}
88
89#[inline]
90fn parse_header(mut rest: &[u8]) -> Result<(HandshakeType, Option<u8>, usize, &[u8]), RecordError> {
91    let msg_type_raw = rest.split_off(..1).ok_or(RecordError::Size)?;
92
93    let msg_type: HandshakeType = msg_type_raw[0].into();
94
95    if let HandshakeType::Unknown(_) = msg_type {
96        return Err(RecordError::Validity);
97    }
98
99    let mut req_ctx: Option<u8> = None;
100
101    if let HandshakeType::Certificate = msg_type {
102        let req_ctx_t = rest.split_off(..1).ok_or(RecordError::Size)?;
103        req_ctx = Some(req_ctx_t[0]);
104    }
105
106    let msg_len_b = rest.split_off(..3).ok_or(RecordError::Size)?;
107
108    let msg_len = u32::from_be_bytes([0, msg_len_b[0], msg_len_b[1], msg_len_b[2]]);
109
110    Ok((msg_type, req_ctx, msg_len as usize, rest))
111}
112
113impl<'r> HandshakeMsg<'r> {
114    /// The inner Message
115    pub fn msg(&'r self) -> &'r MsgType<'r> {
116        &self.msg
117    }
118    /// Parse Server Wrapped Record (Application phase)
119    #[inline]
120    pub fn server_wrapped_ap_parse<P: ServerApRecordProcessor>(
121        _prc: &mut P,
122        bytes: &'r [u8],
123    ) -> Result<Self, RecordError> {
124        let (msg_type, req_ctx, _msg_len, _rest) = parse_header(bytes)?;
125
126        let msg: MsgType<'_> = match msg_type {
127            HandshakeType::NewSessionTicket => MsgType::NewSessionTicket,
128            _ => todo!("Handshake parsing missing {:?}", msg_type),
129        };
130        Ok(Self { req_ctx, msg })
131    }
132    /// Parse Server Wrapped Record (Handshake phase)
133    #[inline]
134    pub fn server_wrapped_hs_parse<P: ServerWrappedRecordProcessor>(
135        prc: &mut P,
136        bytes: &'r [u8],
137    ) -> Result<Self, RecordError> {
138        let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
139
140        let msg = match msg_type {
141            HandshakeType::EncryptedExtensions => {
142                // todo support these
143                match rest {
144                    &[0, 0] => {}
145                    _ => return Err(RecordError::Validity),
146                }
147                MsgType::EncryptedExtensions
148            }
149            HandshakeType::Certificate => {
150                ServerCertificate::parse_wrapped(prc, rest)?;
151                MsgType::ServerCertificate
152            }
153            HandshakeType::CertificateVerify => {
154                ServerCertificateVerify::parse_wrapped(prc, rest)?;
155                MsgType::ServerCertificateVerify
156            }
157            HandshakeType::Finished => {
158                ServerFinished::parse_wrapped(prc, rest)?;
159                MsgType::ServerFinished
160            }
161            _ => todo!("Handshake parsing missing {:?}", msg_type),
162        };
163
164        Ok(Self { req_ctx, msg })
165    }
166    /// Parse Client Wrapped Record
167    pub fn client_wrapped_parse(bytes: &'r [u8]) -> Result<Self, RecordError> {
168        let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
169
170        let msg = match msg_type {
171            HandshakeType::ClientHello => return Err(RecordError::NotAllowed),
172            HandshakeType::Finished => {
173                let c_finished = ClientFinished::parse_wrapped(rest)?;
174                MsgType::ClientFinished(c_finished)
175            }
176            _ => todo!("Handshake parsing missing {:?}", msg_type),
177        };
178
179        Ok(Self { req_ctx, msg })
180    }
181    /// Parse Server Record
182    pub fn server_parse<P: ServerRecordProcessor>(
183        prc: &mut P,
184        bytes: &'r [u8],
185    ) -> Result<(Self, &'r [u8]), RecordError> {
186        let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
187
188        let (msg, rest_next) = match msg_type {
189            HandshakeType::ServerHello => {
190                let (s_hello, r_next) = ServerHello::parse(prc, rest)?;
191                (MsgType::ServerHello(s_hello), r_next)
192            }
193            _ => todo!("Missing msg_type {:?}", msg_type),
194        };
195
196        Ok((Self { req_ctx, msg }, rest_next))
197    }
198    /// Parse Client Record
199    pub fn client_parse<P: ClientHelloProcessor>(
200        prc: &mut P,
201        bytes: &'r [u8],
202    ) -> Result<(Self, &'r [u8]), RecordError> {
203        let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
204
205        let (msg, rest_next) = match msg_type {
206            HandshakeType::ClientHello => {
207                let (c_hello, r_next) = ClientHello::parse(prc, rest)?;
208                (MsgType::ClientHello(c_hello), r_next)
209            }
210            _ => todo!(),
211        };
212
213        Ok((Self { req_ctx, msg }, rest_next))
214    }
215}