Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / net / ssl_config_service_manager_pref.cc
blobf419580269d767a52529adef0e3fd74f703a8798
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/metrics/field_trial.h"
13 #include "base/prefs/pref_change_registrar.h"
14 #include "base/prefs/pref_member.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/prefs/pref_service.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/pref_names.h"
20 #include "components/content_settings/core/browser/content_settings_utils.h"
21 #include "components/content_settings/core/common/content_settings.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "net/socket/ssl_client_socket.h"
24 #include "net/ssl/ssl_cipher_suite_names.h"
25 #include "net/ssl/ssl_config_service.h"
27 using content::BrowserThread;
29 namespace {
31 // Converts a ListValue of StringValues into a vector of strings. Any Values
32 // which cannot be converted will be skipped.
33 std::vector<std::string> ListValueToStringVector(const base::ListValue* value) {
34 std::vector<std::string> results;
35 results.reserve(value->GetSize());
36 std::string s;
37 for (base::ListValue::const_iterator it = value->begin(); it != value->end();
38 ++it) {
39 if (!(*it)->GetAsString(&s))
40 continue;
41 results.push_back(s);
43 return results;
46 // Parses a vector of cipher suite strings, returning a sorted vector
47 // containing the underlying SSL/TLS cipher suites. Unrecognized/invalid
48 // cipher suites will be ignored.
49 std::vector<uint16> ParseCipherSuites(
50 const std::vector<std::string>& cipher_strings) {
51 std::vector<uint16> cipher_suites;
52 cipher_suites.reserve(cipher_strings.size());
54 for (std::vector<std::string>::const_iterator it = cipher_strings.begin();
55 it != cipher_strings.end(); ++it) {
56 uint16 cipher_suite = 0;
57 if (!net::ParseSSLCipherString(*it, &cipher_suite)) {
58 LOG(ERROR) << "Ignoring unrecognized or unparsable cipher suite: "
59 << *it;
60 continue;
62 cipher_suites.push_back(cipher_suite);
64 std::sort(cipher_suites.begin(), cipher_suites.end());
65 return cipher_suites;
68 // Returns the SSL protocol version (as a uint16) represented by a string.
69 // Returns 0 if the string is invalid.
70 uint16 SSLProtocolVersionFromString(const std::string& version_str) {
71 uint16 version = 0; // Invalid.
72 if (version_str == switches::kSSLVersionTLSv1) {
73 version = net::SSL_PROTOCOL_VERSION_TLS1;
74 } else if (version_str == switches::kSSLVersionTLSv11) {
75 version = net::SSL_PROTOCOL_VERSION_TLS1_1;
76 } else if (version_str == switches::kSSLVersionTLSv12) {
77 version = net::SSL_PROTOCOL_VERSION_TLS1_2;
79 return version;
82 } // namespace
84 ////////////////////////////////////////////////////////////////////////////////
85 // SSLConfigServicePref
87 // An SSLConfigService which stores a cached version of the current SSLConfig
88 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
89 // change.
90 class SSLConfigServicePref : public net::SSLConfigService {
91 public:
92 SSLConfigServicePref() {}
94 // Store SSL config settings in |config|. Must only be called from IO thread.
95 void GetSSLConfig(net::SSLConfig* config) override;
97 private:
98 // Allow the pref watcher to update our internal state.
99 friend class SSLConfigServiceManagerPref;
101 ~SSLConfigServicePref() override {}
103 // This method is posted to the IO thread from the browser thread to carry the
104 // new config information.
105 void SetNewSSLConfig(const net::SSLConfig& new_config);
107 // Cached value of prefs, should only be accessed from IO thread.
108 net::SSLConfig cached_config_;
110 DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref);
113 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
114 DCHECK_CURRENTLY_ON(BrowserThread::IO);
115 *config = cached_config_;
118 void SSLConfigServicePref::SetNewSSLConfig(
119 const net::SSLConfig& new_config) {
120 net::SSLConfig orig_config = cached_config_;
121 cached_config_ = new_config;
122 ProcessConfigUpdate(orig_config, new_config);
125 ////////////////////////////////////////////////////////////////////////////////
126 // SSLConfigServiceManagerPref
128 // The manager for holding and updating an SSLConfigServicePref instance.
129 class SSLConfigServiceManagerPref
130 : public SSLConfigServiceManager {
131 public:
132 explicit SSLConfigServiceManagerPref(PrefService* local_state);
133 ~SSLConfigServiceManagerPref() override {}
135 // Register local_state SSL preferences.
136 static void RegisterPrefs(PrefRegistrySimple* registry);
138 net::SSLConfigService* Get() override;
140 private:
141 // Callback for preference changes. This will post the changes to the IO
142 // thread with SetNewSSLConfig.
143 void OnPreferenceChanged(PrefService* prefs,
144 const std::string& pref_name);
146 // Store SSL config settings in |config|, directly from the preferences. Must
147 // only be called from UI thread.
148 void GetSSLConfigFromPrefs(net::SSLConfig* config);
150 // Processes changes to the disabled cipher suites preference, updating the
151 // cached list of parsed SSL/TLS cipher suites that are disabled.
152 void OnDisabledCipherSuitesChange(PrefService* local_state);
154 PrefChangeRegistrar local_state_change_registrar_;
156 // The local_state prefs (should only be accessed from UI thread)
157 BooleanPrefMember rev_checking_enabled_;
158 BooleanPrefMember rev_checking_required_local_anchors_;
159 StringPrefMember ssl_version_min_;
160 StringPrefMember ssl_version_max_;
161 StringPrefMember ssl_version_fallback_min_;
162 BooleanPrefMember ssl_record_splitting_disabled_;
164 // The cached list of disabled SSL cipher suites.
165 std::vector<uint16> disabled_cipher_suites_;
167 scoped_refptr<SSLConfigServicePref> ssl_config_service_;
169 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref);
172 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
173 PrefService* local_state)
174 : ssl_config_service_(new SSLConfigServicePref()) {
175 DCHECK(local_state);
177 PrefChangeRegistrar::NamedChangeCallback local_state_callback = base::Bind(
178 &SSLConfigServiceManagerPref::OnPreferenceChanged,
179 base::Unretained(this),
180 local_state);
182 rev_checking_enabled_.Init(
183 prefs::kCertRevocationCheckingEnabled, local_state, local_state_callback);
184 rev_checking_required_local_anchors_.Init(
185 prefs::kCertRevocationCheckingRequiredLocalAnchors,
186 local_state,
187 local_state_callback);
188 ssl_version_min_.Init(
189 prefs::kSSLVersionMin, local_state, local_state_callback);
190 ssl_version_max_.Init(
191 prefs::kSSLVersionMax, local_state, local_state_callback);
192 ssl_version_fallback_min_.Init(
193 prefs::kSSLVersionFallbackMin, local_state, local_state_callback);
194 ssl_record_splitting_disabled_.Init(
195 prefs::kDisableSSLRecordSplitting, local_state, local_state_callback);
197 local_state_change_registrar_.Init(local_state);
198 local_state_change_registrar_.Add(
199 prefs::kCipherSuiteBlacklist, local_state_callback);
201 OnDisabledCipherSuitesChange(local_state);
203 // Initialize from UI thread. This is okay as there shouldn't be anything on
204 // the IO thread trying to access it yet.
205 GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_);
208 // static
209 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple* registry) {
210 net::SSLConfig default_config;
211 registry->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled,
212 default_config.rev_checking_enabled);
213 registry->RegisterBooleanPref(
214 prefs::kCertRevocationCheckingRequiredLocalAnchors,
215 default_config.rev_checking_required_local_anchors);
216 registry->RegisterStringPref(prefs::kSSLVersionMin, std::string());
217 registry->RegisterStringPref(prefs::kSSLVersionMax, std::string());
218 registry->RegisterStringPref(prefs::kSSLVersionFallbackMin, std::string());
219 registry->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting,
220 !default_config.false_start_enabled);
221 registry->RegisterListPref(prefs::kCipherSuiteBlacklist);
224 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
225 return ssl_config_service_.get();
228 void SSLConfigServiceManagerPref::OnPreferenceChanged(
229 PrefService* prefs,
230 const std::string& pref_name_in) {
231 DCHECK_CURRENTLY_ON(BrowserThread::UI);
232 DCHECK(prefs);
233 if (pref_name_in == prefs::kCipherSuiteBlacklist)
234 OnDisabledCipherSuitesChange(prefs);
236 net::SSLConfig new_config;
237 GetSSLConfigFromPrefs(&new_config);
239 // Post a task to |io_loop| with the new configuration, so it can
240 // update |cached_config_|.
241 BrowserThread::PostTask(
242 BrowserThread::IO,
243 FROM_HERE,
244 base::Bind(
245 &SSLConfigServicePref::SetNewSSLConfig,
246 ssl_config_service_.get(),
247 new_config));
250 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
251 net::SSLConfig* config) {
252 // rev_checking_enabled was formerly a user-settable preference, but now
253 // it is managed-only.
254 if (rev_checking_enabled_.IsManaged())
255 config->rev_checking_enabled = rev_checking_enabled_.GetValue();
256 else
257 config->rev_checking_enabled = false;
258 config->rev_checking_required_local_anchors =
259 rev_checking_required_local_anchors_.GetValue();
260 std::string version_min_str = ssl_version_min_.GetValue();
261 std::string version_max_str = ssl_version_max_.GetValue();
262 std::string version_fallback_min_str = ssl_version_fallback_min_.GetValue();
263 config->version_min = net::kDefaultSSLVersionMin;
264 config->version_max = net::SSLClientSocket::GetMaxSupportedSSLVersion();
265 config->version_fallback_min = net::kDefaultSSLVersionFallbackMin;
266 uint16 version_min = SSLProtocolVersionFromString(version_min_str);
267 uint16 version_max = SSLProtocolVersionFromString(version_max_str);
268 uint16 version_fallback_min =
269 SSLProtocolVersionFromString(version_fallback_min_str);
270 if (version_min) {
271 config->version_min = version_min;
273 if (version_max) {
274 uint16 supported_version_max = config->version_max;
275 config->version_max = std::min(supported_version_max, version_max);
277 if (version_fallback_min) {
278 config->version_fallback_min = version_fallback_min;
280 config->disabled_cipher_suites = disabled_cipher_suites_;
281 // disabling False Start also happens to disable record splitting.
282 config->false_start_enabled = !ssl_record_splitting_disabled_.GetValue();
285 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
286 PrefService* local_state) {
287 const base::ListValue* value =
288 local_state->GetList(prefs::kCipherSuiteBlacklist);
289 disabled_cipher_suites_ = ParseCipherSuites(ListValueToStringVector(value));
292 ////////////////////////////////////////////////////////////////////////////////
293 // SSLConfigServiceManager
295 // static
296 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
297 PrefService* local_state) {
298 return new SSLConfigServiceManagerPref(local_state);
301 // static
302 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple* registry) {
303 SSLConfigServiceManagerPref::RegisterPrefs(registry);