use rustls::RootCertStore;
use rustls_pki_types::pem::PemObject;
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use crate::value::Result;
#[derive(Clone)]
pub struct ClientTlsConfig {
pub client_cert: Vec<u8>,
pub client_key: Vec<u8>,
}
#[derive(Clone)]
pub struct TlsCertificates {
pub client_tls: Option<ClientTlsConfig>,
pub root_cert: Option<Vec<u8>>,
}
pub fn retrieve_tls_certificates(certificates: TlsCertificates) -> Result<TlsConnParams> {
let TlsCertificates {
client_tls,
root_cert,
} = certificates;
let client_tls_params = if let Some(ClientTlsConfig {
client_cert,
client_key,
}) = client_tls
{
let certs = CertificateDer::pem_slice_iter(&client_cert);
let client_cert_chain = certs
.collect::<std::result::Result<Vec<_>, _>>()
.map_err(|e| std::io::Error::other(format!("Failed to parse certificate: {}", e)))?;
let client_key = PrivateKeyDer::from_pem_slice(&client_key)
.map_err(|e| std::io::Error::other(format!("Failed to parse private key: {}", e)))?;
Some(ClientTlsParams {
client_cert_chain,
client_key,
})
} else {
None
};
let root_cert_store = if let Some(root_cert) = root_cert {
let certs = CertificateDer::pem_slice_iter(&root_cert);
let mut root_cert_store = RootCertStore::empty();
for result in certs {
let cert = result
.map_err(|e| std::io::Error::other(format!("Failed to parse root certificate: {}", e)))?;
if root_cert_store.add(cert.to_owned()).is_err() {
return Err(std::io::Error::other("Unable to parse TLS trust anchors").into());
}
}
Some(root_cert_store)
} else {
None
};
Ok(TlsConnParams {
client_tls_params,
root_cert_store,
})
}
#[derive(Debug)]
pub struct ClientTlsParams {
pub(crate) client_cert_chain: Vec<CertificateDer<'static>>,
pub(crate) client_key: PrivateKeyDer<'static>,
}
impl Clone for ClientTlsParams {
fn clone(&self) -> Self {
Self {
client_cert_chain: self.client_cert_chain.clone(),
client_key: self.client_key.clone_key(),
}
}
}
#[derive(Debug, Clone)]
pub struct TlsConnParams {
pub(crate) client_tls_params: Option<ClientTlsParams>,
pub(crate) root_cert_store: Option<RootCertStore>,
}