Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 | 4 |
| 5 #include "chromeos/network/cert_loader.h" | 5 #include "chromeos/network/cert_loader.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/chromeos/chromeos_version.h" | 9 #include "base/chromeos/chromeos_version.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | |
| 10 #include "base/observer_list.h" | 11 #include "base/observer_list.h" |
| 12 #include "base/sequenced_task_runner.h" | |
| 11 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
| 13 #include "base/threading/worker_pool.h" | 15 #include "base/threading/worker_pool.h" |
| 14 #include "chromeos/dbus/cryptohome_client.h" | 16 #include "chromeos/dbus/cryptohome_client.h" |
| 15 #include "chromeos/dbus/dbus_thread_manager.h" | 17 #include "chromeos/dbus/dbus_thread_manager.h" |
| 16 #include "crypto/encryptor.h" | 18 #include "crypto/encryptor.h" |
| 17 #include "crypto/nss_util.h" | 19 #include "crypto/nss_util.h" |
| 18 #include "crypto/sha2.h" | 20 #include "crypto/sha2.h" |
| 19 #include "crypto/symmetric_key.h" | 21 #include "crypto/symmetric_key.h" |
| 20 #include "net/cert/nss_cert_database.h" | 22 #include "net/cert/nss_cert_database.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 51 CertLoader::CertLoader() | 53 CertLoader::CertLoader() |
| 52 : certificates_requested_(false), | 54 : certificates_requested_(false), |
| 53 certificates_loaded_(false), | 55 certificates_loaded_(false), |
| 54 certificates_update_required_(false), | 56 certificates_update_required_(false), |
| 55 certificates_update_running_(false), | 57 certificates_update_running_(false), |
| 56 tpm_token_state_(TPM_STATE_UNKNOWN), | 58 tpm_token_state_(TPM_STATE_UNKNOWN), |
| 57 tpm_request_delay_( | 59 tpm_request_delay_( |
| 58 base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)), | 60 base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)), |
| 59 initialize_token_factory_(this), | 61 initialize_token_factory_(this), |
| 60 update_certificates_factory_(this) { | 62 update_certificates_factory_(this) { |
| 63 } | |
| 64 | |
| 65 void CertLoader::Init( | |
| 66 const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner) { | |
| 67 main_task_runner_ = base::MessageLoopProxy::current(); | |
| 68 crypto_task_runner_ = crypto_task_runner; | |
| 61 net::CertDatabase::GetInstance()->AddObserver(this); | 69 net::CertDatabase::GetInstance()->AddObserver(this); |
| 62 if (LoginState::IsInitialized()) | 70 if (LoginState::IsInitialized()) |
| 63 LoginState::Get()->AddObserver(this); | 71 LoginState::Get()->AddObserver(this); |
| 64 RequestCertificates(); | 72 RequestCertificates(); |
| 65 } | 73 } |
| 66 | 74 |
| 67 CertLoader::~CertLoader() { | 75 CertLoader::~CertLoader() { |
| 68 net::CertDatabase::GetInstance()->RemoveObserver(this); | 76 net::CertDatabase::GetInstance()->RemoveObserver(this); |
| 69 if (LoginState::IsInitialized()) | 77 if (LoginState::IsInitialized()) |
| 70 LoginState::Get()->RemoveObserver(this); | 78 LoginState::Get()->RemoveObserver(this); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 89 void CertLoader::RequestCertificates() { | 97 void CertLoader::RequestCertificates() { |
| 90 CHECK(thread_checker_.CalledOnValidThread()); | 98 CHECK(thread_checker_.CalledOnValidThread()); |
| 91 const bool logged_in = LoginState::IsInitialized() ? | 99 const bool logged_in = LoginState::IsInitialized() ? |
| 92 LoginState::Get()->IsUserLoggedIn() : false; | 100 LoginState::Get()->IsUserLoggedIn() : false; |
| 93 VLOG(1) << "RequestCertificates: " << logged_in; | 101 VLOG(1) << "RequestCertificates: " << logged_in; |
| 94 if (certificates_requested_ || !logged_in) | 102 if (certificates_requested_ || !logged_in) |
| 95 return; | 103 return; |
| 96 | 104 |
| 97 certificates_requested_ = true; | 105 certificates_requested_ = true; |
| 98 | 106 |
| 107 crypto_task_runner_->PostTask( | |
| 108 FROM_HERE, | |
| 109 base::Bind(&CertLoader::CallOpenPersistentNSSDB, | |
| 110 initialize_token_factory_.GetWeakPtr())); | |
| 111 } | |
| 112 | |
| 113 void CertLoader::CallOpenPersistentNSSDB() { | |
| 114 VLOG(1) << "CallOpenPersistentNSSDB"; | |
|
Ryan Sleevi
2013/06/06 23:03:41
Necessary?
stevenjb
2013/06/07 02:37:47
This can be very helpful when debugging hardware t
| |
| 115 | |
| 99 // Ensure we've opened the user's key/certificate database. | 116 // Ensure we've opened the user's key/certificate database. |
| 100 crypto::OpenPersistentNSSDB(); | 117 crypto::OpenPersistentNSSDB(); |
| 101 if (base::chromeos::IsRunningOnChromeOS()) | 118 if (base::chromeos::IsRunningOnChromeOS()) |
| 102 crypto::EnableTPMTokenForNSS(); | 119 crypto::EnableTPMTokenForNSS(); |
| 103 | 120 |
| 104 // This is the entry point to the TPM token initialization process, which we | 121 // This is the entry point to the TPM token initialization process, |
| 105 // should do at most once. | 122 // which we should do at most once. |
| 106 DCHECK(!initialize_token_factory_.HasWeakPtrs()); | 123 DCHECK(tpm_token_state_ == TPM_STATE_UNKNOWN); |
|
Ryan Sleevi
2013/06/06 23:03:41
DCHECK_EQ
stevenjb
2013/06/07 02:37:47
Done.
| |
| 107 InitializeTokenAndLoadCertificates(); | 124 main_task_runner_->PostTask( |
| 125 FROM_HERE, | |
| 126 base::Bind(&CertLoader::InitializeTokenAndLoadCertificates, | |
| 127 initialize_token_factory_.GetWeakPtr())); | |
| 108 } | 128 } |
| 109 | 129 |
| 110 void CertLoader::InitializeTokenAndLoadCertificates() { | 130 void CertLoader::InitializeTokenAndLoadCertificates() { |
| 111 CHECK(thread_checker_.CalledOnValidThread()); | 131 CHECK(thread_checker_.CalledOnValidThread()); |
| 112 VLOG(1) << "InitializeTokenAndLoadCertificates"; | 132 VLOG(1) << "InitializeTokenAndLoadCertificates"; |
| 113 | 133 |
| 114 switch (tpm_token_state_) { | 134 switch (tpm_token_state_) { |
| 115 case TPM_STATE_UNKNOWN: { | 135 case TPM_STATE_UNKNOWN: { |
| 116 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( | 136 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( |
| 117 base::Bind(&CertLoader::OnTpmIsEnabled, | 137 base::Bind(&CertLoader::OnTpmIsEnabled, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 131 } | 151 } |
| 132 case TPM_TOKEN_READY: { | 152 case TPM_TOKEN_READY: { |
| 133 // Retrieve token_name_ and user_pin_ here since they will never change | 153 // Retrieve token_name_ and user_pin_ here since they will never change |
| 134 // and CryptohomeClient calls are not thread safe. | 154 // and CryptohomeClient calls are not thread safe. |
| 135 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo( | 155 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo( |
| 136 base::Bind(&CertLoader::OnPkcs11GetTpmTokenInfo, | 156 base::Bind(&CertLoader::OnPkcs11GetTpmTokenInfo, |
| 137 initialize_token_factory_.GetWeakPtr())); | 157 initialize_token_factory_.GetWeakPtr())); |
| 138 return; | 158 return; |
| 139 } | 159 } |
| 140 case TPM_TOKEN_INFO_RECEIVED: { | 160 case TPM_TOKEN_INFO_RECEIVED: { |
| 161 if (base::chromeos::IsRunningOnChromeOS()) { | |
| 162 crypto_task_runner_->PostTask( | |
| 163 FROM_HERE, | |
| 164 base::Bind(&CertLoader::CallInitializeTPMToken, | |
| 165 initialize_token_factory_.GetWeakPtr())); | |
| 166 return; | |
| 167 } | |
| 168 tpm_token_state_ = TPM_TOKEN_INITIALIZED; | |
| 169 // FALLTHROUGH_INTENDED | |
| 170 } | |
| 171 case TPM_TOKEN_INITIALIZED: { | |
| 141 InitializeNSSForTPMToken(); | 172 InitializeNSSForTPMToken(); |
| 142 return; | 173 return; |
| 143 } | 174 } |
| 144 case TPM_TOKEN_NSS_INITIALIZED: { | 175 case TPM_TOKEN_NSS_INITIALIZED: { |
| 145 StartLoadCertificates(); | 176 StartLoadCertificates(); |
| 146 return; | 177 return; |
| 147 } | 178 } |
| 148 } | 179 } |
| 149 } | 180 } |
| 150 | 181 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 // TODO(stevenjb): The network code expects a slot ID, not a label. See | 258 // TODO(stevenjb): The network code expects a slot ID, not a label. See |
| 228 // crbug.com/201101. For now, use a hard coded, well known slot instead. | 259 // crbug.com/201101. For now, use a hard coded, well known slot instead. |
| 229 const char kHardcodedTpmSlot[] = "0"; | 260 const char kHardcodedTpmSlot[] = "0"; |
| 230 tpm_token_slot_ = kHardcodedTpmSlot; | 261 tpm_token_slot_ = kHardcodedTpmSlot; |
| 231 tpm_user_pin_ = user_pin; | 262 tpm_user_pin_ = user_pin; |
| 232 tpm_token_state_ = TPM_TOKEN_INFO_RECEIVED; | 263 tpm_token_state_ = TPM_TOKEN_INFO_RECEIVED; |
| 233 | 264 |
| 234 InitializeTokenAndLoadCertificates(); | 265 InitializeTokenAndLoadCertificates(); |
| 235 } | 266 } |
| 236 | 267 |
| 268 void CertLoader::CallInitializeTPMToken() { | |
| 269 if (crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) | |
| 270 tpm_token_state_ = TPM_TOKEN_INITIALIZED; | |
|
Ryan Sleevi
2013/06/06 23:03:41
THREADING: You're mutating this object on another
stevenjb
2013/06/07 02:37:47
Was that rhetorical? :) Fixed with the change sugg
| |
| 271 // Call InitializeNSSForTPMToken() on the main (UI) thread. | |
| 272 main_task_runner_->PostTask( | |
| 273 FROM_HERE, | |
| 274 base::Bind(&CertLoader::CallInitializeTPMToken, | |
| 275 initialize_token_factory_.GetWeakPtr())); | |
|
Ryan Sleevi
2013/06/06 23:03:41
THREADING: You're passing the same WeakPtr() on tw
stevenjb
2013/06/07 02:37:47
Yeah, that was an oversight. I like your suggestio
| |
| 276 } | |
| 277 | |
| 237 void CertLoader::InitializeNSSForTPMToken() { | 278 void CertLoader::InitializeNSSForTPMToken() { |
| 238 VLOG(1) << "InitializeNSSForTPMToken"; | 279 VLOG(1) << "InitializeNSSForTPMToken"; |
| 239 | 280 if (tpm_token_state_ != TPM_TOKEN_INITIALIZED) { |
| 240 if (base::chromeos::IsRunningOnChromeOS() && | |
| 241 !crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { | |
| 242 RetryTokenInitializationLater(); | 281 RetryTokenInitializationLater(); |
| 243 return; | 282 return; |
| 244 } | 283 } |
| 245 | 284 |
| 246 tpm_token_state_ = TPM_TOKEN_NSS_INITIALIZED; | 285 tpm_token_state_ = TPM_TOKEN_NSS_INITIALIZED; |
| 247 InitializeTokenAndLoadCertificates(); | 286 InitializeTokenAndLoadCertificates(); |
| 248 } | 287 } |
| 249 | 288 |
| 250 void CertLoader::StartLoadCertificates() { | 289 void CertLoader::StartLoadCertificates() { |
| 251 VLOG(1) << "StartLoadCertificates"; | 290 VLOG(1) << "StartLoadCertificates"; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 VLOG(1) << "OnCertRemoved"; | 339 VLOG(1) << "OnCertRemoved"; |
| 301 StartLoadCertificates(); | 340 StartLoadCertificates(); |
| 302 } | 341 } |
| 303 | 342 |
| 304 void CertLoader::LoggedInStateChanged(LoginState::LoggedInState state) { | 343 void CertLoader::LoggedInStateChanged(LoginState::LoggedInState state) { |
| 305 VLOG(1) << "LoggedInStateChanged: " << state; | 344 VLOG(1) << "LoggedInStateChanged: " << state; |
| 306 RequestCertificates(); | 345 RequestCertificates(); |
| 307 } | 346 } |
| 308 | 347 |
| 309 } // namespace chromeos | 348 } // namespace chromeos |
| OLD | NEW |