use crate::{ racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder}, RaTlsConfig, RaTlsConfigBuilder, RaTlsError, }; use rustls::client::danger::HandshakeSignatureValid; use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider}; use rustls::pki_types::{CertificateDer, UnixTime}; use rustls::{ server::{danger::ClientCertVerified, danger::ClientCertVerifier, ResolvesServerCert}, sign::CertifiedKey, DigitallySignedStruct, DistinguishedName, Error, ServerConfig, SignatureScheme, }; use std::sync::Arc; #[derive(Debug)] pub struct RaTlsClientCertVerifier { config: RaTlsConfig, provider: CryptoProvider, } impl RaTlsClientCertVerifier { pub fn new(config: RaTlsConfig) -> Self { Self { config, provider: aws_lc_rs::default_provider(), // FIPS certified provider } } } impl ClientCertVerifier for RaTlsClientCertVerifier { fn root_hint_subjects(&self) -> &[DistinguishedName] { &[] // TODO: check if any names are needed } fn verify_client_cert( &self, end_entity: &CertificateDer, _intermediates: &[CertificateDer], _now: UnixTime, ) -> Result { end_entity.verify_quote(&self.config).map_err(|e| { log::log!(log::Level::Error, "{}", e); Error::General(e.to_string()) })?; Ok(ClientCertVerified::assertion()) } // TLS 1.2 signature verification from the AWS libcrypto fn verify_tls12_signature( &self, message: &[u8], cert: &CertificateDer<'_>, dss: &DigitallySignedStruct, ) -> Result { let supported_schemes = self.provider.signature_verification_algorithms; verify_tls12_signature(message, cert, dss, &supported_schemes) } // TLS 1.3 signature verification from the AWS libcrypto fn verify_tls13_signature( &self, message: &[u8], cert: &CertificateDer<'_>, dss: &DigitallySignedStruct, ) -> Result { let supported_schemes = self.provider.signature_verification_algorithms; verify_tls13_signature(message, cert, dss, &supported_schemes) } fn supported_verify_schemes(&self) -> Vec { self.provider .signature_verification_algorithms .supported_schemes() } } #[derive(Debug)] pub struct RaTlsServerCertResolver { cert: Arc, } impl RaTlsServerCertResolver { pub fn new() -> Result { let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string()); let cert = builder.build().map(Arc::new)?; Ok(Self { cert }) } } impl ResolvesServerCert for RaTlsServerCertResolver { fn resolve(&self, _client_hello: rustls::server::ClientHello) -> Option> { Some(self.cert.clone()) } } impl RaTlsConfigBuilder for ServerConfig { fn from_ratls_config(config: RaTlsConfig) -> Result { Ok(Self::builder() .with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config))) .with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?))) } }