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::kSSLVersionTLSv1
) {
79 version
= net::SSL_PROTOCOL_VERSION_TLS1
;
80 } else if (version_str
== switches::kSSLVersionTLSv11
) {
81 version
= net::SSL_PROTOCOL_VERSION_TLS1_1
;
82 } else if (version_str
== switches::kSSLVersionTLSv12
) {
83 version
= net::SSL_PROTOCOL_VERSION_TLS1_2
;
90 ////////////////////////////////////////////////////////////////////////////////
91 // SSLConfigServicePref
93 // An SSLConfigService which stores a cached version of the current SSLConfig
94 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
96 class SSLConfigServicePref
: public net::SSLConfigService
{
98 SSLConfigServicePref() {}
100 // Store SSL config settings in |config|. Must only be called from IO thread.
101 void GetSSLConfig(net::SSLConfig
* config
) override
;
103 bool SupportsFastradioPadding(const GURL
& url
) override
;
106 // Allow the pref watcher to update our internal state.
107 friend class SSLConfigServiceManagerPref
;
109 ~SSLConfigServicePref() override
{}
111 // This method is posted to the IO thread from the browser thread to carry the
112 // new config information.
113 void SetNewSSLConfig(const net::SSLConfig
& new_config
);
115 // Cached value of prefs, should only be accessed from IO thread.
116 net::SSLConfig cached_config_
;
118 DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref
);
121 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig
* config
) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
123 *config
= cached_config_
;
126 bool SSLConfigServicePref::SupportsFastradioPadding(const GURL
& url
) {
127 return google_util::IsGoogleHostname(url
.host(),
128 google_util::ALLOW_SUBDOMAIN
);
131 void SSLConfigServicePref::SetNewSSLConfig(
132 const net::SSLConfig
& new_config
) {
133 net::SSLConfig orig_config
= cached_config_
;
134 cached_config_
= new_config
;
135 ProcessConfigUpdate(orig_config
, new_config
);
138 ////////////////////////////////////////////////////////////////////////////////
139 // SSLConfigServiceManagerPref
141 // The manager for holding and updating an SSLConfigServicePref instance.
142 class SSLConfigServiceManagerPref
143 : public SSLConfigServiceManager
{
145 explicit SSLConfigServiceManagerPref(PrefService
* local_state
);
146 ~SSLConfigServiceManagerPref() override
{}
148 // Register local_state SSL preferences.
149 static void RegisterPrefs(PrefRegistrySimple
* registry
);
151 net::SSLConfigService
* Get() override
;
154 // Callback for preference changes. This will post the changes to the IO
155 // thread with SetNewSSLConfig.
156 void OnPreferenceChanged(PrefService
* prefs
,
157 const std::string
& pref_name
);
159 // Store SSL config settings in |config|, directly from the preferences. Must
160 // only be called from UI thread.
161 void GetSSLConfigFromPrefs(net::SSLConfig
* config
);
163 // Processes changes to the disabled cipher suites preference, updating the
164 // cached list of parsed SSL/TLS cipher suites that are disabled.
165 void OnDisabledCipherSuitesChange(PrefService
* local_state
);
167 PrefChangeRegistrar local_state_change_registrar_
;
169 // The local_state prefs (should only be accessed from UI thread)
170 BooleanPrefMember rev_checking_enabled_
;
171 BooleanPrefMember rev_checking_required_local_anchors_
;
172 StringPrefMember ssl_version_min_
;
173 StringPrefMember ssl_version_max_
;
174 StringPrefMember ssl_version_fallback_min_
;
175 BooleanPrefMember ssl_record_splitting_disabled_
;
177 // The cached list of disabled SSL cipher suites.
178 std::vector
<uint16
> disabled_cipher_suites_
;
180 scoped_refptr
<SSLConfigServicePref
> ssl_config_service_
;
182 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref
);
185 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
186 PrefService
* local_state
)
187 : ssl_config_service_(new SSLConfigServicePref()) {
190 PrefChangeRegistrar::NamedChangeCallback local_state_callback
= base::Bind(
191 &SSLConfigServiceManagerPref::OnPreferenceChanged
,
192 base::Unretained(this),
195 rev_checking_enabled_
.Init(
196 prefs::kCertRevocationCheckingEnabled
, local_state
, local_state_callback
);
197 rev_checking_required_local_anchors_
.Init(
198 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
200 local_state_callback
);
201 ssl_version_min_
.Init(
202 prefs::kSSLVersionMin
, local_state
, local_state_callback
);
203 ssl_version_max_
.Init(
204 prefs::kSSLVersionMax
, local_state
, local_state_callback
);
205 ssl_version_fallback_min_
.Init(
206 prefs::kSSLVersionFallbackMin
, local_state
, local_state_callback
);
207 ssl_record_splitting_disabled_
.Init(
208 prefs::kDisableSSLRecordSplitting
, local_state
, local_state_callback
);
210 local_state_change_registrar_
.Init(local_state
);
211 local_state_change_registrar_
.Add(
212 prefs::kCipherSuiteBlacklist
, local_state_callback
);
214 OnDisabledCipherSuitesChange(local_state
);
216 // Initialize from UI thread. This is okay as there shouldn't be anything on
217 // the IO thread trying to access it yet.
218 GetSSLConfigFromPrefs(&ssl_config_service_
->cached_config_
);
222 void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple
* registry
) {
223 net::SSLConfig default_config
;
224 registry
->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled
,
225 default_config
.rev_checking_enabled
);
226 registry
->RegisterBooleanPref(
227 prefs::kCertRevocationCheckingRequiredLocalAnchors
,
228 default_config
.rev_checking_required_local_anchors
);
229 registry
->RegisterStringPref(prefs::kSSLVersionMin
, std::string());
230 registry
->RegisterStringPref(prefs::kSSLVersionMax
, std::string());
231 registry
->RegisterStringPref(prefs::kSSLVersionFallbackMin
, std::string());
232 registry
->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting
,
233 !default_config
.false_start_enabled
);
234 registry
->RegisterListPref(prefs::kCipherSuiteBlacklist
);
237 net::SSLConfigService
* SSLConfigServiceManagerPref::Get() {
238 return ssl_config_service_
.get();
241 void SSLConfigServiceManagerPref::OnPreferenceChanged(
243 const std::string
& pref_name_in
) {
244 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
246 if (pref_name_in
== prefs::kCipherSuiteBlacklist
)
247 OnDisabledCipherSuitesChange(prefs
);
249 net::SSLConfig new_config
;
250 GetSSLConfigFromPrefs(&new_config
);
252 // Post a task to |io_loop| with the new configuration, so it can
253 // update |cached_config_|.
254 BrowserThread::PostTask(
258 &SSLConfigServicePref::SetNewSSLConfig
,
259 ssl_config_service_
.get(),
263 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
264 net::SSLConfig
* config
) {
265 // rev_checking_enabled was formerly a user-settable preference, but now
266 // it is managed-only.
267 if (rev_checking_enabled_
.IsManaged())
268 config
->rev_checking_enabled
= rev_checking_enabled_
.GetValue();
270 config
->rev_checking_enabled
= false;
271 config
->rev_checking_required_local_anchors
=
272 rev_checking_required_local_anchors_
.GetValue();
273 std::string version_min_str
= ssl_version_min_
.GetValue();
274 std::string version_max_str
= ssl_version_max_
.GetValue();
275 std::string version_fallback_min_str
= ssl_version_fallback_min_
.GetValue();
276 config
->version_min
= net::kDefaultSSLVersionMin
;
277 config
->version_max
= net::SSLClientSocket::GetMaxSupportedSSLVersion();
278 config
->version_fallback_min
= net::kDefaultSSLVersionFallbackMin
;
279 uint16 version_min
= SSLProtocolVersionFromString(version_min_str
);
280 uint16 version_max
= SSLProtocolVersionFromString(version_max_str
);
281 uint16 version_fallback_min
=
282 SSLProtocolVersionFromString(version_fallback_min_str
);
284 config
->version_min
= version_min
;
287 uint16 supported_version_max
= config
->version_max
;
288 config
->version_max
= std::min(supported_version_max
, version_max
);
290 if (version_fallback_min
) {
291 config
->version_fallback_min
= version_fallback_min
;
293 config
->disabled_cipher_suites
= disabled_cipher_suites_
;
294 // disabling False Start also happens to disable record splitting.
295 config
->false_start_enabled
= !ssl_record_splitting_disabled_
.GetValue();
297 base::StringPiece group
=
298 base::FieldTrialList::FindFullName(kClientHelloFieldTrialName
);
299 if (group
.starts_with(kClientHelloFieldTrialEnabledGroupName
)) {
300 config
->fastradio_padding_enabled
= true;
304 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
305 PrefService
* local_state
) {
306 const base::ListValue
* value
=
307 local_state
->GetList(prefs::kCipherSuiteBlacklist
);
308 disabled_cipher_suites_
= ParseCipherSuites(ListValueToStringVector(value
));
311 ////////////////////////////////////////////////////////////////////////////////
312 // SSLConfigServiceManager
315 SSLConfigServiceManager
* SSLConfigServiceManager::CreateDefaultManager(
316 PrefService
* local_state
) {
317 return new SSLConfigServiceManagerPref(local_state
);
321 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
322 SSLConfigServiceManagerPref::RegisterPrefs(registry
);