trz_gateway_common/security_configuration/certificate/
cache.rs1use 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
11pub 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 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#[nameth]
46#[derive(Clone)]
47pub struct CachedCertificate {
48 intermediates: Arc<Vec<X509>>,
49 certificate: Arc<X509CertificateInfo>,
50}
51
52impl CachedCertificate {
53 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}