pavex/tls/client/config.rs
1//! Configure the TLS policy for a client.
2//!
3//! Check out the documentation for [`TlsClientPolicyConfig`](super::TlsClientPolicyConfig) for
4//! a detailed explanation of the available configuration options.
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8// Wrapped into a sub-module to avoid exposing `TlsClientPolicyConfig` in two places:
9// inside `pavex::tls::config` and `pavex::tls::client`.
10// We only want users to see `pavex::tls::client::TlsClientPolicyConfig`.
11pub(crate) mod _config {
12 use super::*;
13
14 /// Configure the TLS policy for a client.
15 ///
16 /// It covers:
17 /// - The [cryptographic stack](`Self::crypto_provider`) used to secure the connection.
18 /// - Which [TLS versions](`Self::allowed_versions`) are allowed.
19 /// - The [certificate verification](`Self::certificate_verification`) mechanism used to verify server certificates.
20 ///
21 /// For testing/development purposes only, it exposes a few [insecure](`Self::insecure`) configuration options
22 /// that lower the security posture of your client.
23 ///
24 /// # Defaults
25 ///
26 /// The default configuration should be suitable for most production environments:
27 ///
28 /// ```yaml
29 #[doc = include_str!("../../../tests/fixtures/tls_config/default.yaml")]
30 /// ```
31 ///
32 /// # Overriding the default configuration
33 ///
34 /// If you want to deviate from the default configuration, it's enough to specify the fields you
35 /// want to override.
36 ///
37 /// ## Example: Disable TLS 1.2
38 ///
39 /// ```yaml
40 #[doc = include_str!("../../../tests/fixtures/tls_config/disable_tls_1_2.yaml")]
41 /// ```
42 ///
43 /// ## Example: Trust additional root certificates
44 ///
45 /// ```yaml
46 #[doc = include_str!("../../../tests/fixtures/tls_config/additional_roots.yaml")]
47 /// ```
48 ///
49 /// ## Example: Disable certificate verification
50 ///
51 /// ```yaml
52 #[doc = include_str!("../../../tests/fixtures/tls_config/skip_verification.yaml")]
53 /// ```
54 #[derive(Debug, Default, Clone, Deserialize, Serialize)]
55 #[non_exhaustive]
56 pub struct TlsClientPolicyConfig {
57 /// The cryptographic stack used to secure the connection.
58 ///
59 /// Refer to the documentation for [`CryptoProviderConfig`]
60 /// for more details.
61 #[serde(default)]
62 #[serde(with = "serde_yaml::with::singleton_map_recursive")]
63 pub crypto_provider: CryptoProviderConfig,
64 /// Which TLS versions are allowed.
65 ///
66 /// Refer to the documentation for [`AllowedTlsVersionsConfig`]
67 /// for more details.
68 #[serde(default)]
69 pub allowed_versions: AllowedTlsVersionsConfig,
70 /// The mechanism used to verify server certificates.
71 ///
72 /// Refer to the documentation for [`CertificateVerificationConfig`]
73 /// for more details.
74 #[serde(default)]
75 pub certificate_verification: CertificateVerificationConfig,
76 /// Dangerous configuration options that lower the security
77 /// posture of your client.
78 ///
79 /// These options should never be used in production scenarios.
80 /// They are available for testing/development purposes only.
81 #[serde(default)]
82 pub insecure: InsecureTlsClientConfig,
83 }
84}
85
86/// Which TLS versions are allowed.
87///
88/// By default, TLS 1.2 and TLS 1.3 are enabled.
89///
90/// # Security
91///
92/// The lack of support for TLS 1.0 and TLS 1.1 is intentional.
93#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
94#[non_exhaustive]
95pub struct AllowedTlsVersionsConfig {
96 /// Enables TLS 1.2 if `true`.
97 ///
98 /// It requires the server to support TLS 1.2.
99 #[serde(default = "default_v1_2")]
100 pub v1_2: bool,
101 /// Enables TLS 1.3 if `true`.
102 ///
103 /// It requires the server to support TLS 1.3.
104 #[serde(default = "default_v1_3")]
105 pub v1_3: bool,
106}
107
108fn default_v1_2() -> bool {
109 true
110}
111
112fn default_v1_3() -> bool {
113 true
114}
115
116impl Default for AllowedTlsVersionsConfig {
117 fn default() -> Self {
118 Self {
119 v1_2: default_v1_2(),
120 v1_3: default_v1_3(),
121 }
122 }
123}
124
125/// Configure how server certificates are verified.
126///
127/// # Default
128///
129/// By default, we rely on verification machinery of the underlying operating system.
130/// Refer to the documentation for [`rustls-platform-verifier`](https://docs.rs/rustls-platform-verifier/latest/rustls_platform_verifier/)
131/// for more information on how each platform handles certificate verification.
132///
133/// # Customization
134///
135/// Set [`additional_roots`][`CertificateVerificationConfig::additional_roots`] to trust
136/// additional root certificates in addition to the ones already trusted
137/// by the operating system.
138///
139/// # Skipping Verification
140///
141/// If you want to skip certificate verification altogether, check out the [`insecure`][`super::TlsClientPolicyConfig::insecure`]
142/// options in [`TlsClientPolicyConfig`][`super::TlsClientPolicyConfig`].
143///
144/// ## Incorrect Usage
145///
146/// Setting [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] to `false`, with
147/// no [`additional_roots`][`CertificateVerificationConfig::additional_roots`] specified, does **not**
148/// disable certificate verification. It does instead cause all certificate verification attempts to fail.
149///
150/// We treat this scenario as a misconfiguration and return an error at runtime, when
151/// trying to initialize the client.
152#[derive(Debug, Clone, Deserialize, Serialize)]
153#[non_exhaustive]
154pub struct CertificateVerificationConfig {
155 /// Whether to use the certificate verification machinery provided by
156 /// the underlying operating system.
157 ///
158 /// Defaults to `true`.
159 #[serde(default = "default_use_os_verifier")]
160 pub use_os_verifier: bool,
161 /// Trust one or more additional root certificates.
162 ///
163 /// If [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] is `false`,
164 /// these will be the only trusted root certificates.
165 /// If [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] is `true`, these will be
166 /// trusted **in addition** to the ones already trusted by the underlying operating system.
167 ///
168 /// They can either be loaded from files or inlined in configuration.
169 #[serde(default)]
170 #[serde(with = "serde_yaml::with::singleton_map_recursive")]
171 pub additional_roots: Vec<RootCertificate>,
172}
173
174fn default_use_os_verifier() -> bool {
175 true
176}
177
178impl Default for CertificateVerificationConfig {
179 fn default() -> Self {
180 CertificateVerificationConfig {
181 use_os_verifier: default_use_os_verifier(),
182 additional_roots: Default::default(),
183 }
184 }
185}
186
187/// [Additional root certificates](`CertificateVerificationConfig::additional_roots`) to be trusted.
188#[derive(Debug, Clone, Deserialize, Serialize)]
189#[serde(rename_all = "snake_case")]
190#[non_exhaustive]
191pub enum RootCertificate {
192 /// Retrieve the root certificate from a file.
193 File {
194 /// How to decode the root certificate inside the file.
195 encoding: RootCertificateFileEncoding,
196 /// The path to the root certificate file.
197 path: PathBuf,
198 },
199 /// A root certificate inlined inside the provided configuration.
200 Inline {
201 /// A PEM-encoded X.509 certificate; as specified in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5).
202 data: String,
203 },
204}
205
206/// Supported encodings for the root certificate in [`RootCertificate::File`].
207#[derive(Debug, Clone, Deserialize, Serialize)]
208#[serde(rename_all = "snake_case")]
209#[non_exhaustive]
210pub enum RootCertificateFileEncoding {
211 /// A DER-encoded X.509 certificate; as specified in [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1).
212 Der,
213 /// A PEM-encoded X.509 certificate; as specified in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5).
214 Pem,
215}
216
217/// Dangerous configuration options to lower the security posture of a TLS client.
218#[derive(Debug, Clone, Deserialize, Serialize)]
219#[non_exhaustive]
220pub struct InsecureTlsClientConfig {
221 /// Don't verify server certificates.
222 ///
223 /// Extremely dangerous option, limit its usage to local development environments.
224 #[serde(default = "default_skip_verification")]
225 pub skip_verification: bool,
226}
227
228impl Default for InsecureTlsClientConfig {
229 fn default() -> Self {
230 InsecureTlsClientConfig {
231 skip_verification: default_skip_verification(),
232 }
233 }
234}
235
236fn default_skip_verification() -> bool {
237 false
238}
239
240/// Which implementation to use for TLS cryptographic operations.
241#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize)]
242#[serde(rename_all = "snake_case")]
243#[non_exhaustive]
244pub enum CryptoProviderConfig {
245 /// Use [`aws-lc-rs`](https://docs.rs/aws-lc-rs/) for cryptographic operations.
246 ///
247 /// If you require FIPS compliance, use the [`AwsLcRsFips`][`CryptoProviderConfig::AwsLcRsFips`]
248 /// instead.
249 #[default]
250 AwsLcRs,
251 /// Use [`aws-lc-rs`](https://docs.rs/aws-lc-rs/) for cryptographic operations,
252 /// in FIPS-compliant mode.
253 ///
254 /// # Additional constraints
255 ///
256 /// FIPS mode is not supported on all platforms.
257 /// Furthermore, `aws-lc-rs` requires additional system dependencies at build time.
258 /// Check out their [documentation](https://docs.rs/aws-lc-rs/latest/aws_lc_rs/#fips) for
259 /// more information.
260 AwsLcRsFips,
261 /// Use [`ring`](https://docs.rs/ring/) for cryptographic operations.
262 Ring,
263}