2022-08-31 10:24:54 +00:00
|
|
|
use std::fs::File;
|
|
|
|
use std::io::BufReader;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use std::time::SystemTime;
|
|
|
|
|
|
|
|
use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier};
|
2022-08-31 12:36:07 +00:00
|
|
|
use rustls::{Certificate, DistinguishedNames, Error, RootCertStore};
|
2022-08-31 10:24:54 +00:00
|
|
|
use rustls_pemfile::certs;
|
|
|
|
|
|
|
|
use crate::server_config::ServerConfig;
|
|
|
|
|
|
|
|
pub struct CustomCertClientVerifier {
|
|
|
|
upstream_cert_verifier: Box<Arc<dyn ClientCertVerifier>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CustomCertClientVerifier {
|
|
|
|
pub fn new(conf: Arc<ServerConfig>) -> Self {
|
2022-08-31 12:36:07 +00:00
|
|
|
let cert_path = conf
|
|
|
|
.tls_client_auth_root_cert
|
|
|
|
.as_deref()
|
2022-08-31 10:24:54 +00:00
|
|
|
.expect("No root certificates for client authentication provided!");
|
2022-08-31 12:36:07 +00:00
|
|
|
let cert_file = &mut BufReader::new(
|
|
|
|
File::open(cert_path)
|
|
|
|
.expect("Failed to read root certificates for client authentication!"),
|
|
|
|
);
|
2022-08-31 10:24:54 +00:00
|
|
|
|
2022-08-31 12:36:07 +00:00
|
|
|
let root_certs = certs(cert_file)
|
|
|
|
.unwrap()
|
2022-08-31 10:24:54 +00:00
|
|
|
.into_iter()
|
|
|
|
.map(Certificate)
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
if root_certs.is_empty() {
|
|
|
|
log::error!("No certificates found for client authentication!");
|
|
|
|
panic!();
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut store = RootCertStore::empty();
|
|
|
|
for cert in root_certs {
|
2022-08-31 12:36:07 +00:00
|
|
|
store
|
|
|
|
.add(&cert)
|
|
|
|
.expect("Failed to add certificate to root store");
|
2022-08-31 10:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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<bool> {
|
|
|
|
Some(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
|
|
|
|
Some(vec![])
|
|
|
|
}
|
|
|
|
|
2022-08-31 12:36:07 +00:00
|
|
|
fn verify_client_cert(
|
|
|
|
&self,
|
|
|
|
end_entity: &Certificate,
|
|
|
|
intermediates: &[Certificate],
|
|
|
|
now: SystemTime,
|
|
|
|
) -> Result<ClientCertVerified, Error> {
|
|
|
|
self.upstream_cert_verifier
|
|
|
|
.verify_client_cert(end_entity, intermediates, now)
|
2022-08-31 10:24:54 +00:00
|
|
|
}
|
|
|
|
}
|