rvoip_rtp_core/api/client/security/
mod.rs1use std::net::SocketAddr;
6use std::sync::Arc;
7use std::any::Any;
8use async_trait::async_trait;
9use tokio::net::UdpSocket;
10
11use crate::api::common::error::SecurityError;
12use crate::api::common::config::{SecurityInfo, SecurityMode, SrtpProfile};
13use crate::api::server::security::SocketHandle;
14use crate::dtls::{DtlsConfig, DtlsRole};
15
16pub mod default;
18pub mod dtls;
19pub mod srtp;
20pub mod fingerprint;
21pub mod packet;
22
23pub use default::DefaultClientSecurityContext;
25
26#[derive(Debug, Clone)]
28pub struct ClientSecurityConfig {
29 pub security_mode: SecurityMode,
31 pub fingerprint_algorithm: String,
33 pub remote_fingerprint: Option<String>,
35 pub remote_fingerprint_algorithm: Option<String>,
37 pub validate_fingerprint: bool,
39 pub srtp_profiles: Vec<SrtpProfile>,
41 pub certificate_path: Option<String>,
43 pub private_key_path: Option<String>,
45 pub srtp_key: Option<Vec<u8>>,
47}
48
49impl Default for ClientSecurityConfig {
50 fn default() -> Self {
51 Self {
52 security_mode: SecurityMode::DtlsSrtp,
53 fingerprint_algorithm: "sha-256".to_string(),
54 remote_fingerprint: None,
55 remote_fingerprint_algorithm: None,
56 validate_fingerprint: true,
57 srtp_profiles: vec![
58 SrtpProfile::AesCm128HmacSha1_80,
59 SrtpProfile::AesGcm128,
60 ],
61 certificate_path: None,
62 private_key_path: None,
63 srtp_key: None,
64 }
65 }
66}
67
68pub(crate) fn convert_to_dtls_profile(profile: SrtpProfile) -> crate::dtls::message::extension::SrtpProtectionProfile {
70 match profile {
71 SrtpProfile::AesCm128HmacSha1_80 => crate::dtls::message::extension::SrtpProtectionProfile::Aes128CmSha1_80,
72 SrtpProfile::AesCm128HmacSha1_32 => crate::dtls::message::extension::SrtpProtectionProfile::Aes128CmSha1_32,
73 SrtpProfile::AesGcm128 => crate::dtls::message::extension::SrtpProtectionProfile::AeadAes128Gcm,
74 SrtpProfile::AesGcm256 => crate::dtls::message::extension::SrtpProtectionProfile::AeadAes256Gcm,
75 }
76}
77
78pub(crate) fn create_dtls_config(config: &ClientSecurityConfig) -> DtlsConfig {
80 if config.srtp_profiles.is_empty() {
82 panic!("No SRTP profiles specified in client security config");
83 }
84
85 let dtls_profiles: Vec<crate::dtls::message::extension::SrtpProtectionProfile> = config.srtp_profiles.iter()
87 .map(|p| convert_to_dtls_profile(*p))
88 .collect();
89
90 let mut dtls_config = DtlsConfig::default();
92 dtls_config.role = DtlsRole::Client;
93
94 let crypto_suites: Vec<crate::srtp::SrtpCryptoSuite> = dtls_profiles.iter()
96 .map(|profile| match profile {
97 &crate::dtls::message::extension::SrtpProtectionProfile::Aes128CmSha1_80 =>
98 crate::srtp::SRTP_AES128_CM_SHA1_80,
99 &crate::dtls::message::extension::SrtpProtectionProfile::Aes128CmSha1_32 =>
100 crate::srtp::SRTP_AES128_CM_SHA1_32,
101 &crate::dtls::message::extension::SrtpProtectionProfile::AeadAes128Gcm =>
102 crate::srtp::SRTP_AEAD_AES_128_GCM,
103 &crate::dtls::message::extension::SrtpProtectionProfile::AeadAes256Gcm =>
104 crate::srtp::SRTP_AEAD_AES_256_GCM,
105 &crate::dtls::message::extension::SrtpProtectionProfile::Unknown(_) =>
106 panic!("Unknown SRTP protection profile specified"), })
108 .collect();
109
110 if crypto_suites.is_empty() {
112 panic!("Failed to map any SRTP profiles to crypto suites");
113 }
114
115 dtls_config.srtp_profiles = crypto_suites;
117
118 dtls_config.mtu = 1200;
120 dtls_config.max_retransmissions = 5;
121
122 dtls_config
123}
124
125#[async_trait]
130pub trait ClientSecurityContext: Send + Sync {
131 async fn initialize(&self) -> Result<(), SecurityError>;
133
134 async fn start_handshake(&self) -> Result<(), SecurityError>;
136
137 async fn is_handshake_complete(&self) -> Result<bool, SecurityError>;
139
140 async fn wait_for_handshake(&self) -> Result<(), SecurityError>;
142
143 async fn set_remote_address(&self, addr: SocketAddr) -> Result<(), SecurityError>;
145
146 async fn set_socket(&self, socket: SocketHandle) -> Result<(), SecurityError>;
148
149 async fn set_remote_fingerprint(&self, fingerprint: &str, algorithm: &str) -> Result<(), SecurityError>;
151
152 async fn complete_handshake(&self, remote_addr: SocketAddr, remote_fingerprint: &str) -> Result<(), SecurityError>;
155
156 async fn process_packet(&self, data: &[u8]) -> Result<(), SecurityError>;
159
160 async fn start_packet_handler(&self) -> Result<(), SecurityError>;
164
165 async fn get_security_info(&self) -> Result<SecurityInfo, SecurityError>;
167
168 async fn close(&self) -> Result<(), SecurityError>;
170
171 async fn is_ready(&self) -> Result<bool, SecurityError>;
174
175 fn is_secure(&self) -> bool;
177
178 fn get_security_info_sync(&self) -> SecurityInfo;
181
182 async fn get_fingerprint(&self) -> Result<String, SecurityError>;
184
185 async fn get_fingerprint_algorithm(&self) -> Result<String, SecurityError>;
187
188 async fn has_transport(&self) -> Result<bool, SecurityError>;
190
191 async fn process_dtls_packet(&self, data: &[u8]) -> Result<(), SecurityError>;
193
194 fn get_config(&self) -> &ClientSecurityConfig;
196
197 fn as_any(&self) -> &dyn Any;
199}