1use util::KeyingMaterialExporter;
2
3use crate::error::Result;
4use crate::option::*;
5use crate::protection_profile::*;
6
7const LABEL_EXTRACTOR_DTLS_SRTP: &str = "EXTRACTOR-dtls_srtp";
8
9#[derive(Default, Debug, Clone)]
11pub struct SessionKeys {
12 pub local_master_key: Vec<u8>,
13 pub local_master_salt: Vec<u8>,
14 pub remote_master_key: Vec<u8>,
15 pub remote_master_salt: Vec<u8>,
16}
17
18#[derive(Default)]
23pub struct Config {
24 pub keys: SessionKeys,
25 pub profile: ProtectionProfile,
26 pub local_rtp_options: Option<ContextOption>,
31 pub remote_rtp_options: Option<ContextOption>,
32
33 pub local_rtcp_options: Option<ContextOption>,
34 pub remote_rtcp_options: Option<ContextOption>,
35}
36
37impl Config {
38 pub async fn extract_session_keys_from_dtls(
42 &mut self,
43 exporter: impl KeyingMaterialExporter,
44 is_client: bool,
45 ) -> Result<()> {
46 let key_len = self.profile.key_len();
47 let salt_len = self.profile.salt_len();
48
49 let keying_material = exporter
50 .export_keying_material(
51 LABEL_EXTRACTOR_DTLS_SRTP,
52 &[],
53 (key_len * 2) + (salt_len * 2),
54 )
55 .await?;
56
57 let mut offset = 0;
58 let client_write_key = keying_material[offset..offset + key_len].to_vec();
59 offset += key_len;
60
61 let server_write_key = keying_material[offset..offset + key_len].to_vec();
62 offset += key_len;
63
64 let client_write_salt = keying_material[offset..offset + salt_len].to_vec();
65 offset += salt_len;
66
67 let server_write_salt = keying_material[offset..offset + salt_len].to_vec();
68
69 if is_client {
70 self.keys.local_master_key = client_write_key;
71 self.keys.local_master_salt = client_write_salt;
72 self.keys.remote_master_key = server_write_key;
73 self.keys.remote_master_salt = server_write_salt;
74 } else {
75 self.keys.local_master_key = server_write_key;
76 self.keys.local_master_salt = server_write_salt;
77 self.keys.remote_master_key = client_write_key;
78 self.keys.remote_master_salt = client_write_salt;
79 }
80
81 Ok(())
82 }
83}