From 43b430e5b0723784862fb090ef091bc404542989 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Oct 2016 14:26:28 -0700 Subject: [PATCH 1/4] Pass SslMethod into constructors --- openssl/src/ssl/connector.rs | 20 +++----------------- openssl/src/ssl/mod.rs | 11 +++++++---- openssl/src/ssl/tests/mod.rs | 10 ++++++---- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 0ec6526e..794523bb 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -47,11 +47,7 @@ impl ClientConnectorBuilder { /// Creates a new builder for TLS connections. /// /// The default configuration is based off of libcurl's and is subject to change. - pub fn tls() -> Result { - ClientConnectorBuilder::new(SslMethod::tls()) - } - - fn new(method: SslMethod) -> Result { + pub fn new(method: SslMethod) -> Result { let mut ctx = try!(ctx(method)); try!(ctx.set_default_verify_paths()); try!(ctx.set_cipher_list("ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH")); @@ -107,23 +103,13 @@ impl ServerConnectorBuilder { /// /// The default configuration is based off of the intermediate profile of Mozilla's server side /// TLS configuration recommendations, and is subject to change. - pub fn tls(private_key: &PKeyRef, + pub fn new(method: SslMethod, + private_key: &PKeyRef, certificate: &X509Ref, chain: I) -> Result where I: IntoIterator, I::Item: AsRef - { - ServerConnectorBuilder::new(SslMethod::tls(), private_key, certificate, chain) - } - - fn new(method: SslMethod, - private_key: &PKeyRef, - certificate: &X509Ref, - chain: I) - -> Result - where I: IntoIterator, - I::Item: AsRef { let mut ctx = try!(ctx(method)); ctx.set_options(ssl::SSL_OP_SINGLE_DH_USE | ssl::SSL_OP_SINGLE_ECDH_USE | diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index ffcc61ab..f363d452 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -8,11 +8,11 @@ //! To connect as a client to a remote server: //! //! ``` -//! use openssl::ssl::ClientConnectorBuilder; +//! use openssl::ssl::{SslMethod, ClientConnectorBuilder}; //! use std::io::{Read, Write}; //! use std::net::TcpStream; //! -//! let connector = ClientConnectorBuilder::tls().unwrap().build(); +//! let connector = ClientConnectorBuilder::new(SslMethod::tls()).unwrap().build(); //! //! let stream = TcpStream::connect("google.com:443").unwrap(); //! let mut stream = connector.connect("google.com", stream).unwrap(); @@ -27,7 +27,7 @@ //! //! ```no_run //! use openssl::pkcs12::Pkcs12; -//! use openssl::ssl::{ServerConnectorBuilder, SslStream}; +//! use openssl::ssl::{SslMethod, ServerConnectorBuilder, SslStream}; //! use std::fs::File; //! use std::io::{Read, Write}; //! use std::net::{TcpListener, TcpStream}; @@ -43,7 +43,10 @@ //! let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap(); //! let identity = pkcs12.parse("password123").unwrap(); //! -//! let connector = ServerConnectorBuilder::tls(&identity.pkey, &identity.cert, &identity.chain) +//! let connector = ServerConnectorBuilder::new(SslMethod::tls(), +//! &identity.pkey, +//! &identity.cert, +//! &identity.chain) //! .unwrap() //! .build(); //! let connector = Arc::new(connector); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 5a8067c9..5e5d8988 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -1082,7 +1082,7 @@ fn verify_invalid_hostname() { #[test] fn connector_valid_hostname() { - let connector = ClientConnectorBuilder::tls().unwrap().build(); + let connector = ClientConnectorBuilder::new(SslMethod::tls()).unwrap().build(); let s = TcpStream::connect("google.com:443").unwrap(); let mut socket = connector.connect("google.com", s).unwrap(); @@ -1098,7 +1098,7 @@ fn connector_valid_hostname() { #[test] fn connector_invalid_hostname() { - let connector = ClientConnectorBuilder::tls().unwrap().build(); + let connector = ClientConnectorBuilder::new(SslMethod::tls()).unwrap().build(); let s = TcpStream::connect("google.com:443").unwrap(); assert!(connector.connect("foobar.com", s).is_err()); @@ -1112,14 +1112,16 @@ fn connector_client_server() { let t = thread::spawn(move || { let key = PKey::private_key_from_pem(KEY).unwrap(); let cert = X509::from_pem(CERT).unwrap(); - let connector = ServerConnectorBuilder::tls(&key, &cert, None::).unwrap().build(); + let connector = ServerConnectorBuilder::new(SslMethod::tls(), &key, &cert, None::) + .unwrap() + .build(); let stream = listener.accept().unwrap().0; let mut stream = connector.connect(stream).unwrap(); stream.write_all(b"hello").unwrap(); }); - let mut connector = ClientConnectorBuilder::tls().unwrap(); + let mut connector = ClientConnectorBuilder::new(SslMethod::tls()).unwrap(); connector.context_mut().set_CA_file("test/root-ca.pem").unwrap(); let connector = connector.build(); From 7d13176cd1719dd0047c3fafad8e0fd6bbaa1711 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Oct 2016 14:34:05 -0700 Subject: [PATCH 2/4] Rename nwe to mozilla_intermediate --- openssl/src/ssl/connector.rs | 10 +++++----- openssl/src/ssl/mod.rs | 6 ++---- openssl/src/ssl/tests/mod.rs | 3 ++- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 794523bb..0bac87cf 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -103,11 +103,11 @@ impl ServerConnectorBuilder { /// /// The default configuration is based off of the intermediate profile of Mozilla's server side /// TLS configuration recommendations, and is subject to change. - pub fn new(method: SslMethod, - private_key: &PKeyRef, - certificate: &X509Ref, - chain: I) - -> Result + pub fn mozilla_intermediate(method: SslMethod, + private_key: &PKeyRef, + certificate: &X509Ref, + chain: I) + -> Result where I: IntoIterator, I::Item: AsRef { diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index f363d452..802ce8f0 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -43,10 +43,8 @@ //! let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap(); //! let identity = pkcs12.parse("password123").unwrap(); //! -//! let connector = ServerConnectorBuilder::new(SslMethod::tls(), -//! &identity.pkey, -//! &identity.cert, -//! &identity.chain) +//! let connector = ServerConnectorBuilder::mozilla_intermediate( +//! SslMethod::tls(), &identity.pkey, &identity.cert, &identity.chain) //! .unwrap() //! .build(); //! let connector = Arc::new(connector); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 5e5d8988..0c0c7957 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -1112,7 +1112,8 @@ fn connector_client_server() { let t = thread::spawn(move || { let key = PKey::private_key_from_pem(KEY).unwrap(); let cert = X509::from_pem(CERT).unwrap(); - let connector = ServerConnectorBuilder::new(SslMethod::tls(), &key, &cert, None::) + let connector = ServerConnectorBuilder::mozilla_intermediate( + SslMethod::tls(), &key, &cert, None::) .unwrap() .build(); let stream = listener.accept().unwrap().0; From 52f288e090ef5d420ea0692c435c42c30570a957 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Oct 2016 14:57:22 -0700 Subject: [PATCH 3/4] Add a mozilla modern profile --- openssl/src/ssl/connector.rs | 35 +++++++++++++++++++++++++++++++++-- openssl/src/ssl/tests/mod.rs | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 0bac87cf..701fdeaf 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -101,8 +101,8 @@ pub struct ServerConnectorBuilder(SslContextBuilder); impl ServerConnectorBuilder { /// Creates a new builder for server-side TLS connections. /// - /// The default configuration is based off of the intermediate profile of Mozilla's server side - /// TLS configuration recommendations, and is subject to change. + /// The configuration is based off of the intermediate profile of Mozilla's server side + /// TLS configuration recommendations. pub fn mozilla_intermediate(method: SslMethod, private_key: &PKeyRef, certificate: &X509Ref, @@ -128,6 +128,37 @@ impl ServerConnectorBuilder { DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\ EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:\ AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS")); + ServerConnectorBuilder::finish_setup(ctx, private_key, certificate, chain) + } + + pub fn mozilla_modern(method: SslMethod, + private_key: &PKeyRef, + certificate: &X509Ref, + chain: I) + -> Result + where I: IntoIterator, + I::Item: AsRef + { + let mut ctx = try!(ctx(method)); + ctx.set_options(ssl::SSL_OP_SINGLE_ECDH_USE | ssl::SSL_OP_CIPHER_SERVER_PREFERENCE); + try!(setup_curves(&mut ctx)); + try!(ctx.set_cipher_list( + "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\ + ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\ + ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ + ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:\ + ECDHE-RSA-AES128-SHA256")); + ServerConnectorBuilder::finish_setup(ctx, private_key, certificate, chain) + } + + fn finish_setup(mut ctx: SslContextBuilder, + private_key: &PKeyRef, + certificate: &X509Ref, + chain: I) + -> Result + where I: IntoIterator, + I::Item: AsRef + { try!(ctx.set_private_key(private_key)); try!(ctx.set_certificate(certificate)); try!(ctx.check_private_key()); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 0c0c7957..eeada33a 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -1105,7 +1105,7 @@ fn connector_invalid_hostname() { } #[test] -fn connector_client_server() { +fn connector_client_server_mozilla_intermediate() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); @@ -1136,6 +1136,38 @@ fn connector_client_server() { t.join().unwrap(); } +#[test] +fn connector_client_server_mozilla_modern() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let port = listener.local_addr().unwrap().port(); + + let t = thread::spawn(move || { + let key = PKey::private_key_from_pem(KEY).unwrap(); + let cert = X509::from_pem(CERT).unwrap(); + let connector = ServerConnectorBuilder::mozilla_modern( + SslMethod::tls(), &key, &cert, None::) + .unwrap() + .build(); + let stream = listener.accept().unwrap().0; + let mut stream = connector.connect(stream).unwrap(); + + stream.write_all(b"hello").unwrap(); + }); + + let mut connector = ClientConnectorBuilder::new(SslMethod::tls()).unwrap(); + connector.context_mut().set_CA_file("test/root-ca.pem").unwrap(); + let connector = connector.build(); + + let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); + let mut stream = connector.connect("foobar.com", stream).unwrap(); + + let mut buf = [0; 5]; + stream.read_exact(&mut buf).unwrap(); + assert_eq!(b"hello", &buf); + + t.join().unwrap(); +} + #[test] fn shutdown() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); From d1179f1ad28f16c90eba8d89a03b2821aabd9469 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Oct 2016 15:14:29 -0700 Subject: [PATCH 4/4] Update docs --- openssl/src/ssl/connector.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 701fdeaf..c283145e 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -99,10 +99,13 @@ impl ClientConnector { pub struct ServerConnectorBuilder(SslContextBuilder); impl ServerConnectorBuilder { - /// Creates a new builder for server-side TLS connections. + /// Creates a new builder configured to connect to non-legacy clients. This should generally be + /// considered a reasonable default choice. /// - /// The configuration is based off of the intermediate profile of Mozilla's server side - /// TLS configuration recommendations. + /// This corresponds to the intermediate configuration of Mozilla's server side TLS + /// recommendations. See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_intermediate(method: SslMethod, private_key: &PKeyRef, certificate: &X509Ref, @@ -131,6 +134,12 @@ impl ServerConnectorBuilder { ServerConnectorBuilder::finish_setup(ctx, private_key, certificate, chain) } + /// Creates a new builder configured to connect to modern clients. + /// + /// This corresponds to the modern configuration of Mozilla's server side TLS recommendations. + /// See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_modern(method: SslMethod, private_key: &PKeyRef, certificate: &X509Ref,