tor-browser

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

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