use std::sync::Arc;
use hive_router_config::traffic_shaping::ServerTLSConfig;
use hive_router_plan_executor::executors::{
error::TlsCertificatesError, tls::from_cert_file_config_to_certificate_der,
};
use rustls::{
pki_types::{pem::PemObject, PrivateKeyDer},
server::{NoClientAuth, WebPkiClientVerifier},
RootCertStore, ServerConfig,
};
pub fn build_rustls_config(
tls_config: &ServerTLSConfig,
) -> Result<ServerConfig, TlsCertificatesError> {
let client_auth = if let Some(client_auth_config) = tls_config.client_auth.as_ref() {
let certs = from_cert_file_config_to_certificate_der(&client_auth_config.cert_file)?;
let mut roots = RootCertStore::empty();
roots.add_parsable_certificates(certs);
let builder = WebPkiClientVerifier::builder(roots.into());
let required = client_auth_config.required.unwrap_or(true);
if required {
builder.build()?
} else {
builder.allow_unauthenticated().build()?
}
} else {
Arc::new(NoClientAuth)
};
let certs = from_cert_file_config_to_certificate_der(&tls_config.cert_file)?;
let key = PrivateKeyDer::from_pem_file(&tls_config.key_file.absolute)
.map_err(|err| TlsCertificatesError::CustomTlsCertificatesError("key_file", err))?;
Ok(ServerConfig::builder()
.with_client_cert_verifier(client_auth)
.with_single_cert(certs, key)?)
}