tor-browser

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

ssl_dhe_unittest.cc (29185B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include <functional>
      8 #include <memory>
      9 #include <set>
     10 #include "secerr.h"
     11 #include "ssl.h"
     12 #include "sslerr.h"
     13 #include "sslproto.h"
     14 
     15 #include "gtest_utils.h"
     16 #include "nss_scoped_ptrs.h"
     17 #include "tls_connect.h"
     18 #include "tls_filter.h"
     19 #include "tls_parser.h"
     20 
     21 namespace nss_test {
     22 
     23 TEST_P(TlsConnectGeneric, ConnectDhe) {
     24  EnableOnlyDheCiphers();
     25  Connect();
     26  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
     27            ssl_sig_rsa_pss_rsae_sha256);
     28 }
     29 
     30 TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
     31  EnsureTlsSetup();
     32  client_->ConfigNamedGroups(kAllDHEGroups);
     33 
     34  auto groups_capture =
     35      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
     36  auto shares_capture =
     37      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
     38  std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
     39                                                         shares_capture};
     40  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
     41 
     42  Connect();
     43 
     44  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
     45 
     46  bool ec, dh;
     47  auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
     48    if ((group & 0xff00U) == 0x100U) {
     49      dh = true;
     50    } else {
     51      ec = true;
     52    }
     53  };
     54  CheckGroups(groups_capture->extension(), track_group_type);
     55  CheckShares(shares_capture->extension(), track_group_type);
     56  EXPECT_TRUE(ec) << "Should include an EC group and share";
     57  EXPECT_TRUE(dh) << "Should include an FFDHE group and share";
     58 }
     59 
     60 TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
     61  EnableOnlyDheCiphers();
     62  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
     63  auto groups_capture =
     64      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
     65  auto shares_capture =
     66      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
     67  std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
     68                                                         shares_capture};
     69  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
     70 
     71  Connect();
     72 
     73  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
     74  auto is_ffdhe = [](SSLNamedGroup group) {
     75    // The group has to be in this range.
     76    EXPECT_LE(ssl_grp_ffdhe_2048, group);
     77    EXPECT_GE(ssl_grp_ffdhe_8192, group);
     78  };
     79  CheckGroups(groups_capture->extension(), is_ffdhe);
     80  if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
     81    CheckShares(shares_capture->extension(), is_ffdhe);
     82  } else {
     83    EXPECT_EQ(0U, shares_capture->extension().len());
     84  }
     85 }
     86 
     87 // Requiring the FFDHE extension on the server alone means that clients won't be
     88 // able to connect using a DHE suite.  They should still connect in TLS 1.3,
     89 // because the client automatically sends the supported groups extension.
     90 TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
     91  EnableOnlyDheCiphers();
     92  server_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
     93 
     94  if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
     95    Connect();
     96    CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
     97  } else {
     98    ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
     99    client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    100    server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    101  }
    102 }
    103 
    104 class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
    105 public:
    106  TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& a)
    107      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
    108  virtual PacketFilter::Action FilterHandshake(
    109      const TlsHandshakeFilter::HandshakeHeader& header,
    110      const DataBuffer& input, DataBuffer* output) {
    111    // Damage the first octet of dh_p.  Anything other than the known prime will
    112    // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled.
    113    *output = input;
    114    output->data()[3] ^= 73;
    115    return CHANGE;
    116  }
    117 };
    118 
    119 // Changing the prime in the server's key share results in an error.  This will
    120 // invalidate the signature over the ServerKeyShare. That's ok, NSS won't check
    121 // the signature until everything else has been checked.
    122 TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
    123  EnableOnlyDheCiphers();
    124  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    125  MakeTlsFilter<TlsDheServerKeyExchangeDamager>(server_);
    126 
    127  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    128 
    129  client_->CheckErrorCode(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY);
    130  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    131 }
    132 
    133 class TlsDheSkeChangeY : public TlsHandshakeFilter {
    134 public:
    135  enum ChangeYTo {
    136    kYZero,
    137    kYOne,
    138    kYPMinusOne,
    139    kYGreaterThanP,
    140    kYTooLarge,
    141    kYZeroPad
    142  };
    143 
    144  TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& a, uint8_t handshake_type,
    145                   ChangeYTo change)
    146      : TlsHandshakeFilter(a, {handshake_type}), change_Y_(change) {}
    147 
    148 protected:
    149  void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
    150               const DataBuffer& prime) {
    151    static const uint8_t kExtraZero = 0;
    152    static const uint8_t kTooLargeExtra = 1;
    153 
    154    uint32_t dh_Ys_len;
    155    EXPECT_TRUE(input.Read(offset, 2, &dh_Ys_len));
    156    EXPECT_LT(offset + dh_Ys_len, input.len());
    157    offset += 2;
    158 
    159    // This isn't generally true, but our code pads.
    160    EXPECT_EQ(prime.len(), dh_Ys_len)
    161        << "Length of dh_Ys must equal length of dh_p";
    162 
    163    *output = input;
    164    switch (change_Y_) {
    165      case kYZero:
    166        memset(output->data() + offset, 0, prime.len());
    167        break;
    168 
    169      case kYOne:
    170        memset(output->data() + offset, 0, prime.len() - 1);
    171        output->Write(offset + prime.len() - 1, 1U, 1);
    172        break;
    173 
    174      case kYPMinusOne:
    175        output->Write(offset, prime);
    176        EXPECT_TRUE(output->data()[offset + prime.len() - 1] & 0x01)
    177            << "P must at least be odd";
    178        --output->data()[offset + prime.len() - 1];
    179        break;
    180 
    181      case kYGreaterThanP:
    182        // Set the first 32 octets of Y to 0xff, except the first which we set
    183        // to p[0].  This will make Y > p.  That is, unless p is Mersenne, or
    184        // improbably large (but still the same bit length).  We currently only
    185        // use a fixed prime that isn't a problem for this code.
    186        EXPECT_LT(0, prime.data()[0]) << "dh_p should not be zero-padded";
    187        offset = output->Write(offset, prime.data()[0], 1);
    188        memset(output->data() + offset, 0xff, 31);
    189        break;
    190 
    191      case kYTooLarge:
    192        // Increase the dh_Ys length.
    193        output->Write(offset - 2, prime.len() + sizeof(kTooLargeExtra), 2);
    194        // Then insert the octet.
    195        output->Splice(&kTooLargeExtra, sizeof(kTooLargeExtra), offset);
    196        break;
    197 
    198      case kYZeroPad:
    199        output->Write(offset - 2, prime.len() + sizeof(kExtraZero), 2);
    200        output->Splice(&kExtraZero, sizeof(kExtraZero), offset);
    201        break;
    202    }
    203  }
    204 
    205 private:
    206  ChangeYTo change_Y_;
    207 };
    208 
    209 class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
    210 public:
    211  TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
    212                         bool modify)
    213      : TlsDheSkeChangeY(a, kTlsHandshakeServerKeyExchange, change),
    214        modify_(modify),
    215        p_() {}
    216 
    217  const DataBuffer& prime() const { return p_; }
    218 
    219 protected:
    220  virtual PacketFilter::Action FilterHandshake(
    221      const TlsHandshakeFilter::HandshakeHeader& header,
    222      const DataBuffer& input, DataBuffer* output) override {
    223    size_t offset = 2;
    224    // Read dh_p
    225    uint32_t dh_len = 0;
    226    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    227    EXPECT_GT(input.len(), offset + dh_len);
    228    p_.Assign(input.data() + offset, dh_len);
    229    offset += dh_len;
    230 
    231    // Skip dh_g to find dh_Ys
    232    EXPECT_TRUE(input.Read(offset, 2, &dh_len));
    233    offset += 2 + dh_len;
    234 
    235    if (modify_) {
    236      ChangeY(input, output, offset, p_);
    237      return CHANGE;
    238    }
    239    return KEEP;
    240  }
    241 
    242 private:
    243  bool modify_;
    244  DataBuffer p_;
    245 };
    246 
    247 class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
    248 public:
    249  TlsDheSkeChangeYClient(
    250      const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
    251      std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)
    252      : TlsDheSkeChangeY(a, kTlsHandshakeClientKeyExchange, change),
    253        server_filter_(server_filter) {}
    254 
    255 protected:
    256  virtual PacketFilter::Action FilterHandshake(
    257      const TlsHandshakeFilter::HandshakeHeader& header,
    258      const DataBuffer& input, DataBuffer* output) override {
    259    ChangeY(input, output, 0, server_filter_->prime());
    260    return CHANGE;
    261  }
    262 
    263 private:
    264  std::shared_ptr<const TlsDheSkeChangeYServer> server_filter_;
    265 };
    266 
    267 /* This matrix includes: variant (stream/datagram), TLS version, what change to
    268 * make to dh_Ys, whether the client will be configured to require DH named
    269 * groups.  Test all combinations. */
    270 typedef std::tuple<SSLProtocolVariant, uint16_t, TlsDheSkeChangeY::ChangeYTo,
    271                   bool>
    272    DamageDHYProfile;
    273 class TlsDamageDHYTest
    274    : public TlsConnectTestBase,
    275      public ::testing::WithParamInterface<DamageDHYProfile> {
    276 public:
    277  TlsDamageDHYTest()
    278      : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
    279 };
    280 
    281 TEST_P(TlsDamageDHYTest, DamageServerY) {
    282  EnableOnlyDheCiphers();
    283  if (std::get<3>(GetParam())) {
    284    client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    285  }
    286  TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
    287  MakeTlsFilter<TlsDheSkeChangeYServer>(server_, change, true);
    288 
    289  if (change == TlsDheSkeChangeY::kYZeroPad) {
    290    ExpectAlert(client_, kTlsAlertDecryptError);
    291  } else {
    292    ExpectAlert(client_, kTlsAlertIllegalParameter);
    293  }
    294  ConnectExpectFail();
    295  if (change == TlsDheSkeChangeY::kYZeroPad) {
    296    // Zero padding Y only manifests in a signature failure.
    297    // In TLS 1.0 and 1.1, the client reports a device error.
    298    if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
    299      client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
    300    } else {
    301      client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
    302    }
    303    server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    304  } else {
    305    client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
    306    server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    307  }
    308 }
    309 
    310 TEST_P(TlsDamageDHYTest, DamageClientY) {
    311  EnableOnlyDheCiphers();
    312  if (std::get<3>(GetParam())) {
    313    client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    314  }
    315  // The filter on the server is required to capture the prime.
    316  auto server_filter = MakeTlsFilter<TlsDheSkeChangeYServer>(
    317      server_, TlsDheSkeChangeY::kYZero, false);
    318 
    319  // The client filter does the damage.
    320  TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
    321  MakeTlsFilter<TlsDheSkeChangeYClient>(client_, change, server_filter);
    322 
    323  if (change == TlsDheSkeChangeY::kYZeroPad) {
    324    ExpectAlert(server_, kTlsAlertDecryptError);
    325  } else {
    326    ExpectAlert(server_, kTlsAlertHandshakeFailure);
    327  }
    328  ConnectExpectFail();
    329  if (change == TlsDheSkeChangeY::kYZeroPad) {
    330    // Zero padding Y only manifests in a finished error.
    331    client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    332    server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    333  } else {
    334    client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
    335    server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
    336  }
    337 }
    338 
    339 static const TlsDheSkeChangeY::ChangeYTo kAllYArr[] = {
    340    TlsDheSkeChangeY::kYZero,      TlsDheSkeChangeY::kYOne,
    341    TlsDheSkeChangeY::kYPMinusOne, TlsDheSkeChangeY::kYGreaterThanP,
    342    TlsDheSkeChangeY::kYTooLarge,  TlsDheSkeChangeY::kYZeroPad};
    343 static ::testing::internal::ParamGenerator<TlsDheSkeChangeY::ChangeYTo> kAllY =
    344    ::testing::ValuesIn(kAllYArr);
    345 static const bool kTrueFalseArr[] = {true, false};
    346 static ::testing::internal::ParamGenerator<bool> kTrueFalse =
    347    ::testing::ValuesIn(kTrueFalseArr);
    348 
    349 INSTANTIATE_TEST_SUITE_P(
    350    DamageYStream, TlsDamageDHYTest,
    351    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
    352                       TlsConnectTestBase::kTlsV10ToV12, kAllY, kTrueFalse));
    353 INSTANTIATE_TEST_SUITE_P(
    354    DamageYDatagram, TlsDamageDHYTest,
    355    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
    356                       TlsConnectTestBase::kTlsV11V12, kAllY, kTrueFalse));
    357 
    358 class TlsDheSkeMakePEven : public TlsHandshakeFilter {
    359 public:
    360  TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& a)
    361      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
    362 
    363  virtual PacketFilter::Action FilterHandshake(
    364      const TlsHandshakeFilter::HandshakeHeader& header,
    365      const DataBuffer& input, DataBuffer* output) {
    366    // Find the end of dh_p
    367    uint32_t dh_len = 0;
    368    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    369    EXPECT_GT(input.len(), 2 + dh_len) << "enough space for dh_p";
    370    size_t offset = 2 + dh_len - 1;
    371    EXPECT_TRUE((input.data()[offset] & 0x01) == 0x01) << "p should be odd";
    372 
    373    *output = input;
    374    output->data()[offset] &= 0xfe;
    375 
    376    return CHANGE;
    377  }
    378 };
    379 
    380 // Even without requiring named groups, an even value for p is bad news.
    381 TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
    382  EnableOnlyDheCiphers();
    383  MakeTlsFilter<TlsDheSkeMakePEven>(server_);
    384 
    385  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    386 
    387  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
    388  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    389 }
    390 
    391 class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
    392 public:
    393  TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& a)
    394      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
    395 
    396  virtual PacketFilter::Action FilterHandshake(
    397      const TlsHandshakeFilter::HandshakeHeader& header,
    398      const DataBuffer& input, DataBuffer* output) {
    399    *output = input;
    400    uint32_t dh_len = 0;
    401    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    402    static const uint8_t kZeroPad = 0;
    403    output->Write(0, dh_len + sizeof(kZeroPad), 2);  // increment the length
    404    output->Splice(&kZeroPad, sizeof(kZeroPad), 2);  // insert a zero
    405 
    406    return CHANGE;
    407  }
    408 };
    409 
    410 // Zero padding only causes signature failure.
    411 TEST_P(TlsConnectGenericPre13, PadDheP) {
    412  EnableOnlyDheCiphers();
    413  MakeTlsFilter<TlsDheSkeZeroPadP>(server_);
    414 
    415  ConnectExpectAlert(client_, kTlsAlertDecryptError);
    416 
    417  // In TLS 1.0 and 1.1, the client reports a device error.
    418  if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
    419    client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
    420  } else {
    421    client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
    422  }
    423  server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    424 }
    425 
    426 // The server should not pick the weak DH group if the client includes FFDHE
    427 // named groups in the supported_groups extension. The server then picks a
    428 // commonly-supported named DH group and this connects.
    429 //
    430 // Note: This test case can take ages to generate the weak DH key.
    431 TEST_P(TlsConnectGenericPre13, WeakDHGroup) {
    432  EnableOnlyDheCiphers();
    433  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    434  EXPECT_EQ(SECSuccess,
    435            SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE));
    436 
    437  Connect();
    438 }
    439 
    440 TEST_P(TlsConnectGeneric, Ffdhe3072) {
    441  EnableOnlyDheCiphers();
    442  static const std::vector<SSLNamedGroup> groups = {ssl_grp_ffdhe_3072};
    443  client_->ConfigNamedGroups(groups);
    444 
    445  Connect();
    446 }
    447 
    448 // Even though the client doesn't have DHE groups enabled the server assumes it
    449 // does. Because the client doesn't require named groups it accepts FF3072 as
    450 // custom group.
    451 TEST_P(TlsConnectGenericPre13, NamedGroupMismatchPre13) {
    452  EnableOnlyDheCiphers();
    453  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
    454  static const std::vector<SSLNamedGroup> client_groups = {
    455      ssl_grp_ec_secp256r1};
    456  server_->ConfigNamedGroups(server_groups);
    457  client_->ConfigNamedGroups(client_groups);
    458 
    459  Connect();
    460  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_custom, ssl_auth_rsa_sign,
    461            ssl_sig_rsa_pss_rsae_sha256);
    462 }
    463 
    464 // Same test but for TLS 1.3. This has to fail.
    465 TEST_P(TlsConnectTls13, NamedGroupMismatch13) {
    466  EnableOnlyDheCiphers();
    467  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
    468  static const std::vector<SSLNamedGroup> client_groups = {
    469      ssl_grp_ec_secp256r1};
    470  server_->ConfigNamedGroups(server_groups);
    471  client_->ConfigNamedGroups(client_groups);
    472 
    473  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
    474  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    475  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    476 }
    477 
    478 // Replace the key share in the server key exchange message with one that's
    479 // larger than 8192 bits.
    480 class TooLongDHEServerKEXFilter : public TlsHandshakeFilter {
    481 public:
    482  TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent>& server)
    483      : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
    484 
    485 protected:
    486  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
    487                                               const DataBuffer& input,
    488                                               DataBuffer* output) {
    489    // Replace the server key exchange message very large DH shares that are
    490    // not supported by NSS.
    491    const uint32_t share_len = 0x401;
    492    const uint8_t zero_share[share_len] = {0x80};
    493    size_t offset = 0;
    494    // Write dh_p.
    495    offset = output->Write(offset, share_len, 2);
    496    offset = output->Write(offset, zero_share, share_len);
    497    // Write dh_g.
    498    offset = output->Write(offset, share_len, 2);
    499    offset = output->Write(offset, zero_share, share_len);
    500    // Write dh_Y.
    501    offset = output->Write(offset, share_len, 2);
    502    offset = output->Write(offset, zero_share, share_len);
    503 
    504    return CHANGE;
    505  }
    506 };
    507 
    508 TEST_P(TlsConnectGenericPre13, TooBigDHGroup) {
    509  EnableOnlyDheCiphers();
    510  MakeTlsFilter<TooLongDHEServerKEXFilter>(server_);
    511  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_FALSE);
    512  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    513  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
    514  client_->CheckErrorCode(SSL_ERROR_DH_KEY_TOO_LONG);
    515 }
    516 
    517 // Even though the client doesn't have DHE groups enabled the server assumes it
    518 // does. The client requires named groups and thus does not accept FF3072 as
    519 // custom group in contrast to the previous test.
    520 TEST_P(TlsConnectGenericPre13, RequireNamedGroupsMismatchPre13) {
    521  EnableOnlyDheCiphers();
    522  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    523  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
    524  static const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
    525                                                           ssl_grp_ffdhe_2048};
    526  server_->ConfigNamedGroups(server_groups);
    527  client_->ConfigNamedGroups(client_groups);
    528 
    529  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
    530  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    531  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    532 }
    533 
    534 TEST_P(TlsConnectGenericPre13, PreferredFfdhe) {
    535  EnableOnlyDheCiphers();
    536  static const SSLDHEGroupType groups[] = {ssl_ff_dhe_3072_group,
    537                                           ssl_ff_dhe_2048_group};
    538  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), groups,
    539                                            PR_ARRAY_SIZE(groups)));
    540 
    541  Connect();
    542  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    543  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    544  client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
    545  server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
    546 }
    547 
    548 TEST_P(TlsConnectGenericPre13, MismatchDHE) {
    549  EnableOnlyDheCiphers();
    550  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
    551  static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group};
    552  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups,
    553                                            PR_ARRAY_SIZE(serverGroups)));
    554  static const SSLDHEGroupType clientGroups[] = {ssl_ff_dhe_2048_group};
    555  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(client_->ssl_fd(), clientGroups,
    556                                            PR_ARRAY_SIZE(clientGroups)));
    557 
    558  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
    559  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    560  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    561 }
    562 
    563 TEST_P(TlsConnectTls13, ResumeFfdhe) {
    564  EnableOnlyDheCiphers();
    565  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
    566  Connect();
    567  SendReceive();  // Need to read so that we absorb the session ticket.
    568  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
    569            ssl_sig_rsa_pss_rsae_sha256);
    570 
    571  Reset();
    572  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
    573  EnableOnlyDheCiphers();
    574  auto clientCapture =
    575      MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
    576  auto serverCapture =
    577      MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_pre_shared_key_xtn);
    578  ExpectResumption(RESUME_TICKET);
    579  Connect();
    580  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
    581            ssl_sig_rsa_pss_rsae_sha256);
    582  ASSERT_LT(0UL, clientCapture->extension().len());
    583  ASSERT_LT(0UL, serverCapture->extension().len());
    584 }
    585 
    586 class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
    587 public:
    588  TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& a, uint16_t version,
    589                           const uint8_t* data, size_t len)
    590      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}),
    591        version_(version),
    592        data_(data),
    593        len_(len) {}
    594 
    595 protected:
    596  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
    597                                               const DataBuffer& input,
    598                                               DataBuffer* output) {
    599    TlsParser parser(input);
    600    EXPECT_TRUE(parser.SkipVariable(2));  // dh_p
    601    EXPECT_TRUE(parser.SkipVariable(2));  // dh_g
    602    EXPECT_TRUE(parser.SkipVariable(2));  // dh_Ys
    603 
    604    // Copy DH params to output.
    605    size_t offset = output->Write(0, input.data(), parser.consumed());
    606 
    607    if (version_ == SSL_LIBRARY_VERSION_TLS_1_2) {
    608      // Write signature algorithm.
    609      offset = output->Write(offset, ssl_sig_dsa_sha256, 2);
    610    }
    611 
    612    // Write new signature.
    613    offset = output->Write(offset, len_, 2);
    614    offset = output->Write(offset, data_, len_);
    615 
    616    return CHANGE;
    617  }
    618 
    619 private:
    620  uint16_t version_;
    621  const uint8_t* data_;
    622  size_t len_;
    623 };
    624 
    625 #ifndef NSS_DISABLE_DSA
    626 TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) {
    627  const uint8_t kBogusDheSignature[] = {
    628      0x30, 0x69, 0x3c, 0x02, 0x1c, 0x7d, 0x0b, 0x2f, 0x64, 0x00, 0x27,
    629      0xae, 0xcf, 0x1e, 0x28, 0x08, 0x6a, 0x7f, 0xb1, 0xbd, 0x78, 0xb5,
    630      0x3b, 0x8c, 0x8f, 0x59, 0xed, 0x8f, 0xee, 0x78, 0xeb, 0x2c, 0xe9,
    631      0x02, 0x1c, 0x6d, 0x7f, 0x3c, 0x0f, 0xf4, 0x44, 0x35, 0x0b, 0xb2,
    632      0x6d, 0xdc, 0xb8, 0x21, 0x87, 0xdd, 0x0d, 0xb9, 0x46, 0x09, 0x3e,
    633      0xef, 0x81, 0x5b, 0x37, 0x09, 0x39, 0xeb};
    634 
    635  Reset(TlsAgent::kServerDsa);
    636 
    637  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048};
    638  client_->ConfigNamedGroups(client_groups);
    639 
    640  MakeTlsFilter<TlsDheSkeChangeSignature>(server_, version_, kBogusDheSignature,
    641                                          sizeof(kBogusDheSignature));
    642 
    643  ConnectExpectAlert(client_, kTlsAlertDecryptError);
    644  client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
    645 }
    646 #endif
    647 
    648 TEST_P(TlsConnectTls12, ConnectInconsistentSigAlgDHE) {
    649  EnableOnlyDheCiphers();
    650 
    651  MakeTlsFilter<DHEServerKEXSigAlgReplacer>(server_,
    652                                            ssl_sig_ecdsa_secp256r1_sha256);
    653  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
    654 }
    655 
    656 static void CheckSkeSigScheme(
    657    std::shared_ptr<TlsHandshakeRecorder>& capture_ske,
    658    uint16_t expected_scheme) {
    659  TlsParser parser(capture_ske->buffer());
    660  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_p";
    661  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_q";
    662  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_Ys";
    663 
    664  uint32_t tmp;
    665  EXPECT_TRUE(parser.Read(&tmp, 2)) << " read sig_scheme";
    666  EXPECT_EQ(expected_scheme, static_cast<uint16_t>(tmp));
    667 }
    668 
    669 TEST_P(TlsConnectTls12, ConnectSigAlgEnabledByPolicyDhe) {
    670  EnableOnlyDheCiphers();
    671 
    672  const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
    673                                                   ssl_sig_rsa_pkcs1_sha384};
    674 
    675  EnsureTlsSetup();
    676  client_->SetSignatureSchemes(schemes.data(), schemes.size());
    677  server_->SetSignatureSchemes(schemes.data(), schemes.size());
    678  auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
    679      server_, kTlsHandshakeServerKeyExchange);
    680 
    681  StartConnect();
    682  client_->Handshake();  // Send ClientHello
    683 
    684  // Enable SHA-1 by policy.
    685  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, NSS_USE_ALG_IN_SSL_KX, 0);
    686  ASSERT_EQ(SECSuccess, rv);
    687  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
    688                              0);
    689  ASSERT_EQ(SECSuccess, rv);
    690 
    691  Handshake();  // Remainder of handshake
    692  // The server should now report that it is connected
    693  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
    694 
    695  CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha1);
    696 }
    697 
    698 TEST_P(TlsConnectTls12, ConnectSigAlgDisabledByPolicyDhe) {
    699  EnableOnlyDheCiphers();
    700 
    701  const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
    702                                                   ssl_sig_rsa_pkcs1_sha384};
    703 
    704  EnsureTlsSetup();
    705  client_->SetSignatureSchemes(schemes.data(), schemes.size());
    706  server_->SetSignatureSchemes(schemes.data(), schemes.size());
    707  auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
    708      server_, kTlsHandshakeServerKeyExchange);
    709 
    710  StartConnect();
    711  client_->Handshake();  // Send ClientHello
    712 
    713  // Disable SHA-1 by policy after sending ClientHello so that CH
    714  // includes SHA-1 signature scheme.
    715  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
    716  ASSERT_EQ(SECSuccess, rv);
    717  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
    718                              0);
    719  ASSERT_EQ(SECSuccess, rv);
    720 
    721  Handshake();  // Remainder of handshake
    722  // The server should now report that it is connected
    723  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
    724 
    725  CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha384);
    726 }
    727 
    728 TEST_P(TlsConnectPre12, ConnectSigAlgDisabledWeakGroupByOption3072DhePre12) {
    729  EnableOnlyDheCiphers();
    730 
    731  // explicitly enable the weak groups
    732  EXPECT_EQ(SECSuccess,
    733            SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE));
    734  EXPECT_EQ(SECSuccess,
    735            SSL_EnableWeakDHEPrimeGroup(client_->ssl_fd(), PR_TRUE));
    736  server_->SetNssOption(NSS_DH_MIN_KEY_SIZE, 3072);
    737  Connect();
    738  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    739  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    740 }
    741 
    742 TEST_P(TlsConnectPre12, ConnectSigAlgDisabledWeakGroupByOption2048DhePre12) {
    743  EnableOnlyDheCiphers();
    744 
    745  // explicitly enable the weak groups
    746  EXPECT_EQ(SECSuccess,
    747            SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE));
    748  EXPECT_EQ(SECSuccess,
    749            SSL_EnableWeakDHEPrimeGroup(client_->ssl_fd(), PR_TRUE));
    750  server_->SetNssOption(NSS_DH_MIN_KEY_SIZE, 2048);
    751  Connect();
    752  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_2048, 2048);
    753  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_2048, 2048);
    754 }
    755 
    756 TEST_P(TlsConnectPre12, ConnectSigAlgDisabledByPolicyDhePre12) {
    757  EnableOnlyDheCiphers();
    758 
    759  EnsureTlsSetup();
    760  StartConnect();
    761  client_->Handshake();  // Send ClientHello
    762 
    763  // Disable SHA-1 by policy.  This will cause the connection fail as
    764  // TLS 1.1 or earlier uses combined SHA-1 + MD5 signature.
    765  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
    766  ASSERT_EQ(SECSuccess, rv);
    767  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
    768                              0);
    769  ASSERT_EQ(SECSuccess, rv);
    770 
    771  server_->ExpectSendAlert(kTlsAlertHandshakeFailure);
    772  client_->ExpectReceiveAlert(kTlsAlertHandshakeFailure);
    773 
    774  // Remainder of handshake
    775  Handshake();
    776 
    777  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
    778 }
    779 
    780 TEST_P(TlsConnectTls12, ConnectSigAlgDisablePreferredGroupByOption3072Dhe) {
    781  EnableOnlyDheCiphers();
    782  static const SSLDHEGroupType dhe_groups[] = {
    783      ssl_ff_dhe_2048_group,  // first in the lists is the preferred group
    784      ssl_ff_dhe_3072_group};
    785 
    786  server_->SetNssOption(NSS_DH_MIN_KEY_SIZE, 3072);
    787  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), &dhe_groups[0],
    788                                            PR_ARRAY_SIZE(dhe_groups)));
    789  Connect();
    790  // our option size should override the preferred group
    791  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    792  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    793 }
    794 
    795 TEST_P(TlsConnectTls12, ConnectSigAlgDisableGroupByOption3072Dhe) {
    796  EnableOnlyDheCiphers();
    797 
    798  server_->SetNssOption(NSS_DH_MIN_KEY_SIZE, 3072);
    799  Connect();
    800  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    801  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
    802 }
    803 
    804 }  // namespace nss_test