/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <functional>
#include <memory>
#include <set>
#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"

#include "gtest_utils.h"
#include "nss_scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"

namespace nss_test {

TEST_P(TlsConnectGeneric, ConnectDhe) {
  EnableOnlyDheCiphers();
  Connect();
  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
  EnsureTlsSetup();
  client_->ConfigNamedGroups(kAllDHEGroups);

  auto groups_capture =
      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
  auto shares_capture =
      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
  std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
                                                         shares_capture};
  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));

  Connect();

  CheckKeys();

  bool ec, dh;
  auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
    if ((group & 0xff00U) == 0x100U) {
      dh = true;
    } else {
      ec = true;
    }
  };
  CheckGroups(groups_capture->extension(), track_group_type);
  CheckShares(shares_capture->extension(), track_group_type);
  EXPECT_TRUE(ec) << "Should include an EC group and share";
  EXPECT_TRUE(dh) << "Should include an FFDHE group and share";
}

TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
  EnableOnlyDheCiphers();
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  auto groups_capture =
      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
  auto shares_capture =
      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
  std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
                                                         shares_capture};
  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));

  Connect();

  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
  auto is_ffdhe = [](SSLNamedGroup group) {
    // The group has to be in this range.
    EXPECT_LE(ssl_grp_ffdhe_2048, group);
    EXPECT_GE(ssl_grp_ffdhe_8192, group);
  };
  CheckGroups(groups_capture->extension(), is_ffdhe);
  if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
    CheckShares(shares_capture->extension(), is_ffdhe);
  } else {
    EXPECT_EQ(0U, shares_capture->extension().len());
  }
}

// Requiring the FFDHE extension on the server alone means that clients won't be
// able to connect using a DHE suite.  They should still connect in TLS 1.3,
// because the client automatically sends the supported groups extension.
TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
  EnableOnlyDheCiphers();
  server_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);

  if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
    Connect();
    CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
  } else {
    ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
    client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
    server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  }
}

class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
 public:
  TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) {
    // Damage the first octet of dh_p.  Anything other than the known prime will
    // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled.
    *output = input;
    output->data()[3] ^= 73;
    return CHANGE;
  }
};

// Changing the prime in the server's key share results in an error.  This will
// invalidate the signature over the ServerKeyShare. That's ok, NSS won't check
// the signature until everything else has been checked.
TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
  EnableOnlyDheCiphers();
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  MakeTlsFilter<TlsDheServerKeyExchangeDamager>(server_);

  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);

  client_->CheckErrorCode(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

class TlsDheSkeChangeY : public TlsHandshakeFilter {
 public:
  enum ChangeYTo {
    kYZero,
    kYOne,
    kYPMinusOne,
    kYGreaterThanP,
    kYTooLarge,
    kYZeroPad
  };

  TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& a, uint8_t handshake_type,
                   ChangeYTo change)
      : TlsHandshakeFilter(a, {handshake_type}), change_Y_(change) {}

 protected:
  void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
               const DataBuffer& prime) {
    static const uint8_t kExtraZero = 0;
    static const uint8_t kTooLargeExtra = 1;

    uint32_t dh_Ys_len;
    EXPECT_TRUE(input.Read(offset, 2, &dh_Ys_len));
    EXPECT_LT(offset + dh_Ys_len, input.len());
    offset += 2;

    // This isn't generally true, but our code pads.
    EXPECT_EQ(prime.len(), dh_Ys_len)
        << "Length of dh_Ys must equal length of dh_p";

    *output = input;
    switch (change_Y_) {
      case kYZero:
        memset(output->data() + offset, 0, prime.len());
        break;

      case kYOne:
        memset(output->data() + offset, 0, prime.len() - 1);
        output->Write(offset + prime.len() - 1, 1U, 1);
        break;

      case kYPMinusOne:
        output->Write(offset, prime);
        EXPECT_TRUE(output->data()[offset + prime.len() - 1] & 0x01)
            << "P must at least be odd";
        --output->data()[offset + prime.len() - 1];
        break;

      case kYGreaterThanP:
        // Set the first 32 octets of Y to 0xff, except the first which we set
        // to p[0].  This will make Y > p.  That is, unless p is Mersenne, or
        // improbably large (but still the same bit length).  We currently only
        // use a fixed prime that isn't a problem for this code.
        EXPECT_LT(0, prime.data()[0]) << "dh_p should not be zero-padded";
        offset = output->Write(offset, prime.data()[0], 1);
        memset(output->data() + offset, 0xff, 31);
        break;

      case kYTooLarge:
        // Increase the dh_Ys length.
        output->Write(offset - 2, prime.len() + sizeof(kTooLargeExtra), 2);
        // Then insert the octet.
        output->Splice(&kTooLargeExtra, sizeof(kTooLargeExtra), offset);
        break;

      case kYZeroPad:
        output->Write(offset - 2, prime.len() + sizeof(kExtraZero), 2);
        output->Splice(&kExtraZero, sizeof(kExtraZero), offset);
        break;
    }
  }

 private:
  ChangeYTo change_Y_;
};

