ssl_drop_unittest.cc (36351B)
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 "sslexp.h" 10 11 extern "C" { 12 // This is not something that should make you happy. 13 #include "libssl_internals.h" 14 } 15 16 #include "gtest_utils.h" 17 #include "nss_scoped_ptrs.h" 18 #include "tls_connect.h" 19 #include "tls_filter.h" 20 #include "tls_parser.h" 21 22 namespace nss_test { 23 24 TEST_P(TlsConnectDatagramPre13, DropClientFirstFlightOnce) { 25 client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1)); 26 Connect(); 27 SendReceive(); 28 } 29 30 TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) { 31 server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1)); 32 Connect(); 33 SendReceive(); 34 } 35 36 // This drops the first transmission from both the client and server of all 37 // flights that they send. Note: In DTLS 1.3, the shorter handshake means that 38 // this will also drop some application data, so we can't call SendReceive(). 39 TEST_P(TlsConnectDatagramPre13, DropAllFirstTransmissions) { 40 client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x15)); 41 server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x5)); 42 Connect(); 43 } 44 45 // This drops the server's first flight three times. 46 TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightThrice) { 47 server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x7)); 48 Connect(); 49 } 50 51 // This drops the client's second flight once 52 TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightOnce) { 53 client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2)); 54 Connect(); 55 } 56 57 // This drops the client's second flight three times. 58 TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightThrice) { 59 client_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe)); 60 Connect(); 61 } 62 63 // This drops the server's second flight three times. 64 TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) { 65 server_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe)); 66 Connect(); 67 } 68 69 static void CheckAcks(const std::shared_ptr<TlsRecordRecorder>& acks, 70 size_t index, std::vector<uint64_t> expected) { 71 ASSERT_LT(index, acks->count()); 72 const DataBuffer& buf = acks->record(index).buffer; 73 size_t offset = 2; 74 uint64_t len; 75 // RFC 9147 - 7. ACK Message. 76 // 16 bytes correspond to the length of the epoch and the length of the seqNum 77 EXPECT_EQ(2 + expected.size() * 16, buf.len()); 78 ASSERT_TRUE(buf.Read(0, 2, &len)); 79 ASSERT_EQ(static_cast<size_t>(len + 2), buf.len()); 80 if ((2 + expected.size() * 16) != buf.len()) { 81 while (offset < buf.len()) { 82 uint64_t ack; 83 ASSERT_TRUE(buf.Read(offset, 8, &ack)); 84 offset += 8; 85 std::cerr << "Ack=0x" << std::hex << ack << std::dec << std::endl; 86 } 87 return; 88 } 89 90 for (size_t i = 0; i < expected.size(); ++i) { 91 uint64_t a = expected[i]; 92 uint64_t ackEpoch; 93 uint64_t ackSeq; 94 ASSERT_TRUE(buf.Read(offset, 8, &ackEpoch)); 95 offset += 8; 96 ASSERT_TRUE(buf.Read(offset, 8, &ackSeq)); 97 offset += 8; 98 uint64_t ack = (ackEpoch << 48) | ackSeq; 99 if (a != ack) { 100 ADD_FAILURE() << "Wrong ack " << i << " expected=0x" << std::hex << a 101 << " got=0x" << ack << std::dec; 102 } 103 } 104 } 105 106 class TlsDropDatagram13 : public TlsConnectDatagram13, 107 public ::testing::WithParamInterface<bool> { 108 public: 109 TlsDropDatagram13() 110 : client_filters_(), 111 server_filters_(), 112 expected_client_acks_(0), 113 expected_server_acks_(1) {} 114 115 void SetUp() override { 116 TlsConnectDatagram13::SetUp(); 117 ConfigureSessionCache(RESUME_NONE, RESUME_NONE); 118 int short_header = GetParam() ? PR_TRUE : PR_FALSE; 119 client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header); 120 server_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header); 121 SetFilters(); 122 } 123 124 void SetFilters() { 125 EnsureTlsSetup(); 126 client_filters_.Init(client_); 127 server_filters_.Init(server_); 128 } 129 130 void HandshakeAndAck(const std::shared_ptr<TlsAgent>& agent) { 131 agent->Handshake(); // Read flight. 132 ShiftDtlsTimers(); 133 agent->Handshake(); // Generate ACK. 134 } 135 136 void ShrinkPostServerHelloMtu() { 137 // Abuse the custom extension mechanism to modify the MTU so that the 138 // Certificate message is split into two pieces. 139 ASSERT_EQ( 140 SECSuccess, 141 SSL_InstallExtensionHooks( 142 server_->ssl_fd(), 1, 143 [](PRFileDesc* fd, SSLHandshakeType message, PRUint8* data, 144 unsigned int* len, unsigned int maxLen, void* arg) -> PRBool { 145 SSLInt_SetMTU(fd, 500); // Splits the certificate. 146 return PR_FALSE; 147 }, 148 nullptr, 149 [](PRFileDesc* fd, SSLHandshakeType message, const PRUint8* data, 150 unsigned int len, SSLAlertDescription* alert, 151 void* arg) -> SECStatus { return SECSuccess; }, 152 nullptr)); 153 } 154 155 protected: 156 class DropAckChain { 157 public: 158 DropAckChain() 159 : records_(nullptr), ack_(nullptr), drop_(nullptr), chain_(nullptr) {} 160 161 void Init(const std::shared_ptr<TlsAgent>& agent) { 162 records_ = std::make_shared<TlsRecordRecorder>(agent); 163 ack_ = std::make_shared<TlsRecordRecorder>(agent, ssl_ct_ack); 164 ack_->EnableDecryption(); 165 drop_ = std::make_shared<SelectiveRecordDropFilter>(agent, 0, false); 166 chain_ = std::make_shared<ChainedPacketFilter>( 167 ChainedPacketFilterInit({records_, ack_, drop_})); 168 agent->SetFilter(chain_); 169 } 170 171 const TlsRecord& record(size_t i) const { return records_->record(i); } 172 173 std::shared_ptr<TlsRecordRecorder> records_; 174 std::shared_ptr<TlsRecordRecorder> ack_; 175 std::shared_ptr<SelectiveRecordDropFilter> drop_; 176 std::shared_ptr<PacketFilter> chain_; 177 }; 178 179 void CheckedHandshakeSendReceive() { 180 Handshake(); 181 CheckPostHandshake(); 182 } 183 184 void CheckPostHandshake() { 185 CheckConnected(); 186 SendReceive(); 187 EXPECT_EQ(expected_client_acks_, client_filters_.ack_->count()); 188 EXPECT_EQ(expected_server_acks_, server_filters_.ack_->count()); 189 } 190 191 protected: 192 DropAckChain client_filters_; 193 DropAckChain server_filters_; 194 size_t expected_client_acks_; 195 size_t expected_server_acks_; 196 }; 197 198 // All of these tests produce a minimum one ACK, from the server 199 // to the client upon receiving the client Finished. 200 // Dropping complete first and second flights does not produce 201 // ACKs 202 TEST_P(TlsDropDatagram13, DropClientFirstFlightOnce) { 203 client_filters_.drop_->Reset({0}); 204 // filters only work with particular groups 205 client_->ConfigNamedGroups(kNonPQDHEGroups); 206 StartConnect(); 207 client_->Handshake(); 208 server_->Handshake(); 209 CheckedHandshakeSendReceive(); 210 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 211 } 212 213 TEST_P(TlsDropDatagram13, DropServerFirstFlightOnce) { 214 server_filters_.drop_->Reset(0xff); 215 // filters only work with particular groups 216 server_->ConfigNamedGroups(kNonPQDHEGroups); 217 client_->ConfigNamedGroups(kNonPQDHEGroups); 218 StartConnect(); 219 client_->Handshake(); 220 // Send the first flight, all dropped. 221 server_->Handshake(); 222 server_filters_.drop_->Disable(); 223 CheckedHandshakeSendReceive(); 224 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 225 } 226 227 // Dropping the server's first record also does not produce 228 // an ACK because the next record is ignored. 229 // TODO(ekr@rtfm.com): We should generate an empty ACK. 230 TEST_P(TlsDropDatagram13, DropServerFirstRecordOnce) { 231 server_filters_.drop_->Reset({0}); 232 // filters only work with particular groups 233 server_->ConfigNamedGroups(kNonPQDHEGroups); 234 client_->ConfigNamedGroups(kNonPQDHEGroups); 235 StartConnect(); 236 client_->Handshake(); 237 server_->Handshake(); 238 Handshake(); 239 CheckedHandshakeSendReceive(); 240 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 241 } 242 243 // Dropping the second packet of the server's flight should 244 // produce an ACK. 245 TEST_P(TlsDropDatagram13, DropServerSecondRecordOnce) { 246 server_filters_.drop_->Reset({1}); 247 // filters only work with particular groups 248 server_->ConfigNamedGroups(kNonPQDHEGroups); 249 StartConnect(); 250 client_->Handshake(); 251 server_->Handshake(); 252 HandshakeAndAck(client_); 253 expected_client_acks_ = 1; 254 CheckedHandshakeSendReceive(); 255 CheckAcks(client_filters_.ack_, 0, {0}); // ServerHello 256 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 257 } 258 259 // Drop the server ACK and verify that the client retransmits 260 // the ClientHello. 261 TEST_P(TlsDropDatagram13, DropServerAckOnce) { 262 StartConnect(); 263 client_->Handshake(); 264 server_->Handshake(); 265 // At this point the server has sent it's first flight, 266 // so make it drop the ACK. 267 server_filters_.drop_->Reset({0}); 268 client_->Handshake(); // Send the client Finished. 269 server_->Handshake(); // Receive the Finished and send the ACK. 270 EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); 271 EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); 272 // Wait for the DTLS timeout to make sure we retransmit the 273 // Finished. 274 ShiftDtlsTimers(); 275 client_->Handshake(); // Retransmit the Finished. 276 server_->Handshake(); // Read the Finished and send an ACK. 277 uint8_t buf[1]; 278 PRInt32 rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf)); 279 expected_server_acks_ = 2; 280 EXPECT_GT(0, rv); 281 EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); 282 CheckPostHandshake(); 283 // There should be two copies of the finished ACK 284 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 285 CheckAcks(server_filters_.ack_, 1, {0x0002000000000000ULL}); 286 } 287 288 // Drop the client certificate verify. 289 TEST_P(TlsDropDatagram13, DropClientCertVerify) { 290 StartConnect(); 291 client_->SetupClientAuth(); 292 server_->RequestClientAuth(true); 293 client_->Handshake(); 294 server_->Handshake(); 295 // Have the client drop Cert Verify 296 client_filters_.drop_->Reset({1}); 297 expected_server_acks_ = 2; 298 CheckedHandshakeSendReceive(); 299 // Ack of the Cert. 300 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 301 // Ack of the whole client handshake. 302 CheckAcks( 303 server_filters_.ack_, 1, 304 {0x0002000000000000ULL, // CH (we drop everything after this on client) 305 0x0002000000000003ULL, // CT (2) 306 0x0002000000000004ULL}); // FIN (2) 307 } 308 309 // Shrink the MTU down so that certs get split and drop the first piece. 310 TEST_P(TlsDropDatagram13, DropFirstHalfOfServerCertificate) { 311 server_filters_.drop_->Reset({2}); 312 // filters only work with particular groups 313 server_->ConfigNamedGroups(kNonPQDHEGroups); 314 client_->ConfigNamedGroups(kNonPQDHEGroups); 315 StartConnect(); 316 ShrinkPostServerHelloMtu(); 317 client_->Handshake(); 318 server_->Handshake(); 319 // Check that things got split. 320 EXPECT_EQ(6UL, 321 server_filters_.records_->count()); // SH, EE, CT1, CT2, CV, FIN 322 size_t ct1_size = server_filters_.record(2).buffer.len(); 323 server_filters_.records_->Clear(); 324 expected_client_acks_ = 1; 325 HandshakeAndAck(client_); 326 server_->Handshake(); // Retransmit 327 EXPECT_EQ(3UL, server_filters_.records_->count()); // CT2, CV, FIN 328 // Check that the first record is CT1 (which is identical to the same 329 // as the previous CT1). 330 EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len()); 331 CheckedHandshakeSendReceive(); 332 CheckAcks(client_filters_.ack_, 0, 333 {0, // SH 334 0x0002000000000000ULL, // EE 335 0x0002000000000002ULL}); // CT2 336 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 337 } 338 339 // Shrink the MTU down so that certs get split and drop the second piece. 340 TEST_P(TlsDropDatagram13, DropSecondHalfOfServerCertificate) { 341 server_filters_.drop_->Reset({3}); 342 // filters only work with particular groups 343 server_->ConfigNamedGroups(kNonPQDHEGroups); 344 client_->ConfigNamedGroups(kNonPQDHEGroups); 345 StartConnect(); 346 ShrinkPostServerHelloMtu(); 347 client_->Handshake(); 348 server_->Handshake(); 349 // Check that things got split. 350 EXPECT_EQ(6UL, 351 server_filters_.records_->count()); // SH, EE, CT1, CT2, CV, FIN 352 size_t ct1_size = server_filters_.record(3).buffer.len(); 353 server_filters_.records_->Clear(); 354 expected_client_acks_ = 1; 355 HandshakeAndAck(client_); 356 server_->Handshake(); // Retransmit 357 EXPECT_EQ(3UL, server_filters_.records_->count()); // CT1, CV, FIN 358 // Check that the first record is CT1 359 EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len()); 360 CheckedHandshakeSendReceive(); 361 CheckAcks(client_filters_.ack_, 0, 362 { 363 0, // SH 364 0x0002000000000000ULL, // EE 365 0x0002000000000001ULL, // CT1 366 }); 367 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 368 } 369 370 // In this test, the Certificate message is sent four times, we drop all or part 371 // of the first three attempts: 372 // 1. Without fragmentation so that we can see how big it is - we drop that. 373 // 2. In two pieces - we drop half AND the resulting ACK. 374 // 3. In three pieces - we drop the middle piece. 375 // 376 // After that we let all the ACKs through and allow the handshake to complete 377 // without further interference. 378 // 379 // This allows us to test that ranges of handshake messages are sent correctly 380 // even when there are overlapping acknowledgments; that ACKs with duplicate or 381 // overlapping message ranges are handled properly; and that extra 382 // retransmissions are handled properly. 383 class TlsFragmentationAndRecoveryTest : public TlsDropDatagram13 { 384 public: 385 TlsFragmentationAndRecoveryTest() : cert_len_(0) {} 386 387 protected: 388 void RunTest(size_t dropped_half) { 389 FirstFlightDropCertificate(); 390 391 SecondAttemptDropHalf(dropped_half); 392 size_t dropped_half_size = server_record_len(dropped_half); 393 size_t second_flight_count = server_filters_.records_->count(); 394 395 ThirdAttemptDropMiddle(); 396 size_t repaired_third_size = server_record_len((dropped_half == 0) ? 0 : 2); 397 size_t third_flight_count = server_filters_.records_->count(); 398 399 AckAndCompleteRetransmission(); 400 size_t final_server_flight_count = server_filters_.records_->count(); 401 EXPECT_LE(3U, final_server_flight_count); // CT(sixth), CV, Fin 402 CheckSizeOfSixth(dropped_half_size, repaired_third_size); 403 404 SendDelayedAck(); 405 // Same number of messages as the last flight. 406 EXPECT_EQ(final_server_flight_count, server_filters_.records_->count()); 407 // Double check that the Certificate size is still correct. 408 CheckSizeOfSixth(dropped_half_size, repaired_third_size); 409 410 CompleteHandshake(final_server_flight_count); 411 412 // This is the ACK for the first attempt to send a whole certificate. 413 std::vector<uint64_t> client_acks = { 414 0, // SH 415 0x0002000000000000ULL // EE 416 }; 417 CheckAcks(client_filters_.ack_, 0, client_acks); 418 // And from the second attempt for the half was kept (we delayed this ACK). 419 client_acks.push_back(0x0002000000000000ULL + second_flight_count + 420 ~dropped_half % 2); 421 CheckAcks(client_filters_.ack_, 1, client_acks); 422 // And the third attempt where the first and last thirds got through. 423 client_acks.push_back(0x0002000000000000ULL + second_flight_count + 424 third_flight_count - 1); 425 client_acks.push_back(0x0002000000000000ULL + second_flight_count + 426 third_flight_count + 1); 427 CheckAcks(client_filters_.ack_, 2, client_acks); 428 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 429 } 430 431 private: 432 void FirstFlightDropCertificate() { 433 // filters only work with particular groups 434 server_->ConfigNamedGroups(kNonPQDHEGroups); 435 client_->ConfigNamedGroups(kNonPQDHEGroups); 436 StartConnect(); 437 client_->Handshake(); 438 439 // Note: 1 << N is the Nth packet, starting from zero. 440 server_filters_.drop_->Reset(1 << 2); // Drop Cert0. 441 server_->Handshake(); 442 EXPECT_EQ(5U, server_filters_.records_->count()); // SH, EE, CT, CV, Fin 443 cert_len_ = server_filters_.records_->record(2).buffer.len(); 444 445 HandshakeAndAck(client_); 446 EXPECT_EQ(2U, client_filters_.records_->count()); 447 } 448 449 // Lower the MTU so that the server has to split the certificate in two 450 // pieces. The server resends Certificate (in two), plus CV and Fin. 451 void SecondAttemptDropHalf(size_t dropped_half) { 452 ASSERT_LE(0U, dropped_half); 453 ASSERT_GT(2U, dropped_half); 454 server_filters_.records_->Clear(); 455 server_filters_.drop_->Reset({dropped_half}); // Drop Cert1[half] 456 SplitServerMtu(2); 457 server_->Handshake(); 458 EXPECT_LE(4U, server_filters_.records_->count()); // CT x2, CV, Fin 459 460 // Generate and capture the ACK from the client. 461 client_filters_.drop_->Reset({0}); 462 HandshakeAndAck(client_); 463 EXPECT_EQ(3U, client_filters_.records_->count()); 464 } 465 466 // Lower the MTU again so that the server sends Certificate cut into three 467 // pieces. Drop the middle piece. 468 void ThirdAttemptDropMiddle() { 469 server_filters_.records_->Clear(); 470 server_filters_.drop_->Reset({1}); // Drop Cert2[1] (of 3) 471 SplitServerMtu(3); 472 // Because we dropped the client ACK, the server retransmits on a timer. 473 ShiftDtlsTimers(); 474 server_->Handshake(); 475 EXPECT_LE(5U, server_filters_.records_->count()); // CT x3, CV, Fin 476 } 477 478 void AckAndCompleteRetransmission() { 479 // Generate ACKs. 480 HandshakeAndAck(client_); 481 // The server should send the final sixth of the certificate: the client has 482 // acknowledged the first half and the last third. Also send CV and Fin. 483 server_filters_.records_->Clear(); 484 server_->Handshake(); 485 } 486 487 void CheckSizeOfSixth(size_t size_of_half, size_t size_of_third) { 488 // Work out if the final sixth is the right size. We get the records with 489 // overheads added, which obscures the length of the payload. We want to 490 // ensure that the server only sent the missing sixth of the Certificate. 491 // 492 // We captured |size_of_half + overhead| and |size_of_third + overhead| and 493 // want to calculate |size_of_third - size_of_third + overhead|. We can't 494 // calculate |overhead|, but it is is (currently) always a handshake message 495 // header, a content type, and an authentication tag: 496 static const size_t record_overhead = 12 + 1 + 16; 497 EXPECT_EQ(size_of_half - size_of_third + record_overhead, 498 server_filters_.records_->record(0).buffer.len()); 499 } 500 501 void SendDelayedAck() { 502 // Send the ACK we held back. The reordered ACK doesn't add new 503 // information, 504 // but triggers an extra retransmission of the missing records again (even 505 // though the client has all that it needs). 506 client_->SendRecordDirect(client_filters_.records_->record(2)); 507 server_filters_.records_->Clear(); 508 server_->Handshake(); 509 } 510 511 void CompleteHandshake(size_t extra_retransmissions) { 512 // All this messing around shouldn't cause a failure... 513 Handshake(); 514 // ...but it leaves a mess. Add an extra few calls to Handshake() for the 515 // client so that it absorbs the extra retransmissions. 516 for (size_t i = 0; i < extra_retransmissions; ++i) { 517 client_->Handshake(); 518 } 519 CheckConnected(); 520 } 521 522 // Split the server MTU so that the Certificate is split into |count| pieces. 523 // The calculation doesn't need to be perfect as long as the Certificate 524 // message is split into the right number of pieces. 525 void SplitServerMtu(size_t count) { 526 // Set the MTU based on the formula: 527 // bare_size = cert_len_ - actual_overhead 528 // MTU = ceil(bare_size / count) + pessimistic_overhead 529 // 530 // actual_overhead is the amount of actual overhead on the record we 531 // captured, which is (note that our length doesn't include the header): 532 static const size_t actual_overhead = 12 + // handshake message header 533 1 + // content type 534 16; // authentication tag 535 size_t bare_size = cert_len_ - actual_overhead; 536 537 // pessimistic_overhead is the amount of expansion that NSS assumes will be 538 // added to each handshake record. Right now, that is DTLS_MIN_FRAGMENT: 539 static const size_t pessimistic_overhead = 540 12 + // handshake message header 541 1 + // content type 542 13 + // record header length 543 64; // maximum record expansion: IV, MAC and block cipher expansion 544 545 size_t mtu = (bare_size + count - 1) / count + pessimistic_overhead; 546 if (g_ssl_gtest_verbose) { 547 std::cerr << "server: set MTU to " << mtu << std::endl; 548 } 549 EXPECT_EQ(SECSuccess, SSLInt_SetMTU(server_->ssl_fd(), mtu)); 550 } 551 552 size_t server_record_len(size_t index) const { 553 return server_filters_.records_->record(index).buffer.len(); 554 } 555 556 size_t cert_len_; 557 }; 558 559 TEST_P(TlsFragmentationAndRecoveryTest, DropFirstHalf) { RunTest(0); } 560 561 TEST_P(TlsFragmentationAndRecoveryTest, DropSecondHalf) { RunTest(1); } 562 563 TEST_P(TlsDropDatagram13, NoDropsDuringZeroRtt) { 564 SetupForZeroRtt(); 565 SetFilters(); 566 std::cerr << "Starting second handshake" << std::endl; 567 client_->Set0RttEnabled(true); 568 server_->Set0RttEnabled(true); 569 ExpectResumption(RESUME_TICKET); 570 ZeroRttSendReceive(true, true); 571 Handshake(); 572 ExpectEarlyDataAccepted(true); 573 CheckConnected(); 574 SendReceive(); 575 EXPECT_EQ(0U, client_filters_.ack_->count()); 576 CheckAcks(server_filters_.ack_, 0, 577 {0x0001000000000001ULL, // EOED 578 0x0002000000000000ULL}); // Finished 579 } 580 581 TEST_P(TlsDropDatagram13, DropEEDuringZeroRtt) { 582 SetupForZeroRtt(); 583 // filters only work with particular groups 584 server_->ConfigNamedGroups(kNonPQDHEGroups); 585 client_->ConfigNamedGroups(kNonPQDHEGroups); 586 SetFilters(); 587 std::cerr << "Starting second handshake" << std::endl; 588 client_->Set0RttEnabled(true); 589 server_->Set0RttEnabled(true); 590 ExpectResumption(RESUME_TICKET); 591 server_filters_.drop_->Reset({1}); 592 ZeroRttSendReceive(true, true); 593 HandshakeAndAck(client_); 594 Handshake(); 595 ExpectEarlyDataAccepted(true); 596 CheckConnected(); 597 SendReceive(); 598 CheckAcks(client_filters_.ack_, 0, {0}); 599 CheckAcks(server_filters_.ack_, 0, 600 {0x0001000000000002ULL, // EOED 601 0x0002000000000000ULL}); // Finished 602 } 603 604 class TlsReorderDatagram13 : public TlsDropDatagram13 { 605 public: 606 TlsReorderDatagram13() {} 607 608 // Send records from the records buffer in the given order. 609 void ReSend(TlsAgent::Role side, std::vector<size_t> indices) { 610 std::shared_ptr<TlsAgent> agent; 611 std::shared_ptr<TlsRecordRecorder> records; 612 613 if (side == TlsAgent::CLIENT) { 614 agent = client_; 615 records = client_filters_.records_; 616 } else { 617 agent = server_; 618 records = server_filters_.records_; 619 } 620 621 for (auto i : indices) { 622 agent->SendRecordDirect(records->record(i)); 623 } 624 } 625 }; 626 627 // Reorder the server records so that EE comes at the end 628 // of the flight and will still produce an ACK. 629 TEST_P(TlsDropDatagram13, ReorderServerEE) { 630 server_filters_.drop_->Reset({1}); 631 // filters only work with particular groups 632 server_->ConfigNamedGroups(kNonPQDHEGroups); 633 client_->ConfigNamedGroups(kNonPQDHEGroups); 634 StartConnect(); 635 client_->Handshake(); 636 server_->Handshake(); 637 // We dropped EE, now reinject. 638 server_->SendRecordDirect(server_filters_.record(1)); 639 expected_client_acks_ = 1; 640 HandshakeAndAck(client_); 641 CheckedHandshakeSendReceive(); 642 CheckAcks(client_filters_.ack_, 0, 643 { 644 0, // SH 645 0x0002000000000000, // EE 646 }); 647 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 648 } 649 650 // The client sends an out of order non-handshake message 651 // but with the handshake key. 652 TEST_F(TlsConnectDatagram13, SendOutOfOrderAppWithHandshakeKey) { 653 StartConnect(); 654 // Capturing secrets means that we can't use decrypting filters on the client. 655 TlsSendCipherSpecCapturer capturer(client_); 656 client_->Handshake(); 657 server_->Handshake(); 658 client_->Handshake(); 659 EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); 660 server_->Handshake(); 661 EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); 662 // After the client sends Finished, inject an app data record 663 // with the handshake key. This should produce an alert. 664 uint8_t buf[] = {'a', 'b', 'c'}; 665 auto spec = capturer.spec(0); 666 ASSERT_NE(nullptr, spec.get()); 667 ASSERT_EQ(2, spec->epoch()); 668 669 uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno | 670 kCtDtlsCiphertextLengthPresent; 671 ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002, dtls13_ct, 672 DataBuffer(buf, sizeof(buf)))); 673 674 // Now have the server consume the bogus message. 675 server_->ExpectSendAlert(illegal_parameter, kTlsAlertFatal); 676 server_->Handshake(); 677 EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state()); 678 EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, PORT_GetError()); 679 } 680 681 TEST_F(TlsConnectDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) { 682 StartConnect(); 683 TlsSendCipherSpecCapturer capturer(client_); 684 auto acks = MakeTlsFilter<TlsRecordRecorder>(server_, ssl_ct_ack); 685 acks->EnableDecryption(); 686 687 client_->Handshake(); 688 server_->Handshake(); 689 client_->Handshake(); 690 EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); 691 server_->Handshake(); 692 EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state()); 693 // Inject a new bogus handshake record, which the server responds 694 // to by just ACKing the original one (we ignore the contents). 695 uint8_t buf[] = {'a', 'b', 'c'}; 696 auto spec = capturer.spec(0); 697 ASSERT_NE(nullptr, spec.get()); 698 ASSERT_EQ(2, spec->epoch()); 699 ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002, 700 ssl_ct_handshake, 701 DataBuffer(buf, sizeof(buf)))); 702 server_->Handshake(); 703 EXPECT_EQ(2UL, acks->count()); 704 // The server acknowledges client Finished twice. 705 CheckAcks(acks, 0, {0x0002000000000000ULL}); 706 CheckAcks(acks, 1, {0x0002000000000000ULL}); 707 } 708 709 // Shrink the MTU down so that certs get split and then swap the first and 710 // second pieces of the server certificate. 711 TEST_P(TlsReorderDatagram13, ReorderServerCertificate) { 712 // filters only work with particular groups 713 server_->ConfigNamedGroups(kNonPQDHEGroups); 714 client_->ConfigNamedGroups(kNonPQDHEGroups); 715 StartConnect(); 716 ShrinkPostServerHelloMtu(); 717 client_->Handshake(); 718 // Drop the entire handshake flight so we can reorder. 719 server_filters_.drop_->Reset(0xff); 720 server_->Handshake(); 721 // Check that things got split. 722 EXPECT_EQ(6UL, 723 server_filters_.records_->count()); // CH, EE, CT1, CT2, CV, FIN 724 // Now re-send things in a different order. 725 ReSend(TlsAgent::SERVER, std::vector<size_t>{0, 1, 3, 2, 4, 5}); 726 // Clear. 727 server_filters_.drop_->Disable(); 728 server_filters_.records_->Clear(); 729 // Wait for client to send ACK. 730 ShiftDtlsTimers(); 731 CheckedHandshakeSendReceive(); 732 EXPECT_EQ(2UL, server_filters_.records_->count()); // ACK + Data 733 CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL}); 734 } 735 736 TEST_P(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) { 737 SetupForZeroRtt(); 738 SetFilters(); 739 std::cerr << "Starting second handshake" << std::endl; 740 client_->Set0RttEnabled(true); 741 server_->Set0RttEnabled(true); 742 ExpectResumption(RESUME_TICKET); 743 // Send the client's first flight of zero RTT data. 744 ZeroRttSendReceive(true, true); 745 // Now send another client application data record but 746 // capture it. 747 client_filters_.records_->Clear(); 748 client_filters_.drop_->Reset(0xff); 749 const char* k0RttData = "123456"; 750 const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); 751 PRInt32 rv = 752 PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write. 753 EXPECT_EQ(k0RttDataLen, rv); 754 EXPECT_EQ(1UL, client_filters_.records_->count()); // data 755 server_->Handshake(); 756 client_->Handshake(); 757 ExpectEarlyDataAccepted(true); 758 // The server still hasn't received anything at this point. 759 EXPECT_EQ(3UL, client_filters_.records_->count()); // data, EOED, FIN 760 EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); 761 EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); 762 // Now re-send the client's messages: EOED, data, FIN 763 ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 0, 2})); 764 server_->Handshake(); 765 CheckConnected(); 766 EXPECT_EQ(0U, client_filters_.ack_->count()); 767 // Acknowledgements for EOED and Finished. 768 CheckAcks(server_filters_.ack_, 0, 769 {0x0001000000000002ULL, 0x0002000000000000ULL}); 770 uint8_t buf[8]; 771 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf)); 772 EXPECT_EQ(-1, rv); 773 EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); 774 } 775 776 TEST_P(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) { 777 SetupForZeroRtt(); 778 SetFilters(); 779 std::cerr << "Starting second handshake" << std::endl; 780 client_->Set0RttEnabled(true); 781 server_->Set0RttEnabled(true); 782 ExpectResumption(RESUME_TICKET); 783 // Send the client's first flight of zero RTT data. 784 ZeroRttSendReceive(true, true); 785 // Now send another client application data record but 786 // capture it. 787 client_filters_.records_->Clear(); 788 client_filters_.drop_->Reset(0xff); 789 const char* k0RttData = "123456"; 790 const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData)); 791 PRInt32 rv = 792 PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen); // 0-RTT write. 793 EXPECT_EQ(k0RttDataLen, rv); 794 EXPECT_EQ(1UL, client_filters_.records_->count()); // data 795 server_->Handshake(); 796 client_->Handshake(); 797 ExpectEarlyDataAccepted(true); 798 // The server still hasn't received anything at this point. 799 EXPECT_EQ(3UL, client_filters_.records_->count()); // EOED, FIN, Data 800 EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); 801 EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state()); 802 // Now re-send the client's messages: EOED, FIN, Data 803 ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 2, 0})); 804 server_->Handshake(); 805 CheckConnected(); 806 EXPECT_EQ(0U, client_filters_.ack_->count()); 807 // Acknowledgements for EOED and Finished. 808 CheckAcks(server_filters_.ack_, 0, 809 {0x0001000000000002ULL, 0x0002000000000000ULL}); 810 uint8_t buf[8]; 811 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf)); 812 EXPECT_EQ(-1, rv); 813 EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); 814 } 815 816 static void GetCipherAndLimit(uint16_t version, uint16_t* cipher, 817 uint64_t* limit = nullptr) { 818 uint64_t l; 819 if (!limit) limit = &l; 820 821 if (version < SSL_LIBRARY_VERSION_TLS_1_2) { 822 *cipher = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; 823 *limit = 0x5aULL << 28; 824 } else if (version == SSL_LIBRARY_VERSION_TLS_1_2) { 825 *cipher = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256; 826 *limit = (1ULL << 48) - 1; 827 } else { 828 // This test probably isn't especially useful for TLS 1.3, which has a much 829 // shorter sequence number encoding. That space can probably be searched in 830 // a reasonable amount of time. 831 *cipher = TLS_CHACHA20_POLY1305_SHA256; 832 // Assume that we are starting with an expected sequence number of 0. 833 *limit = (1ULL << 15) - 1; 834 } 835 } 836 837 // This simulates a huge number of drops on one side. 838 // See Bug 12965514 where a large gap was handled very inefficiently. 839 TEST_P(TlsConnectDatagram, MissLotsOfPackets) { 840 uint16_t cipher; 841 uint64_t limit; 842 843 GetCipherAndLimit(version_, &cipher, &limit); 844 845 EnsureTlsSetup(); 846 server_->EnableSingleCipher(cipher); 847 Connect(); 848 849 // Note that the limit for ChaCha is 2^48-1. 850 EXPECT_EQ(SECSuccess, 851 SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), limit - 10)); 852 SendReceive(); 853 } 854 855 // Send a sequence number of 0xfffd and it should be interpreted as that 856 // (and not -3 or UINT64_MAX - 2). 857 TEST_F(TlsConnectDatagram13, UnderflowSequenceNumber) { 858 Connect(); 859 // This is only valid if short headers are disabled. 860 client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, PR_FALSE); 861 EXPECT_EQ(SECSuccess, 862 SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), (1ULL << 16) - 3)); 863 SendReceive(); 864 } 865 866 class TlsConnectDatagram12Plus : public TlsConnectDatagram { 867 public: 868 TlsConnectDatagram12Plus() : TlsConnectDatagram() {} 869 }; 870 871 // This simulates missing a window's worth of packets. 872 TEST_P(TlsConnectDatagram12Plus, MissAWindow) { 873 EnsureTlsSetup(); 874 uint16_t cipher; 875 GetCipherAndLimit(version_, &cipher); 876 server_->EnableSingleCipher(cipher); 877 Connect(); 878 EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqByAWindow(client_->ssl_fd(), 0)); 879 SendReceive(); 880 } 881 882 TEST_P(TlsConnectDatagram12Plus, MissAWindowAndOne) { 883 EnsureTlsSetup(); 884 uint16_t cipher; 885 GetCipherAndLimit(version_, &cipher); 886 server_->EnableSingleCipher(cipher); 887 Connect(); 888 889 EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqByAWindow(client_->ssl_fd(), 1)); 890 SendReceive(); 891 } 892 893 // This filter replaces the first record it sees with junk application data. 894 class TlsReplaceFirstRecordWithJunk : public TlsRecordFilter { 895 public: 896 TlsReplaceFirstRecordWithJunk(const std::shared_ptr<TlsAgent>& a) 897 : TlsRecordFilter(a), replaced_(false) {} 898 899 protected: 900 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 901 const DataBuffer& record, size_t* offset, 902 DataBuffer* output) override { 903 if (replaced_) { 904 return KEEP; 905 } 906 replaced_ = true; 907 908 uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno | 909 kCtDtlsCiphertextLengthPresent; 910 TlsRecordHeader out_header( 911 header.variant(), header.version(), 912 is_dtls13() ? dtls13_ct : ssl_ct_application_data, 913 header.sequence_number()); 914 915 static const uint8_t junk[] = {1, 2, 3, 4}; 916 *offset = out_header.Write(output, *offset, DataBuffer(junk, sizeof(junk))); 917 return CHANGE; 918 } 919 920 private: 921 bool replaced_; 922 }; 923 924 // DTLS needs to discard application_data that it receives prior to handshake 925 // completion, not generate an error. 926 TEST_P(TlsConnectDatagram, ReplaceFirstServerRecordWithApplicationData) { 927 MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(server_); 928 Connect(); 929 } 930 931 TEST_P(TlsConnectDatagram, ReplaceFirstClientRecordWithApplicationData) { 932 MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(client_); 933 Connect(); 934 } 935 936 INSTANTIATE_TEST_SUITE_P(Datagram12Plus, TlsConnectDatagram12Plus, 937 TlsConnectTestBase::kTlsV12Plus); 938 INSTANTIATE_TEST_SUITE_P(DatagramPre13, TlsConnectDatagramPre13, 939 TlsConnectTestBase::kTlsV11V12); 940 INSTANTIATE_TEST_SUITE_P(DatagramDrop13, TlsDropDatagram13, 941 ::testing::Values(true, false)); 942 INSTANTIATE_TEST_SUITE_P(DatagramReorder13, TlsReorderDatagram13, 943 ::testing::Values(true, false)); 944 INSTANTIATE_TEST_SUITE_P(DatagramFragment13, TlsFragmentationAndRecoveryTest, 945 ::testing::Values(true, false)); 946 947 class FirstDropThenKeepHandshakeFilter : public TlsHandshakeFilter { 948 public: 949 FirstDropThenKeepHandshakeFilter(const std::shared_ptr<TlsAgent>& a) 950 : TlsHandshakeFilter(a) {} 951 952 virtual PacketFilter::Action FilterHandshake( 953 const TlsHandshakeFilter::HandshakeHeader& header, 954 const DataBuffer& input, DataBuffer* output) { 955 if (enabled) { 956 return KEEP; 957 } else { 958 enabled = true; 959 return DROP; 960 } 961 } 962 963 private: 964 bool enabled = false; 965 }; 966 967 // This test is responsible for checking that when DTLS fragments the message, 968 // the hanshake will be successfully reconstructed, but if one of handshakes 969 // was dropped, they are not going to be glued all together. 970 971 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1874451 972 TEST_F(TlsConnectDatagram13, PreviousHandshakeRemovedWhenDropped) { 973 EnsureTlsSetup(); 974 static const std::vector<SSLNamedGroup> client_groups = { 975 ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1, ssl_grp_ec_curve25519}; 976 client_->ConfigNamedGroups(client_groups); 977 // Ensure that the message is indeed longer than the MTU we install. 978 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 2)); 979 980 SSLInt_SetMTU(client_->ssl_fd(), 150); 981 auto filter = MakeTlsFilter<FirstDropThenKeepHandshakeFilter>(client_); 982 Connect(); 983 } 984 985 } // namespace nss_test