/* -*- 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 "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"

extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.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(TlsConnectGenericPre13, ConnectEcdh) {
  SetExpectedVersion(std::get<1>(GetParam()));
  Reset(TlsAgent::kServerEcdhEcdsa);
  DisableAllCiphers();
  EnableSomeEcdhCiphers();

  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_ecdh_ecdsa,
            ssl_sig_none);
}

TEST_P(TlsConnectGenericPre13, ConnectEcdhWithoutDisablingSuites) {
  SetExpectedVersion(std::get<1>(GetParam()));
  Reset(TlsAgent::kServerEcdhEcdsa);
  EnableSomeEcdhCiphers();

  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_ecdh_ecdsa,
            ssl_sig_none);
}

TEST_P(TlsConnectGeneric, ConnectEcdhe) {
  Connect();
  CheckKeys();
}

// If we pick a 256-bit cipher suite and use a P-384 certificate, the server
// should choose P-384 for key exchange too.  Only valid for TLS == 1.2 because
// we don't have 256-bit ciphers before then and 1.3 doesn't try to couple
// DHE size to symmetric size.
TEST_P(TlsConnectTls12, ConnectEcdheP384) {
  Reset(TlsAgent::kServerEcdsa384);
  ConnectWithCipherSuite(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_ecdsa,
            ssl_sig_ecdsa_secp256r1_sha256);
}

TEST_P(TlsConnectGeneric, ConnectEcdheP384Client) {
  EnsureTlsSetup();
  const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                             ssl_grp_ffdhe_2048};
  client_->ConfigNamedGroups(groups);
  server_->ConfigNamedGroups(groups);
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

// This causes a HelloRetryRequest in TLS 1.3.  Earlier versions don't care.
TEST_P(TlsConnectGeneric, ConnectEcdheP384Server) {
  EnsureTlsSetup();
  auto hrr_capture = MakeTlsFilter<TlsHandshakeRecorder>(
      server_, kTlsHandshakeHelloRetryRequest);
  const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
  server_->ConfigNamedGroups(groups);
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  EXPECT_EQ(version_ == SSL_LIBRARY_VERSION_TLS_1_3,
            hrr_capture->buffer().len() != 0);
}

// This enables only P-256 on the client and disables it on the server.
// This test will fail when we add other groups that identify as ECDHE.
TEST_P(TlsConnectGeneric, ConnectEcdheGroupMismatch) {
  EnsureTlsSetup();
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ffdhe_2048};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_2048};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

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

TEST_P(TlsKeyExchangeTest, P384Priority) {
  // P256, P384 and P521 are enabled. Both prefer P384.
  const std::vector<SSLNamedGroup> groups = {
      ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
  EnsureKeyShareSetup();
  ConfigNamedGroups(groups);
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);

  std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
  CheckKEXDetails(groups, shares);
}

TEST_P(TlsKeyExchangeTest, DuplicateGroupConfig) {
  const std::vector<SSLNamedGroup> groups = {
      ssl_grp_ec_secp384r1, ssl_grp_ec_secp384r1, ssl_grp_ec_secp384r1,
      ssl_grp_ec_secp256r1, ssl_grp_ec_secp256r1};
  EnsureKeyShareSetup();
  ConfigNamedGroups(groups);
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);

  std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
  std::vector<SSLNamedGroup> expectedGroups = {ssl_grp_ec_secp384r1,
                                               ssl_grp_ec_secp256r1};
  CheckKEXDetails(expectedGroups, shares);
}

TEST_P(TlsKeyExchangeTest, P384PriorityDHEnabled) {
  // P256, P384,  P521, and FFDHE2048 are enabled. Both prefer P384.
  const std::vector<SSLNamedGroup> groups = {
      ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048, ssl_grp_ec_secp256r1,
      ssl_grp_ec_secp521r1};
  EnsureKeyShareSetup();
  ConfigNamedGroups(groups);
  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);

  if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
    std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
    CheckKEXDetails(groups, shares);
  } else {
    std::vector<SSLNamedGroup> oldtlsgroups = {
        ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
    CheckKEXDetails(oldtlsgroups, std::vector<SSLNamedGroup>());
  }
}

TEST_P(TlsConnectGenericPre13, P384PriorityOnServer) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  // The server prefers P384. It has to win.
  const std::vector<SSLNamedGroup> server_groups = {
      ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

TEST_P(TlsConnectGenericPre13, P384PriorityFromModelSocket) {
  EnsureModelSockets();

  /* Both prefer P384, set on the model socket. */
  const std::vector<SSLNamedGroup> groups = {
      ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1,
      ssl_grp_ffdhe_2048};
  client_model_->ConfigNamedGroups(groups);
  server_model_->ConfigNamedGroups(groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

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

  SSLNamedGroup group() const { return group_; }

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                               const DataBuffer &input,
                                               DataBuffer *output) {
    uint32_t value = 0;
    EXPECT_TRUE(input.Read(0, 1, &value));
    EXPECT_EQ(3U, value) << "curve type has to be 3";

    EXPECT_TRUE(input.Read(1, 2, &value));
    group_ = static_cast<SSLNamedGroup>(value);

    return KEEP;
  }

 private:
  SSLNamedGroup group_;
};