class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
 public:
  TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
                         bool modify)
      : TlsDheSkeChangeY(a, kTlsHandshakeServerKeyExchange, change),
        modify_(modify),
        p_() {}

  const DataBuffer& prime() const { return p_; }

 protected:
  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) override {
    size_t offset = 2;
    // Read dh_p
    uint32_t dh_len = 0;
    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    EXPECT_GT(input.len(), offset + dh_len);
    p_.Assign(input.data() + offset, dh_len);
    offset += dh_len;

    // Skip dh_g to find dh_Ys
    EXPECT_TRUE(input.Read(offset, 2, &dh_len));
    offset += 2 + dh_len;

    if (modify_) {
      ChangeY(input, output, offset, p_);
      return CHANGE;
    }
    return KEEP;
  }

 private:
  bool modify_;
  DataBuffer p_;
};

class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
 public:
  TlsDheSkeChangeYClient(
      const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
      std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)
      : TlsDheSkeChangeY(a, kTlsHandshakeClientKeyExchange, change),
        server_filter_(server_filter) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) override {
    ChangeY(input, output, 0, server_filter_->prime());
    return CHANGE;
  }

 private:
  std::shared_ptr<const TlsDheSkeChangeYServer> server_filter_;
};

/* This matrix includes: variant (stream/datagram), TLS version, what change to
 * make to dh_Ys, whether the client will be configured to require DH named
 * groups.  Test all combinations. */
typedef std::tuple<SSLProtocolVariant, uint16_t, TlsDheSkeChangeY::ChangeYTo,
                   bool>
    DamageDHYProfile;
class TlsDamageDHYTest
    : public TlsConnectTestBase,
      public ::testing::WithParamInterface<DamageDHYProfile> {
 public:
  TlsDamageDHYTest()
      : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
};

TEST_P(TlsDamageDHYTest, DamageServerY) {
  EnableOnlyDheCiphers();
  if (std::get<3>(GetParam())) {
    client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  }
  TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
  MakeTlsFilter<TlsDheSkeChangeYServer>(server_, change, true);

  if (change == TlsDheSkeChangeY::kYZeroPad) {
    ExpectAlert(client_, kTlsAlertDecryptError);
  } else {
    ExpectAlert(client_, kTlsAlertIllegalParameter);
  }
  ConnectExpectFail();
  if (change == TlsDheSkeChangeY::kYZeroPad) {
    // Zero padding Y only manifests in a signature failure.
    // In TLS 1.0 and 1.1, the client reports a device error.
    if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
      client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
    } else {
      client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
    }
    server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
  } else {
    client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
    server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  }
}

TEST_P(TlsDamageDHYTest, DamageClientY) {
  EnableOnlyDheCiphers();
  if (std::get<3>(GetParam())) {
    client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  }
  // The filter on the server is required to capture the prime.
  auto server_filter = MakeTlsFilter<TlsDheSkeChangeYServer>(
      server_, TlsDheSkeChangeY::kYZero, false);

  // The client filter does the damage.
  TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
  MakeTlsFilter<TlsDheSkeChangeYClient>(client_, change, server_filter);

  if (change == TlsDheSkeChangeY::kYZeroPad) {
    ExpectAlert(server_, kTlsAlertDecryptError);
  } else {
    ExpectAlert(server_, kTlsAlertHandshakeFailure);
  }
  ConnectExpectFail();
  if (change == TlsDheSkeChangeY::kYZeroPad) {
    // Zero padding Y only manifests in a finished error.
    client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
    server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
  } else {
    client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
    server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
  }
}

static const TlsDheSkeChangeY::ChangeYTo kAllYArr[] = {
    TlsDheSkeChangeY::kYZero,      TlsDheSkeChangeY::kYOne,
    TlsDheSkeChangeY::kYPMinusOne, TlsDheSkeChangeY::kYGreaterThanP,
    TlsDheSkeChangeY::kYTooLarge,  TlsDheSkeChangeY::kYZeroPad};
static ::testing::internal::ParamGenerator<TlsDheSkeChangeY::ChangeYTo> kAllY =
    ::testing::ValuesIn(kAllYArr);
