Skip to content

Commit

Permalink
TLS work WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
blind-oracle committed Apr 12, 2024
1 parent 44bb0ed commit a9d85e1
Show file tree
Hide file tree
Showing 10 changed files with 659 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@ axum = "0.7"
candid = "0.10"
clap = { version = "4.5", features = ["derive", "string"] }
clap_derive = "4.5"
fqdn = "0.3"
futures = "0.3"
hickory-resolver = {version = "0.24", features = ["dns-over-rustls", "dns-over-https-rustls", "dnssec-ring"] }
http = "1.1"
hyper = "1.2"
jemallocator = "0.5"
jemalloc-ctl = "0.5"
lazy_static = "1.4"
little-loadshedder = "0.2"
maxminddb = "0.24"
mockall = "0.12"
moka = { version = "0.12", features = ["sync", "future"] }
prometheus = "0.13"
rand = "0.8"
regex = "1.10"
reqwest = "0.12"
rustls = "0.23"
rustls-pemfile = "1"
rustls-pemfile = "2"
webpki-roots = "0.26"
serde = "1.0"
serde_json = "1.0"
strum = "0.26"
Expand All @@ -46,7 +51,7 @@ tracing-core = "0.1"
tracing-serde = "0.1"
tracing-subscriber = "0.3"
url = "2.5"
x509-parser = "0.16"

[dev-dependencies]
criterion = { version = "0.5", features = ["async_tokio"] }
mockall = "0.12"
9 changes: 9 additions & 0 deletions src/dns/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
mod test;

use hickory_resolver::{
config::{ResolverConfig, ResolverOpts},
Resolver,
};

pub fn prepare_dns_resolver() -> std::io::Result<Resolver> {
Resolver::new(ResolverConfig::cloudflare_tls(), ResolverOpts::default())
}
24 changes: 24 additions & 0 deletions src/http/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use async_trait::async_trait;
use mockall::automock;
use reqwest::{Client, Error, Request, Response};

#[automock]
#[async_trait]
pub trait HttpClient: Send + Sync {
async fn execute(&self, req: Request) -> Result<Response, Error>;
}

pub struct ReqwestClient(Client);

impl ReqwestClient {
pub const fn new(c: Client) -> Self {
Self(c)
}
}

#[async_trait]
impl HttpClient for ReqwestClient {
async fn execute(&self, req: Request) -> Result<Response, Error> {
self.0.execute(req).await
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod cache;
mod cli;
mod core;
mod dns;
mod http;
mod policy;
mod tls;

Expand Down
64 changes: 64 additions & 0 deletions src/tls/cert/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
mod syncer;
mod test;

use std::sync::Arc;

use anyhow::{anyhow, Error};
use async_trait::async_trait;
use futures::future::join_all;
use rustls::{crypto::aws_lc_rs, sign::CertifiedKey};

// Converts raw PEM certificate chain & private key to a CertifiedKey ready to be consumed by Rustls
pub fn pem_convert_to_rustls(key: &[u8], certs: &[u8]) -> Result<Arc<CertifiedKey>, Error> {
let (key, certs) = (key.to_vec(), certs.to_vec());

let key = rustls_pemfile::private_key(&mut key.as_ref())?
.ok_or_else(|| anyhow!("No private key found"))?;

let certs = rustls_pemfile::certs(&mut certs.as_ref()).collect::<Result<Vec<_>, _>>()?;
if certs.is_empty() {
return Err(anyhow!("No certificates found"));
}

let key = aws_lc_rs::sign::any_supported_type(&key)?;
Ok(Arc::new(CertifiedKey::new(certs, key)))
}

// Trait that the certificate sources should implement
// It should return a vector of Rustls-compatible CertifiedKeys
#[async_trait]
pub trait ProvidesCertificates: Sync + Send {
async fn get_certificates(&self) -> Result<Vec<Arc<CertifiedKey>>, Error>;
}

// Provider that aggregates other providers' output
pub struct AggregatingProvider {
providers: Vec<Arc<dyn ProvidesCertificates>>,
}

impl AggregatingProvider {
pub fn new(providers: Vec<Arc<dyn ProvidesCertificates>>) -> Self {
Self { providers }
}
}

#[async_trait]
impl ProvidesCertificates for AggregatingProvider {
async fn get_certificates(&self) -> Result<Vec<Arc<CertifiedKey>>, Error> {
let certs = join_all(
self.providers
.iter()
.map(|x| async { x.get_certificates().await }),
)
.await;

let certs = certs
.into_iter()
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.flatten()
.collect::<Vec<_>>();

Ok(certs)
}
}
Loading

0 comments on commit a9d85e1

Please sign in to comment.