trz_gateway_common/security_configuration/certificate/
cache.rs

1use std::convert::Infallible;
2use std::sync::Arc;
3
4use nameth::nameth;
5use openssl::x509::X509;
6
7use super::CertificateConfig;
8use super::X509CertificateInfo;
9use crate::security_configuration::common::get_or_init;
10
11/// A [CertificateConfig] that computes the certificate and intermediates once,
12/// and then memoizes the results.
13pub struct MemoizedCertificate<C> {
14    base: C,
15    intermediates: std::sync::Mutex<Option<Arc<Vec<X509>>>>,
16    certificate: std::sync::Mutex<Option<Arc<X509CertificateInfo>>>,
17}
18
19impl<C> MemoizedCertificate<C> {
20    /// Creates a [MemoizedCertificate] based on a certificate.
21    pub fn new(base: C) -> Self {
22        Self {
23            base,
24            intermediates: Default::default(),
25            certificate: Default::default(),
26        }
27    }
28}
29
30impl<C: CertificateConfig> CertificateConfig for MemoizedCertificate<C> {
31    type Error = C::Error;
32
33    fn intermediates(&self) -> Result<Arc<Vec<X509>>, Self::Error> {
34        get_or_init(&self.intermediates, || self.base.intermediates())
35    }
36
37    fn certificate(&self) -> Result<Arc<X509CertificateInfo>, Self::Error> {
38        get_or_init(&self.certificate, || self.base.certificate())
39    }
40}
41
42/// A [CertificateConfig] that contains the pre-computed X509 objects.
43///
44/// Computing certificate and intermediates from a [CachedCertificate] is thus an infallible operation.
45#[nameth]
46#[derive(Clone)]
47pub struct CachedCertificate {
48    intermediates: Arc<Vec<X509>>,
49    certificate: Arc<X509CertificateInfo>,
50}
51
52impl CachedCertificate {
53    /// Creates a [CachedCertificate] based on a certificate.
54    pub fn new<C: CertificateConfig>(base: C) -> Result<Self, C::Error> {
55        Ok(Self {
56            intermediates: base.intermediates()?,
57            certificate: base.certificate()?,
58        })
59    }
60}
61
62impl CertificateConfig for CachedCertificate {
63    type Error = Infallible;
64
65    fn intermediates(&self) -> Result<Arc<Vec<X509>>, Self::Error> {
66        Ok(self.intermediates.clone())
67    }
68
69    fn certificate(&self) -> Result<Arc<X509CertificateInfo>, Self::Error> {
70        Ok(self.certificate.clone())
71    }
72}
73
74mod debug {
75    use nameth::NamedType as _;
76
77    use super::CachedCertificate;
78    use super::MemoizedCertificate;
79
80    impl<C: std::fmt::Debug> std::fmt::Debug for MemoizedCertificate<C> {
81        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82            f.debug_struct("MemoizedCertificate")
83                .field("base", &self.base)
84                .finish()
85        }
86    }
87
88    impl std::fmt::Debug for CachedCertificate {
89        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90            f.debug_struct(CachedCertificate::type_name())
91                .field("intermediates", &self.intermediates)
92                .field("certificate", &self.certificate)
93                .finish()
94        }
95    }
96}