rtc_dtls/
state.rs

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
13// State holds the dtls connection state and implements both encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
14pub struct State {
15    pub(crate) local_epoch: u16,
16    pub(crate) remote_epoch: u16,
17    pub(crate) local_sequence_number: Vec<u64>, // uint48
18    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>>, // nil if a cipher_suite hasn't been chosen
22
23    pub(crate) srtp_protection_profile: SrtpProtectionProfile, // Negotiated srtp_protection_profile
24    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, // Did we get a CertificateRequest
39    pub(crate) local_certificates_verify: Vec<u8>, // cache CertificateVerify
40    pub(crate) local_verify_data: Vec<u8>,         // cached VerifyData
41    pub(crate) local_key_signature: Vec<u8>,       // cached keySignature
42    pub(crate) peer_certificates_verified: bool,
43    //pub(crate) replay_detector: Vec<Box<dyn ReplayDetector>>,
44}
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, // nil if a cipher_suite hasn't been chosen
71
72            srtp_protection_profile: SrtpProtectionProfile::Unsupported, // Negotiated srtp_protection_profile
73            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, // Did we get a CertificateRequest
88            local_certificates_verify: vec![],   // cache CertificateVerify
89            local_verify_data: vec![],           // cached VerifyData
90            local_key_signature: vec![],         // cached keySignature
91            peer_certificates_verified: false,
92            //replay_detector: vec![],
93        }
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        // Set epoch values
143        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        // Set random values
154        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        // Set master secret
163        self.master_secret.clone_from(&serialized.master_secret);
164
165        // Set cipher suite
166        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        // Set remote certificate
171        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    // marshal_binary is a binary.BinaryMarshaler.marshal_binary implementation
206    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    // unmarshal_binary is a binary.BinaryUnmarshaler.unmarshal_binary implementation
216    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    /// export_keying_material returns length bytes of exported key material in a new
238    /// slice as defined in RFC 5705.
239    /// This allows protocols to use DTLS for key establishment, but
240    /// then use some of the keying material for their own purposes
241    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}