Merge pull request #504 from sfackler/connector-tweaks
Connector tweaks
This commit is contained in:
commit
fb6052d288
|
|
@ -47,11 +47,7 @@ impl ClientConnectorBuilder {
|
||||||
/// Creates a new builder for TLS connections.
|
/// Creates a new builder for TLS connections.
|
||||||
///
|
///
|
||||||
/// The default configuration is based off of libcurl's and is subject to change.
|
/// The default configuration is based off of libcurl's and is subject to change.
|
||||||
pub fn tls() -> Result<ClientConnectorBuilder, ErrorStack> {
|
pub fn new(method: SslMethod) -> Result<ClientConnectorBuilder, ErrorStack> {
|
||||||
ClientConnectorBuilder::new(SslMethod::tls())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new(method: SslMethod) -> Result<ClientConnectorBuilder, ErrorStack> {
|
|
||||||
let mut ctx = try!(ctx(method));
|
let mut ctx = try!(ctx(method));
|
||||||
try!(ctx.set_default_verify_paths());
|
try!(ctx.set_default_verify_paths());
|
||||||
try!(ctx.set_cipher_list("ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"));
|
try!(ctx.set_cipher_list("ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"));
|
||||||
|
|
@ -103,21 +99,14 @@ impl ClientConnector {
|
||||||
pub struct ServerConnectorBuilder(SslContextBuilder);
|
pub struct ServerConnectorBuilder(SslContextBuilder);
|
||||||
|
|
||||||
impl ServerConnectorBuilder {
|
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 default configuration is based off of the intermediate profile of Mozilla's server side
|
/// This corresponds to the intermediate configuration of Mozilla's server side TLS
|
||||||
/// TLS configuration recommendations, and is subject to change.
|
/// recommendations. See its [documentation][docs] for more details on specifics.
|
||||||
pub fn tls<I>(private_key: &PKeyRef,
|
///
|
||||||
certificate: &X509Ref,
|
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||||
chain: I)
|
pub fn mozilla_intermediate<I>(method: SslMethod,
|
||||||
-> Result<ServerConnectorBuilder, ErrorStack>
|
|
||||||
where I: IntoIterator,
|
|
||||||
I::Item: AsRef<X509Ref>
|
|
||||||
{
|
|
||||||
ServerConnectorBuilder::new(SslMethod::tls(), private_key, certificate, chain)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new<I>(method: SslMethod,
|
|
||||||
private_key: &PKeyRef,
|
private_key: &PKeyRef,
|
||||||
certificate: &X509Ref,
|
certificate: &X509Ref,
|
||||||
chain: I)
|
chain: I)
|
||||||
|
|
@ -142,6 +131,43 @@ impl ServerConnectorBuilder {
|
||||||
DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
|
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:\
|
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:\
|
||||||
AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"));
|
AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"));
|
||||||
|
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<I>(method: SslMethod,
|
||||||
|
private_key: &PKeyRef,
|
||||||
|
certificate: &X509Ref,
|
||||||
|
chain: I)
|
||||||
|
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||||
|
where I: IntoIterator,
|
||||||
|
I::Item: AsRef<X509Ref>
|
||||||
|
{
|
||||||
|
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<I>(mut ctx: SslContextBuilder,
|
||||||
|
private_key: &PKeyRef,
|
||||||
|
certificate: &X509Ref,
|
||||||
|
chain: I)
|
||||||
|
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||||
|
where I: IntoIterator,
|
||||||
|
I::Item: AsRef<X509Ref>
|
||||||
|
{
|
||||||
try!(ctx.set_private_key(private_key));
|
try!(ctx.set_private_key(private_key));
|
||||||
try!(ctx.set_certificate(certificate));
|
try!(ctx.set_certificate(certificate));
|
||||||
try!(ctx.check_private_key());
|
try!(ctx.check_private_key());
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
//! To connect as a client to a remote server:
|
//! 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::io::{Read, Write};
|
||||||
//! use std::net::TcpStream;
|
//! 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 stream = TcpStream::connect("google.com:443").unwrap();
|
||||||
//! let mut stream = connector.connect("google.com", stream).unwrap();
|
//! let mut stream = connector.connect("google.com", stream).unwrap();
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use openssl::pkcs12::Pkcs12;
|
//! use openssl::pkcs12::Pkcs12;
|
||||||
//! use openssl::ssl::{ServerConnectorBuilder, SslStream};
|
//! use openssl::ssl::{SslMethod, ServerConnectorBuilder, SslStream};
|
||||||
//! use std::fs::File;
|
//! use std::fs::File;
|
||||||
//! use std::io::{Read, Write};
|
//! use std::io::{Read, Write};
|
||||||
//! use std::net::{TcpListener, TcpStream};
|
//! use std::net::{TcpListener, TcpStream};
|
||||||
|
|
@ -43,7 +43,8 @@
|
||||||
//! let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap();
|
//! let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap();
|
||||||
//! let identity = pkcs12.parse("password123").unwrap();
|
//! let identity = pkcs12.parse("password123").unwrap();
|
||||||
//!
|
//!
|
||||||
//! let connector = ServerConnectorBuilder::tls(&identity.pkey, &identity.cert, &identity.chain)
|
//! let connector = ServerConnectorBuilder::mozilla_intermediate(
|
||||||
|
//! SslMethod::tls(), &identity.pkey, &identity.cert, &identity.chain)
|
||||||
//! .unwrap()
|
//! .unwrap()
|
||||||
//! .build();
|
//! .build();
|
||||||
//! let connector = Arc::new(connector);
|
//! let connector = Arc::new(connector);
|
||||||
|
|
|
||||||
|
|
@ -1082,7 +1082,7 @@ fn verify_invalid_hostname() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connector_valid_hostname() {
|
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 s = TcpStream::connect("google.com:443").unwrap();
|
||||||
let mut socket = connector.connect("google.com", s).unwrap();
|
let mut socket = connector.connect("google.com", s).unwrap();
|
||||||
|
|
@ -1098,28 +1098,63 @@ fn connector_valid_hostname() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connector_invalid_hostname() {
|
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();
|
let s = TcpStream::connect("google.com:443").unwrap();
|
||||||
assert!(connector.connect("foobar.com", s).is_err());
|
assert!(connector.connect("foobar.com", s).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connector_client_server() {
|
fn connector_client_server_mozilla_intermediate() {
|
||||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||||
let port = listener.local_addr().unwrap().port();
|
let port = listener.local_addr().unwrap().port();
|
||||||
|
|
||||||
let t = thread::spawn(move || {
|
let t = thread::spawn(move || {
|
||||||
let key = PKey::private_key_from_pem(KEY).unwrap();
|
let key = PKey::private_key_from_pem(KEY).unwrap();
|
||||||
let cert = X509::from_pem(CERT).unwrap();
|
let cert = X509::from_pem(CERT).unwrap();
|
||||||
let connector = ServerConnectorBuilder::tls(&key, &cert, None::<X509>).unwrap().build();
|
let connector = ServerConnectorBuilder::mozilla_intermediate(
|
||||||
|
SslMethod::tls(), &key, &cert, None::<X509>)
|
||||||
|
.unwrap()
|
||||||
|
.build();
|
||||||
let stream = listener.accept().unwrap().0;
|
let stream = listener.accept().unwrap().0;
|
||||||
let mut stream = connector.connect(stream).unwrap();
|
let mut stream = connector.connect(stream).unwrap();
|
||||||
|
|
||||||
stream.write_all(b"hello").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();
|
||||||
|
|
||||||
|
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 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::<X509>)
|
||||||
|
.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();
|
connector.context_mut().set_CA_file("test/root-ca.pem").unwrap();
|
||||||
let connector = connector.build();
|
let connector = connector.build();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue