refactor/feat: add cert verifier call, cleanup and extend error enum
This commit is contained in:
parent
04ebac7d6c
commit
ef307f4983
2 changed files with 37 additions and 21 deletions
|
@ -25,7 +25,7 @@ use tokio::{
|
||||||
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt},
|
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt},
|
||||||
net::TcpStream,
|
net::TcpStream,
|
||||||
};
|
};
|
||||||
use tokio_rustls::TlsConnector;
|
use tokio_rustls::{rustls, TlsConnector};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
@ -101,6 +101,20 @@ impl Client {
|
||||||
let stream = self.try_connect(host, port).await?;
|
let stream = self.try_connect(host, port).await?;
|
||||||
let mut stream = self.connector.connect(domain, stream).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
|
// Write URL, then CRLF
|
||||||
stream.write_all(url_str.as_bytes()).await?;
|
stream.write_all(url_str.as_bytes()).await?;
|
||||||
stream.write_all(b"\r\n").await?;
|
stream.write_all(b"\r\n").await?;
|
||||||
|
|
42
src/error.rs
42
src/error.rs
|
@ -1,11 +1,11 @@
|
||||||
//! Library error structures and enums
|
//! Library error structures and enums
|
||||||
|
|
||||||
|
use tokio_rustls::rustls;
|
||||||
|
|
||||||
#[cfg(feature = "hickory")]
|
#[cfg(feature = "hickory")]
|
||||||
use hickory_client::{
|
use hickory_client::{
|
||||||
error::ClientError as HickoryClientError, proto::error::ProtoError as HickoryProtoError,
|
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
|
/// Main error structure, also a wrapper for everything else
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -15,9 +15,12 @@ pub enum LibError {
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
/// URL parse or check error
|
/// URL parse or check error
|
||||||
InvalidUrlError(InvalidUrl),
|
InvalidUrlError(InvalidUrl),
|
||||||
/// DNS provided no suitable records
|
/// DNS server has provided no suitable records
|
||||||
/// (e. g. domain does not exist)
|
/// (e. g. domain does not exist)
|
||||||
HostLookupError,
|
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
|
/// Response status code is out of [10; 69] range
|
||||||
StatusOutOfRange(u8),
|
StatusOutOfRange(u8),
|
||||||
/// Response metadata or content cannot be parsed
|
/// Response metadata or content cannot be parsed
|
||||||
|
@ -25,16 +28,9 @@ pub enum LibError {
|
||||||
DataNotUtf8(std::string::FromUtf8Error),
|
DataNotUtf8(std::string::FromUtf8Error),
|
||||||
/// Provided string is not a valid MIME type
|
/// Provided string is not a valid MIME type
|
||||||
InvalidMime(mime::FromStrError),
|
InvalidMime(mime::FromStrError),
|
||||||
/// Hickory Client error
|
/// Hickory DNS client error
|
||||||
#[cfg(feature = "hickory")]
|
#[cfg(feature = "hickory")]
|
||||||
DnsClientError(HickoryClientError),
|
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 {
|
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 {
|
impl LibError {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn status_out_of_range(num: u8) -> Self {
|
pub fn status_out_of_range(num: u8) -> Self {
|
||||||
|
@ -91,15 +101,7 @@ impl From<HickoryClientError> for LibError {
|
||||||
impl From<HickoryProtoError> for LibError {
|
impl From<HickoryProtoError> for LibError {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(err: HickoryProtoError) -> Self {
|
fn from(err: HickoryProtoError) -> Self {
|
||||||
Self::DnsProtoError(err)
|
Self::DnsClientError(err.into())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "hickory")]
|
|
||||||
impl From<TryCurrentError> for LibError {
|
|
||||||
#[inline]
|
|
||||||
fn from(err: TryCurrentError) -> Self {
|
|
||||||
Self::NoTokioRuntime(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue