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/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 "components/google/core/browser/google_util.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "net/socket/ssl_client_socket.h"
25 #include "net/ssl/ssl_cipher_suite_names.h"
26 #include "net/ssl/ssl_config_service.h"
29 using content::BrowserThread
;
33 // Field trial for ClientHello padding.
34 const char kClientHelloFieldTrialName
[] = "FastRadioPadding";
35 const char kClientHelloFieldTrialEnabledGroupName
[] = "Enabled";
37 // Converts a ListValue of StringValues into a vector of strings. Any Values
38 // which cannot be converted will be skipped.
39 std::vector
<std::string
> ListValueToStringVector(const base::ListValue
* value
) {
40 std::vector
<std::string
> results
;
41 results
.reserve(value
->GetSize());
43 for (base::ListValue::const_iterator it
= value
->begin(); it
!= value
->end();
45 if (!(*it
)->GetAsString(&s
))
52 // Parses a vector of cipher suite strings, returning a sorted vector
53 // containing the underlying SSL/TLS cipher suites. Unrecognized/invalid
54 // cipher suites will be ignored.
55 std::vector
<uint16
> ParseCipherSuites(
56 const std::vector
<std::string
>& cipher_strings
) {
57 std::vector
<uint16
> cipher_suites
;
58 cipher_suites
.reserve(cipher_strings
.size());
60 for (std::vector
<std::string
>::const_iterator it
= cipher_strings
.begin();
61 it
!= cipher_strings
.end(); ++it
) {
62 uint16 cipher_suite
= 0;
63 if (!net::ParseSSLCipherString(*it
, &cipher_suite
)) {
64 LOG(ERROR
) << "Ignoring unrecognized or unparsable cipher suite: "
68 cipher_suites
.push_back(cipher_suite
);
70 std::sort(cipher_suites
.begin(), cipher_suites
.end());
74 // Returns the SSL protocol version (as a uint16) represented by a string.
75 // Returns 0 if the string is invalid.
76 uint16
SSLProtocolVersionFromString(const std::string
& version_str
) {
77 uint16 version
= 0; // Invalid.
78 if (version_str
== switches::kSSLVersionSSLv3
) {
79 version
= net::SSL_PROTOCOL_VERSION_SSL3
;
80 } else if (version_str
== switches::kSSLVersionTLSv1
) {
81 version
= net::SSL_PROTOCOL_VERSION_TLS1
;
82 } else if (version_str
== switches::kSSLVersionTLSv11
) {
83 version
= net::SSL_PROTOCOL_VERSION_TLS1_1
;
84 } else if (version_str
== switches::kSSLVersionTLSv12
) {
85 version
= net::SSL_PROTOCOL_VERSION_TLS1_2
;
92 ////////////////////////////////////////////////////////////////////////////////
93 // SSLConfigServicePref
95 // An SSLConfigService which stores a cached version of the current SSLConfig
96 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
98 class SSLConfigServicePref
: public net::SSLConfigService
{
100 SSLConfigServicePref() {}
102 // Store SSL config settings in |config|. Must only be called from IO thread.
103 void GetSSLConfig(net::SSLConfig
* config
) override
;
105 bool SupportsFastradioPadding(const GURL
& url
) override
;
108 // Allow the pref watcher to update our internal state.
109 friend class SSLConfigServiceManagerPref
;
111 ~SSLConfigServicePref() override
{}
113 // This method is posted to the IO thread from the browser thread to carry the
114 // new config information.
115 void SetNewSSLConfig(const net::SSLConfig
& new_config
);
117 // Cached value of prefs, should only be accessed from IO thread.
118 net::SSLConfig cached_config_
;
120 DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref
);
123 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig
* config
) {
124 *config
= cached_config_
;
127 bool SSLConfigServicePref::SupportsFastradioPadding(const GURL
& url
) {
128 return google_util::IsGoogleHostname(url
.host(),
129 google_util::ALLOW_SUBDOMAIN
);
132 void SSLConfigServicePref::SetNewSSLConfig(
133 const net::SSLConfig
& new_config
) {
134 net::SSLConfig orig_config
= cached_config_
;
135 cached_config_
= new_config
;
136 ProcessConfigUpdate(orig_config
, new_config
);
139 ////////////////////////////////////////////////////////////////////////////////
140 // SSLConfigServiceManagerPref
142 // The manager for holding and updating an SSLConfigServicePref instance.
143 class SSLConfigServiceManagerPref
144 : public SSLConfigServiceManager
{
146 explicit SSLConfigServiceManagerPref(PrefService
* local_state
);
147 ~SSLConfigServiceManagerPref() override
{}
149 // Register local_state SSL preferences.
150 static void RegisterPrefs(PrefRegistrySimple
* registry
);
152 net::SSLConfigService
* Get() override
;
155 // Callback for preference changes. This will post the changes to the IO
156 // thread with SetNewSSLConfig.
157 void OnPreferenceChanged(PrefService
* prefs
,
158 const std::string
& pref_name
);
160 // Store SSL config settings in |config|, directly from the preferences. Must
161 // only be called from UI thread.
162 void GetSSLConfigFromPrefs(net::SSLConfig
* config
);
164 // Processes changes to the disabled cipher suites preference, updating the
165 // cached list of parsed SSL/TLS cipher suites that are disabled.
166 void OnDisabledCipherSuitesChange(PrefService
* local_state
);
168 PrefChangeRegistrar local_state_change_registrar_
;
170 // The local_state prefs (should only be accessed from UI thread)
171 BooleanPrefMember rev_checking_enabled_
;
172 BooleanPrefMember rev_checking_required_local_anchors_
;
173 StringPrefMember ssl_version_min_
;
174 StringPrefMember ssl_version_max_
;
175 StringPrefMember ssl_version_fallback_min_
;
176 BooleanPrefMember ssl_record_splitting_disabled_
;
178 // The cached list of disabled SSL cipher suites.
179 std::vector
<uint16
> disabled_cipher_suites_
;
181 scoped_refptr
<SSLConfigServicePref
> ssl_config_service_
;
183 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref
);
186 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
187 PrefService
* local_state
)
188 : ssl_config_service_(new SSLConfigServicePref()) {
191 PrefChangeRegistrar::NamedChangeCallback local_state_callback
= base::Bind(
192 &SSLConfigServiceManagerPref::OnPreferenceChanged
,
193 base::Unretained(this),
196 rev_checking_enabled_
.Init(
197 prefs::kCertRevocationCheckingEnabled
, local_state
, local_state_callback
);
198 rev_checking_required_local_anchors_
.Init(
199 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
201 local_state_callback
);
202 ssl_version_min_
.Init(
203 prefs::kSSLVersionMin
, local_state
, local_state_callback
);
204 ssl_version_max_
.Init(
205 prefs::kSSLVersionMax
, local_state
, local_state_callback
);
206 ssl_version_fallback_min_
.Init(
207 prefs::kSSLVersionFallbackMin
, local_state
, local_state_callback
);
208 ssl_record_splitting_disabled_
.Init(
209 prefs::kDisableSSLRecordSplitting
, local_state
, local_state_callback
);
211 local_state_change_registrar_
.Init(local_state
);
212 local_state_change_registrar_
.Add(
213 prefs::kCipherSuiteBlacklist
, local_state_callback
);
215 OnDisabledCipherSuitesChange(local_state
);
217 // Initialize from UI thread. This is okay as there shouldn't be anything on
218 // the IO thread trying to access it yet.
219 GetSSLConfigFromPrefs(&ssl_config_service_
->cached_config_
);
223 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple
* registry
) {
224 net::SSLConfig default_config
;
225 registry
->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled
,
226 default_config
.rev_checking_enabled
);
227 registry
->RegisterBooleanPref(
228 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
229 default_config
.rev_checking_required_local_anchors
);
230 registry
->RegisterStringPref(prefs::kSSLVersionMin
, "");
231 registry
->RegisterStringPref(prefs::kSSLVersionMax
, "");
232 registry
->RegisterStringPref(prefs::kSSLVersionFallbackMin
, "");
233 registry
->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting
,
234 !default_config
.false_start_enabled
);
235 registry
->RegisterListPref(prefs::kCipherSuiteBlacklist
);
238 net::SSLConfigService
* SSLConfigServiceManagerPref::Get() {
239 return ssl_config_service_
.get();
242 void SSLConfigServiceManagerPref::OnPreferenceChanged(
244 const std::string
& pref_name_in
) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
247 if (pref_name_in
== prefs::kCipherSuiteBlacklist
)
248 OnDisabledCipherSuitesChange(prefs
);
250 net::SSLConfig new_config
;
251 GetSSLConfigFromPrefs(&new_config
);
253 // Post a task to |io_loop| with the new configuration, so it can
254 // update |cached_config_|.
255 BrowserThread::PostTask(
259 &SSLConfigServicePref::SetNewSSLConfig
,
260 ssl_config_service_
.get(),
264 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
265 net::SSLConfig
* config
) {
266 // rev_checking_enabled was formerly a user-settable preference, but now
267 // it is managed-only.
268 if (rev_checking_enabled_
.IsManaged())
269 config
->rev_checking_enabled
= rev_checking_enabled_
.GetValue();
271 config
->rev_checking_enabled
= false;
272 config
->rev_checking_required_local_anchors
=
273 rev_checking_required_local_anchors_
.GetValue();
274 std::string version_min_str
= ssl_version_min_
.GetValue();
275 std::string version_max_str
= ssl_version_max_
.GetValue();
276 std::string version_fallback_min_str
= ssl_version_fallback_min_
.GetValue();
277 config
->version_min
= net::kDefaultSSLVersionMin
;
278 config
->version_max
= net::SSLClientSocket::GetMaxSupportedSSLVersion();
279 config
->version_fallback_min
= net::kDefaultSSLVersionFallbackMin
;
280 uint16 version_min
= SSLProtocolVersionFromString(version_min_str
);
281 uint16 version_max
= SSLProtocolVersionFromString(version_max_str
);
282 uint16 version_fallback_min
=
283 SSLProtocolVersionFromString(version_fallback_min_str
);
285 config
->version_min
= version_min
;
287 const std::string group
= base::FieldTrialList::FindFullName("SSLv3");
288 if (group
== "Enabled") {
289 config
->version_min
= net::SSL_PROTOCOL_VERSION_SSL3
;
293 uint16 supported_version_max
= config
->version_max
;
294 config
->version_max
= std::min(supported_version_max
, version_max
);
296 if (version_fallback_min
) {
297 config
->version_fallback_min
= version_fallback_min
;
299 config
->disabled_cipher_suites
= disabled_cipher_suites_
;
300 // disabling False Start also happens to disable record splitting.
301 config
->false_start_enabled
= !ssl_record_splitting_disabled_
.GetValue();
303 base::StringPiece group
=
304 base::FieldTrialList::FindFullName(kClientHelloFieldTrialName
);
305 if (group
.starts_with(kClientHelloFieldTrialEnabledGroupName
)) {
306 config
->fastradio_padding_enabled
= true;
310 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
311 PrefService
* local_state
) {
312 const base::ListValue
* value
=
313 local_state
->GetList(prefs::kCipherSuiteBlacklist
);
314 disabled_cipher_suites_
= ParseCipherSuites(ListValueToStringVector(value
));
317 ////////////////////////////////////////////////////////////////////////////////
318 // SSLConfigServiceManager
321 SSLConfigServiceManager
* SSLConfigServiceManager::CreateDefaultManager(
322 PrefService
* local_state
) {
323 return new SSLConfigServiceManagerPref(local_state
);
327 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
328 SSLConfigServiceManagerPref::RegisterPrefs(registry
);