use futures_util::TryFutureExt as _;
pub struct CertifiedKeyLoader<KeyProvider, KeyReader, CertsReader> {
pub key_provider: KeyProvider,
pub key_reader: KeyReader,
pub certs_reader: CertsReader,
}
impl<KeyProvider, KeyReader, CertsReader> std::fmt::Debug
for CertifiedKeyLoader<KeyProvider, KeyReader, CertsReader>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CertifiedKeyLoader")
.field("key_provider", &"...")
.field("key_reader", &"...")
.field("certs_reader", &"...")
.finish()
}
}
#[derive(Debug, thiserror::Error)]
pub enum CertifiedKeyLoaderError<ReadKey, ReadCerts> {
#[error("reading key: {0}")]
ReadKey(ReadKey),
#[error("reading certs: {0}")]
ReadCerts(ReadCerts),
#[error("loading key: {0}")]
LoadKey(rustls::Error),
}
#[async_trait::async_trait]
impl<KeyProvider, KeyReader, CertsReader> rustls_cert_reloadable::Loader
for CertifiedKeyLoader<KeyProvider, KeyReader, CertsReader>
where
KeyProvider: rustls::crypto::KeyProvider,
KeyReader: rustls_cert_read::ReadKey + Send,
CertsReader: rustls_cert_read::ReadCerts + Send,
KeyReader::Error: std::error::Error + Send + 'static,
CertsReader::Error: std::error::Error + Send + 'static,
{
type Value = rustls::sign::CertifiedKey;
type Error = CertifiedKeyLoaderError<KeyReader::Error, CertsReader::Error>;
async fn load(&mut self) -> Result<Self::Value, Self::Error> {
let (certs, key) = {
let key_fut = self
.key_reader
.read_key()
.map_err(CertifiedKeyLoaderError::ReadKey);
let certs_fut = self
.certs_reader
.read_certs()
.map_err(CertifiedKeyLoaderError::ReadCerts);
futures_util::future::try_join(certs_fut, key_fut).await?
};
let key = self
.key_provider
.load_private_key(key)
.map_err(CertifiedKeyLoaderError::LoadKey)?;
Ok(rustls::sign::CertifiedKey::new(certs, key))
}
}