Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "chrome/browser/net/ssl_config_service_manager.h" | |
| 4 | 5 |
| 6 #include <algorithm> | |
| 7 #include <string> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 5 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 6 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 7 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 8 #include "chrome/browser/io_thread.h" | 14 #include "chrome/browser/io_thread.h" |
| 9 #include "chrome/browser/net/ssl_config_service_manager.h" | 15 #include "chrome/browser/prefs/pref_change_registrar.h" |
| 10 #include "chrome/browser/prefs/pref_member.h" | 16 #include "chrome/browser/prefs/pref_member.h" |
| 11 #include "chrome/browser/prefs/pref_service.h" | 17 #include "chrome/browser/prefs/pref_service.h" |
| 12 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
| 13 #include "content/common/content_notification_types.h" | 19 #include "chrome/common/chrome_notification_types.h" |
|
battre
2011/07/20 11:16:30
nit: order
| |
| 14 #include "content/common/notification_details.h" | 20 #include "content/common/notification_details.h" |
| 15 #include "content/common/notification_source.h" | 21 #include "content/common/notification_source.h" |
| 22 #include "net/base/ssl_cipher_suite_names.h" | |
| 16 #include "net/base/ssl_config_service.h" | 23 #include "net/base/ssl_config_service.h" |
| 17 | 24 |
| 25 namespace { | |
| 26 | |
| 27 // Converts a ListValue of StringValues into a vector of strings. Any Values | |
| 28 // which cannot be converted will be skipped. | |
| 29 std::vector<std::string> ListValueToStringVector(const ListValue* value) { | |
| 30 std::vector<std::string> results; | |
| 31 results.reserve(value->GetSize()); | |
| 32 std::string s; | |
| 33 for (ListValue::const_iterator it = value->begin(); it != value->end(); | |
| 34 ++it) { | |
| 35 if (!(*it)->GetAsString(&s)) | |
| 36 continue; | |
| 37 results.push_back(s); | |
| 38 } | |
| 39 return results; | |
| 40 } | |
| 41 | |
| 42 // Parses a vector of cipher suite strings, returning a sorted vector | |
| 43 // containing the underlying SSL/TLS cipher suites. Unrecognized/invalid | |
| 44 // cipher suites will be ignored. | |
| 45 std::vector<uint16> ParseCipherSuites( | |
| 46 const std::vector<std::string>& cipher_strings) { | |
| 47 std::vector<uint16> cipher_suites; | |
| 48 cipher_suites.reserve(cipher_strings.size()); | |
| 49 | |
| 50 for (std::vector<std::string>::const_iterator it = cipher_strings.begin(); | |
| 51 it != cipher_strings.end(); ++it) { | |
| 52 uint16 cipher_suite = 0; | |
| 53 if (!net::ParseSSLCipherString(*it, &cipher_suite)) { | |
| 54 LOG(ERROR) << "Ignoring unrecognized or unparsable cipher suite: " | |
| 55 << cipher_suite; | |
| 56 continue; | |
| 57 } | |
| 58 cipher_suites.push_back(cipher_suite); | |
| 59 } | |
| 60 std::sort(cipher_suites.begin(), cipher_suites.end()); | |
| 61 return cipher_suites; | |
| 62 } | |
| 63 | |
| 64 } // namespace | |
| 65 | |
| 18 //////////////////////////////////////////////////////////////////////////////// | 66 //////////////////////////////////////////////////////////////////////////////// |
| 19 // SSLConfigServicePref | 67 // SSLConfigServicePref |
| 20 | 68 |
| 21 // An SSLConfigService which stores a cached version of the current SSLConfig | 69 // An SSLConfigService which stores a cached version of the current SSLConfig |
| 22 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs | 70 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs |
| 23 // change. | 71 // change. |
| 24 class SSLConfigServicePref : public net::SSLConfigService { | 72 class SSLConfigServicePref : public net::SSLConfigService { |
| 25 public: | 73 public: |
| 26 SSLConfigServicePref() {} | 74 SSLConfigServicePref() {} |
| 27 virtual ~SSLConfigServicePref() {} | 75 virtual ~SSLConfigServicePref() {} |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 // Callback for preference changes. This will post the changes to the IO | 122 // Callback for preference changes. This will post the changes to the IO |
| 75 // thread with SetNewSSLConfig. | 123 // thread with SetNewSSLConfig. |
| 76 virtual void Observe(int type, | 124 virtual void Observe(int type, |
| 77 const NotificationSource& source, | 125 const NotificationSource& source, |
| 78 const NotificationDetails& details); | 126 const NotificationDetails& details); |
| 79 | 127 |
| 80 // Store SSL config settings in |config|, directly from the preferences. Must | 128 // Store SSL config settings in |config|, directly from the preferences. Must |
| 81 // only be called from UI thread. | 129 // only be called from UI thread. |
| 82 void GetSSLConfigFromPrefs(net::SSLConfig* config); | 130 void GetSSLConfigFromPrefs(net::SSLConfig* config); |
| 83 | 131 |
| 132 // Processes changes to the disabled cipher suites preference, updating the | |
| 133 // cached list of parsed SSL/TLS cipher suites that are disabled. | |
| 134 void OnDisabledCipherSuitesChange(PrefService* prefs); | |
| 135 | |
| 136 PrefChangeRegistrar pref_change_registrar_; | |
| 137 | |
| 84 // The prefs (should only be accessed from UI thread) | 138 // The prefs (should only be accessed from UI thread) |
| 85 BooleanPrefMember rev_checking_enabled_; | 139 BooleanPrefMember rev_checking_enabled_; |
| 86 BooleanPrefMember ssl3_enabled_; | 140 BooleanPrefMember ssl3_enabled_; |
| 87 BooleanPrefMember tls1_enabled_; | 141 BooleanPrefMember tls1_enabled_; |
| 88 | 142 |
| 143 // The cached list of disabled SSL cipher suites. | |
| 144 std::vector<uint16> disabled_cipher_suites_; | |
| 145 | |
| 89 scoped_refptr<SSLConfigServicePref> ssl_config_service_; | 146 scoped_refptr<SSLConfigServicePref> ssl_config_service_; |
| 90 | 147 |
| 91 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref); | 148 DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref); |
| 92 }; | 149 }; |
| 93 | 150 |
| 94 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref( | 151 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref( |
| 95 PrefService* local_state) | 152 PrefService* local_state) |
| 96 : ssl_config_service_(new SSLConfigServicePref()) { | 153 : ssl_config_service_(new SSLConfigServicePref()) { |
| 97 DCHECK(local_state); | 154 DCHECK(local_state); |
| 98 | 155 |
| 99 RegisterPrefs(local_state); | 156 RegisterPrefs(local_state); |
|
battre
2011/07/20 11:16:30
This introduces an interesting circular dependency
Ryan Sleevi
2011/07/21 07:05:12
I was surprised by this as well, when I was readin
| |
| 100 | 157 |
| 101 rev_checking_enabled_.Init(prefs::kCertRevocationCheckingEnabled, | 158 rev_checking_enabled_.Init(prefs::kCertRevocationCheckingEnabled, |
| 102 local_state, this); | 159 local_state, this); |
| 103 ssl3_enabled_.Init(prefs::kSSL3Enabled, local_state, this); | 160 ssl3_enabled_.Init(prefs::kSSL3Enabled, local_state, this); |
| 104 tls1_enabled_.Init(prefs::kTLS1Enabled, local_state, this); | 161 tls1_enabled_.Init(prefs::kTLS1Enabled, local_state, this); |
| 162 pref_change_registrar_.Init(local_state); | |
| 163 pref_change_registrar_.Add(prefs::kCipherSuiteBlacklist, this); | |
| 105 | 164 |
| 165 OnDisabledCipherSuitesChange(local_state); | |
| 106 // Initialize from UI thread. This is okay as there shouldn't be anything on | 166 // Initialize from UI thread. This is okay as there shouldn't be anything on |
| 107 // the IO thread trying to access it yet. | 167 // the IO thread trying to access it yet. |
| 108 GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_); | 168 GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_); |
| 109 } | 169 } |
| 110 | 170 |
| 111 // static | 171 // static |
| 112 void SSLConfigServiceManagerPref::RegisterPrefs(PrefService* prefs) { | 172 void SSLConfigServiceManagerPref::RegisterPrefs(PrefService* prefs) { |
| 113 net::SSLConfig default_config; | 173 net::SSLConfig default_config; |
| 114 if (!prefs->FindPreference(prefs::kCertRevocationCheckingEnabled)) { | 174 if (!prefs->FindPreference(prefs::kCertRevocationCheckingEnabled)) { |
| 115 prefs->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled, | 175 prefs->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled, |
| 116 default_config.rev_checking_enabled); | 176 default_config.rev_checking_enabled); |
| 117 } | 177 } |
| 118 if (!prefs->FindPreference(prefs::kSSL3Enabled)) { | 178 if (!prefs->FindPreference(prefs::kSSL3Enabled)) { |
| 119 prefs->RegisterBooleanPref(prefs::kSSL3Enabled, | 179 prefs->RegisterBooleanPref(prefs::kSSL3Enabled, |
| 120 default_config.ssl3_enabled); | 180 default_config.ssl3_enabled); |
| 121 } | 181 } |
| 122 if (!prefs->FindPreference(prefs::kTLS1Enabled)) { | 182 if (!prefs->FindPreference(prefs::kTLS1Enabled)) { |
| 123 prefs->RegisterBooleanPref(prefs::kTLS1Enabled, | 183 prefs->RegisterBooleanPref(prefs::kTLS1Enabled, |
| 124 default_config.tls1_enabled); | 184 default_config.tls1_enabled); |
| 125 } | 185 } |
| 186 if (!prefs->FindPreference(prefs::kCipherSuiteBlacklist)) { | |
| 187 prefs->RegisterListPref(prefs::kCipherSuiteBlacklist); | |
| 188 } | |
| 126 } | 189 } |
| 127 | 190 |
| 128 net::SSLConfigService* SSLConfigServiceManagerPref::Get() { | 191 net::SSLConfigService* SSLConfigServiceManagerPref::Get() { |
| 129 return ssl_config_service_; | 192 return ssl_config_service_; |
| 130 } | 193 } |
| 131 | 194 |
| 132 void SSLConfigServiceManagerPref::Observe(int type, | 195 void SSLConfigServiceManagerPref::Observe(int type, |
| 133 const NotificationSource& source, | 196 const NotificationSource& source, |
| 134 const NotificationDetails& details) { | 197 const NotificationDetails& details) { |
| 198 if (type == chrome::NOTIFICATION_PREF_CHANGED) { | |
| 199 std::string* pref_name_in = Details<std::string>(details).ptr(); | |
| 200 PrefService* prefs = Source<PrefService>(source).ptr(); | |
| 201 DCHECK(pref_name_in && prefs); | |
| 202 if (*pref_name_in == prefs::kCipherSuiteBlacklist) | |
| 203 OnDisabledCipherSuitesChange(prefs); | |
| 204 } | |
| 205 | |
| 135 base::Thread* io_thread = g_browser_process->io_thread(); | 206 base::Thread* io_thread = g_browser_process->io_thread(); |
| 136 if (io_thread) { | 207 if (io_thread) { |
| 137 net::SSLConfig new_config; | 208 net::SSLConfig new_config; |
| 138 GetSSLConfigFromPrefs(&new_config); | 209 GetSSLConfigFromPrefs(&new_config); |
| 139 | 210 |
| 140 // Post a task to |io_loop| with the new configuration, so it can | 211 // Post a task to |io_loop| with the new configuration, so it can |
| 141 // update |cached_config_|. | 212 // update |cached_config_|. |
| 142 io_thread->message_loop()->PostTask( | 213 io_thread->message_loop()->PostTask( |
| 143 FROM_HERE, | 214 FROM_HERE, |
| 144 NewRunnableMethod( | 215 NewRunnableMethod( |
| 145 ssl_config_service_.get(), | 216 ssl_config_service_.get(), |
| 146 &SSLConfigServicePref::SetNewSSLConfig, | 217 &SSLConfigServicePref::SetNewSSLConfig, |
| 147 new_config)); | 218 new_config)); |
| 148 } | 219 } |
| 149 } | 220 } |
| 150 | 221 |
| 151 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs( | 222 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs( |
| 152 net::SSLConfig* config) { | 223 net::SSLConfig* config) { |
| 153 config->rev_checking_enabled = rev_checking_enabled_.GetValue(); | 224 config->rev_checking_enabled = rev_checking_enabled_.GetValue(); |
| 154 config->ssl3_enabled = ssl3_enabled_.GetValue(); | 225 config->ssl3_enabled = ssl3_enabled_.GetValue(); |
| 155 config->tls1_enabled = tls1_enabled_.GetValue(); | 226 config->tls1_enabled = tls1_enabled_.GetValue(); |
| 227 config->disabled_cipher_suites = | |
| 228 disabled_cipher_suites_; | |
|
battre
2011/07/20 11:16:30
nit: single line
| |
| 156 SSLConfigServicePref::SetSSLConfigFlags(config); | 229 SSLConfigServicePref::SetSSLConfigFlags(config); |
| 157 } | 230 } |
| 158 | 231 |
| 232 void SSLConfigServiceManagerPref::OnDisabledCipherSuitesChange( | |
| 233 PrefService* prefs) { | |
| 234 const ListValue* value = prefs->GetList(prefs::kCipherSuiteBlacklist); | |
| 235 disabled_cipher_suites_ = ParseCipherSuites( | |
| 236 ListValueToStringVector(value)); | |
|
battre
2011/07/20 11:16:30
nit: single line?
| |
| 237 } | |
| 238 | |
| 159 //////////////////////////////////////////////////////////////////////////////// | 239 //////////////////////////////////////////////////////////////////////////////// |
| 160 // SSLConfigServiceManager | 240 // SSLConfigServiceManager |
| 161 | 241 |
| 162 // static | 242 // static |
| 163 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager( | 243 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager( |
| 164 PrefService* local_state) { | 244 PrefService* local_state) { |
| 165 return new SSLConfigServiceManagerPref(local_state); | 245 return new SSLConfigServiceManagerPref(local_state); |
| 166 } | 246 } |
| OLD | NEW |