Skip to content

Commit

Permalink
Applied PR tokio-rs#43 for native-tls 0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
izderadicka committed Jul 4, 2018
1 parent 90d3356 commit 39b4d92
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ appveyor = { repository = "alexcrichton/tokio-tls" }

[dependencies]
futures = "0.1.11"
native-tls = "0.1"
native-tls = "0.2"
tokio-core = "0.1.6"
tokio-io = "0.1"
tokio-proto = { version = "0.1", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion examples/download-rust-lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn main() {
let addr = "www.rust-lang.org:443".to_socket_addrs().unwrap().next().unwrap();

let socket = TcpStream::connect(&addr, &core.handle());
let cx = TlsConnector::builder().unwrap().build().unwrap();
let cx = TlsConnector::builder().build().unwrap();

let tls_handshake = socket.and_then(|socket| {
cx.connect_async("www.rust-lang.org", socket).map_err(|e| {
Expand Down
2 changes: 1 addition & 1 deletion examples/hyper-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn main() {
// Create a custom "connector" for Hyper which will route connections
// through the `TlsConnector` we create here after routing them through
// `HttpConnector` first.
let tls_cx = TlsConnector::builder().unwrap().build().unwrap();
let tls_cx = TlsConnector::builder().build().unwrap();
let mut connector = HttpsConnector {
tls: Arc::new(tls_cx),
http: HttpConnector::new(2, &core.handle()),
Expand Down
7 changes: 3 additions & 4 deletions examples/hyper-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod imp {
use futures::future::{ok, Future};
use hyper::server::Http;
use hyper::{Request, Response, StatusCode};
use native_tls::{TlsAcceptor, Pkcs12};
use native_tls::{TlsAcceptor, Identity};
use self::tokio_proto::TcpServer;
use tokio_service::Service;
use tokio_tls::proto;
Expand All @@ -40,9 +40,8 @@ mod imp {
// accepted. This is where we pass in the certificate as well to
// send to clients.
let der = include_bytes!("identity.p12");
let cert = Pkcs12::from_der(der, "mypass").unwrap();
let tls_cx = TlsAcceptor::builder(cert).unwrap()
.build().unwrap();
let cert = Identity::from_pkcs12(der, "mypass").unwrap();
let tls_cx = TlsAcceptor::builder(cert).build().unwrap();

// Wrap up hyper's `Http` protocol in our own `Server` protocol. This
// will run hyper's protocol and then wrap the result in a TLS stream,
Expand Down
37 changes: 3 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,26 +86,6 @@ pub trait TlsConnectorExt: sealed::Sealed {
/// properly.
fn connect_async<S>(&self, domain: &str, stream: S) -> ConnectAsync<S>
where S: Read + Write; // TODO: change to AsyncRead + AsyncWrite

/// Like `connect_async`, but does not validate the server's domain name
/// against its certificate.
///
/// # Warning
///
/// You should think very carefully before you use this method. If hostname
/// verification is not used, *any* valid certificate for *any* site will
/// be trusted for use from any other. This introduces a significant
/// vulnerability to man-in-the-middle attacks.
///
/// # Compatibility notes
///
/// Note that this method currently requires `S: Read + Write` but it's
/// highly recommended to ensure that the object implements the `AsyncRead`
/// and `AsyncWrite` traits as well, otherwise this function will not work
/// properly.
fn danger_connect_async_without_providing_domain_for_certificate_verification_and_server_name_indication<S>(
&self, stream: S) -> ConnectAsync<S>
where S: Read + Write; // TODO: change to AsyncRead + AsyncWrite
}

/// Extension trait for the `TlsAcceptor` type in the `native_tls` crate.
Expand Down Expand Up @@ -189,17 +169,6 @@ impl TlsConnectorExt for TlsConnector {
},
}
}

fn danger_connect_async_without_providing_domain_for_certificate_verification_and_server_name_indication<S>(
&self, stream: S) -> ConnectAsync<S>
where S: Read + Write,
{
ConnectAsync {
inner: MidHandshake {
inner: Some(self.danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication(stream)),
},
}
}
}

impl sealed::Sealed for TlsConnector {}
Expand Down Expand Up @@ -247,12 +216,12 @@ impl<S: Read + Write> Future for MidHandshake<S> {
match self.inner.take().expect("cannot poll MidHandshake twice") {
Ok(stream) => Ok(TlsStream { inner: stream }.into()),
Err(HandshakeError::Failure(e)) => Err(e),
Err(HandshakeError::Interrupted(s)) => {
Err(HandshakeError::WouldBlock(s)) => {
match s.handshake() {
Ok(stream) => Ok(TlsStream { inner: stream }.into()),
Err(HandshakeError::Failure(e)) => Err(e),
Err(HandshakeError::Interrupted(s)) => {
self.inner = Some(Err(HandshakeError::Interrupted(s)));
Err(HandshakeError::WouldBlock(s)) => {
self.inner = Some(Err(HandshakeError::WouldBlock(s)));
Ok(Async::NotReady)
}
}
Expand Down
26 changes: 4 additions & 22 deletions tests/bad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,18 @@ cfg_if! {
not(target_os = "ios"))))] {
extern crate openssl;

use openssl::ssl;
use native_tls::backend::openssl::ErrorExt;

fn get(err: &Error) -> &openssl::error::ErrorStack {
let err = err.get_ref().unwrap();
match *err.downcast_ref::<native_tls::Error>().unwrap().openssl_error() {
ssl::Error::Ssl(ref v) => v,
ref e => panic!("not an ssl eror: {:?}", e),
}
}

fn verify_failed(err: &Error) {
assert!(get(err).errors().iter().any(|e| {
e.reason() == Some("certificate verify failed")
}), "bad errors: {:?}", err);
assert!(format!("{}", err).contains("certificate verify failed"))
}

use verify_failed as assert_expired_error;
use verify_failed as assert_wrong_host;
use verify_failed as assert_self_signed;
use verify_failed as assert_untrusted_root;
} else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
use native_tls::backend::security_framework::ErrorExt;

fn assert_invalid_cert_chain(err: &Error) {
let err = err.get_ref().unwrap();
let err = err.downcast_ref::<native_tls::Error>().unwrap();
let err = err.security_framework_error();
assert_eq!(err.message().unwrap(), "The trust policy was not trusted.");
assert!(format!("{}", err).contains("The trust policy was not trusted."))
}

use assert_invalid_cert_chain as assert_expired_error;
Expand All @@ -89,7 +72,6 @@ cfg_if! {
} else {
extern crate winapi;

use native_tls::backend::schannel::ErrorExt;
use winapi::shared::winerror::*;

fn assert_expired_error(err: &Error) {
Expand Down Expand Up @@ -138,8 +120,8 @@ fn get_host(host: &'static str) -> Error {
let mut l = t!(Core::new());
let client = TcpStream::connect(&addr, &l.handle());
let data = client.and_then(move |socket| {
let builder = t!(TlsConnector::builder());
let cx = t!(builder.build());
let builder = TlsConnector::builder();
let cx = builder.build().unwrap();
cx.connect_async(host, socket).map_err(|e| {
Error::new(io::ErrorKind::Other, e)
})
Expand Down
31 changes: 9 additions & 22 deletions tests/google.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern crate tokio_tls;
#[macro_use]
extern crate cfg_if;

use std::io::{self, Error};
use std::io;
use std::net::ToSocketAddrs;

use futures::Future;
Expand All @@ -27,7 +27,7 @@ macro_rules! t {

cfg_if! {
if #[cfg(feature = "force-rustls")] {
fn assert_bad_hostname_error(err: &Error) {
fn assert_bad_hostname_error(err: &io::Error) {
let err = err.to_string();
assert!(err.contains("CertNotValidForName"), "bad error: {}", err);
}
Expand All @@ -37,36 +37,23 @@ cfg_if! {
not(target_os = "ios"))))] {
extern crate openssl;

use openssl::ssl;
use native_tls::backend::openssl::ErrorExt;

fn assert_bad_hostname_error(err: &Error) {
fn assert_bad_hostname_error(err: &io::Error) {
let err = err.get_ref().unwrap();
let err = err.downcast_ref::<native_tls::Error>().unwrap();
let errs = match *err.openssl_error() {
ssl::Error::Ssl(ref v) => v,
ref e => panic!("not an ssl eror: {:?}", e),
};
assert!(errs.errors().iter().any(|e| {
e.reason() == Some("certificate verify failed")
}), "bad errors: {:?}", errs);
assert!(format!("{}", err).contains("certificate verify failed"));
}
} else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
use native_tls::backend::security_framework::ErrorExt;

fn assert_bad_hostname_error(err: &Error) {
fn assert_bad_hostname_error(err: &io::Error) {
let err = err.get_ref().unwrap();
let err = err.downcast_ref::<native_tls::Error>().unwrap();
let err = err.security_framework_error();
assert_eq!(err.message().unwrap(), "The trust policy was not trusted.");
assert!(format!("{}", err).contains("The trust policy was not trusted."));
}
} else {
extern crate winapi;

use native_tls::backend::schannel::ErrorExt;
use winapi::shared::winerror::*;

fn assert_bad_hostname_error(err: &Error) {
fn assert_bad_hostname_error(err: &io::Error) {
let err = err.get_ref().unwrap();
let err = err.downcast_ref::<native_tls::Error>().unwrap();
let err = err.schannel_error();
Expand Down Expand Up @@ -95,7 +82,7 @@ fn fetch_google() {
// Send off the request by first negotiating an SSL handshake, then writing
// of our request, then flushing, then finally read off the response.
let data = client.and_then(move |socket| {
let builder = t!(TlsConnector::builder());
let builder = TlsConnector::builder();
let connector = t!(builder.build());
connector.connect_async("google.com", socket).map_err(native2io)
})
Expand Down Expand Up @@ -124,7 +111,7 @@ fn wrong_hostname_error() {
let mut l = t!(Core::new());
let client = TcpStream::connect(&addr, &l.handle());
let data = client.and_then(move |socket| {
let builder = t!(TlsConnector::builder());
let builder = TlsConnector::builder();
let connector = t!(builder.build());
connector.connect_async("rust-lang.org", socket)
.map_err(native2io)
Expand Down
44 changes: 12 additions & 32 deletions tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use tokio_io::io::{read_to_end, copy, shutdown};
use tokio_core::reactor::Core;
use tokio_core::net::{TcpListener, TcpStream};
use tokio_tls::{TlsConnectorExt, TlsAcceptorExt};
use native_tls::{TlsConnector, TlsAcceptor, Pkcs12};
use native_tls::{TlsConnector, TlsAcceptor, Identity, Certificate};

macro_rules! t {
($e:expr) => (match $e {
Expand Down Expand Up @@ -120,8 +120,6 @@ cfg_if! {
use std::process::Command;
use std::sync::{ONCE_INIT, Once};

use tokio_tls::backend::rustls::ClientContextExt;
use tokio_tls::backend::rustls::ServerContextExt;
use untrusted::Input;
use webpki::trust_anchor_util;

Expand Down Expand Up @@ -220,32 +218,16 @@ cfg_if! {
use std::env;
use std::sync::{Once, ONCE_INIT};

use openssl::x509::X509;

use native_tls::backend::openssl::TlsConnectorBuilderExt;

fn contexts() -> (TlsAcceptor, TlsConnector) {
let keys = openssl_keys();

let pkcs12 = t!(Pkcs12::from_der(&keys.pkcs12_der, "foobar"));
let srv = t!(TlsAcceptor::builder(pkcs12));
let pkcs12 = t!(Identity::from_pkcs12(&keys.pkcs12_der, "foobar"));
let srv = TlsAcceptor::builder(pkcs12);

let cert = t!(X509::from_der(&keys.cert_der));
let cert = t!(Certificate::from_der(&keys.cert_der));

// Unfortunately looks like the only way to configure this is
// `set_CA_file` file on the client side so we have to actually
// emit the certificate to a file. Do so next to our own binary
// which is likely ephemeral as well.
let path = t!(env::current_exe());
let path = path.parent().unwrap().join("custom.crt");
static INIT: Once = ONCE_INIT;
INIT.call_once(|| {
t!(t!(File::create(&path)).write_all(&t!(cert.to_pem())));
});
let mut client = t!(TlsConnector::builder());
t!(client.builder_mut()
.builder_mut()
.set_ca_file(&path));
let mut client = TlsConnector::builder();
t!(client.add_root_certificate(cert).build());

(t!(srv.build()), t!(client.build()))
}
Expand All @@ -258,16 +240,14 @@ cfg_if! {

use security_framework::certificate::SecCertificate;

use native_tls::backend::security_framework::TlsConnectorBuilderExt;

fn contexts() -> (TlsAcceptor, TlsConnector) {
let keys = openssl_keys();

let pkcs12 = t!(Pkcs12::from_der(&keys.pkcs12_der, "foobar"));
let srv = t!(TlsAcceptor::builder(pkcs12));
let pkcs12 = t!(Identity::from_pkcs12(&keys.pkcs12_der, "foobar"));
let srv = TlsAcceptor::builder(pkcs12);

let cert = SecCertificate::from_der(&keys.cert_der).unwrap();
let mut client = t!(TlsConnector::builder());
let cert = SecCertificate::from_pkcs12(&keys.cert_der).unwrap();
let mut client = TlsConnector::builder();
client.anchor_certificates(&[cert]);

(t!(srv.build()), t!(client.build()))
Expand Down Expand Up @@ -301,10 +281,10 @@ cfg_if! {
let mut store = t!(Memory::new()).into_store();
t!(store.add_cert(&cert, CertAdd::Always));
let pkcs12_der = t!(store.export_pkcs12("foobar"));
let pkcs12 = t!(Pkcs12::from_der(&pkcs12_der, "foobar"));
let pkcs12 = t!(Identity::from_pkcs12(&pkcs12_der, "foobar"));

let srv = t!(TlsAcceptor::builder(pkcs12));
let client = t!(TlsConnector::builder());
let client = TlsConnector::builder();
(t!(srv.build()), t!(client.build()))
}

Expand Down

0 comments on commit 39b4d92

Please sign in to comment.