Skip to main content

kipuka/config/
cms_est.rs

1//! CMS-wrapped EST configuration (RFC 8295).
2//!
3//! The `[cms_est]` section enables EST endpoints that use CMS
4//! message-level security instead of TLS for authentication and
5//! confidentiality.  This supports disconnected/air-gapped
6//! deployments where a TLS-terminating proxy handles transport.
7
8use serde::Deserialize;
9
10/// `[cms_est]` section — CMS message-level security for EST.
11///
12/// ```toml
13/// [cms_est]
14/// enabled = true
15/// require_signed_requests = true
16/// encrypt_responses = true
17/// allowed_content_encryption = ["AES-256-GCM", "AES-128-GCM"]
18/// ```
19#[derive(Debug, Clone, Deserialize)]
20#[serde(deny_unknown_fields)]
21pub struct CmsEstConfig {
22    /// Enable CMS-wrapped EST endpoints.
23    #[serde(default)]
24    pub enabled: bool,
25
26    /// Require CMS SignedData wrapping on all requests.
27    #[serde(default = "default_true")]
28    pub require_signed_requests: bool,
29
30    /// Encrypt responses using CMS EnvelopedData.
31    #[serde(default = "default_true")]
32    pub encrypt_responses: bool,
33
34    /// Allowed content-encryption algorithms for CMS EnvelopedData.
35    #[serde(default = "default_allowed_content_encryption")]
36    pub allowed_content_encryption: Vec<String>,
37}
38
39fn default_true() -> bool {
40    true
41}
42
43fn default_allowed_content_encryption() -> Vec<String> {
44    vec!["AES-256-GCM".to_string(), "AES-128-GCM".to_string()]
45}
46
47impl Default for CmsEstConfig {
48    fn default() -> Self {
49        Self {
50            enabled: false,
51            require_signed_requests: true,
52            encrypt_responses: true,
53            allowed_content_encryption: default_allowed_content_encryption(),
54        }
55    }
56}
57
58impl CmsEstConfig {
59    /// Validate CMS-EST configuration constraints.
60    pub fn validate(&self) -> Result<(), String> {
61        if self.encrypt_responses && self.allowed_content_encryption.is_empty() {
62            return Err(
63                "[cms_est].allowed_content_encryption must not be empty when encrypt_responses is true"
64                    .into(),
65            );
66        }
67
68        Ok(())
69    }
70}