/* -*- 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 "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(TlsConnectGeneric, ServerAuthBigRsa) {
  Reset(TlsAgent::kRsa2048);
  Connect();
  CheckKeys();
}

TEST_P(TlsConnectGeneric, ServerAuthRsaChain) {
  Reset("rsa_chain");
  Connect();
  CheckKeys();
  size_t chain_length;
  EXPECT_TRUE(client_->GetPeerChainLength(&chain_length));
  EXPECT_EQ(2UL, chain_length);
}

TEST_P(TlsConnectTls12Plus, ServerAuthRsaPss) {
  static const SSLSignatureScheme kSignatureSchemePss[] = {
      ssl_sig_rsa_pss_pss_sha256};

  Reset(TlsAgent::kServerRsaPss);
  client_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  server_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
            ssl_sig_rsa_pss_pss_sha256);
}

// PSS doesn't work with TLS 1.0 or 1.1 because we can't signal it.
TEST_P(TlsConnectPre12, ServerAuthRsaPssFails) {
  static const SSLSignatureScheme kSignatureSchemePss[] = {
      ssl_sig_rsa_pss_pss_sha256};

  Reset(TlsAgent::kServerRsaPss);
  client_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  server_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

// Check that a PSS certificate with no parameters works.
TEST_P(TlsConnectTls12Plus, ServerAuthRsaPssNoParameters) {
  static const SSLSignatureScheme kSignatureSchemePss[] = {
      ssl_sig_rsa_pss_pss_sha256};

  Reset("rsa_pss_noparam");
  client_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  server_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
            ssl_sig_rsa_pss_pss_sha256);
}

TEST_P(TlsConnectGeneric, ServerAuthRsaPssChain) {
  Reset("rsa_pss_chain");
  Connect();
  CheckKeys();
  size_t chain_length;
  EXPECT_TRUE(client_->GetPeerChainLength(&chain_length));
  EXPECT_EQ(2UL, chain_length);
}

TEST_P(TlsConnectGeneric, ServerAuthRsaCARsaPssChain) {
  Reset("rsa_ca_rsa_pss_chain");
  Connect();
  CheckKeys();
  size_t chain_length;
  EXPECT_TRUE(client_->GetPeerChainLength(&chain_length));
  EXPECT_EQ(2UL, chain_length);
}

TEST_P(TlsConnectGeneric, ServerAuthRejected) {
  EnsureTlsSetup();
  client_->SetAuthCertificateCallback(
      [](TlsAgent*, PRBool, PRBool) -> SECStatus { return SECFailure; });
  ConnectExpectAlert(client_, kTlsAlertBadCertificate);
  client_->CheckErrorCode(SSL_ERROR_BAD_CERTIFICATE);
  server_->CheckErrorCode(SSL_ERROR_BAD_CERT_ALERT);
  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
}

struct AuthCompleteArgs : public PollTarget {
  AuthCompleteArgs(const std::shared_ptr<TlsAgent>& a, PRErrorCode c)
      : agent(a), code(c) {}

  std::shared_ptr<TlsAgent> agent;
  PRErrorCode code;
};

static void CallAuthComplete(PollTarget* target, Event event) {
  EXPECT_EQ(TIMER_EVENT, event);
  auto args = reinterpret_cast<AuthCompleteArgs*>(target);
  std::cerr << args->agent->role_str() << ": call SSL_AuthCertificateComplete "
            << (args->code ? PR_ErrorToName(args->code) : "no error")
            << std::endl;
  EXPECT_EQ(SECSuccess,
            SSL_AuthCertificateComplete(args->agent->ssl_fd(), args->code));
  args->agent->Handshake();  // Make the TlsAgent aware of the error.
  delete args;
}

// Install an AuthCertificateCallback that blocks when called.  Then
// SSL_AuthCertificateComplete is called on a very short timer.  This allows any
// processing that might follow the callback to complete.
static void SetDeferredAuthCertificateCallback(std::shared_ptr<TlsAgent> agent,
                                               PRErrorCode code) {
  auto args = new AuthCompleteArgs(agent, code);
  agent->SetAuthCertificateCallback(
      [args](TlsAgent*, PRBool, PRBool) -> SECStatus {
        // This can't be 0 or we race the message from the client to the server,
        // and tests assume that we lose that race.
        std::shared_ptr<Poller::Timer> timer_handle;
        Poller::Instance()->SetTimer(1U, args, CallAuthComplete, &timer_handle);
        return SECWouldBlock;
      });
}

TEST_P(TlsConnectTls13, ServerAuthRejectAsync) {
  SetDeferredAuthCertificateCallback(client_, SEC_ERROR_REVOKED_CERTIFICATE);
  ConnectExpectAlert(client_, kTlsAlertCertificateRevoked);
  // We only detect the error here when we attempt to handshake, so all the
  // client learns is that the handshake has already failed.
  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILED);
  server_->CheckErrorCode(SSL_ERROR_REVOKED_CERT_ALERT);
}

// In TLS 1.2 and earlier, this will result in the client sending its Finished
// before learning that the server certificate is bad.  That means that the
// server will believe that the handshake is complete.
TEST_P(TlsConnectGenericPre13, ServerAuthRejectAsync) {
  SetDeferredAuthCertificateCallback(client_, SEC_ERROR_EXPIRED_CERTIFICATE);
  client_->ExpectSendAlert(kTlsAlertCertificateExpired);
  server_->ExpectReceiveAlert(kTlsAlertCertificateExpired);
  ConnectExpectFailOneSide(TlsAgent::CLIENT);
  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILED);

  // The server might not receive the alert that the client sends, which would
  // cause the test to fail when it cleans up.  Reset expectations.
  server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning);
}

TEST_P(TlsConnectGeneric, ClientAuth) {
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys();
}

// In TLS 1.3, the client sends its cert rejection on the
// second flight, and since it has already received the
// server's Finished, it transitions to complete and
// then gets an alert from the server. The test harness
// doesn't handle this right yet.
TEST_P(TlsConnectStream, DISABLED_ClientAuthRequiredRejected) {
  server_->RequestClientAuth(true);
  ConnectExpectFail();
}

TEST_P(TlsConnectGeneric, ClientAuthRequestedRejected) {
  server_->RequestClientAuth(false);
  Connect();
  CheckKeys();
}

TEST_P(TlsConnectGeneric, ClientAuthEcdsa) {
  Reset(TlsAgent::kServerEcdsa256);
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
}

TEST_P(TlsConnectGeneric, ClientAuthBigRsa) {
  Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys();
}

// Offset is the position in the captured buffer where the signature sits.
static void CheckSigScheme(std::shared_ptr<TlsHandshakeRecorder>& capture,
                           size_t offset, std::shared_ptr<TlsAgent>& peer,
                           uint16_t expected_scheme, size_t expected_size) {
  EXPECT_LT(offset + 2U, capture->buffer().len());

  uint32_t scheme = 0;
  capture->buffer().Read(offset, 2, &scheme);
  EXPECT_EQ(expected_scheme, static_cast<uint16_t>(scheme));

  ScopedCERTCertificate remote_cert(SSL_PeerCertificate(peer->ssl_fd()));
  ScopedSECKEYPublicKey remote_key(CERT_ExtractPublicKey(remote_cert.get()));
  EXPECT_EQ(expected_size, SECKEY_PublicKeyStrengthInBits(remote_key.get()));
}

// The server should prefer SHA-256 by default, even for the small key size used
// in the default certificate.
TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) {
  EnsureTlsSetup();
  auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
      server_, kTlsHandshakeServerKeyExchange);
  Connect();
  CheckKeys();

  const DataBuffer& buffer = capture_ske->buffer();
  EXPECT_LT(3U, buffer.len());
  EXPECT_EQ(3U, buffer.data()[0]) << "curve_type == named_curve";
  uint32_t tmp;
  EXPECT_TRUE(buffer.Read(1, 2, &tmp)) << "read NamedCurve";
  EXPECT_EQ(ssl_grp_ec_curve25519, tmp);
  EXPECT_TRUE(buffer.Read(3, 1, &tmp)) << " read ECPoint";
  CheckSigScheme(capture_ske, 4 + tmp, client_, ssl_sig_rsa_pss_rsae_sha256,
                 1024);
}

TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) {
  EnsureTlsSetup();
  auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>(
      client_, kTlsHandshakeCertificateVerify);
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys();

  CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
}

TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
  Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
  auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>(
      client_, kTlsHandshakeCertificateVerify);
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys();
  CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_rsae_sha256,
                 2048);
}

// Replaces the signature scheme in a CertificateVerify message.
class TlsReplaceSignatureSchemeFilter : public TlsHandshakeFilter {
 public:
  TlsReplaceSignatureSchemeFilter(const std::shared_ptr<TlsAgent>& a,
                                  SSLSignatureScheme scheme)
      : TlsHandshakeFilter(a, {kTlsHandshakeCertificateVerify}),
        scheme_(scheme) {
    EnableDecryption();
  }

 protected:
  virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                               const DataBuffer& input,
                                               DataBuffer* output) {
    *output = input;
    output->Write(0, scheme_, 2);
    return CHANGE;
  }

 private:
  SSLSignatureScheme scheme_;
};

// Check if CertificateVerify signed with rsa_pss_rsae_* is properly
// rejected when the certificate is RSA-PSS.
//
// This only works under TLS 1.2, because PSS doesn't work with TLS
// 1.0 or TLS 1.1 and the TLS 1.3 1-RTT handshake is partially
// successful at the client side.
TEST_P(TlsConnectTls12, ClientAuthInconsistentRsaeSignatureScheme) {
  static const SSLSignatureScheme kSignatureSchemePss[] = {
      ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_rsae_sha256};

  Reset(TlsAgent::kServerRsa, "rsa_pss");
  client_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  server_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);

  EnsureTlsSetup();

  MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(client_,
                                                 ssl_sig_rsa_pss_rsae_sha256);

  ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
}

// Check if CertificateVerify signed with rsa_pss_pss_* is properly
// rejected when the certificate is RSA.
//
// This only works under TLS 1.2, because PSS doesn't work with TLS
// 1.0 or TLS 1.1 and the TLS 1.3 1-RTT handshake is partially
// successful at the client side.
TEST_P(TlsConnectTls12, ClientAuthInconsistentPssSignatureScheme) {
  static const SSLSignatureScheme kSignatureSchemePss[] = {
      ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};

  Reset(TlsAgent::kServerRsa, "rsa");
  client_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  server_->SetSignatureSchemes(kSignatureSchemePss,
                               PR_ARRAY_SIZE(kSignatureSchemePss));
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);

  EnsureTlsSetup();

  MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(client_,
                                                 ssl_sig_rsa_pss_pss_sha256);

  ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
}

class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
 public:
  TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(a, {kTlsHandshakeCertificateRequest}) {}
  virtual PacketFilter::Action FilterHandshake(
      const TlsHandshakeFilter::HandshakeHeader& header,
      const DataBuffer& input, DataBuffer* output) {
    TlsParser parser(input);
    std::cerr << "Zeroing CertReq.supported_signature_algorithms" << std::endl;

    DataBuffer cert_types;
    if (!parser.ReadVariable(&cert_types, 1)) {
      ADD_FAILURE();
      return KEEP;
    }

    if (!parser.SkipVariable(2)) {
      ADD_FAILURE();
      return KEEP;
    }

    DataBuffer cas;
    if (!parser.ReadVariable(&cas, 2)) {
      ADD_FAILURE();
      return KEEP;
    }

    size_t idx = 0;

    // Write certificate types.
    idx = output->Write(idx, cert_types.len(), 1);
    idx = output->Write(idx, cert_types);

    // Write zero signature algorithms.
    idx = output->Write(idx, 0U, 2);

    // Write certificate authorities.
    idx = output->Write(idx, cas.len(), 2);
    idx = output->Write(idx, cas);

    return CHANGE;
  }
};

// Check that we send an alert when the server doesn't provide any
// supported_signature_algorithms in the CertificateRequest message.
TEST_P(TlsConnectTls12, ClientAuthNoSigAlgs) {
  EnsureTlsSetup();
  MakeTlsFilter<TlsZeroCertificateRequestSigAlgsFilter>(server_);
  auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>(
      client_, kTlsHandshakeCertificateVerify);
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);

  ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);

  server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
  client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
}

static const SSLSignatureScheme kSignatureSchemeEcdsaSha384[] = {
    ssl_sig_ecdsa_secp384r1_sha384};
static const SSLSignatureScheme kSignatureSchemeEcdsaSha256[] = {
    ssl_sig_ecdsa_secp256r1_sha256};
static const SSLSignatureScheme kSignatureSchemeRsaSha384[] = {
    ssl_sig_rsa_pkcs1_sha384};
static const SSLSignatureScheme kSignatureSchemeRsaSha256[] = {
    ssl_sig_rsa_pkcs1_sha256};

static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
  // NSS tries to match the group size to the symmetric cipher. In TLS 1.1 and
  // 1.0, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is the highest priority suite, so
  // we use P-384. With TLS 1.2 on we pick AES-128 GCM so use x25519.
  if (version <= SSL_LIBRARY_VERSION_TLS_1_1) {
    return ssl_grp_ec_secp384r1;
  }
  return ssl_grp_ec_curve25519;
}

// When signature algorithms match up, this should connect successfully; even
// for TLS 1.1 and 1.0, where they should be ignored.
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerAuth) {
  Reset(TlsAgent::kServerEcdsa384);
  client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  Connect();
  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
            ssl_sig_ecdsa_secp384r1_sha384);
}

// Here the client picks a single option, which should work in all versions.
// Defaults on the server include the first option.
TEST_P(TlsConnectGeneric, SignatureAlgorithmClientOnly) {
  const SSLSignatureAndHashAlg clientAlgorithms[] = {
      {ssl_hash_sha384, ssl_sign_ecdsa},
      {ssl_hash_sha384, ssl_sign_rsa},  // supported but unusable
      {ssl_hash_md5, ssl_sign_ecdsa}    // unsupported and ignored
  };
  Reset(TlsAgent::kServerEcdsa384);
  EnsureTlsSetup();
  // Use the old API for this function.
  EXPECT_EQ(SECSuccess,
            SSL_SignaturePrefSet(client_->ssl_fd(), clientAlgorithms,
                                 PR_ARRAY_SIZE(clientAlgorithms)));
  Connect();
  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
            ssl_sig_ecdsa_secp384r1_sha384);
}

// Here the server picks a single option, which should work in all versions.
// Defaults on the client include the provided option.
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
  Reset(TlsAgent::kServerEcdsa384);
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  Connect();
  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
            ssl_sig_ecdsa_secp384r1_sha384);
}

// In TLS 1.2, curve and hash aren't bound together.
TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch) {
  Reset(TlsAgent::kServerEcdsa256);
  client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  Connect();
}

// In TLS 1.3, curve and hash are coupled.
TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
  Reset(TlsAgent::kServerEcdsa256);
  client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

// Configuring a P-256 cert with only SHA-384 signatures is OK in TLS 1.2.
TEST_P(TlsConnectTls12, SignatureSchemeBadConfig) {
  Reset(TlsAgent::kServerEcdsa256);  // P-256 cert can't be used.
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  Connect();
}

// A P-256 certificate in TLS 1.3 needs a SHA-256 signature scheme.
TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
  Reset(TlsAgent::kServerEcdsa256);  // P-256 cert can't be used.
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

// Where there is no overlap on signature schemes, we still connect successfully
// if we aren't going to use a signature.
TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
  client_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
  server_->SetSignatureSchemes(kSignatureSchemeRsaSha256,
                               PR_ARRAY_SIZE(kSignatureSchemeRsaSha256));
  EnableOnlyStaticRsaCiphers();
  Connect();
  CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
}

TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
  Reset(TlsAgent::kServerEcdsa256);
  client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
}

// Pre 1.2, a mismatch on signature algorithms shouldn't affect anything.
TEST_P(TlsConnectPre12, SignatureAlgorithmNoOverlapEcdsa) {
  Reset(TlsAgent::kServerEcdsa256);
  client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
  server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
                               PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
  Connect();
}

// The signature_algorithms extension is mandatory in TLS 1.3.
TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) {
  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_signature_algorithms_xtn);
  ConnectExpectAlert(server_, kTlsAlertMissingExtension);
  client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
  server_->CheckErrorCode(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION);
}

// TLS 1.2 has trouble detecting this sort of modification: it uses SHA1 and
// only fails when the Finished is checked.
TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) {
  MakeTlsFilter<TlsExtensionDropper>(client_, ssl_signature_algorithms_xtn);
  ConnectExpectAlert(server_, kTlsAlertDecryptError);
  client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
  server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
}

TEST_P(TlsConnectTls13, UnsupportedSignatureSchemeAlert) {
  EnsureTlsSetup();
  MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(server_, ssl_sig_none);

  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
}

TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
  EnsureTlsSetup();

  // This won't work because we use an RSA cert by default.
  MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(
      server_, ssl_sig_ecdsa_secp256r1_sha256);

  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
}

TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
  server_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
                               PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
  server_->RequestClientAuth(false);
  Connect();
}

class BeforeFinished : public TlsRecordFilter {
 private:
  enum HandshakeState { BEFORE_CCS, AFTER_CCS, DONE };

 public:
  BeforeFinished(const std::shared_ptr<TlsAgent>& server,
                 const std::shared_ptr<TlsAgent>& client,
                 VoidFunction before_ccs, VoidFunction before_finished)
      : TlsRecordFilter(server),
        client_(client),
        before_ccs_(before_ccs),
        before_finished_(before_finished),
        state_(BEFORE_CCS) {}

 protected:
  virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                            const DataBuffer& body,
                                            DataBuffer* out) {
    switch (state_) {
      case BEFORE_CCS:
        // Awaken when we see the CCS.
        if (header.content_type() == ssl_ct_change_cipher_spec) {
          before_ccs_();

          // Write the CCS out as a separate write, so that we can make
          // progress. Ordinarily, libssl sends the CCS and Finished together,
          // but that means that they both get processed together.
          DataBuffer ccs;
          header.Write(&ccs, 0, body);
          agent()->SendDirect(ccs);
          client_.lock()->Handshake();
          state_ = AFTER_CCS;
          // Request that the original record be dropped by the filter.
          return DROP;
        }
        break;

      case AFTER_CCS:
        EXPECT_EQ(ssl_ct_handshake, header.content_type());
        // This could check that data contains a Finished message, but it's
        // encrypted, so that's too much extra work.

        before_finished_();
        state_ = DONE;
        break;

      case DONE:
        break;
    }
    return KEEP;
  }

 private:
  std::weak_ptr<TlsAgent> client_;
  VoidFunction before_ccs_;
  VoidFunction before_finished_;
  HandshakeState state_;
};

// Running code after the client has started processing the encrypted part of
// the server's first flight, but before the Finished is processed is very hard
// in TLS 1.3.  These encrypted messages are sent in a single encrypted blob.
// The following test uses DTLS to make it possible to force the client to
// process the handshake in pieces.
//
// The first encrypted message from the server is dropped, and the MTU is
// reduced to just below the original message size so that the server sends two
// messages.  The Finished message is then processed separately.
class BeforeFinished13 : public PacketFilter {
 private:
  enum HandshakeState {
    INIT,
    BEFORE_FIRST_FRAGMENT,
    BEFORE_SECOND_FRAGMENT,
    DONE
  };

 public:
  BeforeFinished13(const std::shared_ptr<TlsAgent>& server,
                   const std::shared_ptr<TlsAgent>& client,
                   VoidFunction before_finished)
      : server_(server),
        client_(client),
        before_finished_(before_finished),
        records_(0) {}

 protected:
  virtual PacketFilter::Action Filter(const DataBuffer& input,
                                      DataBuffer* output) {
    switch (++records_) {
      case 1:
        // Packet 1 is the server's entire first flight.  Drop it.
        EXPECT_EQ(SECSuccess,
                  SSLInt_SetMTU(server_.lock()->ssl_fd(), input.len() - 1));
        return DROP;

      // Packet 2 is the first part of the server's retransmitted first
      // flight.  Keep that.

      case 3:
        // Packet 3 is the second part of the server's retransmitted first
        // flight.  Before passing that on, make sure that the client processes
        // packet 2, then call the before_finished_() callback.
        client_.lock()->Handshake();
        before_finished_();
        break;

      default:
        break;
    }
    return KEEP;
  }

 private:
  std::weak_ptr<TlsAgent> server_;
  std::weak_ptr<TlsAgent> client_;
  VoidFunction before_finished_;
  size_t records_;
};

static SECStatus AuthCompleteBlock(TlsAgent*, PRBool, PRBool) {
  return SECWouldBlock;
}

// This test uses an AuthCertificateCallback that blocks.  A filter is used to
// split the server's first flight into two pieces.  Before the second piece is
// processed by the client, SSL_AuthCertificateComplete() is called.
TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) {
  client_->SetAuthCertificateCallback(AuthCompleteBlock);
  MakeTlsFilter<BeforeFinished13>(server_, client_, [this]() {
    EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
  });
  Connect();
}

// This test uses a simple AuthCertificateCallback.  Due to the way that the
// entire server flight is processed, the call to SSL_AuthCertificateComplete
// will trigger after the Finished message is processed.
TEST_F(TlsConnectDatagram13, AuthCompleteAfterFinished) {
  SetDeferredAuthCertificateCallback(client_, 0);  // 0 = success.
  Connect();
}

TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
  client_->EnableFalseStart();
  MakeTlsFilter<BeforeFinished>(
      server_, client_,
      [this]() { EXPECT_TRUE(client_->can_falsestart_hook_called()); },
      [this]() {
        // Write something, which used to fail: bug 1235366.
        client_->SendData(10);
      });

  Connect();
  server_->SendData(10);
  Receive(10);
}

TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) {
  client_->EnableFalseStart();
  client_->SetAuthCertificateCallback(AuthCompleteBlock);
  MakeTlsFilter<BeforeFinished>(
      server_, client_,
      []() {
        // Do nothing before CCS
      },
      [this]() {
        EXPECT_FALSE(client_->can_falsestart_hook_called());
        // AuthComplete before Finished still enables false start.
        EXPECT_EQ(SECSuccess,
                  SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
        EXPECT_TRUE(client_->can_falsestart_hook_called());
        client_->SendData(10);
      });

  Connect();
  server_->SendData(10);
  Receive(10);
}

class EnforceNoActivity : public PacketFilter {
 protected:
  PacketFilter::Action Filter(const DataBuffer& input,
                              DataBuffer* output) override {
    std::cerr << "Unexpected packet: " << input << std::endl;
    EXPECT_TRUE(false) << "should not send anything";
    return KEEP;
  }
};

// In this test, we want to make sure that the server completes its handshake,
// but the client does not.  Because the AuthCertificate callback blocks and we
// never call SSL_AuthCertificateComplete(), the client should never report that
// it has completed the handshake.  Manually call Handshake(), alternating sides
// between client and server, until the desired state is reached.
TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) {
  client_->SetAuthCertificateCallback(AuthCompleteBlock);

  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello
  client_->Handshake();  // Send ClientKeyExchange and Finished
  server_->Handshake();  // Send Finished
  // The server should now report that it is connected
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());

  // The client should send nothing from here on.
  client_->SetFilter(std::make_shared<EnforceNoActivity>());
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());

  // This should allow the handshake to complete now.
  EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
  client_->Handshake();  // Transition to connected
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());

  // Remove filter before closing or the close_notify alert will trigger it.
  client_->ClearFilter();
}

TEST_P(TlsConnectGenericPre13, AuthCompleteFailDelayed) {
  client_->SetAuthCertificateCallback(AuthCompleteBlock);

  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello
  client_->Handshake();  // Send ClientKeyExchange and Finished
  server_->Handshake();  // Send Finished
  // The server should now report that it is connected
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());

  // The client should send nothing from here on.
  client_->SetFilter(std::make_shared<EnforceNoActivity>());
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());

  // Report failure.
  client_->ClearFilter();
  client_->ExpectSendAlert(kTlsAlertBadCertificate);
  EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(),
                                                    SSL_ERROR_BAD_CERTIFICATE));
  client_->Handshake();  // Fail
  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
}

// TLS 1.3 handles a delayed AuthComplete callback differently since the
// shape of the handshake is different.
TEST_P(TlsConnectTls13, AuthCompleteDelayed) {
  client_->SetAuthCertificateCallback(AuthCompleteBlock);

  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());

  // The client will send nothing until AuthCertificateComplete is called.
  client_->SetFilter(std::make_shared<EnforceNoActivity>());
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());

  // This should allow the handshake to complete now.
  client_->ClearFilter();
  EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
  client_->Handshake();  // Send Finished
  server_->Handshake();  // Transition to connected and send NewSessionTicket
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
}

TEST_P(TlsConnectTls13, AuthCompleteFailDelayed) {
  client_->SetAuthCertificateCallback(AuthCompleteBlock);

  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());

  // The client will send nothing until AuthCertificateComplete is called.
  client_->SetFilter(std::make_shared<EnforceNoActivity>());
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());

  // Report failure.
  client_->ClearFilter();
  ExpectAlert(client_, kTlsAlertBadCertificate);
  EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(),
                                                    SSL_ERROR_BAD_CERTIFICATE));
  client_->Handshake();  // This should now fail.
  server_->Handshake();  // Get the error.
  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
  EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state());
}

static SECStatus AuthCompleteFail(TlsAgent*, PRBool, PRBool) {
  PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
  return SECFailure;
}

TEST_P(TlsConnectGeneric, AuthFailImmediate) {
  client_->SetAuthCertificateCallback(AuthCompleteFail);

  StartConnect();
  ConnectExpectAlert(client_, kTlsAlertBadCertificate);
  client_->CheckErrorCode(SSL_ERROR_BAD_CERTIFICATE);
}

static const SSLExtraServerCertData ServerCertDataRsaPkcs1Decrypt = {
    ssl_auth_rsa_decrypt, nullptr, nullptr, nullptr};
static const SSLExtraServerCertData ServerCertDataRsaPkcs1Sign = {
    ssl_auth_rsa_sign, nullptr, nullptr, nullptr};
static const SSLExtraServerCertData ServerCertDataRsaPss = {
    ssl_auth_rsa_pss, nullptr, nullptr, nullptr};

// Test RSA cert with usage=[signature, encipherment].
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1SignAndKEX) {
  Reset(TlsAgent::kServerRsa);

  PRFileDesc* ssl_fd = agent_->ssl_fd();
  EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
  EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));

  // Configuring for only rsa_sign or rsa_decrypt should work.
  EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
                                       &ServerCertDataRsaPkcs1Decrypt));
  EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
                                       &ServerCertDataRsaPkcs1Sign));
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
                                        &ServerCertDataRsaPss));
}

// Test RSA cert with usage=[signature].
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1Sign) {
  Reset(TlsAgent::kServerRsaSign);

  PRFileDesc* ssl_fd = agent_->ssl_fd();
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
  EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));

  // Configuring for only rsa_decrypt should fail.
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
                                        &ServerCertDataRsaPkcs1Decrypt));

  // Configuring for only rsa_sign should work.
  EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
                                       &ServerCertDataRsaPkcs1Sign));
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
                                        &ServerCertDataRsaPss));
}

// Test RSA cert with usage=[encipherment].
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1KEX) {
  Reset(TlsAgent::kServerRsaDecrypt);

  PRFileDesc* ssl_fd = agent_->ssl_fd();
  EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));

  // Configuring for only rsa_sign or rsa_pss should fail.
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
                                        &ServerCertDataRsaPkcs1Sign));
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
                                        &ServerCertDataRsaPss));

  // Configuring for only rsa_decrypt should work.
  EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
                                       &ServerCertDataRsaPkcs1Decrypt));
}

// Test configuring an RSA-PSS cert.
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPss) {
  Reset(TlsAgent::kServerRsaPss);

  PRFileDesc* ssl_fd = agent_->ssl_fd();
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
  EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
  EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));

  // Configuring for only rsa_sign or rsa_decrypt should fail.
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
                                        &ServerCertDataRsaPkcs1Sign));
  EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
                                        &ServerCertDataRsaPkcs1Decrypt));

  // Configuring for only rsa_pss should work.
  EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
                                       &ServerCertDataRsaPss));
}

// variant, version, certificate, auth type, signature scheme
typedef std::tuple<SSLProtocolVariant, uint16_t, std::string, SSLAuthType,
                   SSLSignatureScheme>
    SignatureSchemeProfile;

class TlsSignatureSchemeConfiguration
    : public TlsConnectTestBase,
      public ::testing::WithParamInterface<SignatureSchemeProfile> {
 public:
  TlsSignatureSchemeConfiguration()
      : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())),
        certificate_(std::get<2>(GetParam())),
        auth_type_(std::get<3>(GetParam())),
        signature_scheme_(std::get<4>(GetParam())) {}

 protected:
  void TestSignatureSchemeConfig(std::shared_ptr<TlsAgent>& configPeer) {
    EnsureTlsSetup();
    configPeer->SetSignatureSchemes(&signature_scheme_, 1);
    Connect();
    CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_,
              signature_scheme_);
  }

  std::string certificate_;
  SSLAuthType auth_type_;
  SSLSignatureScheme signature_scheme_;
};

TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigServer) {
  Reset(certificate_);
  TestSignatureSchemeConfig(server_);
}

TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigClient) {
  Reset(certificate_);
  auto capture =
      MakeTlsFilter<TlsExtensionCapture>(client_, ssl_signature_algorithms_xtn);
  TestSignatureSchemeConfig(client_);

  const DataBuffer& ext = capture->extension();
  ASSERT_EQ(2U + 2U, ext.len());
  uint32_t v = 0;
  ASSERT_TRUE(ext.Read(0, 2, &v));
  EXPECT_EQ(2U, v);
  ASSERT_TRUE(ext.Read(2, 2, &v));
  EXPECT_EQ(signature_scheme_, static_cast<SSLSignatureScheme>(v));
}

TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigBoth) {
  Reset(certificate_);
  EnsureTlsSetup();
  client_->SetSignatureSchemes(&signature_scheme_, 1);
  server_->SetSignatureSchemes(&signature_scheme_, 1);
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_, signature_scheme_);
}

INSTANTIATE_TEST_CASE_P(
    SignatureSchemeRsa, TlsSignatureSchemeConfiguration,
    ::testing::Combine(
        TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus,
        ::testing::Values(TlsAgent::kServerRsaSign),
        ::testing::Values(ssl_auth_rsa_sign),
        ::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384,
                          ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_rsae_sha256,
                          ssl_sig_rsa_pss_rsae_sha384)));
// PSS with SHA-512 needs a bigger key to work.
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12Plus,
                       ::testing::Values(TlsAgent::kRsa2048),
                       ::testing::Values(ssl_auth_rsa_sign),
                       ::testing::Values(ssl_sig_rsa_pss_rsae_sha512)));
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeRsaSha1, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12,
                       ::testing::Values(TlsAgent::kServerRsa),
                       ::testing::Values(ssl_auth_rsa_sign),
                       ::testing::Values(ssl_sig_rsa_pkcs1_sha1)));
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeEcdsaP256, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12Plus,
                       ::testing::Values(TlsAgent::kServerEcdsa256),
                       ::testing::Values(ssl_auth_ecdsa),
                       ::testing::Values(ssl_sig_ecdsa_secp256r1_sha256)));
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeEcdsaP384, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12Plus,
                       ::testing::Values(TlsAgent::kServerEcdsa384),
                       ::testing::Values(ssl_auth_ecdsa),
                       ::testing::Values(ssl_sig_ecdsa_secp384r1_sha384)));
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeEcdsaP521, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12Plus,
                       ::testing::Values(TlsAgent::kServerEcdsa521),
                       ::testing::Values(ssl_auth_ecdsa),
                       ::testing::Values(ssl_sig_ecdsa_secp521r1_sha512)));
INSTANTIATE_TEST_CASE_P(
    SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                       TlsConnectTestBase::kTlsV12,
                       ::testing::Values(TlsAgent::kServerEcdsa256,
                                         TlsAgent::kServerEcdsa384),
                       ::testing::Values(ssl_auth_ecdsa),
                       ::testing::Values(ssl_sig_ecdsa_sha1)));
}  // namespace nss_test
