• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
5 
6 #include <algorithm>
7 #include <string>
8 #include <vector>
9 
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"
23 
24 using content::BrowserThread;
25 
26 namespace {
27 
28 // Converts a ListValue of StringValues into a vector of strings. Any Values
29 // which cannot be converted will be skipped.
ListValueToStringVector(const base::ListValue * value)30 std::vector<std::string> ListValueToStringVector(const base::ListValue* value) {
31   std::vector<std::string> results;
32   results.reserve(value->GetSize());
33   std::string s;
34   for (base::ListValue::const_iterator it = value->begin(); it != value->end();
35        ++it) {
36     if (!(*it)->GetAsString(&s))
37       continue;
38     results.push_back(s);
39   }
40   return results;
41 }
42 
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.
ParseCipherSuites(const std::vector<std::string> & cipher_strings)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());
50 
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: "
56                  << *it;
57       continue;
58     }
59     cipher_suites.push_back(cipher_suite);
60   }
61   std::sort(cipher_suites.begin(), cipher_suites.end());
62   return cipher_suites;
63 }
64 
65 // Returns the string representation of an SSL protocol version. Returns an
66 // empty string on error.
SSLProtocolVersionToString(uint16 version)67 std::string SSLProtocolVersionToString(uint16 version) {
68   switch (version) {
69     case net::SSL_PROTOCOL_VERSION_SSL3:
70       return "ssl3";
71     case net::SSL_PROTOCOL_VERSION_TLS1:
72       return "tls1";
73     case net::SSL_PROTOCOL_VERSION_TLS1_1:
74       return "tls1.1";
75     case net::SSL_PROTOCOL_VERSION_TLS1_2:
76       return "tls1.2";
77     default:
78       NOTREACHED();
79       return std::string();
80   }
81 }
82 
83 // Returns the SSL protocol version (as a uint16) represented by a string.
84 // Returns 0 if the string is invalid.
SSLProtocolVersionFromString(const std::string & version_str)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;
95   }
96   return version;
97 }
98 
99 }  // namespace
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 //  SSLConfigServicePref
103 
104 // An SSLConfigService which stores a cached version of the current SSLConfig
105 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
106 // change.
107 class SSLConfigServicePref : public net::SSLConfigService {
108  public:
SSLConfigServicePref()109   SSLConfigServicePref() {}
110 
111   // Store SSL config settings in |config|. Must only be called from IO thread.
112   virtual void GetSSLConfig(net::SSLConfig* config) OVERRIDE;
113 
114  private:
115   // Allow the pref watcher to update our internal state.
116   friend class SSLConfigServiceManagerPref;
117 
~SSLConfigServicePref()118   virtual ~SSLConfigServicePref() {}
119 
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);
123 
124   // Cached value of prefs, should only be accessed from IO thread.
125   net::SSLConfig cached_config_;
126 
127   DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref);
128 };
129 
GetSSLConfig(net::SSLConfig * config)130 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
131   *config = cached_config_;
132 }
133 
SetNewSSLConfig(const net::SSLConfig & new_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);
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 //  SSLConfigServiceManagerPref
143 
144 // The manager for holding and updating an SSLConfigServicePref instance.
145 class SSLConfigServiceManagerPref
146     : public SSLConfigServiceManager {
147  public:
148   explicit SSLConfigServiceManagerPref(PrefService* local_state);
~SSLConfigServiceManagerPref()149   virtual ~SSLConfigServiceManagerPref() {}
150 
151   // Register local_state SSL preferences.
152   static void RegisterPrefs(PrefRegistrySimple* registry);
153 
154   virtual net::SSLConfigService* Get() OVERRIDE;
155 
156  private:
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);
161 
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);
165 
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);
169 
170   PrefChangeRegistrar local_state_change_registrar_;
171 
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 ssl_record_splitting_disabled_;
178 
179   // The cached list of disabled SSL cipher suites.
180   std::vector<uint16> disabled_cipher_suites_;
181 
182   scoped_refptr<SSLConfigServicePref> ssl_config_service_;
183 
184   DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref);
185 };
186 
SSLConfigServiceManagerPref(PrefService * local_state)187 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
188     PrefService* local_state)
189     : ssl_config_service_(new SSLConfigServicePref()) {
190   DCHECK(local_state);
191 
192   PrefChangeRegistrar::NamedChangeCallback local_state_callback = base::Bind(
193       &SSLConfigServiceManagerPref::OnPreferenceChanged,
194       base::Unretained(this),
195       local_state);
196 
197   rev_checking_enabled_.Init(
198       prefs::kCertRevocationCheckingEnabled, local_state, local_state_callback);
199   rev_checking_required_local_anchors_.Init(
200       prefs::kCertRevocationCheckingRequiredLocalAnchors,
201       local_state,
202       local_state_callback);
203   ssl_version_min_.Init(
204       prefs::kSSLVersionMin, local_state, local_state_callback);
205   ssl_version_max_.Init(
206       prefs::kSSLVersionMax, local_state, local_state_callback);
207   ssl_record_splitting_disabled_.Init(
208       prefs::kDisableSSLRecordSplitting, local_state, local_state_callback);
209 
210   local_state_change_registrar_.Init(local_state);
211   local_state_change_registrar_.Add(
212       prefs::kCipherSuiteBlacklist, local_state_callback);
213 
214   OnDisabledCipherSuitesChange(local_state);
215 
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_);
219 }
220 
221 // static
RegisterPrefs(PrefRegistrySimple * registry)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   std::string version_min_str =
230       SSLProtocolVersionToString(default_config.version_min);
231   std::string version_max_str =
232       SSLProtocolVersionToString(default_config.version_max);
233   registry->RegisterStringPref(prefs::kSSLVersionMin, version_min_str);
234   registry->RegisterStringPref(prefs::kSSLVersionMax, version_max_str);
235   registry->RegisterBooleanPref(prefs::kDisableSSLRecordSplitting,
236                                 !default_config.false_start_enabled);
237   registry->RegisterListPref(prefs::kCipherSuiteBlacklist);
238 }
239 
Get()240 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
241   return ssl_config_service_.get();
242 }
243 
OnPreferenceChanged(PrefService * prefs,const std::string & pref_name_in)244 void SSLConfigServiceManagerPref::OnPreferenceChanged(
245     PrefService* prefs,
246     const std::string& pref_name_in) {
247   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248   DCHECK(prefs);
249   if (pref_name_in == prefs::kCipherSuiteBlacklist)
250     OnDisabledCipherSuitesChange(prefs);
251 
252   net::SSLConfig new_config;
253   GetSSLConfigFromPrefs(&new_config);
254 
255   // Post a task to |io_loop| with the new configuration, so it can
256   // update |cached_config_|.
257   BrowserThread::PostTask(
258       BrowserThread::IO,
259       FROM_HERE,
260       base::Bind(
261           &SSLConfigServicePref::SetNewSSLConfig,
262           ssl_config_service_.get(),
263           new_config));
264 }
265 
GetSSLConfigFromPrefs(net::SSLConfig * config)266 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
267     net::SSLConfig* config) {
268   // rev_checking_enabled was formerly a user-settable preference, but now
269   // it is managed-only.
270   if (rev_checking_enabled_.IsManaged())
271     config->rev_checking_enabled = rev_checking_enabled_.GetValue();
272   else
273     config->rev_checking_enabled = false;
274   config->rev_checking_required_local_anchors =
275       rev_checking_required_local_anchors_.GetValue();
276   std::string version_min_str = ssl_version_min_.GetValue();
277   std::string version_max_str = ssl_version_max_.GetValue();
278   config->version_min = net::kDefaultSSLVersionMin;
279   config->version_max = net::kDefaultSSLVersionMax;
280   uint16 version_min = SSLProtocolVersionFromString(version_min_str);
281   uint16 version_max = SSLProtocolVersionFromString(version_max_str);
282   if (version_min) {
283     // TODO(wtc): get the minimum SSL protocol version supported by the
284     // SSLClientSocket class. Right now it happens to be the same as the
285     // default minimum SSL protocol version because we enable all supported
286     // versions by default.
287     uint16 supported_version_min = config->version_min;
288     config->version_min = std::max(supported_version_min, version_min);
289   }
290   if (version_max) {
291     // TODO(wtc): get the maximum SSL protocol version supported by the
292     // SSLClientSocket class.
293     uint16 supported_version_max = config->version_max;
294     config->version_max = std::min(supported_version_max, version_max);
295   }
296   config->disabled_cipher_suites = disabled_cipher_suites_;
297   // disabling False Start also happens to disable record splitting.
298   config->false_start_enabled = !ssl_record_splitting_disabled_.GetValue();
299 }
300 
OnDisabledCipherSuitesChange(PrefService * local_state)301 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange(
302     PrefService* local_state) {
303   const base::ListValue* value =
304       local_state->GetList(prefs::kCipherSuiteBlacklist);
305   disabled_cipher_suites_ = ParseCipherSuites(ListValueToStringVector(value));
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 //  SSLConfigServiceManager
310 
311 // static
CreateDefaultManager(PrefService * local_state)312 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
313     PrefService* local_state) {
314   return new SSLConfigServiceManagerPref(local_state);
315 }
316 
317 // static
RegisterPrefs(PrefRegistrySimple * registry)318 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple* registry) {
319   SSLConfigServiceManagerPref::RegisterPrefs(registry);
320 }
321