Skip to content

Commit 946e0ac

Browse files
djcg2p
authored andcommitted
Upgrade to rustls 0.20
1 parent 665929a commit 946e0ac

File tree

5 files changed

+59
-44
lines changed

5 files changed

+59
-44
lines changed

Cargo.toml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ repository = "https://github.com/ctz/hyper-rustls"
1111

1212
[dependencies]
1313
log = "0.4.4"
14-
ct-logs = { version = "^0.8", optional = true }
14+
ct-logs = { version = "^0.9", optional = true }
1515
hyper = { version = "0.14", default-features = false, features = ["client", "http1"] }
16-
rustls = "0.19"
17-
rustls-native-certs = { version = "0.5.0", optional = true }
16+
rustls = { git = "https://github.com/ctz/rustls" }
17+
rustls-native-certs = { git = "https://github.com/djc/rustls-native-certs", rev = "6116ef59f5825b0ec74a38807635a70433d68c27", optional = true }
18+
rustls-pemfile = { version = "0.2.1" }
1819
tokio = "1.0"
19-
tokio-rustls = "0.22"
20-
webpki = "0.21.0"
21-
webpki-roots = { version = "0.21", optional = true }
20+
tokio-rustls = { version = "0.23", git = "https://github.com/tokio-rs/tls", rev = "b433932bf1025960e5b99f353cf8eee4ce2f08f3" }
21+
webpki = "0.22.0"
22+
webpki-roots = { version = "0.22", optional = true }
2223

2324
[dev-dependencies]
2425
async-stream = "0.3.0"
@@ -47,3 +48,6 @@ required-features = ["tokio-runtime"]
4748
[package.metadata.docs.rs]
4849
all-features = true
4950
rustdoc-args = ["--cfg", "docsrs"]
51+
52+
[patch."crates-io"]
53+
rustls = { git = "https://github.com/ctz/rustls" }

examples/client.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//! First parameter is the mandatory URL to GET.
44
//! Second parameter is an optional path to CA store.
55
use hyper::{body::to_bytes, client, Body, Uri};
6+
use rustls::RootCertStore;
7+
68
use std::str::FromStr;
79
use std::{env, fs, io};
810

@@ -46,11 +48,16 @@ async fn run_client() -> io::Result<()> {
4648
// Build an HTTP connector which supports HTTPS too.
4749
let mut http = client::HttpConnector::new();
4850
http.enforce_http(false);
49-
// Build a TLS client, using the custom CA store for lookups.
50-
let mut tls = rustls::ClientConfig::new();
51-
tls.root_store
52-
.add_pem_file(rd)
51+
// Read trust roots
52+
let certs = rustls_pemfile::certs(rd)
5353
.map_err(|_| error("failed to load custom CA store".into()))?;
54+
let mut roots = RootCertStore::empty();
55+
roots.add_parsable_certificates(&certs);
56+
// Build a TLS client, using the custom CA store for lookups.
57+
let tls = rustls::ClientConfig::builder()
58+
.with_safe_defaults()
59+
.with_root_certificates(roots, &ct_logs::LOGS)
60+
.with_no_client_auth();
5461
// Join the above part into an HTTPS connector.
5562
hyper_rustls::HttpsConnector::from((http, tls))
5663
}

examples/server.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
//! Certificate and private key are hardcoded to sample files.
55
//! hyper will automatically use HTTP/2 if a client starts talking HTTP/2,
66
//! otherwise HTTP/1.1 will be used.
7+
use std::pin::Pin;
8+
use std::{env, fs, io, sync};
9+
710
use async_stream::stream;
811
use futures_util::future::TryFutureExt;
912
use hyper::server::accept;
1013
use hyper::service::{make_service_fn, service_fn};
1114
use hyper::{Body, Method, Request, Response, Server, StatusCode};
12-
use rustls::internal::pemfile;
13-
use std::vec::Vec;
14-
use std::{env, fs, io, sync};
1515
use tokio::net::TcpListener;
1616
use tokio_rustls::TlsAcceptor;
1717

@@ -43,12 +43,13 @@ async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
4343
// Load private key.
4444
let key = load_private_key("examples/sample.rsa")?;
4545
// Do not use client certificate authentication.
46-
let mut cfg = rustls::ServerConfig::new(rustls::NoClientAuth::new());
47-
// Select a certificate to use.
48-
cfg.set_single_cert(certs, key)
46+
let mut cfg = rustls::ServerConfig::builder()
47+
.with_safe_defaults()
48+
.with_no_client_auth()
49+
.with_single_cert(certs, key)
4950
.map_err(|e| error(format!("{}", e)))?;
5051
// Configure ALPN to accept HTTP/2, HTTP/1.1 in that order.
51-
cfg.set_protocols(&[b"h2".to_vec(), b"http/1.1".to_vec()]);
52+
cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
5253
sync::Arc::new(cfg)
5354
};
5455

@@ -107,7 +108,9 @@ fn load_certs(filename: &str) -> io::Result<Vec<rustls::Certificate>> {
107108
let mut reader = io::BufReader::new(certfile);
108109

109110
// Load and return certificate.
110-
pemfile::certs(&mut reader).map_err(|_| error("failed to load certificate".into()))
111+
let certs = rustls_pemfile::certs(&mut reader)
112+
.map_err(|_| error("failed to load certificate".into()))?;
113+
Ok(certs.into_iter().map(rustls::Certificate).collect())
111114
}
112115

