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. 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. 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. 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. 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: 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 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 130 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) { 131 *config = cached_config_; 132 } 133 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); 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 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 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 240 net::SSLConfigService* SSLConfigServiceManagerPref::Get() { 241 return ssl_config_service_.get(); 242 } 243 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 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 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 312 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager( 313 PrefService* local_state) { 314 return new SSLConfigServiceManagerPref(local_state); 315 } 316 317 // static 318 void SSLConfigServiceManager::RegisterPrefs(PrefRegistrySimple* registry) { 319 SSLConfigServiceManagerPref::RegisterPrefs(registry); 320 } 321