From 01160abd92956e5f995cc45790df7a2b86c8989f Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Sun, 8 May 2016 10:04:37 -0700 Subject: [PATCH] feat(ssl): enable hostname verification by default for OpenSSL Additionally disables SSLv2 and SSLv3, as those are universally considered unsafe. Closes #472 --- Cargo.toml | 6 +++++- src/lib.rs | 2 ++ src/net.rs | 15 ++++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4563026f00..9c1e4bb0d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,10 @@ default-features = false version = "0.7" optional = true +[dependencies.openssl-verify] +version = "0.1" +optional = true + [dependencies.security-framework] version = "0.1.4" optional = true @@ -49,6 +53,6 @@ env_logger = "0.3" [features] default = ["ssl"] -ssl = ["openssl", "cookie/secure"] +ssl = ["openssl", "openssl-verify", "cookie/secure"] serde-serialization = ["serde", "mime/serde"] nightly = [] diff --git a/src/lib.rs b/src/lib.rs index 8343caff8c..72e96e22e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,6 +133,8 @@ extern crate time; #[macro_use] extern crate url; #[cfg(feature = "openssl")] extern crate openssl; +#[cfg(feature = "openssl-verify")] +extern crate openssl_verify; #[cfg(feature = "security-framework")] extern crate security_framework; #[cfg(feature = "serde-serialization")] diff --git a/src/net.rs b/src/net.rs index 315af89fbb..193350d6cb 100644 --- a/src/net.rs +++ b/src/net.rs @@ -619,7 +619,7 @@ mod openssl { use std::sync::Arc; use std::time::Duration; - use openssl::ssl::{Ssl, SslContext, SslStream, SslMethod, SSL_VERIFY_NONE}; + use openssl::ssl::{Ssl, SslContext, SslStream, SslMethod, SSL_VERIFY_NONE, SSL_VERIFY_PEER, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3}; use openssl::ssl::error::StreamError as SslIoError; use openssl::ssl::error::SslError; use openssl::x509::X509FileType; @@ -651,11 +651,10 @@ mod openssl { impl Default for OpensslClient { fn default() -> OpensslClient { - OpensslClient(SslContext::new(SslMethod::Sslv23).unwrap_or_else(|e| { - // if we cannot create a SslContext, that's because of a - // serious problem. just crash. - panic!("{}", e) - })) + let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + ctx.set_default_verify_paths().unwrap(); + ctx.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3); + OpensslClient(ctx) } } @@ -664,8 +663,10 @@ mod openssl { type Stream = SslStream; fn wrap_client(&self, stream: T, host: &str) -> ::Result { - let ssl = try!(Ssl::new(&self.0)); + let mut ssl = try!(Ssl::new(&self.0)); try!(ssl.set_hostname(host)); + let host = host.to_owned(); + ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| ::openssl_verify::verify_callback(&host, p, x)); SslStream::connect(ssl, stream).map_err(From::from) } }