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>,
11 pub local_master_salt: Vec<u8>,
13 pub remote_master_key: Vec<u8>,
15 pub remote_master_salt: Vec<u8>,
17}
18
19#[derive(Default)]
24pub struct Config {
25 pub keys: SessionKeys,
27 pub profile: ProtectionProfile,
29 pub local_rtp_options: Option<ContextOption>,
34 pub remote_rtp_options: Option<ContextOption>,
36
37 pub local_rtcp_options: Option<ContextOption>,
39 pub remote_rtcp_options: Option<ContextOption>,
41}
42
43impl Config {
44 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}