feat: added mTLS auth for beacons
This commit is contained in:
@@ -15,3 +15,5 @@ serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
axum-server = { version = "^0.7", features = ["tokio-rustls", "tls-rustls"] }
|
||||
rustls = "0.23"
|
||||
rcgen = "0.13.2"
|
||||
rustls-pki-types = "1.11.0"
|
||||
|
||||
@@ -5,6 +5,8 @@ pub enum Error {
|
||||
TokioJoin(tokio::task::JoinError),
|
||||
Io(std::io::Error),
|
||||
Rustls(rustls::Error),
|
||||
Rcgen(rcgen::Error),
|
||||
WebPki(rustls::client::VerifierBuilderError),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
@@ -25,6 +27,12 @@ impl std::fmt::Display for Error {
|
||||
Error::Rustls(err) => {
|
||||
write!(f, "rustls error: {err:?}")
|
||||
}
|
||||
Error::Rcgen(err) => {
|
||||
write!(f, "rcgen error: {err:?}")
|
||||
}
|
||||
Error::WebPki(err) => {
|
||||
write!(f, "webpki error: {err:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +44,8 @@ impl std::error::Error for Error {
|
||||
Error::TokioJoin(err) => Some(err),
|
||||
Error::Io(err) => Some(err),
|
||||
Error::Rustls(err) => Some(err),
|
||||
Error::Rcgen(err) => Some(err),
|
||||
Error::WebPki(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -72,3 +82,15 @@ impl From<rustls::Error> for Error {
|
||||
Self::Rustls(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rcgen::Error> for Error {
|
||||
fn from(err: rcgen::Error) -> Self {
|
||||
Self::Rcgen(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rustls::client::VerifierBuilderError> for Error {
|
||||
fn from(err: rustls::client::VerifierBuilderError) -> Self {
|
||||
Self::WebPki(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ use std::{
|
||||
};
|
||||
|
||||
use axum::routing::{Router, get, post};
|
||||
use rcgen::{Certificate, CertificateParams, KeyPair};
|
||||
use rustls::{server::WebPkiClientVerifier, RootCertStore};
|
||||
use sqlx::SqlitePool;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
@@ -114,18 +116,49 @@ pub async fn start_listener(
|
||||
|
||||
let hidden_app = Router::new().nest("/hidden_sparse", app);
|
||||
|
||||
let keypair = match rustls::pki_types::PrivateKeyDer::try_from(listener.privkey.clone()) {
|
||||
Ok(pk) => pk,
|
||||
Err(e) => {
|
||||
let ca_cert = rustls::pki_types::CertificateDer::from(listener.certificate.clone());
|
||||
|
||||
let (keypair, cert) = {
|
||||
let ca_keypair = KeyPair::from_der_and_sign_algo(
|
||||
&rustls_pki_types::PrivateKeyDer::try_from(&*listener.privkey)
|
||||
.map_err(|_| rcgen::Error::CouldNotParseCertificate)?,
|
||||
&rcgen::PKCS_ECDSA_P256_SHA256,
|
||||
)?;
|
||||
let ca_params = CertificateParams::from_ca_cert_der(&(*listener.certificate).into())
|
||||
.map_err(|_| rcgen::Error::CouldNotParseCertificate)?;
|
||||
let ca_cert = ca_params.self_signed(&ca_keypair)?;
|
||||
|
||||
let server_key = KeyPair::generate()?;
|
||||
let Ok(server_params) = CertificateParams::new(
|
||||
vec![listener.domain_name.clone()]
|
||||
) else {
|
||||
return Err(crate::error::Error::Generic(format!(
|
||||
"Could not parse private key: {e}"
|
||||
"Could not generate new server keychain"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let server_cert = server_params.signed_by(&server_key, &ca_cert, &ca_keypair)?;
|
||||
|
||||
let keypair = match rustls::pki_types::PrivateKeyDer::try_from(server_key.serialize_der()) {
|
||||
Ok(pk) => pk,
|
||||
Err(e) => {
|
||||
return Err(crate::error::Error::Generic(format!(
|
||||
"Could not parse private key: {e}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let cert = server_cert.into();
|
||||
|
||||
(keypair, cert)
|
||||
};
|
||||
let cert = rustls::pki_types::CertificateDer::from(listener.certificate.clone());
|
||||
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.add(ca_cert)?;
|
||||
|
||||
let client_verifier = WebPkiClientVerifier::builder(root_store.into())
|
||||
.build()?;
|
||||
|
||||
let mut tls_config = rustls::ServerConfig::builder()
|
||||
.with_no_client_auth()
|
||||
.with_client_cert_verifier(client_verifier)
|
||||
.with_single_cert(vec![cert], keypair)?;
|
||||
tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user