chromium/net/cert/cert_verify_proc_unittest.cc

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

#include "net/cert/cert_verify_proc.h"

#include <memory>
#include <string_view>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/message_loop/message_pump_type.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "crypto/sha2.h"
#include "net/base/cronet_buildflags.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_net_fetcher.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_proc_builtin.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/crl_set.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert/ev_root_ca_metadata.h"
#include "net/cert/internal/system_trust_store.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "net/cert_net/cert_net_fetcher_url_request.h"
#include "net/log/test_net_log.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/test/cert_builder.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/gtest_util.h"
#include "net/test/revocation_builder.h"
#include "net/test/test_certificate_data.h"
#include "net/test/test_data_directory.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
#include "third_party/boringssl/src/pki/extended_key_usage.h"
#include "third_party/boringssl/src/pki/input.h"
#include "third_party/boringssl/src/pki/ocsp_revocation_status.h"
#include "third_party/boringssl/src/pki/parse_certificate.h"
#include "third_party/boringssl/src/pki/parser.h"
#include "third_party/boringssl/src/pki/pem.h"
#include "third_party/boringssl/src/pki/signature_algorithm.h"
#include "third_party/boringssl/src/pki/trust_store.h"

#if BUILDFLAG(IS_ANDROID)
#include "net/cert/cert_verify_proc_android.h"
#elif BUILDFLAG(IS_IOS)
#include "base/ios/ios_util.h"
#include "net/cert/cert_verify_proc_ios.h"
#elif BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
#include "net/cert/internal/trust_store_chrome.h"
#endif

IsError;
IsOk;

HexEncode;

