1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#[cfg(test)]
mod handshake_message_server_hello_test;
use super::handshake_random::*;
use super::*;
use crate::cipher_suite::*;
use crate::compression_methods::*;
use crate::extension::*;
use crate::record_layer::record_layer_header::*;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::fmt;
use std::io::{BufReader, BufWriter};
#[derive(Clone)]
pub struct HandshakeMessageServerHello {
pub(crate) version: ProtocolVersion,
pub(crate) random: HandshakeRandom,
pub(crate) cipher_suite: CipherSuiteID,
pub(crate) compression_method: CompressionMethodId,
pub(crate) extensions: Vec<Extension>,
}
impl PartialEq for HandshakeMessageServerHello {
fn eq(&self, other: &Self) -> bool {
self.version == other.version
&& self.random == other.random
&& self.compression_method == other.compression_method
&& self.extensions == other.extensions
&& self.cipher_suite == other.cipher_suite
}
}
impl fmt::Debug for HandshakeMessageServerHello {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = vec![
format!("version: {:?} random: {:?}", self.version, self.random),
format!("cipher_suites: {:?}", self.cipher_suite),
format!("compression_method: {:?}", self.compression_method),
format!("extensions: {:?}", self.extensions),
];
write!(f, "{}", s.join(" "))
}
}
impl HandshakeMessageServerHello {
pub fn handshake_type(&self) -> HandshakeType {
HandshakeType::ServerHello
}
pub fn size(&self) -> usize {
let mut len = 2 + self.random.size();
len += 1;
len += 2;
len += 1;
len += 2;
for extension in &self.extensions {
len += extension.size();
}
len
}
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
writer.write_u8(self.version.major)?;
writer.write_u8(self.version.minor)?;
self.random.marshal(writer)?;
writer.write_u8(0x00)?;
writer.write_u16::<BigEndian>(self.cipher_suite as u16)?;
writer.write_u8(self.compression_method as u8)?;
let mut extension_buffer = vec![];
{
let mut extension_writer = BufWriter::<&mut Vec<u8>>::new(extension_buffer.as_mut());
for extension in &self.extensions {
extension.marshal(&mut extension_writer)?;
}
}
writer.write_u16::<BigEndian>(extension_buffer.len() as u16)?;
writer.write_all(&extension_buffer)?;
Ok(writer.flush()?)
}
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self, Error> {
let major = reader.read_u8()?;
let minor = reader.read_u8()?;
let random = HandshakeRandom::unmarshal(reader)?;
reader.read_u8()?;
let cipher_suite: CipherSuiteID = reader.read_u16::<BigEndian>()?.into();
let compression_method = reader.read_u8()?.into();
let mut extensions = vec![];
let extension_buffer_len = reader.read_u16::<BigEndian>()? as usize;
let mut extension_buffer = vec![0u8; extension_buffer_len];
reader.read_exact(&mut extension_buffer)?;
let mut extension_reader = BufReader::new(extension_buffer.as_slice());
let mut offset = 0;
while offset < extension_buffer_len {
let extension = Extension::unmarshal(&mut extension_reader)?;
extensions.push(extension);
let extension_len =
u16::from_be_bytes([extension_buffer[offset + 2], extension_buffer[offset + 3]])
as usize;
offset += 4 + extension_len;
}
Ok(HandshakeMessageServerHello {
version: ProtocolVersion { major, minor },
random,
cipher_suite,
compression_method,
extensions,
})
}
}