rama_net/tls/server/
config.rs

1use crate::{
2    address::Host,
3    tls::{ApplicationProtocol, DataEncoding, KeyLogIntent, ProtocolVersion, client::ClientHello},
4};
5use rama_core::error::OpaqueError;
6use serde::{Deserialize, Serialize};
7use std::{num::NonZeroU64, pin::Pin, sync::Arc};
8
9#[derive(Debug, Clone)]
10/// Common API to configure a TLS Server
11pub struct ServerConfig {
12    /// required raw (PEM-encoded) server auth certs
13    pub server_auth: ServerAuth,
14
15    /// optionally provide the option expose the server cert if one is defined
16    ///
17    /// this will effectively clone the memory to keep these at hand,
18    /// so only enable this option if you need it for something specific
19    pub expose_server_cert: bool,
20
21    /// optional supported versions by the server
22    pub protocol_versions: Option<Vec<ProtocolVersion>>,
23
24    /// optional ALPNs used for protocol negotiation with the client
25    pub application_layer_protocol_negotiation: Option<Vec<ApplicationProtocol>>,
26
27    /// optionally define how client should be verified by server
28    pub client_verify_mode: ClientVerifyMode,
29
30    /// key log intent
31    pub key_logger: KeyLogIntent,
32
33    /// store client certificate chain
34    pub store_client_certificate_chain: bool,
35}
36
37impl ServerConfig {
38    /// Create a new [`ServerConfig`] using the given [`ServerAuth`].
39    pub fn new(auth: ServerAuth) -> Self {
40        Self {
41            server_auth: auth,
42            expose_server_cert: false,
43            protocol_versions: None,
44            application_layer_protocol_negotiation: None,
45            client_verify_mode: ClientVerifyMode::default(),
46            key_logger: KeyLogIntent::default(),
47            store_client_certificate_chain: false,
48        }
49    }
50}
51
52#[derive(Debug, Clone)]
53/// The kind of server auth to be used.
54pub enum ServerAuth {
55    /// Request the tls implementation to generate self-signed single data
56    SelfSigned(SelfSignedData),
57    /// Single data provided by the configurator
58    Single(ServerAuthData),
59    /// Issuer which provides certs on the fly
60    CertIssuer(ServerCertIssuerData),
61}
62
63impl Default for ServerAuth {
64    fn default() -> Self {
65        ServerAuth::SelfSigned(SelfSignedData::default())
66    }
67}
68
69#[derive(Debug, Clone, Default)]
70pub struct ServerCertIssuerData {
71    /// The kind of server cert issuer
72    pub kind: ServerCertIssuerKind,
73    /// Cache kind that will be used to cache certificates
74    pub cache_kind: CacheKind,
75}
76
77#[derive(Debug, Clone)]
78/// Cache kind that will be used to cache results of certificate issuers
79pub enum CacheKind {
80    MemCache { max_size: NonZeroU64 },
81    Disabled,
82}
83
84impl Default for CacheKind {
85    fn default() -> Self {
86        Self::MemCache {
87            max_size: NonZeroU64::new(8096).unwrap(),
88        }
89    }
90}
91
92#[derive(Debug, Clone)]
93/// A type of [`ServerAuth`] which can be used to generate
94/// server certs on the fly using the given issuer
95pub enum ServerCertIssuerKind {
96    /// Request the tls implementation to generate self-signed single data
97    SelfSigned(SelfSignedData),
98    /// Single data provided by the configurator
99    Single(ServerAuthData),
100    /// A dynamic data provider which can decide depending on client hello msg
101    Dynamic(DynamicIssuer),
102}
103
104impl Default for ServerCertIssuerKind {
105    fn default() -> Self {
106        ServerCertIssuerKind::SelfSigned(SelfSignedData::default())
107    }
108}
109
110impl<T> From<T> for ServerCertIssuerKind
111where
112    T: DynamicCertIssuer,
113{
114    fn from(issuer: T) -> Self {
115        Self::Dynamic(DynamicIssuer::new(issuer))
116    }
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, Default)]
120/// Data that can be used to configure the self-signed single data
121pub struct SelfSignedData {
122    /// name of the organisation
123    pub organisation_name: Option<String>,
124    /// common name (CN): server name protected by the SSL certificate
125    ///
126    /// (usually the host domain name)
127    pub common_name: Option<Host>,
128    /// Subject Alternative Names (SAN) can be defined
129    /// to create a cert which allows multiple hostnames or domains to be secured under one certificate.
130    pub subject_alternative_names: Option<Vec<String>>,
131}
132
133#[derive(Debug, Clone)]
134/// Raw private key and certificate data to facilitate server authentication.
135pub struct ServerAuthData {
136    /// private key used by server
137    pub private_key: DataEncoding,
138    /// certificate chain as a companion to the private key
139    pub cert_chain: DataEncoding,
140
141    /// `ocsp` is a DER-encoded OCSP response
142    pub ocsp: Option<Vec<u8>>,
143}
144
145#[derive(Clone)]
146/// Dynamic issuer which internally contains the dyn issuer
147pub struct DynamicIssuer {
148    /// Issuer not public in case we want to migrate away from dyn approach to alternative (eg channels)
149    issuer: Arc<dyn DynDynamicCertIssuer + Send + Sync>,
150}
151
152impl DynamicIssuer {
153    pub fn new<T: DynamicCertIssuer>(issuer: T) -> Self {
154        Self {
155            issuer: Arc::new(issuer),
156        }
157    }
158
159    pub async fn issue_cert(
160        &self,
161        client_hello: ClientHello,
162        server_name: Option<Host>,
163    ) -> Result<ServerAuthData, OpaqueError> {
164        self.issuer.issue_cert(client_hello, server_name).await
165    }
166}
167
168impl std::fmt::Debug for DynamicIssuer {
169    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
170        f.debug_struct("DynamicIssuer").finish()
171    }
172}
173
174/// Trait that needs to be implemented by cert issuers to support dynamically
175/// issueing (external) certs based on client_hello input.
176pub trait DynamicCertIssuer: Send + Sync + 'static {
177    fn issue_cert(
178        &self,
179        client_hello: ClientHello,
180        server_name: Option<Host>,
181    ) -> impl Future<Output = Result<ServerAuthData, OpaqueError>> + Send + Sync + '_;
182}
183
184/// Internal trait to support dynamic dispatch of trait with async fn.
185/// See trait [`rama_core::service::svc::DynService`] for more info about this pattern.
186trait DynDynamicCertIssuer {
187    fn issue_cert(
188        &self,
189        client_hello: ClientHello,
190        server_name: Option<Host>,
191    ) -> Pin<Box<dyn Future<Output = Result<ServerAuthData, OpaqueError>> + Send + Sync + '_>>;
192}
193
194impl<T> DynDynamicCertIssuer for T
195where
196    T: DynamicCertIssuer,
197{
198    fn issue_cert(
199        &self,
200        client_hello: ClientHello,
201        server_name: Option<Host>,
202    ) -> Pin<Box<dyn Future<Output = Result<ServerAuthData, OpaqueError>> + Send + Sync + '_>> {
203        Box::pin(self.issue_cert(client_hello, server_name))
204    }
205}
206
207#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
208/// Mode of client verification by a (tls) server
209pub enum ClientVerifyMode {
210    #[default]
211    /// Use the default verification approach as defined
212    /// by the implementation of the used (tls) server
213    Auto,
214    /// Explicitly disable client verification (if possible)
215    Disable,
216    /// PEM-encoded certificate chain containing the acceptable client certificates
217    ClientAuth(DataEncoding),
218}