namespace net {

namespace {

const char kTrustAnchorVerifyHistogram[] =;
const char kTrustAnchorVerifyOutOfDateHistogram[] =;

// Returns a TLV to use as an unknown signature algorithm when building a cert.
// The specific contents are as follows (the OID is from
// https://davidben.net/oid):
//
// SEQUENCE {
//   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
//   NULL {}
// }
std::string TestOid0SignatureAlgorithmTLV() {}

// An OID for use in tests, from https://davidben.net/oid
// OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
bssl::der::Input TestOid0() {}

// Mock CertVerifyProc that sets the CertVerifyResult to a given value for
// all certificates that are Verify()'d
class MockCertVerifyProc : public CertVerifyProc {};

int MockCertVerifyProc::VerifyInternal(X509Certificate* cert,
                                       const std::string& hostname,
                                       const std::string& ocsp_response,
                                       const std::string& sct_list,
                                       int flags,
                                       CertVerifyResult* verify_result,
                                       const NetLogWithSource& net_log) {}

// This enum identifies a concrete implemenation of CertVerifyProc.
//
// The type is erased by CreateCertVerifyProc(), however needs to be known for
// some of the test expectations.
enum CertVerifyProcType {};

// Returns a textual description of the CertVerifyProc implementation
// that is being tested, used to give better names to parameterized
// tests.
std::string VerifyProcTypeToName(
    const testing::TestParamInfo<CertVerifyProcType>& params) {}

scoped_refptr<CertVerifyProc> CreateCertVerifyProc(
    CertVerifyProcType type,
    scoped_refptr<CertNetFetcher> cert_net_fetcher,
    scoped_refptr<CRLSet> crl_set,
    CertificateList additional_trust_anchors,
    CertificateList additional_untrusted_authorities) {}

// The set of all CertVerifyProcTypes that tests should be parameterized on.
// This needs to be kept in sync with CertVerifyProc::CreateSystemVerifyProc()
// and the platforms where CreateSslSystemTrustStore() is not a dummy store.
constexpr CertVerifyProcType kAllCertVerifiers[] =;
static_assert;

// Returns true if a test root added through ScopedTestRoot can verify
// successfully as a target certificate with chain of length 1 on the given
// CertVerifyProcType.
bool ScopedTestRootCanTrustTargetCert(CertVerifyProcType verify_proc_type) {}

// Returns true if a non-self-signed CA certificate added through
// ScopedTestRoot can verify successfully as the root of a chain by the given
// CertVerifyProcType.
bool ScopedTestRootCanTrustIntermediateCert(
    CertVerifyProcType verify_proc_type) {}

std::string MakeRandomHexString(size_t num_bytes) {}

}  // namespace

// This fixture is for tests that apply to concrete implementations of
// CertVerifyProc. It will be run for all of the concrete CertVerifyProc types.
//
// It is called "Internal" as it tests the internal methods like
// "VerifyInternal()".
class CertVerifyProcInternalTest
    : public testing::TestWithParam<CertVerifyProcType> {};

INSTANTIATE_TEST_SUITE_P();

TEST_P(CertVerifyProcInternalTest, DistrustedIntermediate) {}

// Tests that a certificate is recognized as EV, when the valid EV policy OID
// for the trust anchor is the second candidate EV oid in the target
// certificate. This is a regression test for crbug.com/705285.
TEST_P(CertVerifyProcInternalTest, EVVerificationMultipleOID) {}

// Target cert has an EV policy, and verifies successfully, but has a chain of
// length 1 because the target cert was directly trusted in the trust store.
// Should verify OK but not with STATUS_IS_EV.
TEST_P(CertVerifyProcInternalTest, TrustedTargetCertWithEVPolicy) {}

// Target cert has an EV policy, and verifies successfully with a chain of
// length 1, and its fingerprint matches the cert fingerprint for that ev
// policy. This should never happen in reality, but just test that things don't
// explode if it does.
TEST_P(CertVerifyProcInternalTest,
       TrustedTargetCertWithEVPolicyAndEVFingerprint) {}

// Target cert has an EV policy, and has a valid path to the EV root, but the
// intermediate has been trusted directly. Should stop building the path at the
// intermediate and verify OK but not with STATUS_IS_EV.
// See https://crbug.com/979801
TEST_P(CertVerifyProcInternalTest, TrustedIntermediateCertWithEVPolicy) {}

TEST_P(CertVerifyProcInternalTest, CertWithNullInCommonNameAndNoSAN) {}

TEST_P(CertVerifyProcInternalTest, CertWithNullInCommonNameAndValidSAN) {}

TEST_P(CertVerifyProcInternalTest, CertWithNullInSAN) {}

// Tests the case where the target certificate is accepted by
// X509CertificateBytes, but has errors that should cause verification to fail.
TEST_P(CertVerifyProcInternalTest, InvalidTarget) {}

// Tests the case where an intermediate certificate is accepted by
// X509CertificateBytes, but has errors that should prevent using it during
// verification.  The verification should succeed, since the intermediate
// wasn't necessary.
TEST_P(CertVerifyProcInternalTest, UnnecessaryInvalidIntermediate) {}

TEST_P(CertVerifyProcInternalTest, RejectExpiredCert) {}

TEST_P(CertVerifyProcInternalTest, RejectWeakKeys) {}

// Regression test for http://crbug.com/108514.
// Generates a chain with a root with a SHA256 signature, and another root with
// the same name/SPKI/keyid but with a SHA1 signature. The SHA256 root is
// trusted. The SHA1 certificate is supplied as an extra cert, but should be
// ignored as the verifier should prefer the trusted cert when path building
// from the leaf, generating the shortest chain of "leaf -> sha256root". If the
// path builder doesn't prioritize it could build an unoptimal but valid path
// like "leaf -> sha1root -> sha256root".
TEST_P(CertVerifyProcInternalTest, ExtraneousRootCert) {}

// Test for bug 94673.
TEST_P(CertVerifyProcInternalTest, GoogleDigiNotarTest) {}

TEST_P(CertVerifyProcInternalTest, NameConstraintsOk) {}

TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) {}

// This fixture is for testing the verification of a certificate chain which
// has some sort of mismatched signature algorithm (i.e.
// Certificate.signatureAlgorithm and TBSCertificate.algorithm are different).
class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test {};

// This is a control test to make sure that the test helper
// VerifyLeaf() works as expected. There is no actual mismatch in the
// algorithms used here.
//
//  Certificate.signatureAlgorithm:  sha1WithRSASignature
//  TBSCertificate.algorithm:        sha1WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha1) {}

// This is a control test to make sure that the test helper
// VerifyLeaf() works as expected. There is no actual mismatch in the
// algorithms used here.
//
//  Certificate.signatureAlgorithm:  sha256WithRSASignature
//  TBSCertificate.algorithm:        sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha256) {}

// Mismatched signature algorithms in the leaf certificate.
//
//  Certificate.signatureAlgorithm:  sha1WithRSASignature
//  TBSCertificate.algorithm:        sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha256) {}

