network_service_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include "base/feature_list.h"
  6. #include "base/files/file_util.h"
  7. #include "base/run_loop.h"
  8. #include "base/task/sequenced_task_runner.h"
  9. #include "base/task/task_traits.h"
  10. #include "base/test/bind.h"
  11. #include "base/test/scoped_feature_list.h"
  12. #include "base/test/task_environment.h"
  13. #include "build/build_config.h"
  14. #include "mojo/public/cpp/bindings/pending_remote.h"
  15. #include "net/base/test_completion_callback.h"
  16. #include "net/cert/asn1_util.h"
  17. #include "net/cert/test_root_certs.h"
  18. #include "net/cert/x509_util.h"
  19. #include "net/test/cert_test_util.h"
  20. #include "net/test/embedded_test_server/embedded_test_server.h"
  21. #include "net/test/gtest_util.h"
  22. #include "net/test/test_data_directory.h"
  23. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  24. #include "net/url_request/url_request_context.h"
  25. #include "services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.h"
  26. #include "services/cert_verifier/cert_verifier_service_factory.h"
  27. #include "services/network/network_context.h"
  28. #include "services/network/network_service.h"
  29. #include "services/network/public/cpp/cert_verifier/mojo_cert_verifier.h"
  30. #include "services/network/public/cpp/features.h"
  31. #include "services/network/public/cpp/resource_request.h"
  32. #include "services/network/public/mojom/cert_verifier_service.mojom.h"
  33. #include "services/network/public/mojom/network_context.mojom.h"
  34. #include "services/network/ssl_config_service_mojo.h"
  35. #include "services/network/test/fake_test_cert_verifier_params_factory.h"
  36. #include "services/network/test/test_url_loader_client.h"
  37. #include "testing/gtest/include/gtest/gtest.h"
  38. #include "url/gurl.h"
  39. namespace cert_verifier {
  40. namespace {
  41. const base::FilePath::CharType kServicesTestData[] =
  42. FILE_PATH_LITERAL("services/test/data");
  43. } // namespace
  44. // Base class for any tests that just need a NetworkService and a
  45. // TaskEnvironment, and to create NetworkContexts using the NetworkService.
  46. class NetworkServiceIntegrationTest : public testing::Test {
  47. public:
  48. NetworkServiceIntegrationTest()
  49. : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
  50. service_(network::NetworkService::CreateForTesting()),
  51. cert_verifier_service_impl_(
  52. cert_verifier_service_remote_.BindNewPipeAndPassReceiver()) {}
  53. ~NetworkServiceIntegrationTest() override = default;
  54. void DestroyService() { service_.reset(); }
  55. network::mojom::NetworkContextParamsPtr CreateNetworkContextParams() {
  56. mojo::PendingRemote<mojom::CertVerifierService> cv_service_remote;
  57. // Create a cert verifier service.
  58. cert_verifier_service_impl_.GetNewCertVerifierForTesting(
  59. cv_service_remote.InitWithNewPipeAndPassReceiver(),
  60. mojom::CertVerifierCreationParams::New(),
  61. &cert_net_fetcher_url_loader_);
  62. network::mojom::NetworkContextParamsPtr params =
  63. network::mojom::NetworkContextParams::New();
  64. params->cert_verifier_params =
  65. network::mojom::CertVerifierServiceRemoteParams::New(
  66. std::move(cv_service_remote));
  67. // Use a fixed proxy config, to avoid dependencies on local network
  68. // configuration.
  69. params->initial_proxy_config =
  70. net::ProxyConfigWithAnnotation::CreateDirect();
  71. return params;
  72. }
  73. void CreateNetworkContext(network::mojom::NetworkContextParamsPtr params) {
  74. network_context_ = std::make_unique<network::NetworkContext>(
  75. service_.get(), network_context_remote_.BindNewPipeAndPassReceiver(),
  76. std::move(params));
  77. }
  78. void LoadURL(const GURL& url,
  79. int options = network::mojom::kURLLoadOptionNone) {
  80. network::ResourceRequest request;
  81. request.url = url;
  82. request.method = "GET";
  83. request.request_initiator = url::Origin();
  84. StartLoadingURL(request, 0 /* process_id */, options);
  85. client_->RunUntilComplete();
  86. }
  87. void StartLoadingURL(const network::ResourceRequest& request,
  88. uint32_t process_id,
  89. int options = network::mojom::kURLLoadOptionNone) {
  90. client_ = std::make_unique<network::TestURLLoaderClient>();
  91. mojo::Remote<network::mojom::URLLoaderFactory> loader_factory;
  92. network::mojom::URLLoaderFactoryParamsPtr params =
  93. network::mojom::URLLoaderFactoryParams::New();
  94. params->process_id = process_id;
  95. params->is_corb_enabled = false;
  96. network_context_->CreateURLLoaderFactory(
  97. loader_factory.BindNewPipeAndPassReceiver(), std::move(params));
  98. loader_.reset();
  99. loader_factory->CreateLoaderAndStart(
  100. loader_.BindNewPipeAndPassReceiver(), 1, options, request,
  101. client_->CreateRemote(),
  102. net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
  103. }
  104. network::TestURLLoaderClient* client() { return client_.get(); }
  105. base::test::TaskEnvironment* task_environment() { return &task_environment_; }
  106. network::NetworkService* service() const { return service_.get(); }
  107. network::NetworkContext* network_context() { return network_context_.get(); }
  108. mojo::Remote<network::mojom::NetworkContext>& network_context_remote() {
  109. return network_context_remote_;
  110. }
  111. CertNetFetcherURLLoader* cert_net_fetcher_url_loader() {
  112. return cert_net_fetcher_url_loader_.get();
  113. }
  114. private:
  115. base::test::TaskEnvironment task_environment_;
  116. std::unique_ptr<network::NetworkService> service_;
  117. mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
  118. std::unique_ptr<network::NetworkContext> network_context_;
  119. mojo::Remote<mojom::CertVerifierServiceFactory> cert_verifier_service_remote_;
  120. CertVerifierServiceFactoryImpl cert_verifier_service_impl_;
  121. scoped_refptr<CertNetFetcherURLLoader> cert_net_fetcher_url_loader_;
  122. std::unique_ptr<network::TestURLLoaderClient> client_;
  123. mojo::Remote<network::mojom::URLLoader> loader_;
  124. };
  125. // CRLSets are not supported on iOS and Android system verifiers.
  126. #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
  127. class NetworkServiceCRLSetTest : public NetworkServiceIntegrationTest {
  128. public:
  129. NetworkServiceCRLSetTest()
  130. : test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
  131. ~NetworkServiceCRLSetTest() override = default;
  132. void SetUp() override {
  133. NetworkServiceIntegrationTest::SetUp();
  134. test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
  135. test_server_.AddDefaultHandlers(base::FilePath(kServicesTestData));
  136. ASSERT_TRUE(test_server_.Start());
  137. }
  138. GURL GetURL(std::string url) { return test_server_.GetURL(std::move(url)); }
  139. private:
  140. net::EmbeddedTestServer test_server_;
  141. };
  142. // Verifies CRLSets take effect if configured on the service.
  143. TEST_F(NetworkServiceCRLSetTest, CRLSetIsApplied) {
  144. CreateNetworkContext(CreateNetworkContextParams());
  145. uint32_t options =
  146. network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
  147. network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  148. // Make sure the test server loads fine with no CRLSet.
  149. LoadURL(GetURL("/echo"), options);
  150. ASSERT_EQ(net::OK, client()->completion_status().error_code);
  151. // Send a CRLSet that blocks the leaf cert.
  152. std::string crl_set_bytes;
  153. EXPECT_TRUE(base::ReadFileToString(
  154. net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
  155. &crl_set_bytes));
  156. {
  157. base::RunLoop run_loop;
  158. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  159. run_loop.QuitClosure());
  160. run_loop.Run();
  161. }
  162. // Flush all connections in the context, to force a new connection. A new
  163. // verification should be attempted, due to the configuration having
  164. // changed, thus forcing the CRLSet to be checked.
  165. {
  166. base::RunLoop run_loop;
  167. network_context()->CloseAllConnections(run_loop.QuitClosure());
  168. run_loop.Run();
  169. }
  170. // Make sure the connection fails, due to the certificate being revoked.
  171. LoadURL(GetURL("/echo"), options);
  172. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  173. client()->completion_status().error_code);
  174. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  175. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  176. net::CERT_STATUS_REVOKED);
  177. }
  178. // Verifies CRLSets configured before creating a new network context are
  179. // applied to that network context.
  180. TEST_F(NetworkServiceCRLSetTest, CRLSetIsPassedToNewContexts) {
  181. // Send a CRLSet that blocks the leaf cert, even while no NetworkContexts
  182. // exist.
  183. std::string crl_set_bytes;
  184. EXPECT_TRUE(base::ReadFileToString(
  185. net::GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
  186. &crl_set_bytes));
  187. base::RunLoop run_loop;
  188. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  189. run_loop.QuitClosure());
  190. run_loop.Run();
  191. // Configure a new NetworkContext.
  192. CreateNetworkContext(CreateNetworkContextParams());
  193. uint32_t options =
  194. network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
  195. network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  196. // Make sure the connection fails, due to the certificate being revoked.
  197. LoadURL(GetURL("/echo"), options);
  198. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  199. client()->completion_status().error_code);
  200. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  201. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  202. net::CERT_STATUS_REVOKED);
  203. }
  204. // Verifies newer CRLSets (by sequence number) are applied.
  205. TEST_F(NetworkServiceCRLSetTest, CRLSetIsUpdatedIfNewer) {
  206. // Send a CRLSet that only allows the root cert if it matches a known SPKI
  207. // hash (that matches the test server chain)
  208. std::string crl_set_bytes;
  209. ASSERT_TRUE(base::ReadFileToString(
  210. net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
  211. &crl_set_bytes));
  212. {
  213. base::RunLoop run_loop;
  214. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  215. run_loop.QuitClosure());
  216. run_loop.Run();
  217. }
  218. CreateNetworkContext(CreateNetworkContextParams());
  219. uint32_t options =
  220. network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
  221. network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  222. // Make sure the connection loads, due to the root being permitted.
  223. LoadURL(GetURL("/echo"), options);
  224. ASSERT_EQ(net::OK, client()->completion_status().error_code);
  225. // Send a new CRLSet that removes trust in the root.
  226. ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
  227. "crlset_by_root_subject_no_spki.raw"),
  228. &crl_set_bytes));
  229. {
  230. base::RunLoop run_loop;
  231. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  232. run_loop.QuitClosure());
  233. run_loop.Run();
  234. }
  235. // Flush all connections in the context, to force a new connection. A new
  236. // verification should be attempted, due to the configuration having
  237. // changed, thus forcing the CRLSet to be checked.
  238. {
  239. base::RunLoop run_loop;
  240. network_context()->CloseAllConnections(run_loop.QuitClosure());
  241. run_loop.Run();
  242. }
  243. // Make sure the connection fails, due to the certificate being revoked.
  244. LoadURL(GetURL("/echo"), options);
  245. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  246. client()->completion_status().error_code);
  247. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  248. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  249. net::CERT_STATUS_REVOKED);
  250. }
  251. // Verifies that attempting to send an older CRLSet (by sequence number)
  252. // does not apply to existing or new contexts.
  253. TEST_F(NetworkServiceCRLSetTest, CRLSetDoesNotDowngrade) {
  254. // Send a CRLSet that blocks the root certificate by subject name.
  255. std::string crl_set_bytes;
  256. ASSERT_TRUE(base::ReadFileToString(net::GetTestCertsDirectory().AppendASCII(
  257. "crlset_by_root_subject_no_spki.raw"),
  258. &crl_set_bytes));
  259. {
  260. base::RunLoop run_loop;
  261. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  262. run_loop.QuitClosure());
  263. run_loop.Run();
  264. }
  265. CreateNetworkContext(CreateNetworkContextParams());
  266. uint32_t options =
  267. network::mojom::kURLLoadOptionSendSSLInfoWithResponse |
  268. network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  269. // Make sure the connection fails, due to the certificate being revoked.
  270. LoadURL(GetURL("/echo"), options);
  271. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  272. client()->completion_status().error_code);
  273. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  274. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  275. net::CERT_STATUS_REVOKED);
  276. // Attempt to configure an older CRLSet that allowed trust in the root.
  277. ASSERT_TRUE(base::ReadFileToString(
  278. net::GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
  279. &crl_set_bytes));
  280. {
  281. base::RunLoop run_loop;
  282. service()->UpdateCRLSet(base::as_bytes(base::make_span(crl_set_bytes)),
  283. run_loop.QuitClosure());
  284. run_loop.Run();
  285. }
  286. // Flush all connections in the context, to force a new connection. A new
  287. // verification should be attempted, due to the configuration having
  288. // changed, thus forcing the CRLSet to be checked.
  289. {
  290. base::RunLoop run_loop;
  291. network_context()->CloseAllConnections(run_loop.QuitClosure());
  292. run_loop.Run();
  293. }
  294. // Make sure the connection still fails, due to the newer CRLSet still
  295. // applying.
  296. LoadURL(GetURL("/echo"), options);
  297. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  298. client()->completion_status().error_code);
  299. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  300. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  301. net::CERT_STATUS_REVOKED);
  302. // Create a new NetworkContext and ensure the latest CRLSet is still
  303. // applied.
  304. network_context_remote().reset();
  305. CreateNetworkContext(CreateNetworkContextParams());
  306. // The newer CRLSet that blocks the connection should still apply, even to
  307. // new NetworkContexts.
  308. LoadURL(GetURL("/echo"), options);
  309. EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
  310. client()->completion_status().error_code);
  311. ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  312. EXPECT_TRUE(client()->completion_status().ssl_info->cert_status &
  313. net::CERT_STATUS_REVOKED);
  314. }
  315. #endif // !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID)
  316. // TODO(crbug.com/860189): AIA tests fail on iOS
  317. #if BUILDFLAG(IS_IOS)
  318. #define MAYBE(test_name) DISABLED_##test_name
  319. #else
  320. #define MAYBE(test_name) test_name
  321. #endif
  322. class NetworkServiceAIATest : public NetworkServiceIntegrationTest {
  323. public:
  324. NetworkServiceAIATest() : test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
  325. ~NetworkServiceAIATest() override = default;
  326. void SetUp() override {
  327. NetworkServiceIntegrationTest::SetUp();
  328. network::mojom::NetworkContextParamsPtr context_params =
  329. CreateNetworkContextParams();
  330. CreateNetworkContext(std::move(context_params));
  331. net::EmbeddedTestServer::ServerCertificateConfig cert_config;
  332. cert_config.intermediate =
  333. net::EmbeddedTestServer::IntermediateType::kByAIA;
  334. test_server_.SetSSLConfig(cert_config);
  335. test_server_.AddDefaultHandlers(base::FilePath(kServicesTestData));
  336. ASSERT_TRUE(test_server_.Start());
  337. }
  338. void PerformAIATest() {
  339. LoadURL(test_server_.GetURL("/echo"),
  340. network::mojom::kURLLoadOptionSendSSLInfoWithResponse);
  341. EXPECT_EQ(net::OK, client()->completion_status().error_code);
  342. ASSERT_TRUE(client()->response_head());
  343. EXPECT_EQ(0u, client()->response_head()->cert_status &
  344. net::CERT_STATUS_ALL_ERRORS);
  345. ASSERT_TRUE(client()->ssl_info());
  346. ASSERT_TRUE(client()->ssl_info()->cert);
  347. EXPECT_EQ(2u, client()->ssl_info()->cert->intermediate_buffers().size());
  348. ASSERT_TRUE(client()->ssl_info()->unverified_cert);
  349. EXPECT_EQ(
  350. 0u,
  351. client()->ssl_info()->unverified_cert->intermediate_buffers().size());
  352. }
  353. private:
  354. net::EmbeddedTestServer test_server_;
  355. };
  356. TEST_F(NetworkServiceAIATest, MAYBE(AIAFetching)) {
  357. PerformAIATest();
  358. }
  359. // Check that AIA fetching still succeeds even after the URLLoaderFactory
  360. // backing the CertNetFetcherURLLoader disconnects.
  361. // Only relevant if testing with the CertVerifierService, and the underlying
  362. // CertVerifier uses the CertNetFetcher.
  363. TEST_F(NetworkServiceAIATest,
  364. MAYBE(AIAFetchingWithURLLoaderFactoryDisconnect)) {
  365. if (!cert_net_fetcher_url_loader()) {
  366. // TODO(crbug.com/1015706): Switch to GTEST_SKIP().
  367. LOG(WARNING) << "Skipping AIA reconnection test because the underlying "
  368. "cert verifier does not use a CertNetFetcherURLLoader.";
  369. return;
  370. }
  371. PerformAIATest();
  372. // Disconnect the URLLoaderFactory used by the CertNetFetcherURLLoader.
  373. cert_net_fetcher_url_loader()->DisconnectURLLoaderFactoryForTesting();
  374. // Try running the test again to test reconnection of the
  375. // CertNetFetcherURLLoader.
  376. PerformAIATest();
  377. // Repeat one more time to be sure.
  378. cert_net_fetcher_url_loader()->DisconnectURLLoaderFactoryForTesting();
  379. PerformAIATest();
  380. }
  381. } // namespace cert_verifier