// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/crypto/proof_verifier_chromium.h"

#include <utility>

#include "base/memory/ref_counted.h"
#include "base/test/metrics/histogram_tester.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_policy_status.h"
#include "net/cert/ct_serialization.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cert/x509_util.h"
#include "net/http/transport_security_state.h"
#include "net/http/transport_security_state_test_util.h"
#include "net/quic/crypto/proof_source_chromium.h"
#include "net/test/cert_test_util.h"
#include "net/test/ct_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/third_party/quic/core/crypto/proof_verifier.h"
#include "starboard/memory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::Return;

namespace net {
namespace test {

namespace {

const char kCTAndPKPHost[] = "pkp-expect-ct.preloaded.test";

// CertVerifier that will fail the test if it is ever called.
class FailsTestCertVerifier : public CertVerifier {
 public:
  FailsTestCertVerifier() {}
  ~FailsTestCertVerifier() override {}

  // CertVerifier implementation
  int Verify(const RequestParams& params,
             CertVerifyResult* verify_result,
             CompletionOnceCallback callback,
             std::unique_ptr<Request>* out_req,
             const NetLogWithSource& net_log) override {
    ADD_FAILURE() << "CertVerifier::Verify() should not be called";
    return ERR_FAILED;
  }
  void SetConfig(const Config& config) override {}
};

// A mock CTPolicyEnforcer that returns a custom verification result.
class MockCTPolicyEnforcer : public CTPolicyEnforcer {
 public:
  MOCK_METHOD3(CheckCompliance,
               ct::CTPolicyCompliance(X509Certificate* cert,
                                      const ct::SCTList&,
                                      const NetLogWithSource&));
};

class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
 public:
  MOCK_METHOD3(IsCTRequiredForHost,
               CTRequirementLevel(const std::string& host,
                                  const X509Certificate* chain,
                                  const HashValueVector& hashes));
};

// Proof source callback which saves the signature into |signature|.
class SignatureSaver : public quic::ProofSource::Callback {
 public:
  explicit SignatureSaver(std::string* signature) : signature_(signature) {}
  ~SignatureSaver() override {}

  void Run(bool /*ok*/,
           const quic::QuicReferenceCountedPointer<
               quic::ProofSource::Chain>& /*chain*/,
           const quic::QuicCryptoProof& proof,
           std::unique_ptr<quic::ProofSource::Details> /*details*/) override {
    *signature_ = proof.signature;
  }

  std::string* signature_;
};

class DummyProofVerifierCallback : public quic::ProofVerifierCallback {
 public:
  DummyProofVerifierCallback() {}
  ~DummyProofVerifierCallback() override {}

  void Run(bool ok,
           const std::string& error_details,
           std::unique_ptr<quic::ProofVerifyDetails>* details) override {
    // Do nothing
  }
};

const char kTestHostname[] = "test.example.com";
const char kTestChloHash[] = "CHLO hash";
const char kTestEmptySCT[] = "";
const uint16_t kTestPort = 8443;
const char kTestConfig[] = "server config bytes";
const char kLogDescription[] = "somelog";

}  // namespace

class ProofVerifierChromiumTest : public ::testing::Test {
 public:
  ProofVerifierChromiumTest()
      : verify_context_(new ProofVerifyContextChromium(0 /*cert_verify_flags*/,
                                                       NetLogWithSource())) {}

  void SetUp() override {
    EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
        .WillRepeatedly(
            Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

    scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
        ct::GetTestPublicKey(), kLogDescription, "dns.example.com"));
    ASSERT_TRUE(log);
    log_verifiers_.push_back(log);

    ct_verifier_.reset(new MultiLogCTVerifier());
    ct_verifier_->AddLogs(log_verifiers_);

    ASSERT_NO_FATAL_FAILURE(GetTestCertificates(&certs_));
  }

  scoped_refptr<X509Certificate> GetTestServerCertificate() {
    static const char kTestCert[] = "quic-chain.pem";
    return ImportCertFromFile(GetTestCertsDirectory(), kTestCert);
  }