// Mismatched signature algorithms in the leaf certificate.
//
//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
//  TBSCertificate.algorithm:        sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha1) {}

// Unrecognized signature algorithm in the leaf certificate.
//
//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
//  TBSCertificate.algorithm:        ?
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Unknown) {}

// Unrecognized signature algorithm in the leaf certificate.
//
//  Certificate.signatureAlgorithm:  ?
//  TBSCertificate.algorithm:        sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafUnknownSha256) {}

// Mismatched signature algorithms in the intermediate certificate.
//
//  Certificate.signatureAlgorithm:  sha1WithRSASignature
//  TBSCertificate.algorithm:        sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha1Sha256) {}

// Mismatched signature algorithms in the intermediate certificate.
//
//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
//  TBSCertificate.algorithm:        sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha256Sha1) {}

// Mismatched signature algorithms in the root certificate.
//
//  Certificate.signatureAlgorithm:  sha256WithRSAEncryption
//  TBSCertificate.algorithm:        sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootSha256Sha1) {}

// Unrecognized signature algorithm in the root certificate.
//
//  Certificate.signatureAlgorithm:  ?
//  TBSCertificate.algorithm:        sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootUnknownSha256) {}

TEST(CertVerifyProcTest, TestHasTooLongValidity) {}

// Integration test for CertVerifyProc::HasTooLongValidity.
// There isn't a way to add test entries to the known roots list for testing
// the full CertVerifyProc implementations, but HasTooLongValidity is checked
// by the outer CertVerifyProc::Verify. Thus the test can mock the
// VerifyInternal result to pretend there was a successful verification with
// is_issued_by_known_root and see that Verify overrides that with error.
TEST(CertVerifyProcTest, VerifyCertValidityTooLong) {}

TEST_P(CertVerifyProcInternalTest, TestKnownRoot) {}

// This tests that on successful certificate verification,
// CertVerifyResult::public_key_hashes is filled with a SHA256 hash for each
// of the certificates in the chain.
TEST_P(CertVerifyProcInternalTest, PublicKeyHashes) {}

// Basic test for returning the chain in CertVerifyResult. Note that the
// returned chain may just be a reflection of the originally supplied chain;
// that is, if any errors occur, the default chain returned is an exact copy
// of the certificate to be verified. The remaining VerifyReturn* tests are
// used to ensure that the actual, verified chain is being returned by
// Verify().
TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) {}

// Test that certificates issued for 'intranet' names (that is, containing no
// known public registry controlled domain information) issued by well-known
// CAs are flagged appropriately, while certificates that are issued by
// internal CAs are not flagged.
TEST(CertVerifyProcTest, IntranetHostsRejected) {}

// Tests that certificates issued by Symantec's legacy infrastructure
// are rejected according to the policies outlined in
// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
// unless the caller has explicitly disabled that enforcement.
TEST(CertVerifyProcTest, SymantecCertsRejected) {}

// Test that the certificate returned in CertVerifyResult is able to reorder
// certificates that are not ordered from end-entity to root. While this is
// a protocol violation if sent during a TLS handshake, if multiple sources
// of intermediate certificates are combined, it's possible that order may
// not be maintained.
TEST_P(CertVerifyProcInternalTest, VerifyReturnChainProperlyOrdered) {}

// Test that Verify() filters out certificates which are not related to
// or part of the certificate chain being verified.
TEST_P(CertVerifyProcInternalTest, VerifyReturnChainFiltersUnrelatedCerts) {}

TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchors) {}

TEST_P(CertVerifyProcInternalTest, AdditionalIntermediates) {}

TEST_P(CertVerifyProcInternalTest, AdditionalIntermediateDuplicatesRoot) {}

TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchorDuplicateIntermediate) {}

// Tests that certificates issued by user-supplied roots are not flagged as
// issued by a known root. This should pass whether or not the platform supports
// detecting known roots.
TEST_P(CertVerifyProcInternalTest, IsIssuedByKnownRootIgnoresTestRoots) {}

// Test that CRLSets are effective in making a certificate appear to be
// revoked.
TEST_P(CertVerifyProcInternalTest, CRLSet) {}

TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) {}

TEST_P(CertVerifyProcInternalTest, CRLSetRootReturnsChain) {}

