summaryrefslogtreecommitdiff
path: root/chromium/services/cert_verifier
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/services/cert_verifier')
-rw-r--r--chromium/services/cert_verifier/BUILD.gn6
-rw-r--r--chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_test.cc3
-rw-r--r--chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc71
-rw-r--r--chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h18
-rw-r--r--chromium/services/cert_verifier/cert_verifier_service.cc33
-rw-r--r--chromium/services/cert_verifier/cert_verifier_service.h14
-rw-r--r--chromium/services/cert_verifier/cert_verifier_service_factory.cc75
-rw-r--r--chromium/services/cert_verifier/cert_verifier_service_factory.h21
-rw-r--r--chromium/services/cert_verifier/cert_verifier_service_factory_unittest.cc168
-rw-r--r--chromium/services/cert_verifier/integration_tests/DEPS3
-rw-r--r--chromium/services/cert_verifier/integration_tests/network_context_unittest.cc287
-rw-r--r--chromium/services/cert_verifier/integration_tests/network_service_unittest.cc479
-rw-r--r--chromium/services/cert_verifier/integration_tests/ssl_config_service_mojo_unittest.cc201
-rw-r--r--chromium/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom14
-rw-r--r--chromium/services/cert_verifier/test_cert_verifier_service_factory.cc12
-rw-r--r--chromium/services/cert_verifier/test_cert_verifier_service_factory.h6
16 files changed, 1119 insertions, 292 deletions
diff --git a/chromium/services/cert_verifier/BUILD.gn b/chromium/services/cert_verifier/BUILD.gn
index c3a2a899cd6..65d56915897 100644
--- a/chromium/services/cert_verifier/BUILD.gn
+++ b/chromium/services/cert_verifier/BUILD.gn
@@ -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",
]
diff --git a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_test.cc b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_test.cc
index 7e198036355..70ef0ff8a2c 100644
--- a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_test.cc
+++ b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_test.cc
@@ -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,
diff --git a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
index 10af79f7d33..91e3c981d96 100644
--- a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
+++ b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
@@ -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;
}
diff --git a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h
index f273a527adc..ae99c772aec 100644
--- a/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h
+++ b/chromium/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h
@@ -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,
diff --git a/chromium/services/cert_verifier/cert_verifier_service.cc b/chromium/services/cert_verifier/cert_verifier_service.cc
index 344805da6f4..8d1f932c136 100644
--- a/chromium/services/cert_verifier/cert_verifier_service.cc
+++ b/chromium/services/cert_verifier/cert_verifier_service.cc
@@ -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.
diff --git a/chromium/services/cert_verifier/cert_verifier_service.h b/chromium/services/cert_verifier/cert_verifier_service.h
index cfaeec51af2..c4492b8648d 100644
--- a/chromium/services/cert_verifier/cert_verifier_service.h
+++ b/chromium/services/cert_verifier/cert_verifier_service.h
@@ -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
diff --git a/chromium/services/cert_verifier/cert_verifier_service_factory.cc b/chromium/services/cert_verifier/cert_verifier_service_factory.cc
index 33183453138..74abd3e07f0 100644
--- a/chromium/services/cert_verifier/cert_verifier_service_factory.cc
+++ b/chromium/services/cert_verifier/cert_verifier_service_factory.cc
@@ -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
diff --git a/chromium/services/cert_verifier/cert_verifier_service_factory.h b/chromium/services/cert_verifier/cert_verifier_service_factory.h
index 373417afe3e..875862ea5ac 100644
--- a/chromium/services/cert_verifier/cert_verifier_service_factory.h
+++ b/chromium/services/cert_verifier/cert_verifier_service_factory.h
@@ -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_;
};
diff --git a/chromium/services/cert_verifier/cert_verifier_service_factory_unittest.cc b/chromium/services/cert_verifier/cert_verifier_service_factory_unittest.cc
index 9d44bfdb3bf..b19e5372239 100644
--- a/chromium/services/cert_verifier/cert_verifier_service_factory_unittest.cc
+++ b/chromium/services/cert_verifier/cert_verifier_service_factory_unittest.cc
@@ -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()});
-
- // 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(CertVerifierServiceFactoryTest, GetNewCertVerifier) {
+ base::test::TaskEnvironment task_environment;
-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;
diff --git a/chromium/services/cert_verifier/integration_tests/DEPS b/chromium/services/cert_verifier/integration_tests/DEPS
new file mode 100644
index 00000000000..288ba20350c
--- /dev/null
+++ b/chromium/services/cert_verifier/integration_tests/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+services/network"
+]
diff --git a/chromium/services/cert_verifier/integration_tests/network_context_unittest.cc b/chromium/services/cert_verifier/integration_tests/network_context_unittest.cc
new file mode 100644
index 00000000000..98483552717
--- /dev/null
+++ b/chromium/services/cert_verifier/integration_tests/network_context_unittest.cc
@@ -0,0 +1,287 @@
+// 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()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kCertVerifierService);
+ } 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_) {
+ enabled_features.push_back(network::features::kCertVerifierService);
+ } 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
diff --git a/chromium/services/cert_verifier/integration_tests/network_service_unittest.cc b/chromium/services/cert_verifier/integration_tests/network_service_unittest.cc
new file mode 100644
index 00000000000..1ce0aa5c0aa
--- /dev/null
+++ b/chromium/services/cert_verifier/integration_tests/network_service_unittest.cc
@@ -0,0 +1,479 @@
+// 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()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kCertVerifierService);
+ } 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
diff --git a/chromium/services/cert_verifier/integration_tests/ssl_config_service_mojo_unittest.cc b/chromium/services/cert_verifier/integration_tests/ssl_config_service_mojo_unittest.cc
new file mode 100644
index 00000000000..5b100c8c3e8
--- /dev/null
+++ b/chromium/services/cert_verifier/integration_tests/ssl_config_service_mojo_unittest.cc
@@ -0,0 +1,201 @@
+// 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()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kCertVerifierService);
+ } 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
diff --git a/chromium/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom b/chromium/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom
index dc15c52a0b5..c9eda673a7f 100644
--- a/chromium/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom
+++ b/chromium/services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom
@@ -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);
-};
diff --git a/chromium/services/cert_verifier/test_cert_verifier_service_factory.cc b/chromium/services/cert_verifier/test_cert_verifier_service_factory.cc
index a851f76ccce..f06f4365824 100644
--- a/chromium/services/cert_verifier/test_cert_verifier_service_factory.cc
+++ b/chromium/services/cert_verifier/test_cert_verifier_service_factory.cc
@@ -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() {
diff --git a/chromium/services/cert_verifier/test_cert_verifier_service_factory.h b/chromium/services/cert_verifier/test_cert_verifier_service_factory.h
index 70daa06be1f..3aa9ae2a69d 100644
--- a/chromium/services/cert_verifier/test_cert_verifier_service_factory.h
+++ b/chromium/services/cert_verifier/test_cert_verifier_service_factory.h
@@ -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