net_wire/tls/
handshake.rs1use super::{
3 error::{TlsBuildError, TlsParseError},
4 hello::{ClientHello, ServerHello},
5 types::TlsHandshakeType,
6};
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub struct TlsHandshake<'a> {
10 bytes: &'a [u8],
11}
12impl<'a> TlsHandshake<'a> {
13 pub fn parse(bytes: &'a [u8]) -> Result<Self, TlsParseError> {
15 let total = declared(bytes)?;
16 Ok(Self {
17 bytes: &bytes[..total],
18 })
19 }
20 pub fn handshake_type(&self) -> TlsHandshakeType {
22 TlsHandshakeType::new(self.bytes[0])
23 }
24 pub fn body(&self) -> &'a [u8] {
26 &self.bytes[4..]
27 }
28 pub fn as_bytes(&self) -> &'a [u8] {
30 self.bytes
31 }
32 pub fn client_hello(&self) -> Result<Option<ClientHello<'a>>, TlsParseError> {
34 if self.handshake_type() == TlsHandshakeType::CLIENT_HELLO {
35 ClientHello::parse(self.body()).map(Some)
36 } else {
37 Ok(None)
38 }
39 }
40 pub fn server_hello(&self) -> Result<Option<ServerHello<'a>>, TlsParseError> {
42 if self.handshake_type() == TlsHandshakeType::SERVER_HELLO {
43 ServerHello::parse(self.body()).map(Some)
44 } else {
45 Ok(None)
46 }
47 }
48}
49pub struct TlsHandshakeBuilder<'a, 'b> {
51 buffer: &'a mut [u8],
52 handshake_type: TlsHandshakeType,
53 body: &'b [u8],
54}
55impl<'a, 'b> TlsHandshakeBuilder<'a, 'b> {
56 pub fn new(buffer: &'a mut [u8], handshake_type: TlsHandshakeType, body: &'b [u8]) -> Self {
58 Self {
59 buffer,
60 handshake_type,
61 body,
62 }
63 }
64 pub fn build(self) -> Result<&'a mut [u8], TlsBuildError> {
66 if self.body.len() > 0x00ff_ffff {
67 return Err(TlsBuildError::LengthTooLarge);
68 }
69 let total = 4usize
70 .checked_add(self.body.len())
71 .ok_or(TlsBuildError::LengthTooLarge)?;
72 if self.buffer.len() < total {
73 return Err(TlsBuildError::BufferTooShort {
74 required: total,
75 available: self.buffer.len(),
76 });
77 }
78 let bytes = &mut self.buffer[..total];
79 bytes[0] = self.handshake_type.raw();
80 let len = self.body.len() as u32;
81 bytes[1] = (len >> 16) as u8;
82 bytes[2] = (len >> 8) as u8;
83 bytes[3] = len as u8;
84 bytes[4..].copy_from_slice(self.body);
85 Ok(bytes)
86 }
87}
88fn declared(bytes: &[u8]) -> Result<usize, TlsParseError> {
89 if bytes.len() < 4 {
90 return Err(TlsParseError::Incomplete {
91 required: 4,
92 available: bytes.len(),
93 });
94 }
95 let body = (usize::from(bytes[1]) << 16) | (usize::from(bytes[2]) << 8) | usize::from(bytes[3]);
96 let total = 4 + body;
97 if bytes.len() < total {
98 return Err(TlsParseError::Incomplete {
99 required: total,
100 available: bytes.len(),
101 });
102 }
103 Ok(total)
104}