tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ssl_version_unittest.cc (19764B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "secerr.h"
      8 #include "ssl.h"
      9 #include "ssl3prot.h"
     10 #include "sslerr.h"
     11 #include "sslproto.h"
     12 
     13 #include "gtest_utils.h"
     14 #include "nss_scoped_ptrs.h"
     15 #include "tls_connect.h"
     16 #include "tls_filter.h"
     17 #include "tls_parser.h"
     18 
     19 namespace nss_test {
     20 
     21 TEST_P(TlsConnectStream, ServerNegotiateTls10) {
     22  uint16_t minver, maxver;
     23  client_->GetVersionRange(&minver, &maxver);
     24  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, maxver);
     25  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
     26                           SSL_LIBRARY_VERSION_TLS_1_0);
     27  Connect();
     28 }
     29 
     30 TEST_P(TlsConnectGeneric, ServerNegotiateTls11) {
     31  if (version_ < SSL_LIBRARY_VERSION_TLS_1_1) GTEST_SKIP();
     32 
     33  uint16_t minver, maxver;
     34  client_->GetVersionRange(&minver, &maxver);
     35  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, maxver);
     36  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
     37                           SSL_LIBRARY_VERSION_TLS_1_1);
     38  Connect();
     39 }
     40 
     41 TEST_P(TlsConnectGeneric, ServerNegotiateTls12) {
     42  if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) GTEST_SKIP();
     43 
     44  uint16_t minver, maxver;
     45  client_->GetVersionRange(&minver, &maxver);
     46  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, maxver);
     47  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
     48                           SSL_LIBRARY_VERSION_TLS_1_2);
     49  Connect();
     50 }
     51 
     52 TEST_P(TlsConnectGeneric,
     53       ClientOfferTls11_Tls13ServerNegotiateEachVersionOneByOne) {
     54  // DTLS does not support 1.0
     55  if (variant_ == ssl_variant_datagram) {
     56    client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
     57                             SSL_LIBRARY_VERSION_TLS_1_3);
     58  } else {
     59    client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
     60                             SSL_LIBRARY_VERSION_TLS_1_3);
     61  }
     62  server_->SetVersionRange(version_, version_);
     63  Connect();
     64 }
     65 
     66 // Test the ServerRandom version hack from
     67 // [draft-ietf-tls-tls13-11 Section 6.3.1.1].
     68 // The first three tests test for active tampering. The next
     69 // two validate that we can also detect fallback using the
     70 // SSL_SetDowngradeCheckVersion() API.
     71 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls11) {
     72  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
     73                           SSL_LIBRARY_VERSION_TLS_1_2);
     74  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
     75                           SSL_LIBRARY_VERSION_TLS_1_2);
     76  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
     77  MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
     78                                         SSL_LIBRARY_VERSION_TLS_1_1);
     79  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
     80  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
     81  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
     82 }
     83 
     84 // Attempt to negotiate the bogus DTLS 1.1 version.
     85 TEST_F(DtlsConnectTest, TestDtlsVersion11) {
     86  MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
     87                                         ((~0x0101) & 0xffff));
     88  ConnectExpectAlert(server_, kTlsAlertProtocolVersion);
     89  client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
     90  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
     91 }
     92 
     93 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) {
     94  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
     95  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn);
     96  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
     97                           SSL_LIBRARY_VERSION_TLS_1_3);
     98  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
     99                           SSL_LIBRARY_VERSION_TLS_1_3);
    100  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    101  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
    102  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    103 }
    104 
    105 // Disabling downgrade checks will be caught when the Finished MAC check fails.
    106 TEST_F(TlsConnectTest, TestDisableDowngradeDetection) {
    107  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_FALSE);
    108  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn);
    109  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    110                           SSL_LIBRARY_VERSION_TLS_1_3);
    111  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    112                           SSL_LIBRARY_VERSION_TLS_1_3);
    113  ConnectExpectAlert(server_, kTlsAlertDecryptError);
    114  client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    115  server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    116 }
    117 
    118 typedef std::tuple<SSLProtocolVariant,
    119                   uint16_t,  // client version
    120                   uint16_t>  // server version
    121    TlsDowngradeProfile;
    122 
    123 class TlsDowngradeTest
    124    : public TlsConnectTestBase,
    125      public ::testing::WithParamInterface<TlsDowngradeProfile> {
    126 public:
    127  TlsDowngradeTest()
    128      : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())),
    129        c_ver(std::get<1>(GetParam())),
    130        s_ver(std::get<2>(GetParam())) {}
    131 
    132 protected:
    133  const uint16_t c_ver;
    134  const uint16_t s_ver;
    135 };
    136 
    137 TEST_P(TlsDowngradeTest, TlsDowngradeSentinelTest) {
    138  static const uint8_t tls12_downgrade_random[] = {0x44, 0x4F, 0x57, 0x4E,
    139                                                   0x47, 0x52, 0x44, 0x01};
    140  static const uint8_t tls1_downgrade_random[] = {0x44, 0x4F, 0x57, 0x4E,
    141                                                  0x47, 0x52, 0x44, 0x00};
    142  static const size_t kRandomLen = 32;
    143 
    144  if (c_ver > s_ver) {
    145    GTEST_SKIP();
    146  }
    147 
    148  client_->SetVersionRange(c_ver, c_ver);
    149  server_->SetVersionRange(c_ver, s_ver);
    150 
    151  auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
    152  Connect();
    153  ASSERT_TRUE(sh->buffer().len() > (kRandomLen + 2));
    154 
    155  const uint8_t* downgrade_sentinel =
    156      sh->buffer().data() + 2 + kRandomLen - sizeof(tls1_downgrade_random);
    157  if (c_ver < s_ver) {
    158    if (c_ver == SSL_LIBRARY_VERSION_TLS_1_2) {
    159      EXPECT_EQ(0, memcmp(downgrade_sentinel, tls12_downgrade_random,
    160                          sizeof(tls12_downgrade_random)));
    161    } else {
    162      EXPECT_EQ(0, memcmp(downgrade_sentinel, tls1_downgrade_random,
    163                          sizeof(tls1_downgrade_random)));
    164    }
    165  } else {
    166    EXPECT_NE(0, memcmp(downgrade_sentinel, tls12_downgrade_random,
    167                        sizeof(tls12_downgrade_random)));
    168    EXPECT_NE(0, memcmp(downgrade_sentinel, tls1_downgrade_random,
    169                        sizeof(tls1_downgrade_random)));
    170  }
    171 }
    172 
    173 // TLS 1.1 clients do not check the random values, so we should
    174 // instead get a handshake failure alert from the server.
    175 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls10) {
    176  // Setting the option here has no effect.
    177  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
    178  MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
    179                                         SSL_LIBRARY_VERSION_TLS_1_0);
    180  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
    181                           SSL_LIBRARY_VERSION_TLS_1_1);
    182  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
    183                           SSL_LIBRARY_VERSION_TLS_1_2);
    184  ConnectExpectAlert(server_, kTlsAlertDecryptError);
    185  server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    186  client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    187 }
    188 
    189 TEST_F(TlsConnectTest, TestFallbackFromTls12) {
    190  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
    191  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
    192                           SSL_LIBRARY_VERSION_TLS_1_1);
    193  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
    194                           SSL_LIBRARY_VERSION_TLS_1_2);
    195  client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_2);
    196  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    197  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
    198  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    199 }
    200 
    201 static SECStatus AllowFalseStart(PRFileDesc* fd, void* arg,
    202                                 PRBool* can_false_start) {
    203  bool* false_start_attempted = reinterpret_cast<bool*>(arg);
    204  *false_start_attempted = true;
    205  *can_false_start = PR_TRUE;
    206  return SECSuccess;
    207 }
    208 
    209 // If we disable the downgrade check, the sentinel is still generated, and we
    210 // disable false start instead.
    211 TEST_F(TlsConnectTest, DisableFalseStartOnFallback) {
    212  // Don't call client_->EnableFalseStart(), because that sets the client up for
    213  // success, and we want false start to fail.
    214  client_->SetOption(SSL_ENABLE_FALSE_START, PR_TRUE);
    215  bool false_start_attempted = false;
    216  EXPECT_EQ(SECSuccess,
    217            SSL_SetCanFalseStartCallback(client_->ssl_fd(), AllowFalseStart,
    218                                         &false_start_attempted));
    219 
    220  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_FALSE);
    221  client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    222  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    223                           SSL_LIBRARY_VERSION_TLS_1_2);
    224  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    225                           SSL_LIBRARY_VERSION_TLS_1_3);
    226  Connect();
    227  EXPECT_FALSE(false_start_attempted);
    228 }
    229 
    230 TEST_F(TlsConnectTest, TestFallbackFromTls13) {
    231  client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
    232  client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    233  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    234                           SSL_LIBRARY_VERSION_TLS_1_2);
    235  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
    236                           SSL_LIBRARY_VERSION_TLS_1_3);
    237  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    238  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
    239  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    240 }
    241 
    242 TEST_P(TlsConnectGeneric, TestFallbackSCSVVersionMatch) {
    243  client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
    244  Connect();
    245 }
    246 
    247 TEST_P(TlsConnectGenericPre13, TestFallbackSCSVVersionMismatch) {
    248  client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
    249  server_->SetVersionRange(version_, version_ + 1);
    250  ConnectExpectAlert(server_, kTlsAlertInappropriateFallback);
    251  client_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT);
    252  server_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT);
    253 }
    254 
    255 // The TLS v1.3 spec section C.4 states that 'Implementations MUST NOT send or
    256 // accept any records with a version less than { 3, 0 }'. Thus we will not
    257 // allow version ranges including both SSL v3 and TLS v1.3.
    258 TEST_F(TlsConnectTest, DisallowSSLv3HelloWithTLSv13Enabled) {
    259  SECStatus rv;
    260  SSLVersionRange vrange = {SSL_LIBRARY_VERSION_3_0,
    261                            SSL_LIBRARY_VERSION_TLS_1_3};
    262 
    263  EnsureTlsSetup();
    264  rv = SSL_VersionRangeSet(client_->ssl_fd(), &vrange);
    265  EXPECT_EQ(SECFailure, rv);
    266 
    267  rv = SSL_VersionRangeSet(server_->ssl_fd(), &vrange);
    268  EXPECT_EQ(SECFailure, rv);
    269 }
    270 
    271 TEST_P(TlsConnectGeneric, AlertBeforeServerHello) {
    272  EnsureTlsSetup();
    273  client_->ExpectReceiveAlert(kTlsAlertUnrecognizedName, kTlsAlertWarning);
    274  StartConnect();
    275  client_->Handshake();  // Send ClientHello.
    276  static const uint8_t kWarningAlert[] = {kTlsAlertWarning,
    277                                          kTlsAlertUnrecognizedName};
    278  DataBuffer alert;
    279  TlsAgentTestBase::MakeRecord(variant_, ssl_ct_alert,
    280                               SSL_LIBRARY_VERSION_TLS_1_0, kWarningAlert,
    281                               PR_ARRAY_SIZE(kWarningAlert), &alert);
    282  client_->adapter()->PacketReceived(alert);
    283  Handshake();
    284  CheckConnected();
    285 }
    286 
    287 class Tls13NoSupportedVersions : public TlsConnectStreamTls12 {
    288 protected:
    289  void Run(uint16_t overwritten_client_version, uint16_t max_server_version) {
    290    client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    291                             SSL_LIBRARY_VERSION_TLS_1_2);
    292    server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, max_server_version);
    293    MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
    294                                           overwritten_client_version);
    295    auto capture =
    296        MakeTlsFilter<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello);
    297    ConnectExpectAlert(server_, kTlsAlertDecryptError);
    298    client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    299    server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    300    const DataBuffer& server_hello = capture->buffer();
    301    ASSERT_GT(server_hello.len(), 2U);
    302    uint32_t ver;
    303    ASSERT_TRUE(server_hello.Read(0, 2, &ver));
    304    ASSERT_EQ(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), ver);
    305  }
    306 };
    307 
    308 // If we offer a 1.3 ClientHello w/o supported_versions, the server should
    309 // negotiate 1.2.
    310 TEST_F(Tls13NoSupportedVersions,
    311       Tls13ClientHelloWithoutSupportedVersionsServer12) {
    312  Run(SSL_LIBRARY_VERSION_TLS_1_3, SSL_LIBRARY_VERSION_TLS_1_2);
    313 }
    314 
    315 TEST_F(Tls13NoSupportedVersions,
    316       Tls13ClientHelloWithoutSupportedVersionsServer13) {
    317  Run(SSL_LIBRARY_VERSION_TLS_1_3, SSL_LIBRARY_VERSION_TLS_1_3);
    318 }
    319 
    320 TEST_F(Tls13NoSupportedVersions,
    321       Tls14ClientHelloWithoutSupportedVersionsServer13) {
    322  Run(SSL_LIBRARY_VERSION_TLS_1_3 + 1, SSL_LIBRARY_VERSION_TLS_1_3);
    323 }
    324 
    325 // Offer 1.3 but with ClientHello.legacy_version == TLS 1.4. This
    326 // causes a bad MAC error when we read EncryptedExtensions.
    327 TEST_F(TlsConnectStreamTls13, Tls14ClientHelloWithSupportedVersions) {
    328  MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
    329                                         SSL_LIBRARY_VERSION_TLS_1_3 + 1);
    330  auto capture = MakeTlsFilter<TlsExtensionCapture>(
    331      server_, ssl_tls13_supported_versions_xtn);
    332  client_->ExpectSendAlert(kTlsAlertBadRecordMac);
    333  server_->ExpectSendAlert(kTlsAlertBadRecordMac);
    334  ConnectExpectFail();
    335  client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
    336  server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
    337 
    338  ASSERT_EQ(2U, capture->extension().len());
    339  uint32_t version = 0;
    340  ASSERT_TRUE(capture->extension().Read(0, 2, &version));
    341  // This way we don't need to change with new draft version.
    342  ASSERT_LT(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), version);
    343 }
    344 
    345 // Offer 1.3 but with Server/ClientHello.legacy_version == SSL 3.0. This
    346 // causes a protocol version alert.  See RFC 8446 Appendix D.5.
    347 TEST_F(TlsConnectStreamTls13, Ssl30ClientHelloWithSupportedVersions) {
    348  MakeTlsFilter<TlsMessageVersionSetter>(client_, kTlsHandshakeClientHello,
    349                                         SSL_LIBRARY_VERSION_3_0);
    350  ConnectExpectAlert(server_, kTlsAlertProtocolVersion);
    351 }
    352 
    353 TEST_F(TlsConnectStreamTls13, Ssl30ServerHelloWithSupportedVersions) {
    354  MakeTlsFilter<TlsMessageVersionSetter>(server_, kTlsHandshakeServerHello,
    355                                         SSL_LIBRARY_VERSION_3_0);
    356  StartConnect();
    357  client_->ExpectSendAlert(kTlsAlertProtocolVersion);
    358  /* Since the handshake is not finished the client will send an unencrypted
    359   * alert. The server is expected to close the connection with a unexpected
    360   * message alert. */
    361  server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
    362  Handshake();
    363 }
    364 
    365 // Verify the client sends only DTLS versions in supported_versions
    366 TEST_F(DtlsConnectTest, DtlsSupportedVersionsEncoding) {
    367  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
    368                           SSL_LIBRARY_VERSION_TLS_1_3);
    369  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
    370                           SSL_LIBRARY_VERSION_TLS_1_3);
    371  auto capture = MakeTlsFilter<TlsExtensionCapture>(
    372      client_, ssl_tls13_supported_versions_xtn);
    373  Connect();
    374 
    375  ASSERT_EQ(7U, capture->extension().len());
    376  uint32_t version = 0;
    377  ASSERT_TRUE(capture->extension().Read(1, 2, &version));
    378  EXPECT_EQ(SSL_LIBRARY_VERSION_DTLS_1_3_WIRE, static_cast<int>(version));
    379  ASSERT_TRUE(capture->extension().Read(3, 2, &version));
    380  EXPECT_EQ(SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, static_cast<int>(version));
    381  ASSERT_TRUE(capture->extension().Read(5, 2, &version));
    382  EXPECT_EQ(SSL_LIBRARY_VERSION_DTLS_1_0_WIRE, static_cast<int>(version));
    383 }
    384 
    385 // Verify the DTLS 1.3 supported_versions interop workaround.
    386 TEST_F(DtlsConnectTest, Dtls13VersionWorkaround) {
    387  static const uint16_t kExpectVersionsWorkaround[] = {
    388      SSL_LIBRARY_VERSION_DTLS_1_3_WIRE, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE,
    389      SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_DTLS_1_0_WIRE,
    390      SSL_LIBRARY_VERSION_TLS_1_1};
    391  const int min_ver = SSL_LIBRARY_VERSION_TLS_1_1,
    392            max_ver = SSL_LIBRARY_VERSION_TLS_1_3;
    393 
    394  // Toggle the workaround, then verify both encodings are present.
    395  EnsureTlsSetup();
    396  SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE);
    397  SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_FALSE);
    398  SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE);
    399  client_->SetVersionRange(min_ver, max_ver);
    400  server_->SetVersionRange(min_ver, max_ver);
    401  auto capture = MakeTlsFilter<TlsExtensionCapture>(
    402      client_, ssl_tls13_supported_versions_xtn);
    403  Connect();
    404 
    405  uint32_t version = 0;
    406  size_t off = 1;
    407  ASSERT_EQ(1 + sizeof(kExpectVersionsWorkaround), capture->extension().len());
    408  for (unsigned int i = 0; i < PR_ARRAY_SIZE(kExpectVersionsWorkaround); i++) {
    409    ASSERT_TRUE(capture->extension().Read(off, 2, &version));
    410    EXPECT_EQ(kExpectVersionsWorkaround[i], static_cast<uint16_t>(version));
    411    off += 2;
    412  }
    413 }
    414 
    415 // Verify the client sends only TLS versions in supported_versions
    416 TEST_F(TlsConnectTest, TlsSupportedVersionsEncoding) {
    417  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
    418                           SSL_LIBRARY_VERSION_TLS_1_3);
    419  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
    420                           SSL_LIBRARY_VERSION_TLS_1_3);
    421  auto capture = MakeTlsFilter<TlsExtensionCapture>(
    422      client_, ssl_tls13_supported_versions_xtn);
    423  Connect();
    424 
    425  ASSERT_EQ(9U, capture->extension().len());
    426  uint32_t version = 0;
    427  ASSERT_TRUE(capture->extension().Read(1, 2, &version));
    428  EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_3, static_cast<int>(version));
    429  ASSERT_TRUE(capture->extension().Read(3, 2, &version));
    430  EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<int>(version));
    431  ASSERT_TRUE(capture->extension().Read(5, 2, &version));
    432  EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, static_cast<int>(version));
    433  ASSERT_TRUE(capture->extension().Read(7, 2, &version));
    434  EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, static_cast<int>(version));
    435 }
    436 
    437 /* Test that on reception of unsupported ClientHello.legacy_version the TLS 1.3
    438 * server sends the correct alert.
    439 *
    440 * If the "supported_versions" extension is absent and the server only supports
    441 * versions greater than ClientHello.legacy_version, the server MUST abort the
    442 * handshake with a "protocol_version" alert [RFC8446, Appendix D.2]. */
    443 TEST_P(TlsConnectGenericPre13, ClientHelloUnsupportedTlsVersion) {
    444  StartConnect();
    445 
    446  if (variant_ == ssl_variant_stream) {
    447    server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
    448                             SSL_LIBRARY_VERSION_TLS_1_3);
    449  } else {
    450    server_->SetVersionRange(SSL_LIBRARY_VERSION_DTLS_1_3,
    451                             SSL_LIBRARY_VERSION_DTLS_1_3);
    452  }
    453 
    454  // Try to handshake
    455  client_->Handshake();
    456  // Expect protocol version alert
    457  server_->ExpectSendAlert(kTlsAlertProtocolVersion);
    458  server_->Handshake();
    459  // Digest alert at peer
    460  client_->ExpectReceiveAlert(kTlsAlertProtocolVersion);
    461  client_->ReadBytes();
    462 }
    463 
    464 INSTANTIATE_TEST_SUITE_P(
    465    TlsDowngradeSentinelTest, TlsDowngradeTest,
    466    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
    467                       TlsConnectTestBase::kTlsVAll,
    468                       TlsConnectTestBase::kTlsV12Plus));
    469 
    470 }  // namespace nss_test