use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::debug;
use crate::api::common::config::{SecurityInfo, SrtpProfile};
use crate::api::common::error::SecurityError;
use crate::api::server::security::{ServerSecurityConfig, SocketHandle};
use crate::dtls::DtlsConnection;
pub async fn initialize_security_context(
_config: &ServerSecurityConfig,
_socket: Option<SocketHandle>,
connection_template: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<(), SecurityError> {
debug!("Initializing server security context");
let template = connection_template.lock().await;
if template.is_none() {
return Err(SecurityError::Configuration(
"DTLS connection template not initialized".to_string(),
));
}
Ok(())
}
pub async fn get_security_info(
config: &ServerSecurityConfig,
connection_template: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<SecurityInfo, SecurityError> {
let fingerprint = match get_fingerprint_from_template(connection_template).await {
Ok(fp) => Some(fp),
Err(_) => None,
};
let security_info = SecurityInfo {
mode: config.security_mode,
fingerprint: fingerprint,
fingerprint_algorithm: Some(config.fingerprint_algorithm.clone()),
crypto_suites: config
.srtp_profiles
.iter()
.map(|p| match p {
SrtpProfile::AesCm128HmacSha1_80 => "AES_CM_128_HMAC_SHA1_80",
SrtpProfile::AesCm128HmacSha1_32 => "AES_CM_128_HMAC_SHA1_32",
SrtpProfile::AesGcm128 => "AEAD_AES_128_GCM",
SrtpProfile::AesGcm256 => "AEAD_AES_256_GCM",
})
.map(|s| s.to_string())
.collect(),
key_params: None,
srtp_profile: Some("AES_CM_128_HMAC_SHA1_80".to_string()),
};
Ok(security_info)
}
pub async fn is_security_context_ready(
socket: &Arc<Mutex<Option<SocketHandle>>>,
connection_template: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<bool, SecurityError> {
let socket_set = socket.lock().await.is_some();
let connection_initialized = connection_template.lock().await.is_some();
let certificate_initialized = get_fingerprint_from_template(connection_template)
.await
.is_ok();
let is_ready = socket_set && connection_initialized && certificate_initialized;
debug!("Server security context ready: {}", is_ready);
debug!(" - Socket set: {}", socket_set);
debug!(" - Connection initialized: {}", connection_initialized);
debug!(" - Certificate initialized: {}", certificate_initialized);
Ok(is_ready)
}
pub async fn get_fingerprint_from_template(
connection_template: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<String, SecurityError> {
let template = connection_template.lock().await;
if let Some(template) = template.as_ref() {
if let Some(cert) = template.local_certificate() {
let mut cert_copy = cert.clone();
match cert_copy.fingerprint("SHA-256") {
Ok(fingerprint) => Ok(fingerprint),
Err(e) => Err(SecurityError::Internal(format!(
"Failed to get fingerprint: {}",
e
))),
}
} else {
Err(SecurityError::Configuration(
"No certificate available".to_string(),
))
}
} else {
Err(SecurityError::Configuration(
"DTLS connection template not initialized".to_string(),
))
}
}
pub async fn get_fingerprint_algorithm_from_template(
_connection_template: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<String, SecurityError> {
Ok("sha-256".to_string())
}