d_engine_core/config/
tls.rs1use std::fs;
2use std::path::Path;
3
4use config::ConfigError;
5use serde::Deserialize;
6use serde::Serialize;
7
8use crate::Error;
9use crate::Result;
10
11#[derive(Debug, Serialize, Deserialize, Clone)]
12#[allow(dead_code)]
13pub struct TlsConfig {
14 #[serde(default = "default_enable_tls")]
17 pub enable_tls: bool,
18
19 #[serde(default = "default_generate_self_signed")]
22 pub generate_self_signed_certificates: bool,
23
24 #[serde(default = "default_ca_path")]
27 pub certificate_authority_root_path: String,
28
29 #[serde(default = "default_server_cert_path")]
32 pub server_certificate_path: String,
33
34 #[serde(default = "default_server_key_path")]
37 pub server_private_key_path: String,
38
39 #[serde(default = "default_client_ca_path")]
42 pub client_certificate_authority_root_path: String,
43
44 #[serde(default = "default_enable_mtls")]
47 pub enable_mtls: bool,
48}
49impl Default for TlsConfig {
50 fn default() -> Self {
51 Self {
52 enable_tls: default_enable_tls(),
53 generate_self_signed_certificates: default_generate_self_signed(),
54 certificate_authority_root_path: default_ca_path(),
55 server_certificate_path: default_server_cert_path(),
56 server_private_key_path: default_server_key_path(),
57 client_certificate_authority_root_path: default_client_ca_path(),
58 enable_mtls: default_enable_mtls(),
59 }
60 }
61}
62
63impl TlsConfig {
64 pub fn validate(&self) -> Result<()> {
72 if self.enable_mtls && !self.enable_tls {
74 return Err(Error::Config(ConfigError::Message(
75 "mTLS requires enable_tls to be true".into(),
76 )));
77 }
78
79 if !self.enable_tls {
81 return Ok(());
82 }
83
84 if self.generate_self_signed_certificates {
86 if !self.server_certificate_path.is_empty() || !self.server_private_key_path.is_empty()
87 {
88 return Err(Error::Config(ConfigError::Message(
89 "Cannot specify certificate paths with generate_self_signed_certificates=true"
90 .into(),
91 )));
92 }
93
94 if self.enable_mtls {
95 self.validate_cert_file(
96 &self.client_certificate_authority_root_path,
97 "client CA certificate",
98 )?;
99 }
100
101 return Ok(());
102 }
103
104 self.validate_cert_file(&self.server_certificate_path, "server certificate")?;
106 self.validate_key_file(&self.server_private_key_path, "server private key")?;
107 self.validate_cert_file(&self.certificate_authority_root_path, "CA certificate")?;
108
109 if self.enable_mtls {
111 self.validate_cert_file(
112 &self.client_certificate_authority_root_path,
113 "client CA certificate",
114 )?;
115 }
116
117 Ok(())
118 }
119
120 fn validate_cert_file(
122 &self,
123 path: &str,
124 name: &str,
125 ) -> Result<()> {
126 let path = Path::new(path);
127
128 if path.exists() {
129 {
130 fs::File::open(path).map_err(|e| {
132 Error::Config(ConfigError::Message(format!(
133 "{} file {} is unreadable: {}",
134 name,
135 path.display(),
136 e
137 )))
138 })?;
139 }
140 Ok(())
141 } else {
142 Err(Error::Config(ConfigError::Message(format!(
143 "{} file {} not found",
144 name,
145 path.display()
146 ))))
147 }
148 }
149
150 fn validate_key_file(
152 &self,
153 path: &str,
154 name: &str,
155 ) -> Result<()> {
156 let path = Path::new(path);
157
158 if path.exists() {
159 {
160 let metadata = fs::metadata(path).map_err(|e| {
162 Error::Config(ConfigError::Message(format!(
163 "Cannot access {} permissions: {}",
164 path.display(),
165 e
166 )))
167 })?;
168
169 #[cfg(unix)]
170 {
171 use std::os::unix::fs::PermissionsExt;
172 let mode = metadata.permissions().mode();
173 if mode & 0o777 != 0o600 {
174 return Err(Error::Config(ConfigError::Message(format!(
175 "Insecure permissions {:o} for {} (should be 600)",
176 mode & 0o777,
177 path.display()
178 ))));
179 }
180 }
181 }
182 Ok(())
183 } else {
184 Err(Error::Config(ConfigError::Message(format!(
185 "{} file {} not found",
186 name,
187 path.display()
188 ))))
189 }
190 }
191}
192fn default_enable_tls() -> bool {
194 false
195}
196fn default_generate_self_signed() -> bool {
197 false
198}
199fn default_ca_path() -> String {
200 "/etc/ssl/certs/ca.pem".into()
201}
202fn default_server_cert_path() -> String {
203 "./certs/server.pem".into()
204}
205fn default_server_key_path() -> String {
206 "./certs/server.key".into()
207}
208fn default_client_ca_path() -> String {
209 "/etc/ssl/certs/ca.pem".into()
210}
211fn default_enable_mtls() -> bool {
212 false
213}