tor-browser

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

ssl_tls13compat_unittest.cc (20043B)


      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 <memory>
      8 #include <vector>
      9 #include "ssl.h"
     10 #include "sslerr.h"
     11 #include "sslproto.h"
     12 
     13 #include "gtest_utils.h"
     14 #include "tls_connect.h"
     15 #include "tls_filter.h"
     16 #include "tls_parser.h"
     17 
     18 namespace nss_test {
     19 
     20 class Tls13CompatTest : public TlsConnectStreamTls13 {
     21 protected:
     22  void EnableCompatMode() {
     23    client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
     24  }
     25 
     26  void InstallFilters() {
     27    EnsureTlsSetup();
     28    client_recorders_.Install(client_);
     29    server_recorders_.Install(server_);
     30  }
     31 
     32  void CheckRecordVersions() {
     33    ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0,
     34              client_recorders_.records_->record(0).header.version());
     35    CheckRecordsAreTls12("client", client_recorders_.records_, 1);
     36    CheckRecordsAreTls12("server", server_recorders_.records_, 0);
     37  }
     38 
     39  void CheckHelloVersions() {
     40    uint32_t ver;
     41    ASSERT_TRUE(server_recorders_.hello_->buffer().Read(0, 2, &ver));
     42    ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<uint16_t>(ver));
     43    ASSERT_TRUE(client_recorders_.hello_->buffer().Read(0, 2, &ver));
     44    ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, static_cast<uint16_t>(ver));
     45  }
     46 
     47  void CheckForCCS(bool expected_client, bool expected_server) {
     48    client_recorders_.CheckForCCS(expected_client);
     49    server_recorders_.CheckForCCS(expected_server);
     50  }
     51 
     52  void CheckForRegularHandshake() {
     53    CheckRecordVersions();
     54    CheckHelloVersions();
     55    EXPECT_EQ(0U, client_recorders_.session_id_length());
     56    EXPECT_EQ(0U, server_recorders_.session_id_length());
     57    CheckForCCS(false, false);
     58  }
     59 
     60  void CheckForCompatHandshake() {
     61    CheckRecordVersions();
     62    CheckHelloVersions();
     63    EXPECT_EQ(32U, client_recorders_.session_id_length());
     64    EXPECT_EQ(32U, server_recorders_.session_id_length());
     65    CheckForCCS(true, true);
     66  }
     67 
     68 private:
     69  struct Recorders {
     70    Recorders() : records_(nullptr), hello_(nullptr) {}
     71 
     72    uint8_t session_id_length() const {
     73      // session_id is always after version (2) and random (32).
     74      uint32_t len = 0;
     75      EXPECT_TRUE(hello_->buffer().Read(2 + 32, 1, &len));
     76      return static_cast<uint8_t>(len);
     77    }
     78 
     79    void CheckForCCS(bool expected) const {
     80      EXPECT_LT(0U, records_->count());
     81      for (size_t i = 0; i < records_->count(); ++i) {
     82        // Only the second record can be a CCS.
     83        bool expected_match = expected && (i == 1);
     84        EXPECT_EQ(expected_match,
     85                  ssl_ct_change_cipher_spec ==
     86                      records_->record(i).header.content_type());
     87      }
     88    }
     89 
     90    void Install(std::shared_ptr<TlsAgent>& agent) {
     91      if (records_ && records_->agent() == agent) {
     92        // Avoid replacing the filters if they are already installed on this
     93        // agent. This ensures that InstallFilters() can be used after
     94        // MakeNewServer() without losing state on the client filters.
     95        return;
     96      }
     97      records_.reset(new TlsRecordRecorder(agent));
     98      hello_.reset(new TlsHandshakeRecorder(
     99          agent, std::set<uint8_t>(
    100                     {kTlsHandshakeClientHello, kTlsHandshakeServerHello})));
    101      agent->SetFilter(std::make_shared<ChainedPacketFilter>(
    102          ChainedPacketFilterInit({records_, hello_})));
    103    }
    104 
    105    std::shared_ptr<TlsRecordRecorder> records_;
    106    std::shared_ptr<TlsHandshakeRecorder> hello_;
    107  };
    108 
    109  void CheckRecordsAreTls12(const std::string& agent,
    110                            const std::shared_ptr<TlsRecordRecorder>& records,
    111                            size_t start) {
    112    EXPECT_LE(start, records->count());
    113    for (size_t i = start; i < records->count(); ++i) {
    114      EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_2,
    115                records->record(i).header.version())
    116          << agent << ": record " << i << " has wrong version";
    117    }
    118  }
    119 
    120  Recorders client_recorders_;
    121  Recorders server_recorders_;
    122 };
    123 
    124 TEST_F(Tls13CompatTest, Disabled) {
    125  InstallFilters();
    126  Connect();
    127  CheckForRegularHandshake();
    128 }
    129 
    130 TEST_F(Tls13CompatTest, Enabled) {
    131  EnableCompatMode();
    132  InstallFilters();
    133  Connect();
    134  CheckForCompatHandshake();
    135 }
    136 
    137 TEST_F(Tls13CompatTest, EnabledZeroRtt) {
    138  SetupForZeroRtt();
    139  EnableCompatMode();
    140  InstallFilters();
    141 
    142  client_->Set0RttEnabled(true);
    143  server_->Set0RttEnabled(true);
    144  ExpectResumption(RESUME_TICKET);
    145  ZeroRttSendReceive(true, true);
    146  CheckForCCS(true, true);
    147  Handshake();
    148  ExpectEarlyDataAccepted(true);
    149  CheckConnected();
    150 
    151  CheckForCompatHandshake();
    152 }
    153 
    154 TEST_F(Tls13CompatTest, EnabledHrr) {
    155  EnableCompatMode();
    156  InstallFilters();
    157 
    158  // Force a HelloRetryRequest.  The server sends CCS immediately.
    159  server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
    160  client_->StartConnect();
    161  server_->StartConnect();
    162  client_->Handshake();
    163  server_->Handshake();
    164  CheckForCCS(false, true);
    165 
    166  Handshake();
    167  CheckConnected();
    168  CheckForCompatHandshake();
    169 }
    170 
    171 TEST_F(Tls13CompatTest, EnabledStatelessHrr) {
    172  EnableCompatMode();
    173  InstallFilters();
    174 
    175  // Force a HelloRetryRequest
    176  server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
    177  client_->StartConnect();
    178  server_->StartConnect();
    179  client_->Handshake();
    180  server_->Handshake();
    181 
    182  // The server should send CCS before HRR.
    183  CheckForCCS(false, true);
    184 
    185  // A new server should complete the handshake, and not send CCS.
    186  MakeNewServer();
    187  InstallFilters();
    188  server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
    189 
    190  Handshake();
    191  CheckConnected();
    192  CheckRecordVersions();
    193  CheckHelloVersions();
    194  CheckForCCS(true, false);
    195 }
    196 
    197 TEST_F(Tls13CompatTest, EnabledHrrZeroRtt) {
    198  SetupForZeroRtt();
    199  EnableCompatMode();
    200  InstallFilters();
    201  server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
    202 
    203  // With 0-RTT, the client sends CCS immediately.  With HRR, the server sends
    204  // CCS immediately too.
    205  client_->Set0RttEnabled(true);
    206  server_->Set0RttEnabled(true);
    207  ExpectResumption(RESUME_TICKET);
    208  ZeroRttSendReceive(true, false);
    209  CheckForCCS(true, true);
    210 
    211  Handshake();
    212  ExpectEarlyDataAccepted(false);
    213  CheckConnected();
    214  CheckForCompatHandshake();
    215 }
    216 
    217 TEST_F(Tls13CompatTest, EnabledAcceptedEch) {
    218  EnsureTlsSetup();
    219  SetupEch(client_, server_);
    220  EnableCompatMode();
    221  InstallFilters();
    222  Connect();
    223  CheckForCompatHandshake();
    224 }
    225 
    226 TEST_F(Tls13CompatTest, EnabledRejectedEch) {
    227  EnsureTlsSetup();
    228  // Configure ECH on the client only, and expect CCS.
    229  SetupEch(client_, server_, HpkeDhKemX25519Sha256, false, true, false);
    230  EnableCompatMode();
    231  InstallFilters();
    232  ExpectAlert(client_, kTlsAlertEchRequired);
    233  ConnectExpectFailOneSide(TlsAgent::CLIENT);
    234  client_->CheckErrorCode(SSL_ERROR_ECH_RETRY_WITHOUT_ECH);
    235  CheckForCompatHandshake();
    236  // Reset expectations for the TlsAgent dtor.
    237  server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning);
    238 }
    239 
    240 class TlsSessionIDEchoFilter : public TlsHandshakeFilter {
    241 public:
    242  TlsSessionIDEchoFilter(const std::shared_ptr<TlsAgent>& a)
    243      : TlsHandshakeFilter(
    244            a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
    245 
    246 protected:
    247  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
    248                                               const DataBuffer& input,
    249                                               DataBuffer* output) {
    250    TlsParser parser(input);
    251 
    252    // Skip version + random.
    253    EXPECT_TRUE(parser.Skip(2 + 32));
    254 
    255    // Capture CH.legacy_session_id.
    256    if (header.handshake_type() == kTlsHandshakeClientHello) {
    257      EXPECT_TRUE(parser.ReadVariable(&sid_, 1));
    258      return KEEP;
    259    }
    260 
    261    // Check that server sends one too.
    262    uint32_t sid_len = 0;
    263    EXPECT_TRUE(parser.Read(&sid_len, 1));
    264    EXPECT_EQ(sid_len, sid_.len());
    265 
    266    // Echo the one we captured.
    267    *output = input;
    268    output->Write(parser.consumed(), sid_.data(), sid_.len());
    269 
    270    return CHANGE;
    271  }
    272 
    273 private:
    274  DataBuffer sid_;
    275 };
    276 
    277 TEST_F(TlsConnectTest, EchoTLS13CompatibilitySessionID) {
    278  ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
    279 
    280  client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
    281 
    282  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    283                           SSL_LIBRARY_VERSION_TLS_1_3);
    284 
    285  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    286                           SSL_LIBRARY_VERSION_TLS_1_2);
    287 
    288  server_->SetFilter(MakeTlsFilter<TlsSessionIDEchoFilter>(client_));
    289  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    290 
    291  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
    292  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    293 }
    294 
    295 class TlsSessionIDInjectFilter : public TlsHandshakeFilter {
    296 public:
    297  TlsSessionIDInjectFilter(const std::shared_ptr<TlsAgent>& a)
    298      : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}) {}
    299 
    300 protected:
    301  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
    302                                               const DataBuffer& input,
    303                                               DataBuffer* output) {
    304    TlsParser parser(input);
    305 
    306    // Skip version + random.
    307    EXPECT_TRUE(parser.Skip(2 + 32));
    308 
    309    *output = input;
    310 
    311    // Inject a Session ID.
    312    const uint8_t fake_sid[SSL3_SESSIONID_BYTES] = {0xff};
    313    output->Write(parser.consumed(), sizeof(fake_sid), 1);
    314    output->Splice(fake_sid, sizeof(fake_sid), parser.consumed() + 1, 0);
    315 
    316    return CHANGE;
    317  }
    318 };
    319 
    320 TEST_F(TlsConnectTest, TLS13NonCompatModeSessionID) {
    321  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    322 
    323  MakeTlsFilter<TlsSessionIDInjectFilter>(server_);
    324  client_->ExpectSendAlert(kTlsAlertIllegalParameter);
    325  server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
    326  ConnectExpectFail();
    327 
    328  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
    329  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE);
    330 }
    331 
    332 static const uint8_t kCannedCcs[] = {
    333    ssl_ct_change_cipher_spec,
    334    SSL_LIBRARY_VERSION_TLS_1_2 >> 8,
    335    SSL_LIBRARY_VERSION_TLS_1_2 & 0xff,
    336    0,
    337    1,  // length
    338    1   // change_cipher_spec_choice
    339 };
    340 
    341 // A ChangeCipherSpec is ignored by a server because we have to tolerate it for
    342 // compatibility mode.  That doesn't mean that we have to tolerate it
    343 // unconditionally.  If we negotiate 1.3, we expect to see a cookie extension.
    344 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello13) {
    345  EnsureTlsSetup();
    346  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    347                           SSL_LIBRARY_VERSION_TLS_1_3);
    348  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    349                           SSL_LIBRARY_VERSION_TLS_1_3);
    350  // Client sends CCS before starting the handshake.
    351  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    352  ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
    353  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
    354  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
    355 }
    356 
    357 // A ChangeCipherSpec is ignored by a server because we have to tolerate it for
    358 // compatibility mode.  That doesn't mean that we have to tolerate it
    359 // unconditionally.  If we negotiate 1.3, we expect to see a cookie extension.
    360 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHelloTwice) {
    361  EnsureTlsSetup();
    362  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    363                           SSL_LIBRARY_VERSION_TLS_1_3);
    364  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    365                           SSL_LIBRARY_VERSION_TLS_1_3);
    366  // Client sends CCS before starting the handshake.
    367  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    368  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    369  ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
    370  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
    371  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
    372 }
    373 
    374 // The server accepts a ChangeCipherSpec even if the client advertises
    375 // an empty session ID.
    376 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecAfterClientHelloEmptySid) {
    377  EnsureTlsSetup();
    378  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    379 
    380  StartConnect();
    381  client_->Handshake();  // Send ClientHello
    382  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));  // Send CCS
    383 
    384  Handshake();
    385  CheckConnected();
    386 }
    387 
    388 // The server rejects multiple ChangeCipherSpec even if the client
    389 // indicates compatibility mode with non-empty session ID.
    390 TEST_F(Tls13CompatTest, ChangeCipherSpecAfterClientHelloTwice) {
    391  EnsureTlsSetup();
    392  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    393  EnableCompatMode();
    394 
    395  StartConnect();
    396  client_->Handshake();  // Send ClientHello
    397  // Send CCS twice in a row
    398  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    399  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    400 
    401  server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
    402  server_->Handshake();  // Consume ClientHello and CCS.
    403  server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
    404 }
    405 
    406 // The client accepts a ChangeCipherSpec even if it advertises an empty
    407 // session ID.
    408 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecAfterServerHelloEmptySid) {
    409  EnsureTlsSetup();
    410  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    411 
    412  // To replace Finished with a CCS below
    413  auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
    414  filter->SetHandshakeTypes({kTlsHandshakeFinished});
    415  filter->EnableDecryption();
    416 
    417  StartConnect();
    418  client_->Handshake();  // Send ClientHello
    419  server_->Handshake();  // Consume ClientHello, and
    420                         // send ServerHello..CertificateVerify
    421  // Send CCS
    422  server_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    423 
    424  // No alert is sent from the client. As Finished is dropped, we
    425  // can't use Handshake() and CheckConnected().
    426  client_->Handshake();
    427 }
    428 
    429 // The client rejects multiple ChangeCipherSpec in a row even if the
    430 // client indicates compatibility mode with non-empty session ID.
    431 TEST_F(Tls13CompatTest, ChangeCipherSpecAfterServerHelloTwice) {
    432  EnsureTlsSetup();
    433  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    434  EnableCompatMode();
    435 
    436  // To replace Finished with a CCS below
    437  auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
    438  filter->SetHandshakeTypes({kTlsHandshakeFinished});
    439  filter->EnableDecryption();
    440 
    441  StartConnect();
    442  client_->Handshake();  // Send ClientHello
    443  server_->Handshake();  // Consume ClientHello, and
    444                         // send ServerHello..CertificateVerify
    445                         // the ServerHello is followed by CCS
    446  // Send another CCS
    447  server_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    448  client_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
    449  client_->Handshake();  // Consume ClientHello and CCS
    450  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
    451 }
    452 
    453 // If we negotiate 1.2, we abort.
    454 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello12) {
    455  EnsureTlsSetup();
    456  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    457                           SSL_LIBRARY_VERSION_TLS_1_3);
    458  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    459                           SSL_LIBRARY_VERSION_TLS_1_2);
    460  // Client sends CCS before starting the handshake.
    461  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    462  ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
    463  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
    464  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
    465 }
    466 
    467 TEST_F(TlsConnectStreamTls13, ChangeCipherSpecAfterFinished13) {
    468  EnsureTlsSetup();
    469  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
    470  Connect();
    471  SendReceive(10);
    472  // Client sends CCS after the handshake.
    473  client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
    474  server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
    475  server_->ExpectReadWriteError();
    476  server_->ReadBytes();
    477  EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
    478 }
    479 
    480 TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
    481  EnsureTlsSetup();
    482  client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
    483  auto client_records = MakeTlsFilter<TlsRecordRecorder>(client_);
    484  auto server_records = MakeTlsFilter<TlsRecordRecorder>(server_);
    485  // filters only work with particular groups
    486  client_->ConfigNamedGroups(kNonPQDHEGroups);
    487  server_->ConfigNamedGroups(kNonPQDHEGroups);
    488  Connect();
    489 
    490  ASSERT_EQ(2U, client_records->count());  // CH, Fin
    491  EXPECT_EQ(ssl_ct_handshake, client_records->record(0).header.content_type());
    492  EXPECT_EQ(kCtDtlsCiphertext,
    493            (client_records->record(1).header.content_type() &
    494             kCtDtlsCiphertextMask));
    495 
    496  ASSERT_EQ(6U, server_records->count());  // SH, EE, CT, CV, Fin, Ack
    497  EXPECT_EQ(ssl_ct_handshake, server_records->record(0).header.content_type());
    498  for (size_t i = 1; i < server_records->count(); ++i) {
    499    EXPECT_EQ(kCtDtlsCiphertext,
    500              (server_records->record(i).header.content_type() &
    501               kCtDtlsCiphertextMask));
    502  }
    503 }
    504 
    505 class AddSessionIdFilter : public TlsHandshakeFilter {
    506 public:
    507  AddSessionIdFilter(const std::shared_ptr<TlsAgent>& client)
    508      : TlsHandshakeFilter(client, {ssl_hs_client_hello}) {}
    509 
    510 protected:
    511  PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
    512                                       const DataBuffer& input,
    513                                       DataBuffer* output) override {
    514    uint32_t session_id_len = 0;
    515    EXPECT_TRUE(input.Read(2 + 32, 1, &session_id_len));
    516    EXPECT_EQ(0U, session_id_len);
    517    uint8_t session_id[33] = {32};  // 32 for length, the rest zero.
    518    *output = input;
    519    output->Splice(session_id, sizeof(session_id), 34, 1);
    520    return CHANGE;
    521  }
    522 };
    523 
    524 // Adding a session ID to a DTLS ClientHello should not trigger compatibility
    525 // mode.  It should be ignored instead.
    526 TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
    527  EnsureTlsSetup();
    528  auto client_records = std::make_shared<TlsRecordRecorder>(client_);
    529  client_->SetFilter(
    530      std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
    531          {client_records, std::make_shared<AddSessionIdFilter>(client_)})));
    532  auto server_hello =
    533      std::make_shared<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello);
    534  auto server_records = std::make_shared<TlsRecordRecorder>(server_);
    535  server_->SetFilter(std::make_shared<ChainedPacketFilter>(
    536      ChainedPacketFilterInit({server_records, server_hello})));
    537  // filters only work with particular groups
    538  server_->ConfigNamedGroups(kNonPQDHEGroups);
    539  client_->ConfigNamedGroups(kNonPQDHEGroups);
    540  StartConnect();
    541  client_->Handshake();
    542  server_->Handshake();
    543  // The client will consume the ServerHello, but discard everything else
    544  // because it doesn't decrypt.  And don't wait around for the client to ACK.
    545  client_->Handshake();
    546 
    547  ASSERT_EQ(1U, client_records->count());
    548  EXPECT_EQ(ssl_ct_handshake, client_records->record(0).header.content_type());
    549 
    550  ASSERT_EQ(5U, server_records->count());  // SH, EE, CT, CV, Fin
    551  EXPECT_EQ(ssl_ct_handshake, server_records->record(0).header.content_type());
    552  for (size_t i = 1; i < server_records->count(); ++i) {
    553    EXPECT_EQ(kCtDtlsCiphertext,
    554              (server_records->record(i).header.content_type() &
    555               kCtDtlsCiphertextMask));
    556  }
    557 
    558  uint32_t session_id_len = 0;
    559  EXPECT_TRUE(server_hello->buffer().Read(2 + 32, 1, &session_id_len));
    560  EXPECT_EQ(0U, session_id_len);
    561 }
    562 
    563 TEST_F(Tls13CompatTest, ConnectWith12ThenAttemptToResume13CompatMode) {
    564  ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
    565  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2);
    566  Connect();
    567 
    568  Reset();
    569  ExpectResumption(RESUME_NONE);
    570  version_ = SSL_LIBRARY_VERSION_TLS_1_3;
    571  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    572                           SSL_LIBRARY_VERSION_TLS_1_3);
    573  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
    574                           SSL_LIBRARY_VERSION_TLS_1_3);
    575  EnableCompatMode();
    576  Connect();
    577 }
    578 
    579 }  // namespace nss_test