1use std::fmt;
2
3use nom::{
4 bytes::complete::take,
5 combinator::map,
6 error::{Error, ErrorKind},
7 multi::many0,
8 number::complete::{be_u16, be_u24, be_u8},
9 Err, IResult, Parser,
10};
11
12pub struct HandshakeMessage {
13 pub length: u32,
14 pub message_seq: u16,
15 pub fragment_offset: u32,
16 pub fragment_length: u32,
17 pub inner: HandshakeInner,
18}
19
20pub enum HandshakeInner {
21 ClientHello(ClientHello),
22 ServerHello(ServerHello),
23 HelloVerifyRequest(HelloVerifyRequest),
24 Certificates(Certificates),
25 ServerKeyExchange(ServerKeyExchange),
26 CertificateRequest(u8),
27 ServerHelloDone,
28 CertificateVerify(u8),
29 ClientKeyExchange(ClientKeyExchange),
30 Finished,
31}
32
33impl fmt::Display for HandshakeInner {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 match self {
36 Self::ClientHello(msg) => write!(f, "ClientHello({msg})"),
37 Self::ServerHello(msg) => write!(f, "ServerHello({msg})"),
38 Self::HelloVerifyRequest(msg) => write!(f, "HelloVerifyRequest({msg})"),
39 Self::Certificates(msg) => write!(f, "Certificates({msg})"),
40 Self::ServerKeyExchange(msg) => write!(f, "ServerKeyExchange({msg})"),
41 Self::CertificateRequest(msg) => write!(f, "CertificateRequest({msg})"),
42 Self::ServerHelloDone => write!(f, "ServerHelloDone"),
43 Self::CertificateVerify(msg) => write!(f, "CertificateVerify({msg})"),
44 Self::ClientKeyExchange(msg) => write!(f, "ClientKeyExchange({msg})"),
45 Self::Finished => write!(f, "Finished"),
46 }
47 }
48}
49
50impl HandshakeMessage {
51 pub fn parse(input: &[u8]) -> IResult<&[u8], Self> {
52 let (input, discriminant) = be_u8(input)?;
53 let (input, length) = be_u24(input)?;
54 let (input, message_seq) = be_u16(input)?;
55 let (input, fragment_offset) = be_u24(input)?;
56 let (input, fragment_length) = be_u24(input)?;
57 let (input, inner) = match discriminant {
58 1 => map(ClientHello::parse, HandshakeInner::ClientHello).parse(input),
59 2 => map(ServerHello::parse, HandshakeInner::ServerHello).parse(input),
60 3 => map(
61 HelloVerifyRequest::parse,
62 HandshakeInner::HelloVerifyRequest,
63 )
64 .parse(input),
65 11 => map(Certificates::parse, HandshakeInner::Certificates).parse(input),
66 12 => map(ServerKeyExchange::parse, HandshakeInner::ServerKeyExchange).parse(input),
67 13 => Ok((input, HandshakeInner::CertificateRequest(0))),
68 14 => Ok((input, HandshakeInner::ServerHelloDone)),
69 15 => Ok((input, HandshakeInner::CertificateVerify(0))),
70 16 => map(ClientKeyExchange::parse, HandshakeInner::ClientKeyExchange).parse(input),
71 20 => Ok((input, HandshakeInner::Finished)),
72 _ => Err(Err::Error(Error::new(input, ErrorKind::Alt))),
73 }?;
74 Ok((
75 input,
76 HandshakeMessage {
77 length,
78 message_seq,
79 fragment_offset,
80 fragment_length,
81 inner,
82 },
83 ))
84 }
85}
86
87pub struct ClientHello {
88 pub random: [u8; 32],
89 pub session_id: Vec<u8>,
90 pub cookie: Vec<u8>,
91 pub cipher_suites: Vec<u16>,
92 pub compression_methods: Vec<u8>,
93 pub extensions: Vec<Extension>,
94}
95
96impl fmt::Display for ClientHello {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(
99 f,
100 "random={}, session_id=\"{}\", cookie=\"{}\", cipher_suites={:?}, compression_methods={:?}",
101 hex::encode(self.random),
102 hex::encode(&self.session_id),
103 hex::encode(&self.cookie),
104 self.cipher_suites,
105 self.compression_methods,
106 )
107 }
108}
109
110impl ClientHello {
111 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
112 let (input, legacy_record_version) = be_u16(input)?;
113 if legacy_record_version != 0xFEFD {
114 return Err(Err::Error(Error::new(input, ErrorKind::Alt)));
115 }
116 let (input, random) = take(32usize)(input)?;
117 let random = <[u8; 32]>::try_from(random).expect("cannot fail");
118 let (input, l) = be_u8(input)?;
119 let (input, bytes) = take(l as usize)(input)?;
120 let session_id = bytes.to_vec();
121 let (input, l) = be_u8(input)?;
122 let (input, bytes) = take(l as usize)(input)?;
123 let cookie = bytes.to_vec();
124 let (input, l) = be_u16(input)?;
125 let (input, bytes) = take(l as usize)(input)?;
126 let (_, cipher_suites) = many0(be_u16).parse(bytes)?;
127 let (input, compression_methods_len) = be_u8(input)?;
128 let (input, bytes) = take(compression_methods_len as usize)(input)?;
129 let compression_methods = bytes.to_vec();
130 let (input, l) = be_u16(input)?;
131 let (input, bytes) = take(l as usize)(input)?;
132 let (_, extensions) = many0(Extension::parse).parse(bytes)?;
133
134 Ok((
135 input,
136 ClientHello {
137 random,
138 session_id,
139 cookie,
140 cipher_suites,
141 compression_methods,
142 extensions,
143 },
144 ))
145 }
146}
147
148pub struct ServerHello {
149 pub random: [u8; 32],
150 pub session_id: Vec<u8>,
151 pub cipher_suite: u16,
152 pub compression_method: u8,
153 pub extensions: Vec<Extension>,
154}
155
156impl fmt::Display for ServerHello {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 write!(
159 f,
160 "random={}, session_id=\"{}\", cipher_suite={}, compression_method={}",
161 hex::encode(self.random),
162 hex::encode(&self.session_id),
163 self.cipher_suite,
164 self.compression_method,
165 )
166 }
167}
168
169impl ServerHello {
170 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
171 let (input, legacy_record_version) = be_u16(input)?;
172 if legacy_record_version != 0xFEFD {
173 return Err(Err::Error(Error::new(input, ErrorKind::Alt)));
174 }
175 let (input, random) = take(32usize)(input)?;
176 let random = <[u8; 32]>::try_from(random).expect("cannot fail");
177 let (input, l) = be_u8(input)?;
178 let (input, bytes) = take(l as usize)(input)?;
179 let session_id = bytes.to_vec();
180 let (input, cipher_suite) = be_u16(input)?;
181 let (input, compression_method) = be_u8(input)?;
182 let (input, l) = be_u16(input)?;
183 let (input, bytes) = take(l as usize)(input)?;
184 let (_, extensions) = many0(Extension::parse).parse(bytes)?;
185
186 Ok((
187 input,
188 ServerHello {
189 random,
190 session_id,
191 cipher_suite,
192 compression_method,
193 extensions,
194 },
195 ))
196 }
197}
198
199pub struct HelloVerifyRequest {
200 pub cookie: Vec<u8>,
201}
202
203impl fmt::Display for HelloVerifyRequest {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 write!(f, "cookie={}", hex::encode(&self.cookie),)
206 }
207}
208
209impl HelloVerifyRequest {
210 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
211 let (input, legacy_record_version) = be_u16(input)?;
212 if legacy_record_version != 0xFEFD {
213 return Err(Err::Error(Error::new(input, ErrorKind::Alt)));
214 }
215
216 let (input, l) = be_u8(input)?;
217 let (input, bytes) = take(l as usize)(input)?;
218 let cookie = bytes.to_vec();
219
220 Ok((input, HelloVerifyRequest { cookie }))
221 }
222}
223
224pub struct Extension {}
225
226impl Extension {
227 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
228 let _ = be_u8(input)?;
229 Ok((&[], Extension {}))
230 }
231}
232
233pub struct Certificates(pub Vec<Certificate>);
234
235impl fmt::Display for Certificates {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 for certificate in &self.0 {
238 write!(f, "certificate({certificate})")?;
239 }
240 Ok(())
241 }
242}
243
244impl Certificates {
245 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
246 let (input, length) = be_u24(input)?;
247 let (input, bytes) = take(length as usize)(input)?;
248 let (_, certificates) = many0(Certificate::parse).parse(bytes)?;
249 Ok((input, Certificates(certificates)))
250 }
251}
252
253pub struct Certificate {
254 pub data: Vec<u8>,
255}
256
257impl fmt::Display for Certificate {
258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259 write!(f, "{}", hex::encode(&self.data))
260 }
261}
262
263impl Certificate {
264 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
265 let (input, length) = be_u24(input)?;
266 let (input, bytes) = take(length as usize)(input)?;
267 let data = bytes.to_vec();
268
269 Ok((input, Certificate { data }))
270 }
271}
272
273pub struct ServerKeyExchange {
274 pub curve_name: u16,
276 pub public_key: Vec<u8>,
277 pub signature_hash_algorithm: u8,
278 pub signature_algorithm: u8,
279 pub signature: Vec<u8>,
280}
281
282impl fmt::Display for ServerKeyExchange {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 write!(
285 f,
286 "curve_name={}, pk={}, sig_alg=({},{}), sig={}",
287 self.curve_name,
288 hex::encode(&self.public_key),
289 self.signature_hash_algorithm,
290 self.signature_algorithm,
291 hex::encode(&self.signature)
292 )
293 }
294}
295
296impl ServerKeyExchange {
297 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
298 let (input, curve_type) = be_u8(input)?;
299 if curve_type != 3 {
300 return Err(Err::Failure(Error::new(input, ErrorKind::Alt)));
301 }
302 let (input, curve_name) = be_u16(input)?;
303
304 let (input, l) = be_u8(input)?;
305 let (input, bytes) = take(l as usize)(input)?;
306 let public_key = bytes.to_vec();
307
308 let (input, signature_hash_algorithm) = be_u8(input)?;
309 let (input, signature_algorithm) = be_u8(input)?;
310
311 let (input, l) = be_u16(input)?;
312 let (input, bytes) = take(l as usize)(input)?;
313 let signature = bytes.to_vec();
314
315 Ok((
316 input,
317 ServerKeyExchange {
318 curve_name,
319 public_key,
320 signature_hash_algorithm,
321 signature_algorithm,
322 signature,
323 },
324 ))
325 }
326}
327
328pub struct ClientKeyExchange {
329 pub public_key: Vec<u8>,
330}
331
332impl fmt::Display for ClientKeyExchange {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 write!(f, "pk={}", hex::encode(&self.public_key),)
335 }
336}
337
338impl ClientKeyExchange {
339 fn parse(input: &[u8]) -> IResult<&[u8], Self> {
340 let (input, l) = be_u8(input)?;
341 let (input, bytes) = take(l as usize)(input)?;
342 let public_key = bytes.to_vec();
343
344 Ok((input, ClientKeyExchange { public_key }))
345 }
346}