use std::sync::Arc; use std::time::SystemTime; use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier}; use rustls::{Certificate, DistinguishedNames, Error, RootCertStore}; use base::cert_utils::parse_pem_certificates; use crate::server_config::ServerConfig; pub struct CustomCertClientVerifier { upstream_cert_verifier: Box>, } impl CustomCertClientVerifier { pub fn new(conf: Arc) -> Self { let cert_path = conf .tls_client_auth_root_cert .as_deref() .expect("No root certificates for client authentication provided!"); let cert_file = std::fs::read(cert_path) .expect("Failed to read root certificates for client authentication!"); let root_certs = parse_pem_certificates(&cert_file) .expect("Failed to read root certificates for server authentication!"); if root_certs.is_empty() { log::error!("No certificates found for client authentication!"); panic!(); } let mut store = RootCertStore::empty(); for cert in root_certs { store .add(&cert) .expect("Failed to add certificate to root store"); } Self { upstream_cert_verifier: Box::new(AllowAnyAuthenticatedClient::new(store)), } } } impl ClientCertVerifier for CustomCertClientVerifier { fn offer_client_auth(&self) -> bool { true } fn client_auth_mandatory(&self) -> Option { Some(true) } fn client_auth_root_subjects(&self) -> Option { Some(vec![]) } fn verify_client_cert( &self, end_entity: &Certificate, intermediates: &[Certificate], now: SystemTime, ) -> Result { self.upstream_cert_verifier .verify_client_cert(end_entity, intermediates, now) } }