chromium/net/cert/cert_verify_proc_builtin_unittest.cc

// Copyright 2019 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_builtin.h"

#include <optional>
#include <string_view>

#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "components/network_time/time_tracker/time_tracker.h"
#include "net/base/features.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/crl_set.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/sct_status_flags.h"
#include "net/cert/time_conversions.h"
#include "net/cert/x509_util.h"
#include "net/cert_net/cert_net_fetcher_url_request.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.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/embedded_test_server/request_handler_util.h"
#include "net/test/gtest_util.h"
#include "net/test/revocation_builder.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/pki/trust_store.h"
#include "third_party/boringssl/src/pki/trust_store_collection.h"
#include "third_party/boringssl/src/pki/trust_store_in_memory.h"

#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
#include "base/version_info/version_info.h"  // nogncheck
#endif

IsError;
IsOk;

_;

namespace net {

namespace {

std::unique_ptr<test_server::HttpResponse> HangRequestAndCallback(
    base::OnceClosure callback,
    const test_server::HttpRequest& request) {}

void FailTest(const std::string& message) {}

std::unique_ptr<test_server::HttpResponse> FailRequestAndFailTest(
    const std::string& message,
    scoped_refptr<base::TaskRunner> main_task_runner,
    const test_server::HttpRequest& request) {}

std::unique_ptr<test_server::HttpResponse> ServeResponse(
    HttpStatusCode status_code,
    const std::string& content_type,
    const std::string& content,
    const test_server::HttpRequest& request) {}

std::string MakeRandomHexString(size_t num_bytes) {}

static std::string MakeRandomPath(std::string_view suffix) {}

int VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc,
                         scoped_refptr<X509Certificate> cert,
                         const std::string& hostname,
                         const std::string& ocsp_response,
                         const std::string& sct_list,
                         int flags,
                         CertVerifyResult* verify_result,
                         NetLogSource* out_source) {}

class MockSystemTrustStore : public SystemTrustStore {};

class BlockingTrustStore : public bssl::TrustStore {};

class MockCTVerifier : public CTVerifier {};

class MockCTPolicyEnforcer : public CTPolicyEnforcer {};

}  // namespace

class CertVerifyProcBuiltinTest : public ::testing::Test {};

TEST_F(CertVerifyProcBuiltinTest, ShouldBypassHSTS) {}

TEST_F(CertVerifyProcBuiltinTest, SimpleSuccess) {}

TEST_F(CertVerifyProcBuiltinTest, CallsCtVerifierAndReturnsSctStatus) {}

#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
TEST_F(CertVerifyProcBuiltinTest, EVCertStatusMaintainedForCompliantCert) {}
#endif

TEST_F(CertVerifyProcBuiltinTest, DistrustedIntermediate) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithConstraints) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithConstraintsNotEnforced) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithOutsideDNSConstraints) {}

TEST_F(CertVerifyProcBuiltinTest,
       AddedRootWithOutsideDNSConstraintsNotMatched) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithOutsideCIDRConstraints) {}

TEST_F(CertVerifyProcBuiltinTest,
       AddedRootWithOutsideCIDRConstraintsNotMatched) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithBadTime) {}

TEST_F(CertVerifyProcBuiltinTest, AddedRootWithBadTimeButNotEnforced) {}

TEST_F(CertVerifyProcBuiltinTest, TimeTracker) {}

TEST_F(CertVerifyProcBuiltinTest, TimeTrackerFailureIsRetriedWithSystemTime) {}

TEST_F(CertVerifyProcBuiltinTest, CRLNotCheckedForKnownRoots) {}

// Tests that if the verification deadline is exceeded during revocation
// checking, additional CRL fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineCRL) {}

// Tests that if the verification deadline is exceeded during revocation
// checking, additional OCSP fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineOCSP) {}

#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
// Tests that if we're doing EV verification, that no OCSP revocation checking
// is done.
TEST_F(CertVerifyProcBuiltinTest, EVNoOCSPRevocationChecks) {}
#endif  // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)

#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)

scoped_refptr<ct::SignedCertificateTimestamp> MakeSct(base::Time t,
                                                      std::string_view log_id) {}

// Test SCT constraints fail-open if CT is disabled.
TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintSctConstraintsWithCtDisabled) {}

