1use crate::{option::*, protection_profile::*};
2use shared::{crypto::KeyingMaterialExporter, error::Result};
3
4const LABEL_EXTRACTOR_DTLS_SRTP: &str = "EXTRACTOR-dtls_srtp";
5
6#[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#[derive(Default)]
20pub struct Config {
21 pub keys: SessionKeys,
22 pub profile: ProtectionProfile,
23 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 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}