Update to in-progress Rustls, webpki, and webpki-roots.

Use the new, less error-prone, API in Rustls.
This commit is contained in:
Brian Smith 2017-09-03 12:58:55 -10:00
parent 6a8c6431a3
commit 51ed8da9cb
6 changed files with 24 additions and 16 deletions

View File

@ -17,13 +17,14 @@ appveyor = { repository = "quininer/tokio-rustls" }
[dependencies] [dependencies]
futures = "0.1.15" futures = "0.1.15"
tokio-io = "0.1.3" tokio-io = "0.1.3"
rustls = "0.11" rustls = { git = "https://github.com/ctz/rustls" }
tokio-proto = { version = "0.1.1", optional = true } tokio-proto = { version = "0.1.1", optional = true }
webpki = { git = "https://github.com/briansmith/webpki" }
[dev-dependencies] [dev-dependencies]
tokio-core = "0.1.9" tokio-core = "0.1.9"
clap = "2.26" clap = "2.26"
webpki-roots = "0.13" webpki-roots = { git = "https://github.com/briansmith/webpki-roots", branch = "webpki-github" }
[target.'cfg(unix)'.dev-dependencies] [target.'cfg(unix)'.dev-dependencies]
tokio-file-unix = "0.4" tokio-file-unix = "0.4"

View File

@ -3,6 +3,7 @@ extern crate rustls;
extern crate futures; extern crate futures;
extern crate tokio_io; extern crate tokio_io;
extern crate tokio_core; extern crate tokio_core;
extern crate webpki;
extern crate webpki_roots; extern crate webpki_roots;
extern crate tokio_rustls; extern crate tokio_rustls;
@ -68,6 +69,8 @@ fn main() {
} }
let arc_config = Arc::new(config); let arc_config = Arc::new(config);
let domain = webpki::DNSNameRef::try_from_ascii_str(domain).unwrap();
let socket = TcpStream::connect(&addr, &handle); let socket = TcpStream::connect(&addr, &handle);
// Use async non-blocking I/O for stdin/stdout on Unixy platforms. // Use async non-blocking I/O for stdin/stdout on Unixy platforms.

View File

