Upgrade to rustls 0.20
This commit is contained in:
parent
89697449ff
commit
f4bb653aa0
10
Cargo.toml
10
Cargo.toml
|
@ -44,19 +44,21 @@ version = "0.2.3"
|
|||
|
||||
[dependencies.rustls]
|
||||
optional = true
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
|
||||
[dependencies.rustls-native-certs]
|
||||
optional = true
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
git = "https://github.com/rustls/rustls-native-certs.git"
|
||||
rev = "87b84b51bcf38eb9d377e0f5606c444ced43cc60"
|
||||
|
||||
[dependencies.webpki]
|
||||
optional = true
|
||||
version = "0.21"
|
||||
version = "0.22"
|
||||
|
||||
[dependencies.webpki-roots]
|
||||
optional = true
|
||||
version = "0.21"
|
||||
version = "0.22"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.4"
|
||||
|
|
|
@ -56,7 +56,7 @@ pub fn connect_with_config<Req: IntoClientRequest>(
|
|||
Mode::Tls => 443,
|
||||
});
|
||||
let addrs = (host, port).to_socket_addrs()?;
|
||||
let mut stream = connect_to_some(addrs.as_slice(), &request.uri())?;
|
||||
let mut stream = connect_to_some(addrs.as_slice(), request.uri())?;
|
||||
NoDelay::set_nodelay(&mut stream, true)?;
|
||||
|
||||
#[cfg(not(any(feature = "native-tls", feature = "__rustls-tls")))]
|
||||
|
|
10
src/error.rs
10
src/error.rs
|
@ -255,9 +255,13 @@ pub enum TlsError {
|
|||
/// Rustls error.
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
#[error("rustls error: {0}")]
|
||||
Rustls(#[from] rustls::TLSError),
|
||||
Rustls(#[from] rustls::Error),
|
||||
/// Webpki error.
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
#[error("webpki error: {0}")]
|
||||
Webpki(#[from] webpki::Error),
|
||||
/// DNS name resolution error.
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
#[error("Invalid DNS name: {0}")]
|
||||
Dns(#[from] webpki::InvalidDNSNameError),
|
||||
#[error("Invalid DNS name")]
|
||||
InvalidDnsName,
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ fn create_parts<T>(request: &HttpRequest<T>) -> Result<Builder> {
|
|||
|
||||
/// Create a response for the request.
|
||||
pub fn create_response(request: &Request) -> Result<Response> {
|
||||
Ok(create_parts(&request)?.body(())?)
|
||||
Ok(create_parts(request)?.body(())?)
|
||||
}
|
||||
|
||||
/// Create a response for the request with a custom body.
|
||||
|
@ -90,7 +90,7 @@ pub fn create_response_with_body<T>(
|
|||
request: &HttpRequest<T>,
|
||||
generate_body: impl FnOnce() -> T,
|
||||
) -> Result<HttpResponse<T>> {
|
||||
Ok(create_parts(&request)?.body(generate_body())?)
|
||||
Ok(create_parts(request)?.body(generate_body())?)
|
||||
}
|
||||
|
||||
// Assumes that this is a valid response
|
||||
|
@ -263,7 +263,7 @@ impl<S: Read + Write, C: Callback> HandshakeRole for ServerHandshake<S, C> {
|
|||
let resp = self.error_response.as_ref().unwrap();
|
||||
|
||||
let mut output = vec![];
|
||||
write_response(&mut output, &resp)?;
|
||||
write_response(&mut output, resp)?;
|
||||
|
||||
if let Some(body) = resp.body() {
|
||||
output.extend_from_slice(body.as_bytes());
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
//! `native_tls` or `openssl` will work as long as there is a TLS stream supporting standard
|
||||
//! `Read + Write` traits.
|
||||
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
io::{Read, Result as IoResult, Write},
|
||||
|
@ -45,7 +47,12 @@ impl<S: Read + Write + NoDelay> NoDelay for TlsStream<S> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
impl<S: rustls::Session, T: Read + Write + NoDelay> NoDelay for StreamOwned<S, T> {
|
||||
impl<S, SD, T> NoDelay for StreamOwned<S, T>
|
||||
where
|
||||
S: Deref<Target = rustls::ConnectionCommon<SD>>,
|
||||
SD: rustls::SideData,
|
||||
T: Read + Write + NoDelay,
|
||||
{
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
|
||||
self.sock.set_nodelay(nodelay)
|
||||
}
|
||||
|
@ -61,7 +68,7 @@ pub enum MaybeTlsStream<S: Read + Write> {
|
|||
NativeTls(native_tls_crate::TlsStream<S>),
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
/// Encrypted socket stream using `rustls`.
|
||||
Rustls(rustls::StreamOwned<rustls::ClientSession, S>),
|
||||
Rustls(rustls::StreamOwned<rustls::ClientConnection, S>),
|
||||
}
|
||||
|
||||
impl<S: Read + Write + Debug> Debug for MaybeTlsStream<S> {
|
||||
|
@ -73,13 +80,13 @@ impl<S: Read + Write + Debug> Debug for MaybeTlsStream<S> {
|
|||
#[cfg(feature = "__rustls-tls")]
|
||||
Self::Rustls(s) => {
|
||||
struct RustlsStreamDebug<'a, S: Read + Write>(
|
||||
&'a rustls::StreamOwned<rustls::ClientSession, S>,
|
||||
&'a rustls::StreamOwned<rustls::ClientConnection, S>,
|
||||
);
|
||||
|
||||
impl<'a, S: Read + Write + Debug> Debug for RustlsStreamDebug<'a, S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("StreamOwned")
|
||||
.field("sess", &self.0.sess)
|
||||
.field("conn", &self.0.conn)
|
||||
.field("sock", &self.0.sock)
|
||||
.finish()
|
||||
}
|
||||
|
|
40
src/tls.rs
40
src/tls.rs
|
@ -70,10 +70,10 @@ mod encryption {
|
|||
|
||||
#[cfg(feature = "__rustls-tls")]
|
||||
pub mod rustls {
|
||||
use rustls::{ClientConfig, ClientSession, StreamOwned};
|
||||
use webpki::DNSNameRef;
|
||||
use rustls::{ClientConfig, ClientConnection, RootCertStore, ServerName, StreamOwned};
|
||||
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
io::{Read, Write},
|
||||
sync::Arc,
|
||||
};
|
||||
|
@ -100,24 +100,40 @@ mod encryption {
|
|||
Some(config) => config,
|
||||
None => {
|
||||
#[allow(unused_mut)]
|
||||
let mut config = ClientConfig::new();
|
||||
let mut root_store = RootCertStore::empty();
|
||||
|
||||
#[cfg(feature = "rustls-tls-native-roots")]
|
||||
{
|
||||
config.root_store = rustls_native_certs::load_native_certs()
|
||||
.map_err(|(_, err)| err)?;
|
||||
for cert in rustls_native_certs::load_native_certs()? {
|
||||
root_store
|
||||
.add(&rustls::Certificate(cert.0))
|
||||
.map_err(TlsError::Webpki)?;
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "rustls-tls-webpki-roots")]
|
||||
{
|
||||
config
|
||||
.root_store
|
||||
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
root_store.add_server_trust_anchors(
|
||||
webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
|
||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
Arc::new(config)
|
||||
Arc::new(
|
||||
ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let domain = DNSNameRef::try_from_ascii_str(domain).map_err(TlsError::Dns)?;
|
||||
let client = ClientSession::new(&config, domain);
|
||||
let domain =
|
||||
ServerName::try_from(domain).map_err(|_| TlsError::InvalidDnsName)?;
|
||||
let client = ClientConnection::new(config, domain).map_err(TlsError::Rustls)?;
|
||||
let stream = StreamOwned::new(client, socket);
|
||||
|
||||
Ok(MaybeTlsStream::Rustls(stream))
|
||||
|
@ -185,7 +201,7 @@ where
|
|||
None => Err(Error::Url(UrlError::NoHostName)),
|
||||
}?;
|
||||
|
||||
let mode = uri_mode(&request.uri())?;
|
||||
let mode = uri_mode(request.uri())?;
|
||||
|
||||
let stream = match connector {
|
||||
Some(conn) => match conn {
|
||||
|
|
Loading…
Reference in New Issue