// Tests that CertVerifyProc implementations apply CRLSet revocations by
// subject.
TEST_P(CertVerifyProcInternalTest, CRLSetRevokedBySubject) {}

// Ensures that CRLSets can be used to block known interception roots on
// platforms that support CRLSets, while otherwise detect known interception
// on platforms that do not.
TEST_P(CertVerifyProcInternalTest, BlockedInterceptionByRoot) {}

// Ensures that CRLSets can be used to block known interception intermediates,
// while still allowing other certificates from that root..
TEST_P(CertVerifyProcInternalTest, BlockedInterceptionByIntermediate) {}

// Ensures that CRLSets can be used to flag known interception roots, even
// when they are not blocked.
TEST_P(CertVerifyProcInternalTest, DetectsInterceptionByRoot) {}

// Tests that CRLSets participate in path building functions, and that as
// long as a valid path exists within the verification graph, verification
// succeeds.
//
// In this test, there are two roots (D and E), and three possible paths
// to validate a leaf (A):
// 1. A(B) -> B(C) -> C(D) -> D(D)
// 2. A(B) -> B(C) -> C(E) -> E(E)
// 3. A(B) -> B(F) -> F(E) -> E(E)
//
// Each permutation of revocation is tried:
// 1. Revoking E by SPKI, so that only Path 1 is valid (as E is in Paths 2 & 3)
// 2. Revoking C(D) and F(E) by serial, so that only Path 2 is valid.
// 3. Revoking C by SPKI, so that only Path 3 is valid (as C is in Paths 1 & 2)
TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) {}

TEST_P(CertVerifyProcInternalTest, ValidityDayPlus5MinutesBeforeNotBefore) {}

TEST_P(CertVerifyProcInternalTest, ValidityDayBeforeNotBefore) {}

TEST_P(CertVerifyProcInternalTest, ValidityJustBeforeNotBefore) {}

TEST_P(CertVerifyProcInternalTest, ValidityJustAfterNotBefore) {}

TEST_P(CertVerifyProcInternalTest, ValidityJustBeforeNotAfter) {}

TEST_P(CertVerifyProcInternalTest, ValidityJustAfterNotAfter) {}

TEST_P(CertVerifyProcInternalTest, FailedIntermediateSignatureValidation) {}

TEST_P(CertVerifyProcInternalTest, FailedTargetSignatureValidation) {}

class CertVerifyProcNameNormalizationTest : public CertVerifyProcInternalTest {};

INSTANTIATE_TEST_SUITE_P();

// Tries to verify a chain where the leaf's issuer CN is PrintableString, while
// the intermediate's subject CN is UTF8String, and verifies the proper
// histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest, StringType) {}

// Tries to verify a chain where the leaf's issuer CN and intermediate's
// subject CN are both PrintableString but have differing case on the first
// character, and verifies the proper histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest, CaseFolding) {}

// Confirms that a chain generated by the same pattern as the other
// NameNormalizationTest cases which does not require normalization validates
// ok, and that the ByteEqual histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest, ByteEqual) {}

std::string Md5WithRSAEncryption() {}

// This is the same as CertVerifyProcInternalTest, but it additionally sets up
// networking capabilities for the cert verifiers, and a test server that can be
// used to serve mock responses for AIA/OCSP/CRL.
//
// An actual HTTP test server is used rather than simply mocking the network
// layer, since the certificate fetching networking layer is not mockable for
// all of the cert verifier implementations.
//
// The approach taken in this test fixture is to generate certificates
// on the fly so they use randomly chosen URLs, subjects, and serial
// numbers, in order to defeat global caching effects from the platform
// verifiers. Moreover, the AIA needs to be chosen dynamically since the
// test server's port number cannot be known statically.
class CertVerifyProcInternalWithNetFetchingTest
    : public CertVerifyProcInternalTest {};

INSTANTIATE_TEST_SUITE_P();

// Tries verifying a certificate chain that is missing an intermediate. The
// intermediate is available via AIA, however the server responds with a 404.
//
// NOTE: This test is separate from IntermediateFromAia200 as a different URL
// needs to be used to avoid having the result depend on globally cached success
// or failure of the fetch.
// Test is flaky on iOS crbug.com/860189
#if BUILDFLAG(IS_IOS)
#define MAYBE_IntermediateFromAia404
#else
#define MAYBE_IntermediateFromAia404
#endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       MAYBE_IntermediateFromAia404) {}
#undef MAYBE_IntermediateFromAia404

