scratchstack_config/
tls.rs1use {
2 crate::error::{ConfigError, TlsConfigErrorKind},
3 rustls::ServerConfig,
4 rustls_pemfile::{certs, rsa_private_keys},
5 rustls_pki_types::{CertificateDer, PrivateKeyDer},
6 serde::Deserialize,
7 std::{
8 fmt::Debug,
9 fs::File,
10 io::{BufRead, BufReader},
11 },
12};
13
14#[derive(Clone, Deserialize, Debug)]
15pub struct TlsConfig {
16 pub certificate_chain_file: String,
17 pub private_key_file: String,
18}
19
20impl TlsConfig {
21 pub fn to_server_config(&self) -> Result<ServerConfig, ConfigError> {
23 let builder = ServerConfig::builder().with_no_client_auth();
24
25 let cert_file = File::open(&self.certificate_chain_file)?;
26 let mut reader = BufReader::new(cert_file);
27 let certs = read_certs(&mut reader)?;
28 if certs.is_empty() {
29 return Err(TlsConfigErrorKind::InvalidCertificate.into());
30 }
31
32 let private_key_file = File::open(&self.private_key_file)?;
33 let mut reader = BufReader::new(private_key_file);
34 let mut private_keys = read_rsa_private_keys(&mut reader)?;
35 if private_keys.len() != 1 {
36 return Err(TlsConfigErrorKind::InvalidPrivateKey.into());
37 }
38 let private_key = private_keys.remove(0);
39
40 builder
41 .with_single_cert(certs, private_key)
42 .map_err(|e| ConfigError::InvalidTlsConfig(TlsConfigErrorKind::TlsSetupFailed(e)))
43 }
44}
45
46fn read_certs(r: &mut dyn BufRead) -> Result<Vec<CertificateDer<'static>>, ConfigError> {
49 let mut result = Vec::with_capacity(2);
50 for maybe_cert in certs(r) {
51 result.push(maybe_cert?);
52 }
53 Ok(result)
54}
55
56fn read_rsa_private_keys(r: &mut dyn BufRead) -> Result<Vec<PrivateKeyDer<'static>>, ConfigError> {
59 let mut result = Vec::with_capacity(1);
60 for maybe_key in rsa_private_keys(r) {
61 result.push(maybe_key?.into());
62 }
63 Ok(result)
64}