use crate::error::{ZitiError, ZitiResult};
use crate::identity::IdentityManager;
use rustls::{ClientConfig, RootCertStore};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct TlsConfig {
client_config: Arc<ClientConfig>,
}
impl Default for TlsConfig {
fn default() -> Self {
Self::new()
}
}
impl TlsConfig {
pub fn from_identity(identity: &IdentityManager) -> ZitiResult<Self> {
let mut root_store = identity.credentials().ca_store.clone();
root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
let client_config = ClientConfig::builder()
.with_root_certificates(root_store)
.with_client_auth_cert(
identity.credentials().certificate_chain.clone(),
identity.credentials().private_key.clone_key(),
)
.map_err(|e| ZitiError::ConfigError(format!("Failed to create TLS config: {}", e)))?;
Ok(Self {
client_config: Arc::new(client_config),
})
}
pub fn client_config(&self) -> Arc<ClientConfig> {
self.client_config.clone()
}
pub fn new() -> Self {
let root_store = RootCertStore::empty();
let client_config = ClientConfig::builder()
.with_root_certificates(root_store)
.with_no_client_auth();
Self {
client_config: Arc::new(client_config),
}
}
}
pub fn build_client_config(identity: &IdentityManager) -> ZitiResult<Arc<ClientConfig>> {
let tls_config = TlsConfig::from_identity(identity)?;
Ok(tls_config.client_config())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tls_config_new() {
let config = TlsConfig::new();
assert!(config.client_config.clone().alpn_protocols.is_empty());
}
}