// Tries verifying a certificate chain that is missing an intermediate. The
// intermediate is available via AIA.
// TODO(crbug.com/41399468): Failing on iOS
#if BUILDFLAG(IS_IOS)
#define MAYBE_IntermediateFromAia200Der
#else
#define MAYBE_IntermediateFromAia200Der
#endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       MAYBE_IntermediateFromAia200Der) {}

// This test is the same as IntermediateFromAia200Der, except the certificate is
// served as PEM rather than DER.
//
// Tries verifying a certificate chain that is missing an intermediate. The
// intermediate is available via AIA, however is served as a PEM file rather
// than DER.
// TODO(crbug.com/41399468): Failing on iOS
#if BUILDFLAG(IS_IOS)
#define MAYBE_IntermediateFromAia200Pem
#else
#define MAYBE_IntermediateFromAia200Pem
#endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       MAYBE_IntermediateFromAia200Pem) {}

// This test is the same as IntermediateFromAia200Pem, but with a different
// formatting on the PEM data.
//
// TODO(crbug.com/41399468): Failing on iOS
#if BUILDFLAG(IS_IOS)
#define MAYBE_IntermediateFromAia200Pem2
#else
#define MAYBE_IntermediateFromAia200Pem2
#endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       MAYBE_IntermediateFromAia200Pem2) {}

// Tries verifying a certificate chain that uses a SHA1 intermediate,
// however, chasing the AIA can discover a SHA256 version of the intermediate.
//
// Path building should discover the stronger intermediate and use it.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       Sha1IntermediateButAIAHasSha256) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest, RevocationHardFailNoCrls) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailNoCrlsDisableNetworkFetches) {}

// CRL hard fail test where both leaf and intermediate are covered by valid
// CRLs which have empty (non-present) revokedCertificates list. Verification
// should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailCrlGoodNoRevokedCertificates) {}

// CRL hard fail test where both leaf and intermediate are covered by valid
// CRLs which have revokedCertificates lists that revoke other irrelevant
// serial numbers. Verification should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailCrlGoodIrrelevantSerialsRevoked) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailLeafRevokedByCrl) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailIntermediateRevokedByCrl) {}

// CRL hard fail test where the intermediate certificate has a good CRL, but
// the leaf's distribution point returns an http error. Verification should
// fail.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailLeafCrlDpHttpError) {}

// CRL hard fail test where the leaf certificate has a good CRL, but
// the intermediate's distribution point returns an http error. Verification
// should fail.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationHardFailIntermediateCrlDpHttpError) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest, RevocationSoftFailNoCrls) {}

// CRL soft fail test where both leaf and intermediate are covered by valid
// CRLs which have empty (non-present) revokedCertificates list. Verification
// should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailCrlGoodNoRevokedCertificates) {}

// CRL soft fail test where both leaf and intermediate are covered by valid
// CRLs which have revokedCertificates lists that revoke other irrelevant
// serial numbers. Verification should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailCrlGoodIrrelevantSerialsRevoked) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailLeafRevokedByCrl) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailLeafRevokedByCrlDisableNetworkFetches) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailIntermediateRevokedByCrl) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailLeafRevokedBySha1Crl) {}

TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailLeafRevokedByMd5Crl) {}

// CRL soft fail test where the intermediate certificate has a good CRL, but
// the leaf's distribution point returns an http error. Verification should
// succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailLeafCrlDpHttpError) {}

// CRL soft fail test where the leaf certificate has a good CRL, but
// the intermediate's distribution point returns an http error. Verification
// should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       RevocationSoftFailIntermediateCrlDpHttpError) {}

// Tests that an EV cert verification with successful online OCSP revocation
// checks is marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       EVOnlineOCSPRevocationCheckingGood) {}

// Tests that an EV cert verification with that could not retrieve online OCSP
// revocation information is verified but still marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       EVOnlineOCSPRevocationCheckingSoftFail) {}

// Tests that an EV cert verification with online OCSP returning affirmatively
// revoked is marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,
       EVOnlineOCSPRevocationCheckingRevoked) {}

