diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /security/nss/gtests/ssl_gtest/ssl_version_unittest.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_version_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_version_unittest.cc | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc new file mode 100644 index 0000000000..079d865a8f --- /dev/null +++ b/security/nss/gtests/ssl_gtest/ssl_version_unittest.cc @@ -0,0 +1,456 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "secerr.h" +#include "ssl.h" +#include "ssl3prot.h" +#include "sslerr.h" +#include "sslproto.h" + +#include "gtest_utils.h" +#include "nss_scoped_ptrs.h" +#include "tls_connect.h" +#include "tls_filter.h" +#include "tls_parser.h" + +namespace nss_test { + +TEST_P(TlsConnectStream, ServerNegotiateTls10) { + uint16_t minver, maxver; + client_->GetVersionRange(&minver, &maxver); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, maxver); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_0); + Connect(); +} + +TEST_P(TlsConnectGeneric, ServerNegotiateTls11) { + if (version_ < SSL_LIBRARY_VERSION_TLS_1_1) GTEST_SKIP(); + + uint16_t minver, maxver; + client_->GetVersionRange(&minver, &maxver); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, maxver); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_1); + Connect(); +} + +TEST_P(TlsConnectGeneric, ServerNegotiateTls12) { + if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) GTEST_SKIP(); + + uint16_t minver, maxver; + client_->GetVersionRange(&minver, &maxver); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, maxver); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + Connect(); +} + +// Test the ServerRandom version hack from +// [draft-ietf-tls-tls13-11 Section 6.3.1.1]. +// The first three tests test for active tampering. The next +// two validate that we can also detect fallback using the +// SSL_SetDowngradeCheckVersion() API. +TEST_F(TlsConnectTest, TestDowngradeDetectionToTls11) { + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2); + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE); + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + SSL_LIBRARY_VERSION_TLS_1_1); + ConnectExpectAlert(client_, kTlsAlertIllegalParameter); + client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +// Attempt to negotiate the bogus DTLS 1.1 version. +TEST_F(DtlsConnectTest, TestDtlsVersion11) { + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + ((~0x0101) & 0xffff)); + ConnectExpectAlert(server_, kTlsAlertProtocolVersion); + client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION); +} + +TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) { + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + ConnectExpectAlert(client_, kTlsAlertIllegalParameter); + client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +// Disabling downgrade checks will be caught when the Finished MAC check fails. +TEST_F(TlsConnectTest, TestDisableDowngradeDetection) { + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_FALSE); + MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + ConnectExpectAlert(server_, kTlsAlertDecryptError); + client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); + server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); +} + +typedef std::tuple<SSLProtocolVariant, + uint16_t, // client version + uint16_t> // server version + TlsDowngradeProfile; + +class TlsDowngradeTest + : public TlsConnectTestBase, + public ::testing::WithParamInterface<TlsDowngradeProfile> { + public: + TlsDowngradeTest() + : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())), + c_ver(std::get<1>(GetParam())), + s_ver(std::get<2>(GetParam())) {} + + protected: + const uint16_t c_ver; + const uint16_t s_ver; +}; + +TEST_P(TlsDowngradeTest, TlsDowngradeSentinelTest) { + static const uint8_t tls12_downgrade_random[] = {0x44, 0x4F, 0x57, 0x4E, + 0x47, 0x52, 0x44, 0x01}; + static const uint8_t tls1_downgrade_random[] = {0x44, 0x4F, 0x57, 0x4E, + 0x47, 0x52, 0x44, 0x00}; + static const size_t kRandomLen = 32; + + if (c_ver > s_ver) { + GTEST_SKIP(); + } + + client_->SetVersionRange(c_ver, c_ver); + server_->SetVersionRange(c_ver, s_ver); + + auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello); + Connect(); + ASSERT_TRUE(sh->buffer().len() > (kRandomLen + 2)); + + const uint8_t* downgrade_sentinel = + sh->buffer().data() + 2 + kRandomLen - sizeof(tls1_downgrade_random); + if (c_ver < s_ver) { + if (c_ver == SSL_LIBRARY_VERSION_TLS_1_2) { + EXPECT_EQ(0, memcmp(downgrade_sentinel, tls12_downgrade_random, + sizeof(tls12_downgrade_random))); + } else { + EXPECT_EQ(0, memcmp(downgrade_sentinel, tls1_downgrade_random, + sizeof(tls1_downgrade_random))); + } + } else { + EXPECT_NE(0, memcmp(downgrade_sentinel, tls12_downgrade_random, + sizeof(tls12_downgrade_random))); + EXPECT_NE(0, memcmp(downgrade_sentinel, tls1_downgrade_random, + sizeof(tls1_downgrade_random))); + } +} + +// TLS 1.1 clients do not check the random values, so we should +// instead get a handshake failure alert from the server. +TEST_F(TlsConnectTest, TestDowngradeDetectionToTls10) { + // Setting the option here has no effect. + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE); + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + SSL_LIBRARY_VERSION_TLS_1_0); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_1); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2); + ConnectExpectAlert(server_, kTlsAlertDecryptError); + server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); + client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); +} + +TEST_F(TlsConnectTest, TestFallbackFromTls12) { + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_1); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_2); + client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_2); + ConnectExpectAlert(client_, kTlsAlertIllegalParameter); + client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +static SECStatus AllowFalseStart(PRFileDesc* fd, void* arg, + PRBool* can_false_start) { + bool* false_start_attempted = reinterpret_cast<bool*>(arg); + *false_start_attempted = true; + *can_false_start = PR_TRUE; + return SECSuccess; +} + +// If we disable the downgrade check, the sentinel is still generated, and we +// disable false start instead. +TEST_F(TlsConnectTest, DisableFalseStartOnFallback) { + // Don't call client_->EnableFalseStart(), because that sets the client up for + // success, and we want false start to fail. + client_->SetOption(SSL_ENABLE_FALSE_START, PR_TRUE); + bool false_start_attempted = false; + EXPECT_EQ(SECSuccess, + SSL_SetCanFalseStartCallback(client_->ssl_fd(), AllowFalseStart, + &false_start_attempted)); + + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_FALSE); + client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + Connect(); + EXPECT_FALSE(false_start_attempted); +} + +TEST_F(TlsConnectTest, TestFallbackFromTls13) { + client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE); + client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_3); + ConnectExpectAlert(client_, kTlsAlertIllegalParameter); + client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + +TEST_P(TlsConnectGeneric, TestFallbackSCSVVersionMatch) { + client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); + Connect(); +} + +TEST_P(TlsConnectGenericPre13, TestFallbackSCSVVersionMismatch) { + client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); + server_->SetVersionRange(version_, version_ + 1); + ConnectExpectAlert(server_, kTlsAlertInappropriateFallback); + client_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT); + server_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT); +} + +// The TLS v1.3 spec section C.4 states that 'Implementations MUST NOT send or +// accept any records with a version less than { 3, 0 }'. Thus we will not +// allow version ranges including both SSL v3 and TLS v1.3. +TEST_F(TlsConnectTest, DisallowSSLv3HelloWithTLSv13Enabled) { + SECStatus rv; + SSLVersionRange vrange = {SSL_LIBRARY_VERSION_3_0, + SSL_LIBRARY_VERSION_TLS_1_3}; + + EnsureTlsSetup(); + rv = SSL_VersionRangeSet(client_->ssl_fd(), &vrange); + EXPECT_EQ(SECFailure, rv); + + rv = SSL_VersionRangeSet(server_->ssl_fd(), &vrange); + EXPECT_EQ(SECFailure, rv); +} + +TEST_P(TlsConnectGeneric, AlertBeforeServerHello) { + EnsureTlsSetup(); + client_->ExpectReceiveAlert(kTlsAlertUnrecognizedName, kTlsAlertWarning); + StartConnect(); + client_->Handshake(); // Send ClientHello. + static const uint8_t kWarningAlert[] = {kTlsAlertWarning, + kTlsAlertUnrecognizedName}; + DataBuffer alert; + TlsAgentTestBase::MakeRecord(variant_, ssl_ct_alert, + SSL_LIBRARY_VERSION_TLS_1_0, kWarningAlert, + PR_ARRAY_SIZE(kWarningAlert), &alert); + client_->adapter()->PacketReceived(alert); + Handshake(); + CheckConnected(); +} + +class Tls13NoSupportedVersions : public TlsConnectStreamTls12 { + protected: + void Run(uint16_t overwritten_client_version, uint16_t max_server_version) { + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, max_server_version); + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + overwritten_client_version); + auto capture = + MakeTlsFilter<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello); + ConnectExpectAlert(server_, kTlsAlertDecryptError); + client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); + server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); + const DataBuffer& server_hello = capture->buffer(); + ASSERT_GT(server_hello.len(), 2U); + uint32_t ver; + ASSERT_TRUE(server_hello.Read(0, 2, &ver)); + ASSERT_EQ(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), ver); + } +}; + +// If we offer a 1.3 ClientHello w/o supported_versions, the server should +// negotiate 1.2. +TEST_F(Tls13NoSupportedVersions, + Tls13ClientHelloWithoutSupportedVersionsServer12) { + Run(SSL_LIBRARY_VERSION_TLS_1_3, SSL_LIBRARY_VERSION_TLS_1_2); +} + +TEST_F(Tls13NoSupportedVersions, + Tls13ClientHelloWithoutSupportedVersionsServer13) { + Run(SSL_LIBRARY_VERSION_TLS_1_3, SSL_LIBRARY_VERSION_TLS_1_3); +} + +TEST_F(Tls13NoSupportedVersions, + Tls14ClientHelloWithoutSupportedVersionsServer13) { + Run(SSL_LIBRARY_VERSION_TLS_1_3 + 1, SSL_LIBRARY_VERSION_TLS_1_3); +} + +// Offer 1.3 but with ClientHello.legacy_version == TLS 1.4. This +// causes a bad MAC error when we read EncryptedExtensions. +TEST_F(TlsConnectStreamTls13, Tls14ClientHelloWithSupportedVersions) { + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + SSL_LIBRARY_VERSION_TLS_1_3 + 1); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + server_, ssl_tls13_supported_versions_xtn); + client_->ExpectSendAlert(kTlsAlertBadRecordMac); + server_->ExpectSendAlert(kTlsAlertBadRecordMac); + ConnectExpectFail(); + client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); + + ASSERT_EQ(2U, capture->extension().len()); + uint32_t version = 0; + ASSERT_TRUE(capture->extension().Read(0, 2, &version)); + // This way we don't need to change with new draft version. + ASSERT_LT(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), version); +} + +// Offer 1.3 but with Server/ClientHello.legacy_version == SSL 3.0. This +// causes a protocol version alert. See RFC 8446 Appendix D.5. +TEST_F(TlsConnectStreamTls13, Ssl30ClientHelloWithSupportedVersions) { + MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello, + SSL_LIBRARY_VERSION_3_0); + ConnectExpectAlert(server_, kTlsAlertProtocolVersion); +} + +TEST_F(TlsConnectStreamTls13, Ssl30ServerHelloWithSupportedVersions) { + MakeTlsFilter<TlsMessageVersionSetter>(server_, kTlsHandshakeServerHello, + SSL_LIBRARY_VERSION_3_0); + StartConnect(); + client_->ExpectSendAlert(kTlsAlertProtocolVersion); + /* Since the handshake is not finished the client will send an unencrypted + * alert. The server is expected to close the connection with a unexpected + * message alert. */ + server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); + Handshake(); +} + +// Verify the client sends only DTLS versions in supported_versions +TEST_F(DtlsConnectTest, DtlsSupportedVersionsEncoding) { + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, + SSL_LIBRARY_VERSION_TLS_1_3); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_tls13_supported_versions_xtn); + Connect(); + + ASSERT_EQ(7U, capture->extension().len()); + uint32_t version = 0; + ASSERT_TRUE(capture->extension().Read(1, 2, &version)); + EXPECT_EQ(0x7f00 | DTLS_1_3_DRAFT_VERSION, static_cast<int>(version)); + ASSERT_TRUE(capture->extension().Read(3, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, static_cast<int>(version)); + ASSERT_TRUE(capture->extension().Read(5, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_DTLS_1_0_WIRE, static_cast<int>(version)); +} + +// Verify the DTLS 1.3 supported_versions interop workaround. +TEST_F(DtlsConnectTest, Dtls13VersionWorkaround) { + static const uint16_t kExpectVersionsWorkaround[] = { + 0x7f00 | DTLS_1_3_DRAFT_VERSION, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, + SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_DTLS_1_0_WIRE, + SSL_LIBRARY_VERSION_TLS_1_1}; + const int min_ver = SSL_LIBRARY_VERSION_TLS_1_1, + max_ver = SSL_LIBRARY_VERSION_TLS_1_3; + + // Toggle the workaround, then verify both encodings are present. + EnsureTlsSetup(); + SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE); + SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_FALSE); + SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE); + client_->SetVersionRange(min_ver, max_ver); + server_->SetVersionRange(min_ver, max_ver); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_tls13_supported_versions_xtn); + Connect(); + + uint32_t version = 0; + size_t off = 1; + ASSERT_EQ(1 + sizeof(kExpectVersionsWorkaround), capture->extension().len()); + for (unsigned int i = 0; i < PR_ARRAY_SIZE(kExpectVersionsWorkaround); i++) { + ASSERT_TRUE(capture->extension().Read(off, 2, &version)); + EXPECT_EQ(kExpectVersionsWorkaround[i], static_cast<uint16_t>(version)); + off += 2; + } +} + +// Verify the client sends only TLS versions in supported_versions +TEST_F(TlsConnectTest, TlsSupportedVersionsEncoding) { + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_3); + auto capture = MakeTlsFilter<TlsExtensionCapture>( + client_, ssl_tls13_supported_versions_xtn); + Connect(); + + ASSERT_EQ(9U, capture->extension().len()); + uint32_t version = 0; + ASSERT_TRUE(capture->extension().Read(1, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_3, static_cast<int>(version)); + ASSERT_TRUE(capture->extension().Read(3, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<int>(version)); + ASSERT_TRUE(capture->extension().Read(5, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, static_cast<int>(version)); + ASSERT_TRUE(capture->extension().Read(7, 2, &version)); + EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, static_cast<int>(version)); +} + +/* Test that on reception of unsupported ClientHello.legacy_version the TLS 1.3 + * server sends the correct alert. + * + * If the "supported_versions" extension is absent and the server only supports + * versions greater than ClientHello.legacy_version, the server MUST abort the + * handshake with a "protocol_version" alert [RFC8446, Appendix D.2]. */ +TEST_P(TlsConnectGenericPre13, ClientHelloUnsupportedTlsVersion) { + StartConnect(); + + if (variant_ == ssl_variant_stream) { + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3, + SSL_LIBRARY_VERSION_TLS_1_3); + } else { + server_->SetVersionRange(SSL_LIBRARY_VERSION_DTLS_1_3, + SSL_LIBRARY_VERSION_DTLS_1_3); + } + + // Try to handshake + client_->Handshake(); + // Expect protocol version alert + server_->ExpectSendAlert(kTlsAlertProtocolVersion); + server_->Handshake(); + // Digest alert at peer + client_->ExpectReceiveAlert(kTlsAlertProtocolVersion); + client_->ReadBytes(); +} + +INSTANTIATE_TEST_SUITE_P( + TlsDowngradeSentinelTest, TlsDowngradeTest, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream, + TlsConnectTestBase::kTlsVAll, + TlsConnectTestBase::kTlsV12Plus)); + +} // namespace nss_test |