NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / net / ssl_config_service_manager_pref.cc
blob0aab9a6fa7e5b3c42d6c7a805607578f9b0d8d8d
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"
6 #include <algorithm>
7 #include <string>
8 #include <vector>
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"
24 using content::BrowserThread;
26 namespace {
28 // Converts a ListValue of StringValues into a vector of strings. Any Values
29 // which cannot be converted will be skipped.
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);
40 return results;
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.
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());
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;
59 cipher_suites.push_back(cipher_suite);
61 std::sort(cipher_suites.begin(), cipher_suites.end());
62 return cipher_suites;
65 // Returns the string representation of an SSL protocol version. Returns an
66 // empty string on error.
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();
83 // Returns the SSL protocol version (as a uint16) represented by a string.
84 // Returns 0 if the string is invalid.
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;
96 return version;
99 } // namespace
101 ////////////////////////////////////////////////////////////////////////////////
102 // SSLConfigServicePref
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:
109 SSLConfigServicePref() {}
111 // Store SSL config settings in |config|. Must only be called from IO thread.
112 virtual void GetSSLConfig(net::SSLConfig* config) OVERRIDE;
114 private:
115 // Allow the pref watcher to update our internal state.
116 friend class SSLConfigServiceManagerPref;
118 virtual ~SSLConfigServicePref() {}
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);
124 // Cached value of prefs, should only be accessed from IO thread.
125 net::SSLConfig cached_config_;
127 DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref);
130 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
131 *config = cached_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);
141 ////////////////////////////////////////////////////////////////////////////////
142 // SSLConfigServiceManagerPref
144 // The manager for holding and updating an SSLConfigServicePref instance.
145 class SSLConfigServiceManagerPref
146 : public SSLConfigServiceManager {
147 public:
148 explicit SSLConfigServiceManagerPref(PrefService* local_state);
149 virtual ~SSLConfigServiceManagerPref() {}
151 // Register local_state SSL preferences.
152 static void RegisterPrefs(PrefRegistrySimple* registry);
154 virtual net::SSLConfigService* Get() OVERRIDE;
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);
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);
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);
170 PrefChangeRegistrar local_state_change_registrar_;
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 channel_id_enabled_;
178 BooleanPrefMember ssl_record_splitting_disabled_;
179 BooleanPrefMember unrestricted_ssl3_fallback_enabled_;
181 // The cached list of disabled SSL cipher suites.
182 std::vector<uint16> disabled_cipher_suites_;
184 scoped_refptr<SSLConfigServicePref> ssl_config_service_;
186 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref);
189 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
190 PrefService* local_state)
191 : ssl_config_service_(new SSLConfigServicePref()) {
192 DCHECK(local_state);
194 PrefChangeRegistrar::NamedChangeCallback local_state_callback = base::Bind(
195 &SSLConfigServiceManagerPref::OnPreferenceChanged,
196 base::Unretained(this),
197 local_state);
199 rev_checking_enabled_.Init(
200 prefs::kCertRevocationCheckingEnabled, local_state, local_state_callback);
201 rev_checking_required_local_anchors_.Init(
202 prefs::kCertRevocationCheckingRequiredLocalAnchors,
203 local_state,
204 local_state_callback);
205 ssl_version_min_.Init(
206 prefs::kSSLVersionMin, local_state, local_state_callback);
207 ssl_version_max_.Init(
208 prefs::kSSLVersionMax, local_state, local_state_callback);
209 channel_id_enabled_.Init(
210 prefs::kEnableOriginBoundCerts, local_state, local_state_callback);
211 ssl_record_splitting_disabled_.Init(
212 prefs::kDisableSSLRecordSplitting, local_state, local_state_callback);
213 unrestricted_ssl3_fallback_enabled_.Init(
214 prefs::kEnableUnrestrictedSSL3Fallback,
215 local_state,
216 local_state_callback);
218 local_state_change_registrar_.Init(local_state);
219 local_state_change_registrar_.Add(
220 prefs::kCipherSuiteBlacklist, local_state_callback);
222 OnDisabledCipherSuitesChange(local_state);
224 // Initialize from UI thread. This is okay as there shouldn't be anything on
225 // the IO thread trying to access it yet.
226 GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_);
229 // static
230 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple* registry) {
231 net::SSLConfig default_config;
232 registry->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled,
233 default_config.rev_checking_enabled);
234 registry->RegisterBooleanPref(
235 prefs::kCertRevocationCheckingRequiredLocalAnchors,
236 default_config.rev_checking_required_local_anchors);
237 std::string version_min_str =
238 SSLProtocolVersionToString(default_config.version_min);
239 std::string version_max_str =
240 SSLProtocolVersionToString(default_config.version_max);
241 registry->RegisterStringPref(prefs::kSSLVersionMin, version_min_str);
242 registry->RegisterStringPref(prefs::kSSLVersionMax, version_max_str);
243 registry->RegisterBooleanPref(prefs::kEnableOriginBoundCerts,
244 default_config.channel_id_enabled);
245 registry->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting,
246 !default_config.false_start_enabled);
247 registry->RegisterBooleanPref(prefs::kEnableUnrestrictedSSL3Fallback,
248 default_config.unrestricted_ssl3_fallback_enabled);
249 registry->RegisterListPref(prefs::kCipherSuiteBlacklist);
252 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
253 return ssl_config_service_.get();
256 void SSLConfigServiceManagerPref::OnPreferenceChanged(
257 PrefService* prefs,
258 const std::string& pref_name_in) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
260 DCHECK(prefs);
261 if (pref_name_in == prefs::kCipherSuiteBlacklist)
262 OnDisabledCipherSuitesChange(prefs);
264 net::SSLConfig new_config;
265 GetSSLConfigFromPrefs(&new_config);
267 // Post a task to |io_loop| with the new configuration, so it can
268 // update |cached_config_|.
269 BrowserThread::PostTask(
270 BrowserThread::IO,
271 FROM_HERE,
272 base::Bind(
273 &SSLConfigServicePref::SetNewSSLConfig,
274 ssl_config_service_.get(),
275 new_config));
278 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
279 net::SSLConfig* config) {
280 config->rev_checking_enabled = rev_checking_enabled_.GetValue();
281 config->rev_checking_required_local_anchors =
282 rev_checking_required_local_anchors_.GetValue();
283 std::string version_min_str = ssl_version_min_.GetValue();
284 std::string version_max_str = ssl_version_max_.GetValue();
285 config->version_min = net::SSLConfigService::default_version_min();
286 config->version_max = net::SSLConfigService::default_version_max();
287 uint16 version_min = SSLProtocolVersionFromString(version_min_str);
288 uint16 version_max = SSLProtocolVersionFromString(version_max_str);
289 if (version_min) {
290 // TODO(wtc): get the minimum SSL protocol version supported by the
291 // SSLClientSocket class. Right now it happens to be the same as the
292 // default minimum SSL protocol version because we enable all supported
293 // versions by default.
294 uint16 supported_version_min = config->version_min;
295 config->version_min = std::max(supported_version_min, version_min);
297 if (version_max) {
298 // TODO(wtc): get the maximum SSL protocol version supported by the
299 // SSLClientSocket class.
300 uint16 supported_version_max = config->version_max;
301 config->version_max = std::min(supported_version_max, version_max);
303 config->disabled_cipher_suites = disabled_cipher_suites_;
304 config->channel_id_enabled = channel_id_enabled_.GetValue();
305 // disabling False Start also happens to disable record splitting.
306 config->false_start_enabled = !ssl_record_splitting_disabled_.GetValue();
307 config->unrestricted_ssl3_fallback_enabled =
308 unrestricted_ssl3_fallback_enabled_.GetValue();
311 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
312 PrefService* local_state) {
313 const base::ListValue* value =
314 local_state->GetList(prefs::kCipherSuiteBlacklist);
315 disabled_cipher_suites_ = ParseCipherSuites(ListValueToStringVector(value));
318 ////////////////////////////////////////////////////////////////////////////////
319 // SSLConfigServiceManager
321 // static
322 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
323 PrefService* local_state) {
324 return new SSLConfigServiceManagerPref(local_state);
327 // static
328 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple* registry) {
329 SSLConfigServiceManagerPref::RegisterPrefs(registry);