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 shared::error::*;
8
9use serde::{Deserialize, Serialize};
10use shared::crypto::KeyingMaterialExporter;
11use std::io::{BufWriter, Cursor};
12
13pub struct State {
15 pub(crate) local_epoch: u16,
16 pub(crate) remote_epoch: u16,
17 pub(crate) local_sequence_number: Vec<u64>, pub(crate) local_random: HandshakeRandom,
19 pub(crate) remote_random: HandshakeRandom,
20 pub(crate) master_secret: Vec<u8>,
21 pub(crate) cipher_suite: Option<Box<dyn CipherSuite>>, pub(crate) srtp_protection_profile: SrtpProtectionProfile, pub peer_certificates: Vec<Vec<u8>>,
25 pub identity_hint: Vec<u8>,
26
27 pub(crate) is_client: bool,
28
29 pub(crate) pre_master_secret: Vec<u8>,
30 pub(crate) extended_master_secret: bool,
31
32 pub(crate) named_curve: NamedCurve,
33 pub(crate) local_keypair: Option<NamedCurveKeypair>,
34 pub(crate) cookie: Vec<u8>,
35 pub(crate) handshake_send_sequence: isize,
36 pub(crate) handshake_recv_sequence: isize,
37 pub(crate) server_name: String,
38 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,
43 }
45
46#[derive(Serialize, Deserialize, PartialEq, Debug)]
47struct SerializedState {
48 local_epoch: u16,
49 remote_epoch: u16,
50 local_random: [u8; HANDSHAKE_RANDOM_LENGTH],
51 remote_random: [u8; HANDSHAKE_RANDOM_LENGTH],
52 cipher_suite_id: u16,
53 master_secret: Vec<u8>,
54 sequence_number: u64,
55 srtp_protection_profile: u16,
56 peer_certificates: Vec<Vec<u8>>,
57 identity_hint: Vec<u8>,
58 is_client: bool,
59}
60
61impl Default for State {
62 fn default() -> Self {
63 State {
64 local_epoch: 0,
65 remote_epoch: 0,
66 local_sequence_number: vec![],
67 local_random: HandshakeRandom::default(),
68 remote_random: HandshakeRandom::default(),
69 master_secret: vec![],
70 cipher_suite: None, srtp_protection_profile: SrtpProtectionProfile::Unsupported, peer_certificates: vec![],
74 identity_hint: vec![],
75
76 is_client: false,
77
78 pre_master_secret: vec![],
79 extended_master_secret: false,
80
81 named_curve: NamedCurve::Unsupported,
82 local_keypair: None,
83 cookie: vec![],
84 handshake_send_sequence: 0,
85 handshake_recv_sequence: 0,
86 server_name: "".to_string(),
87 remote_requested_certificate: false, local_certificates_verify: vec![], local_verify_data: vec![], local_key_signature: vec![], peer_certificates_verified: false,
92 }
94 }
95}
96
97impl State {
98 fn serialize(&self) -> Result<SerializedState> {
99 let mut local_rand = vec![];
100 {
101 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_rand.as_mut());
102 self.local_random.marshal(&mut writer)?;
103 }
104 let mut remote_rand = vec![];
105 {
106 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_rand.as_mut());
107 self.remote_random.marshal(&mut writer)?;
108 }
109
110 let mut local_random = [0u8; HANDSHAKE_RANDOM_LENGTH];
111 let mut remote_random = [0u8; HANDSHAKE_RANDOM_LENGTH];
112
113 local_random.copy_from_slice(&local_rand);
114 remote_random.copy_from_slice(&remote_rand);
115
116 let local_epoch = self.local_epoch;
117 let remote_epoch = self.remote_epoch;
118 let sequence_number = self.local_sequence_number[local_epoch as usize];
119 let cipher_suite_id = {
120 match &self.cipher_suite {
121 Some(cipher_suite) => cipher_suite.id() as u16,
122 None => return Err(Error::ErrCipherSuiteUnset),
123 }
124 };
125
126 Ok(SerializedState {
127 local_epoch,
128 remote_epoch,
129 local_random,
130 remote_random,
131 cipher_suite_id,
132 master_secret: self.master_secret.clone(),
133 sequence_number,
134 srtp_protection_profile: self.srtp_protection_profile as u16,
135 peer_certificates: self.peer_certificates.clone(),
136 identity_hint: self.identity_hint.clone(),
137 is_client: self.is_client,
138 })
139 }
140
141 fn deserialize(&mut self, serialized: &SerializedState) -> Result<()> {
142 self.local_epoch = serialized.local_epoch;
144 self.remote_epoch = serialized.remote_epoch;
145 {
146 while self.local_sequence_number.len() <= serialized.local_epoch as usize {
147 self.local_sequence_number.push(0);
148 }
149 self.local_sequence_number[serialized.local_epoch as usize] =
150 serialized.sequence_number;
151 }
152
153 let mut reader = Cursor::new(&serialized.local_random);
155 self.local_random = HandshakeRandom::unmarshal(&mut reader)?;
156
157 let mut reader = Cursor::new(&serialized.remote_random);
158 self.remote_random = HandshakeRandom::unmarshal(&mut reader)?;
159
160 self.is_client = serialized.is_client;
161
162 self.master_secret.clone_from(&serialized.master_secret);
164
165 self.cipher_suite = Some(cipher_suite_for_id(serialized.cipher_suite_id.into())?);
167
168 self.srtp_protection_profile = serialized.srtp_protection_profile.into();
169
170 self.peer_certificates
172 .clone_from(&serialized.peer_certificates);
173 self.identity_hint.clone_from(&serialized.identity_hint);
174
175 Ok(())
176 }
177
178 pub fn init_cipher_suite(&mut self) -> Result<()> {
179 if let Some(cipher_suite) = &mut self.cipher_suite {
180 if cipher_suite.is_initialized() {
181 return Ok(());
182 }
183
184 let mut local_random = vec![];
185 {
186 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_random.as_mut());
187 self.local_random.marshal(&mut writer)?;
188 }
189 let mut remote_random = vec![];
190 {
191 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_random.as_mut());
192 self.remote_random.marshal(&mut writer)?;
193 }
194
195 if self.is_client {
196 cipher_suite.init(&self.master_secret, &local_random, &remote_random, true)
197 } else {
198 cipher_suite.init(&self.master_secret, &remote_random, &local_random, false)
199 }
200 } else {
201 Err(Error::ErrCipherSuiteUnset)
202 }
203 }
204
205 pub fn marshal_binary(&self) -> Result<Vec<u8>> {
207 let serialized = self.serialize()?;
208
209 match bincode::serialize(&serialized) {
210 Ok(enc) => Ok(enc),
211 Err(err) => Err(Error::Other(err.to_string())),
212 }
213 }
214
215 pub fn unmarshal_binary(&mut self, data: &[u8]) -> Result<()> {
217 let serialized: SerializedState = match bincode::deserialize(data) {
218 Ok(dec) => dec,
219 Err(err) => return Err(Error::Other(err.to_string())),
220 };
221 self.deserialize(&serialized)?;
222 self.init_cipher_suite()?;
223
224 Ok(())
225 }
226
227 pub fn srtp_protection_profile(&self) -> SrtpProtectionProfile {
228 self.srtp_protection_profile
229 }
230
231 pub fn is_client(&self) -> bool {
232 self.is_client
233 }
234}
235
236impl KeyingMaterialExporter for State {
237 fn export_keying_material(
242 &self,
243 label: &str,
244 context: &[u8],
245 length: usize,
246 ) -> shared::error::Result<Vec<u8>> {
247 if self.local_epoch == 0 {
248 return Err(Error::HandshakeInProgress);
249 } else if !context.is_empty() {
250 return Err(Error::ContextUnsupported);
251 } else if INVALID_KEYING_LABELS.contains(&label) {
252 return Err(Error::ReservedExportKeyingMaterial);
253 }
254
255 let mut local_random = vec![];
256 {
257 let mut writer = BufWriter::<&mut Vec<u8>>::new(local_random.as_mut());
258 self.local_random.marshal(&mut writer)?;
259 }
260 let mut remote_random = vec![];
261 {
262 let mut writer = BufWriter::<&mut Vec<u8>>::new(remote_random.as_mut());
263 self.remote_random.marshal(&mut writer)?;
264 }
265
266 let mut seed = label.as_bytes().to_vec();
267 if self.is_client {
268 seed.extend_from_slice(&local_random);
269 seed.extend_from_slice(&remote_random);
270 } else {
271 seed.extend_from_slice(&remote_random);
272 seed.extend_from_slice(&local_random);
273 }
274
275 if let Some(cipher_suite) = &self.cipher_suite {
276 match prf_p_hash(&self.master_secret, &seed, length, cipher_suite.hash_func()) {
277 Ok(v) => Ok(v),
278 Err(err) => Err(Error::Hash(err.to_string())),
279 }
280 } else {
281 Err(Error::CipherSuiteUnset)
282 }
283 }
284}