use crate::cfg::{cfg_rustls, cfg_s2n_tls};
use crate::HttpClientError;
#[derive(Debug, Eq, PartialEq, Clone)]
#[non_exhaustive]
pub enum Provider {
#[cfg(any(
feature = "rustls-aws-lc",
feature = "rustls-aws-lc-fips",
feature = "rustls-ring"
))]
Rustls(rustls_provider::CryptoMode),
#[cfg(feature = "s2n-tls")]
S2nTls,
}
#[derive(Debug, Clone)]
pub struct TlsContext {
#[allow(unused)]
trust_store: TrustStore,
}
impl TlsContext {
pub fn builder() -> TlsContextBuilder {
TlsContextBuilder::new()
}
}
impl Default for TlsContext {
fn default() -> Self {
TlsContext::builder().build().expect("valid default config")
}
}
#[derive(Debug)]
pub struct TlsContextBuilder {
trust_store: TrustStore,
}
impl TlsContextBuilder {
fn new() -> Self {
TlsContextBuilder {
trust_store: TrustStore::default(),
}
}
pub fn with_trust_store(mut self, trust_store: TrustStore) -> Self {
self.trust_store = trust_store;
self
}
pub fn build(self) -> Result<TlsContext, HttpClientError> {
Ok(TlsContext {
trust_store: self.trust_store,
})
}
}
#[allow(unused)]
#[derive(Debug, Clone)]
struct CertificatePEM(Vec<u8>);
impl From<&[u8]> for CertificatePEM {
fn from(value: &[u8]) -> Self {
CertificatePEM(value.to_vec())
}
}
#[derive(Debug, Clone)]
pub struct TrustStore {
enable_native_roots: bool,
custom_certs: Vec<CertificatePEM>,
}
impl TrustStore {
pub fn empty() -> Self {
Self {
enable_native_roots: false,
custom_certs: Vec::new(),
}
}
pub fn with_native_roots(mut self, enable_native_roots: bool) -> Self {
self.enable_native_roots = enable_native_roots;
self
}
pub fn with_pem_certificate(mut self, pem_bytes: impl Into<Vec<u8>>) -> Self {
self.custom_certs.push(CertificatePEM(pem_bytes.into()));
self
}
pub fn add_pem_certificate(&mut self, pem_bytes: impl Into<Vec<u8>>) -> &mut Self {
self.custom_certs.push(CertificatePEM(pem_bytes.into()));
self
}
}
impl Default for TrustStore {
fn default() -> Self {
Self {
enable_native_roots: true,
custom_certs: Vec::new(),
}
}
}
cfg_rustls! {
pub mod rustls_provider;
}
cfg_s2n_tls! {
pub(crate) mod s2n_tls_provider;
}