1 // Copyright 2018 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 
5 #include "services/network/ssl_config_service_mojo.h"
6 
7 #include "base/feature_list.h"
8 #include "base/files/file_util.h"
9 #include "base/run_loop.h"
10 #include "base/stl_util.h"
11 #include "base/test/task_environment.h"
12 #include "build/build_config.h"
13 #include "crypto/sha2.h"
14 #include "mojo/public/cpp/bindings/remote.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/cert/asn1_util.h"
17 #include "net/cert/cert_verifier.h"
18 #include "net/cert/cert_verify_result.h"
19 #include "net/cert/crl_set.h"
20 #include "net/cert/test_root_certs.h"
21 #include "net/cert/x509_certificate.h"
22 #include "net/cert/x509_util.h"
23 #include "net/log/net_log_with_source.h"
24 #include "net/ssl/ssl_config.h"
25 #include "net/ssl/ssl_config_service.h"
26 #include "net/test/cert_test_util.h"
27 #include "net/test/gtest_util.h"
28 #include "net/test/test_data_directory.h"
29 #include "net/url_request/url_request_context.h"
30 #include "services/network/network_context.h"
31 #include "services/network/network_service.h"
32 #include "services/network/public/cpp/features.h"
33 #include "services/network/public/mojom/network_service.mojom.h"
34 #include "services/network/public/mojom/ssl_config.mojom.h"
35 #include "services/network/test/fake_test_cert_verifier_params_factory.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 
39 namespace network {
40 namespace {
41 
42 class TestSSLConfigServiceObserver : public net::SSLConfigService::Observer {
43  public:
TestSSLConfigServiceObserver(net::SSLConfigService * ssl_config_service)44   explicit TestSSLConfigServiceObserver(
45       net::SSLConfigService* ssl_config_service)
46       : ssl_config_service_(ssl_config_service) {
47     ssl_config_service_->AddObserver(this);
48   }
49 
~TestSSLConfigServiceObserver()50   ~TestSSLConfigServiceObserver() override {
51     EXPECT_EQ(observed_changes_, changes_to_wait_for_);
52     ssl_config_service_->RemoveObserver(this);
53   }
54 
55   // net::SSLConfigService::Observer implementation:
OnSSLContextConfigChanged()56   void OnSSLContextConfigChanged() override {
57     ++observed_changes_;
58     ssl_context_config_during_change_ =
59         ssl_config_service_->GetSSLContextConfig();
60     if (run_loop_)
61       run_loop_->Quit();
62   }
63 
64   // Waits for a SSLContextConfig change. The first time it's called, waits for
65   // the first change, if one hasn't been observed already, the second time,
66   // waits for the second, etc. Must be called once for each change that
67   // happens, and fails if more than once change happens between calls, or
68   // during a call.
WaitForChange()69   void WaitForChange() {
70     EXPECT_FALSE(run_loop_);
71     ++changes_to_wait_for_;
72     if (changes_to_wait_for_ == observed_changes_)
73       return;
74     EXPECT_LT(observed_changes_, changes_to_wait_for_);
75 
76     run_loop_ = std::make_unique<base::RunLoop>();
77     run_loop_->Run();
78     run_loop_.reset();
79     EXPECT_EQ(observed_changes_, changes_to_wait_for_);
80   }
81 
ssl_context_config_during_change() const82   const net::SSLContextConfig& ssl_context_config_during_change() const {
83     return ssl_context_config_during_change_;
84   }
85 
observed_changes() const86   int observed_changes() const { return observed_changes_; }
87 
88  private:
89   net::SSLConfigService* const ssl_config_service_;
90   int observed_changes_ = 0;
91   int changes_to_wait_for_ = 0;
92   net::SSLContextConfig ssl_context_config_during_change_;
93   std::unique_ptr<base::RunLoop> run_loop_;
94 };
95 
96 class TestCertVerifierConfigObserver : public net::CertVerifier {
97  public:
98   TestCertVerifierConfigObserver() = default;
~TestCertVerifierConfigObserver()99   ~TestCertVerifierConfigObserver() override {
100     EXPECT_EQ(observed_changes_, changes_to_wait_for_);
101   }
102 
103   // CertVerifier implementation:
Verify(const net::CertVerifier::RequestParams & params,net::CertVerifyResult * verify_result,net::CompletionOnceCallback callback,std::unique_ptr<net::CertVerifier::Request> * out_req,const net::NetLogWithSource & net_log)104   int Verify(const net::CertVerifier::RequestParams& params,
105              net::CertVerifyResult* verify_result,
106              net::CompletionOnceCallback callback,
107              std::unique_ptr<net::CertVerifier::Request>* out_req,
108              const net::NetLogWithSource& net_log) override {
109     ADD_FAILURE() << "Verify should not be called by tests";
110     return net::ERR_FAILED;
111   }
SetConfig(const Config & config)112   void SetConfig(const Config& config) override {
113     ++observed_changes_;
114     verifier_config_during_change_ = config;
115     if (run_loop_)
116       run_loop_->Quit();
117   }
118 
119   // Waits for a SSLConfig change. The first time it's called, waits for the
120   // first change, if one hasn't been observed already, the second time, waits
121   // for the second, etc. Must be called once for each change that happens, and
122   // fails it more than once change happens between calls, or during a call.
WaitForChange()123   void WaitForChange() {
124     EXPECT_FALSE(run_loop_);
125     ++changes_to_wait_for_;
126     if (changes_to_wait_for_ == observed_changes_)
127       return;
128     EXPECT_LT(observed_changes_, changes_to_wait_for_);
129 
130     run_loop_ = std::make_unique<base::RunLoop>();
131     run_loop_->Run();
132     run_loop_.reset();
133     EXPECT_EQ(observed_changes_, changes_to_wait_for_);
134   }
135 
verifier_config_during_change() const136   const net::CertVerifier::Config& verifier_config_during_change() const {
137     return verifier_config_during_change_;
138   }
139 
observed_changes() const140   int observed_changes() const { return observed_changes_; }
141 
142  private:
143   int observed_changes_ = 0;
144   int changes_to_wait_for_ = 0;
145   net::CertVerifier::Config verifier_config_during_change_;
146   std::unique_ptr<base::RunLoop> run_loop_;
147 };
148 
149 class NetworkServiceSSLConfigServiceTest : public testing::Test {
150  public:
NetworkServiceSSLConfigServiceTest()151   NetworkServiceSSLConfigServiceTest()
152       : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
153         network_service_(NetworkService::CreateForTesting()) {}
~NetworkServiceSSLConfigServiceTest()154   ~NetworkServiceSSLConfigServiceTest() override {
155     NetworkContext::SetCertVerifierForTesting(nullptr);
156   }
157 
158   // Creates a NetworkContext using the specified NetworkContextParams, and
159   // stores it in |network_context_|.
SetUpNetworkContext(mojom::NetworkContextParamsPtr network_context_params)160   void SetUpNetworkContext(
161       mojom::NetworkContextParamsPtr network_context_params) {
162     // Use a dummy CertVerifier that always passes cert verification, since
163     // these unittests don't need to test the behavior of a real CertVerifier.
164     // There are a parallel set of tests in services/cert_verifier/ that *do*
165     // test CertVerifier behavior.
166     network_context_params->cert_verifier_params =
167         FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
168     ssl_config_client_.reset();
169     network_context_params->ssl_config_client_receiver =
170         ssl_config_client_.BindNewPipeAndPassReceiver();
171     network_context_remote_.reset();
172     network_context_ = std::make_unique<NetworkContext>(
173         network_service_.get(),
174         network_context_remote_.BindNewPipeAndPassReceiver(),
175         std::move(network_context_params));
176   }
177 
178   // Returns the current SSLContextConfig for |network_context_|.
GetSSLContextConfig()179   net::SSLContextConfig GetSSLContextConfig() {
180     return network_context_->url_request_context()
181         ->ssl_config_service()
182         ->GetSSLContextConfig();
183   }
184 
185   // Runs two conversion tests for |mojo_config|.  Uses it as a initial
186   // SSLConfig for a NetworkContext, making sure it matches
187   // |expected_net_config|. Then switches to the default configuration and then
188   // back to |mojo_config|, to make sure it works as a new configuration. The
189   // expected configuration must not be the default configuration.
RunConversionTests(const mojom::SSLConfig & mojo_config,const net::SSLContextConfig & expected_net_config)190   void RunConversionTests(const mojom::SSLConfig& mojo_config,
191                           const net::SSLContextConfig& expected_net_config) {
192     // The expected configuration must not be the default configuration, or the
193     // change test won't send an event.
194     EXPECT_FALSE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
195         net::SSLContextConfig(), expected_net_config));
196 
197     // Set up |mojo_config| as the initial configuration of a NetworkContext.
198     mojom::NetworkContextParamsPtr network_context_params =
199         mojom::NetworkContextParams::New();
200     network_context_params->initial_ssl_config = mojo_config.Clone();
201     SetUpNetworkContext(std::move(network_context_params));
202     EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
203         GetSSLContextConfig(), expected_net_config));
204     // Sanity check.
205     EXPECT_FALSE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
206         GetSSLContextConfig(), net::SSLContextConfig()));
207 
208     // Reset the configuration to the default ones, and check the results.
209     TestSSLConfigServiceObserver observer(
210         network_context_->url_request_context()->ssl_config_service());
211     ssl_config_client_->OnSSLConfigUpdated(mojom::SSLConfig::New());
212     observer.WaitForChange();
213     EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
214         GetSSLContextConfig(), net::SSLContextConfig()));
215     EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
216         observer.ssl_context_config_during_change(), net::SSLContextConfig()));
217     // Sanity check.
218     EXPECT_FALSE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
219         GetSSLContextConfig(), expected_net_config));
220 
221     // Set the configuration to |mojo_config| again, and check the results.
222     ssl_config_client_->OnSSLConfigUpdated(mojo_config.Clone());
223     observer.WaitForChange();
224     EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
225         GetSSLContextConfig(), expected_net_config));
226     EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
227         observer.ssl_context_config_during_change(), expected_net_config));
228   }
229 
230   // Runs two conversion tests for |mojo_config|.  Uses it as an initial
231   // net::CertVerifier::Config for a NetworkContext, making sure it matches
232   // |expected_net_config|. Then switches to the default configuration and then
233   // back to |mojo_config|, to make sure it works as a new configuration. The
234   // expected configuration must not be the default configuration.
RunCertConversionTests(const mojom::SSLConfig & mojo_config,const net::CertVerifier::Config & expected_net_config)235   void RunCertConversionTests(
236       const mojom::SSLConfig& mojo_config,
237       const net::CertVerifier::Config& expected_net_config) {
238     TestCertVerifierConfigObserver observer;
239     NetworkContext::SetCertVerifierForTesting(&observer);
240 
241     EXPECT_NE(net::CertVerifier::Config(), expected_net_config);
242 
243     // Set up |mojo_config| as the initial configuration of a NetworkContext.
244     mojom::NetworkContextParamsPtr network_context_params =
245         mojom::NetworkContextParams::New();
246     network_context_params->initial_ssl_config = mojo_config.Clone();
247     SetUpNetworkContext(std::move(network_context_params));
248 
249     // Make sure the initial configuration is set.
250     observer.WaitForChange();
251     EXPECT_EQ(observer.verifier_config_during_change(), expected_net_config);
252     // Sanity check.
253     EXPECT_NE(observer.verifier_config_during_change(),
254               net::CertVerifier::Config());
255 
256     // Reset the configuration to the default ones, and check the results.
257     ssl_config_client_->OnSSLConfigUpdated(mojom::SSLConfig::New());
258     observer.WaitForChange();
259     EXPECT_EQ(observer.verifier_config_during_change(),
260               net::CertVerifier::Config());
261     // Sanity check.
262     EXPECT_NE(observer.verifier_config_during_change(), expected_net_config);
263 
264     // Set the configuration to |mojo_config| again, and check the results.
265     ssl_config_client_->OnSSLConfigUpdated(mojo_config.Clone());
266     observer.WaitForChange();
267     EXPECT_EQ(observer.verifier_config_during_change(), expected_net_config);
268 
269     // Reset the CertVerifier for subsequent invocations.
270     NetworkContext::SetCertVerifierForTesting(nullptr);
271   }
272 
273  protected:
274   base::test::TaskEnvironment task_environment_;
275   std::unique_ptr<NetworkService> network_service_;
276   mojo::Remote<mojom::SSLConfigClient> ssl_config_client_;
277   mojo::Remote<mojom::NetworkContext> network_context_remote_;
278   std::unique_ptr<NetworkContext> network_context_;
279 };
280 
281 // Check that passing in a no mojom::SSLConfig matches the default
282 // net::SSLConfig.
TEST_F(NetworkServiceSSLConfigServiceTest,NoSSLConfig)283 TEST_F(NetworkServiceSSLConfigServiceTest, NoSSLConfig) {
284   SetUpNetworkContext(mojom::NetworkContextParams::New());
285   EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
286       GetSSLContextConfig(), net::SSLContextConfig()));
287 
288   // Make sure the default TLS version range is as expected.
289   EXPECT_EQ(net::kDefaultSSLVersionMin, GetSSLContextConfig().version_min);
290   EXPECT_EQ(net::kDefaultSSLVersionMax, GetSSLContextConfig().version_max);
291 }
292 
293 // Check that passing in the default mojom::SSLConfig matches the default
294 // net::SSLConfig.
TEST_F(NetworkServiceSSLConfigServiceTest,Default)295 TEST_F(NetworkServiceSSLConfigServiceTest, Default) {
296   mojom::NetworkContextParamsPtr network_context_params =
297       mojom::NetworkContextParams::New();
298   network_context_params->initial_ssl_config = mojom::SSLConfig::New();
299   SetUpNetworkContext(std::move(network_context_params));
300   EXPECT_TRUE(net::SSLConfigService::SSLContextConfigsAreEqualForTesting(
301       GetSSLContextConfig(), net::SSLContextConfig()));
302 
303   // Make sure the default TLS version range is as expected.
304   EXPECT_EQ(net::kDefaultSSLVersionMin, GetSSLContextConfig().version_min);
305   EXPECT_EQ(net::kDefaultSSLVersionMax, GetSSLContextConfig().version_max);
306 }
307 
308 // Check that passing in the default mojom::SSLConfig matches the default
309 // net::CertVerifier::Config.
TEST_F(NetworkServiceSSLConfigServiceTest,DefaultCertConfig)310 TEST_F(NetworkServiceSSLConfigServiceTest, DefaultCertConfig) {
311   TestCertVerifierConfigObserver observer;
312   NetworkContext::SetCertVerifierForTesting(&observer);
313 
314   mojom::NetworkContextParamsPtr network_context_params =
315       mojom::NetworkContextParams::New();
316   network_context_params->initial_ssl_config = mojom::SSLConfig::New();
317   SetUpNetworkContext(std::move(network_context_params));
318 
319   observer.WaitForChange();
320 
321   net::CertVerifier::Config default_config;
322   EXPECT_EQ(observer.verifier_config_during_change(), default_config);
323 
324   NetworkContext::SetCertVerifierForTesting(nullptr);
325 }
326 
TEST_F(NetworkServiceSSLConfigServiceTest,RevCheckingEnabled)327 TEST_F(NetworkServiceSSLConfigServiceTest, RevCheckingEnabled) {
328   net::CertVerifier::Config expected_net_config;
329   // Use the opposite of the default value.
330   expected_net_config.enable_rev_checking =
331       !expected_net_config.enable_rev_checking;
332 
333   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
334   mojo_config->rev_checking_enabled = expected_net_config.enable_rev_checking;
335 
336   RunCertConversionTests(*mojo_config, expected_net_config);
337 }
338 
TEST_F(NetworkServiceSSLConfigServiceTest,RevCheckingRequiredLocalTrustAnchors)339 TEST_F(NetworkServiceSSLConfigServiceTest,
340        RevCheckingRequiredLocalTrustAnchors) {
341   net::CertVerifier::Config expected_net_config;
342   // Use the opposite of the default value.
343   expected_net_config.require_rev_checking_local_anchors =
344       !expected_net_config.require_rev_checking_local_anchors;
345 
346   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
347   mojo_config->rev_checking_required_local_anchors =
348       expected_net_config.require_rev_checking_local_anchors;
349 
350   RunCertConversionTests(*mojo_config, expected_net_config);
351 }
352 
TEST_F(NetworkServiceSSLConfigServiceTest,Sha1LocalAnchorsEnabled)353 TEST_F(NetworkServiceSSLConfigServiceTest, Sha1LocalAnchorsEnabled) {
354   net::CertVerifier::Config expected_net_config;
355   // Use the opposite of the default value.
356   expected_net_config.enable_sha1_local_anchors =
357       !expected_net_config.enable_sha1_local_anchors;
358 
359   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
360   mojo_config->sha1_local_anchors_enabled =
361       expected_net_config.enable_sha1_local_anchors;
362 
363   RunCertConversionTests(*mojo_config, expected_net_config);
364 }
365 
TEST_F(NetworkServiceSSLConfigServiceTest,SymantecEnforcementDisabled)366 TEST_F(NetworkServiceSSLConfigServiceTest, SymantecEnforcementDisabled) {
367   net::CertVerifier::Config expected_net_config;
368   // Use the opposite of the default value.
369   expected_net_config.disable_symantec_enforcement =
370       !expected_net_config.disable_symantec_enforcement;
371 
372   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
373   mojo_config->symantec_enforcement_disabled =
374       expected_net_config.disable_symantec_enforcement;
375 
376   RunCertConversionTests(*mojo_config, expected_net_config);
377 }
378 
TEST_F(NetworkServiceSSLConfigServiceTest,SSLVersion)379 TEST_F(NetworkServiceSSLConfigServiceTest, SSLVersion) {
380   const struct {
381     mojom::SSLVersion mojo_ssl_version;
382     int net_ssl_version;
383   } kVersionTable[] = {
384       {mojom::SSLVersion::kTLS1, net::SSL_PROTOCOL_VERSION_TLS1},
385       {mojom::SSLVersion::kTLS11, net::SSL_PROTOCOL_VERSION_TLS1_1},
386       {mojom::SSLVersion::kTLS12, net::SSL_PROTOCOL_VERSION_TLS1_2},
387       {mojom::SSLVersion::kTLS13, net::SSL_PROTOCOL_VERSION_TLS1_3},
388   };
389 
390   for (size_t min_index = 0; min_index < base::size(kVersionTable);
391        ++min_index) {
392     for (size_t max_index = min_index; max_index < base::size(kVersionTable);
393          ++max_index) {
394       // If the versions match the default values, skip this value in the table.
395       // The defaults will get plenty of testing anyways, when switching back to
396       // the default values in RunConversionTests().
397       if (kVersionTable[min_index].net_ssl_version ==
398               net::SSLContextConfig().version_min &&
399           kVersionTable[max_index].net_ssl_version ==
400               net::SSLContextConfig().version_max) {
401         continue;
402       }
403       net::SSLContextConfig expected_net_config;
404       expected_net_config.version_min =
405           kVersionTable[min_index].net_ssl_version;
406       expected_net_config.version_max =
407           kVersionTable[max_index].net_ssl_version;
408 
409       mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
410       mojo_config->version_min = kVersionTable[min_index].mojo_ssl_version;
411       mojo_config->version_max = kVersionTable[max_index].mojo_ssl_version;
412 
413       RunConversionTests(*mojo_config, expected_net_config);
414     }
415   }
416 }
417 
TEST_F(NetworkServiceSSLConfigServiceTest,InitialConfigDisableCipherSuite)418 TEST_F(NetworkServiceSSLConfigServiceTest, InitialConfigDisableCipherSuite) {
419   net::SSLContextConfig expected_net_config;
420   expected_net_config.disabled_cipher_suites.push_back(0x0004);
421 
422   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
423   mojo_config->disabled_cipher_suites =
424       expected_net_config.disabled_cipher_suites;
425 
426   RunConversionTests(*mojo_config, expected_net_config);
427 }
428 
TEST_F(NetworkServiceSSLConfigServiceTest,InitialConfigDisableTwoCipherSuites)429 TEST_F(NetworkServiceSSLConfigServiceTest,
430        InitialConfigDisableTwoCipherSuites) {
431   net::SSLContextConfig expected_net_config;
432   expected_net_config.disabled_cipher_suites.push_back(0x0004);
433   expected_net_config.disabled_cipher_suites.push_back(0x0005);
434 
435   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
436   mojo_config->disabled_cipher_suites =
437       expected_net_config.disabled_cipher_suites;
438 
439   RunConversionTests(*mojo_config, expected_net_config);
440 }
441 
TEST_F(NetworkServiceSSLConfigServiceTest,CanShareConnectionWithClientCerts)442 TEST_F(NetworkServiceSSLConfigServiceTest, CanShareConnectionWithClientCerts) {
443   // Create a default NetworkContext and test that
444   // CanShareConnectionWithClientCerts returns false.
445   SetUpNetworkContext(mojom::NetworkContextParams::New());
446 
447   net::SSLConfigService* config_service =
448       network_context_->url_request_context()->ssl_config_service();
449 
450   EXPECT_FALSE(
451       config_service->CanShareConnectionWithClientCerts("example.com"));
452   EXPECT_FALSE(
453       config_service->CanShareConnectionWithClientCerts("example.net"));
454 
455   // Configure policy to allow example.com (but no subdomains), and example.net
456   // (including subdomains), update the config, and test that pooling is allowed
457   // with this policy.
458   mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New();
459   mojo_config->client_cert_pooling_policy = {".example.com", "example.net"};
460 
461   TestSSLConfigServiceObserver observer(config_service);
462   ssl_config_client_->OnSSLConfigUpdated(std::move(mojo_config));
463   observer.WaitForChange();
464 
465   EXPECT_TRUE(config_service->CanShareConnectionWithClientCerts("example.com"));
466   EXPECT_FALSE(
467       config_service->CanShareConnectionWithClientCerts("sub.example.com"));
468 
469   EXPECT_TRUE(config_service->CanShareConnectionWithClientCerts("example.net"));
470   EXPECT_TRUE(
471       config_service->CanShareConnectionWithClientCerts("sub.example.net"));
472   EXPECT_TRUE(
473       config_service->CanShareConnectionWithClientCerts("sub.sub.example.net"));
474   EXPECT_FALSE(
475       config_service->CanShareConnectionWithClientCerts("notexample.net"));
476 
477   EXPECT_FALSE(
478       config_service->CanShareConnectionWithClientCerts("example.org"));
479 
480   // Reset the configuration to the default and check that pooling is no longer
481   // allowed.
482   ssl_config_client_->OnSSLConfigUpdated(mojom::SSLConfig::New());
483   observer.WaitForChange();
484 
485   EXPECT_FALSE(
486       config_service->CanShareConnectionWithClientCerts("example.com"));
487   EXPECT_FALSE(
488       config_service->CanShareConnectionWithClientCerts("example.net"));
489 }
490 
491 }  // namespace
492 }  // namespace network
493