trz_gateway_common/security_configuration/
mod.rs

1use std::sync::Arc;
2
3use openssl::x509::X509;
4use openssl::x509::store::X509Store;
5
6use self::certificate::CertificateConfig;
7use self::trusted_store::TrustedStoreConfig;
8use crate::certificate_info::X509CertificateInfo;
9use crate::dynamic_config::DynamicConfig;
10use crate::dynamic_config::mode::Mode;
11use crate::is_global::IsGlobal;
12
13pub mod certificate;
14pub mod common;
15pub mod custom_server_certificate_verifier;
16pub mod either;
17pub mod trusted_store;
18
19/// A security config has both a trusted store and a client certificate.
20///
21/// - This is used to configure the client certificate issuer: we need both
22///     1. When issuing client certificates: the certificate (+intermediates)
23///        to sign the CMS extension.
24///     2. When validating client certificates: the trusted roots to validate
25///        the issuing cert in the signed CMS extension
26/// - This is also used to configure the Root CA
27///     - The Root CA doesn't need to be secure. It's just there to sanity
28///       check client certs are owned by us before the custom validation logic
29///       kicks in.
30///     - The Root CA is the issuer of client certificates. Technically we need
31///       an issuer, but the real validation is the CMS extension.
32#[derive(Clone, Debug)]
33pub struct SecurityConfig<T, C> {
34    pub trusted_store: T,
35    pub certificate: C,
36}
37
38impl<T: TrustedStoreConfig, C: IsGlobal> TrustedStoreConfig for SecurityConfig<T, C> {
39    type Error = T::Error;
40
41    fn root_certificates(&self) -> Result<Arc<X509Store>, Self::Error> {
42        self.trusted_store.root_certificates()
43    }
44}
45
46impl<T: IsGlobal, C: CertificateConfig> CertificateConfig for SecurityConfig<T, C> {
47    type Error = C::Error;
48
49    fn intermediates(&self) -> Result<Arc<Vec<X509>>, Self::Error> {
50        self.certificate.intermediates()
51    }
52
53    fn certificate(&self) -> Result<Arc<X509CertificateInfo>, Self::Error> {
54        self.certificate.certificate()
55    }
56
57    fn is_dynamic(&self) -> bool {
58        self.certificate.is_dynamic()
59    }
60}
61
62/// A trait that combines [TrustedStoreConfig] + [CertificateConfig]
63///
64/// Typically implemented using [SecurityConfig] struct.
65pub trait HasSecurityConfig: TrustedStoreConfig + CertificateConfig {}
66impl<T: TrustedStoreConfig + CertificateConfig> HasSecurityConfig for T {}
67
68/// A trait similar to [HasSecurityConfig] but dynamic.
69pub trait HasDynamicSecurityConfig {
70    type HasSecurityConfig: HasSecurityConfig + Clone + std::fmt::Debug;
71    fn as_dyn(&self) -> Arc<DynamicConfig<Self::HasSecurityConfig, impl Mode>>;
72}
73
74impl<T, M> HasDynamicSecurityConfig for Arc<DynamicConfig<T, M>>
75where
76    T: HasSecurityConfig + Clone + std::fmt::Debug,
77    M: Mode,
78{
79    type HasSecurityConfig = T;
80
81    fn as_dyn(&self) -> Arc<DynamicConfig<Self::HasSecurityConfig, impl Mode>> {
82        self.clone()
83    }
84}