  void GetTestCertificates(std::vector<std::string>* certs) {
    scoped_refptr<X509Certificate> cert = GetTestServerCertificate();
    ASSERT_TRUE(cert);

    certs->clear();
    certs->emplace_back(
        x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
  }

  std::string GetTestSignature() {
    ProofSourceChromium source;
    source.Initialize(GetTestCertsDirectory().AppendASCII("quic-chain.pem"),
                      GetTestCertsDirectory().AppendASCII("quic-leaf-cert.key"),
                      base::FilePath());
    std::string signature;
    source.GetProof(quic::QuicSocketAddress(), kTestHostname, kTestConfig,
                    quic::QUIC_VERSION_39, kTestChloHash,
                    std::make_unique<SignatureSaver>(&signature));
    return signature;
  }

  void GetSCTTestCertificates(std::vector<std::string>* certs) {
    std::string der_test_cert(ct::GetDerEncodedX509Cert());
    scoped_refptr<X509Certificate> test_cert = X509Certificate::CreateFromBytes(
        der_test_cert.data(), der_test_cert.length());
    ASSERT_TRUE(test_cert.get());

    certs->clear();
    certs->emplace_back(
        x509_util::CryptoBufferAsStringPiece(test_cert->cert_buffer()));
  }

  void CheckSCT(bool sct_expected_ok) {
    ProofVerifyDetailsChromium* proof_details =
        reinterpret_cast<ProofVerifyDetailsChromium*>(details_.get());
    const ct::CTVerifyResult& ct_verify_result =
        proof_details->ct_verify_result;
    if (sct_expected_ok) {
      ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(ct_verify_result.scts,
                                                        kLogDescription));
      ASSERT_TRUE(ct::CheckForSCTOrigin(
          ct_verify_result.scts,
          ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
    } else {
      EXPECT_EQ(1U, ct_verify_result.scts.size());
      EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, ct_verify_result.scts[0].status);
    }
  }

 protected:
  TransportSecurityState transport_security_state_;
  MockCTPolicyEnforcer ct_policy_enforcer_;

  std::unique_ptr<MultiLogCTVerifier> ct_verifier_;
  std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers_;
  std::unique_ptr<quic::ProofVerifyContext> verify_context_;
  std::unique_ptr<quic::ProofVerifyDetails> details_;
  std::string error_details_;
  std::vector<std::string> certs_;
};

// Tests that the quic::ProofVerifier fails verification if certificate
// verification fails.
TEST_F(ProofVerifierChromiumTest, FailsIfCertFails) {
  MockCertVerifier dummy_verifier;
  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);
}

// Valid SCT, but invalid signature.
TEST_F(ProofVerifierChromiumTest, ValidSCTList) {
  // Use different certificates for SCT tests.
  ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));

  MockCertVerifier cert_verifier;

  ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, ct::GetSCTListForTesting(), kTestEmptySCT,
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);
  CheckSCT(/*sct_expected_ok=*/true);
}

// Invalid SCT and signature.
TEST_F(ProofVerifierChromiumTest, InvalidSCTList) {
  // Use different certificates for SCT tests.
  ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));

  MockCertVerifier cert_verifier;
  ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, ct::GetSCTListWithInvalidSCT(), kTestEmptySCT,
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);
  CheckSCT(/*sct_expected_ok=*/false);
}

// Tests that the quic::ProofVerifier doesn't verify certificates if the config
// signature fails.
TEST_F(ProofVerifierChromiumTest, FailsIfSignatureFails) {
  FailsTestCertVerifier cert_verifier;
  ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, kTestConfig, verify_context_.get(),
      &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);
}

// Tests that the certificate policy enforcer is consulted for EV
// and the certificate is allowed to be EV.
TEST_F(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.cert_status = CERT_STATUS_IS_EV;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_EQ(dummy_result.cert_status,
            verify_details->cert_verify_result.cert_status);
}

// Tests that the certificate policy enforcer is consulted for EV
// and the certificate is not allowed to be EV.
TEST_F(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.cert_status = CERT_STATUS_IS_EV;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_EQ(CERT_STATUS_CT_COMPLIANCE_FAILED,
            verify_details->cert_verify_result.cert_status &
                (CERT_STATUS_CT_COMPLIANCE_FAILED | CERT_STATUS_IS_EV));
}

// Tests that the when a certificate's EV status is stripped to EV
// non-compliance, the correct histogram is recorded.
TEST_F(ProofVerifierChromiumTest, CTEVHistogramNonCompliant) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.EVCompliance2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.cert_status = CERT_STATUS_IS_EV;
  dummy_result.is_issued_by_known_root = true;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_EQ(CERT_STATUS_CT_COMPLIANCE_FAILED,
            verify_details->cert_verify_result.cert_status &
                (CERT_STATUS_CT_COMPLIANCE_FAILED | CERT_STATUS_IS_EV));

  histograms.ExpectUniqueSample(
      kHistogramName,
      static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS), 1);
}

// Tests that when a connection is CT-compliant and its EV status is preserved,
// the correct histogram is recorded.
TEST_F(ProofVerifierChromiumTest, CTEVHistogramCompliant) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.EVCompliance2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.cert_status = CERT_STATUS_IS_EV;
  dummy_result.is_issued_by_known_root = true;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
              CERT_STATUS_IS_EV);

  histograms.ExpectUniqueSample(
      kHistogramName,
      static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS), 1);
}

HashValueVector MakeHashValueVector(uint8_t tag) {
  HashValue hash(HASH_VALUE_SHA256);
  SbMemorySet(hash.data(), tag, hash.size());
  HashValueVector hashes;
  hashes.push_back(hash);
  return hashes;
}