// Test SctNotAfter constraint only requires 1 valid SCT that satisfies the
// constraint.
// Set a SctNotAfter constraint at time t1.
// Mock that there are two SCTs, one of which is at t1 and thus satisfies the
// constraint. The second is at t2 and does not satisfy the constraint, but
// this is ok as only one valid SCT that meets the constraint is needed.
TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintSctNotAfter) {}

// Test SctNotAfter constraint is only satisfied by successfully verified SCTs.
// Set a SctNotAfter constraint at time t1.
// Mock that there are two SCTs. One SCT for time t1 but from an unknown log,
// thus should not be usable for the SctNotAfter constraint. The second CT is
// from a known log but is at time t2 which is after t1, so does not satisfy
// the constraint. Therefore the certificate should fail verification.
TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintSctNotAfterLogUnknown) {}

// Test SctNotAfter constraint is not satisfied by a SCT from a disqualified
// log even if the SCT timestamp is before the log was disqualified. Once a log
// is disqualified we assume it can not be trusted and could sign SCTs for any
// timestamp.
// SCT #1 is from a disqualified log and the timestamp is before the log was
// disqualified.
// SCT #2 is from a valid log but is after the SctNotAfter constraint, so does
// not satisfy the constraint.
TEST_F(
    CertVerifyProcBuiltinTest,
    ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogBeforeDisqualification) {}

// Test SctNotAfter constraint is not satisfied by a SCT from a disqualified
// log if the SCT timestamp is after the log was disqualified.
// SCT #1 is from a disqualified log and the timestamp is after the log was
// disqualified.
// SCT #2 is from a valid log but is after the SctNotAfter constraint, so does
// not satisfy the constraint.
TEST_F(
    CertVerifyProcBuiltinTest,
    ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogAfterDisqualification) {}

// Test SctNotAfter constraint is satisfied by a SCT from a disqualified
// log if the log disqualification time is in the future.
TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintSctNotAfterFromFutureDisqualifiedLog) {}

// Test SctAllAfter constraint requires all valid SCTs to satisfy the
// constraint.
TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintSctAllAfter) {}

std::string CurVersionString() {}
std::string NextVersionString() {}
std::string PrevVersionString() {}

TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMinVersion) {}

TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMaxVersion) {}

TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMinAndMaxVersion) {}

// Tests multiple constraint objects in the constraints vector. The CRS
// constraints are satisfied if at least one of the constraint objects is
// satisfied.
//
// The first constraint has a SctNotAfter that is before the SCT and thus is
// not satisfied.
// The second constraint has a SctAllAfter set to the same time, which is
// before the certificate SCT, and thus the certificate verification succeeds.
//
// TODO(https://crbug.com/40941039): This test isn't very interesting right
// now. Once more constraint types are added change the test to be more
// realistic of how multiple constraint sets is expected to be used.
TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintMultipleConstraints) {}

TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintNotEnforcedIfAnchorLocallyTrusted) {}

TEST_F(CertVerifyProcBuiltinTest,
       ChromeRootStoreConstraintNotEnforcedIfAnchorAdditionallyTrusted) {}
#endif  // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)

TEST_F(CertVerifyProcBuiltinTest, DeadlineExceededDuringSyncGetIssuers) {}

namespace {

// 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 UnknownSignatureAlgorithmTLV() {}

// Returns a TLV to use as an invalid signature algorithm when building a cert.
// This is a SEQUENCE so that it will pass the bssl::ParseCertificate code
// and fail inside bssl::ParseSignatureAlgorithm.
// SEQUENCE {
//   INTEGER { 42 }
// }
std::string InvalidSignatureAlgorithmTLV() {}

}  // namespace

TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmTarget) {}

TEST_F(CertVerifyProcBuiltinTest,
       UnparsableMismatchedTBSSignatureAlgorithmTarget) {}

TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmIntermediate) {}

TEST_F(CertVerifyProcBuiltinTest,
       UnparsableMismatchedTBSSignatureAlgorithmIntermediate) {}

TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmRoot) {}

// This test is disabled on Android as adding the invalid root through
// ScopedTestRoot causes it to be parsed by the Java X509 code which barfs. We
// could re-enable if Chrome on Android has fully switched to the
// builtin-verifier and ScopedTestRoot no longer has Android-specific code.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot
#else
#define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot
#endif
TEST_F(CertVerifyProcBuiltinTest,
       MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot) {}

TEST_F(CertVerifyProcBuiltinTest, IterationLimit) {}

}  // namespace net