ssl_config_service_mojo_unittest.cc 19 KB

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