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"
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
;
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());
34 for (base::ListValue::const_iterator it
= value
->begin(); it
!= value
->end();
36 if (!(*it
)->GetAsString(&s
))
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: "
59 cipher_suites
.push_back(cipher_suite
);
61 std::sort(cipher_suites
.begin(), cipher_suites
.end());
65 // Returns the string representation of an SSL protocol version. Returns an
66 // empty string on error.
67 std::string
SSLProtocolVersionToString(uint16 version
) {
69 case net::SSL_PROTOCOL_VERSION_SSL3
:
71 case net::SSL_PROTOCOL_VERSION_TLS1
:
73 case net::SSL_PROTOCOL_VERSION_TLS1_1
:
75 case net::SSL_PROTOCOL_VERSION_TLS1_2
:
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
;
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
107 class SSLConfigServicePref
: public net::SSLConfigService
{
109 SSLConfigServicePref() {}
111 // Store SSL config settings in |config|. Must only be called from IO thread.
112 virtual void GetSSLConfig(net::SSLConfig
* config
) OVERRIDE
;
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
{
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
;
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()) {
194 PrefChangeRegistrar::NamedChangeCallback local_state_callback
= base::Bind(
195 &SSLConfigServiceManagerPref::OnPreferenceChanged
,
196 base::Unretained(this),
199 rev_checking_enabled_
.Init(
200 prefs::kCertRevocationCheckingEnabled
, local_state
, local_state_callback
);
201 rev_checking_required_local_anchors_
.Init(
202 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
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
,
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_
);
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(
258 const std::string
& pref_name_in
) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
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(
273 &SSLConfigServicePref::SetNewSSLConfig
,
274 ssl_config_service_
.get(),
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
);
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
);
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
322 SSLConfigServiceManager
* SSLConfigServiceManager::CreateDefaultManager(
323 PrefService
* local_state
) {
324 return new SSLConfigServiceManagerPref(local_state
);
328 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
329 SSLConfigServiceManagerPref::RegisterPrefs(registry
);