trz_gateway_common/security_configuration/trusted_store/
cache.rs

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