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