TEST_F(ProofVerifierChromiumTest, IsFatalErrorNotSetForNonFatalError) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.cert_status = MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
  dummy_result.verified_cert = test_cert;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result,
                                  ERR_CERT_DATE_INVALID);

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);

  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_FALSE(verify_details->is_fatal_cert_error);
}

TEST_F(ProofVerifierChromiumTest, IsFatalErrorSetForFatalError) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.cert_status = MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
  dummy_result.verified_cert = test_cert;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result,
                                  ERR_CERT_DATE_INVALID);

  const base::Time expiry =
      base::Time::Now() + base::TimeDelta::FromSeconds(1000);
  transport_security_state_.AddHSTS(kTestHostname, expiry, true);

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->is_fatal_cert_error);
}

// Test that PKP is enforced for certificates that chain up to known roots.
TEST_F(ProofVerifierChromiumTest, PKPEnforced) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  transport_security_state_.EnableStaticPinsForTesting();
  ScopedTransportSecurityStateSource scoped_security_state_source;

#if defined(STARBOARD)
  // Cobalt does not enable static transport security states so we have to
  // enable the PKP here dynamically.
  HashValueVector pin_hashes = MakeHashValueVector(0x02);
  transport_security_state_.AddHPKP(
      kCTAndPKPHost, base::Time::Now() + base::TimeDelta::FromSeconds(10000),
      true, pin_hashes, GURL());
#endif

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
              CERT_STATUS_PINNED_KEY_MISSING);
  EXPECT_FALSE(verify_details->pkp_bypassed);
  EXPECT_NE("", verify_details->pinning_failure_log);
}

// Test |pkp_bypassed| is set when PKP is bypassed due to a local
// trust anchor
TEST_F(ProofVerifierChromiumTest, PKPBypassFlagSet) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = false;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  transport_security_state_.EnableStaticPinsForTesting();
  ScopedTransportSecurityStateSource scoped_security_state_source;

#if defined(STARBOARD)
  // Cobalt does not enable static transport security states so we have to
  // enable the PKP here dynamically.
  HashValueVector pin_hashes = MakeHashValueVector(0x02);
  transport_security_state_.AddHPKP(
      kCTAndPKPHost, base::Time::Now() + base::TimeDelta::FromSeconds(10000),
      true, pin_hashes, GURL());
#endif

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->pkp_bypassed);
}

// Test that when CT is required (in this case, by the delegate), the
// absence of CT information is a socket error.
TEST_F(ProofVerifierChromiumTest, CTIsRequired) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
              CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
}

// Test that when CT is required (in this case, by the delegate) and CT
// information is not compliant, then the CT-required histogram is recorded
// properly.
TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramNonCompliant) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);

  histograms.ExpectUniqueSample(
      kHistogramName,
      static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS), 1);
}

// Test that when CT is required (in this case, by the delegate) and CT
// information is compliant, then the CT-required histogram is recorded
// properly.
TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramCompliant) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = false;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));

  // First test that the histogram is not recorded for locally-installed roots.
  {
    MockCertVerifier dummy_verifier;
    dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
    ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                         &transport_security_state_,
                                         ct_verifier_.get());

    std::unique_ptr<DummyProofVerifierCallback> callback(
        new DummyProofVerifierCallback);
    quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
        kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
        kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
        verify_context_.get(), &error_details_, &details_, std::move(callback));
    ASSERT_EQ(quic::QUIC_SUCCESS, status);

    histograms.ExpectTotalCount(kHistogramName, 0);
  }
  // Now test that the histogram is recorded for public roots.
  {
    dummy_result.is_issued_by_known_root = true;
    MockCertVerifier dummy_verifier;
    dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
    ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                         &transport_security_state_,
                                         ct_verifier_.get());

    std::unique_ptr<DummyProofVerifierCallback> callback(
        new DummyProofVerifierCallback);
    quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
        kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
        kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
        verify_context_.get(), &error_details_, &details_, std::move(callback));
    ASSERT_EQ(quic::QUIC_SUCCESS, status);

    histograms.ExpectUniqueSample(
        kHistogramName,
        static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS),
        1);
  }
}

// Test that when CT is not required (because of a private root, in this case),
// the CT-required histogram is not recorded.
TEST_F(ProofVerifierChromiumTest, CTIsNotRequiredHistogram) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = false;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  histograms.ExpectTotalCount(kHistogramName, 0);
}

// Test that CT is considered even when PKP fails.
TEST_F(ProofVerifierChromiumTest, PKPAndCTBothTested) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.public_key_hashes = MakeHashValueVector(0x01);
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  // Set up PKP.
  transport_security_state_.EnableStaticPinsForTesting();
  ScopedTransportSecurityStateSource scoped_security_state_source;

