use crate::{GurtError, Result}; use rustls::{ClientConfig, ServerConfig}; use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use tokio_rustls::{TlsConnector, TlsAcceptor}; use std::sync::Arc; pub const TLS_VERSION: &str = "TLS/1.3"; pub const GURT_ALPN: &[u8] = b"GURT/1.0"; #[derive(Debug, Clone)] pub struct TlsConfig { pub client_config: Option>, pub server_config: Option>, } impl TlsConfig { pub fn new_client() -> Result { let mut config = ClientConfig::builder() .with_root_certificates(rustls::RootCertStore::empty()) .with_no_client_auth(); config.alpn_protocols = vec![GURT_ALPN.to_vec()]; Ok(Self { client_config: Some(Arc::new(config)), server_config: None, }) } pub fn new_server(cert_chain: Vec>, private_key: PrivateKeyDer<'static>) -> Result { let mut config = ServerConfig::builder() .with_no_client_auth() .with_single_cert(cert_chain, private_key) .map_err(|e| GurtError::crypto(format!("TLS server config error: {}", e)))?; config.alpn_protocols = vec![GURT_ALPN.to_vec()]; Ok(Self { client_config: None, server_config: Some(Arc::new(config)), }) } pub fn get_connector(&self) -> Result { let config = self.client_config.as_ref() .ok_or_else(|| GurtError::crypto("No client config available"))?; Ok(TlsConnector::from(config.clone())) } pub fn get_acceptor(&self) -> Result { let config = self.server_config.as_ref() .ok_or_else(|| GurtError::crypto("No server config available"))?; Ok(TlsAcceptor::from(config.clone())) } } #[derive(Debug)] pub struct CryptoManager { tls_config: Option, } impl CryptoManager { pub fn new() -> Self { Self { tls_config: None, } } pub fn with_tls_config(config: TlsConfig) -> Self { Self { tls_config: Some(config), } } pub fn set_tls_config(&mut self, config: TlsConfig) { self.tls_config = Some(config); } pub fn has_tls_config(&self) -> bool { self.tls_config.is_some() } pub fn get_tls_connector(&self) -> Result { let config = self.tls_config.as_ref() .ok_or_else(|| GurtError::crypto("No TLS config available"))?; config.get_connector() } pub fn get_tls_acceptor(&self) -> Result { let config = self.tls_config.as_ref() .ok_or_else(|| GurtError::crypto("No TLS config available"))?; config.get_acceptor() } } impl Default for CryptoManager { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_tls_config_creation() { let client_config = TlsConfig::new_client(); assert!(client_config.is_ok()); let config = client_config.unwrap(); assert!(config.client_config.is_some()); assert!(config.server_config.is_none()); } #[test] fn test_crypto_manager() { let crypto = CryptoManager::new(); assert!(!crypto.has_tls_config()); } }