@ -11,7 +11,7 @@ use std::net::ToSocketAddrs;
use std::io::BufReader; use std::io::BufReader;
use std::fs::File; use std::fs::File;
use futures::{ Future, Stream }; use futures::{ Future, Stream };
use rustls::{ Certificate, PrivateKey, ServerConfig }; use rustls::{ Certificate, NoClientAuth, PrivateKey, ServerConfig };
use rustls::internal::pemfile::{ certs, rsa_private_keys }; use rustls::internal::pemfile::{ certs, rsa_private_keys };
use tokio_io::{ io, AsyncRead }; use tokio_io::{ io, AsyncRead };
use tokio_core::net::TcpListener; use tokio_core::net::TcpListener;
@ -51,7 +51,7 @@ fn main() {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let handle = core.handle(); let handle = core.handle();
let mut config = ServerConfig::new(); let mut config = ServerConfig::new(NoClientAuth::new());
config.set_single_cert(load_certs(cert_file), load_keys(key_file).remove(0)); config.set_single_cert(load_certs(cert_file), load_keys(key_file).remove(0));
let arc_config = Arc::new(config); let arc_config = Arc::new(config);

View File

@ -4,6 +4,7 @@
#[cfg_attr(feature = "tokio-proto", macro_use)] extern crate futures; #[cfg_attr(feature = "tokio-proto", macro_use)] extern crate futures;
#[macro_use] extern crate tokio_io; #[macro_use] extern crate tokio_io;
extern crate rustls; extern crate rustls;
extern crate webpki;
pub mod proto; pub mod proto;
@ -19,7 +20,7 @@ use rustls::{
/// Extension trait for the `Arc<ClientConfig>` type in the `rustls` crate. /// Extension trait for the `Arc<ClientConfig>` type in the `rustls` crate.
pub trait ClientConfigExt { pub trait ClientConfigExt {
fn connect_async<S>(&self, domain: &str, stream: S) fn connect_async<S>(&self, domain: webpki::DNSNameRef, stream: S)
-> ConnectAsync<S> -> ConnectAsync<S>
where S: AsyncRead + AsyncWrite; where S: AsyncRead + AsyncWrite;
} }
@ -42,7 +43,7 @@ pub struct AcceptAsync<S>(MidHandshake<S, ServerSession>);
impl ClientConfigExt for Arc<ClientConfig> { impl ClientConfigExt for Arc<ClientConfig> {
fn connect_async<S>(&self, domain: &str, stream: S) fn connect_async<S>(&self, domain: webpki::DNSNameRef, stream: S)
-> ConnectAsync<S> -> ConnectAsync<S>
where S: AsyncRead + AsyncWrite where S: AsyncRead + AsyncWrite
{ {

View File

@ -19,6 +19,7 @@ use rustls::{ ServerConfig, ClientConfig, ServerSession, ClientSession };
use self::tokio_proto::multiplex; use self::tokio_proto::multiplex;
use self::tokio_proto::pipeline; use self::tokio_proto::pipeline;
use self::tokio_proto::streaming; use self::tokio_proto::streaming;
use webpki;
use { TlsStream, ServerConfigExt, ClientConfigExt, AcceptAsync, ConnectAsync }; use { TlsStream, ServerConfigExt, ClientConfigExt, AcceptAsync, ConnectAsync };
@ -292,7 +293,7 @@ impl<T, I> Future for ServerStreamingMultiplexBind<T, I>
pub struct Client<T> { pub struct Client<T> {
inner: Arc<T>, inner: Arc<T>,
connector: Arc<ClientConfig>, connector: Arc<ClientConfig>,
hostname: String, hostname: webpki::DNSName,
} }
impl<T> Client<T> { impl<T> Client<T> {
@ -303,11 +304,11 @@ impl<T> Client<T> {
/// will go through the negotiated TLS stream through the `protocol` specified. /// will go through the negotiated TLS stream through the `protocol` specified.
pub fn new(protocol: T, pub fn new(protocol: T,
connector: Arc<ClientConfig>, connector: Arc<ClientConfig>,
hostname: &str) -> Client<T> { hostname: webpki::DNSName) -> Client<T> {
Client { Client {
inner: Arc::new(protocol), inner: Arc::new(protocol),
connector: connector, connector: connector,
hostname: hostname.to_string(), hostname: hostname,
} }
} }
} }
@ -339,7 +340,7 @@ impl<T, I> pipeline::ClientProto<I> for Client<T>
fn bind_transport(&self, io: I) -> Self::BindTransport { fn bind_transport(&self, io: I) -> Self::BindTransport {
let proto = self.inner.clone(); let proto = self.inner.clone();
let io = self.connector.connect_async(&self.hostname, io); let io = self.connector.connect_async(self.hostname.as_ref(), io);
ClientPipelineBind { ClientPipelineBind {
state: ClientPipelineState::First(io, proto), state: ClientPipelineState::First(io, proto),
@ -397,7 +398,7 @@ impl<T, I> multiplex::ClientProto<I> for Client<T>
fn bind_transport(&self, io: I) -> Self::BindTransport { fn bind_transport(&self, io: I) -> Self::BindTransport {
let proto = self.inner.clone(); let proto = self.inner.clone();
let io = self.connector.connect_async(&self.hostname, io); let io = self.connector.connect_async(self.hostname.as_ref(), io);
ClientMultiplexBind { ClientMultiplexBind {
state: ClientMultiplexState::First(io, proto), state: ClientMultiplexState::First(io, proto),
@ -458,7 +459,7 @@ impl<T, I> streaming::pipeline::ClientProto<I> for Client<T>
fn bind_transport(&self, io: I) -> Self::BindTransport { fn bind_transport(&self, io: I) -> Self::BindTransport {
let proto = self.inner.clone(); let proto = self.inner.clone();
let io = self.connector.connect_async(&self.hostname, io); let io = self.connector.connect_async(self.hostname.as_ref(), io);
ClientStreamingPipelineBind { ClientStreamingPipelineBind {
state: ClientStreamingPipelineState::First(io, proto), state: ClientStreamingPipelineState::First(io, proto),
@ -519,7 +520,7 @@ impl<T, I> streaming::multiplex::ClientProto<I> for Client<T>
fn bind_transport(&self, io: I) -> Self::BindTransport { fn bind_transport(&self, io: I) -> Self::BindTransport {
let proto = self.inner.clone(); let proto = self.inner.clone();
let io = self.connector.connect_async(&self.hostname, io); let io = self.connector.connect_async(self.hostname.as_ref(), io);
ClientStreamingMultiplexBind { ClientStreamingMultiplexBind {
state: ClientStreamingMultiplexState::First(io, proto), state: ClientStreamingMultiplexState::First(io, proto),

View File

@ -3,6 +3,7 @@ extern crate futures;
extern crate tokio_core; extern crate tokio_core;
extern crate tokio_io; extern crate tokio_io;
extern crate tokio_rustls; extern crate tokio_rustls;
extern crate webpki;
use std::{ io, thread }; use std::{ io, thread };
use std::io::{ BufReader, Cursor }; use std::io::{ BufReader, Cursor };
@ -24,7 +25,7 @@ const HELLO_WORLD: &[u8] = b"Hello world!";
fn start_server(cert: Vec<Certificate>, rsa: PrivateKey) -> SocketAddr { fn start_server(cert: Vec<Certificate>, rsa: PrivateKey) -> SocketAddr {
let mut config = ServerConfig::new(); let mut config = ServerConfig::new(rustls::NoClientAuth::new());
config.set_single_cert(cert, rsa); config.set_single_cert(cert, rsa);
let config = Arc::new(config); let config = Arc::new(config);
@ -60,7 +61,9 @@ fn start_server(cert: Vec<Certificate>, rsa: PrivateKey) -> SocketAddr {
recv.recv().unwrap() recv.recv().unwrap()
} }
fn start_client(addr: &SocketAddr, domain: &str, chain: Option<BufReader<Cursor<&str>>>) -> io::Result<()> { fn start_client(addr: &SocketAddr, domain: &str,
chain: Option<BufReader<Cursor<&str>>>) -> io::Result<()> {
let domain = webpki::DNSNameRef::try_from_ascii_str(domain).unwrap();
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
if let Some(mut chain) = chain { if let Some(mut chain) = chain {
config.root_store.add_pem_file(&mut chain).unwrap(); config.root_store.add_pem_file(&mut chain).unwrap();
@ -91,7 +94,6 @@ fn main() {
let chain = BufReader::new(Cursor::new(CHAIN)); let chain = BufReader::new(Cursor::new(CHAIN));
let addr = start_server(cert, keys.pop().unwrap()); let addr = start_server(cert, keys.pop().unwrap());
start_client(&addr, "localhost", Some(chain)).unwrap(); start_client(&addr, "localhost", Some(chain)).unwrap();
} }