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/pref_names.h"
19 #include "components/content_settings/core/common/content_settings.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 StringPrefMember ssl_version_fallback_min_
;
178 BooleanPrefMember ssl_record_splitting_disabled_
;
180 // The cached list of disabled SSL cipher suites.
181 std::vector
<uint16
> disabled_cipher_suites_
;
183 scoped_refptr
<SSLConfigServicePref
> ssl_config_service_
;
185 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref
);
188 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
189 PrefService
* local_state
)
190 : ssl_config_service_(new SSLConfigServicePref()) {
193 PrefChangeRegistrar::NamedChangeCallback local_state_callback
= base::Bind(
194 &SSLConfigServiceManagerPref::OnPreferenceChanged
,
195 base::Unretained(this),
198 rev_checking_enabled_
.Init(
199 prefs::kCertRevocationCheckingEnabled
, local_state
, local_state_callback
);
200 rev_checking_required_local_anchors_
.Init(
201 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
203 local_state_callback
);
204 ssl_version_min_
.Init(
205 prefs::kSSLVersionMin
, local_state
, local_state_callback
);
206 ssl_version_max_
.Init(
207 prefs::kSSLVersionMax
, local_state
, local_state_callback
);
208 ssl_version_fallback_min_
.Init(
209 prefs::kSSLVersionFallbackMin
, local_state
, local_state_callback
);
210 ssl_record_splitting_disabled_
.Init(
211 prefs::kDisableSSLRecordSplitting
, local_state
, local_state_callback
);
213 local_state_change_registrar_
.Init(local_state
);
214 local_state_change_registrar_
.Add(
215 prefs::kCipherSuiteBlacklist
, local_state_callback
);
217 OnDisabledCipherSuitesChange(local_state
);
219 // Initialize from UI thread. This is okay as there shouldn't be anything on
220 // the IO thread trying to access it yet.
221 GetSSLConfigFromPrefs(&ssl_config_service_
->cached_config_
);
225 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple
* registry
) {
226 net::SSLConfig default_config
;
227 registry
->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled
,
228 default_config
.rev_checking_enabled
);
229 registry
->RegisterBooleanPref(
230 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
231 default_config
.rev_checking_required_local_anchors
);
232 std::string version_min_str
=
233 SSLProtocolVersionToString(default_config
.version_min
);
234 std::string version_max_str
=
235 SSLProtocolVersionToString(default_config
.version_max
);
236 std::string version_fallback_min_str
=
237 SSLProtocolVersionToString(default_config
.version_fallback_min
);
238 registry
->RegisterStringPref(prefs::kSSLVersionMin
, version_min_str
);
239 registry
->RegisterStringPref(prefs::kSSLVersionMax
, version_max_str
);
240 registry
->RegisterStringPref(prefs::kSSLVersionFallbackMin
,
241 version_fallback_min_str
);
242 registry
->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting
,
243 !default_config
.false_start_enabled
);
244 registry
->RegisterListPref(prefs::kCipherSuiteBlacklist
);
247 net::SSLConfigService
* SSLConfigServiceManagerPref::Get() {
248 return ssl_config_service_
.get();
251 void SSLConfigServiceManagerPref::OnPreferenceChanged(
253 const std::string
& pref_name_in
) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
256 if (pref_name_in
== prefs::kCipherSuiteBlacklist
)
257 OnDisabledCipherSuitesChange(prefs
);
259 net::SSLConfig new_config
;
260 GetSSLConfigFromPrefs(&new_config
);
262 // Post a task to |io_loop| with the new configuration, so it can
263 // update |cached_config_|.
264 BrowserThread::PostTask(
268 &SSLConfigServicePref::SetNewSSLConfig
,
269 ssl_config_service_
.get(),
273 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
274 net::SSLConfig
* config
) {
275 // rev_checking_enabled was formerly a user-settable preference, but now
276 // it is managed-only.
277 if (rev_checking_enabled_
.IsManaged())
278 config
->rev_checking_enabled
= rev_checking_enabled_
.GetValue();
280 config
->rev_checking_enabled
= false;
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 std::string version_fallback_min_str
= ssl_version_fallback_min_
.GetValue();
286 config
->version_min
= net::kDefaultSSLVersionMin
;
287 config
->version_max
= net::kDefaultSSLVersionMax
;
288 config
->version_fallback_min
= net::kDefaultSSLVersionFallbackMin
;
289 uint16 version_min
= SSLProtocolVersionFromString(version_min_str
);
290 uint16 version_max
= SSLProtocolVersionFromString(version_max_str
);
291 uint16 version_fallback_min
=
292 SSLProtocolVersionFromString(version_fallback_min_str
);
294 // TODO(wtc): get the minimum SSL protocol version supported by the
295 // SSLClientSocket class. Right now it happens to be the same as the
296 // default minimum SSL protocol version because we enable all supported
297 // versions by default.
298 uint16 supported_version_min
= config
->version_min
;
299 config
->version_min
= std::max(supported_version_min
, version_min
);
302 // TODO(wtc): get the maximum SSL protocol version supported by the
303 // SSLClientSocket class.
304 uint16 supported_version_max
= config
->version_max
;
305 config
->version_max
= std::min(supported_version_max
, version_max
);
307 if (version_fallback_min
) {
308 config
->version_fallback_min
= version_fallback_min
;
310 config
->disabled_cipher_suites
= disabled_cipher_suites_
;
311 // disabling False Start also happens to disable record splitting.
312 config
->false_start_enabled
= !ssl_record_splitting_disabled_
.GetValue();
315 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
316 PrefService
* local_state
) {
317 const base::ListValue
* value
=
318 local_state
->GetList(prefs::kCipherSuiteBlacklist
);
319 disabled_cipher_suites_
= ParseCipherSuites(ListValueToStringVector(value
));
322 ////////////////////////////////////////////////////////////////////////////////
323 // SSLConfigServiceManager
326 SSLConfigServiceManager
* SSLConfigServiceManager::CreateDefaultManager(
327 PrefService
* local_state
) {
328 return new SSLConfigServiceManagerPref(local_state
);
332 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
333 SSLConfigServiceManagerPref::RegisterPrefs(registry
);