mod builder;
use std::{fmt, io};
pub use builder::TlsConnectorBuilder;
use openssl::ssl::{SslConnector, SslVerifyMode};
use crate::{sync_io::TlsStream, HandshakeError, Protocol};
#[derive(Clone)]
pub struct TlsConnector {
connector: SslConnector,
use_sni: bool,
accept_invalid_hostnames: bool,
accept_invalid_certs: bool,
}
impl fmt::Debug for TlsConnector {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("TlsConnector")
.field("use_sni", &self.use_sni)
.field("accept_invalid_hostnames", &self.accept_invalid_hostnames)
.field("accept_invalid_certs", &self.accept_invalid_certs)
.finish()
}
}
impl TlsConnector {
pub fn new() -> crate::Result<Self> {
Self::builder().build()
}
pub fn builder() -> TlsConnectorBuilder {
TlsConnectorBuilder {
identity: None,
min_protocol: Some(Protocol::Tlsv10),
max_protocol: None,
root_certificates: vec![],
use_sni: true,
accept_invalid_certs: false,
accept_invalid_hostnames: false,
disable_built_in_roots: false,
}
}
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
where
S: io::Read + io::Write,
{
let mut ssl = self
.connector
.configure()?
.use_server_name_indication(self.use_sni)
.verify_hostname(!self.accept_invalid_hostnames);
if self.accept_invalid_certs {
ssl.set_verify(SslVerifyMode::NONE);
}
Ok(TlsStream(ssl.connect(domain, stream)?))
}
}