Integrate Cert Verifier Service into Network Service and Chrome
Bug: 1015134 Change-Id: I7cf982dae2f62be1987c24f0a8c822a4733cb7bd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2155824 Commit-Queue: Matthew Denton <mpdenton@chromium.org> Reviewed-by: Matt Falkenhagen <falken@chromium.org> Reviewed-by: John Abd-El-Malek <jam@chromium.org> Reviewed-by: Ryan Sleevi <rsleevi@chromium.org> Cr-Commit-Position: refs/heads/master@{#773901}
This commit is contained in:

committed by
Commit Bot

parent
8621cf2a3a
commit
03c45a2667
android_webview/browser/safe_browsing
chrome
browser
BUILD.gnDEPS
browsing_data
chromeos
component_updater
net
cert_verify_proc_browsertest.ccchrome_network_service_browsertest.ccnetwork_quality_estimator_prefs_browsertest.ccprofile_network_context_service_browsertest.ccsystem_network_context_manager.ccsystem_network_context_manager.hsystem_network_context_manager_browsertest.cc
prefs
prerender
isolated
sharing
webrtc
ssl
test
components/net_log
content
browser
BUILD.gnDEPSnetwork_service_browsertest.ccnetwork_service_instance_impl.ccnetwork_service_restart_browsertest.ccstorage_partition_impl.cc
public
headless/lib/browser
services
cert_verifier
BUILD.gn
cert_net_url_loader
cert_verifier_service.cccert_verifier_service.hcert_verifier_service_factory.cccert_verifier_service_factory.hcert_verifier_service_factory_unittest.ccintegration_tests
public
test_cert_verifier_service_factory.cctest_cert_verifier_service_factory.hnetwork
BUILD.gn
cors
crl_set_distributor.cchttp_cache_data_counter_unittest.cchttp_cache_data_remover_unittest.ccnetwork_context.ccnetwork_context.hnetwork_context_unittest.ccnetwork_service_unittest.ccorigin_policy
public
quic_transport_unittest.ccssl_config_service_mojo_unittest.cctest
weblayer/browser
@ -26,6 +26,7 @@
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/navigation_controller.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
@ -48,6 +49,8 @@ void RecordIsWebViewViewable(bool isViewable) {
|
||||
network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams() {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
network_context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
network_context_params->user_agent = GetUserAgent();
|
||||
return network_context_params;
|
||||
}
|
||||
|
@ -2241,6 +2241,7 @@ static_library("browser") {
|
||||
"//printing/buildflags",
|
||||
"//rlz/buildflags",
|
||||
"//services/audio/public/cpp",
|
||||
"//services/cert_verifier:lib",
|
||||
"//services/data_decoder/public/cpp",
|
||||
"//services/device/public/cpp:device_features",
|
||||
"//services/device/public/cpp/usb",
|
||||
|
@ -335,6 +335,7 @@ include_rules = [
|
||||
"+rlz",
|
||||
"+sandbox/win/src", # The path doesn't say it, but this is the Windows sandbox.
|
||||
"+services/audio/public",
|
||||
"+services/cert_verifier",
|
||||
"+services/data_decoder/public",
|
||||
"+services/device/public",
|
||||
"+services/image_annotation/public",
|
||||
|
@ -117,6 +117,7 @@
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/cookie_manager.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/gfx/favicon_size.h"
|
||||
|
||||
@ -1124,11 +1125,15 @@ class ChromeBrowsingDataRemoverDelegateTest : public testing::Test {
|
||||
content::GetNetworkService();
|
||||
task_environment_.RunUntilIdle();
|
||||
|
||||
auto network_context_params = network::mojom::NetworkContextParams::New();
|
||||
network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
mojo::PendingRemote<network::mojom::NetworkContext> network_context_remote;
|
||||
network_context_ = std::make_unique<network::NetworkContext>(
|
||||
network::NetworkService::GetNetworkServiceForTesting(),
|
||||
network_context_remote.InitWithNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
std::move(network_context_params));
|
||||
content::BrowserContext::GetDefaultStoragePartition(profile_.get())
|
||||
->SetNetworkContextForTesting(std::move(network_context_remote));
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
@ -89,10 +90,16 @@ class SigninPartitionManagerTest : public ChromeRenderViewHostTestHarness {
|
||||
signin_ui_web_contents_ = content::WebContentsTester::CreateTestWebContents(
|
||||
GetSigninProfile(), content::SiteInstance::Create(GetSigninProfile()));
|
||||
|
||||
auto system_network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
system_network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
|
||||
system_network_context_ = std::make_unique<network::NetworkContext>(
|
||||
network::NetworkService::GetNetworkServiceForTesting(),
|
||||
system_network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
std::move(system_network_context_params));
|
||||
|
||||
GURL url(kEmbedderUrl);
|
||||
content::WebContentsTester::For(signin_ui_web_contents())
|
||||
@ -186,10 +193,17 @@ class SigninPartitionManagerTest : public ChromeRenderViewHostTestHarness {
|
||||
// Bind the NetworkContext for the new StoragePartition.
|
||||
mojo::PendingRemote<network::mojom::NetworkContext>
|
||||
signin_network_context_remote;
|
||||
|
||||
auto signin_network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
signin_network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
|
||||
signin_network_context_ = std::make_unique<network::NetworkContext>(
|
||||
network::NetworkService::GetNetworkServiceForTesting(),
|
||||
signin_network_context_remote.InitWithNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
std::move(signin_network_context_params));
|
||||
storage_partition->SetNetworkContextForTesting(
|
||||
std::move(signin_network_context_remote));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "net/test/embedded_test_server/embedded_test_server.h"
|
||||
@ -82,6 +83,13 @@ class CRLSetComponentInstallerTest : public PlatformTest {
|
||||
task_environment_.RunUntilIdle();
|
||||
}
|
||||
|
||||
network::mojom::NetworkContextParamsPtr CreateNetworkContextParams() {
|
||||
auto params = network::mojom::NetworkContextParams::New();
|
||||
params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
return params;
|
||||
}
|
||||
|
||||
protected:
|
||||
content::BrowserTaskEnvironment task_environment_;
|
||||
net::EmbeddedTestServer test_server_;
|
||||
@ -100,7 +108,7 @@ class CRLSetComponentInstallerTest : public PlatformTest {
|
||||
TEST_F(CRLSetComponentInstallerTest, ConfiguresOnInstall) {
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
CreateNetworkContextParams());
|
||||
|
||||
// Ensure the test server can load by default.
|
||||
LoadURL(test_server_.GetURL("/empty.html"));
|
||||
@ -122,7 +130,7 @@ TEST_F(CRLSetComponentInstallerTest, ConfiguresOnInstall) {
|
||||
TEST_F(CRLSetComponentInstallerTest, ReconfiguresAfterRestartWithCRLSet) {
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
CreateNetworkContextParams());
|
||||
|
||||
// Ensure the test server can load by default.
|
||||
LoadURL(test_server_.GetURL("/empty.html"));
|
||||
@ -148,7 +156,7 @@ TEST_F(CRLSetComponentInstallerTest, ReconfiguresAfterRestartWithCRLSet) {
|
||||
network_context_.reset();
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
CreateNetworkContextParams());
|
||||
|
||||
// Ensure the test server is still flagged even with a new context and
|
||||
// service.
|
||||
@ -162,7 +170,7 @@ TEST_F(CRLSetComponentInstallerTest, ReconfiguresAfterRestartWithCRLSet) {
|
||||
TEST_F(CRLSetComponentInstallerTest, ReconfiguresAfterRestartWithNoCRLSet) {
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
CreateNetworkContextParams());
|
||||
|
||||
// Ensure the test server can load by default.
|
||||
LoadURL(test_server_.GetURL("/empty.html"));
|
||||
@ -176,7 +184,7 @@ TEST_F(CRLSetComponentInstallerTest, ReconfiguresAfterRestartWithNoCRLSet) {
|
||||
network_context_.reset();
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
network::mojom::NetworkContextParams::New());
|
||||
CreateNetworkContextParams());
|
||||
|
||||
// Ensure the test server can still load.
|
||||
LoadURL(test_server_.GetURL("/empty.html"));
|
||||
|
@ -7,12 +7,14 @@
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/test/base/chrome_test_utils.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "net/dns/mock_host_resolver.h"
|
||||
#include "net/test/embedded_test_server/embedded_test_server.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
@ -83,8 +85,26 @@ class NetLogPlatformBrowserTestBase : public PlatformBrowserTest {
|
||||
// This is an integration test to ensure that CertVerifyProc netlog events
|
||||
// continue to be logged once cert verification is moved out of the network
|
||||
// service process. (See crbug.com/1015134 and crbug.com/1040681.)
|
||||
class CertVerifyProcNetLogBrowserTest : public NetLogPlatformBrowserTestBase {
|
||||
class CertVerifyProcNetLogBrowserTest
|
||||
: public NetLogPlatformBrowserTestBase,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
void SetUpInProcessBrowserTestFixture() override {
|
||||
if (GetParam()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
scoped_feature_list_.InitAndEnableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
#endif
|
||||
} else {
|
||||
scoped_feature_list_.InitAndDisableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
}
|
||||
}
|
||||
|
||||
void SetUpOnMainThread() override {
|
||||
PlatformBrowserTest::SetUpOnMainThread();
|
||||
|
||||
@ -129,10 +149,11 @@ class CertVerifyProcNetLogBrowserTest : public NetLogPlatformBrowserTestBase {
|
||||
const std::string kTestHost = "netlog-example.a.test";
|
||||
|
||||
protected:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(CertVerifyProcNetLogBrowserTest, Test) {
|
||||
IN_PROC_BROWSER_TEST_P(CertVerifyProcNetLogBrowserTest, Test) {
|
||||
ASSERT_TRUE(https_server_.Start());
|
||||
|
||||
// Request using a unique host name to ensure that the cert verification wont
|
||||
@ -150,3 +171,7 @@ IN_PROC_BROWSER_TEST_F(CertVerifyProcNetLogBrowserTest, Test) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
content::FlushNetworkServiceInstanceForTesting();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(CertVerifierService,
|
||||
CertVerifyProcNetLogBrowserTest,
|
||||
::testing::Bool());
|
||||
|
@ -88,6 +88,8 @@ class ChromeNetworkServiceBrowserTest
|
||||
context_params->enable_encrypted_cookies = enable_encrypted_cookies;
|
||||
context_params->cookie_path =
|
||||
browser()->profile()->GetPath().Append(FILE_PATH_LITERAL("cookies"));
|
||||
context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
GetNetworkService()->CreateNetworkContext(
|
||||
network_context.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
|
@ -195,6 +195,8 @@ IN_PROC_BROWSER_TEST_F(NetworkQualityEstimatorPrefsBrowserTest,
|
||||
mojo::PendingRemote<network::mojom::NetworkContext> network_context;
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
context_params->http_server_properties_path =
|
||||
browser()->profile()->GetPath().Append(
|
||||
FILE_PATH_LITERAL("Temp Network Persistent State"));
|
||||
|
@ -3,12 +3,16 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/optional.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
@ -25,8 +29,10 @@
|
||||
#include "chrome/browser/net/profile_network_context_service.h"
|
||||
#include "chrome/browser/net/profile_network_context_service_factory.h"
|
||||
#include "chrome/browser/net/profile_network_context_service_test_utils.h"
|
||||
#include "chrome/browser/net/system_network_context_manager.h"
|
||||
#include "chrome/browser/policy/policy_test_utils.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/profiles/profile_manager.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_features.h"
|
||||
@ -38,10 +44,12 @@
|
||||
#include "components/policy/core/common/policy_map.h"
|
||||
#include "components/policy/policy_constants.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/simple_url_loader_test_helper.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/system/data_pipe_utils.h"
|
||||
#include "net/base/features.h"
|
||||
#include "net/base/load_flags.h"
|
||||
@ -51,6 +59,8 @@
|
||||
#include "net/test/embedded_test_server/http_response.h"
|
||||
#include "net/test/embedded_test_server/request_handler_util.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
|
||||
#include "services/cert_verifier/test_cert_verifier_service_factory.h"
|
||||
#include "services/network/public/cpp/cors/cors.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
@ -444,19 +454,94 @@ IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceDiskCacheBrowsertest,
|
||||
}
|
||||
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
namespace {
|
||||
void UnblockOnProfileCreation(base::RunLoop* run_loop,
|
||||
Profile* profile,
|
||||
Profile::CreateStatus status) {
|
||||
if (status == Profile::CREATE_STATUS_INITIALIZED)
|
||||
run_loop->Quit();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest
|
||||
: public policy::PolicyTest,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
void SetUpInProcessBrowserTestFixture() override {
|
||||
scoped_feature_list_.InitWithFeatureState(
|
||||
net::features::kCertVerifierBuiltinFeature,
|
||||
/*enabled=*/GetParam());
|
||||
std::vector<base::Feature> enabled_features, disabled_features;
|
||||
if (use_builtin_cert_verifier()) {
|
||||
enabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
} else {
|
||||
disabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
}
|
||||
if (enable_cert_verifier_service()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
enabled_features.push_back(network::features::kCertVerifierService);
|
||||
test_cert_verifier_service_factory_.emplace();
|
||||
content::SetCertVerifierServiceFactoryForTesting(
|
||||
&test_cert_verifier_service_factory_.value());
|
||||
#endif
|
||||
} else {
|
||||
disabled_features.push_back(network::features::kCertVerifierService);
|
||||
}
|
||||
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
|
||||
policy::PolicyTest::SetUpInProcessBrowserTestFixture();
|
||||
}
|
||||
|
||||
void TearDownInProcessBrowserTestFixture() override {
|
||||
content::SetCertVerifierServiceFactoryForTesting(nullptr);
|
||||
}
|
||||
|
||||
void SetUpOnMainThread() override {
|
||||
if (enable_cert_verifier_service()) {
|
||||
test_cert_verifier_service_factory_->ReleaseAllCertVerifierParams();
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectUseBuiltinCertVerifierCorrectUsingCertVerifierService(
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl
|
||||
use_builtin_cert_verifier) {
|
||||
ASSERT_TRUE(enable_cert_verifier_service());
|
||||
ASSERT_TRUE(test_cert_verifier_service_factory_);
|
||||
EXPECT_EQ(1ul, test_cert_verifier_service_factory_->num_captured_params());
|
||||
EXPECT_EQ(use_builtin_cert_verifier,
|
||||
test_cert_verifier_service_factory_->GetParamsAtIndex(0)
|
||||
->creation_params->use_builtin_cert_verifier);
|
||||
// Send it to the actual CertVerifierServiceFactory.
|
||||
test_cert_verifier_service_factory_->ReleaseNextCertVerifierParams();
|
||||
}
|
||||
|
||||
Profile* CreateNewProfile() {
|
||||
ProfileManager* profile_manager = g_browser_process->profile_manager();
|
||||
base::FilePath new_path =
|
||||
profile_manager->GenerateNextProfileDirectoryPath();
|
||||
base::RunLoop run_loop;
|
||||
profile_manager->CreateProfileAsync(
|
||||
new_path, base::BindRepeating(&UnblockOnProfileCreation, &run_loop),
|
||||
base::string16(), std::string());
|
||||
run_loop.Run();
|
||||
return profile_manager->GetProfileByPath(new_path);
|
||||
}
|
||||
|
||||
bool use_builtin_cert_verifier() const { return GetParam(); }
|
||||
bool enable_cert_verifier_service() const {
|
||||
return enable_cert_verifier_service_;
|
||||
}
|
||||
void set_enable_cert_verifier_service(bool enable_cv_service) {
|
||||
enable_cert_verifier_service_ = enable_cv_service;
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
bool enable_cert_verifier_service_ = false;
|
||||
|
||||
// Used if enable_cert_verifier_service() returns true.
|
||||
base::Optional<cert_verifier::TestCertVerifierServiceFactoryImpl>
|
||||
test_cert_verifier_service_factory_;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(
|
||||
@ -472,10 +557,11 @@ IN_PROC_BROWSER_TEST_P(
|
||||
/*in_memory=*/false, empty_relative_partition_path,
|
||||
&network_context_params, &cert_verifier_creation_params);
|
||||
|
||||
EXPECT_EQ(GetParam() ? network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kSystem,
|
||||
EXPECT_EQ(use_builtin_cert_verifier()
|
||||
? network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kSystem,
|
||||
cert_verifier_creation_params.use_builtin_cert_verifier);
|
||||
}
|
||||
|
||||
@ -519,6 +605,68 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
All,
|
||||
ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest,
|
||||
::testing::Bool());
|
||||
|
||||
class
|
||||
ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTestWithService
|
||||
: public ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest {
|
||||
public:
|
||||
ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTestWithService() {
|
||||
set_enable_cert_verifier_service(true);
|
||||
}
|
||||
|
||||
~ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTestWithService()
|
||||
override = default;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(
|
||||
ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTestWithService,
|
||||
Test) {
|
||||
{
|
||||
content::BrowserContext::GetDefaultStoragePartition(CreateNewProfile())
|
||||
->GetNetworkContext();
|
||||
|
||||
ExpectUseBuiltinCertVerifierCorrectUsingCertVerifierService(
|
||||
use_builtin_cert_verifier()
|
||||
? network::mojom::CertVerifierCreationParams::CertVerifierImpl::
|
||||
kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::CertVerifierImpl::
|
||||
kSystem);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_POLICY_SUPPORTED)
|
||||
// If the BuiltinCertificateVerifierEnabled policy is set it should override
|
||||
// the feature flag.
|
||||
policy::PolicyMap policies;
|
||||
SetPolicy(&policies, policy::key::kBuiltinCertificateVerifierEnabled,
|
||||
std::make_unique<base::Value>(true));
|
||||
UpdateProviderPolicy(policies);
|
||||
|
||||
{
|
||||
content::BrowserContext::GetDefaultStoragePartition(CreateNewProfile())
|
||||
->GetNetworkContext();
|
||||
|
||||
ExpectUseBuiltinCertVerifierCorrectUsingCertVerifierService(
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kBuiltin);
|
||||
}
|
||||
|
||||
SetPolicy(&policies, policy::key::kBuiltinCertificateVerifierEnabled,
|
||||
std::make_unique<base::Value>(false));
|
||||
UpdateProviderPolicy(policies);
|
||||
|
||||
{
|
||||
content::BrowserContext::GetDefaultStoragePartition(CreateNewProfile())
|
||||
->GetNetworkContext();
|
||||
|
||||
ExpectUseBuiltinCertVerifierCorrectUsingCertVerifierService(
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kSystem);
|
||||
}
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_POLICY_SUPPORTED)
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
All,
|
||||
ProfileNetworkContextServiceCertVerifierBuiltinFeaturePolicyTestWithService,
|
||||
::testing::Bool());
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
|
||||
enum class CorsTestMode {
|
||||
|
@ -55,14 +55,17 @@
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "crypto/sha2.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "net/base/features.h"
|
||||
#include "net/net_buildflags.h"
|
||||
#include "net/third_party/uri_template/uri_template.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/shared_url_loader_factory.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
@ -272,6 +275,7 @@ SystemNetworkContextManager::GetURLLoaderFactory() {
|
||||
params->process_id = network::mojom::kBrowserProcessId;
|
||||
params->is_corb_enabled = false;
|
||||
params->is_trusted = true;
|
||||
|
||||
url_loader_factory_.reset();
|
||||
GetContext()->CreateURLLoaderFactory(
|
||||
url_loader_factory_.BindNewPipeAndPassReceiver(), std::move(params));
|
||||
@ -644,8 +648,8 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
|
||||
network::mojom::CertVerifierCreationParams::New();
|
||||
ConfigureDefaultNetworkContextParams(network_context_params.get(),
|
||||
cert_verifier_creation_params.get());
|
||||
network_context_params->cert_verifier_creation_params =
|
||||
std::move(cert_verifier_creation_params);
|
||||
network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(std::move(cert_verifier_creation_params));
|
||||
return network_context_params;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/optional.h"
|
||||
@ -123,9 +124,12 @@ class SystemNetworkContextManager {
|
||||
network::mojom::CertVerifierCreationParams*
|
||||
cert_verifier_creation_params);
|
||||
|
||||
// Same as ConfigureDefaultNetworkContextParams() but returns a newly
|
||||
// allocated network::mojom::NetworkContextParams with the
|
||||
// CertVerifierCreationParams already placed into the NetworkContextParams.
|
||||
// Performs the same function as ConfigureDefaultNetworkContextParams(), and
|
||||
// then returns a newly allocated network::mojom::NetworkContextParams with
|
||||
// some modifications: if the CertVerifierService is enabled, the new
|
||||
// NetworkContextParams will contain a CertVerifierServiceRemoteParams.
|
||||
// Otherwise the newly configured CertVerifierCreationParams is placed
|
||||
// directly into the NetworkContextParams.
|
||||
network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams();
|
||||
|
||||
// Returns a shared global NetExportFileWriter instance, used by net-export.
|
||||
@ -160,6 +164,10 @@ class SystemNetworkContextManager {
|
||||
}
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(
|
||||
SystemNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest,
|
||||
Test);
|
||||
|
||||
class URLLoaderFactoryForSystem;
|
||||
|
||||
// Constructor. |pref_service| must out live this object.
|
||||
|
@ -21,8 +21,11 @@
|
||||
#include "chrome/test/base/in_process_browser_test.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/version_info/version_info.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "services/cert_verifier/test_cert_verifier_service_factory.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/network_service_buildflags.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
@ -458,57 +461,142 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
class SystemNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest
|
||||
: public policy::PolicyTest,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public testing::WithParamInterface<std::tuple<bool, bool>> {
|
||||
public:
|
||||
SystemNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest() {
|
||||
bool use_builtin_cert_verifier;
|
||||
std::tie(use_builtin_cert_verifier, enable_cert_verification_service_) =
|
||||
GetParam();
|
||||
cert_verifier_impl_ = use_builtin_cert_verifier
|
||||
? network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kSystem;
|
||||
}
|
||||
|
||||
void SetUpInProcessBrowserTestFixture() override {
|
||||
scoped_feature_list_.InitWithFeatureState(
|
||||
net::features::kCertVerifierBuiltinFeature,
|
||||
/*enabled=*/GetParam());
|
||||
std::vector<base::Feature> enabled_features, disabled_features;
|
||||
if (cert_verifier_impl_ == network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin) {
|
||||
enabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
} else {
|
||||
disabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
}
|
||||
if (enable_cert_verification_service_) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
enabled_features.push_back(network::features::kCertVerifierService);
|
||||
test_cert_verifier_service_factory_.emplace();
|
||||
content::SetCertVerifierServiceFactoryForTesting(
|
||||
&test_cert_verifier_service_factory_.value());
|
||||
#endif
|
||||
} else {
|
||||
disabled_features.push_back(network::features::kCertVerifierService);
|
||||
}
|
||||
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
|
||||
policy::PolicyTest::SetUpInProcessBrowserTestFixture();
|
||||
}
|
||||
|
||||
void TearDownInProcessBrowserTestFixture() override {
|
||||
content::SetCertVerifierServiceFactoryForTesting(nullptr);
|
||||
}
|
||||
|
||||
void SetUpOnMainThread() override {
|
||||
if (enable_cert_verification_service_) {
|
||||
test_cert_verifier_service_factory_->ReleaseAllCertVerifierParams();
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectUseBuiltinCertVerifierCorrect(
|
||||
network::mojom::NetworkContextParamsPtr& network_context_params_ptr,
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl
|
||||
use_builtin_cert_verifier) {
|
||||
ASSERT_TRUE(network_context_params_ptr);
|
||||
ASSERT_TRUE(network_context_params_ptr->cert_verifier_params);
|
||||
if (enable_cert_verification_service_) {
|
||||
EXPECT_TRUE(
|
||||
network_context_params_ptr->cert_verifier_params->is_remote_params());
|
||||
ASSERT_TRUE(test_cert_verifier_service_factory_);
|
||||
ASSERT_EQ(1ul,
|
||||
test_cert_verifier_service_factory_->num_captured_params());
|
||||
ASSERT_TRUE(test_cert_verifier_service_factory_->GetParamsAtIndex(0)
|
||||
->creation_params);
|
||||
EXPECT_EQ(use_builtin_cert_verifier,
|
||||
test_cert_verifier_service_factory_->GetParamsAtIndex(0)
|
||||
->creation_params->use_builtin_cert_verifier);
|
||||
// Send it to the actual CertVerifierServiceFactory.
|
||||
test_cert_verifier_service_factory_->ReleaseNextCertVerifierParams();
|
||||
} else {
|
||||
ASSERT_TRUE(network_context_params_ptr->cert_verifier_params
|
||||
->is_creation_params());
|
||||
EXPECT_EQ(use_builtin_cert_verifier,
|
||||
network_context_params_ptr->cert_verifier_params
|
||||
->get_creation_params()
|
||||
->use_builtin_cert_verifier);
|
||||
}
|
||||
}
|
||||
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl
|
||||
cert_verifier_impl() const {
|
||||
return cert_verifier_impl_;
|
||||
}
|
||||
|
||||
private:
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl
|
||||
cert_verifier_impl_;
|
||||
bool enable_cert_verification_service_;
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
|
||||
// Used if |enable_cert_verification_service_| set to true.
|
||||
base::Optional<cert_verifier::TestCertVerifierServiceFactoryImpl>
|
||||
test_cert_verifier_service_factory_;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(
|
||||
SystemNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest,
|
||||
Test) {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params_ptr;
|
||||
|
||||
// If no BuiltinCertificateVerifierEnabled policy is set, the
|
||||
// use_builtin_cert_verifier param should be set from the feature flag.
|
||||
EXPECT_EQ(GetParam() ? network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kSystem,
|
||||
g_browser_process->system_network_context_manager()
|
||||
->CreateDefaultNetworkContextParams()
|
||||
->cert_verifier_creation_params->use_builtin_cert_verifier);
|
||||
network_context_params_ptr =
|
||||
g_browser_process->system_network_context_manager()
|
||||
->CreateDefaultNetworkContextParams();
|
||||
ExpectUseBuiltinCertVerifierCorrect(network_context_params_ptr,
|
||||
cert_verifier_impl());
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_POLICY_SUPPORTED)
|
||||
// If the BuiltinCertificateVerifierEnabled policy is set it should override
|
||||
// the feature flag.
|
||||
// If the BuiltinCertificateVerifierEnabled policy is set it should
|
||||
// override the feature flag.
|
||||
policy::PolicyMap policies;
|
||||
SetPolicy(&policies, policy::key::kBuiltinCertificateVerifierEnabled,
|
||||
std::make_unique<base::Value>(true));
|
||||
UpdateProviderPolicy(policies);
|
||||
EXPECT_EQ(
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kBuiltin,
|
||||
|
||||
network_context_params_ptr =
|
||||
g_browser_process->system_network_context_manager()
|
||||
->CreateDefaultNetworkContextParams()
|
||||
->cert_verifier_creation_params->use_builtin_cert_verifier);
|
||||
->CreateDefaultNetworkContextParams();
|
||||
ExpectUseBuiltinCertVerifierCorrect(
|
||||
network_context_params_ptr,
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kBuiltin);
|
||||
|
||||
SetPolicy(&policies, policy::key::kBuiltinCertificateVerifierEnabled,
|
||||
std::make_unique<base::Value>(false));
|
||||
UpdateProviderPolicy(policies);
|
||||
EXPECT_EQ(
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kSystem,
|
||||
|
||||
network_context_params_ptr =
|
||||
g_browser_process->system_network_context_manager()
|
||||
->CreateDefaultNetworkContextParams()
|
||||
->cert_verifier_creation_params->use_builtin_cert_verifier);
|
||||
->CreateDefaultNetworkContextParams();
|
||||
ExpectUseBuiltinCertVerifierCorrect(
|
||||
network_context_params_ptr,
|
||||
network::mojom::CertVerifierCreationParams::CertVerifierImpl::kSystem);
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_POLICY_SUPPORTED)
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
All,
|
||||
SystemNetworkContextServiceCertVerifierBuiltinFeaturePolicyTest,
|
||||
::testing::Bool());
|
||||
::testing::Combine(::testing::Bool(), ::testing::Bool()));
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/testing_pref_store.h"
|
||||
#include "components/sync_preferences/pref_service_mock_factory.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/ssl_config.mojom.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -43,6 +44,8 @@ TEST_F(CommandLinePrefStoreSSLManagerTest, CommandLinePrefs) {
|
||||
SSLConfigServiceManager::RegisterPrefs(registry.get());
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
std::unique_ptr<SSLConfigServiceManager> config_manager(
|
||||
SSLConfigServiceManager::CreateDefaultManager(local_state.get()));
|
||||
config_manager->AddToNetworkContextParams(context_params.get());
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "services/network/public/cpp/shared_url_loader_factory.h"
|
||||
#include "services/network/public/cpp/simple_url_loader.h"
|
||||
#include "services/network/public/mojom/cookie_manager.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
@ -795,6 +796,8 @@ void IsolatedPrerenderTabHelper::CreateIsolatedURLLoaderFactory() {
|
||||
context_params->initial_custom_proxy_config =
|
||||
isolated_prerender_service->proxy_configurator()
|
||||
->CreateCustomProxyConfig();
|
||||
context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
|
||||
// Also register a client config receiver so that updates to the set of proxy
|
||||
// hosts or proxy headers will be updated.
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "services/network/public/cpp/shared_url_loader_factory.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/p2p.mojom.h"
|
||||
#include "services/network/public/mojom/p2p_trusted.mojom.h"
|
||||
@ -321,6 +322,8 @@ network::mojom::NetworkContext* SharingServiceHost::GetNetworkContext() {
|
||||
network::mojom::NetworkContextParams::New();
|
||||
context_params->user_agent = "";
|
||||
context_params->accept_language = "en-us,en";
|
||||
context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
|
||||
content::GetNetworkService()->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(), std::move(context_params));
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/testing_pref_service.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "net/cert/cert_verifier.h"
|
||||
#include "net/ssl/ssl_config.h"
|
||||
@ -46,6 +47,9 @@ class SSLConfigServiceManagerPrefTest : public testing::Test,
|
||||
// steal the only two params that the |config_manager| populates.
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
config_manager->AddToNetworkContextParams(network_context_params.get());
|
||||
EXPECT_TRUE(network_context_params->initial_ssl_config);
|
||||
initial_config_ = std::move(network_context_params->initial_ssl_config);
|
||||
|
@ -220,6 +220,7 @@ static_library("test_support") {
|
||||
"//pdf",
|
||||
"//ppapi/buildflags",
|
||||
"//printing/buildflags",
|
||||
"//services/cert_verifier:test_support",
|
||||
"//skia",
|
||||
"//sql",
|
||||
"//sql:test_support",
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/cpp/simple_url_loader.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_network_context.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -294,6 +295,10 @@ class NetExportFileWriterTest : public ::testing::Test {
|
||||
ASSERT_TRUE(log_temp_dir_.CreateUniqueTempDir());
|
||||
network::mojom::NetworkContextParamsPtr params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
params->cert_verifier_params =
|
||||
network::FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config =
|
||||
|
@ -148,6 +148,7 @@ jumbo_source_set("browser") {
|
||||
"//services/audio",
|
||||
"//services/audio/public/cpp",
|
||||
"//services/audio/public/mojom",
|
||||
"//services/cert_verifier:lib",
|
||||
"//services/content:impl",
|
||||
"//services/content/public/cpp",
|
||||
"//services/content/public/mojom",
|
||||
|
@ -72,6 +72,9 @@ include_rules = [
|
||||
"-services/network",
|
||||
"+services/network/public/cpp",
|
||||
"+services/network/public/mojom",
|
||||
"-services/cert_verifier",
|
||||
"+services/cert_verifier/public/cpp",
|
||||
"+services/cert_verifier/public/mojom",
|
||||
|
||||
# In general, //content shouldn't depend on //device.
|
||||
# This is the an exception.
|
||||
@ -152,6 +155,8 @@ specific_include_rules = {
|
||||
"+services/network/url_request_context_owner.h",
|
||||
],
|
||||
"network_service_instance_impl\.cc": [
|
||||
# Used to instantiate a CertVerifierServiceFactory in the browser process.
|
||||
"+services/cert_verifier/cert_verifier_service_factory.h",
|
||||
# TODO(crbug.com/1049894): Remove.
|
||||
"+services/network/network_service.h",
|
||||
],
|
||||
|
@ -255,6 +255,8 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
|
||||
mojo::Remote<network::mojom::NetworkContext> network_context;
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
context_params->cert_verifier_params =
|
||||
GetCertVerifierParams(network::mojom::CertVerifierCreationParams::New());
|
||||
context_params->http_cache_path = GetCacheDirectory();
|
||||
GetNetworkService()->CreateNetworkContext(
|
||||
network_context.BindNewPipeAndPassReceiver(), std::move(context_params));
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "net/log/net_log_util.h"
|
||||
#include "services/cert_verifier/cert_verifier_service_factory.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
@ -481,4 +482,95 @@ void PingNetworkService(base::OnceClosure closure) {
|
||||
base::Passed(std::move(closure))));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
mojo::PendingRemote<cert_verifier::mojom::CertVerifierService>
|
||||
GetNewCertVerifierServiceRemote(
|
||||
cert_verifier::mojom::CertVerifierServiceFactory*
|
||||
cert_verifier_service_factory,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) {
|
||||
mojo::PendingRemote<cert_verifier::mojom::CertVerifierService>
|
||||
cert_verifier_remote;
|
||||
cert_verifier_service_factory->GetNewCertVerifier(
|
||||
cert_verifier_remote.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(creation_params));
|
||||
return cert_verifier_remote;
|
||||
}
|
||||
|
||||
// Owns the CertVerifierServiceFactory used by the browser.
|
||||
// Lives on the UI thread.
|
||||
class CertVerifierServiceFactoryOwner {
|
||||
public:
|
||||
CertVerifierServiceFactoryOwner() = default;
|
||||
CertVerifierServiceFactoryOwner(const CertVerifierServiceFactoryOwner&) =
|
||||
delete;
|
||||
CertVerifierServiceFactoryOwner& operator=(
|
||||
const CertVerifierServiceFactoryOwner&) = delete;
|
||||
~CertVerifierServiceFactoryOwner() = delete;
|
||||
|
||||
static CertVerifierServiceFactoryOwner* Get() {
|
||||
static base::NoDestructor<CertVerifierServiceFactoryOwner>
|
||||
cert_verifier_service_factory_owner;
|
||||
return &*cert_verifier_service_factory_owner;
|
||||
}
|
||||
|
||||
// Passing nullptr will reset the current remote.
|
||||
void SetCertVerifierServiceFactoryForTesting(
|
||||
cert_verifier::mojom::CertVerifierServiceFactory* service_factory) {
|
||||
if (service_factory) {
|
||||
DCHECK(!service_factory_);
|
||||
}
|
||||
service_factory_ = service_factory;
|
||||
service_factory_remote_.reset();
|
||||
}
|
||||
|
||||
// Returns a pointer to a CertVerifierServiceFactory usable on the UI thread.
|
||||
cert_verifier::mojom::CertVerifierServiceFactory*
|
||||
GetCertVerifierServiceFactory() {
|
||||
if (!service_factory_) {
|
||||
// Except in tests, our CertVerifierServiceFactoryImpl is a singleton.
|
||||
static base::NoDestructor<cert_verifier::CertVerifierServiceFactoryImpl>
|
||||
cv_service_factory(
|
||||
service_factory_remote_.BindNewPipeAndPassReceiver());
|
||||
service_factory_ = service_factory_remote_.get();
|
||||
}
|
||||
return service_factory_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Bound to UI thread.
|
||||
mojo::Remote<cert_verifier::mojom::CertVerifierServiceFactory>
|
||||
service_factory_remote_;
|
||||
cert_verifier::mojom::CertVerifierServiceFactory* service_factory_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
network::mojom::CertVerifierParamsPtr GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParamsPtr
|
||||
cert_verifier_creation_params) {
|
||||
if (!base::FeatureList::IsEnabled(network::features::kCertVerifierService)) {
|
||||
return network::mojom::CertVerifierParams::NewCreationParams(
|
||||
std::move(cert_verifier_creation_params));
|
||||
}
|
||||
|
||||
auto cv_service_remote_params =
|
||||
network::mojom::CertVerifierServiceRemoteParams::New();
|
||||
|
||||
// Create a cert verifier service.
|
||||
cv_service_remote_params
|
||||
->cert_verifier_service = GetNewCertVerifierServiceRemote(
|
||||
CertVerifierServiceFactoryOwner::Get()->GetCertVerifierServiceFactory(),
|
||||
std::move(cert_verifier_creation_params));
|
||||
|
||||
return network::mojom::CertVerifierParams::NewRemoteParams(
|
||||
std::move(cv_service_remote_params));
|
||||
}
|
||||
|
||||
void SetCertVerifierServiceFactoryForTesting(
|
||||
cert_verifier::mojom::CertVerifierServiceFactory* service_factory) {
|
||||
CertVerifierServiceFactoryOwner::Get()
|
||||
->SetCertVerifierServiceFactoryForTesting(service_factory);
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -69,6 +69,8 @@ mojo::PendingRemote<network::mojom::NetworkContext> CreateNetworkContext() {
|
||||
mojo::PendingRemote<network::mojom::NetworkContext> network_context;
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
context_params->cert_verifier_params =
|
||||
GetCertVerifierParams(network::mojom::CertVerifierCreationParams::New());
|
||||
GetNetworkService()->CreateNetworkContext(
|
||||
network_context.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@ -95,6 +96,7 @@
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
|
||||
#include "services/metrics/public/cpp/ukm_builders.h"
|
||||
#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
@ -2369,13 +2371,14 @@ void StoragePartitionImpl::InitNetworkContext() {
|
||||
GetContentClient()->browser()->ConfigureNetworkContextParams(
|
||||
browser_context_, is_in_memory_, relative_partition_path_,
|
||||
context_params.get(), cert_verifier_creation_params.get());
|
||||
DCHECK(!context_params->cert_verifier_creation_params)
|
||||
<< "|cert_verifier_creation_params| should not be set in the "
|
||||
"NetworkContextParams, as they will eventually be removed when the "
|
||||
"CertVerifierService ships.";
|
||||
DCHECK(!context_params->cert_verifier_params)
|
||||
<< "|cert_verifier_params| should not be set in the NetworkContextParams,"
|
||||
"as they will be replaced with either the newly configured "
|
||||
"|cert_verifier_creation_params| or with a new pipe to the "
|
||||
"CertVerifierService.";
|
||||
|
||||
context_params->cert_verifier_creation_params =
|
||||
std::move(cert_verifier_creation_params);
|
||||
context_params->cert_verifier_params =
|
||||
GetCertVerifierParams(std::move(cert_verifier_creation_params));
|
||||
|
||||
// This mechanisms should be used only for legacy internal headers. You can
|
||||
// find a recommended alternative approach on URLRequest::cors_exempt_headers
|
||||
|
@ -1,6 +1,7 @@
|
||||
include_rules = [
|
||||
"-content",
|
||||
|
||||
"+services/cert_verifier/public/mojom",
|
||||
"+services/network/public/mojom",
|
||||
"+services/service_manager/public",
|
||||
"+services/service_manager/sandbox",
|
||||
|
@ -435,6 +435,7 @@ jumbo_source_set("browser_sources") {
|
||||
"//mojo/public/cpp/bindings",
|
||||
"//mojo/public/cpp/system",
|
||||
"//services/audio/public/mojom",
|
||||
"//services/cert_verifier/public/mojom",
|
||||
"//services/content/public/mojom",
|
||||
"//services/data_decoder/public/mojom",
|
||||
"//services/device/public/mojom:device_service",
|
||||
|
@ -1472,6 +1472,12 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
// BrowserContext's StoragePartition. StoragePartition will use the
|
||||
// NetworkService to create a new NetworkContext using these params.
|
||||
//
|
||||
// If the CertVerifierService is enabled, the CertVerifierCreationParams will
|
||||
// be used to create a new CertVerifierService, which will be passed to the
|
||||
// network service in NetworkContextParams. Otherwise, the
|
||||
// CertVerifierCreationParams will be placed in the NetworkContextParams and
|
||||
// sent directly to the NetworkService for in-process CertVerifier creation.
|
||||
//
|
||||
// If |in_memory| is true, |relative_partition_path| is still a path that
|
||||
// uniquely identifies the storage partition, though nothing should be written
|
||||
// to it.
|
||||
|
@ -11,7 +11,9 @@
|
||||
#include "base/callback_list.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom-forward.h"
|
||||
#include "services/network/public/cpp/network_connection_tracker.h"
|
||||
#include "services/network/public/mojom/network_context.mojom-forward.h"
|
||||
|
||||
namespace base {
|
||||
class SequencedTaskRunner;
|
||||
@ -77,6 +79,25 @@ CONTENT_EXPORT void SetNetworkConnectionTrackerForTesting(
|
||||
CONTENT_EXPORT const scoped_refptr<base::SequencedTaskRunner>&
|
||||
GetNetworkTaskRunner();
|
||||
|
||||
// Returns a CertVerifierParams that can be placed into a new
|
||||
// network::mojom::NetworkContextParams.
|
||||
//
|
||||
// If the CertVerifierService feature is enabled, the
|
||||
// |cert_verifier_creation_params| will be used to configure a new
|
||||
// CertVerifierService, and a pipe to the new CertVerifierService will be placed
|
||||
// in the CertVerifierParams.
|
||||
//
|
||||
// Otherwise, |cert_verifier_creation_params| will just be placed directly into
|
||||
// the CertVerifierParams to configure an in-network-service CertVerifier.
|
||||
CONTENT_EXPORT network::mojom::CertVerifierParamsPtr GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParamsPtr
|
||||
cert_verifier_creation_params);
|
||||
|
||||
// Sets the CertVerifierServiceFactory used to instantiate
|
||||
// CertVerifierServices.
|
||||
CONTENT_EXPORT void SetCertVerifierServiceFactoryForTesting(
|
||||
cert_verifier::mojom::CertVerifierServiceFactory* service_factory);
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_PUBLIC_BROWSER_NETWORK_SERVICE_INSTANCE_H_
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "base/test/test_suite.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/browser/network_service_instance_impl.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/test/test_host_resolver.h"
|
||||
#include "content/test/test_blink_web_unit_test_support.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -54,6 +55,21 @@ class ResetNetworkServiceBetweenTests : public testing::EmptyTestEventListener {
|
||||
DISALLOW_COPY_AND_ASSIGN(ResetNetworkServiceBetweenTests);
|
||||
};
|
||||
|
||||
// Similarly to the above, the global CertVerifierServiceFactory object needs
|
||||
// to be destructed in between tests.
|
||||
class ResetCertVerifierServiceFactoryBetweenTests
|
||||
: public testing::EmptyTestEventListener {
|
||||
public:
|
||||
ResetCertVerifierServiceFactoryBetweenTests() = default;
|
||||
|
||||
void OnTestEnd(const testing::TestInfo& test_info) override {
|
||||
SetCertVerifierServiceFactoryForTesting(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ResetCertVerifierServiceFactoryBetweenTests);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
UnitTestTestSuite::UnitTestTestSuite(base::TestSuite* test_suite)
|
||||
@ -69,6 +85,7 @@ UnitTestTestSuite::UnitTestTestSuite(base::TestSuite* test_suite)
|
||||
testing::TestEventListeners& listeners =
|
||||
testing::UnitTest::GetInstance()->listeners();
|
||||
listeners.Append(new ResetNetworkServiceBetweenTests);
|
||||
listeners.Append(new ResetCertVerifierServiceFactoryBetweenTests);
|
||||
|
||||
// The ThreadPool created by the test launcher is never destroyed.
|
||||
// Similarly, the FeatureList created here is never destroyed so it
|
||||
|
@ -179,8 +179,8 @@ HeadlessRequestContextManager::CreateSystemContext(
|
||||
::network::mojom::CertVerifierCreationParams::New();
|
||||
manager->ConfigureNetworkContextParamsInternal(
|
||||
network_context_params.get(), cert_verifier_creation_params.get());
|
||||
network_context_params->cert_verifier_creation_params =
|
||||
std::move(cert_verifier_creation_params);
|
||||
network_context_params->cert_verifier_params =
|
||||
content::GetCertVerifierParams(std::move(cert_verifier_creation_params));
|
||||
network_service->CreateNetworkContext(
|
||||
manager->system_context_.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(network_context_params));
|
||||
|
@ -29,6 +29,9 @@ source_set("tests") {
|
||||
sources = [
|
||||
"cert_verifier_service_factory_unittest.cc",
|
||||
"cert_verifier_service_unittest.cc",
|
||||
"integration_tests/network_context_unittest.cc",
|
||||
"integration_tests/network_service_unittest.cc",
|
||||
"integration_tests/ssl_config_service_mojo_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@ -37,8 +40,11 @@ source_set("tests") {
|
||||
"//base/test:test_support",
|
||||
"//net",
|
||||
"//net:test_support",
|
||||
"//services/cert_verifier/cert_net_url_loader:cert_net_url_loader",
|
||||
"//services/cert_verifier/public/mojom",
|
||||
"//services/network:network_service",
|
||||
"//services/network:test_support",
|
||||
"//services/network/public/cpp/cert_verifier:mojo_cert_verifier",
|
||||
"//services/network/public/mojom",
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
@ -17,7 +17,8 @@ CertNetFetcherTestUtil::CertNetFetcherTestUtil() {
|
||||
pending_receiver_ =
|
||||
pending_remote_url_loader_factory.InitWithNewPipeAndPassReceiver();
|
||||
|
||||
fetcher_ = base::MakeRefCounted<CertNetFetcherURLLoader>(
|
||||
fetcher_ = base::MakeRefCounted<CertNetFetcherURLLoader>();
|
||||
fetcher_->SetURLLoaderFactoryAndReconnector(
|
||||
std::move(pending_remote_url_loader_factory),
|
||||
base::BindRepeating(
|
||||
&CertNetFetcherTestUtil::RebindURLLoaderFactoryTrampoline,
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/cert/cert_net_fetcher.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
@ -142,6 +143,10 @@ class CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader {
|
||||
// requests have completed or Shutdown() is called.
|
||||
~AsyncCertNetFetcherURLLoader();
|
||||
|
||||
// Disconnects |factory_|, and calls FlushForTesting() in order to
|
||||
// synchronously disconnect.
|
||||
void DisconnectURLLoaderFactoryForTesting();
|
||||
|
||||
// Starts an asynchronous request to fetch the given URL. On completion
|
||||
// request->OnJobCompleted() will be invoked.
|
||||
void Fetch(std::unique_ptr<RequestParams> request_params,
|
||||
@ -156,8 +161,8 @@ class CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader {
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
// Callback for disconnection of |factory_|. Attempts to use
|
||||
// |bind_new_url_loader_factory_cb_| to reconnect.
|
||||
// Attempts to use |bind_new_url_loader_factory_cb_| to reconnect |factory_|.
|
||||
// There's no guarantee that |bind_new_url_loader_factory_cb_| will succeed.
|
||||
void RebindURLLoaderFactory();
|
||||
|
||||
// Finds a job with a matching RequestPararms or returns nullptr if there was
|
||||
@ -592,15 +597,7 @@ CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
BindNewURLLoaderFactoryCallback bind_new_url_loader_factory_cb)
|
||||
: factory_(std::move(factory_pending_remote)),
|
||||
bind_new_url_loader_factory_cb_(
|
||||
std::move(bind_new_url_loader_factory_cb)) {
|
||||
// If the URLLoaderFactory disconnects, try to rebind immediately in case this
|
||||
// was a deliberate disconnection to force a restart. Safe to use
|
||||
// base::Unretained(this) because |this| owns |factory_|.
|
||||
factory_.set_disconnect_handler(
|
||||
base::BindOnce(&CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
RebindURLLoaderFactory,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
std::move(bind_new_url_loader_factory_cb)) {}
|
||||
|
||||
CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
~AsyncCertNetFetcherURLLoader() {
|
||||
@ -611,6 +608,16 @@ CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
DCHECK(jobs_.empty());
|
||||
}
|
||||
|
||||
void CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
DisconnectURLLoaderFactoryForTesting() {
|
||||
// Sadly, there's no good way to disconnect a Mojo remote other than resetting
|
||||
// it, binding it to a new pipe, and dropping the PendingReceiver on the
|
||||
// floor.
|
||||
factory_.reset();
|
||||
ignore_result(factory_.BindNewPipeAndPassReceiver());
|
||||
factory_.FlushForTesting();
|
||||
}
|
||||
|
||||
bool JobComparator::operator()(const Job* job1, const Job* job2) const {
|
||||
return job1->request_params() < job2->request_params();
|
||||
}
|
||||
@ -628,6 +635,10 @@ void CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::Fetch(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!factory_.is_connected()) {
|
||||
RebindURLLoaderFactory();
|
||||
}
|
||||
|
||||
job = new Job(std::move(request_params), this);
|
||||
jobs_[job] = base::WrapUnique(job);
|
||||
// Attach the request before calling |StartURLLoader()|; this ensures that the
|
||||
@ -655,12 +666,12 @@ void CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
// trying to reconnect a URLLoaderFactory.
|
||||
DCHECK(factory_);
|
||||
|
||||
if (!bind_new_url_loader_factory_cb_) {
|
||||
return;
|
||||
}
|
||||
|
||||
factory_.reset();
|
||||
bind_new_url_loader_factory_cb_.Run(factory_.BindNewPipeAndPassReceiver());
|
||||
factory_.set_disconnect_handler(
|
||||
base::BindOnce(&CertNetFetcherURLLoader::AsyncCertNetFetcherURLLoader::
|
||||
RebindURLLoaderFactory,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -726,21 +737,30 @@ class CertNetFetcherRequestImpl : public net::CertNetFetcher::Request {
|
||||
|
||||
} // namespace
|
||||
|
||||
CertNetFetcherURLLoader::CertNetFetcherURLLoader(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> factory,
|
||||
BindNewURLLoaderFactoryCallback bind_new_url_loader_factory_cb)
|
||||
: task_runner_(base::SequencedTaskRunnerHandle::Get()),
|
||||
impl_(std::make_unique<AsyncCertNetFetcherURLLoader>(
|
||||
std::move(factory),
|
||||
std::move(bind_new_url_loader_factory_cb))) {}
|
||||
CertNetFetcherURLLoader::CertNetFetcherURLLoader()
|
||||
: task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
|
||||
|
||||
CertNetFetcherURLLoader::~CertNetFetcherURLLoader() = default;
|
||||
|
||||
void CertNetFetcherURLLoader::SetURLLoaderFactoryAndReconnector(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> factory,
|
||||
base::RepeatingCallback<
|
||||
void(mojo::PendingReceiver<network::mojom::URLLoaderFactory>)>
|
||||
bind_new_url_loader_factory_cb) {
|
||||
DCHECK(!impl_);
|
||||
impl_ = std::make_unique<AsyncCertNetFetcherURLLoader>(
|
||||
std::move(factory), std::move(bind_new_url_loader_factory_cb));
|
||||
}
|
||||
|
||||
// static
|
||||
base::TimeDelta CertNetFetcherURLLoader::GetDefaultTimeoutForTesting() {
|
||||
return GetTimeout(CertNetFetcher::DEFAULT);
|
||||
}
|
||||
|
||||
void CertNetFetcherURLLoader::DisconnectURLLoaderFactoryForTesting() {
|
||||
impl_->DisconnectURLLoaderFactoryForTesting();
|
||||
}
|
||||
|
||||
void CertNetFetcherURLLoader::Shutdown() {
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
if (impl_) {
|
||||
@ -800,9 +820,10 @@ void CertNetFetcherURLLoader::DoFetchOnTaskRunner(
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
|
||||
if (!impl_) {
|
||||
// The fetcher might have been shutdown (which resets |impl_|) between when
|
||||
// this task was posted and when it is running. In this case, signal the
|
||||
// request and do not start a network request.
|
||||
// |SetURLLoaderFactoryAndReconnector| may not have been called yet, or the
|
||||
// fetcher might have been shutdown between when this task was posted and
|
||||
// when it is running. In this case, signal the request and do not start a
|
||||
// network request.
|
||||
request->SignalImmediateError();
|
||||
return;
|
||||
}
|
||||
|
@ -30,10 +30,17 @@ class COMPONENT_EXPORT(CERT_VERIFIER_CPP) CertNetFetcherURLLoader
|
||||
class RequestCore;
|
||||
struct RequestParams;
|
||||
|
||||
// Creates the CertNetFetcherURLLoader, using the provided URLLoaderFactory.
|
||||
// If the other side of the remote disconnects, the CertNetFetcherURLLoader
|
||||
// will attempt that reconnect using |bind_new_url_loader_factory_cb|.
|
||||
explicit CertNetFetcherURLLoader(
|
||||
// The CertNetFetcherURLLoader will immediately fail all requests until
|
||||
// SetURLLoaderFactoryAndReconnector() is called.
|
||||
CertNetFetcherURLLoader();
|
||||
|
||||
// Enables this CertNetFetcher to load URLs using |factory|.
|
||||
// If the other side of the |factory| remote disconnects, the
|
||||
// CertNetFetcherURLLoader will attempt to reconnect using
|
||||
// |bind_new_url_loader_factory_cb|. This must be called before ever
|
||||
// performing a fetch. It is recommended, but not required, to provide a
|
||||
// functional |bind_new_url_loader_factory_cb|.
|
||||
void SetURLLoaderFactoryAndReconnector(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> factory,
|
||||
base::RepeatingCallback<
|
||||
void(mojo::PendingReceiver<network::mojom::URLLoaderFactory>)>
|
||||
@ -42,6 +49,9 @@ class COMPONENT_EXPORT(CERT_VERIFIER_CPP) CertNetFetcherURLLoader
|
||||
// Returns the default timeout value. Intended for test use only.
|
||||
static base::TimeDelta GetDefaultTimeoutForTesting();
|
||||
|
||||
// Disconnects the URLLoaderFactory used for fetches.
|
||||
void DisconnectURLLoaderFactoryForTesting();
|
||||
|
||||
// CertNetFetcher impl:
|
||||
void Shutdown() override;
|
||||
std::unique_ptr<Request> FetchCaIssuers(const GURL& url,
|
||||
|
@ -4,9 +4,12 @@
|
||||
|
||||
#include "services/cert_verifier/cert_verifier_service.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "net/base/completion_once_callback.h"
|
||||
#include "services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
namespace internal {
|
||||
@ -65,12 +68,18 @@ class CertVerifyResultHelper {
|
||||
std::unique_ptr<net::CertVerifier::Request> local_request_;
|
||||
};
|
||||
|
||||
void ReconnectURLLoaderFactory(
|
||||
mojo::Remote<mojom::URLLoaderFactoryConnector>* reconnector,
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
|
||||
(*reconnector)->CreateURLLoaderFactory(std::move(receiver));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CertVerifierServiceImpl::CertVerifierServiceImpl(
|
||||
std::unique_ptr<net::CertVerifier> verifier,
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
scoped_refptr<net::CertNetFetcher> cert_net_fetcher)
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher)
|
||||
: verifier_(std::move(verifier)),
|
||||
receiver_(this, std::move(receiver)),
|
||||
cert_net_fetcher_(std::move(cert_net_fetcher)) {
|
||||
@ -95,6 +104,20 @@ void CertVerifierServiceImpl::SetConfig(
|
||||
verifier_->SetConfig(config);
|
||||
}
|
||||
|
||||
void CertVerifierServiceImpl::EnableNetworkAccess(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector> reconnector) {
|
||||
if (cert_net_fetcher_) {
|
||||
auto reconnect_cb =
|
||||
std::make_unique<mojo::Remote<mojom::URLLoaderFactoryConnector>>(
|
||||
std::move(reconnector));
|
||||
cert_net_fetcher_->SetURLLoaderFactoryAndReconnector(
|
||||
std::move(url_loader_factory),
|
||||
base::BindRepeating(&ReconnectURLLoaderFactory,
|
||||
base::Owned(std::move(reconnect_cb))));
|
||||
}
|
||||
}
|
||||
|
||||
void CertVerifierServiceImpl::Verify(
|
||||
const net::CertVerifier::RequestParams& params,
|
||||
mojo::PendingRemote<mojom::CertVerifierRequest> cert_verifier_request) {
|
||||
@ -115,9 +138,11 @@ void CertVerifierServiceImpl::Verify(
|
||||
base::BindOnce(&CertVerifyResultHelper::CompleteCertVerifierRequest,
|
||||
std::move(result_helper));
|
||||
|
||||
int net_err =
|
||||
verifier_->Verify(params, result.get(), std::move(callback),
|
||||
result_helper_ptr->local_request(), null_net_log_);
|
||||
int net_err = verifier_->Verify(
|
||||
params, result.get(), std::move(callback),
|
||||
result_helper_ptr->local_request(),
|
||||
net::NetLogWithSource::Make(net::NetLog::Get(),
|
||||
net::NetLogSourceType::CERT_VERIFIER_JOB));
|
||||
if (net_err == net::ERR_IO_PENDING) {
|
||||
// If this request is to be completely asynchronously, give the callback
|
||||
// ownership of our mojom::CertVerifierRequest and net::CertVerifyResult.
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
#include "net/cert/cert_net_fetcher.h"
|
||||
#include "net/log/net_log_with_source.h"
|
||||
#include "services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
|
||||
// Defines an implementation of a Cert Verifier Service to be queried by network
|
||||
// service or others.
|
||||
@ -26,13 +28,17 @@ class CertVerifierServiceImpl : public mojom::CertVerifierService {
|
||||
explicit CertVerifierServiceImpl(
|
||||
std::unique_ptr<net::CertVerifier> verifier,
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
scoped_refptr<net::CertNetFetcher> cert_net_fetcher);
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher);
|
||||
|
||||
// mojom::CertVerifierService implementation:
|
||||
void Verify(const net::CertVerifier::RequestParams& params,
|
||||
mojo::PendingRemote<mojom::CertVerifierRequest>
|
||||
cert_verifier_request) override;
|
||||
void SetConfig(const net::CertVerifier::Config& config) override;
|
||||
void EnableNetworkAccess(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector> reconnector)
|
||||
override;
|
||||
|
||||
private:
|
||||
~CertVerifierServiceImpl() override;
|
||||
@ -41,11 +47,7 @@ class CertVerifierServiceImpl : public mojom::CertVerifierService {
|
||||
|
||||
std::unique_ptr<net::CertVerifier> verifier_;
|
||||
mojo::Receiver<mojom::CertVerifierService> receiver_;
|
||||
scoped_refptr<net::CertNetFetcher> cert_net_fetcher_;
|
||||
|
||||
// A null NetLog for |verifier_->Verify()|. Initialized with a non-capturing
|
||||
// NetLog.
|
||||
const net::NetLogWithSource null_net_log_;
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -20,58 +20,19 @@
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
|
||||
namespace {
|
||||
void ReconnectCertNetFetcher(
|
||||
mojo::Remote<mojom::URLLoaderFactoryConnector>* connector,
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>
|
||||
url_loader_factory) {
|
||||
(*connector)->CreateURLLoaderFactory(std::move(url_loader_factory));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
CertVerifierServiceFactoryImpl::CertVerifierServiceFactoryImpl(
|
||||
mojo::PendingReceiver<mojom::CertVerifierServiceFactory> receiver)
|
||||
: receiver_(this, std::move(receiver)) {}
|
||||
|
||||
CertVerifierServiceFactoryImpl::~CertVerifierServiceFactoryImpl() = default;
|
||||
|
||||
// static
|
||||
scoped_refptr<CertNetFetcherURLLoader>
|
||||
CertVerifierServiceFactoryImpl::CreateCertNetFetcher(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector) {
|
||||
auto connector =
|
||||
std::make_unique<mojo::Remote<mojom::URLLoaderFactoryConnector>>(
|
||||
std::move(cert_net_fetcher_url_loader_factory_connector));
|
||||
// The callback will own the CertNetFetcherReconnector, and the callback
|
||||
// will be owned by the CertNetFetcherURLLoader. Only the
|
||||
// CertNetFetcherURLLoader uses the CertNetFetcherReconnector.
|
||||
auto reconnector_cb = base::BindRepeating(&ReconnectCertNetFetcher,
|
||||
base::Owned(std::move(connector)));
|
||||
return base::MakeRefCounted<CertNetFetcherURLLoader>(
|
||||
std::move(url_loader_factory), std::move(reconnector_cb));
|
||||
}
|
||||
|
||||
void CertVerifierServiceFactoryImpl::GetNewCertVerifier(
|
||||
void GetNewCertVerifierImpl(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) {
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params,
|
||||
scoped_refptr<CertNetFetcherURLLoader>* cert_net_fetcher_ptr) {
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher;
|
||||
|
||||
// Sometimes the cert_net_fetcher isn't used by CreateCertVerifier.
|
||||
// But losing the last ref without calling Shutdown() will cause a CHECK
|
||||
// failure, so keep a ref.
|
||||
if (network::IsUsingCertNetFetcher()) {
|
||||
DCHECK(url_loader_factory.is_valid());
|
||||
DCHECK(cert_net_fetcher_url_loader_factory_connector.is_valid());
|
||||
cert_net_fetcher = CreateCertNetFetcher(
|
||||
std::move(url_loader_factory),
|
||||
std::move(cert_net_fetcher_url_loader_factory_connector));
|
||||
}
|
||||
if (network::IsUsingCertNetFetcher())
|
||||
cert_net_fetcher = base::MakeRefCounted<CertNetFetcherURLLoader>();
|
||||
|
||||
// Create a new CertVerifier to back our service. This will be instantiated
|
||||
// without the coalescing or caching layers, because those layers will work
|
||||
@ -87,10 +48,36 @@ void CertVerifierServiceFactoryImpl::GetNewCertVerifier(
|
||||
cert_net_fetcher.reset();
|
||||
}
|
||||
|
||||
if (cert_net_fetcher_ptr)
|
||||
*cert_net_fetcher_ptr = cert_net_fetcher;
|
||||
|
||||
// The service will delete itself upon disconnection.
|
||||
new internal::CertVerifierServiceImpl(std::move(cert_verifier),
|
||||
std::move(receiver),
|
||||
std::move(cert_net_fetcher));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CertVerifierServiceFactoryImpl::CertVerifierServiceFactoryImpl(
|
||||
mojo::PendingReceiver<mojom::CertVerifierServiceFactory> receiver)
|
||||
: receiver_(this, std::move(receiver)) {}
|
||||
|
||||
CertVerifierServiceFactoryImpl::~CertVerifierServiceFactoryImpl() = default;
|
||||
|
||||
void CertVerifierServiceFactoryImpl::GetNewCertVerifier(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) {
|
||||
GetNewCertVerifierImpl(std::move(receiver), std::move(creation_params),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CertVerifierServiceFactoryImpl::GetNewCertVerifierForTesting(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params,
|
||||
scoped_refptr<CertNetFetcherURLLoader>* cert_net_fetcher_ptr) {
|
||||
GetNewCertVerifierImpl(std::move(receiver), std::move(creation_params),
|
||||
cert_net_fetcher_ptr);
|
||||
}
|
||||
|
||||
} // namespace cert_verifier
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
@ -28,23 +29,19 @@ class CertVerifierServiceFactoryImpl
|
||||
mojo::PendingReceiver<mojom::CertVerifierServiceFactory> receiver);
|
||||
~CertVerifierServiceFactoryImpl() override;
|
||||
|
||||
// Creates a CertNetFetcherURLLoader using the given URLLoaderFactory, that
|
||||
// will try to reconnect its URLLoaderFactory using the
|
||||
// URLLoaderFactoryConnector in case the original URLLoaderFactory
|
||||
// disconnects.
|
||||
static scoped_refptr<CertNetFetcherURLLoader> CreateCertNetFetcher(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector);
|
||||
|
||||
// mojom::CertVerifierServiceFactory implementation:
|
||||
void GetNewCertVerifier(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) override;
|
||||
|
||||
// Performs the same function as above, but stores a ref to the new
|
||||
// CertNetFetcherURLLoader in |*cert_net_fetcher_ptr|, if the
|
||||
// CertNetFetcherURLLoader is in use.
|
||||
void GetNewCertVerifierForTesting(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params,
|
||||
scoped_refptr<CertNetFetcherURLLoader>* cert_net_fetcher_ptr);
|
||||
|
||||
private:
|
||||
mojo::Receiver<mojom::CertVerifierServiceFactory> receiver_;
|
||||
};
|
||||
|
@ -13,113 +13,25 @@
|
||||
#include "base/check_op.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/task/task_traits.h"
|
||||
#include "base/test/bind_test_util.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/cert/cert_net_fetcher.h"
|
||||
#include "net/cert/cert_status_flags.h"
|
||||
#include "net/cert/cert_verifier.h"
|
||||
#include "net/test/cert_test_util.h"
|
||||
#include "net/test/test_data_directory.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/test/test_url_loader_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "testing/platform_test.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
namespace {
|
||||
|
||||
const char kMockURL[] = "http://mock.invalid/";
|
||||
|
||||
class TestReconnector : public mojom::URLLoaderFactoryConnector {
|
||||
public:
|
||||
explicit TestReconnector(
|
||||
network::TestURLLoaderFactory* test_url_loader_factory)
|
||||
: test_url_loader_factory_(test_url_loader_factory) {}
|
||||
void CreateURLLoaderFactory(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>
|
||||
url_loader_factory_receiver) override {
|
||||
num_connects_++;
|
||||
receiver_set_.Add(test_url_loader_factory_,
|
||||
std::move(url_loader_factory_receiver));
|
||||
}
|
||||
|
||||
void DisconnectAll() { receiver_set_.Clear(); }
|
||||
|
||||
size_t num_connects() const { return num_connects_; }
|
||||
|
||||
private:
|
||||
network::TestURLLoaderFactory* test_url_loader_factory_;
|
||||
mojo::ReceiverSet<network::mojom::URLLoaderFactory> receiver_set_;
|
||||
|
||||
size_t num_connects_ = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<net::CertNetFetcher::Request>
|
||||
PerformCertNetFetcherRequestOnTaskRunner(
|
||||
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher) {
|
||||
std::unique_ptr<net::CertNetFetcher::Request> request;
|
||||
base::RunLoop run_loop;
|
||||
runner->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() {
|
||||
request = cert_net_fetcher->FetchCaIssuers(
|
||||
GURL(kMockURL), net::CertNetFetcher::DEFAULT,
|
||||
net::CertNetFetcher::DEFAULT);
|
||||
run_loop.QuitWhenIdle();
|
||||
}));
|
||||
run_loop.Run();
|
||||
return request;
|
||||
}
|
||||
|
||||
class CertVerifierServiceFactoryTest : public PlatformTest {
|
||||
public:
|
||||
CertVerifierServiceFactoryTest()
|
||||
: test_reconnector_(&test_url_loader_factory_),
|
||||
test_reconnector_receiver_(&test_reconnector_) {
|
||||
test_reconnector_.CreateURLLoaderFactory(
|
||||
test_url_loader_factory_remote_.InitWithNewPipeAndPassReceiver());
|
||||
EXPECT_EQ(test_reconnector_.num_connects(), 1ul);
|
||||
}
|
||||
|
||||
TestReconnector* test_reconnector() { return &test_reconnector_; }
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
||||
TakeURLLoaderFactoryPendingRemote() {
|
||||
return std::move(test_url_loader_factory_remote_);
|
||||
}
|
||||
mojo::Receiver<mojom::URLLoaderFactoryConnector>&
|
||||
test_reconnector_receiver() {
|
||||
return test_reconnector_receiver_;
|
||||
}
|
||||
network::TestURLLoaderFactory* test_url_loader_factory() {
|
||||
return &test_url_loader_factory_;
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
|
||||
// Instantiate a TestURLLoaderFactory which we can use to respond and unpause
|
||||
// network requests.
|
||||
network::TestURLLoaderFactory test_url_loader_factory_;
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
||||
test_url_loader_factory_remote_;
|
||||
|
||||
// Instantiate a dummy URLLoaderFactoryConnector that can disconnect at will
|
||||
// and will automatically reconnect to the |test_url_loader_factory| above.
|
||||
TestReconnector test_reconnector_;
|
||||
mojo::Receiver<mojom::URLLoaderFactoryConnector> test_reconnector_receiver_;
|
||||
};
|
||||
|
||||
struct DummyCVServiceRequest : public mojom::CertVerifierRequest {
|
||||
explicit DummyCVServiceRequest(base::RepeatingClosure on_finish)
|
||||
: on_finish_(std::move(on_finish)) {}
|
||||
@ -138,83 +50,9 @@ struct DummyCVServiceRequest : public mojom::CertVerifierRequest {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Test that the CertNetFetcherURLLoader handed to the CertVerifierService
|
||||
// successfully tries to reconnect after URLLoaderFactory disconnection.
|
||||
TEST_F(CertVerifierServiceFactoryTest,
|
||||
CertNetFetcherReconnectAfterURLLoaderFactoryReset) {
|
||||
scoped_refptr<base::SequencedTaskRunner> caller_task_runner =
|
||||
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
|
||||
TEST(CertVerifierServiceFactoryTest, GetNewCertVerifier) {
|
||||
base::test::TaskEnvironment task_environment;
|
||||
|
||||
// Pass mojo::Remote's for |test_url_loader_factory| and
|
||||
// |test_reconnector| to the CertNetFetcherURLLoader
|
||||
// created by the CertVerifierServiceFactoryImpl.
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher =
|
||||
CertVerifierServiceFactoryImpl::CreateCertNetFetcher(
|
||||
TakeURLLoaderFactoryPendingRemote(),
|
||||
test_reconnector_receiver().BindNewPipeAndPassRemote());
|
||||
|
||||
// Now run the test.
|
||||
auto request1 = PerformCertNetFetcherRequestOnTaskRunner(caller_task_runner,
|
||||
cert_net_fetcher);
|
||||
EXPECT_EQ(test_url_loader_factory()->NumPending(), 1);
|
||||
EXPECT_TRUE(test_url_loader_factory()->IsPending(kMockURL));
|
||||
|
||||
EXPECT_TRUE(test_url_loader_factory()->SimulateResponseForPendingRequest(
|
||||
kMockURL, "", net::HTTP_NOT_FOUND));
|
||||
EXPECT_EQ(test_url_loader_factory()->NumPending(), 0);
|
||||
|
||||
// Disconnect the test_url_loader_factory to test reconnection.
|
||||
test_reconnector()->DisconnectAll();
|
||||
|
||||
// Now run the test.
|
||||
auto request2 = PerformCertNetFetcherRequestOnTaskRunner(caller_task_runner,
|
||||
cert_net_fetcher);
|
||||
|
||||
EXPECT_EQ(test_url_loader_factory()->NumPending(), 1);
|
||||
EXPECT_TRUE(test_url_loader_factory()->IsPending(kMockURL));
|
||||
|
||||
EXPECT_TRUE(test_url_loader_factory()->SimulateResponseForPendingRequest(
|
||||
kMockURL, "", net::HTTP_NOT_FOUND));
|
||||
EXPECT_EQ(test_reconnector()->num_connects(), 2ul);
|
||||
|
||||
// Disconnect the test_url_loader_factory to test reconnection one more time.
|
||||
test_reconnector()->DisconnectAll();
|
||||
|
||||
// Now run the test.
|
||||
auto request3 = PerformCertNetFetcherRequestOnTaskRunner(caller_task_runner,
|
||||
cert_net_fetcher);
|
||||
|
||||
EXPECT_EQ(test_url_loader_factory()->NumPending(), 1);
|
||||
EXPECT_TRUE(test_url_loader_factory()->IsPending(kMockURL));
|
||||
|
||||
EXPECT_EQ(test_reconnector()->num_connects(), 3ul);
|
||||
|
||||
// The test simulated responses for at least the first two requests, so they
|
||||
// should complete without hanging. The response content is not important, but
|
||||
// the test sent error responses, so check that net::OK wasn't returned.
|
||||
// The third request may have attached to a previous job, but cancelling it
|
||||
// should not cause problems.
|
||||
{
|
||||
net::Error error1, error2;
|
||||
std::vector<uint8_t> bytes1, bytes2;
|
||||
base::RunLoop run_loop;
|
||||
caller_task_runner->PostTask(
|
||||
FROM_HERE, base::BindLambdaForTesting([&]() {
|
||||
base::ScopedAllowBaseSyncPrimitivesForTesting allow_base_sync;
|
||||
request1->WaitForResult(&error1, &bytes1);
|
||||
request2->WaitForResult(&error2, &bytes2);
|
||||
request3.reset();
|
||||
run_loop.Quit();
|
||||
}));
|
||||
run_loop.Run();
|
||||
EXPECT_NE(error1, net::OK);
|
||||
EXPECT_NE(error2, net::OK);
|
||||
}
|
||||
|
||||
cert_net_fetcher->Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CertVerifierServiceFactoryTest, GetNewCertVerifier) {
|
||||
base::FilePath certs_dir = net::GetTestCertsDirectory();
|
||||
scoped_refptr<net::X509Certificate> test_cert(
|
||||
net::ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
||||
@ -230,8 +68,6 @@ TEST_F(CertVerifierServiceFactoryTest, GetNewCertVerifier) {
|
||||
|
||||
cv_service_factory_remote->GetNewCertVerifier(
|
||||
cv_service_remote.BindNewPipeAndPassReceiver(),
|
||||
TakeURLLoaderFactoryPendingRemote(),
|
||||
test_reconnector_receiver().BindNewPipeAndPassRemote(),
|
||||
std::move(cv_creation_params));
|
||||
|
||||
base::RunLoop request_completed_run_loop;
|
||||
|
3
services/cert_verifier/integration_tests/DEPS
Normal file
3
services/cert_verifier/integration_tests/DEPS
Normal file
@ -0,0 +1,3 @@
|
||||
include_rules = [
|
||||
"+services/network"
|
||||
]
|
@ -0,0 +1,299 @@
|
||||
// Copyright 2020 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 <memory>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "net/base/features.h"
|
||||
#include "net/test/embedded_test_server/default_handlers.h"
|
||||
#include "net/test/embedded_test_server/embedded_test_server.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
|
||||
#include "services/cert_verifier/cert_verifier_service_factory.h"
|
||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
namespace {
|
||||
|
||||
mojo::PendingRemote<mojom::CertVerifierService> GetNewCertVerifierServiceRemote(
|
||||
mojom::CertVerifierServiceFactory* cert_verifier_service_factory,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) {
|
||||
mojo::PendingRemote<mojom::CertVerifierService> cert_verifier_remote;
|
||||
cert_verifier_service_factory->GetNewCertVerifier(
|
||||
cert_verifier_remote.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(creation_params));
|
||||
return cert_verifier_remote;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class NetworkContextTest : public testing::Test {
|
||||
public:
|
||||
explicit NetworkContextTest(
|
||||
base::test::TaskEnvironment::TimeSource time_source =
|
||||
base::test::TaskEnvironment::TimeSource::DEFAULT)
|
||||
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
|
||||
time_source),
|
||||
network_change_notifier_(
|
||||
net::NetworkChangeNotifier::CreateMockIfNeeded()),
|
||||
network_service_(network::NetworkService::CreateForTesting()) {}
|
||||
~NetworkContextTest() override = default;
|
||||
|
||||
std::unique_ptr<network::NetworkContext> CreateContextWithParams(
|
||||
network::mojom::NetworkContextParamsPtr context_params) {
|
||||
network_context_remote_.reset();
|
||||
return std::make_unique<network::NetworkContext>(
|
||||
network_service_.get(),
|
||||
network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
}
|
||||
|
||||
network::mojom::CertVerifierParamsPtr GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParamsPtr
|
||||
cert_verifier_creation_params =
|
||||
network::mojom::CertVerifierCreationParams::New()) {
|
||||
if (!base::FeatureList::IsEnabled(
|
||||
network::features::kCertVerifierService)) {
|
||||
return network::mojom::CertVerifierParams::NewCreationParams(
|
||||
std::move(cert_verifier_creation_params));
|
||||
}
|
||||
|
||||
if (!cert_verifier_service_factory_) {
|
||||
cert_verifier_service_factory_ =
|
||||
std::make_unique<CertVerifierServiceFactoryImpl>(
|
||||
cert_verifier_service_factory_remote_
|
||||
.BindNewPipeAndPassReceiver());
|
||||
}
|
||||
|
||||
auto cv_service_remote_params =
|
||||
network::mojom::CertVerifierServiceRemoteParams::New();
|
||||
|
||||
// Create a cert verifier service.
|
||||
cv_service_remote_params->cert_verifier_service =
|
||||
GetNewCertVerifierServiceRemote(
|
||||
cert_verifier_service_factory_.get(),
|
||||
std::move(cert_verifier_creation_params));
|
||||
|
||||
return network::mojom::CertVerifierParams::NewRemoteParams(
|
||||
std::move(cv_service_remote_params));
|
||||
}
|
||||
|
||||
network::mojom::NetworkService* network_service() const {
|
||||
return network_service_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
|
||||
std::unique_ptr<network::NetworkService> network_service_;
|
||||
// Stores the mojo::Remote<NetworkContext> of the most recently created
|
||||
// NetworkContext. Not strictly needed, but seems best to mimic real-world
|
||||
// usage.
|
||||
mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
|
||||
|
||||
mojo::Remote<mojom::CertVerifierServiceFactory>
|
||||
cert_verifier_service_factory_remote_;
|
||||
std::unique_ptr<mojom::CertVerifierServiceFactory>
|
||||
cert_verifier_service_factory_;
|
||||
};
|
||||
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
namespace {
|
||||
|
||||
network::mojom::NetworkContextParamsPtr CreateContextParams() {
|
||||
network::mojom::NetworkContextParamsPtr params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config = net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
return params;
|
||||
}
|
||||
|
||||
std::unique_ptr<network::TestURLLoaderClient> FetchRequest(
|
||||
const network::ResourceRequest& request,
|
||||
network::NetworkContext* network_context,
|
||||
int url_loader_options = network::mojom::kURLLoadOptionNone,
|
||||
int process_id = network::mojom::kBrowserProcessId,
|
||||
network::mojom::URLLoaderFactoryParamsPtr params = nullptr) {
|
||||
mojo::Remote<network::mojom::URLLoaderFactory> loader_factory;
|
||||
if (!params)
|
||||
params = network::mojom::URLLoaderFactoryParams::New();
|
||||
params->process_id = process_id;
|
||||
params->is_corb_enabled = false;
|
||||
|
||||
// If |site_for_cookies| is null, any non-empty NIK is fine. Otherwise, the
|
||||
// NIK must be consistent with |site_for_cookies|.
|
||||
if (request.site_for_cookies.IsNull()) {
|
||||
params->isolation_info = net::IsolationInfo::Create(
|
||||
net::IsolationInfo::RedirectMode::kUpdateNothing,
|
||||
url::Origin::Create(GURL("https://abc.invalid")),
|
||||
url::Origin::Create(GURL("https://xyz.invalid")),
|
||||
request.site_for_cookies);
|
||||
} else {
|
||||
params->isolation_info = net::IsolationInfo::CreateForInternalRequest(
|
||||
url::Origin::Create(request.site_for_cookies.RepresentativeUrl()));
|
||||
}
|
||||
|
||||
network_context->CreateURLLoaderFactory(
|
||||
loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
|
||||
|
||||
auto client = std::make_unique<network::TestURLLoaderClient>();
|
||||
mojo::PendingRemote<network::mojom::URLLoader> loader;
|
||||
loader_factory->CreateLoaderAndStart(
|
||||
loader.InitWithNewPipeAndPassReceiver(), 0 /* routing_id */,
|
||||
0 /* request_id */, url_loader_options, request, client->CreateRemote(),
|
||||
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
|
||||
|
||||
client->RunUntilComplete();
|
||||
return client;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class UseCertVerifierBuiltinTest : public NetworkContextTest,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
UseCertVerifierBuiltinTest() = default;
|
||||
~UseCertVerifierBuiltinTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
if (GetParam()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
scoped_feature_list_.InitAndEnableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
#endif
|
||||
} else {
|
||||
scoped_feature_list_.InitAndDisableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
}
|
||||
NetworkContextTest::SetUp();
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
TEST_P(UseCertVerifierBuiltinTest, UseCertVerifierBuiltin) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
net::test_server::RegisterDefaultHandlers(&test_server);
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// This just happens to be the only histogram that directly records which
|
||||
// verifier was used.
|
||||
const char kBuiltinVerifierHistogram[] =
|
||||
"Net.CertVerifier.NameNormalizationPrivateRoots.Builtin";
|
||||
|
||||
for (bool builtin_verifier_enabled : {false, true}) {
|
||||
SCOPED_TRACE(builtin_verifier_enabled);
|
||||
|
||||
network::mojom::NetworkContextParamsPtr params = CreateContextParams();
|
||||
auto creation_params = network::mojom::CertVerifierCreationParams::New();
|
||||
creation_params->use_builtin_cert_verifier =
|
||||
builtin_verifier_enabled ? network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kBuiltin
|
||||
: network::mojom::CertVerifierCreationParams::
|
||||
CertVerifierImpl::kSystem;
|
||||
params->cert_verifier_params =
|
||||
GetCertVerifierParams(std::move(creation_params));
|
||||
std::unique_ptr<network::NetworkContext> network_context =
|
||||
CreateContextWithParams(std::move(params));
|
||||
|
||||
network::ResourceRequest request;
|
||||
request.url = test_server.GetURL("/nocontent");
|
||||
base::HistogramTester histogram_tester;
|
||||
std::unique_ptr<network::TestURLLoaderClient> client =
|
||||
FetchRequest(request, network_context.get());
|
||||
EXPECT_EQ(net::OK, client->completion_status().error_code);
|
||||
histogram_tester.ExpectTotalCount(kBuiltinVerifierHistogram,
|
||||
builtin_verifier_enabled ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All, UseCertVerifierBuiltinTest, ::testing::Bool());
|
||||
|
||||
class NetworkContextCertVerifierBuiltinFeatureFlagTest
|
||||
: public NetworkContextTest,
|
||||
public testing::WithParamInterface<std::tuple<bool, bool>> {
|
||||
public:
|
||||
NetworkContextCertVerifierBuiltinFeatureFlagTest()
|
||||
: use_builtin_cert_verifier_feature_(std::get<0>(GetParam())),
|
||||
use_cert_verifier_service_feature_(std::get<1>(GetParam())) {
|
||||
std::vector<base::Feature> enabled_features, disabled_features;
|
||||
if (use_builtin_cert_verifier_feature_) {
|
||||
enabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
} else {
|
||||
disabled_features.push_back(net::features::kCertVerifierBuiltinFeature);
|
||||
}
|
||||
if (use_cert_verifier_service_feature_) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
enabled_features.push_back(network::features::kCertVerifierService);
|
||||
#endif
|
||||
} else {
|
||||
disabled_features.push_back(network::features::kCertVerifierService);
|
||||
}
|
||||
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
|
||||
}
|
||||
|
||||
bool use_builtin_cert_verifier_feature() const {
|
||||
return use_builtin_cert_verifier_feature_;
|
||||
}
|
||||
|
||||
private:
|
||||
const bool use_builtin_cert_verifier_feature_;
|
||||
const bool use_cert_verifier_service_feature_;
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
TEST_P(NetworkContextCertVerifierBuiltinFeatureFlagTest,
|
||||
DefaultNetworkContextParamsUsesCorrectVerifier) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
net::test_server::RegisterDefaultHandlers(&test_server);
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// This just happens to be the only histogram that directly records which
|
||||
// verifier was used.
|
||||
const char kBuiltinVerifierHistogram[] =
|
||||
"Net.CertVerifier.NameNormalizationPrivateRoots.Builtin";
|
||||
|
||||
// Test creating a NetworkContextParams without specifying a value for
|
||||
// use_builtin_cert_verifier. Should use whatever the default cert verifier
|
||||
// implementation is according to the feature flag.
|
||||
network::mojom::NetworkContextParamsPtr params = CreateContextParams();
|
||||
params->cert_verifier_params = GetCertVerifierParams();
|
||||
std::unique_ptr<network::NetworkContext> network_context =
|
||||
CreateContextWithParams(std::move(params));
|
||||
|
||||
network::ResourceRequest request;
|
||||
request.url = test_server.GetURL("/nocontent");
|
||||
base::HistogramTester histogram_tester;
|
||||
std::unique_ptr<network::TestURLLoaderClient> client =
|
||||
FetchRequest(request, network_context.get());
|
||||
EXPECT_EQ(net::OK, client->completion_status().error_code);
|
||||
histogram_tester.ExpectTotalCount(
|
||||
kBuiltinVerifierHistogram, use_builtin_cert_verifier_feature() ? 1 : 0);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All,
|
||||
NetworkContextCertVerifierBuiltinFeatureFlagTest,
|
||||
::testing::Combine(::testing::Bool(),
|
||||
::testing::Bool()));
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
} // namespace cert_verifier
|
@ -0,0 +1,485 @@
|
||||
// Copyright 2020 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 <memory>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "base/task/task_traits.h"
|
||||
#include "base/test/bind_test_util.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/test_completion_callback.h"
|
||||
#include "net/cert/asn1_util.h"
|
||||
#include "net/cert/test_root_certs.h"
|
||||
#include "net/cert/x509_util.h"
|
||||
#include "net/test/cert_test_util.h"
|
||||
#include "net/test/embedded_test_server/embedded_test_server.h"
|
||||
#include "net/test/gtest_util.h"
|
||||
#include "net/test/test_data_directory.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h"
|
||||
#include "services/cert_verifier/cert_verifier_service_factory.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/cert_verifier/mojo_cert_verifier.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/ssl_config_service_mojo.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
namespace {
|
||||
const base::FilePath::CharType kServicesTestData[] =
|
||||
FILE_PATH_LITERAL("services/test/data");
|
||||
} // namespace
|
||||
|
||||
// Base class for any tests that just need a NetworkService and a
|
||||
// TaskEnvironment, and to create NetworkContexts using the NetworkService.
|
||||
// Parametrized on whether or not the CertVerifierService feature is enabled.
|
||||
class NetworkServiceIntegrationTest : public testing::TestWithParam<bool> {
|
||||
public:
|
||||
NetworkServiceIntegrationTest()
|
||||
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
|
||||
service_(network::NetworkService::CreateForTesting()),
|
||||
cert_verifier_service_impl_(
|
||||
cert_verifier_service_remote_.BindNewPipeAndPassReceiver()) {}
|
||||
~NetworkServiceIntegrationTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
if (GetParam()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
scoped_feature_list_.InitAndEnableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
#endif
|
||||
} else {
|
||||
scoped_feature_list_.InitAndDisableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyService() { service_.reset(); }
|
||||
|
||||
network::mojom::NetworkContextParamsPtr CreateNetworkContextParams() {
|
||||
network::mojom::CertVerifierCreationParamsPtr
|
||||
cert_verifier_creation_params =
|
||||
network::mojom::CertVerifierCreationParams::New();
|
||||
network::mojom::CertVerifierParamsPtr cert_verifier_params;
|
||||
if (base::FeatureList::IsEnabled(network::features::kCertVerifierService)) {
|
||||
mojo::PendingRemote<mojom::CertVerifierService> cv_service_remote;
|
||||
|
||||
auto cv_service_remote_params =
|
||||
network::mojom::CertVerifierServiceRemoteParams::New();
|
||||
|
||||
// Create a cert verifier service.
|
||||
cert_verifier_service_impl_.GetNewCertVerifierForTesting(
|
||||
cv_service_remote.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(cert_verifier_creation_params),
|
||||
&cert_net_fetcher_url_loader_);
|
||||
|
||||
cv_service_remote_params->cert_verifier_service =
|
||||
std::move(cv_service_remote);
|
||||
|
||||
cert_verifier_params =
|
||||
network::mojom::CertVerifierParams::NewRemoteParams(
|
||||
std::move(cv_service_remote_params));
|
||||
} else {
|
||||
cert_verifier_params =
|
||||
network::mojom::CertVerifierParams::NewCreationParams(
|
||||
std::move(cert_verifier_creation_params));
|
||||
}
|
||||
|
||||
network::mojom::NetworkContextParamsPtr params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
params->cert_verifier_params = std::move(cert_verifier_params);
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config =
|
||||
net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
return params;
|
||||
}
|
||||
|
||||
void CreateNetworkContext(network::mojom::NetworkContextParamsPtr params) {
|
||||
network_context_ = std::make_unique<network::NetworkContext>(
|
||||
service_.get(), network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
std::move(params));
|
||||
}
|
||||
|
||||
void LoadURL(const GURL& url,
|
||||
int options = network::mojom::kURLLoadOptionNone) {
|
||||
network::ResourceRequest request;
|
||||
request.url = url;
|
||||
request.method = "GET";
|
||||
request.request_initiator = url::Origin();
|
||||
StartLoadingURL(request, 0 /* process_id */, options);
|
||||
client_->RunUntilComplete();
|
||||
}
|
||||
|
||||
void StartLoadingURL(const network::ResourceRequest& request,
|
||||
uint32_t process_id,
|
||||
int options = network::mojom::kURLLoadOptionNone) {
|
||||
client_ = std::make_unique<network::TestURLLoaderClient>();
|
||||
mojo::Remote<network::mojom::URLLoaderFactory> loader_factory;
|
||||
network::mojom::URLLoaderFactoryParamsPtr params =
|
||||
network::mojom::URLLoaderFactoryParams::New();
|
||||
params->process_id = process_id;
|
||||
params->is_corb_enabled = false;
|
||||
network_context_->CreateURLLoaderFactory(
|
||||
loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
|
||||
|
||||
loader_.reset();
|
||||
loader_factory->CreateLoaderAndStart(
|
||||
loader_.BindNewPipeAndPassReceiver(), 1, 1, options, request,
|
||||
client_->CreateRemote(),
|
||||
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
|
||||
}
|
||||
|
||||
network::TestURLLoaderClient* client() { return client_.get(); }
|
||||
|
||||
base::test::TaskEnvironment* task_environment() { return &task_environment_; }
|
||||
|
||||
network::NetworkService* service() const { return service_.get(); }
|
||||
|
||||
network::NetworkContext* network_context() { return network_context_.get(); }
|
||||
|
||||
mojo::Remote<network::mojom::NetworkContext>& network_context_remote() {
|
||||
return network_context_remote_;
|
||||
}
|
||||
|
||||
CertNetFetcherURLLoader* cert_net_fetcher_url_loader() {
|
||||
return cert_net_fetcher_url_loader_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
std::unique_ptr<network::NetworkService> service_;
|
||||
|
||||
mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
|
||||
std::unique_ptr<network::NetworkContext> network_context_;
|
||||
|
||||
mojo::Remote<mojom::CertVerifierServiceFactory> cert_verifier_service_remote_;
|
||||
CertVerifierServiceFactoryImpl cert_verifier_service_impl_;
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher_url_loader_;
|
||||
|
||||
std::unique_ptr<network::TestURLLoaderClient> client_;
|
||||
mojo::Remote<network::mojom::URLLoader> loader_;
|
||||
};
|
||||
|
||||
// CRLSets are not supported on iOS and Android system verifiers.
|
||||
#if !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
class NetworkServiceCRLSetTest : public NetworkServiceIntegrationTest {
|
||||
public:
|
||||
NetworkServiceCRLSetTest()
|
||||
: test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
|
||||
~NetworkServiceCRLSetTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
NetworkServiceIntegrationTest::SetUp();
|
||||
test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
|
||||
test_server_.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server_.Start());
|
||||
}
|
||||
|
||||
GURL GetURL(std::string url) { return test_server_.GetURL(std::move(url)); }
|
||||
|
||||
private:
|
||||
net::EmbeddedTestServer test_server_;
|
||||
};
|
||||
|
||||
// Verifies CRLSets take effect if configured on the service.
|
||||
TEST_P(NetworkServiceCRLSetTest, CRLSetIsApplied) {
|
||||
CreateNetworkContext(CreateNetworkContextParams());
|
||||
|
||||
uint32_t options =
|
||||
network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the test server loads fine with no CRLSet.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
ASSERT_EQ(net::OK, client()->completion_status().error_code);
|
||||
|
||||
// Send a CRLSet that blocks the leaf cert.
|
||||
std::string crl_set_bytes;
|
||||
EXPECT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
network_context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies CRLSets configured before creating a new network context are
|
||||
// applied to that network context.
|
||||
TEST_P(NetworkServiceCRLSetTest, CRLSetIsPassedToNewContexts) {
|
||||
// Send a CRLSet that blocks the leaf cert, even while no NetworkContexts
|
||||
// exist.
|
||||
std::string crl_set_bytes;
|
||||
EXPECT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
|
||||
// Configure a new NetworkContext.
|
||||
CreateNetworkContext(CreateNetworkContextParams());
|
||||
|
||||
uint32_t options =
|
||||
network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies newer CRLSets (by sequence number) are applied.
|
||||
TEST_P(NetworkServiceCRLSetTest, CRLSetIsUpdatedIfNewer) {
|
||||
// Send a CRLSet that only allows the root cert if it matches a known SPKI
|
||||
// hash (that matches the test server chain)
|
||||
std::string crl_set_bytes;
|
||||
ASSERT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
CreateNetworkContext(CreateNetworkContextParams());
|
||||
|
||||
uint32_t options =
|
||||
network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection loads, due to the root being permitted.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
ASSERT_EQ(net::OK, client()->completion_status().error_code);
|
||||
|
||||
// Send a new CRLSet that removes trust in the root.
|
||||
ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
|
||||
"crlset_by_root_subject_no_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
network_context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies that attempting to send an older CRLSet (by sequence number)
|
||||
// does not apply to existing or new contexts.
|
||||
TEST_P(NetworkServiceCRLSetTest, CRLSetDoesNotDowngrade) {
|
||||
// Send a CRLSet that blocks the root certificate by subject name.
|
||||
std::string crl_set_bytes;
|
||||
ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
|
||||
"crlset_by_root_subject_no_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
CreateNetworkContext(CreateNetworkContextParams());
|
||||
|
||||
uint32_t options =
|
||||
network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
|
||||
// Attempt to configure an older CRLSet that allowed trust in the root.
|
||||
ASSERT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
network_context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection still fails, due to the newer CRLSet still
|
||||
// applying.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
|
||||
// Create a new NetworkContext and ensure the latest CRLSet is still
|
||||
// applied.
|
||||
network_context_remote().reset();
|
||||
CreateNetworkContext(CreateNetworkContextParams());
|
||||
|
||||
// The newer CRLSet that blocks the connection should still apply, even to
|
||||
// new NetworkContexts.
|
||||
LoadURL(GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All, NetworkServiceCRLSetTest, ::testing::Bool());
|
||||
#endif // !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
// TODO(crbug.com/860189): AIA tests fail on iOS
|
||||
#if defined(OS_IOS)
|
||||
#define MAYBE(test_name) DISABLED_##test_name
|
||||
#else
|
||||
#define MAYBE(test_name) test_name
|
||||
#endif
|
||||
|
||||
class NetworkServiceAIATest : public NetworkServiceIntegrationTest {
|
||||
public:
|
||||
NetworkServiceAIATest() : test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
|
||||
~NetworkServiceAIATest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
NetworkServiceIntegrationTest::SetUp();
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
CreateNetworkContextParams();
|
||||
CreateNetworkContext(std::move(context_params));
|
||||
|
||||
net::EmbeddedTestServer::ServerCertificateConfig cert_config;
|
||||
cert_config.intermediate =
|
||||
net::EmbeddedTestServer::IntermediateType::kByAIA;
|
||||
test_server_.SetSSLConfig(cert_config);
|
||||
test_server_.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server_.Start());
|
||||
}
|
||||
|
||||
void PerformAIATest() {
|
||||
LoadURL(test_server_.GetURL("/echo"),
|
||||
network::mojom::kURLLoadOptionSendSSLInfoWithResponse);
|
||||
EXPECT_EQ(net::OK, client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->response_head());
|
||||
EXPECT_EQ(0u, client()->response_head()->cert_status &
|
||||
net::CERT_STATUS_ALL_ERRORS);
|
||||
ASSERT_TRUE(client()->ssl_info());
|
||||
ASSERT_TRUE(client()->ssl_info()->cert);
|
||||
EXPECT_EQ(2u, client()->ssl_info()->cert->intermediate_buffers().size());
|
||||
ASSERT_TRUE(client()->ssl_info()->unverified_cert);
|
||||
EXPECT_EQ(
|
||||
0u,
|
||||
client()->ssl_info()->unverified_cert->intermediate_buffers().size());
|
||||
}
|
||||
|
||||
private:
|
||||
net::EmbeddedTestServer test_server_;
|
||||
};
|
||||
|
||||
TEST_P(NetworkServiceAIATest, MAYBE(AIAFetching)) {
|
||||
PerformAIATest();
|
||||
}
|
||||
|
||||
// Check that AIA fetching still succeeds even after the URLLoaderFactory
|
||||
// backing the CertNetFetcherURLLoader disconnects.
|
||||
// Only relevant if testing with the CertVerifierService, and the underlying
|
||||
// CertVerifier uses the CertNetFetcher.
|
||||
TEST_P(NetworkServiceAIATest,
|
||||
MAYBE(AIAFetchingWithURLLoaderFactoryDisconnect)) {
|
||||
if (!base::FeatureList::IsEnabled(network::features::kCertVerifierService) ||
|
||||
!cert_net_fetcher_url_loader()) {
|
||||
// TODO(crbug.com/1015706): Switch to GTEST_SKIP().
|
||||
LOG(WARNING) << "Skipping AIA reconnection test because the underlying "
|
||||
"cert verifier does not use a CertNetFetcherURLLoader.";
|
||||
return;
|
||||
}
|
||||
PerformAIATest();
|
||||
// Disconnect the URLLoaderFactory used by the CertNetFetcherURLLoader.
|
||||
cert_net_fetcher_url_loader()->DisconnectURLLoaderFactoryForTesting();
|
||||
// Try running the test again to test reconnection of the
|
||||
// CertNetFetcherURLLoader.
|
||||
PerformAIATest();
|
||||
// Repeat one more time to be sure.
|
||||
cert_net_fetcher_url_loader()->DisconnectURLLoaderFactoryForTesting();
|
||||
PerformAIATest();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All, NetworkServiceAIATest, ::testing::Bool());
|
||||
} // namespace cert_verifier
|
@ -0,0 +1,207 @@
|
||||
// Copyright 2020 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 <memory>
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "base/task/task_traits.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/test_completion_callback.h"
|
||||
#include "net/cert/test_root_certs.h"
|
||||
#include "net/cert/x509_util.h"
|
||||
#include "net/test/cert_test_util.h"
|
||||
#include "net/test/gtest_util.h"
|
||||
#include "net/test/test_data_directory.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h"
|
||||
#include "services/cert_verifier/cert_verifier_service_factory.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/ssl_config_service_mojo.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
|
||||
// Base class for any tests that just need a NetworkService and a
|
||||
// TaskEnvironment, and to create NetworkContexts using the NetworkService.
|
||||
class SSLConfigServiceMojoTestWithCertVerifier
|
||||
: public testing::TestWithParam<bool> {
|
||||
public:
|
||||
SSLConfigServiceMojoTestWithCertVerifier()
|
||||
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
|
||||
service_(network::NetworkService::CreateForTesting()),
|
||||
cert_verifier_service_impl_(
|
||||
cert_verifier_service_remote_.BindNewPipeAndPassReceiver()) {}
|
||||
~SSLConfigServiceMojoTestWithCertVerifier() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
if (GetParam()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// TODO(crbug.com/1085379): remove this GTEST_SKIP().
|
||||
GTEST_SKIP() << "Skipping test, CertVerifierService feature not yet "
|
||||
"available on ChromeOS.";
|
||||
#else
|
||||
scoped_feature_list_.InitAndEnableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
#endif
|
||||
} else {
|
||||
scoped_feature_list_.InitAndDisableFeature(
|
||||
network::features::kCertVerifierService);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyService() { service_.reset(); }
|
||||
|
||||
network::mojom::NetworkContextParamsPtr CreateNetworkContextParams() {
|
||||
network::mojom::CertVerifierCreationParamsPtr
|
||||
cert_verifier_creation_params =
|
||||
network::mojom::CertVerifierCreationParams::New();
|
||||
network::mojom::CertVerifierParamsPtr cert_verifier_params;
|
||||
if (base::FeatureList::IsEnabled(network::features::kCertVerifierService)) {
|
||||
mojo::PendingRemote<mojom::CertVerifierService> cv_service_remote;
|
||||
|
||||
auto cv_service_remote_params =
|
||||
network::mojom::CertVerifierServiceRemoteParams::New();
|
||||
|
||||
// Create a cert verifier service.
|
||||
cert_verifier_service_impl_.GetNewCertVerifierForTesting(
|
||||
cv_service_remote.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(cert_verifier_creation_params),
|
||||
&cert_net_fetcher_url_loader_);
|
||||
|
||||
cv_service_remote_params->cert_verifier_service =
|
||||
std::move(cv_service_remote);
|
||||
|
||||
cert_verifier_params =
|
||||
network::mojom::CertVerifierParams::NewRemoteParams(
|
||||
std::move(cv_service_remote_params));
|
||||
} else {
|
||||
cert_verifier_params =
|
||||
network::mojom::CertVerifierParams::NewCreationParams(
|
||||
std::move(cert_verifier_creation_params));
|
||||
}
|
||||
|
||||
network::mojom::NetworkContextParamsPtr params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
params->cert_verifier_params = std::move(cert_verifier_params);
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config =
|
||||
net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
return params;
|
||||
}
|
||||
|
||||
void CreateNetworkContext(network::mojom::NetworkContextParamsPtr params) {
|
||||
network_context_ = std::make_unique<network::NetworkContext>(
|
||||
service_.get(), network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
std::move(params));
|
||||
}
|
||||
|
||||
base::test::TaskEnvironment* task_environment() { return &task_environment_; }
|
||||
|
||||
network::NetworkService* service() const { return service_.get(); }
|
||||
|
||||
network::NetworkContext* network_context() { return network_context_.get(); }
|
||||
|
||||
mojo::Remote<network::mojom::NetworkContext>& network_context_remote() {
|
||||
return network_context_remote_;
|
||||
}
|
||||
|
||||
CertNetFetcherURLLoader* cert_net_fetcher_url_loader() {
|
||||
return cert_net_fetcher_url_loader_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
std::unique_ptr<network::NetworkService> service_;
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
|
||||
mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
|
||||
std::unique_ptr<network::NetworkContext> network_context_;
|
||||
|
||||
mojo::Remote<mojom::CertVerifierServiceFactory> cert_verifier_service_remote_;
|
||||
CertVerifierServiceFactoryImpl cert_verifier_service_impl_;
|
||||
scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher_url_loader_;
|
||||
};
|
||||
|
||||
#if !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
TEST_P(SSLConfigServiceMojoTestWithCertVerifier, CRLSetIsApplied) {
|
||||
mojo::Remote<network::mojom::SSLConfigClient> ssl_config_client;
|
||||
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
CreateNetworkContextParams();
|
||||
context_params->ssl_config_client_receiver =
|
||||
ssl_config_client.BindNewPipeAndPassReceiver();
|
||||
CreateNetworkContext(std::move(context_params));
|
||||
|
||||
network::SSLConfigServiceMojo* config_service =
|
||||
static_cast<network::SSLConfigServiceMojo*>(
|
||||
network_context()->url_request_context()->ssl_config_service());
|
||||
|
||||
scoped_refptr<net::X509Certificate> root_cert =
|
||||
net::CreateCertificateChainFromFile(
|
||||
net::GetTestCertsDirectory(), "root_ca_cert.pem",
|
||||
net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
|
||||
ASSERT_TRUE(root_cert);
|
||||
net::ScopedTestRoot test_root(root_cert.get());
|
||||
|
||||
scoped_refptr<net::X509Certificate> leaf_cert =
|
||||
net::CreateCertificateChainFromFile(
|
||||
net::GetTestCertsDirectory(), "ok_cert.pem",
|
||||
net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
|
||||
ASSERT_TRUE(leaf_cert);
|
||||
|
||||
// Ensure that |leaf_cert| is trusted without any CRLSet explicitly
|
||||
// configured.
|
||||
net::TestCompletionCallback callback1;
|
||||
net::CertVerifyResult cert_verify_result1;
|
||||
std::unique_ptr<net::CertVerifier::Request> request1;
|
||||
int result =
|
||||
network_context()->url_request_context()->cert_verifier()->Verify(
|
||||
net::CertVerifier::RequestParams(leaf_cert, "127.0.0.1",
|
||||
/*flags=*/0,
|
||||
/*ocsp_response=*/std::string(),
|
||||
/*sct_list=*/std::string()),
|
||||
&cert_verify_result1, callback1.callback(), &request1,
|
||||
net::NetLogWithSource());
|
||||
ASSERT_THAT(callback1.GetResult(result), net::test::IsOk());
|
||||
|
||||
// Load a CRLSet that removes trust in |leaf_cert| by SPKI.
|
||||
scoped_refptr<net::CRLSet> crl_set;
|
||||
std::string crl_set_bytes;
|
||||
ASSERT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
ASSERT_TRUE(net::CRLSet::ParseAndStoreUnparsedData(crl_set_bytes, &crl_set));
|
||||
|
||||
config_service->OnNewCRLSet(crl_set);
|
||||
|
||||
// Ensure that |leaf_cert| is revoked, due to the CRLSet being applied.
|
||||
net::TestCompletionCallback callback2;
|
||||
net::CertVerifyResult cert_verify_result2;
|
||||
std::unique_ptr<net::CertVerifier::Request> request2;
|
||||
result = network_context()->url_request_context()->cert_verifier()->Verify(
|
||||
net::CertVerifier::RequestParams(leaf_cert, "127.0.0.1",
|
||||
/*flags=*/0,
|
||||
/*ocsp_response=*/std::string(),
|
||||
/*sct_list=*/std::string()),
|
||||
&cert_verify_result2, callback2.callback(), &request2,
|
||||
net::NetLogWithSource());
|
||||
ASSERT_THAT(callback2.GetResult(result),
|
||||
net::test::IsError(net::ERR_CERT_REVOKED));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All,
|
||||
SSLConfigServiceMojoTestWithCertVerifier,
|
||||
::testing::Bool());
|
||||
#endif // !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
} // namespace cert_verifier
|
@ -15,19 +15,5 @@ interface CertVerifierServiceFactory {
|
||||
// Gets a new CertVerifierFactory, which //net code can interface with using
|
||||
// cert_verifier::MojoCertVerifier.
|
||||
GetNewCertVerifier(pending_receiver<CertVerifierService> receiver,
|
||||
pending_remote<network.mojom.URLLoaderFactory>?
|
||||
cert_net_fetcher_url_loader_factory,
|
||||
pending_remote<URLLoaderFactoryConnector>?
|
||||
cert_net_fetcher_url_loader_factory_connector,
|
||||
network.mojom.CertVerifierCreationParams? creation_params);
|
||||
};
|
||||
|
||||
// Allows the CertVerifierService to connect a new URLLoaderFactory if its
|
||||
// existing URLLoaderFactory is disconnected. The CertVerifierService uses the
|
||||
// URLLoaderFactory for AIA and OCSP fetching.
|
||||
interface URLLoaderFactoryConnector {
|
||||
// Binds a URLLoaderFactory. The implementer of this interface is in charge
|
||||
// of choosing the URLLoaderFactoryParams.
|
||||
CreateURLLoaderFactory(
|
||||
pending_receiver<network.mojom.URLLoaderFactory> url_loader_factory);
|
||||
};
|
||||
|
@ -32,9 +32,6 @@ TestCertVerifierServiceFactoryImpl::~TestCertVerifierServiceFactoryImpl() =
|
||||
|
||||
void TestCertVerifierServiceFactoryImpl::GetNewCertVerifier(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) {
|
||||
if (!delegate_) {
|
||||
InitDelegate();
|
||||
@ -42,9 +39,6 @@ void TestCertVerifierServiceFactoryImpl::GetNewCertVerifier(
|
||||
|
||||
GetNewCertVerifierParams params;
|
||||
params.receiver = std::move(receiver);
|
||||
params.url_loader_factory = std::move(url_loader_factory);
|
||||
params.cert_net_fetcher_url_loader_factory_connector =
|
||||
std::move(cert_net_fetcher_url_loader_factory_connector);
|
||||
params.creation_params = std::move(creation_params);
|
||||
|
||||
captured_params_.push_front(std::move(params));
|
||||
@ -60,10 +54,8 @@ void TestCertVerifierServiceFactoryImpl::ReleaseNextCertVerifierParams() {
|
||||
DCHECK(delegate_);
|
||||
GetNewCertVerifierParams params = std::move(captured_params_.back());
|
||||
captured_params_.pop_back();
|
||||
delegate_remote_->GetNewCertVerifier(
|
||||
std::move(params.receiver), std::move(params.url_loader_factory),
|
||||
std::move(params.cert_net_fetcher_url_loader_factory_connector),
|
||||
std::move(params.creation_params));
|
||||
delegate_remote_->GetNewCertVerifier(std::move(params.receiver),
|
||||
std::move(params.creation_params));
|
||||
}
|
||||
|
||||
void TestCertVerifierServiceFactoryImpl::InitDelegate() {
|
||||
|
@ -38,18 +38,12 @@ class TestCertVerifierServiceFactoryImpl
|
||||
~GetNewCertVerifierParams();
|
||||
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver;
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector;
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params;
|
||||
};
|
||||
|
||||
// mojom::CertVerifierServiceFactory implementation:
|
||||
void GetNewCertVerifier(
|
||||
mojo::PendingReceiver<mojom::CertVerifierService> receiver,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector>
|
||||
cert_net_fetcher_url_loader_factory_connector,
|
||||
network::mojom::CertVerifierCreationParamsPtr creation_params) override;
|
||||
|
||||
// Pops the first request off the back of the list and forwards it to the
|
||||
|
@ -417,6 +417,8 @@ jumbo_source_set("test_support") {
|
||||
sources = [
|
||||
"mojo_socket_test_util.cc",
|
||||
"mojo_socket_test_util.h",
|
||||
"test/fake_test_cert_verifier_params_factory.cc",
|
||||
"test/fake_test_cert_verifier_params_factory.h",
|
||||
"test/test_cookie_manager.cc",
|
||||
"test/test_cookie_manager.h",
|
||||
"test/test_data_pipe_getter.cc",
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/resource_scheduler/resource_scheduler.h"
|
||||
#include "services/network/resource_scheduler/resource_scheduler_client.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/gurl.h"
|
||||
@ -54,6 +55,10 @@ class CorsURLLoaderFactoryTest : public testing::Test {
|
||||
network_service_ = NetworkService::CreateForTesting();
|
||||
|
||||
auto context_params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
context_params->initial_proxy_config =
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/resource_scheduler/resource_scheduler.h"
|
||||
#include "services/network/resource_scheduler/resource_scheduler_client.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
#include "services/network/url_loader.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
@ -162,6 +163,12 @@ class CorsURLLoaderTest : public testing::Test {
|
||||
|
||||
network_service_ = NetworkService::CreateForTesting();
|
||||
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
context_params->initial_proxy_config =
|
||||
net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
context_params->cors_exempt_header_list.push_back(kTestCorsExemptHeader);
|
||||
|
@ -21,8 +21,10 @@
|
||||
#include "services/network/cors/cors_url_loader_factory.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/cors/cors.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_network_service_client.h"
|
||||
#include "services/network/test/test_url_loader_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -347,9 +349,14 @@ class PreflightControllerTest : public testing::Test {
|
||||
network_service_ = NetworkService::Create(
|
||||
network_service_remote.BindNewPipeAndPassReceiver());
|
||||
|
||||
auto context_params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
network_service_remote->CreateNetworkContext(
|
||||
network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
mojom::NetworkContextParams::New());
|
||||
std::move(context_params));
|
||||
|
||||
network::mojom::URLLoaderFactoryParamsPtr params =
|
||||
network::mojom::URLLoaderFactoryParams::New();
|
||||
|
@ -8,10 +8,12 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/location.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
@ -21,8 +23,13 @@ namespace {
|
||||
// CRLSet.
|
||||
scoped_refptr<net::CRLSet> ParseCRLSet(std::string crl_set) {
|
||||
scoped_refptr<net::CRLSet> result;
|
||||
if (!net::CRLSet::Parse(crl_set, &result))
|
||||
return nullptr;
|
||||
if (base::FeatureList::IsEnabled(network::features::kCertVerifierService)) {
|
||||
if (!net::CRLSet::ParseAndStoreUnparsedData(std::move(crl_set), &result))
|
||||
return nullptr;
|
||||
} else {
|
||||
if (!net::CRLSet::Parse(std::move(crl_set), &result))
|
||||
return nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace network {
|
||||
@ -54,6 +55,10 @@ constexpr CacheTestEntry kCacheEntries[] = {
|
||||
|
||||
mojom::NetworkContextParamsPtr CreateContextParams() {
|
||||
mojom::NetworkContextParamsPtr params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config = net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "net/url_request/url_request_context_builder.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace network {
|
||||
@ -61,6 +62,10 @@ constexpr CacheTestEntry kCacheEntries[] = {
|
||||
|
||||
mojom::NetworkContextParamsPtr CreateContextParams() {
|
||||
mojom::NetworkContextParamsPtr params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config = net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/pref_service_factory.h"
|
||||
#include "crypto/sha2.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/base/network_delegate.h"
|
||||
@ -86,11 +87,14 @@
|
||||
#include "services/network/proxy_lookup_request.h"
|
||||
#include "services/network/proxy_resolving_socket_factory_mojo.h"
|
||||
#include "services/network/public/cpp/cert_verifier/cert_verifier_creation.h"
|
||||
#include "services/network/public/cpp/cert_verifier/mojo_cert_verifier.h"
|
||||
#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
#include "services/network/public/cpp/parsed_headers.h"
|
||||
#include "services/network/public/mojom/network_context.mojom-forward.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/quic_transport.h"
|
||||
#include "services/network/resolve_host_request.h"
|
||||
#include "services/network/resource_scheduler/resource_scheduler_client.h"
|
||||
@ -345,7 +349,15 @@ NetworkContext::NetworkContext(
|
||||
cors_preflight_controller_(
|
||||
params_->cors_extra_safelisted_request_header_names,
|
||||
network_service) {
|
||||
url_request_context_owner_ = MakeURLRequestContext();
|
||||
mojo::PendingRemote<mojom::URLLoaderFactory>
|
||||
url_loader_factory_for_cert_net_fetcher;
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory>
|
||||
url_loader_factory_for_cert_net_fetcher_receiver =
|
||||
url_loader_factory_for_cert_net_fetcher
|
||||
.InitWithNewPipeAndPassReceiver();
|
||||
|
||||
url_request_context_owner_ =
|
||||
MakeURLRequestContext(std::move(url_loader_factory_for_cert_net_fetcher));
|
||||
url_request_context_ = url_request_context_owner_.url_request_context.get();
|
||||
|
||||
network_service_->RegisterNetworkContext(this);
|
||||
@ -383,6 +395,9 @@ NetworkContext::NetworkContext(
|
||||
if (params_->cookie_manager)
|
||||
GetCookieManager(std::move(params_->cookie_manager));
|
||||
#endif
|
||||
|
||||
CreateURLLoaderFactoryForCertNetFetcher(
|
||||
std::move(url_loader_factory_for_cert_net_fetcher_receiver));
|
||||
}
|
||||
|
||||
NetworkContext::NetworkContext(
|
||||
@ -463,6 +478,7 @@ NetworkContext::~NetworkContext() {
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void NetworkContext::SetCertVerifierForTesting(
|
||||
net::CertVerifier* cert_verifier) {
|
||||
g_cert_verifier_for_testing = cert_verifier;
|
||||
@ -477,6 +493,18 @@ void NetworkContext::CreateURLLoaderFactory(
|
||||
std::move(receiver), &cors_origin_access_list_));
|
||||
}
|
||||
|
||||
void NetworkContext::CreateURLLoaderFactoryForCertNetFetcher(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory> factory_receiver) {
|
||||
// TODO(crbug.com/1087790): investigate changing these params.
|
||||
auto url_loader_factory_params = mojom::URLLoaderFactoryParams::New();
|
||||
url_loader_factory_params->is_trusted = true;
|
||||
url_loader_factory_params->process_id = mojom::kBrowserProcessId;
|
||||
url_loader_factory_params->automatically_assign_isolation_info = true;
|
||||
url_loader_factory_params->is_corb_enabled = false;
|
||||
CreateURLLoaderFactory(std::move(factory_receiver),
|
||||
std::move(url_loader_factory_params));
|
||||
}
|
||||
|
||||
void NetworkContext::ActivateDohProbes() {
|
||||
DCHECK(url_request_context_->host_resolver());
|
||||
|
||||
@ -942,8 +970,12 @@ void NetworkContext::SetEnableReferrers(bool enable_referrers) {
|
||||
void NetworkContext::UpdateAdditionalCertificates(
|
||||
mojom::AdditionalCertificatesPtr additional_certificates) {
|
||||
if (!cert_verifier_with_trust_anchors_) {
|
||||
CHECK(g_cert_verifier_for_testing ||
|
||||
params_->cert_verifier_creation_params->username_hash.empty());
|
||||
// TODO(crbug.com/1085379): include this CHECK somewhere in the
|
||||
// CertVerifierService when it's launched on ChromeOS.
|
||||
CHECK(g_cert_verifier_for_testing || !params_->cert_verifier_params ||
|
||||
params_->cert_verifier_params->is_remote_params() ||
|
||||
params_->cert_verifier_params->get_creation_params()
|
||||
->username_hash.empty());
|
||||
return;
|
||||
}
|
||||
if (!additional_certificates) {
|
||||
@ -1674,26 +1706,61 @@ void NetworkContext::OnHttpAuthDynamicParamsChanged(
|
||||
#endif
|
||||
}
|
||||
|
||||
URLRequestContextOwner NetworkContext::MakeURLRequestContext() {
|
||||
URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
mojo::PendingRemote<mojom::URLLoaderFactory>
|
||||
url_loader_factory_for_cert_net_fetcher) {
|
||||
URLRequestContextBuilderMojo builder;
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
|
||||
DCHECK(
|
||||
g_cert_verifier_for_testing ||
|
||||
!base::FeatureList::IsEnabled(network::features::kCertVerifierService) ||
|
||||
(params_->cert_verifier_params &&
|
||||
params_->cert_verifier_params->is_remote_params()))
|
||||
<< "If cert verification service is on, the creator of the "
|
||||
"NetworkContext should pass CertVerifierServiceRemoteParams.";
|
||||
|
||||
std::unique_ptr<net::CertVerifier> cert_verifier;
|
||||
if (g_cert_verifier_for_testing) {
|
||||
cert_verifier = std::make_unique<WrappedTestingCertVerifier>();
|
||||
} else {
|
||||
mojom::CertVerifierCreationParams* creation_params = nullptr;
|
||||
if (params_->cert_verifier_creation_params)
|
||||
creation_params = params_->cert_verifier_creation_params.get();
|
||||
if (params_->cert_verifier_params &&
|
||||
params_->cert_verifier_params->is_remote_params()) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
DLOG(FATAL) << "Servicified cert verifier not yet supported on ChromeOS.";
|
||||
CHECK(false);
|
||||
#endif
|
||||
|
||||
if (IsUsingCertNetFetcher())
|
||||
cert_net_fetcher_ = base::MakeRefCounted<net::CertNetFetcherURLRequest>();
|
||||
// base::Unretained() is safe below because |this| will own
|
||||
// |cert_verifier|.
|
||||
// TODO(https://crbug.com/1085233): this cert verifier should deal with
|
||||
// disconnections if the CertVerifierService is run outside of the browser
|
||||
// process.
|
||||
cert_verifier = std::make_unique<cert_verifier::MojoCertVerifier>(
|
||||
std::move(params_->cert_verifier_params->get_remote_params()
|
||||
->cert_verifier_service),
|
||||
std::move(url_loader_factory_for_cert_net_fetcher),
|
||||
base::BindRepeating(
|
||||
&NetworkContext::CreateURLLoaderFactoryForCertNetFetcher,
|
||||
base::Unretained(this)));
|
||||
} else {
|
||||
mojom::CertVerifierCreationParams* creation_params = nullptr;
|
||||
if (params_->cert_verifier_params &&
|
||||
params_->cert_verifier_params->is_creation_params()) {
|
||||
creation_params =
|
||||
params_->cert_verifier_params->get_creation_params().get();
|
||||
}
|
||||
|
||||
cert_verifier = CreateCertVerifier(creation_params, cert_net_fetcher_);
|
||||
if (IsUsingCertNetFetcher())
|
||||
cert_net_fetcher_ =
|
||||
base::MakeRefCounted<net::CertNetFetcherURLRequest>();
|
||||
|
||||
// Wrap the cert verifier in caching and coalescing layers to avoid extra
|
||||
// verifications.
|
||||
cert_verifier = CreateCertVerifier(creation_params, cert_net_fetcher_);
|
||||
}
|
||||
|
||||
// Whether the cert verifier is remote or in-process, we should wrap it in
|
||||
// caching and coalescing layers to avoid extra verifications and IPCs.
|
||||
cert_verifier = std::make_unique<net::CachingCertVerifier>(
|
||||
std::make_unique<net::CoalescingCertVerifier>(
|
||||
std::move(cert_verifier)));
|
||||
|
@ -172,6 +172,14 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
mojom::URLLoaderFactoryParamsPtr params,
|
||||
scoped_refptr<ResourceSchedulerClient> resource_scheduler_client);
|
||||
|
||||
// Creates a URLLoaderFactory with params specific to the
|
||||
// CertVerifierService. A URLLoaderFactory created by this function will be
|
||||
// used by a CertNetFetcherURLLoader to perform AIA and OCSP fetching.
|
||||
// These URLLoaderFactories should only ever be used by the
|
||||
// CertVerifierService, and should never be passed to a renderer.
|
||||
void CreateURLLoaderFactoryForCertNetFetcher(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory> factory_receiver);
|
||||
|
||||
// Enables DoH probes to be sent using this context whenever the DNS
|
||||
// configuration contains DoH servers.
|
||||
void ActivateDohProbes();
|
||||
@ -484,7 +492,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
}
|
||||
|
||||
private:
|
||||
URLRequestContextOwner MakeURLRequestContext();
|
||||
URLRequestContextOwner MakeURLRequestContext(
|
||||
mojo::PendingRemote<mojom::URLLoaderFactory>
|
||||
url_loader_factory_for_cert_net_fetcher);
|
||||
|
||||
// Invoked when the HTTP cache was cleared. Invokes |callback|.
|
||||
void OnHttpCacheCleared(ClearHttpCacheCallback callback,
|
||||
@ -644,7 +654,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
#endif
|
||||
|
||||
// CertNetFetcher used by the context's CertVerifier. May be nullptr if
|
||||
// CertNetFetcher is not used by the current platform.
|
||||
// CertNetFetcher is not used by the current platform, or if the actual
|
||||
// net::CertVerifier is instantiated outside of the network service.
|
||||
scoped_refptr<net::CertNetFetcherURLRequest> cert_net_fetcher_;
|
||||
|
||||
// Created on-demand. Null if unused.
|
||||
|
@ -118,6 +118,7 @@
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/proxy_config.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom-shared.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
#include "services/network/trust_tokens/pending_trust_token_store.h"
|
||||
#include "services/network/trust_tokens/trust_token_parameterization.h"
|
||||
@ -392,6 +393,11 @@ class NetworkContextTest : public testing::Test {
|
||||
|
||||
std::unique_ptr<NetworkContext> CreateContextWithParams(
|
||||
mojom::NetworkContextParamsPtr context_params) {
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
DCHECK(!context_params->cert_verifier_params);
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
network_context_remote_.reset();
|
||||
return std::make_unique<NetworkContext>(
|
||||
network_service_.get(),
|
||||
@ -6144,87 +6150,6 @@ TEST_F(NetworkContextTest, FactoriesDeletedWhenBindingsCleared) {
|
||||
EXPECT_EQ(network_context->num_url_loader_factories_for_testing(), 0u);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
TEST_F(NetworkContextTest, UseCertVerifierBuiltin) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
net::test_server::RegisterDefaultHandlers(&test_server);
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// This just happens to be the only histogram that directly records which
|
||||
// verifier was used.
|
||||
const char kBuiltinVerifierHistogram[] =
|
||||
"Net.CertVerifier.NameNormalizationPrivateRoots.Builtin";
|
||||
|
||||
for (bool builtin_verifier_enabled : {false, true}) {
|
||||
SCOPED_TRACE(builtin_verifier_enabled);
|
||||
|
||||
mojom::NetworkContextParamsPtr params = CreateContextParams();
|
||||
auto creation_params = mojom::CertVerifierCreationParams::New();
|
||||
creation_params->use_builtin_cert_verifier =
|
||||
builtin_verifier_enabled
|
||||
? mojom::CertVerifierCreationParams::CertVerifierImpl::kBuiltin
|
||||
: mojom::CertVerifierCreationParams::CertVerifierImpl::kSystem;
|
||||
params->cert_verifier_creation_params = std::move(creation_params);
|
||||
std::unique_ptr<NetworkContext> network_context =
|
||||
CreateContextWithParams(std::move(params));
|
||||
|
||||
ResourceRequest request;
|
||||
request.url = test_server.GetURL("/nocontent");
|
||||
base::HistogramTester histogram_tester;
|
||||
std::unique_ptr<TestURLLoaderClient> client =
|
||||
FetchRequest(request, network_context.get());
|
||||
EXPECT_EQ(net::OK, client->completion_status().error_code);
|
||||
histogram_tester.ExpectTotalCount(kBuiltinVerifierHistogram,
|
||||
builtin_verifier_enabled ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
class NetworkContextCertVerifierBuiltinFeatureFlagTest
|
||||
: public NetworkContextTest,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
NetworkContextCertVerifierBuiltinFeatureFlagTest() {
|
||||
scoped_feature_list_.InitWithFeatureState(
|
||||
net::features::kCertVerifierBuiltinFeature,
|
||||
/*enabled=*/GetParam());
|
||||
}
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
TEST_P(NetworkContextCertVerifierBuiltinFeatureFlagTest,
|
||||
DefaultNetworkContextParamsUsesCorrectVerifier) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
net::test_server::RegisterDefaultHandlers(&test_server);
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// This just happens to be the only histogram that directly records which
|
||||
// verifier was used.
|
||||
const char kBuiltinVerifierHistogram[] =
|
||||
"Net.CertVerifier.NameNormalizationPrivateRoots.Builtin";
|
||||
|
||||
// Test creating a NetworkContextParams without specifying a value for
|
||||
// use_builtin_cert_verifier. Should use whatever the default cert verifier
|
||||
// implementation is according to the feature flag.
|
||||
std::unique_ptr<NetworkContext> network_context =
|
||||
CreateContextWithParams(CreateContextParams());
|
||||
|
||||
ResourceRequest request;
|
||||
request.url = test_server.GetURL("/nocontent");
|
||||
base::HistogramTester histogram_tester;
|
||||
std::unique_ptr<TestURLLoaderClient> client =
|
||||
FetchRequest(request, network_context.get());
|
||||
EXPECT_EQ(net::OK, client->completion_status().error_code);
|
||||
histogram_tester.ExpectTotalCount(kBuiltinVerifierHistogram,
|
||||
GetParam() ? 1 : 0);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All,
|
||||
NetworkContextCertVerifierBuiltinFeatureFlagTest,
|
||||
::testing::Bool());
|
||||
#endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
|
||||
|
||||
static ResourceRequest CreateResourceRequest(const char* method,
|
||||
const GURL& url) {
|
||||
ResourceRequest request;
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "services/network/public/mojom/network_change_manager.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_network_context_client.h"
|
||||
#include "services/network/test/test_network_service_client.h"
|
||||
#include "services/network/test/test_url_loader_client.h"
|
||||
@ -83,6 +84,10 @@ GURL AddQuery(const GURL& url,
|
||||
|
||||
mojom::NetworkContextParamsPtr CreateContextParams() {
|
||||
mojom::NetworkContextParamsPtr params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
params->initial_proxy_config = net::ProxyConfigWithAnnotation::CreateDirect();
|
||||
@ -904,6 +909,10 @@ class NetworkServiceTestWithService : public testing::Test {
|
||||
void CreateNetworkContext() {
|
||||
mojom::NetworkContextParamsPtr context_params =
|
||||
mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
@ -1230,261 +1239,6 @@ TEST_F(NetworkServiceTestWithService, SetsTrustTokenKeyCommitments) {
|
||||
EXPECT_TRUE(result.Equals(expectation));
|
||||
}
|
||||
|
||||
// CRLSets are not supported on iOS and Android system verifiers.
|
||||
#if !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
// Verifies CRLSets take effect if configured on the service.
|
||||
TEST_F(NetworkServiceTestWithService, CRLSetIsApplied) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
|
||||
test_server.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
CreateNetworkContext();
|
||||
|
||||
uint32_t options = mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the test server loads fine with no CRLSet.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
ASSERT_EQ(net::OK, client()->completion_status().error_code);
|
||||
|
||||
// Send a CRLSet that blocks the leaf cert.
|
||||
std::string crl_set_bytes;
|
||||
EXPECT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies CRLSets configured before creating a new network context are
|
||||
// applied to that network context.
|
||||
TEST_F(NetworkServiceTestWithService, CRLSetIsPassedToNewContexts) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
|
||||
test_server.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// Send a CRLSet that blocks the leaf cert, even while no NetworkContexts
|
||||
// exist.
|
||||
std::string crl_set_bytes;
|
||||
EXPECT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
|
||||
// Configure a new NetworkContext.
|
||||
CreateNetworkContext();
|
||||
|
||||
uint32_t options = mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies newer CRLSets (by sequence number) are applied.
|
||||
TEST_F(NetworkServiceTestWithService, CRLSetIsUpdatedIfNewer) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
|
||||
test_server.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// Send a CRLSet that only allows the root cert if it matches a known SPKI
|
||||
// hash (that matches the test server chain)
|
||||
std::string crl_set_bytes;
|
||||
ASSERT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
CreateNetworkContext();
|
||||
|
||||
uint32_t options = mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection loads, due to the root being permitted.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
ASSERT_EQ(net::OK, client()->completion_status().error_code);
|
||||
|
||||
// Send a new CRLSet that removes trust in the root.
|
||||
ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
|
||||
"crlset_by_root_subject_no_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
// Verifies that attempting to send an older CRLSet (by sequence number)
|
||||
// does not apply to existing or new contexts.
|
||||
TEST_F(NetworkServiceTestWithService, CRLSetDoesNotDowngrade) {
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
|
||||
test_server.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
// Send a CRLSet that blocks the root certificate by subject name.
|
||||
std::string crl_set_bytes;
|
||||
ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
|
||||
"crlset_by_root_subject_no_spki.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
CreateNetworkContext();
|
||||
|
||||
uint32_t options = mojom::kURLLoadOptionSendSSLInfoWithResponse |
|
||||
mojom::kURLLoadOptionSendSSLInfoForCertificateError;
|
||||
// Make sure the connection fails, due to the certificate being revoked.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
|
||||
// Attempt to configure an older CRLSet that allowed trust in the root.
|
||||
ASSERT_TRUE(base::ReadFileToString(
|
||||
net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
|
||||
&crl_set_bytes));
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
|
||||
run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Flush all connections in the context, to force a new connection. A new
|
||||
// verification should be attempted, due to the configuration having
|
||||
// changed, thus forcing the CRLSet to be checked.
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
context()->CloseAllConnections(run_loop.QuitClosure());
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
// Make sure the connection still fails, due to the newer CRLSet still
|
||||
// applying.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
|
||||
// Create a new NetworkContext and ensure the latest CRLSet is still
|
||||
// applied.
|
||||
network_context_.reset();
|
||||
CreateNetworkContext();
|
||||
|
||||
// The newer CRLSet that blocks the connection should still apply, even to
|
||||
// new NetworkContexts.
|
||||
LoadURL(test_server.GetURL("/echo"), options);
|
||||
EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
|
||||
client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
|
||||
EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
|
||||
net::CERT_STATUS_REVOKED);
|
||||
}
|
||||
|
||||
#endif // !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
// TODO(crbug.com/860189): AIA tests fail on iOS
|
||||
#if defined(OS_IOS)
|
||||
#define MAYBE_AIAFetching DISABLED_AIAFetching
|
||||
#else
|
||||
#define MAYBE_AIAFetching AIAFetching
|
||||
#endif
|
||||
TEST_F(NetworkServiceTestWithService, MAYBE_AIAFetching) {
|
||||
mojom::NetworkContextParamsPtr context_params = CreateContextParams();
|
||||
|
||||
network_service_->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(), std::move(context_params));
|
||||
|
||||
net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
|
||||
net::EmbeddedTestServer::ServerCertificateConfig cert_config;
|
||||
cert_config.intermediate = net::EmbeddedTestServer::IntermediateType::kByAIA;
|
||||
test_server.SetSSLConfig(cert_config);
|
||||
test_server.AddDefaultHandlers(base::FilePath(kServicesTestData));
|
||||
ASSERT_TRUE(test_server.Start());
|
||||
|
||||
LoadURL(test_server.GetURL("/echo"),
|
||||
mojom::kURLLoadOptionSendSSLInfoWithResponse);
|
||||
EXPECT_EQ(net::OK, client()->completion_status().error_code);
|
||||
ASSERT_TRUE(client()->response_head());
|
||||
EXPECT_EQ(
|
||||
0u, client()->response_head()->cert_status & net::CERT_STATUS_ALL_ERRORS);
|
||||
ASSERT_TRUE(client()->ssl_info());
|
||||
ASSERT_TRUE(client()->ssl_info()->cert);
|
||||
EXPECT_EQ(2u, client()->ssl_info()->cert->intermediate_buffers().size());
|
||||
ASSERT_TRUE(client()->ssl_info()->unverified_cert);
|
||||
EXPECT_EQ(
|
||||
0u, client()->ssl_info()->unverified_cert->intermediate_buffers().size());
|
||||
}
|
||||
|
||||
TEST_F(NetworkServiceTestWithService, GetDnsConfigChangeManager) {
|
||||
mojo::Remote<mojom::DnsConfigChangeManager> remote;
|
||||
ASSERT_FALSE(remote.is_bound());
|
||||
@ -1641,6 +1395,10 @@ class NetworkServiceNetworkDelegateTest : public NetworkServiceTest {
|
||||
void CreateNetworkContext() {
|
||||
mojom::NetworkContextParamsPtr context_params =
|
||||
mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
service()->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/origin_policy.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
@ -30,6 +31,10 @@ class OriginPolicyManagerTest : public testing::Test {
|
||||
network_service_ = NetworkService::CreateForTesting();
|
||||
|
||||
auto context_params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
// Use a fixed proxy config, to avoid dependencies on local network
|
||||
// configuration.
|
||||
context_params->initial_proxy_config =
|
||||
|
@ -3,6 +3,9 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/network/public/cpp/cert_verifier/mojo_cert_verifier.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "net/base/net_errors.h"
|
||||
@ -62,9 +65,44 @@ class CertVerifierRequestImpl : public mojom::CertVerifierRequest,
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class MojoCertVerifier::MojoReconnector
|
||||
: public mojom::URLLoaderFactoryConnector {
|
||||
public:
|
||||
MojoReconnector(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactoryConnector> receiver,
|
||||
base::RepeatingCallback<void(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>)> reconnector)
|
||||
: receiver_(this, std::move(receiver)),
|
||||
reconnector_(std::move(reconnector)) {}
|
||||
|
||||
// mojom::URLLoaderFactoryConnector implementation:
|
||||
void CreateURLLoaderFactory(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>
|
||||
url_loader_factory) override {
|
||||
reconnector_.Run(std::move(url_loader_factory));
|
||||
}
|
||||
|
||||
private:
|
||||
mojo::Receiver<mojom::URLLoaderFactoryConnector> receiver_;
|
||||
base::RepeatingCallback<void(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>)>
|
||||
reconnector_;
|
||||
};
|
||||
|
||||
MojoCertVerifier::MojoCertVerifier(
|
||||
mojo::PendingRemote<mojom::CertVerifierService> mojo_cert_verifier)
|
||||
: mojo_cert_verifier_(std::move(mojo_cert_verifier)) {}
|
||||
mojo::PendingRemote<mojom::CertVerifierService> mojo_cert_verifier,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
base::RepeatingCallback<void(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>)> reconnector)
|
||||
: mojo_cert_verifier_(std::move(mojo_cert_verifier)) {
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector> reconnector_remote;
|
||||
|
||||
reconnector_ = std::make_unique<MojoReconnector>(
|
||||
reconnector_remote.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(reconnector));
|
||||
mojo_cert_verifier_->EnableNetworkAccess(std::move(url_loader_factory),
|
||||
std::move(reconnector_remote));
|
||||
}
|
||||
|
||||
MojoCertVerifier::~MojoCertVerifier() = default;
|
||||
|
||||
@ -90,4 +128,8 @@ int MojoCertVerifier::Verify(
|
||||
void MojoCertVerifier::SetConfig(const net::CertVerifier::Config& config) {
|
||||
mojo_cert_verifier_->SetConfig(config);
|
||||
}
|
||||
|
||||
void MojoCertVerifier::FlushForTesting() {
|
||||
mojo_cert_verifier_.FlushForTesting();
|
||||
}
|
||||
} // namespace cert_verifier
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef SERVICES_NETWORK_PUBLIC_CPP_CERT_VERIFIER_MOJO_CERT_VERIFIER_H_
|
||||
#define SERVICES_NETWORK_PUBLIC_CPP_CERT_VERIFIER_MOJO_CERT_VERIFIER_H_
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "net/base/completion_once_callback.h"
|
||||
#include "net/base/net_export.h"
|
||||
@ -12,6 +14,7 @@
|
||||
#include "net/cert/cert_verify_result.h"
|
||||
#include "net/log/net_log_with_source.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
|
||||
namespace cert_verifier {
|
||||
|
||||
@ -19,8 +22,16 @@ namespace cert_verifier {
|
||||
// verify certificates.
|
||||
class MojoCertVerifier : public net::CertVerifier {
|
||||
public:
|
||||
explicit MojoCertVerifier(
|
||||
mojo::PendingRemote<mojom::CertVerifierService> mojo_cert_verifier);
|
||||
using ReconnectURLLoaderFactory = base::RepeatingCallback<void(
|
||||
mojo::PendingReceiver<network::mojom::URLLoaderFactory>)>;
|
||||
|
||||
// The remote CertNetFetcher will use |url_loader_factory| for fetches. If
|
||||
// |url_loader_factory| disconnects it will use |reconnector| to try to
|
||||
// connect a new URLLoaderFactory.
|
||||
MojoCertVerifier(
|
||||
mojo::PendingRemote<mojom::CertVerifierService> mojo_cert_verifier,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
|
||||
ReconnectURLLoaderFactory reconnector);
|
||||
~MojoCertVerifier() override;
|
||||
|
||||
// net::CertVerifier implementation:
|
||||
@ -31,8 +42,14 @@ class MojoCertVerifier : public net::CertVerifier {
|
||||
const net::NetLogWithSource& net_log) override;
|
||||
void SetConfig(const net::CertVerifier::Config& config) override;
|
||||
|
||||
// Flushes the underlying Mojo pipe.
|
||||
void FlushForTesting();
|
||||
|
||||
private:
|
||||
class MojoReconnector;
|
||||
|
||||
mojo::Remote<mojom::CertVerifierService> mojo_cert_verifier_;
|
||||
std::unique_ptr<MojoReconnector> reconnector_;
|
||||
};
|
||||
|
||||
} // namespace cert_verifier
|
||||
|
@ -7,9 +7,11 @@
|
||||
#include <map>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/bind_helpers.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/test/bind_test_util.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/test_completion_callback.h"
|
||||
#include "net/cert/cert_status_flags.h"
|
||||
#include "net/cert/cert_verifier.h"
|
||||
@ -36,12 +38,27 @@ net::CertVerifier::RequestParams GetDummyParams() {
|
||||
/*sct_list=*/std::string());
|
||||
}
|
||||
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
||||
CreateUnconnectedURLLoaderFactory() {
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
|
||||
// Bind the factory, but don't bother connecting it.
|
||||
ignore_result(url_loader_factory.InitWithNewPipeAndPassReceiver());
|
||||
return url_loader_factory;
|
||||
}
|
||||
|
||||
class MojoCertVerifierTest : public PlatformTest {
|
||||
public:
|
||||
MojoCertVerifierTest()
|
||||
: dummy_cv_service_(this),
|
||||
cv_service_receiver_(&dummy_cv_service_),
|
||||
mojo_cert_verifier_(cv_service_receiver_.BindNewPipeAndPassRemote()) {}
|
||||
mojo_cert_verifier_(
|
||||
cv_service_receiver_.BindNewPipeAndPassRemote(),
|
||||
CreateUnconnectedURLLoaderFactory(),
|
||||
base::BindRepeating(&MojoCertVerifierTest::ReconnectCb,
|
||||
base::Unretained(this))) {
|
||||
// Any Mojo requests in the MojoCertVerifier constructor should run here.
|
||||
mojo_cert_verifier_.FlushForTesting();
|
||||
}
|
||||
|
||||
class DummyCVService final : public mojom::CertVerifierService {
|
||||
public:
|
||||
@ -57,12 +74,24 @@ class MojoCertVerifierTest : public PlatformTest {
|
||||
config_ = config;
|
||||
}
|
||||
|
||||
void EnableNetworkAccess(
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
||||
url_loader_factory,
|
||||
mojo::PendingRemote<mojom::URLLoaderFactoryConnector> reconnector)
|
||||
override {
|
||||
reconnector_.Bind(std::move(reconnector));
|
||||
}
|
||||
|
||||
const net::CertVerifier::Config* config() const { return &config_; }
|
||||
mojom::URLLoaderFactoryConnector* reconnector() {
|
||||
return reconnector_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
MojoCertVerifierTest* test_;
|
||||
|
||||
net::CertVerifier::Config config_;
|
||||
mojo::Remote<mojom::URLLoaderFactoryConnector> reconnector_;
|
||||
};
|
||||
|
||||
base::test::TaskEnvironment* task_environment() { return &task_environment_; }
|
||||
@ -97,6 +126,16 @@ class MojoCertVerifierTest : public PlatformTest {
|
||||
|
||||
void SimulateCVServiceDisconnect() { cv_service_receiver_.reset(); }
|
||||
|
||||
void ReconnectCb(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
|
||||
mojo_cert_verifier) {
|
||||
if (reconnect_cb_)
|
||||
reconnect_cb_.Run(std::move(mojo_cert_verifier));
|
||||
}
|
||||
|
||||
void SetReconnectCb(MojoCertVerifier::ReconnectURLLoaderFactory cb) {
|
||||
reconnect_cb_ = std::move(cb);
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<net::CertVerifier::RequestParams,
|
||||
mojo::Remote<mojom::CertVerifierRequest>>
|
||||
@ -109,6 +148,8 @@ class MojoCertVerifierTest : public PlatformTest {
|
||||
|
||||
MojoCertVerifier mojo_cert_verifier_;
|
||||
|
||||
MojoCertVerifier::ReconnectURLLoaderFactory reconnect_cb_;
|
||||
|
||||
net::NetLogWithSource empty_net_log_with_source_;
|
||||
};
|
||||
} // namespace
|
||||
@ -244,4 +285,22 @@ TEST_F(MojoCertVerifierTest, SendsConfig) {
|
||||
ASSERT_TRUE(dummy_cv_service()->config()->disable_symantec_enforcement);
|
||||
}
|
||||
|
||||
TEST_F(MojoCertVerifierTest, ReconnectorCallsCb) {
|
||||
base::RunLoop run_loop;
|
||||
SetReconnectCb(base::BindLambdaForTesting(
|
||||
[&](mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
|
||||
run_loop.Quit();
|
||||
}));
|
||||
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>
|
||||
dummy_url_loader_factory_remote;
|
||||
// Simulate a remote CertVerifierService trying to reconnect after
|
||||
// disconnection. This should call the callback given to the MojoCertVerifier
|
||||
// on construction.
|
||||
dummy_cv_service()->reconnector()->CreateURLLoaderFactory(
|
||||
dummy_url_loader_factory_remote.InitWithNewPipeAndPassReceiver());
|
||||
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
} // namespace cert_verifier
|
||||
|
@ -194,6 +194,12 @@ const char kCorbAllowlistAlsoAppliesToOorCorsParamName[] =
|
||||
const base::Feature kStrictAccessControlAllowListCheck = {
|
||||
"StrictAccessControlAllowListCheck", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
// When the CertVerifierService is enabled, certificate verification will not be
|
||||
// performed in the network service, but will instead be brokered to a separate
|
||||
// cert verification service potentially running in a different process.
|
||||
const base::Feature kCertVerifierService{"CertVerifierService",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
|
||||
// Enables preprocessing requests with the Trust Tokens API Fetch flags set,
|
||||
// and handling their responses, according to the protocol.
|
||||
// (See https://github.com/WICG/trust-token-api.)
|
||||
|
@ -73,6 +73,8 @@ COMPONENT_EXPORT(NETWORK_CPP)
|
||||
extern const char kCorbAllowlistAlsoAppliesToOorCorsParamName[];
|
||||
COMPONENT_EXPORT(NETWORK_CPP)
|
||||
extern const base::Feature kStrictAccessControlAllowListCheck;
|
||||
COMPONENT_EXPORT(NETWORK_CPP)
|
||||
extern const base::Feature kCertVerifierService;
|
||||
|
||||
COMPONENT_EXPORT(NETWORK_CPP)
|
||||
extern const base::Feature kTrustTokens;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "services/network/test/test_network_context_client.h"
|
||||
#include "services/network/test/test_network_service_client.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -592,6 +593,12 @@ class SimpleURLLoaderTestBase {
|
||||
network_service_remote.BindNewPipeAndPassReceiver());
|
||||
network::mojom::NetworkContextParamsPtr context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
|
||||
network_service_remote->CreateNetworkContext(
|
||||
network_context_.BindNewPipeAndPassReceiver(),
|
||||
std::move(context_params));
|
||||
|
@ -6,6 +6,7 @@ module cert_verifier.mojom;
|
||||
|
||||
import "mojo/public/mojom/base/big_buffer.mojom";
|
||||
import "services/network/public/mojom/network_param.mojom";
|
||||
import "services/network/public/mojom/url_loader_factory.mojom";
|
||||
|
||||
// Mojo version of net::CertVerifier::RequestParams.
|
||||
struct RequestParams {
|
||||
@ -27,10 +28,27 @@ struct CertVerifierConfig {
|
||||
array<network.mojom.X509Certificate> additional_trust_anchors;
|
||||
};
|
||||
|
||||
// Allows the CertVerifierService to connect a new URLLoaderFactory if its
|
||||
// existing URLLoaderFactory is disconnected. The CertVerifierService uses the
|
||||
// URLLoaderFactory for AIA and OCSP fetching.
|
||||
interface URLLoaderFactoryConnector {
|
||||
// Binds a URLLoaderFactory.
|
||||
CreateURLLoaderFactory(
|
||||
pending_receiver<network.mojom.URLLoaderFactory> url_loader_factory);
|
||||
};
|
||||
|
||||
// An interface that verifies a certificate based on the |params|, and calls the
|
||||
// |Complete| method on the returned CertVerifierRequest when the result is
|
||||
// available.
|
||||
interface CertVerifierService {
|
||||
// |url_loader_factory| allows the CertVerifierService to connect to the
|
||||
// network for things like AIA or OCSP. |reconnector| allows the CertVerifier
|
||||
// to reconnect its URLLoaderFactory in case the network service disconnects
|
||||
// its URLLoaderFactories without crashing. Must be called before Verify() to
|
||||
// have an effect.
|
||||
EnableNetworkAccess(
|
||||
pending_remote<network.mojom.URLLoaderFactory> url_loader_factory,
|
||||
pending_remote<URLLoaderFactoryConnector>? reconnector);
|
||||
// Mojo IPC used to verify a certificate. Sends results to the
|
||||
// |cert_verifier_request| interface when verification is complete.
|
||||
Verify(RequestParams params,
|
||||
|
@ -11,7 +11,7 @@ import "mojo/public/mojom/base/time.mojom";
|
||||
import "mojo/public/mojom/base/unguessable_token.mojom";
|
||||
import "mojo/public/mojom/base/values.mojom";
|
||||
import "services/network/public/mojom/address_list.mojom";
|
||||
import "services/network/public/mojom/parsed_headers.mojom";
|
||||
import "services/network/public/mojom/cert_verifier_service.mojom";
|
||||
import "services/network/public/mojom/cookie_access_observer.mojom";
|
||||
import "services/network/public/mojom/cookie_manager.mojom";
|
||||
import "services/network/public/mojom/default_credentials.mojom";
|
||||
@ -29,6 +29,7 @@ import "services/network/public/mojom/network_isolation_key.mojom";
|
||||
import "services/network/public/mojom/isolation_info.mojom";
|
||||
import "services/network/public/mojom/network_param.mojom";
|
||||
import "services/network/public/mojom/origin_policy_manager.mojom";
|
||||
import "services/network/public/mojom/parsed_headers.mojom";
|
||||
import "services/network/public/mojom/p2p.mojom";
|
||||
import "services/network/public/mojom/p2p_trusted.mojom";
|
||||
import "services/network/public/mojom/proxy_config.mojom";
|
||||
@ -123,6 +124,21 @@ struct CertVerifierCreationParams {
|
||||
TrialComparisonCertVerifierParams? trial_comparison_cert_verifier_params;
|
||||
};
|
||||
|
||||
// Includes a pipe to a CertVerifierService for usage by the
|
||||
// NetworkContext.
|
||||
struct CertVerifierServiceRemoteParams {
|
||||
// A pipe to the CertVerifierService.
|
||||
pending_remote<cert_verifier.mojom.CertVerifierService>?
|
||||
cert_verifier_service;
|
||||
};
|
||||
|
||||
// Contains the parameters necessary to either connect to a CertVerifierService
|
||||
// or create a net::CertVerifier in the network service itself.
|
||||
union CertVerifierParams {
|
||||
CertVerifierServiceRemoteParams remote_params;
|
||||
CertVerifierCreationParams creation_params;
|
||||
};
|
||||
|
||||
// Client to update the custom proxy config.
|
||||
interface CustomProxyConfigClient {
|
||||
OnCustomProxyConfigUpdated(CustomProxyConfig proxy_config);
|
||||
@ -373,8 +389,9 @@ struct NetworkContextParams {
|
||||
[EnableIf=is_ct_supported]
|
||||
mojo_base.mojom.Time ct_log_update_time;
|
||||
|
||||
// Contains the parameters used to instantiate a net::CertVerifier in-process.
|
||||
CertVerifierCreationParams? cert_verifier_creation_params;
|
||||
// Contains either a pipe to a CertVerifierService, or parameters used to
|
||||
// instantiate a net::CertVerifier in-process.
|
||||
CertVerifierParams? cert_verifier_params;
|
||||
|
||||
// Initial additional certificates that will be used for certificate
|
||||
// validation.
|
||||
|
@ -18,11 +18,22 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace network {
|
||||
namespace {
|
||||
|
||||
mojom::NetworkContextParamsPtr CreateNetworkContextParams() {
|
||||
auto context_params = mojom::NetworkContextParams::New();
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test CertVerifier behavior.
|
||||
context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
return context_params;
|
||||
}
|
||||
|
||||
// We don't use mojo::BlockingCopyToString because it leads to deadlocks.
|
||||
std::string Read(mojo::ScopedDataPipeConsumerHandle readable) {
|
||||
std::string output;
|
||||
@ -194,7 +205,7 @@ class QuicTransportTest : public testing::Test {
|
||||
network_context_remote_(mojo::NullRemote()),
|
||||
network_context_(network_service_.get(),
|
||||
network_context_remote_.BindNewPipeAndPassReceiver(),
|
||||
mojom::NetworkContextParams::New()),
|
||||
CreateNetworkContextParams()),
|
||||
server_(/* port= */ 0,
|
||||
{origin_},
|
||||
quic::test::crypto_test_utils::ProofSourceForTesting()) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "services/network/ssl_config_service_mojo.h"
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/stl_util.h"
|
||||
@ -28,8 +29,10 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "services/network/network_context.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "services/network/public/mojom/ssl_config.mojom.h"
|
||||
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -156,6 +159,12 @@ class NetworkServiceSSLConfigServiceTest : public testing::Test {
|
||||
// stores it in |network_context_|.
|
||||
void SetUpNetworkContext(
|
||||
mojom::NetworkContextParamsPtr network_context_params) {
|
||||
// Use a dummy CertVerifier that always passes cert verification, since
|
||||
// these unittests don't need to test the behavior of a real CertVerifier.
|
||||
// There are a parallel set of tests in services/cert_verifier/ that *do*
|
||||
// test CertVerifier behavior.
|
||||
network_context_params->cert_verifier_params =
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
|
||||
ssl_config_client_.reset();
|
||||
network_context_params->ssl_config_client_receiver =
|
||||
ssl_config_client_.BindNewPipeAndPassReceiver();
|
||||
@ -489,66 +498,5 @@ TEST_F(NetworkServiceSSLConfigServiceTest, CanShareConnectionWithClientCerts) {
|
||||
config_service->CanShareConnectionWithClientCerts("example.net"));
|
||||
}
|
||||
|
||||
#if !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
TEST_F(NetworkServiceSSLConfigServiceTest, CRLSetIsApplied) {
|
||||
SetUpNetworkContext(mojom::NetworkContextParams::New());
|
||||
|
||||
SSLConfigServiceMojo* config_service = static_cast<SSLConfigServiceMojo*>(
|
||||
network_context_->url_request_context()->ssl_config_service());
|
||||
|
||||
scoped_refptr<net::X509Certificate> root_cert =
|
||||
net::CreateCertificateChainFromFile(
|
||||
net::GetTestCertsDirectory(), "root_ca_cert.pem",
|
||||
net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
|
||||
ASSERT_TRUE(root_cert);
|
||||
net::ScopedTestRoot test_root(root_cert.get());
|
||||
|
||||
scoped_refptr<net::X509Certificate> cert =
|
||||
net::CreateCertificateChainFromFile(
|
||||
net::GetTestCertsDirectory(), "ok_cert.pem",
|
||||
net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
|
||||
ASSERT_TRUE(cert);
|
||||
|
||||
// Ensure that |cert| is trusted without any CRLSet explicitly configured.
|
||||
net::TestCompletionCallback callback1;
|
||||
net::CertVerifyResult cert_verify_result1;
|
||||
std::unique_ptr<net::CertVerifier::Request> request1;
|
||||
int result = network_context_->url_request_context()->cert_verifier()->Verify(
|
||||
net::CertVerifier::RequestParams(cert, "127.0.0.1",
|
||||
/*flags=*/0,
|
||||
/*ocsp_response=*/std::string(),
|
||||
/*sct_list=*/std::string()),
|
||||
&cert_verify_result1, callback1.callback(), &request1,
|
||||
net::NetLogWithSource());
|
||||
ASSERT_THAT(callback1.GetResult(result), net::test::IsOk());
|
||||
|
||||
// Configure an explicit CRLSet that removes trust in |leaf_cert| by SPKI.
|
||||
base::StringPiece spki;
|
||||
ASSERT_TRUE(net::asn1::ExtractSPKIFromDERCert(
|
||||
net::x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()),
|
||||
&spki));
|
||||
net::SHA256HashValue spki_sha256;
|
||||
crypto::SHA256HashString(spki, spki_sha256.data, sizeof(spki_sha256.data));
|
||||
|
||||
config_service->OnNewCRLSet(net::CRLSet::ForTesting(
|
||||
false, &spki_sha256, cert->serial_number(), "", {}));
|
||||
|
||||
// Ensure that |cert| is revoked, due to the CRLSet being applied.
|
||||
net::TestCompletionCallback callback2;
|
||||
net::CertVerifyResult cert_verify_result2;
|
||||
std::unique_ptr<net::CertVerifier::Request> request2;
|
||||
result = network_context_->url_request_context()->cert_verifier()->Verify(
|
||||
net::CertVerifier::RequestParams(cert, "127.0.0.1",
|
||||
/*flags=*/0,
|
||||
/*ocsp_response=*/std::string(),
|
||||
/*sct_list=*/std::string()),
|
||||
&cert_verify_result2, callback2.callback(), &request2,
|
||||
net::NetLogWithSource());
|
||||
ASSERT_THAT(callback2.GetResult(result),
|
||||
net::test::IsError(net::ERR_CERT_REVOKED));
|
||||
}
|
||||
|
||||
#endif // !defined(OS_IOS) && !defined(OS_ANDROID)
|
||||
|
||||
} // namespace
|
||||
} // namespace network
|
||||
|
@ -0,0 +1,53 @@
|
||||
// Copyright 2020 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 "services/network/test/fake_test_cert_verifier_params_factory.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/cert/cert_verify_result.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
FakeTestCertVerifierParamsFactory::FakeTestCertVerifierParamsFactory() =
|
||||
default;
|
||||
FakeTestCertVerifierParamsFactory::~FakeTestCertVerifierParamsFactory() =
|
||||
default;
|
||||
|
||||
// static
|
||||
mojom::CertVerifierParamsPtr
|
||||
FakeTestCertVerifierParamsFactory::GetCertVerifierParams() {
|
||||
if (!base::FeatureList::IsEnabled(network::features::kCertVerifierService)) {
|
||||
return mojom::CertVerifierParams::NewCreationParams(
|
||||
mojom::CertVerifierCreationParams::New());
|
||||
}
|
||||
|
||||
auto remote_params = mojom::CertVerifierServiceRemoteParams::New();
|
||||
mojo::PendingRemote<cert_verifier::mojom::CertVerifierService> cv_remote;
|
||||
mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<FakeTestCertVerifierParamsFactory>(),
|
||||
cv_remote.InitWithNewPipeAndPassReceiver());
|
||||
remote_params->cert_verifier_service = std::move(cv_remote);
|
||||
return mojom::CertVerifierParams::NewRemoteParams(std::move(remote_params));
|
||||
}
|
||||
|
||||
void FakeTestCertVerifierParamsFactory::Verify(
|
||||
const ::net::CertVerifier::RequestParams& params,
|
||||
mojo::PendingRemote<cert_verifier::mojom::CertVerifierRequest>
|
||||
cert_verifier_request) {
|
||||
mojo::Remote<cert_verifier::mojom::CertVerifierRequest> request(
|
||||
std::move(cert_verifier_request));
|
||||
net::CertVerifyResult result;
|
||||
result.verified_cert = params.certificate();
|
||||
request->Complete(std::move(result), net::OK);
|
||||
}
|
||||
} // namespace network
|
@ -0,0 +1,43 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
#ifndef SERVICES_NETWORK_TEST_FAKE_TEST_CERT_VERIFIER_PARAMS_FACTORY_H_
|
||||
#define SERVICES_NETWORK_TEST_FAKE_TEST_CERT_VERIFIER_PARAMS_FACTORY_H_
|
||||
|
||||
#include "net/cert/cert_verifier.h"
|
||||
#include "services/network/public/mojom/cert_verifier_service.mojom-forward.h"
|
||||
#include "services/network/public/mojom/network_context.mojom-forward.h"
|
||||
|
||||
namespace network {
|
||||
|
||||
// FakeTestCertVerifierParamsFactory::GetCertVerifierParams returns a
|
||||
// mojom::CertVerifierParamsPtr, which either contains the parameters for a real
|
||||
// in-network-service CertVerifier, or contains a pipe to a fake
|
||||
// CertVerifierService that successfully verifies every certificate, even
|
||||
// invalid ones. This is useful for tests that need to set up a NetworkContext,
|
||||
// which requires CertVerifierParams, but the test doesn't actually need to test
|
||||
// cert verifier behavior.
|
||||
class FakeTestCertVerifierParamsFactory
|
||||
: public cert_verifier::mojom::CertVerifierService {
|
||||
public:
|
||||
FakeTestCertVerifierParamsFactory();
|
||||
~FakeTestCertVerifierParamsFactory() override;
|
||||
|
||||
static mojom::CertVerifierParamsPtr GetCertVerifierParams();
|
||||
|
||||
private:
|
||||
// cert_verifier::mojom::CertVerifierService implementation:
|
||||
void Verify(const net::CertVerifier::RequestParams& params,
|
||||
mojo::PendingRemote<cert_verifier::mojom::CertVerifierRequest>
|
||||
cert_verifier_request) override;
|
||||
void SetConfig(const net::CertVerifier::Config& config) override {}
|
||||
void EnableNetworkAccess(
|
||||
mojo::PendingRemote<mojom::URLLoaderFactory>,
|
||||
mojo::PendingRemote<cert_verifier::mojom::URLLoaderFactoryConnector>
|
||||
reconnector) override {}
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
|
||||
#endif // SERVICES_NETWORK_TEST_FAKE_TEST_CERT_VERIFIER_PARAMS_FACTORY_H_
|
@ -14,8 +14,10 @@
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/network_service_instance.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
|
||||
#include "weblayer/browser/safe_browsing/safe_browsing_navigation_throttle.h"
|
||||
@ -29,6 +31,8 @@ network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams(
|
||||
const std::string& user_agent) {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
network_context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
network_context_params->user_agent = user_agent;
|
||||
return network_context_params;
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams(
|
||||
const std::string& user_agent) {
|
||||
network::mojom::NetworkContextParamsPtr network_context_params =
|
||||
network::mojom::NetworkContextParams::New();
|
||||
network_context_params->cert_verifier_params = content::GetCertVerifierParams(
|
||||
network::mojom::CertVerifierCreationParams::New());
|
||||
ConfigureDefaultNetworkContextParams(network_context_params.get(),
|
||||
user_agent);
|
||||
variations::UpdateCorsExemptHeaderForVariations(network_context_params.get());
|
||||
|
Reference in New Issue
Block a user