fix: inappropriate location of CertsAndKeys implementations
This commit is contained in:
parent
629e3a1f98
commit
15e8659633
2 changed files with 81 additions and 80 deletions
87
src/certs.rs
87
src/certs.rs
|
|
@ -1,13 +1,11 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustls::{Certificate, PrivateKey};
|
use rustc_hash::FxHashSet as HashSet;
|
||||||
|
use rustls::{
|
||||||
/// Certificates and private keys in rustls loaded from files
|
sign::{any_supported_type, CertifiedKey},
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
Certificate, OwnedTrustAnchor, PrivateKey,
|
||||||
pub struct CertsAndKeys {
|
};
|
||||||
pub certs: Vec<Certificate>,
|
use std::io;
|
||||||
pub cert_keys: Vec<PrivateKey>,
|
use x509_parser::prelude::*;
|
||||||
pub client_ca_certs: Option<Vec<Certificate>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
// Trait to read certs and keys anywhere from KVS, file, sqlite, etc.
|
// Trait to read certs and keys anywhere from KVS, file, sqlite, etc.
|
||||||
|
|
@ -20,3 +18,74 @@ pub trait CryptoSource {
|
||||||
/// Returns true when mutual tls is enabled
|
/// Returns true when mutual tls is enabled
|
||||||
fn is_mutual_tls(&self) -> bool;
|
fn is_mutual_tls(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Certificates and private keys in rustls loaded from files
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub struct CertsAndKeys {
|
||||||
|
pub certs: Vec<Certificate>,
|
||||||
|
pub cert_keys: Vec<PrivateKey>,
|
||||||
|
pub client_ca_certs: Option<Vec<Certificate>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CertsAndKeys {
|
||||||
|
pub fn parse_server_certs_and_keys(&self) -> Result<CertifiedKey, anyhow::Error> {
|
||||||
|
// for (server_name_bytes_exp, certs_and_keys) in self.inner.iter() {
|
||||||
|
let signing_key = self
|
||||||
|
.cert_keys
|
||||||
|
.iter()
|
||||||
|
.find_map(|k| {
|
||||||
|
if let Ok(sk) = any_supported_type(k) {
|
||||||
|
Some(sk)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok_or_else(|| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
"Unable to find a valid certificate and key",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(CertifiedKey::new(self.certs.clone(), signing_key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_client_ca_certs(&self) -> Result<(Vec<OwnedTrustAnchor>, HashSet<Vec<u8>>), anyhow::Error> {
|
||||||
|
let certs = self.client_ca_certs.as_ref().ok_or(anyhow::anyhow!("No client cert"))?;
|
||||||
|
|
||||||
|
let owned_trust_anchors: Vec<_> = certs
|
||||||
|
.iter()
|
||||||
|
.map(|v| {
|
||||||
|
// let trust_anchor = tokio_rustls::webpki::TrustAnchor::try_from_cert_der(&v.0).unwrap();
|
||||||
|
let trust_anchor = webpki::TrustAnchor::try_from_cert_der(&v.0).unwrap();
|
||||||
|
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||||
|
trust_anchor.subject,
|
||||||
|
trust_anchor.spki,
|
||||||
|
trust_anchor.name_constraints,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// TODO: SKID is not used currently
|
||||||
|
let subject_key_identifiers: HashSet<_> = certs
|
||||||
|
.iter()
|
||||||
|
.filter_map(|v| {
|
||||||
|
// retrieve ca key id (subject key id)
|
||||||
|
let cert = parse_x509_certificate(&v.0).unwrap().1;
|
||||||
|
let subject_key_ids = cert
|
||||||
|
.iter_extensions()
|
||||||
|
.filter_map(|ext| match ext.parsed_extension() {
|
||||||
|
ParsedExtension::SubjectKeyIdentifier(skid) => Some(skid),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !subject_key_ids.is_empty() {
|
||||||
|
Some(subject_key_ids[0].0.to_owned())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok((owned_trust_anchors, subject_key_identifiers))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use hot_reload::*;
|
use hot_reload::*;
|
||||||
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
|
use rustc_hash::FxHashMap as HashMap;
|
||||||
use rustls::{
|
use rustls::{server::ResolvesServerCertUsingSni, sign::CertifiedKey, RootCertStore, ServerConfig};
|
||||||
server::ResolvesServerCertUsingSni,
|
use std::sync::Arc;
|
||||||
sign::{any_supported_type, CertifiedKey},
|
|
||||||
OwnedTrustAnchor, RootCertStore, ServerConfig,
|
|
||||||
};
|
|
||||||
use std::{io, sync::Arc};
|
|
||||||
use x509_parser::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
/// Reloader service for certificates and keys for TLS
|
/// Reloader service for certificates and keys for TLS
|
||||||
|
|
@ -69,69 +64,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CertsAndKeys {
|
|
||||||
fn parse_server_certs_and_keys(&self) -> Result<CertifiedKey, anyhow::Error> {
|
|
||||||
// for (server_name_bytes_exp, certs_and_keys) in self.inner.iter() {
|
|
||||||
let signing_key = self
|
|
||||||
.cert_keys
|
|
||||||
.iter()
|
|
||||||
.find_map(|k| {
|
|
||||||
if let Ok(sk) = any_supported_type(k) {
|
|
||||||
Some(sk)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok_or_else(|| {
|
|
||||||
io::Error::new(
|
|
||||||
io::ErrorKind::InvalidInput,
|
|
||||||
"Unable to find a valid certificate and key",
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
Ok(CertifiedKey::new(self.certs.clone(), signing_key))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_client_ca_certs(&self) -> Result<(Vec<OwnedTrustAnchor>, HashSet<Vec<u8>>), anyhow::Error> {
|
|
||||||
let certs = self.client_ca_certs.as_ref().ok_or(anyhow::anyhow!("No client cert"))?;
|
|
||||||
|
|
||||||
let owned_trust_anchors: Vec<_> = certs
|
|
||||||
.iter()
|
|
||||||
.map(|v| {
|
|
||||||
// let trust_anchor = tokio_rustls::webpki::TrustAnchor::try_from_cert_der(&v.0).unwrap();
|
|
||||||
let trust_anchor = webpki::TrustAnchor::try_from_cert_der(&v.0).unwrap();
|
|
||||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
|
||||||
trust_anchor.subject,
|
|
||||||
trust_anchor.spki,
|
|
||||||
trust_anchor.name_constraints,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// TODO: SKID is not used currently
|
|
||||||
let subject_key_identifiers: HashSet<_> = certs
|
|
||||||
.iter()
|
|
||||||
.filter_map(|v| {
|
|
||||||
// retrieve ca key id (subject key id)
|
|
||||||
let cert = parse_x509_certificate(&v.0).unwrap().1;
|
|
||||||
let subject_key_ids = cert
|
|
||||||
.iter_extensions()
|
|
||||||
.filter_map(|ext| match ext.parsed_extension() {
|
|
||||||
ParsedExtension::SubjectKeyIdentifier(skid) => Some(skid),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if !subject_key_ids.is_empty() {
|
|
||||||
Some(subject_key_ids[0].0.to_owned())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok((owned_trust_anchors, subject_key_identifiers))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryInto<Arc<ServerCrypto>> for &ServerCryptoBase {
|
impl TryInto<Arc<ServerCrypto>> for &ServerCryptoBase {
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue