104 lines
3.3 KiB
Rust
104 lines
3.3 KiB
Rust
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<ClientCertVerified, Error> {
|
|
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<HandshakeSignatureValid, Error> {
|
|
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<HandshakeSignatureValid, Error> {
|
|
let supported_schemes = self.provider.signature_verification_algorithms;
|
|
verify_tls13_signature(message, cert, dss, &supported_schemes)
|
|
}
|
|
|
|
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
|
self.provider
|
|
.signature_verification_algorithms
|
|
.supported_schemes()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct RaTlsServerCertResolver {
|
|
cert: Arc<CertifiedKey>,
|
|
}
|
|
|
|
impl RaTlsServerCertResolver {
|
|
pub fn new() -> Result<Self, RaTlsError> {
|
|
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<Arc<CertifiedKey>> {
|
|
Some(self.cert.clone())
|
|
}
|
|
}
|
|
|
|
impl RaTlsConfigBuilder<ServerConfig> for ServerConfig {
|
|
fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
|
|
Ok(Self::builder()
|
|
.with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config)))
|
|
.with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?)))
|
|
}
|
|
}
|