rtc_srtp/
config.rs

1use crate::{option::*, protection_profile::*};
2use shared::{crypto::KeyingMaterialExporter, error::Result};
3
4const LABEL_EXTRACTOR_DTLS_SRTP: &str = "EXTRACTOR-dtls_srtp";
5
6/// SessionKeys bundles the keys required to setup an SRTP session
7#[derive(Default, Debug, Clone)]
8pub struct SessionKeys {
9    pub local_master_key: Vec<u8>,
10    pub local_master_salt: Vec<u8>,
11    pub remote_master_key: Vec<u8>,
12    pub remote_master_salt: Vec<u8>,
13}
14
15/// Config is used to configure a session.
16/// You can provide either a KeyingMaterialExporter to export keys
17/// or directly pass the keys themselves.
18/// After a Config is passed to a session it must not be modified.
19#[derive(Default)]
20pub struct Config {
21    pub keys: SessionKeys,
22    pub profile: ProtectionProfile,
23    //LoggerFactory: logging.LoggerFactory
24    /// List of local/remote context options.
25    /// ReplayProtection is enabled on remote context by default.
26    /// Default replay protection window size is 64.
27    pub local_rtp_options: Option<ContextOption>,
28    pub remote_rtp_options: Option<ContextOption>,
29
30    pub local_rtcp_options: Option<ContextOption>,
31    pub remote_rtcp_options: Option<ContextOption>,
32}
33
34impl Config {
35    /// ExtractSessionKeysFromDTLS allows setting the Config SessionKeys by
36    /// extracting them from DTLS. This behavior is defined in RFC5764:
37    /// <https://tools.ietf.org/html/rfc5764>
38    pub fn extract_session_keys_from_dtls(
39        &mut self,
40        exporter: &impl KeyingMaterialExporter,
41        is_client: bool,
42    ) -> Result<()> {
43        let key_len = self.profile.key_len();
44        let salt_len = self.profile.salt_len();
45
46        let keying_material = exporter.export_keying_material(
47            LABEL_EXTRACTOR_DTLS_SRTP,
48            &[],
49            (key_len * 2) + (salt_len * 2),
50        )?;
51
52        let mut offset = 0;
53        let client_write_key = keying_material[offset..offset + key_len].to_vec();
54        offset += key_len;
55
56        let server_write_key = keying_material[offset..offset + key_len].to_vec();
57        offset += key_len;
58
59        let client_write_salt = keying_material[offset..offset + salt_len].to_vec();
60        offset += salt_len;
61
62        let server_write_salt = keying_material[offset..offset + salt_len].to_vec();
63
64        if is_client {
65            self.keys.local_master_key = client_write_key;
66            self.keys.local_master_salt = client_write_salt;
67            self.keys.remote_master_key = server_write_key;
68            self.keys.remote_master_salt = server_write_salt;
69        } else {
70            self.keys.local_master_key = server_write_key;
71            self.keys.local_master_salt = server_write_salt;
72            self.keys.remote_master_key = client_write_key;
73            self.keys.remote_master_salt = client_write_salt;
74        }
75
76        Ok(())
77    }
78}