Merged all workspace projects into a single binary project

This commit is contained in:
2022-09-01 10:11:24 +02:00
parent 3be4c5a68e
commit b24e8ba68b
19 changed files with 96 additions and 123 deletions

View File

@ -0,0 +1,103 @@
use std::sync::Arc;
use std::time::SystemTime;
use rustls::internal::msgs::enums::AlertDescription;
use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier};
use rustls::{Certificate, DistinguishedNames, Error, RootCertStore};
use x509_parser::prelude::{CertificateRevocationList, FromDer, X509Certificate};
use crate::base::cert_utils::parse_pem_certificates;
use crate::tcp_relay_server::server_config::ServerConfig;
pub struct CustomCertClientVerifier {
upstream_cert_verifier: Box<Arc<dyn ClientCertVerifier>>,
crl: Option<Vec<u8>>,
}
impl CustomCertClientVerifier {
pub fn new(conf: Arc<ServerConfig>) -> Self {
// Build root certifications list
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");
}
// Parse CRL file (if any)
let crl = if let Some(crl_file) = &conf.tls_revocation_list {
let crl_file = std::fs::read(crl_file).expect("Failed to open / read CRL file!");
let parsed_crl = pem::parse(crl_file).expect("Failed to decode CRL file!");
Some(parsed_crl.contents)
} else {
None
};
Self {
upstream_cert_verifier: Box::new(AllowAnyAuthenticatedClient::new(store)),
crl,
}
}
}
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![])
}
fn verify_client_cert(
&self,
end_entity: &Certificate,
intermediates: &[Certificate],
now: SystemTime,
) -> Result<ClientCertVerified, Error> {
// Check the certificates sent by the client has been revoked
if let Some(crl) = &self.crl {
let (_rem, crl) =
CertificateRevocationList::from_der(crl).expect("Failed to read CRL!");
let (_rem, cert) =
X509Certificate::from_der(&end_entity.0).expect("Failed to read certificate!");
for revoked in crl.iter_revoked_certificates() {
if revoked.user_certificate == cert.serial {
log::error!(
"Client attempted to use a revoked certificate! Serial={:?} Subject={}",
cert.serial,
cert.subject
);
return Err(Error::AlertReceived(AlertDescription::CertificateRevoked));
}
}
}
self.upstream_cert_verifier
.verify_client_cert(end_entity, intermediates, now)
}
}