ssl_certificate_compression_unittest.cc (57916B)
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 #include "secerr.h" 7 #include "ssl.h" 8 #include "sslerr.h" 9 #include "sslproto.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 class TLSCertificateCompressionExtensionCatcher : public TlsExtensionFilter { 25 public: 26 TLSCertificateCompressionExtensionCatcher(const std::shared_ptr<TlsAgent>& a) 27 : TlsExtensionFilter(a), 28 received_compressed_certificate_extension_(false){}; 29 30 PacketFilter::Action FilterExtension(uint16_t extension_type, 31 const DataBuffer& input, 32 DataBuffer* output) { 33 if (extension_type != ssl_certificate_compression_xtn) { 34 return KEEP; 35 } 36 received_compressed_certificate_extension_ = true; 37 38 /* struct { 39 * CertificateCompressionAlgorithm algorithms<2..2^8-2>; 40 * } CertificateCompressionAlgorithms; 41 */ 42 uint32_t numberOfExtensions = input.data()[0]; 43 algorithms = DataBuffer(&input.data()[1], numberOfExtensions); 44 return KEEP; 45 } 46 47 DataBuffer GetBufCompressionAlgs() { return algorithms; } 48 49 bool sawCertificateCompressionExtension() { 50 return received_compressed_certificate_extension_; 51 } 52 53 private: 54 DataBuffer algorithms; 55 bool received_compressed_certificate_extension_; 56 }; 57 58 class TLSCertificateCompressionExtensionModifier : public TlsExtensionFilter { 59 public: 60 TLSCertificateCompressionExtensionModifier(const std::shared_ptr<TlsAgent>& a, 61 uint8_t byte, uint8_t value) 62 : TlsExtensionFilter(a), offset_(byte), value_(value){}; 63 64 PacketFilter::Action FilterExtension(uint16_t extension_type, 65 const DataBuffer& input, 66 DataBuffer* output) { 67 if (extension_type != ssl_certificate_compression_xtn) { 68 return KEEP; 69 } 70 71 *output = input; 72 output->data()[offset_] = value_; 73 return CHANGE; 74 } 75 76 private: 77 uint8_t offset_; 78 uint8_t value_; 79 }; 80 81 /* The function returns a reference to a message of the following Handshake 82 * Type. */ 83 uint64_t findPointerToHandshakeType(DataBuffer plaintext, SSLHandshakeType t) { 84 uint64_t skip = 0; 85 /* struct { 86 ** HandshakeType msg_type; 87 ** uint24 length; 88 ** select (Handshake.msg_type) { 89 ** case client_hello: ClientHello;... 90 ** }; 91 ** } Handshake; 92 */ 93 while (skip < plaintext.len() && plaintext.data()[skip] != t) { 94 skip = skip + 1 /* HandshakeType */ + 3 /* length */ 95 + (plaintext.data()[skip + 1 /* Handshake.msg_type */] << 16) + 96 (plaintext.data()[skip + 2] << 8) + (plaintext.data()[skip + 3]); 97 } 98 99 return skip; 100 } 101 102 class TLSCertificateCompressionCertificateCatcher : public TlsRecordFilter { 103 public: 104 TLSCertificateCompressionCertificateCatcher( 105 const std::shared_ptr<TlsAgent>& a) 106 : TlsRecordFilter(a) { 107 received_compressed_certificate_ = false; 108 used_compression_algorithm_ = 0x0; 109 EnableDecryption(); 110 } 111 112 bool sawCompressedCertificate() { return received_compressed_certificate_; } 113 uint16_t getCertCompressionAlg() { return used_compression_algorithm_; } 114 void unsetSawCompressedCertificate() { 115 received_compressed_certificate_ = false; 116 } 117 118 protected: 119 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 120 const DataBuffer& record, size_t* offset, 121 DataBuffer* output) override { 122 uint8_t inner_content_type; 123 DataBuffer plaintext; 124 uint16_t protection_epoch = 0; 125 TlsRecordHeader out_header(header); 126 127 if (!Unprotect(header, record, &protection_epoch, &inner_content_type, 128 &plaintext, &out_header)) { 129 return KEEP; 130 } 131 132 uint64_t skip = 133 findPointerToHandshakeType(plaintext, ssl_hs_compressed_certificate); 134 if (skip >= plaintext.len() || 135 plaintext.data()[skip] != ssl_hs_compressed_certificate) { 136 return KEEP; 137 } 138 139 skip = skip + 1 /* HandshakeType */ + 3 /* length */; 140 if (skip + 1 >= plaintext.len()) { 141 return KEEP; 142 } 143 used_compression_algorithm_ = 144 (plaintext.data()[skip] << 8) + plaintext.data()[skip + 1]; 145 received_compressed_certificate_ = true; 146 return KEEP; 147 } 148 149 private: 150 bool received_compressed_certificate_; 151 uint16_t used_compression_algorithm_; 152 }; 153 154 class TLSCertificateToEncodedCertificateChanger : public TlsRecordFilter { 155 public: 156 TLSCertificateToEncodedCertificateChanger(const std::shared_ptr<TlsAgent>& a) 157 : TlsRecordFilter(a) { 158 EnableDecryption(); 159 } 160 161 protected: 162 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 163 const DataBuffer& record, size_t* offset, 164 DataBuffer* output) override { 165 uint8_t inner_content_type; 166 DataBuffer plaintext; 167 uint16_t protection_epoch = 0; 168 TlsRecordHeader out_header(header); 169 170 if (!Unprotect(header, record, &protection_epoch, &inner_content_type, 171 &plaintext, &out_header)) { 172 return KEEP; 173 } 174 175 uint64_t skip = findPointerToHandshakeType(plaintext, ssl_hs_certificate); 176 if (skip >= plaintext.len() || 177 plaintext.data()[skip] != ssl_hs_certificate) { 178 return KEEP; 179 } 180 181 DataBuffer plaintextEncodedCert(plaintext); 182 /* ssl_hs_certificate -> ssl_hs_compressed_certificate */ 183 plaintextEncodedCert.data()[skip] = ssl_hs_compressed_certificate; 184 /* Next 3 bytes are length*/ 185 uint32_t certificateLen = (plaintext.data()[skip + 1] << 16) + 186 (plaintext.data()[skip + 2] << 8) + 187 plaintext.data()[skip + 3]; 188 189 /* Random Encoding*/ 190 const uint8_t encodingId[2] = {0xff, 0x01}; 191 /* struct { 192 CertificateCompressionAlgorithm algorithm; 193 uint24 uncompressed_length; 194 opaque compressed_certificate_message<1..2^24-1>; 195 } CompressedCertificate; */ 196 197 plaintextEncodedCert.Write(skip + 1, certificateLen + 5, 198 3); // 2 bytes for algorithm + 3 bytes for len 199 plaintextEncodedCert.Write(skip + 4, (const uint8_t*)&encodingId, 2); 200 /* the uncompressed_length (the same as we did not change the length of the 201 * cert) */ 202 plaintextEncodedCert.Write(skip + 6, certificateLen, 3); 203 /* Copy the rest of the certificate. */ 204 plaintextEncodedCert.Write(skip + 9, 205 (const uint8_t*)&plaintext.data()[skip + 4], 206 plaintext.len() - skip - 4); 207 208 DataBuffer ciphertext; 209 bool ok = Protect(spec(protection_epoch), out_header, inner_content_type, 210 plaintextEncodedCert, &ciphertext, &out_header); 211 EXPECT_TRUE(ok); 212 if (!ok) { 213 return KEEP; 214 } 215 *offset = out_header.Write(output, *offset, ciphertext); 216 return CHANGE; 217 } 218 }; 219 220 /* Test encoding function. */ 221 static SECStatus SimpleXorCertCompEncode(const SECItem* input, 222 SECItem* output) { 223 SECITEM_CopyItem(NULL, output, input); 224 PORT_Memcpy(output->data, input->data, output->len); 225 for (size_t i = 0; i < output->len; i++) { 226 output->data[i] ^= 0x55; 227 } 228 return SECSuccess; 229 } 230 231 /* Test decoding function. */ 232 static SECStatus SimpleXorCertCompDecode(const SECItem* input, uint8_t* output, 233 size_t outputLen, 234 size_t* receivedOutputLen) { 235 if (input->len != outputLen) { 236 return SECFailure; 237 } 238 239 PORT_Memcpy(output, input->data, input->len); 240 for (size_t i = 0; i < outputLen; i++) { 241 output[i] ^= 0x55; 242 } 243 *receivedOutputLen = outputLen; 244 245 return SECSuccess; 246 } 247 248 static SECStatus SimpleXorWithDifferentValueEncode(const SECItem* input, 249 SECItem* output) { 250 SECITEM_CopyItem(NULL, output, input); 251 for (size_t i = 0; i < output->len; i++) { 252 output->data[i] ^= 0x77; 253 } 254 return SECSuccess; 255 } 256 257 /* Test decoding function. */ 258 static SECStatus SimpleXorWithDifferentValueDecode(const SECItem* input, 259 uint8_t* output, 260 size_t outputLen, 261 size_t* receivedOutputLen) { 262 if (input->len != outputLen) { 263 return SECFailure; 264 } 265 266 PORT_Memcpy(output, input->data, input->len); 267 for (size_t i = 0; i < outputLen; i++) { 268 output[i] ^= 0x77; 269 } 270 *receivedOutputLen = outputLen; 271 272 return SECSuccess; 273 } 274 275 /* These tests are checking the behaviour 276 * using the different compression algorithms. 277 * 278 * struct { 279 * CertificateCompressionAlgorithm algorithms<2..2^8-2>; 280 * } CertificateCompressionAlgorithms; 281 * 282 * The "extension_data" field of this extension 283 * SHALL contain a CertificateCompressionAlgorithms value: 284 * enum { 285 * zlib(1), 286 * brotli(2), 287 * zstd(3), 288 * (65535) 289 * } CertificateCompressionAlgorithm; 290 */ 291 292 /* Algorithm number 0 is reserved. If we receive it, we ignore this algorithm: 293 * 1) We do not return a failure if we encountered it 294 * 2) If it was the only certificate compression algorithm, we consider that we 295 * did not negotiate the extension 296 * 3) If there were the other agorithms, the 297 * extension is negotiated if one of the other algorithms is supported by the 298 * both parties. 299 */ 300 301 /* We can not add an algorithm with empty encoding/decoding function. */ 302 TEST_F(TlsConnectStreamTls13, 303 CertificateCompression_CannotAddAlgorithmEmptyEncodingAndDecoding) { 304 EnsureTlsSetup(); 305 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", NULL, NULL}; 306 307 EXPECT_EQ(SECFailure, 308 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 309 } 310 311 /* We can not add an algorithm with reserved id. */ 312 TEST_F(TlsConnectStreamTls13, 313 CertificateCompression_CannotAddAlgorithmWithReservedID) { 314 EnsureTlsSetup(); 315 SSLCertificateCompressionAlgorithm t = { 316 0, "test function", SimpleXorCertCompEncode, SimpleXorCertCompDecode}; 317 318 EXPECT_EQ(SECFailure, 319 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 320 } 321 322 /* We can add an algorithm with the ID already existed. 323 * In this case the previous algorithm will be re-written. 324 */ 325 TEST_F(TlsConnectStreamTls13, CertificateCompression_AddingAlreadyExistingAlg) { 326 EnsureTlsSetup(); 327 328 SSLCertificateCompressionAlgorithm alg_ff01 = {0xff01, "test function", 329 SimpleXorCertCompEncode, 330 SimpleXorCertCompDecode}; 331 332 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 333 client_->ssl_fd(), alg_ff01)); 334 335 EXPECT_EQ(SECFailure, SSLExp_SetCertificateCompressionAlgorithm( 336 client_->ssl_fd(), alg_ff01)); 337 } 338 339 /* The test modifies the length of the compression certificates algorithms 340 * supported by a server. Each identifier of CertificateCompressionAlgorithm is 341 * 2 bytes, so the odd length is incorrect. 342 */ 343 TEST_F(TlsConnectStreamTls13, CertificateCompression_LengthIsOdd) { 344 EnsureTlsSetup(); 345 SSLCertificateCompressionAlgorithm alg_ff01 = {0xff01, "test function", 346 SimpleXorCertCompEncode, 347 SimpleXorCertCompDecode}; 348 349 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 350 server_->ssl_fd(), alg_ff01)); 351 352 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 353 client_->ssl_fd(), alg_ff01)); 354 355 auto filterExtension = 356 MakeTlsFilter<TLSCertificateCompressionExtensionModifier>(client_, 0, 1); 357 filterExtension->EnableDecryption(); 358 359 ExpectAlert(client_, kTlsAlertDecodeError); 360 ConnectExpectAlert(server_, kTlsAlertDecodeError); 361 362 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 363 client_->ExpectSendAlert(kTlsAlertCloseNotify); 364 365 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 366 ssl_certificate_compression_xtn)); 367 368 server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); 369 client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT); 370 } 371 372 /* The test checks that the extension is not negotiated if in the ClientHello 373 * the extension length is bigger than the actual length of the extension. 374 */ 375 TEST_F(TlsConnectStreamTls13, 376 CertificateCompression_LengthIsBiggerThanExpected) { 377 EnsureTlsSetup(); 378 379 SSLCertificateCompressionAlgorithm alg_ff01 = {0xff01, "test function", 380 SimpleXorCertCompEncode, 381 SimpleXorCertCompDecode}; 382 383 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 384 server_->ssl_fd(), alg_ff01)); 385 386 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 387 client_->ssl_fd(), alg_ff01)); 388 389 auto filterExtension = 390 /*But we specify 1 algorithm*/ 391 MakeTlsFilter<TLSCertificateCompressionExtensionModifier>(client_, 0, 4); 392 filterExtension->EnableDecryption(); 393 394 ExpectAlert(client_, kTlsAlertDecodeError); 395 ConnectExpectAlert(server_, kTlsAlertDecodeError); 396 397 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 398 client_->ExpectSendAlert(kTlsAlertCloseNotify); 399 400 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 401 ssl_certificate_compression_xtn)); 402 403 server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); 404 client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT); 405 } 406 407 /* The test checks that the extension is not negotiated if in the ClientHello 408 * the extension length is smaller than the actual length of the extension. 409 */ 410 TEST_F(TlsConnectStreamTls13, 411 CertificateCompression_LengthIsSmallerThanExpected) { 412 EnsureTlsSetup(); 413 414 SSLCertificateCompressionAlgorithm alg_ff01 = {0xff01, "test function", 415 SimpleXorCertCompEncode, 416 SimpleXorCertCompDecode}; 417 418 SSLCertificateCompressionAlgorithm alg_ff02 = {0xff02, "test function", 419 SimpleXorCertCompEncode, 420 SimpleXorCertCompDecode}; 421 422 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 423 server_->ssl_fd(), alg_ff01)); 424 425 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 426 client_->ssl_fd(), alg_ff01)); 427 428 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 429 client_->ssl_fd(), alg_ff02)); 430 431 auto filterExtension = 432 /* But we specify two algorithms*/ 433 MakeTlsFilter<TLSCertificateCompressionExtensionModifier>(client_, 0, 2); 434 filterExtension->EnableDecryption(); 435 436 ExpectAlert(client_, kTlsAlertDecodeError); 437 ConnectExpectAlert(server_, kTlsAlertDecodeError); 438 439 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 440 client_->ExpectSendAlert(kTlsAlertCloseNotify); 441 442 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 443 ssl_certificate_compression_xtn)); 444 445 server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); 446 client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT); 447 } 448 449 TEST_F(TlsConnectStreamTls13, 450 CertificateCompression_ClientHelloUsedCompressedCertificate) { 451 EnsureTlsSetup(); 452 auto filterExtension = 453 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(server_); 454 455 SSLCertificateCompressionAlgorithm alg_ff01 = { 456 0xff01, "test function id ff01", SimpleXorCertCompEncode, 457 SimpleXorCertCompDecode}; 458 459 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 460 server_->ssl_fd(), alg_ff01)); 461 462 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 463 client_->ssl_fd(), alg_ff01)); 464 Connect(); 465 466 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 467 } 468 469 TEST_F(TlsConnectStreamTls13, 470 CertificateCompression_ClientAuthUsesTheServerPreferredAlg) { 471 EnsureTlsSetup(); 472 auto filterExtension = 473 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(client_); 474 475 SSLCertificateCompressionAlgorithm serverPreferableAlg = { 476 // for decompression 477 0xff01, "test function id ff01", SimpleXorCertCompEncode, 478 SimpleXorCertCompDecode}; 479 480 SSLCertificateCompressionAlgorithm clientPreferableAlg = { 481 0xff02, "test function id ff02", SimpleXorWithDifferentValueEncode, 482 SimpleXorWithDifferentValueDecode}; 483 484 /* The server wants to use serverPreferableAlg for decompression. */ 485 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 486 server_->ssl_fd(), serverPreferableAlg)); 487 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 488 server_->ssl_fd(), clientPreferableAlg)); 489 490 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 491 client_->ssl_fd(), clientPreferableAlg)); 492 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 493 client_->ssl_fd(), serverPreferableAlg)); 494 495 client_->SetupClientAuth(); 496 server_->RequestClientAuth(true); 497 498 /* Client is sending the client certificate. */ 499 Connect(); 500 501 EXPECT_TRUE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 502 ssl_certificate_compression_xtn)); 503 EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(), 504 ssl_certificate_compression_xtn)); 505 506 uint16_t certCompressionAlg = filterExtension->getCertCompressionAlg(); 507 EXPECT_EQ(certCompressionAlg, serverPreferableAlg.id); 508 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 509 } 510 511 TEST_F(TlsConnectStreamTls13, 512 CertificateCompression_ServerReceivedUnexpectedEncodedCertificate) { 513 EnsureTlsSetup(); 514 auto filterExtension = 515 MakeTlsFilter<TLSCertificateToEncodedCertificateChanger>(client_); 516 client_->SetupClientAuth(); 517 server_->RequestClientAuth(true); 518 519 ExpectAlert(server_, kTlsAlertDecodeError); 520 StartConnect(); 521 522 server_->SetServerKeyBits(client_->server_key_bits()); 523 server_->Handshake(); 524 client_->Handshake(); 525 526 ASSERT_TRUE_WAIT((server_->state() != TlsAgent::STATE_CONNECTING), 5000); 527 ASSERT_EQ(TlsAgent::STATE_ERROR, server_->state()); 528 529 server_->ExpectSendAlert(kTlsAlertCloseNotify); 530 client_->ExpectReceiveAlert(kTlsAlertCloseNotify); 531 532 server_->CheckErrorCode(SEC_ERROR_UNEXPECTED_COMPRESSED_CERTIFICATE); 533 } 534 535 TEST_F(TlsConnectStreamTls13, 536 CertificateCompression_UnknownAlgorithmNoExtensionNegotiated) { 537 EnsureTlsSetup(); 538 539 SSLCertificateCompressionAlgorithm alg_ff01 = { 540 0xff01, "test function id ff01", SimpleXorCertCompEncode, 541 SimpleXorCertCompDecode}; 542 543 /* Server does not support the encoding algorithm, only client. */ 544 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 545 client_->ssl_fd(), alg_ff01)); 546 547 Connect(); 548 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 549 ssl_certificate_compression_xtn)); 550 } 551 552 class TLSCertificateToEncodedCertificateCrasher : public TlsRecordFilter { 553 public: 554 TLSCertificateToEncodedCertificateCrasher(const std::shared_ptr<TlsAgent>& a) 555 : TlsRecordFilter(a) { 556 EnableDecryption(); 557 } 558 559 protected: 560 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 561 const DataBuffer& record, size_t* offset, 562 DataBuffer* output) override { 563 uint8_t inner_content_type; 564 DataBuffer plaintext; 565 uint16_t protection_epoch = 0; 566 TlsRecordHeader out_header(header); 567 568 if (!Unprotect(header, record, &protection_epoch, &inner_content_type, 569 &plaintext, &out_header)) { 570 return KEEP; 571 } 572 573 uint64_t skip = findPointerToHandshakeType(plaintext, ssl_hs_key_update); 574 if (skip >= plaintext.len() || 575 plaintext.data()[skip] != ssl_hs_key_update) { 576 return KEEP; 577 } 578 579 uint32_t ku_len = (plaintext.data()[skip + 1] << 16) + 580 (plaintext.data()[skip + 2] << 8) + 581 plaintext.data()[skip + 3]; 582 583 DataBuffer plaintextEncodedCert(plaintext); 584 plaintextEncodedCert.Write(skip, &plaintext.data()[skip], ku_len + 1); 585 586 const uint8_t encodedCert[456] = { 587 0x19, 0x00, 0x01, 0xc4, 0xff, 0x01, 0x00, 0x01, 0xbf, 0x00, 0x00, 0x01, 588 0xbb, 0x00, 0x01, 0xb6, 0x30, 0x82, 0x01, 0xb2, 0x30, 0x82, 0x01, 0x1b, 589 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 590 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 591 0x11, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x06, 592 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 593 0x31, 0x32, 0x31, 0x33, 0x31, 0x38, 0x31, 0x34, 0x31, 0x38, 0x5a, 0x17, 594 0x0d, 0x33, 0x33, 0x31, 0x32, 0x31, 0x33, 0x31, 0x38, 0x31, 0x34, 0x31, 595 0x38, 0x5a, 0x30, 0x11, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 596 0x03, 0x13, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x30, 0x81, 0x9f, 597 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 598 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 599 0x81, 0x00, 0xb2, 0xe9, 0x2c, 0xe7, 0x25, 0xe2, 0x10, 0x83, 0x1c, 0xe5, 600 0x22, 0xa2, 0x08, 0x55, 0x1a, 0xdf, 0x17, 0xc9, 0x8b, 0x23, 0x48, 0xef, 601 0x45, 0x28, 0xe5, 0x8d, 0x6c, 0x37, 0xc0, 0x5e, 0x74, 0x39, 0x05, 0x01, 602 0xde, 0x15, 0x17, 0x43, 0xa0, 0x78, 0x5e, 0x3e, 0x02, 0x05, 0xf4, 0x4c, 603 0x61, 0x97, 0xb2, 0x01, 0x29, 0xf7, 0x61, 0xf0, 0x10, 0x47, 0x1d, 0x68, 604 0x22, 0xf9, 0xef, 0xf2, 0x8c, 0x3b, 0xe5, 0x78, 0x5f, 0x58, 0xf5, 0x88, 605 0xd0, 0xb9, 0xa6, 0xe0, 0x9b, 0x3e, 0x6f, 0x86, 0xf1, 0x9d, 0xe5, 0x34, 606 0x78, 0xd6, 0xad, 0x6f, 0x6e, 0x38, 0x90, 0x88, 0x29, 0x45, 0x9d, 0xd8, 607 0x6d, 0x12, 0x14, 0x9a, 0x87, 0x45, 0xb7, 0x9e, 0x6b, 0xe3, 0x98, 0xdf, 608 0x65, 0xa9, 0xb6, 0x30, 0x53, 0xb6, 0xca, 0xed, 0x82, 0x18, 0x69, 0x30, 609 0x4e, 0xda, 0x8e, 0x11, 0xc9, 0x98, 0xc6, 0x2e, 0xd8, 0xcd, 0x02, 0x03, 610 0x01, 0x00, 0x01, 0xa3, 0x1a, 0x30, 0x18, 0x30, 0x09, 0x06, 0x03, 0x55, 611 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 612 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0d, 0x06, 0x09, 0x2a, 613 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 614 0x81, 0x00, 0x4f, 0x9b, 0x47, 0x31, 0xe7, 0x71, 0x11, 0x45, 0x44, 0xf6, 615 0x17, 0x09, 0xb3, 0x32, 0x95, 0xaa, 0xe7, 0xd1, 0xec, 0xb4, 0x8b, 0xb6, 616 0xd3, 0xb6, 0xb5, 0x30, 0x61, 0x5b, 0x5a, 0xfe, 0x0e, 0xb8, 0x1d, 0x72, 617 0xdb, 0x80, 0xd2, 0xf6, 0xd5, 0xdc, 0xbe, 0xff, 0x99, 0x69, 0xb9, 0x5c, 618 0x67, 0x18, 0xd4, 0xcb, 0xa8, 0xcf, 0x57, 0x60, 0x3d, 0xc8, 0x76, 0x5e, 619 0xc0, 0xcb, 0x6f, 0x22, 0x1a, 0x2c, 0xe6, 0xd1, 0x0e, 0x59, 0xb7, 0x0d, 620 0xef, 0x36, 0x6f, 0x57, 0xd3, 0x77, 0x7b, 0xab, 0x29, 0x00, 0x09, 0x87, 621 0x0f, 0xf2, 0xfb, 0x59, 0xf5, 0x72, 0x86, 0x33, 0x2f, 0x2f, 0x16, 0x44, 622 0x77, 0xed, 0x03, 0x11, 0x43, 0x29, 0x81, 0x07, 0xd1, 0x1a, 0xc2, 0xd5, 623 0x78, 0xd8, 0xaa, 0x20, 0x9e, 0x3e, 0x69, 0xcd, 0x6c, 0x3b, 0xd3, 0x07, 624 0x32, 0xa3, 0x12, 0x60, 0x01, 0x2e, 0xf4, 0x29, 0x7f, 0x47, 0x00, 0x00}; 625 plaintextEncodedCert.Write(skip, encodedCert, 456); 626 plaintextEncodedCert.Write(skip + 456, &plaintext.data()[skip], ku_len + 1); 627 628 DataBuffer ciphertext; 629 bool ok = Protect(spec(protection_epoch), out_header, inner_content_type, 630 plaintextEncodedCert, &ciphertext, &out_header); 631 EXPECT_TRUE(ok); 632 if (!ok) { 633 return KEEP; 634 } 635 *offset = out_header.Write(output, *offset, ciphertext); 636 return CHANGE; 637 } 638 }; 639 640 TEST_F( 641 TlsConnectStreamTls13, 642 CertificateCompression_ServerReceivedUnexpectedEncodedCertificate_PostAuth) { 643 SSLCertificateCompressionAlgorithm alg_ff01 = { 644 0xff01, "test function id ff01", SimpleXorCertCompEncode, 645 SimpleXorCertCompDecode}; 646 647 EnsureTlsSetup(); 648 auto filterExtension = 649 MakeTlsFilter<TLSCertificateToEncodedCertificateCrasher>(client_); 650 651 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 652 server_->ssl_fd(), alg_ff01)); 653 654 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 655 client_->ssl_fd(), alg_ff01)); 656 657 Connect(); 658 EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE)); 659 660 server_->ExpectSendAlert(kTlsAlertDecodeError); 661 client_->ExpectSendAlert(kTlsAlertCloseNotify); 662 server_->SendData(50); 663 client_->ReadBytes(50); 664 client_->SendData(50); 665 server_->ExpectReadWriteError(); 666 server_->ReadBytes(50); 667 server_->CheckErrorCode(SEC_ERROR_UNEXPECTED_COMPRESSED_CERTIFICATE); 668 } 669 670 /* Here the server first request a client certificate during the handshake, 671 but after the handshake it received another, encoded certificate. */ 672 TEST_F( 673 TlsConnectStreamTls13, 674 CertificateCompression_ServerReceivedUnexpectedEncodedCertificateAfterRequesting) { 675 SSLCertificateCompressionAlgorithm alg_ff01 = { 676 0xff01, "test function id ff01", SimpleXorCertCompEncode, 677 SimpleXorCertCompDecode}; 678 679 EnsureTlsSetup(); 680 auto filterExtension = 681 MakeTlsFilter<TLSCertificateToEncodedCertificateCrasher>(client_); 682 683 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 684 server_->ssl_fd(), alg_ff01)); 685 686 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 687 client_->ssl_fd(), alg_ff01)); 688 689 client_->SetupClientAuth(); 690 server_->RequestClientAuth(true); 691 692 Connect(); 693 EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE)); 694 695 server_->ExpectSendAlert(kTlsAlertDecodeError); 696 client_->ExpectSendAlert(kTlsAlertCloseNotify); 697 server_->SendData(50); 698 client_->ReadBytes(50); 699 client_->SendData(50); 700 server_->ExpectReadWriteError(); 701 server_->ReadBytes(50); 702 server_->CheckErrorCode(SEC_ERROR_UNEXPECTED_COMPRESSED_CERTIFICATE); 703 } 704 705 TEST_F(TlsConnectStreamTls13, CertificateCompression_OneCommonAlg) { 706 EnsureTlsSetup(); 707 708 SSLCertificateCompressionAlgorithm alg_ff01 = { 709 0xff01, "test function id ff01", SimpleXorCertCompEncode, 710 SimpleXorCertCompDecode}; 711 712 SSLCertificateCompressionAlgorithm alg_ff02 = { 713 0xff02, "test function id ff02", SimpleXorCertCompEncode, 714 SimpleXorCertCompDecode}; 715 716 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 717 server_->ssl_fd(), alg_ff01)); 718 719 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 720 server_->ssl_fd(), alg_ff02)); 721 722 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 723 client_->ssl_fd(), alg_ff02)); 724 725 Connect(); 726 EXPECT_TRUE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 727 ssl_certificate_compression_xtn)); 728 729 SSLCertificateCompressionAlgorithm alg; 730 EXPECT_EQ(SECSuccess, 731 SSLInt_GetCertificateCompressionAlgorithm(server_->ssl_fd(), &alg)); 732 EXPECT_EQ(0xff02, alg.id); 733 } 734 735 /* 736 Test checking the correct behaviour of the preference choice. 737 In NSS, the priority is based on the order of the algorithms set up: 738 739 For the CertificateCompression_Preference case, 740 the client algorithm 0xff01 has the higher priority and the 741 0xff03 algorithm has the lowest priority. 742 743 Then, for each of the advertised algorithms, the second party checks if there 744 is a support of this algorithm. In our case, the server supports algs 0xff01 745 and 0xff02. 746 747 But as the algorithms 0xff02 has the highest priority, it will be negotiated. 748 */ 749 750 TEST_F(TlsConnectStreamTls13, CertificateCompression_Preference) { 751 EnsureTlsSetup(); 752 753 SSLCertificateCompressionAlgorithm alg_ff01 = { 754 0xff01, "test function id ff01", SimpleXorCertCompEncode, 755 SimpleXorCertCompDecode}; 756 757 SSLCertificateCompressionAlgorithm alg_ff02 = { 758 0xff02, "test function id ff02", SimpleXorCertCompEncode, 759 SimpleXorCertCompDecode}; 760 761 SSLCertificateCompressionAlgorithm alg_ff03 = { 762 0xff03, "test function id ff02", SimpleXorCertCompEncode, 763 SimpleXorCertCompDecode}; 764 765 /* By sending a compress_certificate extension, the sender indicates to 766 the peer the certificate-compression algorithms it is willing to use 767 for decompression. */ 768 769 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 770 client_->ssl_fd(), alg_ff03)); 771 772 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 773 client_->ssl_fd(), alg_ff02)); 774 775 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 776 client_->ssl_fd(), alg_ff01)); 777 778 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 779 server_->ssl_fd(), alg_ff01)); 780 781 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 782 server_->ssl_fd(), alg_ff02)); 783 784 Connect(); 785 EXPECT_TRUE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 786 ssl_certificate_compression_xtn)); 787 788 SSLCertificateCompressionAlgorithm alg; 789 EXPECT_EQ(SECSuccess, 790 SSLInt_GetCertificateCompressionAlgorithm(server_->ssl_fd(), &alg)); 791 EXPECT_EQ(alg_ff02.id, alg.id); 792 } 793 794 TEST_F(TlsConnectStreamTls13, CertificateCompression_SameIDDifferentAlgs) { 795 EnsureTlsSetup(); 796 797 SSLCertificateCompressionAlgorithm alg_ff01 = { 798 0xff01, "test function id ff01", SimpleXorCertCompEncode, 799 SimpleXorCertCompDecode}; 800 801 SSLCertificateCompressionAlgorithm alg_ff01_but_diffent_alg = { 802 0xff01, "test function pretending to be id ff01", 803 SimpleXorWithDifferentValueEncode, SimpleXorWithDifferentValueDecode}; 804 805 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 806 server_->ssl_fd(), alg_ff01)); 807 808 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 809 client_->ssl_fd(), alg_ff01_but_diffent_alg)); 810 811 ExpectAlert(client_, kTlsAlertDecodeError); 812 ConnectExpectAlert(server_, kTlsAlertDecodeError); 813 814 server_->ExpectSendAlert(kTlsAlertCloseNotify); 815 client_->ExpectReceiveAlert(kTlsAlertCloseNotify); 816 817 server_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT); 818 client_->CheckErrorCode(SSL_ERROR_BAD_SERVER); 819 820 EXPECT_TRUE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 821 ssl_certificate_compression_xtn)); 822 } 823 824 /* This test ensures that if the supported algorithms between server and client 825 * are different, no extension is negotiated. 826 */ 827 TEST_F(TlsConnectStreamTls13, CertificateCompression_NoCommonAlgs) { 828 EnsureTlsSetup(); 829 830 SSLCertificateCompressionAlgorithm alg_ff01 = {0xff01, "test function", 831 SimpleXorCertCompEncode, 832 SimpleXorCertCompDecode}; 833 834 SSLCertificateCompressionAlgorithm alg_ff02 = {0xff02, "test function", 835 SimpleXorCertCompEncode, 836 SimpleXorCertCompDecode}; 837 838 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 839 server_->ssl_fd(), alg_ff01)); 840 841 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 842 client_->ssl_fd(), alg_ff02)); 843 844 Connect(); 845 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 846 ssl_certificate_compression_xtn)); 847 } 848 849 /* The user is trying to add more certificate compression algorithms than it is 850 * allowed. The maximum of algorithms is specified by 851 * MAX_SUPPORTED_CERTCOMPR_ALGS. 852 */ 853 TEST_F(TlsConnectStreamTls13, CertificateCompression_TooManyAlgorithms) { 854 EnsureTlsSetup(); 855 856 for (size_t i = 0; i < MAX_SUPPORTED_CERTIFICATE_COMPRESSION_ALGS; i++) { 857 SSLCertificateCompressionAlgorithm t = { 858 (SSLCertificateCompressionAlgorithmID)(i + 1), "test function", 859 SimpleXorCertCompEncode, SimpleXorCertCompDecode}; 860 EXPECT_EQ(SECSuccess, 861 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 862 } 863 864 SSLCertificateCompressionAlgorithm t_last = { 865 (SSLCertificateCompressionAlgorithmID)(MAX_SUPPORTED_CERTIFICATE_COMPRESSION_ALGS + 866 1), 867 "test function", SimpleXorCertCompEncode, SimpleXorCertCompDecode}; 868 869 EXPECT_EQ(SECFailure, SSLExp_SetCertificateCompressionAlgorithm( 870 server_->ssl_fd(), t_last)); 871 } 872 873 /* The test checking that when we install a new compression mechanism, it is 874 * advertised. 875 */ 876 TEST_F(TlsConnectStreamTls13, 877 CertificateCompression_SameEncodingAsInCertificateExt) { 878 ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); 879 StartConnect(); 880 auto filterExtension = 881 MakeTlsFilter<TLSCertificateCompressionExtensionCatcher>(client_); 882 filterExtension->EnableDecryption(); 883 884 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 885 SimpleXorCertCompEncode, 886 SimpleXorCertCompDecode}; 887 888 EXPECT_EQ(SECSuccess, 889 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 890 EXPECT_EQ(SECSuccess, 891 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 892 893 Connect(); 894 895 DataBuffer supportedAlgorithms = filterExtension->GetBufCompressionAlgs(); 896 bool supportsEstablishedExtension = false; 897 898 for (size_t i = 0; i < supportedAlgorithms.len() / 2; i++) { 899 uint16_t alg = (supportedAlgorithms.data()[2 * i] << 8) + 900 supportedAlgorithms.data()[2 * i + 1]; 901 supportsEstablishedExtension = 902 supportsEstablishedExtension || (alg == 0xff01); 903 } 904 905 EXPECT_TRUE(supportsEstablishedExtension); 906 } 907 908 /* If there is no certificate compression algorithm is possible, 909 * the extension is not sent. 910 */ 911 TEST_F(TlsConnectStreamTls13, 912 CertificateCompression_ServerChecksEncodingNoneInstalled) { 913 ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); 914 StartConnect(); 915 916 auto filterExtension = 917 MakeTlsFilter<TLSCertificateCompressionExtensionCatcher>(client_); 918 Connect(); 919 920 EXPECT_FALSE(filterExtension->sawCertificateCompressionExtension()); 921 } 922 923 /* RFC 8879 924 * This extension is only supported with TLS 1.3 [RFC8446] and newer; 925 * if TLS 1.2 [RFC5246] or earlier is negotiated, 926 * the peers MUST ignore this extension. 927 */ 928 TEST_P(TlsConnectGeneric, CertificateCompressionTLS12AndBelow) { 929 if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) GTEST_SKIP(); 930 if (version_ < SSL_LIBRARY_VERSION_TLS_1_1) GTEST_SKIP(); 931 StartConnect(); 932 933 /* Adding the certificate compression extension.*/ 934 const uint8_t empty_buf[] = {0x01, 0x00, 0x01}; 935 DataBuffer empty(empty_buf, 3); 936 auto filter = MakeTlsFilter<TlsExtensionAppender>( 937 client_, kTlsHandshakeClientHello, 27, empty); 938 939 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { 940 filter->EnableDecryption(); 941 } 942 943 ConnectExpectAlert(server_, kTlsAlertDecryptError); 944 945 EXPECT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(), 946 ssl_certificate_compression_xtn)); 947 948 server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); 949 client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT); 950 } 951 952 /* Test encoding function. Creates an encoded certificate of size 0. */ 953 static SECStatus SimpleXorCertCompEncode_returns_buffer_size_0( 954 const SECItem* input, SECItem* output) { 955 SECITEM_MakeItem(NULL, output, input->data, 0); 956 return SECSuccess; 957 } 958 959 /* The CompressedCertificate message is formed as follows: 960 * struct { 961 * CertificateCompressionAlgorithm algorithm; 962 * uint24 uncompressed_length; 963 * opaque compressed_certificate_message<1..2^24-1>; 964 * } CompressedCertificate; 965 */ 966 967 TEST_F(TlsConnectStreamTls13, 968 CertificateCompression_CompressionFunctionCreatesABufferOfSize0) { 969 ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); 970 StartConnect(); 971 972 SSLCertificateCompressionAlgorithm t = { 973 0xff01, "test function", SimpleXorCertCompEncode_returns_buffer_size_0, 974 SimpleXorCertCompDecode}; 975 976 EXPECT_EQ(SECSuccess, 977 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 978 EXPECT_EQ(SECSuccess, 979 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 980 981 ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); 982 server_->CheckErrorCode(SEC_ERROR_LIBRARY_FAILURE); 983 } 984 985 class TLSCertificateCompressionCertificateModifier : public TlsRecordFilter { 986 public: 987 TLSCertificateCompressionCertificateModifier( 988 const std::shared_ptr<TlsAgent>& a, uint64_t _byte, uint64_t _value) 989 : TlsRecordFilter(a), 990 offset_start_(_byte), 991 offset_finish_(0xffffffff), 992 value_(_value) { 993 EnableDecryption(); 994 } 995 TLSCertificateCompressionCertificateModifier( 996 const std::shared_ptr<TlsAgent>& a, uint64_t _byteStart, 997 uint64_t _byteFinish, uint64_t _value) 998 : TlsRecordFilter(a), 999 offset_start_(_byteStart), 1000 offset_finish_(_byteFinish), 1001 value_(_value) { 1002 EnableDecryption(); 1003 } 1004 1005 protected: 1006 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 1007 const DataBuffer& record, size_t* offset, 1008 DataBuffer* output) override { 1009 uint8_t inner_content_type; 1010 DataBuffer plaintext; 1011 uint16_t protection_epoch = 0; 1012 TlsRecordHeader out_header(header); 1013 1014 if (!Unprotect(header, record, &protection_epoch, &inner_content_type, 1015 &plaintext, &out_header)) { 1016 return KEEP; 1017 } 1018 1019 uint64_t skip = 1020 findPointerToHandshakeType(plaintext, ssl_hs_compressed_certificate); 1021 if (skip >= plaintext.len() || 1022 plaintext.data()[skip] != ssl_hs_compressed_certificate) { 1023 return KEEP; 1024 } 1025 1026 if (offset_finish_ == 0xffffffff) { 1027 plaintext.data()[skip + offset_start_] = value_; 1028 } else { 1029 for (size_t i = offset_start_; i < offset_finish_ + 1; i++) { 1030 plaintext.data()[skip + i] = value_; 1031 } 1032 } 1033 1034 DataBuffer ciphertext; 1035 bool ok = Protect(spec(protection_epoch), out_header, inner_content_type, 1036 plaintext, &ciphertext, &out_header); 1037 EXPECT_TRUE(ok); 1038 if (!ok) { 1039 return KEEP; 1040 } 1041 *offset = out_header.Write(output, *offset, ciphertext); 1042 return CHANGE; 1043 } 1044 1045 private: 1046 uint64_t offset_start_; 1047 uint64_t offset_finish_; 1048 uint8_t value_; 1049 }; 1050 1051 class TLSCertificateCompressionCertificateElongator : public TlsRecordFilter { 1052 public: 1053 TLSCertificateCompressionCertificateElongator( 1054 const std::shared_ptr<TlsAgent>& a, uint64_t len) 1055 : TlsRecordFilter(a), len_(len) { 1056 EnableDecryption(); 1057 } 1058 1059 protected: 1060 PacketFilter::Action FilterRecord(const TlsRecordHeader& header, 1061 const DataBuffer& record, size_t* offset, 1062 DataBuffer* output) override { 1063 uint8_t inner_content_type; 1064 DataBuffer plaintext; 1065 uint16_t protection_epoch = 0; 1066 TlsRecordHeader out_header(header); 1067 1068 if (!Unprotect(header, record, &protection_epoch, &inner_content_type, 1069 &plaintext, &out_header)) { 1070 return KEEP; 1071 } 1072 1073 uint64_t skip = 1074 findPointerToHandshakeType(plaintext, ssl_hs_compressed_certificate); 1075 if (skip >= plaintext.len() || 1076 plaintext.data()[skip] != ssl_hs_compressed_certificate) { 1077 return KEEP; 1078 } 1079 1080 plaintext.Write(plaintext.len(), (uint32_t)0, len_); 1081 1082 DataBuffer ciphertext; 1083 bool ok = Protect(spec(protection_epoch), out_header, inner_content_type, 1084 plaintext, &ciphertext, &out_header); 1085 EXPECT_TRUE(ok); 1086 if (!ok) { 1087 return KEEP; 1088 } 1089 *offset = out_header.Write(output, *offset, ciphertext); 1090 return CHANGE; 1091 } 1092 1093 private: 1094 uint64_t len_; 1095 }; 1096 1097 /* The CompressedCertificate message is formed as follows: 1098 * struct { 1099 * CertificateCompressionAlgorithm algorithm; 1100 * uint24 uncompressed_length; 1101 * opaque compressed_certificate_message<1..2^24-1>; 1102 * } CompressedCertificate; 1103 * 1104 * algorithm: 1105 * The algorithm used to compress the certificate. 1106 * The algorithm MUST be one of the algorithms listed in the peer's 1107 * compress_certificate extension. 1108 * 1109 * In the next test we modify the encoding used to encode the certificate to the 1110 * one that the server did not advertise. 1111 */ 1112 TEST_F(TlsConnectStreamTls13, CertificateCompression_ReceivedWrongAlgorithm) { 1113 EnsureTlsSetup(); 1114 auto filterExtension = 1115 MakeTlsFilter<TLSCertificateCompressionCertificateModifier>(server_, 0x5, 1116 0x2); 1117 1118 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1119 SimpleXorCertCompEncode, 1120 SimpleXorCertCompDecode}; 1121 1122 EXPECT_EQ(SECSuccess, 1123 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1124 EXPECT_EQ(SECSuccess, 1125 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1126 1127 ExpectAlert(client_, kTlsAlertIllegalParameter); 1128 StartConnect(); 1129 1130 client_->SetServerKeyBits(server_->server_key_bits()); 1131 client_->Handshake(); 1132 server_->Handshake(); 1133 1134 ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING), 5000); 1135 ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state()); 1136 1137 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1138 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1139 1140 client_->CheckErrorCode( 1141 SEC_ERROR_CERTIFICATE_COMPRESSION_ALGORITHM_NOT_SUPPORTED); 1142 } 1143 1144 /* The next test modifies the length of the encoded certificate 1145 * (compressed_certificate_message len); 1146 * the new length is compressed_certificate_message is equal to 0. 1147 */ 1148 TEST_F(TlsConnectStreamTls13, 1149 CertificateCompression_ReceivedZeroCompressedMessage) { 1150 EnsureTlsSetup(); 1151 auto filterExtension = 1152 MakeTlsFilter<TLSCertificateCompressionCertificateModifier>(server_, 0xa, 1153 0xb, 0x0); 1154 1155 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1156 SimpleXorCertCompEncode, 1157 SimpleXorCertCompDecode}; 1158 1159 EXPECT_EQ(SECSuccess, 1160 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1161 EXPECT_EQ(SECSuccess, 1162 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1163 1164 ExpectAlert(client_, kTlsAlertBadCertificate); 1165 StartConnect(); 1166 1167 client_->SetServerKeyBits(server_->server_key_bits()); 1168 client_->Handshake(); 1169 server_->Handshake(); 1170 1171 ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING), 5000); 1172 ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state()); 1173 1174 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1175 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1176 1177 client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE); 1178 } 1179 1180 /* The next test modifies the length of the encoded certificate 1181 * (compressed_certificate_message len); 1182 * the new length is compressed_certificate_message is longer than the 1183 * certificate. 1184 */ 1185 TEST_F(TlsConnectStreamTls13, 1186 CertificateCompression_ReceivedLongerCompressedMessage) { 1187 EnsureTlsSetup(); 1188 auto filterExtension = 1189 MakeTlsFilter<TLSCertificateCompressionCertificateModifier>(server_, 0x9, 1190 0xb, 0xff); 1191 1192 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1193 SimpleXorCertCompEncode, 1194 SimpleXorCertCompDecode}; 1195 1196 EXPECT_EQ(SECSuccess, 1197 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1198 EXPECT_EQ(SECSuccess, 1199 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1200 1201 ExpectAlert(client_, kTlsAlertBadCertificate); 1202 StartConnect(); 1203 1204 client_->SetServerKeyBits(server_->server_key_bits()); 1205 client_->Handshake(); 1206 server_->Handshake(); 1207 1208 ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING), 5000); 1209 ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state()); 1210 1211 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1212 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1213 1214 client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE); 1215 } 1216 1217 TEST_F(TlsConnectStreamTls13, 1218 CertificateCompression_ReceivedCertificateTooLong) { 1219 EnsureTlsSetup(); 1220 auto filterExtension = 1221 MakeTlsFilter<TLSCertificateCompressionCertificateElongator>(server_, 1222 0x4); 1223 1224 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1225 SimpleXorCertCompEncode, 1226 SimpleXorCertCompDecode}; 1227 EXPECT_EQ(SECSuccess, 1228 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1229 EXPECT_EQ(SECSuccess, 1230 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1231 1232 ExpectAlert(client_, kTlsAlertUnexpectedMessage); 1233 StartConnect(); 1234 Handshake(); 1235 1236 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1237 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1238 1239 client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE); 1240 } 1241 1242 /* Test encoding function. Returns error unconditionally. */ 1243 static SECStatus SimpleXorCertCompEncode_always_error(const SECItem* input, 1244 SECItem* output) { 1245 return SECFailure; 1246 } 1247 1248 /* Test decoding function. Returns error unconditionally. */ 1249 static SECStatus SimpleXorCertCompDecode_always_error( 1250 const SECItem* input, uint8_t* output, size_t outputLen, 1251 size_t* receivedOutputLen) { 1252 return SECFailure; 1253 } 1254 1255 TEST_F(TlsConnectStreamTls13, CertificateCompression_CertificateCannotEncode) { 1256 EnsureTlsSetup(); 1257 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1258 SimpleXorCertCompEncode_always_error, 1259 SimpleXorCertCompDecode}; 1260 1261 EXPECT_EQ(SECSuccess, 1262 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1263 EXPECT_EQ(SECSuccess, 1264 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1265 1266 ExpectAlert(server_, kTlsAlertHandshakeFailure); 1267 StartConnect(); 1268 1269 client_->SetServerKeyBits(server_->server_key_bits()); 1270 client_->Handshake(); 1271 server_->Handshake(); 1272 1273 ASSERT_TRUE_WAIT(client_->state() != TlsAgent::STATE_CONNECTING, 5000); 1274 1275 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1276 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1277 1278 server_->CheckErrorCode(SEC_ERROR_NO_MEMORY); 1279 } 1280 1281 TEST_F(TlsConnectStreamTls13, CertificateCompression_CertificateCannotDecode) { 1282 EnsureTlsSetup(); 1283 1284 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1285 SimpleXorCertCompEncode, 1286 SimpleXorCertCompDecode_always_error}; 1287 1288 EXPECT_EQ(SECSuccess, 1289 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1290 EXPECT_EQ(SECSuccess, 1291 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1292 1293 ExpectAlert(client_, kTlsAlertBadCertificate); 1294 StartConnect(); 1295 1296 client_->SetServerKeyBits(server_->server_key_bits()); 1297 client_->Handshake(); 1298 server_->Handshake(); 1299 1300 ASSERT_TRUE_WAIT(client_->state() != TlsAgent::STATE_CONNECTING, 5000); 1301 1302 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1303 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1304 1305 client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE); 1306 } 1307 1308 /* Decoding function returning unexpected decoded certificate length. */ 1309 static SECStatus WrongUsedLenCertCompDecode(const SECItem* input, 1310 uint8_t* output, size_t outputLen, 1311 size_t* receivedOutputLen) { 1312 if (input->len != outputLen) { 1313 return SECFailure; 1314 } 1315 1316 PORT_Memcpy(output, input->data, input->len); 1317 *receivedOutputLen = outputLen - 1; 1318 1319 return SECSuccess; 1320 } 1321 1322 TEST_F(TlsConnectStreamTls13, 1323 CertificateCompression_WrongDecodedCertificateLength) { 1324 EnsureTlsSetup(); 1325 1326 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1327 SimpleXorCertCompEncode, 1328 WrongUsedLenCertCompDecode}; 1329 1330 EXPECT_EQ(SECSuccess, 1331 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1332 EXPECT_EQ(SECSuccess, 1333 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1334 1335 ExpectAlert(client_, kTlsAlertBadCertificate); 1336 StartConnect(); 1337 1338 client_->SetServerKeyBits(server_->server_key_bits()); 1339 client_->Handshake(); 1340 server_->Handshake(); 1341 1342 ASSERT_TRUE_WAIT(client_->state() != TlsAgent::STATE_CONNECTING, 5000); 1343 1344 server_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1345 client_->ExpectSendAlert(kTlsAlertCloseNotify); 1346 1347 client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE); 1348 } 1349 1350 /* The test checking the client authentification is successful using certificate 1351 * compression. */ 1352 TEST_F(TlsConnectStreamTls13, CertificateCompression_PostAuth) { 1353 EnsureTlsSetup(); 1354 1355 auto filterExtension = 1356 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(client_); 1357 1358 SSLCertificateCompressionAlgorithm t = {0xff01, "test function", 1359 SimpleXorCertCompEncode, 1360 SimpleXorCertCompDecode}; 1361 1362 EXPECT_EQ(SECSuccess, 1363 SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t)); 1364 EXPECT_EQ(SECSuccess, 1365 SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t)); 1366 1367 SSLSignatureScheme scheme = ssl_sig_rsa_pss_rsae_sha256; 1368 SECStatus rv = SSL_SignatureSchemePrefSet(server_->ssl_fd(), &scheme, 1); 1369 EXPECT_EQ(SECSuccess, rv); 1370 rv = SSL_SignatureSchemePrefSet(client_->ssl_fd(), &scheme, 1); 1371 EXPECT_EQ(SECSuccess, rv); 1372 1373 client_->SetupClientAuth(); 1374 client_->SetOption(SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE); 1375 size_t called = 0; 1376 server_->SetAuthCertificateCallback( 1377 [&called](TlsAgent*, PRBool, PRBool) -> SECStatus { 1378 called++; 1379 return SECSuccess; 1380 }); 1381 Connect(); 1382 // Send CertificateRequest. 1383 EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd())) 1384 << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); 1385 1386 // Need to do a round-trip so that the post-handshake message is 1387 // handled on both client and server. 1388 server_->SendData(50); 1389 client_->ReadBytes(50); 1390 client_->SendData(50); 1391 server_->ReadBytes(50); 1392 1393 EXPECT_EQ(1U, called); 1394 EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(), 1395 ssl_certificate_compression_xtn)); 1396 1397 SendReceive(60); 1398 client_->CheckClientAuthCompleted(); 1399 1400 /* Ensuring that we used CompressedCertificate*/ 1401 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 1402 } 1403 1404 /* Partial decoding/encoding algorithms. */ 1405 TEST_F(TlsConnectStreamTls13, CertificateCompression_ClientOnlyDecodes) { 1406 EnsureTlsSetup(); 1407 auto filterExtension = 1408 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(server_); 1409 1410 SSLCertificateCompressionAlgorithm alg_only_encode = { 1411 0xff01, "test function id ff01", SimpleXorCertCompEncode, NULL}; 1412 1413 SSLCertificateCompressionAlgorithm alg_only_decode = { 1414 0xff01, "test function id ff01", NULL, SimpleXorCertCompDecode}; 1415 1416 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1417 server_->ssl_fd(), alg_only_encode)); 1418 1419 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1420 client_->ssl_fd(), alg_only_decode)); 1421 1422 Connect(); 1423 1424 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 1425 } 1426 1427 TEST_F(TlsConnectStreamTls13, 1428 CertificateCompression_ClientOnlyDecodes_NoEncoding) { 1429 EnsureTlsSetup(); 1430 auto filterExtension = 1431 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(client_); 1432 1433 SSLCertificateCompressionAlgorithm alg_only_encode = { 1434 0xff01, "test function id ff01", SimpleXorCertCompEncode, NULL}; 1435 1436 SSLCertificateCompressionAlgorithm alg_only_decode = { 1437 0xff01, "test function id ff01", NULL, SimpleXorCertCompDecode}; 1438 1439 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1440 server_->ssl_fd(), alg_only_encode)); 1441 1442 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1443 client_->ssl_fd(), alg_only_decode)); 1444 1445 SSLSignatureScheme scheme = ssl_sig_rsa_pss_rsae_sha256; 1446 SECStatus rv = SSL_SignatureSchemePrefSet(server_->ssl_fd(), &scheme, 1); 1447 EXPECT_EQ(SECSuccess, rv); 1448 rv = SSL_SignatureSchemePrefSet(client_->ssl_fd(), &scheme, 1); 1449 EXPECT_EQ(SECSuccess, rv); 1450 1451 client_->SetupClientAuth(); 1452 client_->SetOption(SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE); 1453 size_t called = 0; 1454 server_->SetAuthCertificateCallback( 1455 [&called](TlsAgent*, PRBool, PRBool) -> SECStatus { 1456 called++; 1457 return SECSuccess; 1458 }); 1459 Connect(); 1460 // Send CertificateRequest. 1461 EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd())) 1462 << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); 1463 1464 // Need to do a round-trip so that the post-handshake message is 1465 // handled on both client and server. 1466 server_->SendData(50); 1467 client_->ReadBytes(50); 1468 client_->SendData(50); 1469 server_->ReadBytes(50); 1470 1471 EXPECT_EQ(1U, called); 1472 EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(), 1473 ssl_certificate_compression_xtn)); 1474 1475 SendReceive(60); 1476 client_->CheckClientAuthCompleted(); 1477 1478 /* Ensuring that we have not used CompressedCertificate. */ 1479 EXPECT_FALSE(filterExtension->sawCompressedCertificate()); 1480 } 1481 1482 /* SSL_SendCertificateRequest function called by a server advertises 1483 the Certificate Compression Extension. */ 1484 TEST_F(TlsConnectStreamTls13, 1485 CertificateCompression_TwoEncodedCertificateRequests) { 1486 EnsureTlsSetup(); 1487 auto filterExtension = 1488 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(client_); 1489 1490 SSLCertificateCompressionAlgorithm alg_ff01 = { 1491 0xff01, "test function id ff01", SimpleXorCertCompEncode, 1492 SimpleXorCertCompDecode}; 1493 1494 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1495 server_->ssl_fd(), alg_ff01)); 1496 1497 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1498 client_->ssl_fd(), alg_ff01)); 1499 1500 client_->SetupClientAuth(); 1501 client_->SetOption(SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE); 1502 size_t called = 0; 1503 server_->SetAuthCertificateCallback( 1504 [&called](TlsAgent*, PRBool, PRBool) -> SECStatus { 1505 called++; 1506 return SECSuccess; 1507 }); 1508 Connect(); 1509 // Send CertificateRequest. 1510 EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd())) 1511 << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); 1512 1513 // Need to do a round-trip so that the post-handshake message is 1514 // handled on both client and server. 1515 server_->SendData(50); 1516 client_->ReadBytes(50); 1517 client_->SendData(50); 1518 server_->ReadBytes(50); 1519 1520 EXPECT_EQ(1U, called); 1521 1522 SendReceive(60); 1523 client_->CheckClientAuthCompleted(); 1524 1525 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 1526 filterExtension->unsetSawCompressedCertificate(); 1527 EXPECT_FALSE(filterExtension->sawCompressedCertificate()); 1528 1529 /* Advertising again the certificate encoding alg. */ 1530 EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd())) 1531 << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); 1532 1533 server_->SendData(50); 1534 client_->ReadBytes(50); 1535 client_->SendData(50); 1536 server_->ReadBytes(50); 1537 1538 EXPECT_EQ(2U, called); 1539 /* We saw the compressed certificate again. */ 1540 EXPECT_TRUE(filterExtension->sawCompressedCertificate()); 1541 1542 SendReceive(200); 1543 client_->CheckClientAuthCallbacksCompleted(2); 1544 } 1545 1546 TEST_F(TlsConnectStreamTls13, CertificateCompression_ServerDecodingIsNULL) { 1547 EnsureTlsSetup(); 1548 auto filterExtension = 1549 MakeTlsFilter<TLSCertificateCompressionCertificateCatcher>(server_); 1550 1551 SSLCertificateCompressionAlgorithm alg_only_encode = { 1552 0xff01, "test function id ff01", SimpleXorCertCompEncode, NULL}; 1553 1554 SSLCertificateCompressionAlgorithm alg_only_decode = { 1555 0xff01, "test function id ff01", SimpleXorCertCompEncode, NULL}; 1556 1557 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1558 server_->ssl_fd(), alg_only_encode)); 1559 1560 EXPECT_EQ(SECSuccess, SSLExp_SetCertificateCompressionAlgorithm( 1561 client_->ssl_fd(), alg_only_decode)); 1562 1563 ExpectAlert(client_, kTlsAlertIllegalParameter); 1564 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 1565 1566 server_->ExpectSendAlert(kTlsAlertCloseNotify); 1567 client_->ExpectReceiveAlert(kTlsAlertCloseNotify); 1568 1569 server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); 1570 client_->CheckErrorCode(SEC_ERROR_LIBRARY_FAILURE); 1571 } 1572 1573 } // namespace nss_test