refactor/feat: add cert verifier call, cleanup and extend error enum

This commit is contained in:
DarkCat09 2024-08-28 14:44:34 +04:00
parent 04ebac7d6c
commit ef307f4983
Signed by: DarkCat09
GPG key ID: BD3CE9B65916CD82
2 changed files with 37 additions and 21 deletions

View file

@ -25,7 +25,7 @@ use tokio::{
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
use tokio_rustls::TlsConnector;
use tokio_rustls::{rustls, TlsConnector};
use url::Url;
pub struct Client {
@ -101,6 +101,20 @@ impl Client {
let stream = self.try_connect(host, port).await?;
let mut stream = self.connector.connect(domain, stream).await?;
if let Some(ssv) = &self.ss_verifier {
let cert = stream
.get_ref()
.1 // rustls::ClientConnection
.peer_certificates()
.unwrap() // i think handshake already completed if we awaited on connector.connect?
.first()
.ok_or(rustls::Error::NoCertificatesPresented)?;
if !ssv.verify(cert, host, port).await? {
return Err(rustls::CertificateError::ApplicationVerificationFailure.into());
}
}
// Write URL, then CRLF
stream.write_all(url_str.as_bytes()).await?;
stream.write_all(b"\r\n").await?;

View file

@ -1,11 +1,11 @@
//! Library error structures and enums
use tokio_rustls::rustls;
#[cfg(feature = "hickory")]
use hickory_client::{
error::ClientError as HickoryClientError, proto::error::ProtoError as HickoryProtoError,
};
#[cfg(feature = "hickory")]
use tokio::runtime::TryCurrentError;
/// Main error structure, also a wrapper for everything else
#[derive(Debug)]
@ -15,9 +15,12 @@ pub enum LibError {
IoError(std::io::Error),
/// URL parse or check error
InvalidUrlError(InvalidUrl),
/// DNS provided no suitable records
/// DNS server has provided no suitable records
/// (e. g. domain does not exist)
HostLookupError,
/// TLS library error related to certificate/signature
/// verification failure or connection failure
RustlsError(rustls::Error),
/// Response status code is out of [10; 69] range
StatusOutOfRange(u8),
/// Response metadata or content cannot be parsed
@ -25,16 +28,9 @@ pub enum LibError {
DataNotUtf8(std::string::FromUtf8Error),
/// Provided string is not a valid MIME type
InvalidMime(mime::FromStrError),
/// Hickory Client error
/// Hickory DNS client error
#[cfg(feature = "hickory")]
DnsClientError(HickoryClientError),
/// Hickory Proto error
#[cfg(feature = "hickory")]
DnsProtoError(HickoryProtoError),
/// Could not get Tokio runtime handle
/// inside Rustls cert verifier
#[cfg(feature = "hickory")]
NoTokioRuntime(TryCurrentError),
}
impl From<std::io::Error> for LibError {
@ -58,6 +54,20 @@ impl From<InvalidUrl> for LibError {
}
}
impl From<rustls::Error> for LibError {
#[inline]
fn from(err: rustls::Error) -> Self {
Self::RustlsError(err)
}
}
impl From<rustls::CertificateError> for LibError {
#[inline]
fn from(err: rustls::CertificateError) -> Self {
Self::RustlsError(err.into())
}
}
impl LibError {
#[inline]
pub fn status_out_of_range(num: u8) -> Self {
@ -91,15 +101,7 @@ impl From<HickoryClientError> for LibError {
impl From<HickoryProtoError> for LibError {
#[inline]
fn from(err: HickoryProtoError) -> Self {
Self::DnsProtoError(err)
}
}
#[cfg(feature = "hickory")]
impl From<TryCurrentError> for LibError {
#[inline]
fn from(err: TryCurrentError) -> Self {
Self::NoTokioRuntime(err)
Self::DnsClientError(err.into())
}
}