// If we strip the client's supported groups extension, the server should assume
// P-256 is supported by the client (<= 1.2 only).
TEST_P(TlsConnectGenericPre13, DropSupportedGroupExtensionP256) {
  EnsureTlsSetup();
  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_supported_groups_xtn);
  auto group_capture = MakeTlsFilter<TlsKeyExchangeGroupCapture>(server_);

  ConnectExpectAlert(server_, kTlsAlertDecryptError);
  client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
  server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);

  EXPECT_EQ(ssl_grp_ec_secp256r1, group_capture->group());
}

// Supported groups is mandatory in TLS 1.3.
TEST_P(TlsConnectTls13, DropSupportedGroupExtension) {
  EnsureTlsSetup();
  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_supported_groups_xtn);
  ConnectExpectAlert(server_, kTlsAlertMissingExtension);
  client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
  server_->CheckErrorCode(SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION);
}

// If we only have a lame group, we fall back to static RSA.
TEST_P(TlsConnectGenericPre13, UseLameGroup) {
  const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp192r1};
  client_->ConfigNamedGroups(groups);
  server_->ConfigNamedGroups(groups);
  Connect();
  CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
}

// In TLS 1.3, we can't generate the ClientHello.
TEST_P(TlsConnectTls13, UseLameGroup) {
  const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_sect283k1};
  client_->ConfigNamedGroups(groups);
  server_->ConfigNamedGroups(groups);
  client_->StartConnect();
  client_->Handshake();
  client_->CheckErrorCode(SSL_ERROR_NO_CIPHERS_SUPPORTED);
}

TEST_P(TlsConnectStreamPre13, ConfiguredGroupsRenegotiate) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_secp256r1};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  CheckConnected();

  // The renegotiation has to use the same preferences as the original session.
  server_->PrepareForRenegotiate();
  client_->StartRenegotiate();
  Handshake();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

TEST_P(TlsKeyExchangeTest, Curve25519) {
  Reset(TlsAgent::kServerEcdsa256);
  const std::vector<SSLNamedGroup> groups = {
      ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
  EnsureKeyShareSetup();
  ConfigNamedGroups(groups);
  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_ecdsa,
            ssl_sig_ecdsa_secp256r1_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(groups, shares);
}

TEST_P(TlsConnectGenericPre13, GroupPreferenceServerPriority) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  // The client prefers P256 while the server prefers 25519.
  // The server's preference has to win.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_curve25519};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
}

#ifndef NSS_DISABLE_TLS_1_3
TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityClient13) {
  EnsureKeyShareSetup();

  // The client sends a P256 key share while the server prefers 25519.
  // We have to accept P256 without retry.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_curve25519};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp256r1};
  CheckKEXDetails(client_groups, shares);
}

TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityServer13) {
  EnsureKeyShareSetup();

  // The client sends a 25519 key share while the server prefers P256.
  // We have to accept 25519 without retry.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares);
}

