1use crate::{
26 Buf,
27 BufError::{self},
28 BufMut, BufResult, Codec, Cursor,
29 ietf::tls::{LengthPrefix, ProtocolVersion, TlsVec, u24},
30 ietf::tls1_3::Extension,
31};
32use ring::rand::{SecureRandom, SystemRandom};
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
41#[repr(u8)]
42pub enum HandshakeType {
43 ClientHello = 1,
45 ServerHello = 2,
47 NewSessionTicket = 4,
49 EndOfEarlyData = 5,
51 EncryptedExtensions = 8,
53 Certificate = 11,
55 CertificateRequest = 13,
57 CertificateVerify = 15,
59 Finished = 20,
61 KeyUpdate = 24,
63 MessageHash = 254,
65}
66
67impl Codec for HandshakeType {
68 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
69 (*self as u8).encode(writer, ())
70 }
71
72 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
73 match u8::decode(reader, ())? {
74 x if x == (Self::ClientHello as u8) => Ok(Self::ClientHello),
75 x if x == (Self::ServerHello as u8) => Ok(Self::ServerHello),
76 x if x == (Self::NewSessionTicket as u8) => Ok(Self::NewSessionTicket),
77 x if x == (Self::EndOfEarlyData as u8) => Ok(Self::EndOfEarlyData),
78 x if x == (Self::EncryptedExtensions as u8) => Ok(Self::EncryptedExtensions),
79 x if x == (Self::Certificate as u8) => Ok(Self::Certificate),
80 x if x == (Self::CertificateRequest as u8) => Ok(Self::CertificateRequest),
81 x if x == (Self::CertificateVerify as u8) => Ok(Self::CertificateVerify),
82 x if x == (Self::Finished as u8) => Ok(Self::Finished),
83 x if x == (Self::KeyUpdate as u8) => Ok(Self::KeyUpdate),
84 x if x == (Self::MessageHash as u8) => Ok(Self::MessageHash),
85 _ => Err(BufError::UnexpectedValue),
86 }
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash)]
94pub struct Handshake {
95 pub msg_type: HandshakeType,
97 pub msg: Vec<u8>,
99}
100
101impl Codec for Handshake {
102 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
103 self.msg_type.encode(writer, ())?;
104 let len = u24::from_usize(self.msg.len())?;
105 len.encode(writer, ())?;
106 writer.write_slice(&self.msg)
107 }
108
109 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
110 let msg_type = HandshakeType::decode(reader, ())?;
111 let length_u24 = u24::decode(reader, ())?;
112 let length = length_u24.as_usize();
113
114 if reader.remaining() < length {
115 return Err(BufError::UnexpectedEof);
116 }
117
118 let mut msg = vec![0u8; length];
119 reader.read_into(&mut msg)?;
120
121 Ok(Self { msg_type, msg })
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
132#[repr(u16)]
133pub enum CipherSuite {
134 TlsAes128GcmSha256 = 0x1301,
136 TlsAes256GcmSha384 = 0x1302,
138 TlsChacha20Poly1305Sha256 = 0x1303,
140 TlsAes128CcmSha256 = 0x1304,
142 TlsAes128Ccm8Sha256 = 0x1305,
144 TlsEmptyRenegotiationInfoScsv = 0x00FF,
146}
147
148impl Codec for CipherSuite {
149 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
150 (*self as u16).encode(writer, ())
151 }
152
153 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
154 match u16::decode(reader, ())? {
155 x if x == (Self::TlsAes128GcmSha256 as u16) => Ok(Self::TlsAes128GcmSha256),
156 x if x == (Self::TlsAes256GcmSha384 as u16) => Ok(Self::TlsAes256GcmSha384),
157 x if x == (Self::TlsChacha20Poly1305Sha256 as u16) => {
158 Ok(Self::TlsChacha20Poly1305Sha256)
159 }
160 x if x == (Self::TlsAes128CcmSha256 as u16) => Ok(Self::TlsAes128CcmSha256),
161 x if x == (Self::TlsAes128Ccm8Sha256 as u16) => Ok(Self::TlsAes128Ccm8Sha256),
162 x if x == (Self::TlsEmptyRenegotiationInfoScsv as u16) => {
163 Ok(Self::TlsEmptyRenegotiationInfoScsv)
164 }
165 _ => Err(BufError::UnexpectedValue),
166 }
167 }
168}
169
170#[derive(Debug, Clone, PartialEq, Eq, Hash)]
174pub struct Random(pub [u8; 32]);
175
176impl Random {
177 pub fn random() -> Self {
179 let mut random = [0u8; 32];
180 let rng = SystemRandom::new();
181 rng.fill(&mut random).unwrap();
182 Self(random)
183 }
184}
185
186impl Codec for Random {
187 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
188 writer.write_array(&self.0)
189 }
190
191 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
192 Ok(Self(reader.read_array::<32>()?))
193 }
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, Hash)]
200pub struct ClientHello {
201 pub legacy_version: ProtocolVersion,
203 pub random: Random,
205 pub legacy_session_id: TlsVec<u8, u8>,
207 pub cipher_suites: TlsVec<CipherSuite, u16>,
209 pub legacy_compression_methods: TlsVec<u8, u8>,
211 pub extensions: TlsVec<Extension, u16>,
213}
214
215impl ClientHello {
216 pub fn default(extensions: TlsVec<Extension, u16>) -> Self {
218 Self {
219 legacy_version: ProtocolVersion::TLS12,
220 random: Random::random(),
221 legacy_session_id: TlsVec::new(vec![]),
222 cipher_suites: TlsVec::new(vec![
223 CipherSuite::TlsAes128GcmSha256,
224 CipherSuite::TlsChacha20Poly1305Sha256,
225 ]),
226 legacy_compression_methods: TlsVec::new(vec![0x00]),
227 extensions,
228 }
229 }
230}
231
232impl Codec for ClientHello {
233 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
234 self.legacy_version.encode(writer, ())?;
235 self.random.encode(writer, ())?;
236 self.legacy_session_id.encode(writer, ())?;
237 self.cipher_suites.encode(writer, ())?;
238 self.legacy_compression_methods.encode(writer, ())?;
239 self.extensions.encode(writer, ())
240 }
241
242 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
243 Ok(Self {
244 legacy_version: ProtocolVersion::decode(reader, ())?,
245 random: Random::decode(reader, ())?,
246 legacy_session_id: TlsVec::<u8, u8>::decode(reader, ())?,
247 cipher_suites: TlsVec::<CipherSuite, u16>::decode(reader, ())?,
248 legacy_compression_methods: TlsVec::<u8, u8>::decode(reader, ())?,
249 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
250 })
251 }
252}
253
254#[derive(Debug, Clone, PartialEq, Eq, Hash)]
258pub struct ServerHello {
259 pub legacy_version: ProtocolVersion,
261 pub random: Random,
263 pub legacy_session_id_echo: TlsVec<u8, u8>,
265 pub cipher_suite: CipherSuite,
267 pub legacy_compression_method: u8,
269 pub extensions: TlsVec<Extension, u16>,
271}
272
273impl Codec for ServerHello {
274 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
275 self.legacy_version.encode(writer, ())?;
276 self.random.encode(writer, ())?;
277 self.legacy_session_id_echo.encode(writer, ())?;
278 self.cipher_suite.encode(writer, ())?;
279 self.legacy_compression_method.encode(writer, ())?;
280 self.extensions.encode(writer, ())
281 }
282
283 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
284 Ok(Self {
285 legacy_version: ProtocolVersion::decode(reader, ())?,
286 random: Random::decode(reader, ())?,
287 legacy_session_id_echo: TlsVec::<u8, u8>::decode(reader, ())?,
288 cipher_suite: CipherSuite::decode(reader, ())?,
289 legacy_compression_method: u8::decode(reader, ())?,
290 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
291 })
292 }
293}
294
295#[derive(Debug, Clone, PartialEq, Eq, Hash)]
299pub struct NewSessionTicket {
300 pub ticket_lifetime: u32,
302 pub ticket_age_add: u32,
304 pub ticket_nonce: TlsVec<u8, u8>,
306 pub ticket: TlsVec<u8, u16>,
308 pub extensions: TlsVec<Extension, u16>,
310}
311
312impl Codec for NewSessionTicket {
313 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
314 self.ticket_lifetime.encode(writer, ())?;
315 self.ticket_age_add.encode(writer, ())?;
316 self.ticket_nonce.encode(writer, ())?;
317 self.ticket.encode(writer, ())?;
318 self.extensions.encode(writer, ())
319 }
320
321 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
322 Ok(Self {
323 ticket_lifetime: u32::decode(reader, ())?,
324 ticket_age_add: u32::decode(reader, ())?,
325 ticket_nonce: TlsVec::<u8, u8>::decode(reader, ())?,
326 ticket: TlsVec::<u8, u16>::decode(reader, ())?,
327 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
328 })
329 }
330}
331
332#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
336pub struct EndOfEarlyData;
337
338impl Codec for EndOfEarlyData {
339 fn encode<W: BufMut>(&self, _writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
340 Ok(())
341 }
342
343 fn decode<R: Buf>(_reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
344 Ok(Self)
345 }
346}
347
348#[derive(Debug, Clone, PartialEq, Eq, Hash)]
352pub struct EncryptedExtensions {
353 pub extensions: TlsVec<Extension, u16>,
355}
356
357impl Codec for EncryptedExtensions {
358 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
359 self.extensions.encode(writer, ())
360 }
361
362 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
363 Ok(Self {
364 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
365 })
366 }
367}
368
369#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
375pub struct SignatureScheme(pub u16);
376
377impl SignatureScheme {
378 pub const RSA_PKCS1_SHA256: Self = Self(0x0401);
380 pub const ECDSA_SECP256R1_SHA256: Self = Self(0x0403);
382 pub const ECDSA_SECP384R1_SHA384: Self = Self(0x0503);
384 pub const RSA_PSS_RSAE_SHA256: Self = Self(0x0804);
386 pub const RSA_PSS_RSAE_SHA384: Self = Self(0x0805);
388 pub const ED25519: Self = Self(0x0807);
390}
391
392impl Codec for SignatureScheme {
393 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
394 self.0.encode(writer, ())
395 }
396
397 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
398 Ok(Self(u16::decode(reader, ())?))
399 }
400}
401
402#[derive(Debug, Clone, PartialEq, Eq, Hash)]
406pub struct CertificateEntry {
407 pub cert_data: TlsVec<u8, u24>,
409 pub extensions: TlsVec<Extension, u16>,
411}
412
413impl Codec for CertificateEntry {
414 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
415 self.cert_data.encode(writer, ())?;
416 self.extensions.encode(writer, ())
417 }
418
419 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
420 Ok(Self {
421 cert_data: TlsVec::<u8, u24>::decode(reader, ())?,
422 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
423 })
424 }
425}
426
427#[derive(Debug, Clone, PartialEq, Eq, Hash)]
431pub struct Certificate {
432 pub certificate_request_context: TlsVec<u8, u8>,
434 pub certificate_list: TlsVec<CertificateEntry, u24>,
436}
437
438impl Codec for Certificate {
439 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
440 self.certificate_request_context.encode(writer, ())?;
441 self.certificate_list.encode(writer, ())
442 }
443
444 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
445 Ok(Self {
446 certificate_request_context: TlsVec::<u8, u8>::decode(reader, ())?,
447 certificate_list: TlsVec::<CertificateEntry, u24>::decode(reader, ())?,
448 })
449 }
450}
451
452#[derive(Debug, Clone, PartialEq, Eq, Hash)]
456pub struct CertificateRequest {
457 pub certificate_request_context: TlsVec<u8, u8>,
459 pub extensions: TlsVec<Extension, u16>,
461}
462
463impl Codec for CertificateRequest {
464 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
465 self.certificate_request_context.encode(writer, ())?;
466 self.extensions.encode(writer, ())
467 }
468
469 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
470 Ok(Self {
471 certificate_request_context: TlsVec::<u8, u8>::decode(reader, ())?,
472 extensions: TlsVec::<Extension, u16>::decode(reader, ())?,
473 })
474 }
475}
476
477#[derive(Debug, Clone, PartialEq, Eq, Hash)]
481pub struct CertificateVerify {
482 pub algorithm: SignatureScheme,
484 pub signature: TlsVec<u8, u16>,
486}
487
488impl Codec for CertificateVerify {
489 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
490 self.algorithm.encode(writer, ())?;
491 self.signature.encode(writer, ())
492 }
493
494 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
495 Ok(Self {
496 algorithm: SignatureScheme::decode(reader, ())?,
497 signature: TlsVec::<u8, u16>::decode(reader, ())?,
498 })
499 }
500}
501
502#[derive(Debug, Clone, PartialEq, Eq, Hash)]
506pub struct Finished {
507 pub verify_data: Vec<u8>,
509}
510
511impl Codec for Finished {
512 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
513 self.verify_data.encode(writer, ())
514 }
515
516 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
517 Ok(Self {
518 verify_data: Vec::<u8>::decode(reader, ())?,
519 })
520 }
521}
522
523#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
530#[repr(u8)]
531pub enum KeyUpdateRequest {
532 UpdateNotRequested = 0,
534 UpdateRequested = 1,
536}
537
538impl Codec for KeyUpdateRequest {
539 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
540 (*self as u8).encode(writer, ())
541 }
542
543 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
544 match u8::decode(reader, ())? {
545 x if x == (Self::UpdateNotRequested as u8) => Ok(Self::UpdateNotRequested),
546 x if x == (Self::UpdateRequested as u8) => Ok(Self::UpdateRequested),
547 _ => Err(BufError::UnexpectedValue),
548 }
549 }
550}
551
552#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
556pub struct KeyUpdate {
557 pub request_update: KeyUpdateRequest,
559}
560
561impl Codec for KeyUpdate {
562 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
563 self.request_update.encode(writer, ())
564 }
565
566 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
567 Ok(Self {
568 request_update: KeyUpdateRequest::decode(reader, ())?,
569 })
570 }
571}
572
573#[cfg(test)]
574mod tests {
575 use core::fmt::Debug;
576
577 use super::{CipherSuite, HandshakeType, KeyUpdateRequest};
578 use crate::{Codec, Cursor};
579
580 fn codec_roundtrip<T: Codec<C> + Debug + Eq, C: Copy>(
581 etalon_struct: T,
582 etalon_bytes: &[u8],
583 context: C,
584 ) {
585 let mut encoded_bytes = vec![];
586 {
587 let writer = &mut Cursor::new(&mut encoded_bytes);
588 etalon_struct.encode(writer, context).unwrap();
589 }
590 assert_eq!(etalon_bytes, &encoded_bytes);
591
592 let decoded_struct = {
593 let reader = &mut Cursor::new(&mut encoded_bytes);
594 T::decode(reader, context).unwrap()
595 };
596 assert_eq!(etalon_struct, decoded_struct);
597
598 encoded_bytes.fill(0x00);
599 {
600 let writer = &mut Cursor::new(&mut encoded_bytes);
601 decoded_struct.encode(writer, context).unwrap();
602 }
603 assert_eq!(etalon_bytes, &encoded_bytes);
604 }
605
606 #[test]
607 fn handshake_type() {
608 let etalon_bytes = &[0x01];
609 let etalon_struct = HandshakeType::ClientHello;
610
611 codec_roundtrip(etalon_struct, etalon_bytes, ());
612 }
613
614 #[test]
615 fn cipher_suite() {
616 let etalon_bytes = &[0x13, 0x01];
617 let etalon_struct = CipherSuite::TlsAes128GcmSha256;
618
619 codec_roundtrip(etalon_struct, etalon_bytes, ());
620 }
621
622 #[test]
623 fn key_update_request() {
624 let etalon_bytes = &[0x01];
625 let etalon_struct = KeyUpdateRequest::UpdateRequested;
626
627 codec_roundtrip(etalon_struct, etalon_bytes, ());
628 }
629}