chromium/chrome/browser/ssl/sct_reporting_service_browsertest.cc

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

#include "chrome/browser/ssl/sct_reporting_service.h"

#include <memory>
#include <tuple>

#include "base/base64.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/functional/callback.h"
#include "base/i18n/time_formatting.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/cert_verifier_browser_test.h"
#include "chrome/browser/ssl/sct_reporting_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/network_service_test_helper.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/sct_status_flags.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/cert/x509_certificate.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/cert_test_util.h"
#include "net/test/ct_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/simple_connection_listener.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/ct_log_info.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/proto/sct_audit_report.pb.h"
#include "services/network/test/test_url_loader_factory.h"

namespace {

// These LogId constants allow test cases to specify SCTs from both Google and
// non-Google logs, allowing tests to vary how they meet (or don't meet) the
// Chrome CT policy. To be compliant, the cert used by the embedded test server
// currently requires three embedded SCTs, including at least one from a Google
// log and one from a non-Google log.
//
// Google's "Argon2023" log ("6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4="):
const uint8_t kTestGoogleLogId[] =;
// Cloudflare's "Nimbus2023" log
// ("ejKMVNi3LbYg6jjgUh7phBZwMhOFTTvSK8E6V6NS61I="):
const uint8_t kTestNonGoogleLogId1[] =;
// DigiCert's "Yeti2023" log ("Nc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kw="):
const uint8_t kTestNonGoogleLogId2[] =;

// Constructs a net::SignedCertificateTimestampAndStatus with the given
// information and appends it to |sct_list|.
void MakeTestSCTAndStatus(
    net::ct::SignedCertificateTimestamp::Origin origin,
    const std::string& extensions,
    const std::string& signature_data,
    const base::Time& timestamp,
    const std::string& log_id,
    net::ct::SCTVerifyStatus status,
    net::SignedCertificateTimestampAndStatusList* sct_list) {}

std::string ExtractRESTURLParameter(std::string url, std::string param) {}

std::string HexToString(const char* hex) {}

}  // namespace

class SCTReportingServiceBrowserTest : public CertVerifierBrowserTest {};

// Tests that reports should be sent when extended reporting is opted in.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       OptedIn_ShouldEnqueueReport) {}

// Tests that disabling Safe Browsing entirely should cause reports to not get
// sent.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, DisableSafebrowsing) {}

// Tests that we don't send a report for a navigation with a cert error.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       CertErrorDoesNotEnqueueReport) {}

// Tests that reports aren't sent for Incognito windows.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       IncognitoWindow_ShouldNotEnqueueReport) {}

// Tests that disabling Extended Reporting causes the cache to be cleared.
// TODO(crbug.com/40749747): Reenable. Flakes heavily on all platforms.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       DISABLED_OptingOutClearsSCTAuditingCache) {}

// Tests that reports are still sent for opted-in profiles after the network
// service crashes and is restarted.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       ReportsSentAfterNetworkServiceRestart) {}

// Tests that invalid SCTs don't get reported when the overall result is
// compliant with CT policy.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       CTCompliantInvalidSCTsNotReported) {}

// Tests that invalid SCTs don't get included when the overall result is
// non-compliant with CT policy. Valid SCTs should still be reported.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       CTNonCompliantInvalidSCTsNotReported) {}

IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, NoValidSCTsNoReport) {}

class SCTReportingServiceZeroSamplingRateBrowserTest
    : public SCTReportingServiceBrowserTest {};

// Tests that the embedder is not notified when the sampling rate is zero.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceZeroSamplingRateBrowserTest,
                       EmbedderNotNotified) {}

// Tests the simple case where a report succeeds on the first try.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, SucceedOnFirstTry) {}

IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, RetryOnceAndSucceed) {}

IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest, FailAfterMaxRetries) {}

// Test that a cert error on the first attempt to send a report will trigger
// retries that succeed if the server starts using a good cert.
IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       CertificateErrorTriggersRetry) {}

class SCTHashdanceBrowserTest : public SCTReportingServiceBrowserTest {};

IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest, ReportSCTNotFound) {}

IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest, DoNotReportSCTFound) {}

IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest,
                       HashdanceReportCountIncremented) {}

// Test that report count isn't incremented when retrying a single audit report.
// Regression test for crbug.com/1348313.
IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest,
                       HashdanceReportCountNotIncrementedOnRetry) {}

IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest, HashdanceReportLimitReached) {}

// Wrapper around FilePathWatcher to help tests wait for an auditing report to
// be persisted to disk. This is also robust to the persistence file being
// written to before the test initiates the wait, helping avoid race conditions
// that can cause hard-to-debug flakes.
//
// This currently monitors *two* file paths, because depending on the platform
// (and the state of the network service sandbox rollout) the persisted data
// file path may have an extra "Network/" subdirectory component, but it is
// difficult to determine this from test data. WaitUntilPersisted() will wait
// until *either* of the two paths have been written to.
//
// ReportPersistenceWaiter also takes a `filesize_threshold` as the "empty"
// persistence file still has some structure/data in it. For the current
// persistence format (list of JSON dicts), the "empty" persistence file is 2
// bytes (the empty list `[]`).
class ReportPersistenceWaiter {};

IN_PROC_BROWSER_TEST_F(SCTReportingServiceBrowserTest,
                       PersistedReportClearedOnClearBrowsingHistory) {}