diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 5def68b2..4096cc29 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -9,6 +9,17 @@ use ssl::{ }; use version; +const FFDHE_2048: &str = " +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- +"; + fn ctx(method: SslMethod) -> Result { let mut ctx = SslContextBuilder::new(method)?; @@ -17,8 +28,7 @@ fn ctx(method: SslMethod) -> Result { | SslOptions::NO_SSLV2 | SslOptions::NO_SSLV3 | SslOptions::SINGLE_DH_USE - | SslOptions::SINGLE_ECDH_USE - | SslOptions::CIPHER_SERVER_PREFERENCE; + | SslOptions::SINGLE_ECDH_USE; opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; ctx.set_options(opts); @@ -191,26 +201,60 @@ impl SslAcceptor { /// Creates a new builder configured to connect to non-legacy clients. This should generally be /// considered a reasonable default choice. /// - /// This corresponds to the intermediate configuration of Mozilla's server side TLS + /// This corresponds to the intermediate configuration of version 5 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_v5(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1); + let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?; + ctx.set_tmp_dh(&dh)?; + setup_curves(&mut ctx)?; + ctx.set_cipher_list( + "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:\ + ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\ + DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" + )?; + #[cfg(ossl111)] + ctx.set_ciphersuites( + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Creates a new builder configured to connect to modern clients. + /// + /// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations. + /// See its [documentation][docs] for more details on specifics. + /// + /// Requires OpenSSL 1.1.1 or newer. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + #[cfg(ossl111)] + pub fn mozilla_modern_v5(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_options(SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_3); + ctx.set_ciphersuites( + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Creates a new builder configured to connect to non-legacy clients. This should generally be + /// considered a reasonable default choice. + /// + /// This corresponds to the intermediate configuration of version 4 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 + // FIXME remove in next major version pub fn mozilla_intermediate(method: SslMethod) -> Result { let mut ctx = ctx(method)?; + ctx.set_options(SslOptions::CIPHER_SERVER_PREFERENCE); #[cfg(ossl111)] ctx.set_options(SslOptions::NO_TLSV1_3); - let dh = Dh::params_from_pem( - b" ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz -+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a -87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 -YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi -7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD -ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== ------END DH PARAMETERS----- -", - )?; + let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?; ctx.set_tmp_dh(&dh)?; setup_curves(&mut ctx)?; ctx.set_cipher_list( @@ -228,13 +272,16 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== /// Creates a new builder configured to connect to modern clients. /// - /// This corresponds to the modern configuration of Mozilla's server side TLS recommendations. + /// This corresponds to the modern configuration of version 4 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 + // FIXME remove in next major version pub fn mozilla_modern(method: SslMethod) -> Result { let mut ctx = ctx(method)?; - ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1); + ctx.set_options( + SslOptions::CIPHER_SERVER_PREFERENCE | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1, + ); #[cfg(ossl111)] ctx.set_options(SslOptions::NO_TLSV1_3); setup_curves(&mut ctx)?; diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index c1f730ec..18cbb395 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -17,6 +17,7 @@ use std::time::Duration; use tempdir::TempDir; use dh::Dh; +use error::ErrorStack; use hash::MessageDigest; use ocsp::{OcspResponse, OcspResponseStatus}; use pkey::PKey; @@ -29,8 +30,8 @@ use ssl::SslVersion; use ssl::{ClientHelloResponse, ExtensionContext}; use ssl::{ Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor, - SslConnector, SslContext, SslFiletype, SslMethod, SslOptions, SslSessionCacheMode, SslStream, - SslVerifyMode, StatusType, SslContextBuilder + SslAcceptorBuilder, SslConnector, SslContext, SslContextBuilder, SslFiletype, SslMethod, + SslOptions, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType, }; #[cfg(ossl102)] use x509::store::X509StoreBuilder; @@ -737,15 +738,14 @@ fn connector_no_hostname_can_disable_verify() { s.read_exact(&mut [0]).unwrap(); } -#[test] -fn connector_client_server_mozilla_intermediate() { - let listener = TcpListener::bind("127.0.0.1:1234").unwrap(); +fn test_mozilla_server(new: fn(SslMethod) -> Result) { + 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 mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + let mut acceptor = new(SslMethod::tls()).unwrap(); acceptor.set_private_key(&key).unwrap(); acceptor.set_certificate(&cert).unwrap(); let acceptor = acceptor.build(); @@ -769,36 +769,25 @@ fn connector_client_server_mozilla_intermediate() { t.join().unwrap(); } +#[test] +fn connector_client_server_mozilla_intermediate() { + test_mozilla_server(SslAcceptor::mozilla_intermediate); +} + #[test] fn connector_client_server_mozilla_modern() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); + test_mozilla_server(SslAcceptor::mozilla_modern); +} - let t = thread::spawn(move || { - let key = PKey::private_key_from_pem(KEY).unwrap(); - let cert = X509::from_pem(CERT).unwrap(); - let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - acceptor.set_private_key(&key).unwrap(); - acceptor.set_certificate(&cert).unwrap(); - let acceptor = acceptor.build(); - let stream = listener.accept().unwrap().0; - let mut stream = acceptor.accept(stream).unwrap(); +#[test] +fn connector_client_server_mozilla_intermediate_v5() { + test_mozilla_server(SslAcceptor::mozilla_intermediate_v5); +} - stream.write_all(b"hello").unwrap(); - }); - - let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); - connector.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] +#[cfg(ossl111)] +fn connector_client_server_mozilla_modern_v5() { + test_mozilla_server(SslAcceptor::mozilla_modern_v5); } #[test] @@ -1041,7 +1030,7 @@ fn new_session_callback_swapped_ctx() { client .ctx() .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); - + let mut client = client.build().builder(); let ctx = SslContextBuilder::new(SslMethod::tls()).unwrap().build();