1 // Copyright 2012 The Chromium Authors
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 "net/ssl/ssl_config_service.h"
6
7 #include <vector>
8
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace net {
13
14 namespace {
15
16 class MockSSLConfigService : public SSLConfigService {
17 public:
MockSSLConfigService(const SSLContextConfig & config)18 explicit MockSSLConfigService(const SSLContextConfig& config)
19 : config_(config) {}
20 ~MockSSLConfigService() override = default;
21
22 // SSLConfigService implementation
GetSSLContextConfig()23 SSLContextConfig GetSSLContextConfig() override { return config_; }
24
CanShareConnectionWithClientCerts(std::string_view hostname) const25 bool CanShareConnectionWithClientCerts(
26 std::string_view hostname) const override {
27 return false;
28 }
29
30 // Sets the SSLContextConfig to be returned by GetSSLContextConfig and
31 // processes any updates.
SetSSLContextConfig(const SSLContextConfig & config)32 void SetSSLContextConfig(const SSLContextConfig& config) {
33 SSLContextConfig old_config = config_;
34 config_ = config;
35 ProcessConfigUpdate(old_config, config_, /*force_notification*/ false);
36 }
37
38 using SSLConfigService::ProcessConfigUpdate;
39
40 private:
41 SSLContextConfig config_;
42 };
43
44 class MockSSLConfigServiceObserver : public SSLConfigService::Observer {
45 public:
46 MockSSLConfigServiceObserver() = default;
47 ~MockSSLConfigServiceObserver() override = default;
48
49 MOCK_METHOD0(OnSSLContextConfigChanged, void());
50 };
51
52 } // namespace
53
TEST(SSLConfigServiceTest,NoChangesWontNotifyObservers)54 TEST(SSLConfigServiceTest, NoChangesWontNotifyObservers) {
55 SSLContextConfig initial_config;
56 initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1_2;
57 initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
58
59 MockSSLConfigService mock_service(initial_config);
60 MockSSLConfigServiceObserver observer;
61 mock_service.AddObserver(&observer);
62
63 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(0);
64 mock_service.SetSSLContextConfig(initial_config);
65
66 mock_service.RemoveObserver(&observer);
67 }
68
TEST(SSLConfigServiceTest,ForceNotificationNotifiesObservers)69 TEST(SSLConfigServiceTest, ForceNotificationNotifiesObservers) {
70 SSLContextConfig initial_config;
71 initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1_2;
72 initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
73
74 MockSSLConfigService mock_service(initial_config);
75 MockSSLConfigServiceObserver observer;
76 mock_service.AddObserver(&observer);
77
78 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
79 mock_service.ProcessConfigUpdate(initial_config, initial_config, true);
80
81 mock_service.RemoveObserver(&observer);
82 }
83
TEST(SSLConfigServiceTest,ConfigUpdatesNotifyObservers)84 TEST(SSLConfigServiceTest, ConfigUpdatesNotifyObservers) {
85 SSLContextConfig initial_config;
86 initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
87
88 MockSSLConfigService mock_service(initial_config);
89 MockSSLConfigServiceObserver observer;
90 mock_service.AddObserver(&observer);
91
92 // Test that changing the SSL version range triggers updates.
93 initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1_3;
94 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
95 mock_service.SetSSLContextConfig(initial_config);
96
97 initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1_2;
98 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
99 mock_service.SetSSLContextConfig(initial_config);
100
101 initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
102 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
103 mock_service.SetSSLContextConfig(initial_config);
104
105 // Test that disabling certain cipher suites triggers an update.
106 std::vector<uint16_t> disabled_ciphers;
107 disabled_ciphers.push_back(0x0004u);
108 disabled_ciphers.push_back(0xBEEFu);
109 disabled_ciphers.push_back(0xDEADu);
110 initial_config.disabled_cipher_suites = disabled_ciphers;
111 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
112 mock_service.SetSSLContextConfig(initial_config);
113
114 // Ensure that changing a disabled cipher suite, while still maintaining
115 // sorted order, triggers an update.
116 disabled_ciphers[1] = 0xCAFEu;
117 initial_config.disabled_cipher_suites = disabled_ciphers;
118 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
119 mock_service.SetSSLContextConfig(initial_config);
120
121 // Ensure that removing a disabled cipher suite, while still keeping some
122 // cipher suites disabled, triggers an update.
123 disabled_ciphers.pop_back();
124 initial_config.disabled_cipher_suites = disabled_ciphers;
125 EXPECT_CALL(observer, OnSSLContextConfigChanged()).Times(1);
126 mock_service.SetSSLContextConfig(initial_config);
127
128 mock_service.RemoveObserver(&observer);
129 }
130
131 } // namespace net
132