From 377096c14e5dde27d311b1a133eac064ddcd7e93 Mon Sep 17 00:00:00 2001 From: Jun Kurihara Date: Mon, 27 May 2024 11:55:22 +0900 Subject: [PATCH] wip: started to implement reloader service --- rpxy-certs/src/certs.rs | 62 +++++++++++++++++++++++++++++++++++++-- rpxy-certs/src/lib.rs | 59 ++----------------------------------- rpxy-certs/src/service.rs | 15 ++++++++++ rpxy-certs/src/source.rs | 10 +++---- 4 files changed, 82 insertions(+), 64 deletions(-) diff --git a/rpxy-certs/src/certs.rs b/rpxy-certs/src/certs.rs index 7df964e..92578b3 100644 --- a/rpxy-certs/src/certs.rs +++ b/rpxy-certs/src/certs.rs @@ -9,19 +9,21 @@ use x509_parser::prelude::*; type Certificate = rustls::pki_types::CertificateDer<'static>; /// Raw private key in rustls format type PrivateKey = pki_types::PrivateKeyDer<'static>; +/// Subject Key ID in bytes +type SubjectKeyIdentifier = Vec; /// Client CA trust anchors subject to the subject key identifier -type TrustAnchors = HashMap, pki_types::TrustAnchor<'static>>; +type TrustAnchors = HashMap>; /* ------------------------------------------------ */ /// Raw certificates and private keys loaded from files for a single server name #[derive(Debug, PartialEq, Eq, Clone)] -pub struct SingleServerCrypto { +pub struct SingleServerCertsKeys { certs: Vec, cert_keys: Arc>, client_ca_certs: Option>, } -impl SingleServerCrypto { +impl SingleServerCertsKeys { /// Create a new instance of SingleServerCrypto pub fn new(certs: &[Certificate], cert_keys: &Arc>, client_ca_certs: &Option>) -> Self { Self { @@ -100,3 +102,57 @@ impl SingleServerCrypto { Ok(trust_anchors) } } + +/* ------------------------------------------------ */ +#[cfg(test)] +mod tests { + use super::super::*; + + #[tokio::test] + async fn read_server_crt_key_files() { + let tls_cert_path = "../example-certs/server.crt"; + let tls_cert_key_path = "../example-certs/server.key"; + let crypto_file_source = CryptoFileSourceBuilder::default() + .tls_cert_key_path(tls_cert_key_path) + .tls_cert_path(tls_cert_path) + .build(); + assert!(crypto_file_source.is_ok()); + + let crypto_file_source = crypto_file_source.unwrap(); + let crypto_elem = crypto_file_source.read().await; + assert!(crypto_elem.is_ok()); + + let crypto_elem = crypto_elem.unwrap(); + let certificed_key = crypto_elem.rustls_certified_key(); + assert!(certificed_key.is_ok()); + } + + #[tokio::test] + async fn read_server_crt_key_files_with_client_ca_crt() { + let tls_cert_path = "../example-certs/server.crt"; + let tls_cert_key_path = "../example-certs/server.key"; + let client_ca_cert_path = Some("../example-certs/client.ca.crt"); + let crypto_file_source = CryptoFileSourceBuilder::default() + .tls_cert_key_path(tls_cert_key_path) + .tls_cert_path(tls_cert_path) + .client_ca_cert_path(client_ca_cert_path) + .build(); + assert!(crypto_file_source.is_ok()); + + let crypto_file_source = crypto_file_source.unwrap(); + let crypto_elem = crypto_file_source.read().await; + assert!(crypto_elem.is_ok()); + + let crypto_elem = crypto_elem.unwrap(); + assert!(crypto_elem.is_mutual_tls()); + + let certificed_key = crypto_elem.rustls_certified_key(); + assert!(certificed_key.is_ok()); + + let trust_anchors = crypto_elem.rustls_trust_anchors(); + assert!(trust_anchors.is_ok()); + + let trust_anchors = trust_anchors.unwrap(); + assert_eq!(trust_anchors.len(), 1); + } +} diff --git a/rpxy-certs/src/lib.rs b/rpxy-certs/src/lib.rs index 18b7da5..75b107c 100644 --- a/rpxy-certs/src/lib.rs +++ b/rpxy-certs/src/lib.rs @@ -4,65 +4,12 @@ mod service; mod source; #[allow(unused_imports)] -pub(crate) mod log { +mod log { pub(crate) use tracing::{debug, error, info, warn}; } pub use crate::{ - certs::SingleServerCrypto, + certs::SingleServerCertsKeys, + service::{ServerCrypto, ServerNameBytes, ServerNameCryptoMap}, source::{CryptoFileSource, CryptoFileSourceBuilder, CryptoFileSourceBuilderError, CryptoSource}, }; - -/* ------------------------------------------------ */ -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn read_server_crt_key_files() { - let tls_cert_path = "../example-certs/server.crt"; - let tls_cert_key_path = "../example-certs/server.key"; - let crypto_file_source = CryptoFileSourceBuilder::default() - .tls_cert_key_path(tls_cert_key_path) - .tls_cert_path(tls_cert_path) - .build(); - assert!(crypto_file_source.is_ok()); - - let crypto_file_source = crypto_file_source.unwrap(); - let crypto_elem = crypto_file_source.read().await; - assert!(crypto_elem.is_ok()); - - let crypto_elem = crypto_elem.unwrap(); - let certificed_key = crypto_elem.rustls_certified_key(); - assert!(certificed_key.is_ok()); - } - - #[tokio::test] - async fn read_server_crt_key_files_with_client_ca_crt() { - let tls_cert_path = "../example-certs/server.crt"; - let tls_cert_key_path = "../example-certs/server.key"; - let client_ca_cert_path = Some("../example-certs/client.ca.crt"); - let crypto_file_source = CryptoFileSourceBuilder::default() - .tls_cert_key_path(tls_cert_key_path) - .tls_cert_path(tls_cert_path) - .client_ca_cert_path(client_ca_cert_path) - .build(); - assert!(crypto_file_source.is_ok()); - - let crypto_file_source = crypto_file_source.unwrap(); - let crypto_elem = crypto_file_source.read().await; - assert!(crypto_elem.is_ok()); - - let crypto_elem = crypto_elem.unwrap(); - assert!(crypto_elem.is_mutual_tls()); - - let certificed_key = crypto_elem.rustls_certified_key(); - assert!(certificed_key.is_ok()); - - let trust_anchors = crypto_elem.rustls_trust_anchors(); - assert!(trust_anchors.is_ok()); - - let trust_anchors = trust_anchors.unwrap(); - assert_eq!(trust_anchors.len(), 1); - } -} diff --git a/rpxy-certs/src/service.rs b/rpxy-certs/src/service.rs index e69de29..31f24a1 100644 --- a/rpxy-certs/src/service.rs +++ b/rpxy-certs/src/service.rs @@ -0,0 +1,15 @@ +use rustc_hash::FxHashMap as HashMap; +use rustls::ServerConfig; +use std::sync::Arc; + +/// ServerName in bytes type +pub type ServerNameBytes = Vec; +/// ServerName (SNI) to ServerConfig map type +pub type ServerNameCryptoMap = HashMap>; +/// ServerName (SNI) to ServerConfig map +pub struct ServerCrypto { + // For Quic/HTTP3, only servers with no client authentication + pub inner_global_no_client_auth: Arc, + // // For TLS over TCP/HTTP2 and 1.1, map of SNI to server_crypto for all given servers + pub inner_local_map: Arc, +} diff --git a/rpxy-certs/src/source.rs b/rpxy-certs/src/source.rs index e4dba81..4eae104 100644 --- a/rpxy-certs/src/source.rs +++ b/rpxy-certs/src/source.rs @@ -1,4 +1,4 @@ -use crate::{certs::SingleServerCrypto, error::*, log::*}; +use crate::{certs::SingleServerCertsKeys, error::*, log::*}; use async_trait::async_trait; use derive_builder::Builder; use std::{ @@ -15,7 +15,7 @@ pub trait CryptoSource { type Error; /// read crypto materials from source - async fn read(&self) -> Result; + async fn read(&self) -> Result; /// Returns true when mutual tls is enabled fn is_mutual_tls(&self) -> bool; @@ -58,7 +58,7 @@ impl CryptoFileSourceBuilder { impl CryptoSource for CryptoFileSource { type Error = RpxyCertError; /// read crypto materials from source - async fn read(&self) -> Result { + async fn read(&self) -> Result { read_certs_and_keys( &self.tls_cert_path, &self.tls_cert_key_path, @@ -77,7 +77,7 @@ fn read_certs_and_keys( cert_path: &PathBuf, cert_key_path: &PathBuf, client_ca_cert_path: Option<&PathBuf>, -) -> Result { +) -> Result { debug!("Read TLS server certificates and private key"); // certificates @@ -152,7 +152,7 @@ fn read_certs_and_keys( None }; - Ok(SingleServerCrypto::new( + Ok(SingleServerCertsKeys::new( &raw_certs, &Arc::new(raw_cert_keys), &client_ca_certs,