Skip to content

Commit

Permalink
v0.4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Dec 7, 2023
1 parent 09981bc commit d776716
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mail-send 0.4.3
================================
- Bump `rustls` dependency to 0.22

mail-send 0.4.2
================================
- Bump `webpki-roots` dependency to 0.26
Expand Down
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "mail-send"
description = "E-mail delivery library with SMTP and DKIM support"
version = "0.4.2"
version = "0.4.3"
edition = "2021"
authors = [ "Stalwart Labs <hello@stalw.art>"]
license = "Apache-2.0 OR MIT"
Expand All @@ -22,9 +22,10 @@ base64 = "0.21"
rand = { version = "0.8.5", optional = true }
md5 = { version = "0.7.0", optional = true }
tokio = { version = "1.23", features = ["net", "io-util", "time"]}
rustls = { version = "0.21", features = ["tls12", "dangerous_configuration"]}
tokio-rustls = { version = "0.24"}
rustls = { version = "0.22", features = ["tls12"]}
tokio-rustls = { version = "0.25"}
webpki-roots = { version = "0.26"}
rustls-pki-types = { version = "1" }
gethostname = { version = "0.4"}

[dev-dependencies]
Expand Down
15 changes: 15 additions & 0 deletions src/smtp/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,24 @@ mod test {
.await
.unwrap();
client.quit().await.unwrap();
let client = SmtpClientBuilder::new("mail.smtp2go.com", 2525)
.allow_invalid_certs()
.implicit_tls(false)
.connect()
.await
.unwrap();
client.quit().await.unwrap();

// Say hello to Google over TLS and quit
let client = SmtpClientBuilder::new("smtp.gmail.com", 465)
.connect()
.await
.unwrap();
client.quit().await.unwrap();

// Say hello to Google over TLS and quit
let client = SmtpClientBuilder::new("smtp.gmail.com", 465)
.allow_invalid_certs()
.connect()
.await
.unwrap();
Expand Down
77 changes: 55 additions & 22 deletions src/smtp/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
use std::{convert::TryFrom, io, sync::Arc};

use rustls::{
client::{ServerCertVerified, ServerCertVerifier},
Certificate, ClientConfig, ClientConnection, OwnedTrustAnchor, RootCertStore, ServerName,
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
ClientConfig, ClientConnection, RootCertStore, SignatureScheme,
};
use rustls_pki_types::{ServerName, TrustAnchor};
use tokio::net::TcpStream;
use tokio_rustls::{client::TlsStream, TlsConnector};

Expand Down Expand Up @@ -45,7 +46,9 @@ impl SmtpClient<TcpStream> {
Ok(SmtpClient {
stream: tls_connector
.connect(
ServerName::try_from(hostname).map_err(|_| crate::Error::InvalidTLSName)?,
ServerName::try_from(hostname)
.map_err(|_| crate::Error::InvalidTLSName)?
.to_owned(),
self.stream,
)
.await
Expand Down Expand Up @@ -75,27 +78,21 @@ impl SmtpClient<TlsStream<TcpStream>> {
}

pub fn build_tls_connector(allow_invalid_certs: bool) -> TlsConnector {
let config = ClientConfig::builder().with_safe_defaults();

let config = if !allow_invalid_certs {
let mut root_cert_store = RootCertStore::empty();

root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject.as_ref(),
ta.subject_public_key_info.as_ref(),
ta.name_constraints.as_ref().map(|v| v.as_ref()),
)
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| TrustAnchor {
subject: ta.subject.clone(),
subject_public_key_info: ta.subject_public_key_info.clone(),
name_constraints: ta.name_constraints.clone(),
}));

//config
// .with_custom_certificate_verifier(Arc::new(WebPkiVerifier::new(root_cert_store, None)))

config
ClientConfig::builder()
.with_root_certificates(root_cert_store)
.with_no_client_auth()
} else {
config
ClientConfig::builder()
.dangerous()
.with_custom_certificate_verifier(Arc::new(DummyVerifier {}))
.with_no_client_auth()
};
Expand All @@ -104,18 +101,54 @@ pub fn build_tls_connector(allow_invalid_certs: bool) -> TlsConnector {
}

#[doc(hidden)]
#[derive(Debug)]
struct DummyVerifier;

impl ServerCertVerifier for DummyVerifier {
fn verify_server_cert(
&self,
_e: &Certificate,
_i: &[Certificate],
_sn: &ServerName,
_sc: &mut dyn Iterator<Item = &[u8]>,
_o: &[u8],
_n: std::time::SystemTime,
_end_entity: &rustls_pki_types::CertificateDer<'_>,
_intermediates: &[rustls_pki_types::CertificateDer<'_>],
_server_name: &rustls_pki_types::ServerName<'_>,
_ocsp_response: &[u8],
_now: rustls_pki_types::UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
Ok(ServerCertVerified::assertion())
}

fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
Ok(HandshakeSignatureValid::assertion())
}

fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
Ok(HandshakeSignatureValid::assertion())
}

fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
vec![
SignatureScheme::RSA_PKCS1_SHA1,
SignatureScheme::ECDSA_SHA1_Legacy,
SignatureScheme::RSA_PKCS1_SHA256,
SignatureScheme::ECDSA_NISTP256_SHA256,
SignatureScheme::RSA_PKCS1_SHA384,
SignatureScheme::ECDSA_NISTP384_SHA384,
SignatureScheme::RSA_PKCS1_SHA512,
SignatureScheme::ECDSA_NISTP521_SHA512,
SignatureScheme::RSA_PSS_SHA256,
SignatureScheme::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA512,
SignatureScheme::ED25519,
SignatureScheme::ED448,
]
}
}

0 comments on commit d776716

Please sign in to comment.