diff --git a/aquatic_http/src/lib/config.rs b/aquatic_http/src/lib/config.rs index fe75932..08ccfad 100644 --- a/aquatic_http/src/lib/config.rs +++ b/aquatic_http/src/lib/config.rs @@ -1,4 +1,4 @@ -use std::net::SocketAddr; +use std::{net::SocketAddr, path::PathBuf}; use aquatic_common::access_list::AccessListConfig; use serde::{Deserialize, Serialize}; @@ -37,6 +37,8 @@ pub struct TlsConfig { pub use_tls: bool, pub tls_pkcs12_path: String, pub tls_pkcs12_password: String, + pub tls_certificate_path: PathBuf, + pub tls_private_key_path: PathBuf, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -182,6 +184,8 @@ impl Default for TlsConfig { use_tls: false, tls_pkcs12_path: "".into(), tls_pkcs12_password: "".into(), + tls_certificate_path: "".into(), + tls_private_key_path: "".into(), } } } diff --git a/aquatic_http/src/lib/glommio/mod.rs b/aquatic_http/src/lib/glommio/mod.rs index 3bb89fb..e5b577e 100644 --- a/aquatic_http/src/lib/glommio/mod.rs +++ b/aquatic_http/src/lib/glommio/mod.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, atomic::AtomicUsize}; +use std::{fs::File, io::BufReader, sync::{Arc, atomic::AtomicUsize}}; use aquatic_common::access_list::AccessList; use glommio::{channels::channel_mesh::MeshBuilder, prelude::*}; @@ -25,10 +25,13 @@ pub fn run( let num_bound_sockets = Arc::new(AtomicUsize::new(0)); + let tls_config = Arc::new(create_tls_config(&config).unwrap()); + let mut executors = Vec::new(); for i in 0..(config.socket_workers) { let config = config.clone(); + let tls_config = tls_config.clone(); let request_mesh_builder = request_mesh_builder.clone(); let response_mesh_builder = response_mesh_builder.clone(); let num_bound_sockets = num_bound_sockets.clone(); @@ -43,6 +46,7 @@ pub fn run( let executor = builder.spawn(|| async move { network::run_socket_worker( config, + tls_config, request_mesh_builder, response_mesh_builder, num_bound_sockets, @@ -62,4 +66,35 @@ pub fn run( } Ok(()) +} + +fn create_tls_config( + config: &Config, +) -> anyhow::Result { + let certs = { + let f = File::open(&config.network.tls.tls_certificate_path)?; + let mut f = BufReader::new(f); + + rustls_pemfile::certs(&mut f)? + .into_iter() + .map(|bytes| rustls::Certificate(bytes)) + .collect() + }; + + let private_key = { + let f = File::open(&config.network.tls.tls_private_key_path)?; + let mut f = BufReader::new(f); + + rustls_pemfile::pkcs8_private_keys(&mut f)? + .first() + .map(|bytes| rustls::PrivateKey(bytes.clone())) + .ok_or(anyhow::anyhow!("No private keys in file"))? + }; + + let tls_config = rustls::ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(certs, private_key)?; + + Ok(tls_config) } \ No newline at end of file diff --git a/aquatic_http/src/lib/glommio/network.rs b/aquatic_http/src/lib/glommio/network.rs index 87cb2ec..904b32e 100644 --- a/aquatic_http/src/lib/glommio/network.rs +++ b/aquatic_http/src/lib/glommio/network.rs @@ -37,11 +37,11 @@ struct Connection { pub async fn run_socket_worker( config: Config, + tls_config: Arc, request_mesh_builder: MeshBuilder<(ConnectionId, Request), Partial>, response_mesh_builder: MeshBuilder<(ConnectionId, Response), Partial>, num_bound_sockets: Arc, ) { - let tls_config = Arc::new(create_tls_config(&config)); let config = Rc::new(config); let listener = TcpListener::bind(config.network.address).expect("bind socket"); @@ -174,35 +174,3 @@ impl Connection { Request::from_bytes(&request_bytes[..]).map_err(|err| anyhow::anyhow!("{:?}", err)) } } - -fn create_tls_config( - config: &Config, -) -> rustls::ServerConfig { - let mut certs = Vec::new(); - let mut private_key = None; - - use std::iter; - use rustls_pemfile::{Item, read_one}; - - let pemfile = Vec::new(); - let mut reader = BufReader::new(&pemfile[..]); - - for item in iter::from_fn(|| read_one(&mut reader).transpose()) { - match item.unwrap() { - Item::X509Certificate(cert) => { - certs.push(rustls::Certificate(cert)); - }, - Item::RSAKey(key) | Item::PKCS8Key(key) => { - if private_key.is_none(){ - private_key = Some(rustls::PrivateKey(key)); - } - } - } - } - - rustls::ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(certs, private_key.expect("no private key")) - .expect("bad certificate/key") -} \ No newline at end of file