// A set of tests that check how various constraints are enforced when they
// appear at different points in the chain, such as on the trust anchor versus
// on intermediates.
class CertVerifyProcConstraintsTest : public CertVerifyProcInternalTest {};

INSTANTIATE_TEST_SUITE_P();

TEST_P(CertVerifyProcConstraintsTest, BaseCase) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotCaRoot) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotCaIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsIsCaLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen0Root) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen1Root) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen2Root) {}

TEST_P(CertVerifyProcConstraintsTest,
       BasicConstraintsPathlen0IntermediateParent) {}

TEST_P(CertVerifyProcConstraintsTest,
       BasicConstraintsPathlen1IntermediateParent) {}

TEST_P(CertVerifyProcConstraintsTest,
       BasicConstraintsPathlen0IntermediateChild) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentRoot) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentRootX509V1) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, NameConstraintsNotMatchingRoot) {}

TEST_P(CertVerifyProcConstraintsTest, NameConstraintsNotMatchingIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, NameConstraintsMatchingRoot) {}

TEST_P(CertVerifyProcConstraintsTest, NameConstraintsMatchingIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, NameConstraintsOnLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, ValidityExpiredRoot) {}

TEST_P(CertVerifyProcConstraintsTest, ValidityNotYetValidRoot) {}

TEST_P(CertVerifyProcConstraintsTest, ValidityExpiredIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, ValidityNotYetValidIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Root) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints4Root) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints3Root) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints2Root) {}

// This is also a regression test for https://crbug.com/31497: If an
// intermediate has requireExplicitPolicy in its policyConstraints extension,
// verification should still succeed as long as some policy is valid for the
// chain, since Chrome does not specify any required policy as an input to
// certificate verification (allows anyPolicy).
TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints3Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints2Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints1Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Leaf) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitPolicyMapping0Root) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitPolicyMapping1Root) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy0Root) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy1Root) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy0Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy1Intermediate) {}

TEST_P(CertVerifyProcConstraintsTest, PoliciesRoot) {}

TEST_P(CertVerifyProcConstraintsTest, PolicyMappingsRoot) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoCertSignRoot) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentRoot) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoCertSignIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoDigitalSignatureLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, KeyUsageCertSignLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageNoServerAuthRoot) {}

TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageServerAuthRoot) {}

TEST_P(CertVerifyProcConstraintsTest,
       ExtendedKeyUsageNoServerAuthIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageServerAuthIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageNoServerAuthLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmRoot) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmLeaf) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionRoot) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionIntermediate) {}

TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionLeaf) {}

// A set of tests that check how various constraints are enforced when they
// are applied to a directly trusted non-self-signed leaf certificate.
class CertVerifyProcConstraintsTrustedLeafTest
    : public CertVerifyProcInternalTest {};

INSTANTIATE_TEST_SUITE_P();

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BaseCase) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, RootAlsoTrusted) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsIsCa) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsPathlen) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsMissing) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, NameConstraintsNotMatching) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, ValidityExpired) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, PolicyConstraints) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, InhibitAnyPolicy) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, KeyUsageNoDigitalSignature) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, KeyUsageCertSignLeaf) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, ExtendedKeyUsageNoServerAuth) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, UnknownSignatureAlgorithm) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, WeakSignatureAlgorithm) {}

TEST_P(CertVerifyProcConstraintsTrustedLeafTest, UnknownExtension) {}

// A set of tests that check how various constraints are enforced when they
// are applied to a directly trusted self-signed leaf certificate.
class CertVerifyProcConstraintsTrustedSelfSignedTest
    : public CertVerifyProcInternalTest {};

INSTANTIATE_TEST_SUITE_P();

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, BaseCase) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, BasicConstraintsIsCa) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       BasicConstraintsNotCaPathlen) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       BasicConstraintsIsCaPathlen) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       BasicConstraintsMissing) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       NameConstraintsNotMatching) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, ValidityExpired) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, PolicyConstraints) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, InhibitAnyPolicy) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       KeyUsageNoDigitalSignature) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, KeyUsageCertSignLeaf) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       ExtendedKeyUsageNoServerAuth) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
       UnknownSignatureAlgorithm) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, WeakSignatureAlgorithm) {}

TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, UnknownExtension) {}

TEST(CertVerifyProcTest, RejectsPublicSHA1) {}

TEST(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) {}

enum ExpectedAlgorithms {};

