mailin_embedded/
rtls.rs

1use crate::ssl::{SslConfig, Stream};
2use crate::Error;
3use rustls::pki_types::{CertificateDer, PrivateKeyDer};
4use rustls::{Error as TLSError, ServerConfig, ServerConnection, StreamOwned};
5use std::fs;
6use std::io::BufReader;
7use std::net::TcpStream;
8use std::sync::Arc;
9
10// Rustls wrapper
11#[derive(Clone)]
12pub struct SslImpl {
13    tls_config: Arc<ServerConfig>,
14}
15
16impl Stream for StreamOwned<ServerConnection, TcpStream> {}
17
18impl From<TLSError> for Error {
19    fn from(error: TLSError) -> Self {
20        let msg = error.to_string();
21        Error::with_source(msg, error)
22    }
23}
24
25impl SslImpl {
26    pub fn setup(ssl_config: SslConfig) -> Result<Option<Self>, Error> {
27        let config = match ssl_config {
28            SslConfig::Trusted {
29                cert_path,
30                key_path,
31                chain_path,
32            } => {
33                let mut certs = load_certs(&cert_path)?;
34                let mut chain = load_certs(&chain_path)?;
35                certs.append(&mut chain);
36                let key = load_key(&key_path)?;
37                let config = ServerConfig::builder()
38                    .with_no_client_auth()
39                    .with_single_cert(certs, key)?;
40                Some(config)
41            }
42            SslConfig::SelfSigned {
43                cert_path,
44                key_path,
45            } => {
46                let certs = load_certs(&cert_path)?;
47                let key = load_key(&key_path)?;
48                let config = ServerConfig::builder()
49                    .with_no_client_auth()
50                    .with_single_cert(certs, key)?;
51                Some(config)
52            }
53            _ => None,
54        };
55        let ret = config.map(|c| SslImpl {
56            tls_config: Arc::new(c),
57        });
58        Ok(ret)
59    }
60
61    pub fn accept(&self, stream: TcpStream) -> Result<impl Stream, Error> {
62        let session = ServerConnection::new(self.tls_config.clone())?;
63        let tls_stream = StreamOwned::new(session, stream);
64        Ok(tls_stream)
65    }
66}
67
68fn load_certs(filename: &str) -> Result<Vec<CertificateDer<'static>>, Error> {
69    let certfile = fs::File::open(filename)?;
70    let mut reader = BufReader::new(certfile);
71    let ret: Result<Vec<_>, _> = rustls_pemfile::certs(&mut reader).collect();
72    ret.map_err(|_| Error::new("Unparseable certificates"))
73}
74
75fn load_key(filename: &str) -> Result<PrivateKeyDer<'static>, Error> {
76    // Prefer to load pkcs8 keys
77    let keyfile = fs::File::open(filename)?;
78    let mut reader = BufReader::new(keyfile);
79    let Some(key) = rustls_pemfile::private_key(&mut reader)
80        .map_err(|_| Error::new("Unparseable PKCS8 key"))?
81    else {
82        return Err(Error::new("No private certificate keys found in pem"));
83    };
84    Ok(key)
85}