TEST_P(TlsKeyExchangeTest13, EqualPriorityTestRetryECServer13) {
  EnsureKeyShareSetup();

  // The client sends a 25519 key share while the server prefers P256.
  // The server prefers P-384 over x25519, so it must not consider P-256 and
  // x25519 to be equivalent. It will therefore request a P-256 share
  // with a HelloRetryRequest.
  const std::vector<SSLNamedGroup> client_groups = {
      ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1};
  const std::vector<SSLNamedGroup> server_groups = {
      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1);
}

TEST_P(TlsKeyExchangeTest13, NotEqualPriorityWithIntermediateGroup13) {
  EnsureKeyShareSetup();

  // The client sends a 25519 key share while the server prefers P256.
  // The server prefers ffdhe_2048 over x25519, so it must not consider the
  // P-256 and x25519 to be equivalent. It will therefore request a P-256 share
  // with a HelloRetryRequest.
  const std::vector<SSLNamedGroup> client_groups = {
      ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048};
  const std::vector<SSLNamedGroup> server_groups = {
      ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048, ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1);
}

TEST_P(TlsKeyExchangeTest13,
       NotEqualPriorityWithUnsupportedFFIntermediateGroup13) {
  EnsureKeyShareSetup();

  // As in the previous test, the server prefers ffdhe_2048. Thus, even though
  // the client doesn't support this group, the server must not regard x25519 as
  // equivalent to P-256.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {
      ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048, ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1);
}

TEST_P(TlsKeyExchangeTest13,
       NotEqualPriorityWithUnsupportedECIntermediateGroup13) {
  EnsureKeyShareSetup();

  // As in the previous test, the server prefers P-384. Thus, even though
  // the client doesn't support this group, the server must not regard x25519 as
  // equivalent to P-256. The server sends a HelloRetryRequest.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {
      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares, ssl_grp_ec_secp256r1);
}

TEST_P(TlsKeyExchangeTest13, EqualPriority13) {
  EnsureKeyShareSetup();

  // The client sends a 25519 key share while the server prefers P256.
  // We have to accept 25519 without retry because it's considered equivalent to
  // P256 by the server.
  const std::vector<SSLNamedGroup> client_groups = {
      ssl_grp_ec_curve25519, ssl_grp_ffdhe_2048, ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  Connect();

  CheckKeys();
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
  CheckKEXDetails(client_groups, shares);
}
#endif

TEST_P(TlsConnectGeneric, P256ClientAndCurve25519Server) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  // The client sends a P256 key share while the server prefers 25519.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519};

  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

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

TEST_P(TlsKeyExchangeTest13, MultipleClientShares) {
  EnsureKeyShareSetup();

  // The client sends 25519 and P256 key shares. The server prefers P256,
  // which must be chosen here.
  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
                                                    ssl_grp_ec_secp256r1};
  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
                                                    ssl_grp_ec_curve25519};
  client_->ConfigNamedGroups(client_groups);
  server_->ConfigNamedGroups(server_groups);

  // Generate a key share on the client for both curves.
  EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));

  Connect();

  // The server would accept 25519 but its preferred group (P256) has to win.
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
            ssl_sig_rsa_pss_rsae_sha256);
  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519,
                                             ssl_grp_ec_secp256r1};
  CheckKEXDetails(client_groups, shares);
}

// Replace the point in the client key exchange message with an empty one
class ECCClientKEXFilter : public TlsHandshakeFilter {
 public:
  ECCClientKEXFilter(const std::shared_ptr<TlsAgent> &client)
      : TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                               const DataBuffer &input,
                                               DataBuffer *output) {
    // Replace the client key exchange message with an empty point
    output->Allocate(1);
    output->Write(0, 0U, 1);  // set point length 0
    return CHANGE;
  }
};

// Replace the point in the server key exchange message with an empty one
class ECCServerKEXFilter : public TlsHandshakeFilter {
 public:
  ECCServerKEXFilter(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 with an empty point
    output->Allocate(4);
    output->Write(0, 3U, 1);  // named curve
    uint32_t curve = 0;
    EXPECT_TRUE(input.Read(1, 2, &curve));  // get curve id
    output->Write(1, curve, 2);             // write curve id
    output->Write(3, 0U, 1);                // point length 0
    return CHANGE;
  }
};

TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyServerPoint) {
  MakeTlsFilter<ECCServerKEXFilter>(server_);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH);
}

TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyClientPoint) {
  MakeTlsFilter<ECCClientKEXFilter>(client_);
  ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
}

// Damage ECParams/ECPoint of a SKE.
class ECCServerKEXDamager : public TlsHandshakeFilter {
 public:
  ECCServerKEXDamager(const std::shared_ptr<TlsAgent> &server, ECType ec_type,
                      SSLNamedGroup named_curve)
      : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
        ec_type_(ec_type),
        named_curve_(named_curve) {}

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                               const DataBuffer &input,
                                               DataBuffer *output) {
    size_t offset = 0;
    output->Allocate(5);
    offset = output->Write(offset, ec_type_, 1);
    offset = output->Write(offset, named_curve_, 2);
    // Write a point with fmt != EC_POINT_FORM_UNCOMPRESSED.
    offset = output->Write(offset, 1U, 1);
    (void)output->Write(offset, 0x02, 1);  // EC_POINT_FORM_COMPRESSED_Y0
    return CHANGE;
  }

 private:
  ECType ec_type_;
  SSLNamedGroup named_curve_;
};

TEST_P(TlsConnectGenericPre13, ConnectUnsupportedCurveType) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_explicitPrime,
                                     ssl_grp_none);
  ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
  client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
}

TEST_P(TlsConnectGenericPre13, ConnectUnsupportedCurve) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_named,
                                     ssl_grp_ffdhe_2048);
  ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
  client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
}

TEST_P(TlsConnectGenericPre13, ConnectUnsupportedPointFormat) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_named,
                                     ssl_grp_ec_secp256r1);
  ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
  client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
}

// Replace SignatureAndHashAlgorithm of a SKE.
class ECCServerKEXSigAlgReplacer : public TlsHandshakeFilter {
 public:
  ECCServerKEXSigAlgReplacer(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 point_len;
    EXPECT_TRUE(output->Read(3, 1, &point_len));
    output->Write(4 + point_len, sig_scheme_, 2);

    return CHANGE;
  }

 private:
  SSLSignatureScheme sig_scheme_;
};

TEST_P(TlsConnectTls12, ConnectUnsupportedSigAlg) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  MakeTlsFilter<ECCServerKEXSigAlgReplacer>(server_, ssl_sig_none);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
}

TEST_P(TlsConnectTls12, ConnectIncorrectSigAlg) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

  MakeTlsFilter<ECCServerKEXSigAlgReplacer>(server_,
                                            ssl_sig_ecdsa_secp256r1_sha256);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
}

static void CheckSkeSigScheme(
    std::shared_ptr<TlsHandshakeRecorder> &capture_ske,
    uint16_t expected_scheme) {
  TlsParser parser(capture_ske->buffer());
  uint32_t tmp = 0;
  EXPECT_TRUE(parser.Read(&tmp, 1)) << " read curve_type";
  EXPECT_EQ(3U, tmp) << "curve type has to be 3";
  EXPECT_TRUE(parser.Skip(2)) << " read namedcurve";
  EXPECT_TRUE(parser.SkipVariable(1)) << " read public";

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

TEST_P(TlsConnectTls12, ConnectSigAlgEnabledByPolicy) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

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

  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, ConnectSigAlgDisabledByPolicy) {
  EnsureTlsSetup();
  client_->DisableAllCiphers();
  client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);

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

  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.
  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);
}

INSTANTIATE_TEST_SUITE_P(KeyExchangeTest, TlsKeyExchangeTest,
                         ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                                            TlsConnectTestBase::kTlsV11Plus));

#ifndef NSS_DISABLE_TLS_1_3
INSTANTIATE_TEST_SUITE_P(KeyExchangeTest, TlsKeyExchangeTest13,
                         ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                                            TlsConnectTestBase::kTlsV13));
#endif

}  // namespace nss_test
