// Stream wrapper. use rustls_pemfile::{certs, rsa_private_keys}; use std::path::Path; use std::sync::Arc; use tokio_rustls::rustls::{self, Certificate, PrivateKey}; use tokio_rustls::TlsAcceptor; use crate::config::get_config; use crate::errors::Error; // TLS pub fn load_certs(path: &Path) -> std::io::Result> { certs(&mut std::io::BufReader::new(std::fs::File::open(path)?)) .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidInput, "invalid cert")) .map(|mut certs| certs.drain(..).map(Certificate).collect()) } pub fn load_keys(path: &Path) -> std::io::Result> { rsa_private_keys(&mut std::io::BufReader::new(std::fs::File::open(path)?)) .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidInput, "invalid key")) .map(|mut keys| keys.drain(..).map(PrivateKey).collect()) } pub struct Tls { pub acceptor: TlsAcceptor, } impl Tls { pub fn new() -> Result { let config = get_config(); let certs = match load_certs(&Path::new(&config.general.tls_certificate.unwrap())) { Ok(certs) => certs, Err(_) => return Err(Error::TlsError), }; let mut keys = match load_keys(&Path::new(&config.general.tls_private_key.unwrap())) { Ok(keys) => keys, Err(_) => return Err(Error::TlsError), }; let config = match rustls::ServerConfig::builder() .with_safe_defaults() .with_no_client_auth() .with_single_cert(certs, keys.remove(0)) .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err)) { Ok(c) => c, Err(_) => return Err(Error::TlsError), }; Ok(Tls { acceptor: TlsAcceptor::from(Arc::new(config)), }) } }