Disable TLS 1.3 compatibility mode for QUIC. Bug: 335 Change-Id: Ic22dafbc4ada3af56260bc7213f0078876e56c3d Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/41244 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index d77a971..9625b8e 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc
@@ -416,17 +416,20 @@ return ssl_hs_error; } - if (ssl->session != nullptr && - !ssl->s3->initial_handshake_complete && - ssl->session->session_id_length > 0) { - hs->session_id_len = ssl->session->session_id_length; - OPENSSL_memcpy(hs->session_id, ssl->session->session_id, - hs->session_id_len); - } else if (hs->max_version >= TLS1_3_VERSION) { - // Initialize a random session ID. - hs->session_id_len = sizeof(hs->session_id); - if (!RAND_bytes(hs->session_id, hs->session_id_len)) { - return ssl_hs_error; + // Never send a session ID in QUIC. QUIC uses TLS 1.3 at a minimum and + // disables TLS 1.3 middlebox compatibility mode. + if (ssl->quic_method == nullptr) { + if (ssl->session != nullptr && !ssl->s3->initial_handshake_complete && + ssl->session->session_id_length > 0) { + hs->session_id_len = ssl->session->session_id_length; + OPENSSL_memcpy(hs->session_id, ssl->session->session_id, + hs->session_id_len); + } else if (hs->max_version >= TLS1_3_VERSION) { + // Initialize a random session ID. + hs->session_id_len = sizeof(hs->session_id); + if (!RAND_bytes(hs->session_id, hs->session_id_len)) { + return ssl_hs_error; + } } }
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index 2aaff76..424f7d2 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc
@@ -5318,6 +5318,26 @@ ExpectHandshakeSuccess(); } +// Test that the client does not send a legacy_session_id in the ClientHello. +TEST_F(QUICMethodTest, NoLegacySessionId) { + const SSL_QUIC_METHOD quic_method = DefaultQUICMethod(); + + ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method)); + ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method)); + // Check that the session ID length is 0 in an early callback. + SSL_CTX_set_select_certificate_cb( + server_ctx_.get(), + [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t { + EXPECT_EQ(client_hello->session_id_len, 0u); + return ssl_select_cert_success; + }); + + ASSERT_TRUE(CreateClientAndServer()); + ASSERT_TRUE(CompleteHandshakesForQUIC()); + + ExpectHandshakeSuccess(); +} + // Test that, even in a 1-RTT handshake, the server installs keys at the right // time. Half-RTT keys are available early, but 1-RTT read keys are deferred. TEST_F(QUICMethodTest, HalfRTTKeys) {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 3d13b9b..931ecca 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go
@@ -299,6 +299,9 @@ } } + if config.Bugs.MockQUICTransport != nil && len(hs.clientHello.sessionId) > 0 { + return fmt.Errorf("tls: QUIC client did not disable compatibility mode") + } if config.Bugs.ExpectNoTLS12Session { if len(hs.clientHello.sessionId) > 0 && c.vers >= VersionTLS13 { return fmt.Errorf("tls: client offered an unexpected session ID")