1use 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 pub fn msg(&'r self) -> &'r MsgType<'r> {
116 &self.msg
117 }
118 #[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 #[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 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 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 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 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}