use super::{AlpnProtos, AlpsProtos, CertStore, TlsVersion};
use boring2::ssl::{CertCompressionAlgorithm, SslCurve};
use std::borrow::Cow;
use typed_builder::TypedBuilder;
#[derive(Debug, TypedBuilder)]
pub struct TlsConfig {
#[builder(default, setter(transform = |input: impl IntoCertStore| input.into()))]
pub cert_store: Option<Cow<'static, CertStore>>,
#[builder(default = true)]
pub cert_verification: bool,
#[builder(default = true)]
pub tls_sni: bool,
#[builder(default = true)]
pub verify_hostname: bool,
#[builder(default = AlpnProtos::default())]
pub alpn_protos: AlpnProtos,
#[builder(default, setter(into))]
pub alps_protos: Option<AlpsProtos>,
#[builder(default = false)]
pub alps_use_new_codepoint: bool,
#[builder(default = true)]
pub session_ticket: bool,
#[builder(default, setter(into))]
pub min_tls_version: Option<TlsVersion>,
#[builder(default, setter(into))]
pub max_tls_version: Option<TlsVersion>,
#[builder(default = false)]
pub pre_shared_key: bool,
#[builder(default = false)]
pub enable_ech_grease: bool,
#[builder(default, setter(into))]
pub permute_extensions: Option<bool>,
#[builder(default, setter(into))]
pub grease_enabled: Option<bool>,
#[builder(default = false)]
pub enable_ocsp_stapling: bool,
#[builder(default = false)]
pub enable_signed_cert_timestamps: bool,
#[builder(default, setter(into))]
pub record_size_limit: Option<u16>,
#[builder(default = false)]
pub psk_skip_session_ticket: bool,
#[builder(default, setter(into))]
pub key_shares_limit: Option<u8>,
#[builder(default = true)]
pub psk_dhe_ke: bool,
#[builder(default = true)]
pub renegotiation: bool,
#[builder(default, setter(strip_option, into))]
pub delegated_credentials: Option<Cow<'static, str>>,
#[builder(default, setter(strip_option, into))]
pub cipher_list: Option<Cow<'static, str>>,
#[builder(default, setter(strip_option, into))]
pub curves: Option<Cow<'static, [SslCurve]>>,
#[builder(default, setter(strip_option, into))]
pub sigalgs_list: Option<Cow<'static, str>>,
#[builder(default, setter(transform = |input: impl IntoCertCompressionAlgorithm| input.into()))]
pub cert_compression_algorithm: Option<Cow<'static, [CertCompressionAlgorithm]>>,
#[builder(default, setter(strip_option, into))]
pub extension_permutation_indices: Option<Cow<'static, [u8]>>,
#[builder(default, setter(into))]
pub aes_hw_override: Option<bool>,
#[builder(default, setter(into))]
pub random_aes_hw_override: bool,
}
impl Default for TlsConfig {
fn default() -> Self {
Self::builder().build()
}
}
pub trait IntoCertStore {
fn into(self) -> Option<Cow<'static, CertStore>>;
}
macro_rules! impl_into_cert_store {
($($t:ty => $body:expr),* $(,)?) => {
$(impl IntoCertStore for $t {
fn into(self) -> Option<Cow<'static, CertStore>> {
$body(self)
}
})*
};
}
impl_into_cert_store!(
&'static CertStore => |s| Some(Cow::Borrowed(s)),
CertStore => |s| Some(Cow::Owned(s))
);
impl<T: IntoCertStore> IntoCertStore for Option<T> {
fn into(self) -> Option<Cow<'static, CertStore>> {
self.and_then(|v| v.into())
}
}
pub(crate) trait IntoCertCompressionAlgorithm {
fn into(self) -> Option<Cow<'static, [CertCompressionAlgorithm]>>;
}
macro_rules! impl_into_cert_compression_algorithm {
($($t:ty => $body:expr),* $(,)?) => {
$(impl IntoCertCompressionAlgorithm for $t {
fn into(self) -> Option<Cow<'static, [CertCompressionAlgorithm]>> {
$body(self)
}
})*
};
}
impl_into_cert_compression_algorithm!(
&'static [CertCompressionAlgorithm] => |s| Some(Cow::Borrowed(s)),
Cow<'static, [CertCompressionAlgorithm]> => Some,
&'static CertCompressionAlgorithm => |s: &'static CertCompressionAlgorithm| Some(Cow::Owned(vec![*s])),
CertCompressionAlgorithm => |s| Some(Cow::Owned(vec![s])),
Vec<CertCompressionAlgorithm> => |s| Some(Cow::Owned(s)),
);
impl<const N: usize> IntoCertCompressionAlgorithm for &'static [CertCompressionAlgorithm; N] {
fn into(self) -> Option<Cow<'static, [CertCompressionAlgorithm]>> {
Some(Cow::Borrowed(self))
}
}
impl<const N: usize> IntoCertCompressionAlgorithm for [CertCompressionAlgorithm; N] {
fn into(self) -> Option<Cow<'static, [CertCompressionAlgorithm]>> {
Some(Cow::Owned(self.to_vec()))
}
}
impl<T: IntoCertCompressionAlgorithm> IntoCertCompressionAlgorithm for Option<T> {
fn into(self) -> Option<Cow<'static, [CertCompressionAlgorithm]>> {
self.and_then(|v| v.into())
}
}