struct WeakDigestTestData {};

const char* StringOrDefault(const char* str, const char* default_value) {}

// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
// to output the parameter that was passed. Without this, it will simply
// attempt to print out the first twenty bytes of the object, which depending
// on platform and alignment, may result in an invalid read.
void PrintTo(const WeakDigestTestData& data, std::ostream* os) {}

class CertVerifyProcWeakDigestTest
    : public testing::TestWithParam<WeakDigestTestData> {};

// Tests that the CertVerifyProc::Verify() properly surfaces the (weak) hash
// algorithms used in the chain.
TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {}

// The signature algorithm of the root CA should not matter.
const WeakDigestTestData kVerifyRootCATestData[] =;
INSTANTIATE_TEST_SUITE_P();

// The signature algorithm of intermediates should be properly detected.
const WeakDigestTestData kVerifyIntermediateCATestData[] =;

INSTANTIATE_TEST_SUITE_P();

// The signature algorithm of end-entity should be properly detected.
const WeakDigestTestData kVerifyEndEntityTestData[] =;

INSTANTIATE_TEST_SUITE_P();

// Incomplete chains do not report the status of the intermediate.
// Note: really each of these tests should also expect the digest algorithm of
// the intermediate (included as a comment). However CertVerifyProc::Verify() is
// unable to distinguish that this is an intermediate and not a trust anchor, so
// this intermediate is treated like a trust anchor.
const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] =;

INSTANTIATE_TEST_SUITE_P();

// Incomplete chains should report the status of the end-entity.
// since the intermediate is treated as a trust anchor these should
// be still simply be invalid.
const WeakDigestTestData kVerifyIncompleteEETestData[] =;

INSTANTIATE_TEST_SUITE_P();

// Md2, Md4, and Md5 are all considered invalid.
const WeakDigestTestData kVerifyMixedTestData[] =;

INSTANTIATE_TEST_SUITE_P();

// The EE is a trusted certificate. Even though it uses weak hashes, these
// should not be reported.
const WeakDigestTestData kVerifyTrustedEETestData[] =;

INSTANTIATE_TEST_SUITE_P();

// Test fixture for verifying certificate names.
class CertVerifyProcNameTest : public ::testing::Test {};

// Don't match the common name
TEST_F(CertVerifyProcNameTest, DontMatchCommonName) {}

// Matches the iPAddress SAN (IPv4)
TEST_F(CertVerifyProcNameTest, MatchesIpSanIpv4) {}

// Matches the iPAddress SAN (IPv6)
TEST_F(CertVerifyProcNameTest, MatchesIpSanIpv6) {}

// Should not match the iPAddress SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchIpSanIpv6) {}

// Compressed form matches the iPAddress SAN (IPv6)
TEST_F(CertVerifyProcNameTest, MatchesIpSanCompressedIpv6) {}

// IPv6 mapped form should NOT match iPAddress SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchIpSanIPv6Mapped) {}

// Matches the dNSName SAN
TEST_F(CertVerifyProcNameTest, MatchesDnsSan) {}

// Matches the dNSName SAN (trailing . ignored)
TEST_F(CertVerifyProcNameTest, MatchesDnsSanTrailingDot) {}

// Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSan) {}

// Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanInvalid) {}

// Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanTwoTrailingDots) {}

// Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanLeadingAndTrailingDot) {}

// Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanTrailingDot) {}

// Test that trust anchors are appropriately recorded via UMA.
TEST(CertVerifyProcTest, HasTrustAnchorVerifyUMA) {}

// Test that certificates with multiple trust anchors present result in
// only a single trust anchor being recorded, and that being the most specific
// trust anchor.
TEST(CertVerifyProcTest, LogsOnlyMostSpecificTrustAnchorUMA) {}

// Test that trust anchors histograms record whether or not
// is_issued_by_known_root was derived from the OS.
TEST(CertVerifyProcTest, HasTrustAnchorVerifyOutOfDateUMA) {}

// If the CertVerifyProc::VerifyInternal implementation calculated the stapled
// OCSP results in the CertVerifyResult, CertVerifyProc::Verify should not
// re-calculate them.
TEST(CertVerifyProcTest, DoesNotRecalculateStapledOCSPResult) {}

TEST(CertVerifyProcTest, CalculateStapledOCSPResultIfNotAlreadyDone) {}

}  // namespace net