static const bool kTrueFalseArr[] = {true, false};
static ::testing::internal::ParamGenerator<bool> kTrueFalse =
    ::testing::ValuesIn(kTrueFalseArr);

INSTANTIATE_TEST_SUITE_P(
    DamageYStream, TlsDamageDHYTest,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsV10ToV12, kAllY, kTrueFalse));
INSTANTIATE_TEST_SUITE_P(
    DamageYDatagram, TlsDamageDHYTest,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11V12, kAllY, kTrueFalse));

class TlsDheSkeMakePEven : public TlsHandshakeFilter {
 public:
  TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}

  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) {
    // Find the end of dh_p
    uint32_t dh_len = 0;
    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    EXPECT_GT(input.len(), 2 + dh_len) << "enough space for dh_p";
    size_t offset = 2 + dh_len - 1;
    EXPECT_TRUE((input.data()[offset] & 0x01) == 0x01) << "p should be odd";

    *output = input;
    output->data()[offset] &= 0xfe;

    return CHANGE;
  }
};

// Even without requiring named groups, an even value for p is bad news.
TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
  EnableOnlyDheCiphers();
  MakeTlsFilter<TlsDheSkeMakePEven>(server_);

  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);

  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
 public:
  TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}

  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) {
    *output = input;
    uint32_t dh_len = 0;
    EXPECT_TRUE(input.Read(0, 2, &dh_len));
    static const uint8_t kZeroPad = 0;
    output->Write(0, dh_len + sizeof(kZeroPad), 2);  // increment the length
    output->Splice(&kZeroPad, sizeof(kZeroPad), 2);  // insert a zero

    return CHANGE;
  }
};

// Zero padding only causes signature failure.
TEST_P(TlsConnectGenericPre13, PadDheP) {
  EnableOnlyDheCiphers();
  MakeTlsFilter<TlsDheSkeZeroPadP>(server_);

  ConnectExpectAlert(client_, kTlsAlertDecryptError);

  // In TLS 1.0 and 1.1, the client reports a device error.
  if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
    client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
  } else {
    client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
  }
  server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
}

// The server should not pick the weak DH group if the client includes FFDHE
// named groups in the supported_groups extension. The server then picks a
// commonly-supported named DH group and this connects.
//
// Note: This test case can take ages to generate the weak DH key.
TEST_P(TlsConnectGenericPre13, WeakDHGroup) {
  EnableOnlyDheCiphers();
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  EXPECT_EQ(SECSuccess,
            SSL_EnableWeakDHEPrimeGroup(server_->ssl_fd(), PR_TRUE));

  Connect();
}

TEST_P(TlsConnectGeneric, Ffdhe3072) {
  EnableOnlyDheCiphers();
  static const std::vector<SSLNamedGroup> groups = {ssl_grp_ffdhe_3072};
  client_->ConfigNamedGroups(groups);

  Connect();
}

// Even though the client doesn't have DHE groups enabled the server assumes it
// does. Because the client doesn't require named groups it accepts FF3072 as
// custom group.
TEST_P(TlsConnectGenericPre13, NamedGroupMismatchPre13) {
  EnableOnlyDheCiphers();
  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
  static const std::vector<SSLNamedGroup> client_groups = {
      ssl_grp_ec_secp256r1};
  server_->ConfigNamedGroups(server_groups);
  client_->ConfigNamedGroups(client_groups);

  Connect();
  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_custom, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

// Same test but for TLS 1.3. This has to fail.
TEST_P(TlsConnectTls13, NamedGroupMismatch13) {
  EnableOnlyDheCiphers();
  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
  static const std::vector<SSLNamedGroup> client_groups = {
      ssl_grp_ec_secp256r1};
  server_->ConfigNamedGroups(server_groups);
  client_->ConfigNamedGroups(client_groups);

  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

// Replace the key share in the server key exchange message with one that's
// larger than 8192 bits.
class TooLongDHEServerKEXFilter : public TlsHandshakeFilter {
 public:
  TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent>& server)
      : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                               const DataBuffer& input,
                                               DataBuffer* output) {
    // Replace the server key exchange message very large DH shares that are
    // not supported by NSS.
    const uint32_t share_len = 0x401;
    const uint8_t zero_share[share_len] = {0x80};
    size_t offset = 0;
    // Write dh_p.
    offset = output->Write(offset, share_len, 2);
    offset = output->Write(offset, zero_share, share_len);
    // Write dh_g.
    offset = output->Write(offset, share_len, 2);
    offset = output->Write(offset, zero_share, share_len);
    // Write dh_Y.
    offset = output->Write(offset, share_len, 2);
    offset = output->Write(offset, zero_share, share_len);

    return CHANGE;
  }
};

