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