Skip to main content

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    /// The master key used to protect outbound packets.
10    pub local_master_key: Vec<u8>,
11    /// The master salt used to protect outbound packets.
12    pub local_master_salt: Vec<u8>,
13    /// The master key used to unprotect inbound packets.
14    pub remote_master_key: Vec<u8>,
15    /// The master salt used to unprotect inbound packets.
16    pub remote_master_salt: Vec<u8>,
17}
18
19/// Config is used to configure a session.
20/// You can provide either a KeyingMaterialExporter to export keys
21/// or directly pass the keys themselves.
22/// After a Config is passed to a session it must not be modified.
23#[derive(Default)]
24pub struct Config {
25    /// The master keys and salts for both directions.
26    pub keys: SessionKeys,
27    /// The negotiated protection profile, which fixes the cipher and tag lengths.
28    pub profile: ProtectionProfile,
29    //LoggerFactory: logging.LoggerFactory
30    /// List of local/remote context options.
31    /// ReplayProtection is enabled on remote context by default.
32    /// Default replay protection window size is 64.
33    pub local_rtp_options: Option<ContextOption>,
34    /// Replay-protection options for the inbound RTP context. Enabled by default.
35    pub remote_rtp_options: Option<ContextOption>,
36
37    /// Replay-protection options for the outbound RTCP context.
38    pub local_rtcp_options: Option<ContextOption>,
39    /// Replay-protection options for the inbound RTCP context. Enabled by default.
40    pub remote_rtcp_options: Option<ContextOption>,
41}
42
43impl Config {
44    /// ExtractSessionKeysFromDTLS allows setting the Config SessionKeys by
45    /// extracting them from DTLS. This behavior is defined in RFC5764:
46    /// <https://tools.ietf.org/html/rfc5764>
47    pub fn extract_session_keys_from_dtls(
48        &mut self,
49        exporter: &impl KeyingMaterialExporter,
50        is_client: bool,
51    ) -> Result<()> {
52        let key_len = self.profile.key_len();
53        let salt_len = self.profile.salt_len();
54
55        let keying_material = exporter.export_keying_material(
56            LABEL_EXTRACTOR_DTLS_SRTP,
57            &[],
58            (key_len * 2) + (salt_len * 2),
59        )?;
60
61        let mut offset = 0;
62        let client_write_key = keying_material[offset..offset + key_len].to_vec();
63        offset += key_len;
64
65        let server_write_key = keying_material[offset..offset + key_len].to_vec();
66        offset += key_len;
67
68        let client_write_salt = keying_material[offset..offset + salt_len].to_vec();
69        offset += salt_len;
70
71        let server_write_salt = keying_material[offset..offset + salt_len].to_vec();
72
73        if is_client {
74            self.keys.local_master_key = client_write_key;
75            self.keys.local_master_salt = client_write_salt;
76            self.keys.remote_master_key = server_write_key;
77            self.keys.remote_master_salt = server_write_salt;
78        } else {
79            self.keys.local_master_key = server_write_key;
80            self.keys.local_master_salt = server_write_salt;
81            self.keys.remote_master_key = client_write_key;
82            self.keys.remote_master_salt = client_write_salt;
83        }
84
85        Ok(())
86    }
87}