Update rustls to 0.20 (#648)

This commit is contained in:
Paolo Barbolini
2021-10-20 14:37:16 +02:00
committed by GitHub
parent 8f28b0c341
commit 97d3c760c0
4 changed files with 73 additions and 46 deletions

View File

@@ -41,9 +41,9 @@ hostname = { version = "0.3", optional = true } # feature
## tls
native-tls = { version = "0.2", optional = true } # feature
rustls = { version = "0.19", features = ["dangerous_configuration"], optional = true }
webpki = { version = "0.21", optional = true }
webpki-roots = { version = "0.21", optional = true }
rustls = { version = "0.20", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "0.2.1", optional = true }
webpki-roots = { version = "0.22", optional = true }
# async
futures-io = { version = "0.3.7", optional = true }
@@ -53,12 +53,12 @@ async-trait = { version = "0.1", optional = true }
## async-std
async-std = { version = "1.8", optional = true, features = ["unstable"] }
#async-native-tls = { version = "0.3.3", optional = true }
async-rustls = { version = "0.2", optional = true }
futures-rustls = { version = "0.22", optional = true }
## tokio
tokio1_crate = { package = "tokio", version = "1", features = ["fs", "process", "time", "net", "io-util"], optional = true }
tokio1_native_tls_crate = { package = "tokio-native-tls", version = "0.3", optional = true }
tokio1_rustls = { package = "tokio-rustls", version = "0.22", optional = true }
tokio1_rustls = { package = "tokio-rustls", version = "0.23", optional = true }
[dev-dependencies]
criterion = "0.3"
@@ -87,12 +87,12 @@ smtp-transport = ["base64", "nom"]
pool = ["futures-util"]
rustls-tls = ["webpki", "webpki-roots", "rustls"]
rustls-tls = ["webpki-roots", "rustls", "rustls-pemfile"]
# async
async-std1 = ["async-std", "async-trait", "futures-io", "futures-util"]
#async-std1-native-tls = ["async-std1", "native-tls", "async-native-tls"]
async-std1-rustls-tls = ["async-std1", "rustls-tls", "async-rustls"]
async-std1-rustls-tls = ["async-std1", "rustls-tls", "futures-rustls"]
tokio1 = ["tokio1_crate", "async-trait", "futures-io", "futures-util"]
tokio1-native-tls = ["tokio1", "native-tls", "tokio1_native_tls_crate"]
tokio1-rustls-tls = ["tokio1", "rustls-tls", "tokio1_rustls"]

View File

@@ -24,7 +24,7 @@ use async_native_tls::TlsStream as AsyncStd1TlsStream;
use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream;
#[cfg(feature = "async-std1-rustls-tls")]
use async_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
use futures_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
#[cfg(feature = "tokio1-rustls-tls")]
use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream;
@@ -261,9 +261,9 @@ impl AsyncNetworkStream {
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))]
async fn upgrade_tokio1_tls(
tcp_stream: Tokio1TcpStream,
mut tls_parameters: TlsParameters,
tls_parameters: TlsParameters,
) -> Result<InnerAsyncNetworkStream, Error> {
let domain = mem::take(&mut tls_parameters.domain);
let domain = tls_parameters.domain().to_string();
match tls_parameters.connector {
#[cfg(feature = "native-tls")]
@@ -290,10 +290,13 @@ impl AsyncNetworkStream {
#[cfg(feature = "tokio1-rustls-tls")]
return {
use tokio1_rustls::{webpki::DNSNameRef, TlsConnector};
use std::convert::TryFrom;
let domain =
DNSNameRef::try_from_ascii_str(&domain).map_err(error::connection)?;
use rustls::ServerName;
use tokio1_rustls::TlsConnector;
let domain = ServerName::try_from(domain.as_str())
.map_err(|_| error::connection("domain isn't a valid DNS name"))?;
let connector = TlsConnector::from(config);
let stream = connector
@@ -342,10 +345,13 @@ impl AsyncNetworkStream {
#[cfg(feature = "async-std1-rustls-tls")]
return {
use async_rustls::{webpki::DNSNameRef, TlsConnector};
use std::convert::TryFrom;
let domain =
DNSNameRef::try_from_ascii_str(&domain).map_err(error::connection)?;
use futures_rustls::TlsConnector;
use rustls::ServerName;
let domain = ServerName::try_from(domain.as_str())
.map_err(|_| error::connection("domain isn't a valid DNS name"))?;
let connector = TlsConnector::from(config);
let stream = connector

View File

@@ -1,3 +1,5 @@
#[cfg(feature = "rustls-tls")]
use std::convert::TryFrom;
use std::{
io::{self, Read, Write},
mem,
@@ -9,7 +11,7 @@ use std::{
use native_tls::TlsStream;
#[cfg(feature = "rustls-tls")]
use rustls::{ClientSession, StreamOwned};
use rustls::{ClientConnection, ServerName, StreamOwned};
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
use super::InnerTlsParameters;
@@ -33,7 +35,7 @@ enum InnerNetworkStream {
NativeTls(TlsStream<TcpStream>),
/// Encrypted TCP stream
#[cfg(feature = "rustls-tls")]
RustlsTls(StreamOwned<ClientSession, TcpStream>),
RustlsTls(StreamOwned<ClientConnection, TcpStream>),
/// Can't be built
None,
}
@@ -157,12 +159,11 @@ impl NetworkStream {
}
#[cfg(feature = "rustls-tls")]
InnerTlsParameters::RustlsTls(connector) => {
use webpki::DNSNameRef;
let domain = DNSNameRef::try_from_ascii_str(tls_parameters.domain())
.map_err(error::connection)?;
let stream = StreamOwned::new(ClientSession::new(connector, domain), tcp_stream);
let domain = ServerName::try_from(tls_parameters.domain())
.map_err(|_| error::connection("domain isn't a valid DNS name"))?;
let connection =
ClientConnection::new(connector.clone(), domain).map_err(error::connection)?;
let stream = StreamOwned::new(connection, tcp_stream);
InnerNetworkStream::RustlsTls(stream)
}
})

View File

@@ -3,12 +3,13 @@ use crate::transport::smtp::{error, Error};
#[cfg(feature = "native-tls")]
use native_tls::{Protocol, TlsConnector};
#[cfg(feature = "rustls-tls")]
use rustls::{ClientConfig, RootCertStore, ServerCertVerified, ServerCertVerifier, TLSError};
use rustls::{
client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
ClientConfig, Error as TlsError, OwnedTrustAnchor, RootCertStore, ServerName,
};
use std::fmt::{self, Debug};
#[cfg(feature = "rustls-tls")]
use std::sync::Arc;
#[cfg(feature = "rustls-tls")]
use webpki::DNSNameRef;
use std::{sync::Arc, time::SystemTime};
/// Accepted protocols by default.
/// This removes TLS 1.0 and 1.1 compared to tls-native defaults.
@@ -163,21 +164,35 @@ impl TlsParametersBuilder {
#[cfg(feature = "rustls-tls")]
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
pub fn build_rustls(self) -> Result<TlsParameters, Error> {
use webpki_roots::TLS_SERVER_ROOTS;
let tls = ClientConfig::builder();
let tls = tls.with_safe_defaults();
let mut tls = ClientConfig::new();
for cert in self.root_certs {
for rustls_cert in cert.rustls {
tls.root_store.add(&rustls_cert).map_err(error::tls)?;
let tls = if self.accept_invalid_certs {
tls.with_custom_certificate_verifier(Arc::new(InvalidCertsVerifier {}))
} else {
let mut root_cert_store = RootCertStore::empty();
for cert in self.root_certs {
for rustls_cert in cert.rustls {
root_cert_store.add(&rustls_cert).map_err(error::tls)?;
}
}
}
if self.accept_invalid_certs {
tls.dangerous()
.set_certificate_verifier(Arc::new(InvalidCertsVerifier {}));
}
root_cert_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(
|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
},
));
tls.with_custom_certificate_verifier(Arc::new(WebPkiVerifier::new(
root_cert_store,
None,
)))
};
let tls = tls.with_no_client_auth();
tls.root_store.add_server_trust_anchors(&TLS_SERVER_ROOTS);
Ok(TlsParameters {
connector: InnerTlsParameters::RustlsTls(Arc::new(tls)),
domain: self.domain,
@@ -257,11 +272,14 @@ impl Certificate {
#[cfg(feature = "rustls-tls")]
let rustls_cert = {
use rustls::internal::pemfile;
use std::io::Cursor;
let mut pem = Cursor::new(pem);
pemfile::certs(&mut pem).map_err(|_| error::tls("invalid certificates"))?
rustls_pemfile::certs(&mut pem)
.map_err(|_| error::tls("invalid certificates"))?
.into_iter()
.map(rustls::Certificate)
.collect::<Vec<_>>()
};
Ok(Self {
@@ -286,11 +304,13 @@ struct InvalidCertsVerifier;
impl ServerCertVerifier for InvalidCertsVerifier {
fn verify_server_cert(
&self,
_roots: &RootCertStore,
_presented_certs: &[rustls::Certificate],
_dns_name: DNSNameRef<'_>,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
) -> Result<ServerCertVerified, TLSError> {
_now: SystemTime,
) -> Result<ServerCertVerified, TlsError> {
Ok(ServerCertVerified::assertion())
}
}