113116
// Load private key from file.
@@ -118,10 +121,11 @@ fn load_private_key(filename: &str) -> io::Result<rustls::PrivateKey> {
118121
let mut reader = io::BufReader::new(keyfile);
119122

120123
// Load and return a single private key.
121-
let keys = pemfile::rsa_private_keys(&mut reader)
124+
let keys = rustls_pemfile::rsa_private_keys(&mut reader)
122125
.map_err(|_| error("failed to load private key".into()))?;
123126
if keys.len() != 1 {
124127
return Err(error("expected a single private key".into()));
125128
}
126-
Ok(keys[0].clone())
129+
130+
Ok(rustls::PrivateKey(keys[0].clone()))
127131
}

src/connector.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
#[cfg(feature = "tokio-runtime")]
2-
use hyper::client::connect::HttpConnector;
3-
use hyper::{client::connect::Connection, service::Service, Uri};
4-
use rustls::ClientConfig;
51
use std::future::Future;
62
use std::pin::Pin;
73
use std::sync::Arc;
84
use std::task::{Context, Poll};
95
use std::{fmt, io};
6+
use std::convert::TryFrom;
7+
8+
#[cfg(feature = "tokio-runtime")]
9+
use hyper::client::connect::HttpConnector;
10+
use hyper::{client::connect::Connection, service::Service, Uri};
11+
use rustls::{ClientConfig, RootCertStore};
1012
use tokio::io::{AsyncRead, AsyncWrite};
1113
use tokio_rustls::TlsConnector;
12-
use webpki::DNSNameRef;
1314

1415
use crate::stream::MaybeHttpsStream;
1516

@@ -32,30 +33,30 @@ impl HttpsConnector<HttpConnector> {
3233
#[cfg(feature = "rustls-native-certs")]
3334
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))]
3435
pub fn with_native_roots() -> Self {
35-
let mut config = ClientConfig::new();
36-
config.root_store = match rustls_native_certs::load_native_certs() {
37-
Ok(store) => store,
38-
Err((Some(store), err)) => {
39-
log::warn!("Could not load all certificates: {:?}", err);
40-
store
41-
}
42-
Err((None, err)) => Err(err).expect("cannot access native cert store"),
36+
let certs = match rustls_native_certs::load_native_certs() {
37+
Ok(certs) => certs,
38+
Err(err) => Err(err).expect("cannot access native cert store"),
4339
};
44-
if config.root_store.is_empty() {
40+
41+
if certs.is_empty() {
4542
panic!("no CA certificates found");
4643
}
47-
Self::build(config)
44+
45+
let mut roots = RootCertStore::empty();
46+
for cert in certs {
47+
roots.add_parsable_certificates(&[cert.0]);
48+
}
49+
50+
Self::build(roots)
4851
}
4952

5053
/// Construct a new `HttpsConnector` using the `webpki_roots`
5154
#[cfg(feature = "webpki-roots")]
5255
#[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))]
5356
pub fn with_webpki_roots() -> Self {
54-
let mut config = ClientConfig::new();
55-
config
56-
.root_store
57-
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
58-
Self::build(config)
57+
let mut roots = rustls::RootCertStore::empty();
58+
roots.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0);
59+
Self::build(roots)
5960
}
6061

6162
/// Force the use of HTTPS when connecting.
@@ -80,7 +81,6 @@ impl HttpsConnector<HttpConnector> {
8081
config.alpn_protocols.push(b"http/1.1".to_vec());
8182
}
8283

83-
config.ct_logs = Some(&ct_logs::LOGS);
8484
(http, config).into()
8585
}
8686
}
@@ -152,7 +152,7 @@ where
152152
let f = async move {
153153
let tcp = connecting_future.await.map_err(Into::into)?;
154154
let connector = TlsConnector::from(cfg);
155-
let dnsname = DNSNameRef::try_from_ascii_str(&hostname)
155+
let dnsname = rustls::ServerName::try_from(hostname.as_str())
156156
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid dnsname"))?;
157157
let tls = connector
158158
.connect(dnsname, tcp)

src/stream.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use std::task::{Context, Poll};
66

77
use hyper::client::connect::{Connected, Connection};
88

9-
use rustls::Session;
109
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
1110
use tokio_rustls::client::TlsStream;
11+
use tokio_rustls::rustls::{Connection as _};
1212

1313
/// A stream that might be protected with TLS.
1414
pub enum MaybeHttpsStream<T> {
@@ -24,7 +24,7 @@ impl<T: AsyncRead + AsyncWrite + Connection + Unpin> Connection for MaybeHttpsSt
2424
MaybeHttpsStream::Http(s) => s.connected(),
2525
MaybeHttpsStream::Https(s) => {
2626
let (tcp, tls) = s.get_ref();
27-
if tls.get_alpn_protocol() == Some(b"h2") {
27+
if tls.alpn_protocol() == Some(b"h2") {
2828
tcp.connected().negotiated_h2()
2929
} else {
3030
tcp.connected()

0 commit comments

Comments
 (0)