#if defined(STARBOARD)
  // Cobalt does not enable static transport security states so we have to
  // enable the PKP here dynamically.
  HashValueVector pin_hashes = MakeHashValueVector(0x02);
  transport_security_state_.AddHPKP(
      kCTAndPKPHost, base::Time::Now() + base::TimeDelta::FromSeconds(10000),
      true, pin_hashes, GURL());
#endif

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kCTAndPKPHost, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
      kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));
  ASSERT_EQ(quic::QUIC_FAILURE, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
              CERT_STATUS_PINNED_KEY_MISSING);
  EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
              CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
}

// Test that CT compliance status is recorded in a histogram.
TEST_F(ProofVerifierChromiumTest, CTComplianceStatusHistogram) {
  const char kHistogramName[] =
      "Net.CertificateTransparency.ConnectionComplianceStatus2.QUIC";
  base::HistogramTester histograms;

  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = false;
  dummy_result.cert_status = 0;

  // Set up CT.
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));

  // First test that the histogram is not recorded for locally-installed roots.
  {
    MockCertVerifier dummy_verifier;
    dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
    ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                         &transport_security_state_,
                                         ct_verifier_.get());

    std::unique_ptr<DummyProofVerifierCallback> callback(
        new DummyProofVerifierCallback);
    quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
        kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
        kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
        verify_context_.get(), &error_details_, &details_, std::move(callback));
    ASSERT_EQ(quic::QUIC_SUCCESS, status);

    // The histogram should not have been recorded.
    histograms.ExpectTotalCount(kHistogramName, 0);
  }

  // Now test that the histogram is recorded for public roots.
  {
    dummy_result.is_issued_by_known_root = true;
    MockCertVerifier dummy_verifier;
    dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
    ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                         &transport_security_state_,
                                         ct_verifier_.get());

    std::unique_ptr<DummyProofVerifierCallback> callback(
        new DummyProofVerifierCallback);
    quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
        kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
        kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
        verify_context_.get(), &error_details_, &details_, std::move(callback));
    ASSERT_EQ(quic::QUIC_SUCCESS, status);

    // The histogram should have been recorded with the CT compliance status.
    histograms.ExpectUniqueSample(
        kHistogramName,
        static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS),
        1);
  }
}

// Tests that when CT is required but the connection is not compliant, the
// relevant flag is set in the CTVerifyResult.
TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagNotMet) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));

  // The flag should be set in the CTVerifyResult.
  ProofVerifyDetailsChromium* proof_details =
      reinterpret_cast<ProofVerifyDetailsChromium*>(details_.get());
  const ct::CTVerifyResult& ct_verify_result = proof_details->ct_verify_result;
  EXPECT_TRUE(ct_verify_result.policy_compliance_required);
}

// Tests that when CT is required and the connection is compliant, the relevant
// flag is set in the CTVerifyResult.
TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagMet) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.is_issued_by_known_root = true;
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  // Set up CT.
  MockRequireCTDelegate require_ct_delegate;
  transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
      .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
                                 CTRequirementLevel::REQUIRED));
  EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
      .WillRepeatedly(
          Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  proof_verifier.VerifyProof(
      kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_39,
      kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
      verify_context_.get(), &error_details_, &details_, std::move(callback));

  // The flag should be set in the CTVerifyResult.
  ProofVerifyDetailsChromium* proof_details =
      reinterpret_cast<ProofVerifyDetailsChromium*>(details_.get());
  const ct::CTVerifyResult& ct_verify_result = proof_details->ct_verify_result;
  EXPECT_TRUE(ct_verify_result.policy_compliance_required);
}

// Tests that the VerifyCertChain verifies certificates.
TEST_F(ProofVerifierChromiumTest, VerifyCertChain) {
  scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
  ASSERT_TRUE(test_cert);

  CertVerifyResult dummy_result;
  dummy_result.verified_cert = test_cert;
  dummy_result.cert_status = 0;

  MockCertVerifier dummy_verifier;
  dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);

  ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
                                       &transport_security_state_,
                                       ct_verifier_.get());

  std::unique_ptr<DummyProofVerifierCallback> callback(
      new DummyProofVerifierCallback);
  quic::QuicAsyncStatus status = proof_verifier.VerifyCertChain(
      kTestHostname, certs_, verify_context_.get(), &error_details_, &details_,
      std::move(callback));
  ASSERT_EQ(quic::QUIC_SUCCESS, status);

  ASSERT_TRUE(details_.get());
  ProofVerifyDetailsChromium* verify_details =
      static_cast<ProofVerifyDetailsChromium*>(details_.get());
  EXPECT_EQ(0u, verify_details->cert_verify_result.cert_status);
}

}  // namespace test
}  // namespace net