TEST_P(TlsConnectGenericPre13, TooBigDHGroup) {
  EnableOnlyDheCiphers();
  MakeTlsFilter<TooLongDHEServerKEXFilter>(server_);
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_FALSE);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_DH_KEY_TOO_LONG);
}

// Even though the client doesn't have DHE groups enabled the server assumes it
// does. The client requires named groups and thus does not accept FF3072 as
// custom group in contrast to the previous test.
TEST_P(TlsConnectGenericPre13, RequireNamedGroupsMismatchPre13) {
  EnableOnlyDheCiphers();
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  static const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_3072};
  static const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
                                                           ssl_grp_ffdhe_2048};
  server_->ConfigNamedGroups(server_groups);
  client_->ConfigNamedGroups(client_groups);

  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

TEST_P(TlsConnectGenericPre13, PreferredFfdhe) {
  EnableOnlyDheCiphers();
  static const SSLDHEGroupType groups[] = {ssl_ff_dhe_3072_group,
                                           ssl_ff_dhe_2048_group};
  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), groups,
                                            PR_ARRAY_SIZE(groups)));

  Connect();
  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
  client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
  server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}

TEST_P(TlsConnectGenericPre13, MismatchDHE) {
  EnableOnlyDheCiphers();
  client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
  static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group};
  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups,
                                            PR_ARRAY_SIZE(serverGroups)));
  static const SSLDHEGroupType clientGroups[] = {ssl_ff_dhe_2048_group};
  EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(client_->ssl_fd(), clientGroups,
                                            PR_ARRAY_SIZE(clientGroups)));

  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

TEST_P(TlsConnectTls13, ResumeFfdhe) {
  EnableOnlyDheCiphers();
  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
  Connect();
  SendReceive();  // Need to read so that we absorb the session ticket.
  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);

  Reset();
  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
  EnableOnlyDheCiphers();
  auto clientCapture =
      MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
  auto serverCapture =
      MakeTlsFilter<TlsExtensionCapture>(server_, ssl_tls13_pre_shared_key_xtn);
  ExpectResumption(RESUME_TICKET);
  Connect();
  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  ASSERT_LT(0UL, clientCapture->extension().len());
  ASSERT_LT(0UL, serverCapture->extension().len());
}

class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
 public:
  TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& a, uint16_t version,
                           const uint8_t* data, size_t len)
      : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}),
        version_(version),
        data_(data),
        len_(len) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                               const DataBuffer& input,
                                               DataBuffer* output) {
    TlsParser parser(input);
    EXPECT_TRUE(parser.SkipVariable(2));  // dh_p
    EXPECT_TRUE(parser.SkipVariable(2));  // dh_g
    EXPECT_TRUE(parser.SkipVariable(2));  // dh_Ys

    // Copy DH params to output.
    size_t offset = output->Write(0, input.data(), parser.consumed());

    if (version_ == SSL_LIBRARY_VERSION_TLS_1_2) {
      // Write signature algorithm.
      offset = output->Write(offset, ssl_sig_dsa_sha256, 2);
    }

    // Write new signature.
    offset = output->Write(offset, len_, 2);
    offset = output->Write(offset, data_, len_);

    return CHANGE;
  }

 private:
  uint16_t version_;
  const uint8_t* data_;
  size_t len_;
};

TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) {
  const uint8_t kBogusDheSignature[] = {
      0x30, 0x69, 0x3c, 0x02, 0x1c, 0x7d, 0x0b, 0x2f, 0x64, 0x00, 0x27,
      0xae, 0xcf, 0x1e, 0x28, 0x08, 0x6a, 0x7f, 0xb1, 0xbd, 0x78, 0xb5,
      0x3b, 0x8c, 0x8f, 0x59, 0xed, 0x8f, 0xee, 0x78, 0xeb, 0x2c, 0xe9,
      0x02, 0x1c, 0x6d, 0x7f, 0x3c, 0x0f, 0xf4, 0x44, 0x35, 0x0b, 0xb2,
      0x6d, 0xdc, 0xb8, 0x21, 0x87, 0xdd, 0x0d, 0xb9, 0x46, 0x09, 0x3e,
      0xef, 0x81, 0x5b, 0x37, 0x09, 0x39, 0xeb};

  Reset(TlsAgent::kServerDsa);

  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048};
  client_->ConfigNamedGroups(client_groups);

  MakeTlsFilter<TlsDheSkeChangeSignature>(server_, version_, kBogusDheSignature,
                                          sizeof(kBogusDheSignature));

  ConnectExpectAlert(client_, kTlsAlertDecryptError);
  client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
}

