1use super::cipher_suite::*;
2use super::conn::*;
3use super::curve::named_curve::*;
4use super::extension::extension_use_srtp::SrtpProtectionProfile;
5use super::handshake::handshake_random::*;
6use super::prf::*;
7use rkyv::{Archive, Deserialize, Serialize};
8use shared::crypto::KeyingMaterialExporter;
9use shared::error::*;
10use std::io::{BufWriter, Cursor};
11
12pub struct State {
16 pub(crate) local_epoch: u16,
17 pub(crate) remote_epoch: u16,
18 pub(crate) local_sequence_number: Vec<u64>, pub(crate) local_random: HandshakeRandom,
20 pub(crate) remote_random: HandshakeRandom,
21 pub(crate) master_secret: Vec<u8>,
22 pub(crate) cipher_suite: Option<Box<dyn CipherSuite>>, pub(crate) srtp_protection_profile: SrtpProtectionProfile, pub peer_certificates: Vec<Vec<u8>>,
29 pub identity_hint: Vec<u8>,
31
32 pub(crate) is_client: bool,
33
34 pub(crate) pre_master_secret: Vec<u8>,
35 pub(crate) extended_master_secret: bool,
36
37 pub(crate) named_curve: NamedCurve,
38 pub(crate) local_keypair: Option<NamedCurveKeypair>,
39 pub(crate) cookie: Vec<u8>,
40 pub(crate) handshake_send_sequence: isize,
41 pub(crate) handshake_recv_sequence: isize,
42 pub(crate) server_name: String,
43 pub(crate) remote_requested_certificate: bool, pub(crate) local_certificates_verify: Vec<u8>, pub(crate) local_verify_data: Vec<u8>, pub(crate) local_key_signature: Vec<u8>, pub(crate) peer_certificates_verified: bool,
48 }
50
51#[derive(Archive, Serialize, Deserialize, PartialEq, Debug)]
52struct SerializedState {
53 local_epoch: u16,
54 remote_epoch: u16,
55 local_random: [u8; HANDSHAKE_RANDOM_LENGTH],
56 remote_random: [u8; HANDSHAKE_RANDOM_LENGTH],
57 cipher_suite_id: u16,
58 master_secret: Vec<u8>,
59 sequence_number: u64,
60 srtp_protection_profile: u16,
61 peer_certificates: Vec<Vec<u8>>,
62 identity_hint: Vec<u8>,
63 is_client: bool,
64}
65
66impl Default for State {
67 fn default() -> Self {
68 State {
69 local_epoch: 0,
70 remote_epoch: 0,
71 local_sequence_number: vec![],
72 local_random: HandshakeRandom::default(),
73 remote_random: HandshakeRandom::default(),
74 master_secret: vec![],
75 cipher_suite: None, srtp_protection_profile: SrtpProtectionProfile::Unsupported, peer_certificates: vec![],
79 identity_hint: vec![],
80
81 is_client: false,
82
83 pre_master_secret: vec![],
84 extended_master_secret: false,
85
86 named_curve: NamedCurve::Unsupported,
87 local_keypair: None,
88 cookie: vec![],
89 handshake_send_sequence: 0,
90 handshake_recv_sequence: 0,
91 server_name: "".to_string(),
92 remote_requested_certificate: false, local_certificates_verify: vec![], local_verify_data: vec![], local_key_signature: vec![], peer_certificates_verified: false,
97 }
99 }
100}
101
102impl State {
103 fn serialize(&self) -> Result<SerializedState> {
104 let mut local_rand = vec![];
105 {
106 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_rand.as_mut());
107 self.local_random.marshal(&mut writer)?;
108 }
109 let mut remote_rand = vec![];
110 {
111 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_rand.as_mut());
112 self.remote_random.marshal(&mut writer)?;
113 }
114
115 let mut local_random = [0u8; HANDSHAKE_RANDOM_LENGTH];
116 let mut remote_random = [0u8; HANDSHAKE_RANDOM_LENGTH];
117
118 local_random.copy_from_slice(&local_rand);
119 remote_random.copy_from_slice(&remote_rand);
120
121 let local_epoch = self.local_epoch;
122 let remote_epoch = self.remote_epoch;
123 let sequence_number = self.local_sequence_number[local_epoch as usize];
124 let cipher_suite_id = {
125 match &self.cipher_suite {
126 Some(cipher_suite) => cipher_suite.id() as u16,
127 None => return Err(Error::ErrCipherSuiteUnset),
128 }
129 };
130
131 Ok(SerializedState {
132 local_epoch,
133 remote_epoch,
134 local_random,
135 remote_random,
136 cipher_suite_id,
137 master_secret: self.master_secret.clone(),
138 sequence_number,
139 srtp_protection_profile: self.srtp_protection_profile as u16,
140 peer_certificates: self.peer_certificates.clone(),
141 identity_hint: self.identity_hint.clone(),
142 is_client: self.is_client,
143 })
144 }
145
146 fn deserialize(&mut self, serialized: &SerializedState) -> Result<()> {
147 self.local_epoch = serialized.local_epoch;
149 self.remote_epoch = serialized.remote_epoch;
150 {
151 while self.local_sequence_number.len() <= serialized.local_epoch as usize {
152 self.local_sequence_number.push(0);
153 }
154 self.local_sequence_number[serialized.local_epoch as usize] =
155 serialized.sequence_number;
156 }
157
158 let mut reader = Cursor::new(&serialized.local_random);
160 self.local_random = HandshakeRandom::unmarshal(&mut reader)?;
161
162 let mut reader = Cursor::new(&serialized.remote_random);
163 self.remote_random = HandshakeRandom::unmarshal(&mut reader)?;
164
165 self.is_client = serialized.is_client;
166
167 self.master_secret.clone_from(&serialized.master_secret);
169
170 self.cipher_suite = Some(cipher_suite_for_id(serialized.cipher_suite_id.into())?);
172
173 self.srtp_protection_profile = serialized.srtp_protection_profile.into();
174
175 self.peer_certificates
177 .clone_from(&serialized.peer_certificates);
178 self.identity_hint.clone_from(&serialized.identity_hint);
179
180 Ok(())
181 }
182
183 pub fn init_cipher_suite(&mut self) -> Result<()> {
189 if let Some(cipher_suite) = &mut self.cipher_suite {
190 if cipher_suite.is_initialized() {
191 return Ok(());
192 }
193
194 let mut local_random = vec![];
195 {
196 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_random.as_mut());
197 self.local_random.marshal(&mut writer)?;
198 }
199 let mut remote_random = vec![];
200 {
201 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_random.as_mut());
202 self.remote_random.marshal(&mut writer)?;
203 }
204
205 if self.is_client {
206 cipher_suite.init(&self.master_secret, &local_random, &remote_random, true)
207 } else {
208 cipher_suite.init(&self.master_secret, &remote_random, &local_random, false)
209 }
210 } else {
211 Err(Error::ErrCipherSuiteUnset)
212 }
213 }
214
215 pub fn marshal_binary(&self) -> Result<Vec<u8>> {
222 let serialized = self.serialize()?;
223
224 match rkyv::to_bytes::<rkyv::rancor::Error>(&serialized).map(Vec::from) {
225 Ok(enc) => Ok(enc),
226 Err(err) => Err(Error::Other(err.to_string())),
227 }
228 }
229
230 pub fn unmarshal_binary(&mut self, data: &[u8]) -> Result<()> {
237 let serialized: SerializedState =
238 match rkyv::access::<ArchivedSerializedState, rkyv::rancor::Error>(data)
239 .and_then(rkyv::deserialize)
240 {
241 Ok(dec) => dec,
242 Err(err) => return Err(Error::Other(err.to_string())),
243 };
244 self.deserialize(&serialized)?;
245 self.init_cipher_suite()?;
246
247 Ok(())
248 }
249
250 pub fn srtp_protection_profile(&self) -> SrtpProtectionProfile {
252 self.srtp_protection_profile
253 }
254
255 pub fn is_client(&self) -> bool {
257 self.is_client
258 }
259
260 pub fn cipher_suite(&self) -> Option<&dyn CipherSuite> {
262 self.cipher_suite.as_deref()
263 }
264}
265
266impl KeyingMaterialExporter for State {
267 fn export_keying_material(
272 &self,
273 label: &str,
274 context: &[u8],
275 length: usize,
276 ) -> shared::error::Result<Vec<u8>> {
277 if self.local_epoch == 0 {
278 return Err(Error::HandshakeInProgress);
279 } else if !context.is_empty() {
280 return Err(Error::ContextUnsupported);
281 } else if INVALID_KEYING_LABELS.contains(&label) {
282 return Err(Error::ReservedExportKeyingMaterial);
283 }
284
285 let mut local_random = vec![];
286 {
287 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_random.as_mut());
288 self.local_random.marshal(&mut writer)?;
289 }
290 let mut remote_random = vec![];
291 {
292 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_random.as_mut());
293 self.remote_random.marshal(&mut writer)?;
294 }
295
296 let mut seed = label.as_bytes().to_vec();
297 if self.is_client {
298 seed.extend_from_slice(&local_random);
299 seed.extend_from_slice(&remote_random);
300 } else {
301 seed.extend_from_slice(&remote_random);
302 seed.extend_from_slice(&local_random);
303 }
304
305 if let Some(cipher_suite) = &self.cipher_suite {
306 match prf_p_hash(&self.master_secret, &seed, length, cipher_suite.hash_func()) {
307 Ok(v) => Ok(v),
308 Err(err) => Err(Error::Hash(err.to_string())),
309 }
310 } else {
311 Err(Error::CipherSuiteUnset)
312 }
313 }
314}