From 87ab639360d72ef4b45da1f3898f6d60d4316d3f Mon Sep 17 00:00:00 2001 From: Joseph Birr-Pixton Date: Mon, 14 May 2018 20:29:47 +0100 Subject: [PATCH] Enable quic tests in bogo - bogo_shim needs quic feature - provide/check quic transport params in bogo_shim - reject servers that handshake at TLS1.2, but include a quic transport params extension. - don't expose quic transport params extension for TLS1.2 clients. These last two match BoringSSL. --- Cargo.toml | 2 +- bogo/config.json | 3 ++- bogo/runme | 2 +- examples/internal/bogo_shim.rs | 46 ++++++++++++++++++++++++++++------ src/client/hs.rs | 7 ++++++ src/server/hs.rs | 2 +- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aa9599e0..23bb587f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ regex = "0.2" [[example]] name = "bogo_shim" path = "examples/internal/bogo_shim.rs" -required-features = ["dangerous_configuration"] +required-features = ["dangerous_configuration", "quic"] [[example]] name = "trytls_shim" diff --git a/bogo/config.json b/bogo/config.json index 7976e1d7..3a402a22 100644 --- a/bogo/config.json +++ b/bogo/config.json @@ -15,7 +15,6 @@ "TLS13-WrongOuterRecord": "we're lax on this", "*DTLS*": "not supported", "TokenBinding-*": "not supported", - "QUICTransportParams-*": "not supported", "DummyPQPadding-*": "not supported", "MTU*": "dtls only", "DisableEverything": "not useful", @@ -272,6 +271,8 @@ "CurveTest-Server-Compressed-P-384-TLS12": ":PEER_MISBEHAVIOUR:", "CurveTest-Client-Compressed-P-384-TLS13Draft23": ":PEER_MISBEHAVIOUR:", "CurveTest-Server-Compressed-P-384-TLS13Draft23": ":PEER_MISBEHAVIOUR:", + "QUICTransportParams-Client-Rejected-TLS12": ":PEER_MISBEHAVIOUR:", + "QUICTransportParams-Server-Rejected-TLS12": "missing peer quic transport params", "ExtendedMasterSecret-NoToYes-Client": ":PEER_MISBEHAVIOUR:", "ExtendedMasterSecret-YesToNo-Server": ":PEER_MISBEHAVIOUR:", "ExtendedMasterSecret-YesToNo-Client": ":PEER_MISBEHAVIOUR:" diff --git a/bogo/runme b/bogo/runme index eba2e4c9..013e1592 100755 --- a/bogo/runme +++ b/bogo/runme @@ -6,7 +6,7 @@ set -xe if [ ! -e ../target/debug/examples/bogo_shim ] ; then - cargo test --no-run --features dangerous_configuration + cargo test --no-run --features dangerous_configuration,quic fi if [ ! -e bogo/ ] ; then diff --git a/examples/internal/bogo_shim.rs b/examples/internal/bogo_shim.rs index ad002664..eccbdfad 100644 --- a/examples/internal/bogo_shim.rs +++ b/examples/internal/bogo_shim.rs @@ -19,6 +19,8 @@ use std::io::BufReader; use std::io::{Write, Read}; use std::sync::Arc; use rustls::internal::msgs::enums::ProtocolVersion; +use rustls::quic::ClientQuicExt; +use rustls::quic::ServerQuicExt; static BOGO_NACK: i32 = 89; @@ -59,6 +61,8 @@ struct Options { export_keying_material_context: String, export_keying_material_context_used: bool, read_size: usize, + quic_transport_params: Vec, + expect_quic_transport_params: Vec, } impl Options { @@ -93,6 +97,8 @@ impl Options { export_keying_material_context: "".to_string(), export_keying_material_context_used: false, read_size: 512, + quic_transport_params: vec![], + expect_quic_transport_params: vec![], } } @@ -407,6 +413,14 @@ fn exec(opts: &Options, sess: &mut Box) { sent_exporter = true; } + if !sess.is_handshaking() && + !opts.expect_quic_transport_params.is_empty() { + let their_transport_params = sess.get_quic_transport_parameters() + .expect("missing peer quic transport params"); + assert_eq!(opts.expect_quic_transport_params, + their_transport_params); + } + let mut buf = [0u8; 1024]; let len = match sess.read(&mut buf[..opts.read_size]) { Ok(len) => len, @@ -524,6 +538,14 @@ fn main() { "-use-export-context" => { opts.export_keying_material_context_used = true; } + "-quic-transport-params" => { + opts.quic_transport_params = base64::decode(args.remove(0).as_bytes()) + .expect("invalid base64"); + } + "-expected-quic-transport-params" => { + opts.expect_quic_transport_params = base64::decode(args.remove(0).as_bytes()) + .expect("invalid base64"); + } "-ocsp-response" => { opts.server_ocsp_response = base64::decode(args.remove(0).as_bytes()) @@ -664,16 +686,26 @@ fn main() { let make_session = || { if opts.server { - let s: Box = - Box::new(rustls::ServerSession::new(server_cfg.as_ref().unwrap())); - s + let s = if opts.quic_transport_params.is_empty() { + rustls::ServerSession::new(server_cfg.as_ref().unwrap()) + } else { + rustls::ServerSession::new_quic(server_cfg.as_ref().unwrap(), + opts.quic_transport_params.clone()) + + }; + Box::new(s) as Box } else { let dns_name = webpki::DNSNameRef::try_from_ascii_str(&opts.host_name).unwrap(); - let s: Box = - Box::new(rustls::ClientSession::new(client_cfg.as_ref().unwrap(), - dns_name)); - s + let s = if opts.quic_transport_params.is_empty() { + rustls::ClientSession::new(client_cfg.as_ref().unwrap(), + dns_name) + } else { + rustls::ClientSession::new_quic(client_cfg.as_ref().unwrap(), + dns_name, + opts.quic_transport_params.clone()) + }; + Box::new(s) as Box } }; diff --git a/src/client/hs.rs b/src/client/hs.rs index d4c8c636..26216ea6 100644 --- a/src/client/hs.rs +++ b/src/client/hs.rs @@ -644,6 +644,13 @@ impl State for ExpectServerHello { process_alpn_protocol(sess, server_hello.get_alpn_protocol())?; } + // Reject QUIC if TLS1.2 is in use. + if !sess.common.is_tls13() && + server_hello.find_extension(ExtensionType::TransportParameters).is_some() { + sess.common.send_fatal_alert(AlertDescription::UnsupportedExtension); + return Err(TLSError::PeerMisbehavedError("server wants to do quic+tls1.2".to_string())); + } + // If ECPointFormats extension is supplied by the server, it must contain // Uncompressed. But it's allowed to be omitted. if let Some(point_fmts) = server_hello.get_ecpoints_extension() { diff --git a/src/server/hs.rs b/src/server/hs.rs index c8919d85..a2d4d01f 100644 --- a/src/server/hs.rs +++ b/src/server/hs.rs @@ -225,7 +225,7 @@ impl ExpectClientHello { } // QUIC transport parameters - if let Some(params) = hello.get_quic_params_extension() { + if let (Some(params), true) = (hello.get_quic_params_extension(), sess.common.is_tls13()) { sess.quic_params = Some(params); }