// Replace SignatureAndHashAlgorithm of a SKE.
class DHEServerKEXSigAlgReplacer : public TlsHandshakeFilter {
 public:
  DHEServerKEXSigAlgReplacer(const std::shared_ptr<TlsAgent>& server,
                             SSLSignatureScheme sig_scheme)
      : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
        sig_scheme_(sig_scheme) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                               const DataBuffer& input,
                                               DataBuffer* output) {
    *output = input;

    uint32_t len;
    uint32_t idx = 0;
    EXPECT_TRUE(output->Read(idx, 2, &len));
    idx += 2 + len;
    EXPECT_TRUE(output->Read(idx, 2, &len));
    idx += 2 + len;
    EXPECT_TRUE(output->Read(idx, 2, &len));
    idx += 2 + len;
    output->Write(idx, sig_scheme_, 2);

    return CHANGE;
  }

 private:
  SSLSignatureScheme sig_scheme_;
};

TEST_P(TlsConnectTls12, ConnectInconsistentSigAlgDHE) {
  EnableOnlyDheCiphers();

  MakeTlsFilter<DHEServerKEXSigAlgReplacer>(server_,
                                            ssl_sig_ecdsa_secp256r1_sha256);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
}

static void CheckSkeSigScheme(
    std::shared_ptr<TlsHandshakeRecorder>& capture_ske,
    uint16_t expected_scheme) {
  TlsParser parser(capture_ske->buffer());
  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_p";
  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_q";
  EXPECT_TRUE(parser.SkipVariable(2)) << " read dh_Ys";

  uint32_t tmp;
  EXPECT_TRUE(parser.Read(&tmp, 2)) << " read sig_scheme";
  EXPECT_EQ(expected_scheme, static_cast<uint16_t>(tmp));
}

TEST_P(TlsConnectTls12, ConnectSigAlgEnabledByPolicyDhe) {
  EnableOnlyDheCiphers();

  const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
                                                   ssl_sig_rsa_pkcs1_sha384};

  EnsureTlsSetup();
  client_->SetSignatureSchemes(schemes.data(), schemes.size());
  server_->SetSignatureSchemes(schemes.data(), schemes.size());
  auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
      server_, kTlsHandshakeServerKeyExchange);

  StartConnect();
  client_->Handshake();  // Send ClientHello

  // Enable SHA-1 by policy.
  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, NSS_USE_ALG_IN_SSL_KX, 0);
  ASSERT_EQ(SECSuccess, rv);
  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
                              0);
  ASSERT_EQ(SECSuccess, rv);

  Handshake();  // Remainder of handshake
  // The server should now report that it is connected
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());

  CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha1);
}

TEST_P(TlsConnectTls12, ConnectSigAlgDisabledByPolicyDhe) {
  EnableOnlyDheCiphers();

  const std::vector<SSLSignatureScheme> schemes = {ssl_sig_rsa_pkcs1_sha1,
                                                   ssl_sig_rsa_pkcs1_sha384};

  EnsureTlsSetup();
  client_->SetSignatureSchemes(schemes.data(), schemes.size());
  server_->SetSignatureSchemes(schemes.data(), schemes.size());
  auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
      server_, kTlsHandshakeServerKeyExchange);

  StartConnect();
  client_->Handshake();  // Send ClientHello

  // Disable SHA-1 by policy after sending ClientHello so that CH
  // includes SHA-1 signature scheme.
  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
  ASSERT_EQ(SECSuccess, rv);
  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
                              0);
  ASSERT_EQ(SECSuccess, rv);

  Handshake();  // Remainder of handshake
  // The server should now report that it is connected
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());

  CheckSkeSigScheme(capture_ske, ssl_sig_rsa_pkcs1_sha384);
}

TEST_P(TlsConnectPre12, ConnectSigAlgDisabledByPolicyDhePre12) {
  EnableOnlyDheCiphers();

  EnsureTlsSetup();
  StartConnect();
  client_->Handshake();  // Send ClientHello

  // Disable SHA-1 by policy.  This will cause the connection fail as
  // TLS 1.1 or earlier uses combined SHA-1 + MD5 signature.
  SECStatus rv = NSS_SetAlgorithmPolicy(SEC_OID_SHA1, 0, NSS_USE_ALG_IN_SSL_KX);
  ASSERT_EQ(SECSuccess, rv);
  rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
                              0);
  ASSERT_EQ(SECSuccess, rv);

  server_->ExpectSendAlert(kTlsAlertHandshakeFailure);
  client_->ExpectReceiveAlert(kTlsAlertHandshakeFailure);

  // Remainder of handshake
  Handshake();

  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
}

}  // namespace nss_test
