#[cfg(any(feature = "webpki-roots", feature = "native-roots"))]
use super::x509::LOAD_CERTS;
use super::{AlpnProtos, AlpsProtos, CertStore, TlsVersion};
use boring2::{
error::ErrorStack,
ssl::{
CertCompressionAlgorithm, ConnectConfiguration, SslConnectorBuilder, SslOptions, SslRef,
SslVerifyMode,
},
};
use std::borrow::Cow;
pub trait SslConnectorBuilderExt {
fn cert_verification(self, enable: bool) -> crate::Result<SslConnectorBuilder>;
fn alpn_protos(self, alpn: AlpnProtos) -> crate::Result<SslConnectorBuilder>;
fn min_tls_version<V: Into<Option<TlsVersion>>>(
self,
version: V,
) -> crate::Result<SslConnectorBuilder>;
fn max_tls_version<V: Into<Option<TlsVersion>>>(
self,
version: V,
) -> crate::Result<SslConnectorBuilder>;
fn add_cert_compression_algorithm(
self,
alg: CertCompressionAlgorithm,
) -> crate::Result<SslConnectorBuilder>;
fn cert_store(
self,
provider: Option<Cow<'static, CertStore>>,
) -> crate::Result<SslConnectorBuilder>;
}
pub trait SslRefExt {
fn alpn_protos(&mut self, alpn: Option<AlpnProtos>) -> Result<(), ErrorStack>;
}
pub trait ConnectConfigurationExt {
fn alps_protos(
&mut self,
alps: Option<AlpsProtos>,
new_endpoint: bool,
) -> Result<&mut ConnectConfiguration, ErrorStack>;
fn skip_session_ticket(&mut self) -> Result<&mut ConnectConfiguration, ErrorStack>;
fn set_random_aes_hw_override(&mut self, enable: bool);
}
impl SslConnectorBuilderExt for SslConnectorBuilder {
#[inline]
fn cert_verification(mut self, enable: bool) -> crate::Result<SslConnectorBuilder> {
if enable {
self.set_verify(SslVerifyMode::PEER);
} else {
self.set_verify(SslVerifyMode::NONE);
}
Ok(self)
}
#[inline]
fn alpn_protos(mut self, alpn: AlpnProtos) -> crate::Result<SslConnectorBuilder> {
self.set_alpn_protos(alpn.0)
.map(|_| self)
.map_err(Into::into)
}
#[inline]
fn min_tls_version<V: Into<Option<TlsVersion>>>(
mut self,
version: V,
) -> crate::Result<SslConnectorBuilder> {
self.set_min_proto_version(version.into().map(|v| v.0))
.map(|_| self)
.map_err(Into::into)
}
#[inline]
fn max_tls_version<V: Into<Option<TlsVersion>>>(
mut self,
version: V,
) -> crate::Result<SslConnectorBuilder> {
self.set_max_proto_version(version.into().map(|v| v.0))
.map(|_| self)
.map_err(Into::into)
}
#[inline]
fn add_cert_compression_algorithm(
mut self,
alg: CertCompressionAlgorithm,
) -> crate::Result<SslConnectorBuilder> {
self.add_cert_compression_alg(alg)
.map(|_| self)
.map_err(Into::into)
}
#[inline]
fn cert_store(
mut self,
store: Option<Cow<'static, CertStore>>,
) -> crate::Result<SslConnectorBuilder> {
if let Some(store) = store {
match store {
Cow::Borrowed(store) => {
store.add_to_tls_ref(&mut self)?;
}
Cow::Owned(store) => {
store.add_to_tls(&mut self)?;
}
};
} else {
#[cfg(any(feature = "webpki-roots", feature = "native-roots"))]
{
if let Some(store) = LOAD_CERTS.as_ref() {
log::debug!("Using CA certs from webpki/native roots");
store.add_to_tls_ref(&mut self)?;
} else {
log::debug!("No CA certs provided, using system default");
self.set_default_verify_paths()?;
}
}
#[cfg(not(any(feature = "webpki-roots", feature = "native-roots")))]
{
self.set_default_verify_paths()?;
}
}
Ok(self)
}
}
impl ConnectConfigurationExt for ConnectConfiguration {
#[inline]
fn alps_protos(
&mut self,
alps: Option<AlpsProtos>,
new_endpoint: bool,
) -> Result<&mut ConnectConfiguration, ErrorStack> {
if let Some(alps) = alps {
self.add_application_settings(alps.0)?;
if new_endpoint {
self.set_alps_use_new_codepoint(new_endpoint);
}
}
Ok(self)
}
#[inline]
fn skip_session_ticket(&mut self) -> Result<&mut ConnectConfiguration, ErrorStack> {
self.set_options(SslOptions::NO_TICKET).map(|_| self)
}
#[inline]
fn set_random_aes_hw_override(&mut self, enable: bool) {
if enable {
let random_bool = (crate::util::fast_random() % 2) == 0;
self.set_aes_hw_override(random_bool);
}
}
}
impl SslRefExt for SslRef {
#[inline]
fn alpn_protos(&mut self, alpn: Option<AlpnProtos>) -> Result<(), ErrorStack> {
let alpn = match alpn {
Some(alpn) => alpn.0,
None => return Ok(()),
};
self.set_alpn_protos(alpn).map(|_| ())
}
}