1 // Copyright (c) 2012 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 "chrome/browser/net/ssl_config_service_manager.h"
5
6 #include <algorithm>
7 #include <string>
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/prefs/pref_member.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/pref_service.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/content_settings/content_settings_utils.h"
18 #include "chrome/common/content_settings.h"
19 #include "chrome/common/pref_names.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "net/ssl/ssl_cipher_suite_names.h"
22 #include "net/ssl/ssl_config_service.h"
23
24 using content::BrowserThread;
25
26 namespace {
27
28 // Converts a ListValue of StringValues into a vector of strings. Any Values
29 // which cannot be converted will be skipped.
ListValueToStringVector(const base::ListValue * value)30 std::vector<std::string> ListValueToStringVector(const base::ListValue* value) {
31 std::vector<std::string> results;
32 results.reserve(value->GetSize());
33 std::string s;
34 for (base::ListValue::const_iterator it = value->begin(); it != value->end();
35 ++it) {
36 if (!(*it)->GetAsString(&s))
37 continue;
38 results.push_back(s);
39 }
40 return results;
41 }
42
43 // Parses a vector of cipher suite strings, returning a sorted vector
44 // containing the underlying SSL/TLS cipher suites. Unrecognized/invalid
45 // cipher suites will be ignored.
ParseCipherSuites(const std::vector<std::string> & cipher_strings)46 std::vector<uint16> ParseCipherSuites(
47 const std::vector<std::string>& cipher_strings) {
48 std::vector<uint16> cipher_suites;
49 cipher_suites.reserve(cipher_strings.size());
50
51 for (std::vector<std::string>::const_iterator it = cipher_strings.begin();
52 it != cipher_strings.end(); ++it) {
53 uint16 cipher_suite = 0;
54 if (!net::ParseSSLCipherString(*it, &cipher_suite)) {
55 LOG(ERROR) << "Ignoring unrecognized or unparsable cipher suite: "
56 << *it;
57 continue;
58 }
59 cipher_suites.push_back(cipher_suite);
60 }
61 std::sort(cipher_suites.begin(), cipher_suites.end());
62 return cipher_suites;
63 }
64
65 // Returns the string representation of an SSL protocol version. Returns an
66 // empty string on error.
SSLProtocolVersionToString(uint16 version)67 std::string SSLProtocolVersionToString(uint16 version) {
68 switch (version) {
69 case net::SSL_PROTOCOL_VERSION_SSL3:
70 return "ssl3";
71 case net::SSL_PROTOCOL_VERSION_TLS1:
72 return "tls1";
73 case net::SSL_PROTOCOL_VERSION_TLS1_1:
74 return "tls1.1";
75 case net::SSL_PROTOCOL_VERSION_TLS1_2:
76 return "tls1.2";
77 default:
78 NOTREACHED();
79 return std::string();
80 }
81 }
82
83 // Returns the SSL protocol version (as a uint16) represented by a string.
84 // Returns 0 if the string is invalid.
SSLProtocolVersionFromString(const std::string & version_str)85 uint16 SSLProtocolVersionFromString(const std::string& version_str) {
86 uint16 version = 0; // Invalid.
87 if (version_str == "ssl3") {
88 version = net::SSL_PROTOCOL_VERSION_SSL3;
89 } else if (version_str == "tls1") {
90 version = net::SSL_PROTOCOL_VERSION_TLS1;
91 } else if (version_str == "tls1.1") {
92 version = net::SSL_PROTOCOL_VERSION_TLS1_1;
93 } else if (version_str == "tls1.2") {
94 version = net::SSL_PROTOCOL_VERSION_TLS1_2;
95 }
96 return version;
97 }
98
99 } // namespace
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // SSLConfigServicePref
103
104 // An SSLConfigService which stores a cached version of the current SSLConfig
105 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
106 // change.
107 class SSLConfigServicePref : public net::SSLConfigService {
108 public:
SSLConfigServicePref()109 SSLConfigServicePref() {}
110
111 // Store SSL config settings in |config|. Must only be called from IO thread.
112 virtual void GetSSLConfig(net::SSLConfig* config) OVERRIDE;
113
114 private:
115 // Allow the pref watcher to update our internal state.
116 friend class SSLConfigServiceManagerPref;
117
~SSLConfigServicePref()118 virtual ~SSLConfigServicePref() {}
119
120 // This method is posted to the IO thread from the browser thread to carry the
121 // new config information.
122 void SetNewSSLConfig(const net::SSLConfig& new_config);
123
124 // Cached value of prefs, should only be accessed from IO thread.
125 net::SSLConfig cached_config_;
126
127 DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref);
128 };
129
GetSSLConfig(net::SSLConfig * config)130 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
131 *config = cached_config_;
132 }
133
SetNewSSLConfig(const net::SSLConfig & new_config)134 void SSLConfigServicePref::SetNewSSLConfig(
135 const net::SSLConfig& new_config) {
136 net::SSLConfig orig_config = cached_config_;
137 cached_config_ = new_config;
138 ProcessConfigUpdate(orig_config, new_config);
139 }
140
141 ////////////////////////////////////////////////////////////////////////////////
142 // SSLConfigServiceManagerPref
143
144 // The manager for holding and updating an SSLConfigServicePref instance.
145 class SSLConfigServiceManagerPref
146 : public SSLConfigServiceManager {
147 public:
148 explicit SSLConfigServiceManagerPref(PrefService* local_state);
~SSLConfigServiceManagerPref()149 virtual ~SSLConfigServiceManagerPref() {}
150
151 // Register local_state SSL preferences.
152 static void RegisterPrefs(PrefRegistrySimple* registry);
153
154 virtual net::SSLConfigService* Get() OVERRIDE;
155
156 private:
157 // Callback for preference changes. This will post the changes to the IO
158 // thread with SetNewSSLConfig.
159 void OnPreferenceChanged(PrefService* prefs,
160 const std::string& pref_name);
161
162 // Store SSL config settings in |config|, directly from the preferences. Must
163 // only be called from UI thread.
164 void GetSSLConfigFromPrefs(net::SSLConfig* config);
165
166 // Processes changes to the disabled cipher suites preference, updating the
167 // cached list of parsed SSL/TLS cipher suites that are disabled.
168 void OnDisabledCipherSuitesChange(PrefService* local_state);
169
170 PrefChangeRegistrar local_state_change_registrar_;
171
172 // The local_state prefs (should only be accessed from UI thread)
173 BooleanPrefMember rev_checking_enabled_;
174 BooleanPrefMember rev_checking_required_local_anchors_;
175 StringPrefMember ssl_version_min_;
176 StringPrefMember ssl_version_max_;
177 BooleanPrefMember ssl_record_splitting_disabled_;
178
179 // The cached list of disabled SSL cipher suites.
180 std::vector<uint16> disabled_cipher_suites_;
181
182 scoped_refptr<SSLConfigServicePref> ssl_config_service_;
183
184 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref);
185 };
186
SSLConfigServiceManagerPref(PrefService * local_state)187 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
188 PrefService* local_state)
189 : ssl_config_service_(new SSLConfigServicePref()) {
190 DCHECK(local_state);
191
192 PrefChangeRegistrar::NamedChangeCallback local_state_callback = base::Bind(
193 &SSLConfigServiceManagerPref::OnPreferenceChanged,
194 base::Unretained(this),
195 local_state);
196
197 rev_checking_enabled_.Init(
198 prefs::kCertRevocationCheckingEnabled, local_state, local_state_callback);
199 rev_checking_required_local_anchors_.Init(
200 prefs::kCertRevocationCheckingRequiredLocalAnchors,
201 local_state,
202 local_state_callback);
203 ssl_version_min_.Init(
204 prefs::kSSLVersionMin, local_state, local_state_callback);
205 ssl_version_max_.Init(
206 prefs::kSSLVersionMax, local_state, local_state_callback);
207 ssl_record_splitting_disabled_.Init(
208 prefs::kDisableSSLRecordSplitting, local_state, local_state_callback);
209
210 local_state_change_registrar_.Init(local_state);
211 local_state_change_registrar_.Add(
212 prefs::kCipherSuiteBlacklist, local_state_callback);
213
214 OnDisabledCipherSuitesChange(local_state);
215
216 // Initialize from UI thread. This is okay as there shouldn't be anything on
217 // the IO thread trying to access it yet.
218 GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_);
219 }
220
221 // static
RegisterPrefs(PrefRegistrySimple * registry)222 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple* registry) {
223 net::SSLConfig default_config;
224 registry->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled,
225 default_config.rev_checking_enabled);
226 registry->RegisterBooleanPref(
227 prefs::kCertRevocationCheckingRequiredLocalAnchors,
228 default_config.rev_checking_required_local_anchors);
229 std::string version_min_str =
230 SSLProtocolVersionToString(default_config.version_min);
231 std::string version_max_str =
232 SSLProtocolVersionToString(default_config.version_max);
233 registry->RegisterStringPref(prefs::kSSLVersionMin, version_min_str);
234 registry->RegisterStringPref(prefs::kSSLVersionMax, version_max_str);
235 registry->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting,
236 !default_config.false_start_enabled);
237 registry->RegisterListPref(prefs::kCipherSuiteBlacklist);
238 }
239
Get()240 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
241 return ssl_config_service_.get();
242 }
243
OnPreferenceChanged(PrefService * prefs,const std::string & pref_name_in)244 void SSLConfigServiceManagerPref::OnPreferenceChanged(
245 PrefService* prefs,
246 const std::string& pref_name_in) {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248 DCHECK(prefs);
249 if (pref_name_in == prefs::kCipherSuiteBlacklist)
250 OnDisabledCipherSuitesChange(prefs);
251
252 net::SSLConfig new_config;
253 GetSSLConfigFromPrefs(&new_config);
254
255 // Post a task to |io_loop| with the new configuration, so it can
256 // update |cached_config_|.
257 BrowserThread::PostTask(
258 BrowserThread::IO,
259 FROM_HERE,
260 base::Bind(
261 &SSLConfigServicePref::SetNewSSLConfig,
262 ssl_config_service_.get(),
263 new_config));
264 }
265
GetSSLConfigFromPrefs(net::SSLConfig * config)266 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
267 net::SSLConfig* config) {
268 // rev_checking_enabled was formerly a user-settable preference, but now
269 // it is managed-only.
270 if (rev_checking_enabled_.IsManaged())
271 config->rev_checking_enabled = rev_checking_enabled_.GetValue();
272 else
273 config->rev_checking_enabled = false;
274 config->rev_checking_required_local_anchors =
275 rev_checking_required_local_anchors_.GetValue();
276 std::string version_min_str = ssl_version_min_.GetValue();
277 std::string version_max_str = ssl_version_max_.GetValue();
278 config->version_min = net::kDefaultSSLVersionMin;
279 config->version_max = net::kDefaultSSLVersionMax;
280 uint16 version_min = SSLProtocolVersionFromString(version_min_str);
281 uint16 version_max = SSLProtocolVersionFromString(version_max_str);
282 if (version_min) {
283 // TODO(wtc): get the minimum SSL protocol version supported by the
284 // SSLClientSocket class. Right now it happens to be the same as the
285 // default minimum SSL protocol version because we enable all supported
286 // versions by default.
287 uint16 supported_version_min = config->version_min;
288 config->version_min = std::max(supported_version_min, version_min);
289 }
290 if (version_max) {
291 // TODO(wtc): get the maximum SSL protocol version supported by the
292 // SSLClientSocket class.
293 uint16 supported_version_max = config->version_max;
294 config->version_max = std::min(supported_version_max, version_max);
295 }
296 config->disabled_cipher_suites = disabled_cipher_suites_;
297 // disabling False Start also happens to disable record splitting.
298 config->false_start_enabled = !ssl_record_splitting_disabled_.GetValue();
299 }
300
OnDisabledCipherSuitesChange(PrefService * local_state)301 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
302 PrefService* local_state) {
303 const base::ListValue* value =
304 local_state->GetList(prefs::kCipherSuiteBlacklist);
305 disabled_cipher_suites_ = ParseCipherSuites(ListValueToStringVector(value));
306 }
307
308 ////////////////////////////////////////////////////////////////////////////////
309 // SSLConfigServiceManager
310
311 // static
CreateDefaultManager(PrefService * local_state)312 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
313 PrefService* local_state) {
314 return new SSLConfigServiceManagerPref(local_state);
315 }
316
317 // static
RegisterPrefs(PrefRegistrySimple * registry)318 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple* registry) {
319 SSLConfigServiceManagerPref::RegisterPrefs(registry);
320 }
321