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<HandshakeType> for &'static str {
53 fn from(t: HandshakeType) -> &'static str {
54 match t {
55 HandshakeType::ClientHello => "ClientHello",
56 HandshakeType::ServerHello => "ServerHello",
57 HandshakeType::NewSessionTicket => "NewSessionTicket",
58 HandshakeType::EndOfEarlyData => "EndOfEarlyData",
59 HandshakeType::EncryptedExtensions => "EncryptedExtensins",
60 HandshakeType::Certificate => "Certificate",
61 HandshakeType::CertificateRequest => "CertificateRequest",
62 HandshakeType::CertificateVerify => "CertificateVerify",
63 HandshakeType::Finished => "Finished",
64 HandshakeType::KeyUpdate => "KeyUpdate",
65 HandshakeType::MessageHash => "MessageHash",
66 HandshakeType::Unknown(_) => "Unknown",
67 }
68 }
69}
70
71impl From<u8> for HandshakeType {
72 fn from(s: u8) -> HandshakeType {
73 match s {
74 1 => Self::ClientHello,
75 2 => Self::ServerHello,
76 4 => Self::NewSessionTicket,
77 5 => Self::EndOfEarlyData,
78 8 => Self::EncryptedExtensions,
79 11 => Self::Certificate,
80 13 => Self::CertificateRequest,
81 15 => Self::CertificateVerify,
82 20 => Self::Finished,
83 24 => Self::KeyUpdate,
84 254 => Self::MessageHash,
85 _ => Self::Unknown(s),
86 }
87 }
88}
89
90#[derive(Debug, PartialEq)]
91pub enum MsgType<'r> {
92 ClientHello(ClientHello<'r>),
93 ServerHello(ServerHello<'r>),
94 ClientFinished(ClientFinished<'r>),
95 EncryptedExtensions,
96 ServerCertificate,
97 ServerCertificateVerify,
98 ServerFinished,
99 NewSessionTicket,
100}
101
102#[derive(Debug, PartialEq)]
103pub struct HandshakeMsg<'r> {
104 pub req_ctx: Option<u8>,
105 pub msg: MsgType<'r>,
106}
107
108#[inline]
109fn parse_header(mut rest: &[u8]) -> Result<(HandshakeType, Option<u8>, usize, &[u8]), RecordError> {
110 let msg_type_raw = rest.split_off(..1).ok_or(RecordError::Size)?;
111
112 let msg_type: HandshakeType = msg_type_raw[0].into();
113
114 if let HandshakeType::Unknown(_) = msg_type {
115 return Err(RecordError::Validity);
116 }
117
118 let mut req_ctx: Option<u8> = None;
119
120 if let HandshakeType::Certificate = msg_type {
121 let req_ctx_t = rest.split_off(..1).ok_or(RecordError::Size)?;
122 req_ctx = Some(req_ctx_t[0]);
123 }
124
125 let msg_len_b = rest.split_off(..3).ok_or(RecordError::Size)?;
126
127 let msg_len = u32::from_be_bytes([0, msg_len_b[0], msg_len_b[1], msg_len_b[2]]);
128
129 Ok((msg_type, req_ctx, msg_len as usize, rest))
130}
131
132impl<'r> HandshakeMsg<'r> {
133 pub fn msg(&'r self) -> &'r MsgType<'r> {
135 &self.msg
136 }
137 #[inline]
139 pub fn server_wrapped_ap_parse<P: ServerApRecordProcessor>(
140 _prc: &mut P,
141 bytes: &'r [u8],
142 ) -> Result<Self, RecordError> {
143 let (msg_type, req_ctx, _msg_len, _rest) = parse_header(bytes)?;
144
145 let msg: MsgType<'_> = match msg_type {
146 HandshakeType::NewSessionTicket => MsgType::NewSessionTicket,
147 _ => {
148 return Err(RecordError::NotImplemented(
149 msg_type.into(),
150 "HandshakeMsg::client_wrapped_ap_parse",
151 ))
152 }
153 };
154 Ok(Self { req_ctx, msg })
155 }
156 #[inline]
158 pub fn server_wrapped_hs_parse<P: ServerWrappedRecordProcessor>(
159 prc: &mut P,
160 bytes: &'r [u8],
161 ) -> Result<Self, RecordError> {
162 let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
163
164 let msg = match msg_type {
165 HandshakeType::EncryptedExtensions => {
166 match rest {
168 &[0, 0] => {}
169 _ => return Err(RecordError::Validity),
170 }
171 MsgType::EncryptedExtensions
172 }
173 HandshakeType::Certificate => {
174 ServerCertificate::parse_wrapped(prc, rest)?;
175 MsgType::ServerCertificate
176 }
177 HandshakeType::CertificateVerify => {
178 ServerCertificateVerify::parse_wrapped(prc, rest)?;
179 MsgType::ServerCertificateVerify
180 }
181 HandshakeType::Finished => {
182 ServerFinished::parse_wrapped(prc, rest)?;
183 MsgType::ServerFinished
184 }
185 _ => {
186 return Err(RecordError::NotImplemented(
187 msg_type.into(),
188 "HandshakeMsg::server_wrapped_parse",
189 ))
190 }
191 };
192
193 Ok(Self { req_ctx, msg })
194 }
195 pub fn client_wrapped_parse(bytes: &'r [u8]) -> Result<Self, RecordError> {
197 let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
198
199 let msg = match msg_type {
200 HandshakeType::ClientHello => return Err(RecordError::NotAllowed),
201 HandshakeType::Finished => {
202 let c_finished = ClientFinished::parse_wrapped(rest)?;
203 MsgType::ClientFinished(c_finished)
204 }
205 _ => {
206 return Err(RecordError::NotImplemented(
207 msg_type.into(),
208 "HandshakeMsg::client_wrapped_parse",
209 ))
210 }
211 };
212
213 Ok(Self { req_ctx, msg })
214 }
215 pub fn server_parse<P: ServerRecordProcessor>(
217 prc: &mut P,
218 bytes: &'r [u8],
219 ) -> Result<(Self, &'r [u8]), RecordError> {
220 let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
221
222 let (msg, rest_next) = match msg_type {
223 HandshakeType::ServerHello => {
224 let (s_hello, r_next) = ServerHello::parse(prc, rest)?;
225 (MsgType::ServerHello(s_hello), r_next)
226 }
227 _ => {
228 return Err(RecordError::NotImplemented(
229 msg_type.into(),
230 "HandshakeMsg::server_parse",
231 ))
232 }
233 };
234
235 Ok((Self { req_ctx, msg }, rest_next))
236 }
237 pub fn client_parse<P: ClientHelloProcessor>(
239 prc: &mut P,
240 bytes: &'r [u8],
241 ) -> Result<(Self, &'r [u8]), RecordError> {
242 let (msg_type, req_ctx, _msg_len, rest) = parse_header(bytes)?;
243
244 let (msg, rest_next) = match msg_type {
245 HandshakeType::ClientHello => {
246 let (c_hello, r_next) = ClientHello::parse(prc, rest)?;
247 (MsgType::ClientHello(c_hello), r_next)
248 }
249 _ => {
250 return Err(RecordError::NotImplemented(
251 msg_type.into(),
252 "HandshakeMsg::client_parse",
253 ))
254 }
255 };
256
257 Ok((Self { req_ctx, msg }, rest_next))
258 }
259}