trz_gateway_common/security_configuration/
custom_server_certificate_verifier.rs

1use rustls::client::danger::ServerCertVerified;
2use rustls::pki_types::CertificateDer;
3use rustls::pki_types::ServerName;
4use rustls::pki_types::UnixTime;
5use tracing::warn;
6
7use super::TrustedStoreConfig;
8use crate::x509::signed_extension::validate_signed_extension;
9
10/// A trait to create certificate validators that may or may not have custom validation logic.
11pub trait CustomServerCertificateVerifier: Send + Sync {
12    fn has_custom_logic() -> bool {
13        true
14    }
15    fn verify_server_certificate(
16        &self,
17        end_entity: &CertificateDer<'_>,
18        intermediates: &[CertificateDer<'_>],
19        server_name: &ServerName<'_>,
20        ocsp_response: &[u8],
21        now: UnixTime,
22    ) -> Result<ServerCertVerified, rustls::Error>;
23}
24
25/// The [CustomServerCertificateVerifier] that has no custom logic, defaults to chain validation.
26pub struct ChainOnlyServerCertificateVerifier;
27impl CustomServerCertificateVerifier for ChainOnlyServerCertificateVerifier {
28    fn has_custom_logic() -> bool {
29        false
30    }
31    fn verify_server_certificate(
32        &self,
33        _end_entity: &CertificateDer<'_>,
34        _intermediates: &[CertificateDer<'_>],
35        _server_name: &ServerName<'_>,
36        _ocsp_response: &[u8],
37        _now: UnixTime,
38    ) -> Result<ServerCertVerified, rustls::Error> {
39        unreachable!()
40    }
41}
42
43/// The [CustomServerCertificateVerifier] for special client certificates with signed extension.
44pub struct SignedExtensionCertificateVerifier<C: TrustedStoreConfig> {
45    pub store: C,
46    pub signer_name: String,
47}
48
49impl<C: TrustedStoreConfig> CustomServerCertificateVerifier
50    for SignedExtensionCertificateVerifier<C>
51{
52    fn verify_server_certificate(
53        &self,
54        certificate: &CertificateDer<'_>,
55        _intermediates: &[CertificateDer<'_>],
56        _server_name: &ServerName<'_>,
57        _ocsp_response: &[u8],
58        _now: UnixTime,
59    ) -> Result<ServerCertVerified, rustls::Error> {
60        let () = validate_signed_extension(certificate, &self.store, &self.signer_name)
61            .inspect_err(|error| warn!("Failed to validate server certificate: {error}"))?;
62        Ok(ServerCertVerified::assertion())
63    }
64}