Chromium Code Reviews| Index: chromeos/network/cert_loader.cc |
| diff --git a/chromeos/network/cert_loader.cc b/chromeos/network/cert_loader.cc |
| index f75f8bb959b6f2863e1254336eb9d77bb1ee5bde..6b052d3e85784f6ef484faf547c673533738bc26 100644 |
| --- a/chromeos/network/cert_loader.cc |
| +++ b/chromeos/network/cert_loader.cc |
| @@ -7,7 +7,9 @@ |
| #include <algorithm> |
| #include "base/chromeos/chromeos_version.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| #include "base/observer_list.h" |
| +#include "base/sequenced_task_runner.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/task_runner_util.h" |
| #include "base/threading/worker_pool.h" |
| @@ -57,7 +59,13 @@ CertLoader::CertLoader() |
| tpm_request_delay_( |
| base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)), |
| initialize_token_factory_(this), |
| - update_certificates_factory_(this) { |
| + update_certificates_factory_(this), |
| + crypto_factory_(this) { |
| +} |
| + |
| +void CertLoader::Init( |
| + const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner) { |
| + crypto_task_runner_ = crypto_task_runner; |
| net::CertDatabase::GetInstance()->AddObserver(this); |
| if (LoginState::IsInitialized()) |
| LoginState::Get()->AddObserver(this); |
| @@ -65,9 +73,23 @@ CertLoader::CertLoader() |
| } |
| CertLoader::~CertLoader() { |
| + CHECK(thread_checker_.CalledOnValidThread()); |
| net::CertDatabase::GetInstance()->RemoveObserver(this); |
| if (LoginState::IsInitialized()) |
| LoginState::Get()->RemoveObserver(this); |
| + InvalidateCryptoFactory(); |
| + InvalidateUpdateCertificatesFactory(); |
| + InvalidateInitializeTokenFactory(); |
| +} |
| + |
| +void CertLoader::InvalidateInitializeTokenFactory() { |
| + initialize_token_factory_.InvalidateWeakPtrs(); |
| +} |
| +void CertLoader::InvalidateUpdateCertificatesFactory() { |
| + update_certificates_factory_.InvalidateWeakPtrs(); |
| +} |
| +void CertLoader::InvalidateCryptoFactory() { |
| + crypto_factory_.InvalidateWeakPtrs(); |
| } |
| void CertLoader::AddObserver(CertLoader::Observer* observer) { |
| @@ -96,26 +118,30 @@ void CertLoader::RequestCertificates() { |
| certificates_requested_ = true; |
| - // Ensure we've opened the user's key/certificate database. |
| - crypto::OpenPersistentNSSDB(); |
| - if (base::chromeos::IsRunningOnChromeOS()) |
| - crypto::EnableTPMTokenForNSS(); |
| - |
| - // This is the entry point to the TPM token initialization process, which we |
| - // should do at most once. |
| - DCHECK(!initialize_token_factory_.HasWeakPtrs()); |
| + // This is the entry point to the TPM token initialization process, |
| + // which we should do at most once. |
| + DCHECK_EQ(tpm_token_state_, TPM_STATE_UNKNOWN); |
| InitializeTokenAndLoadCertificates(); |
| } |
| void CertLoader::InitializeTokenAndLoadCertificates() { |
| CHECK(thread_checker_.CalledOnValidThread()); |
| - VLOG(1) << "InitializeTokenAndLoadCertificates"; |
| + VLOG(1) << "InitializeTokenAndLoadCertificates: " << tpm_token_state_; |
| switch (tpm_token_state_) { |
| case TPM_STATE_UNKNOWN: { |
| + crypto_task_runner_->PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind(&CertLoader::CallOpenPersistentNSSDB, |
| + crypto_factory_.GetWeakPtr()), |
| + base::Bind(&CertLoader::OnPersistentNSSDBOpened, |
| + initialize_token_factory_.GetWeakPtr())); |
| + return; |
| + } |
| + case TPM_DB_OPENED: { |
| DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( |
| - base::Bind(&CertLoader::OnTpmIsEnabled, |
| - initialize_token_factory_.GetWeakPtr())); |
| + base::Bind(&CertLoader::OnTpmIsEnabled, |
| + initialize_token_factory_.GetWeakPtr())); |
| return; |
| } |
| case TPM_DISABLED: { |
| @@ -138,10 +164,20 @@ void CertLoader::InitializeTokenAndLoadCertificates() { |
| return; |
| } |
| case TPM_TOKEN_INFO_RECEIVED: { |
| - InitializeNSSForTPMToken(); |
| - return; |
| + if (base::chromeos::IsRunningOnChromeOS()) { |
| + base::PostTaskAndReplyWithResult( |
| + crypto_task_runner_.get(), |
| + FROM_HERE, |
| + base::Bind(&crypto::InitializeTPMToken, |
| + tpm_token_name_, tpm_user_pin_), |
| + base::Bind(&CertLoader::OnTPMTokenInitialized, |
| + initialize_token_factory_.GetWeakPtr())); |
| + return; |
| + } |
| + tpm_token_state_ = TPM_TOKEN_INITIALIZED; |
| + // FALL_THROUGH_INTENDED |
| } |
| - case TPM_TOKEN_NSS_INITIALIZED: { |
| + case TPM_TOKEN_INITIALIZED: { |
| StartLoadCertificates(); |
| return; |
| } |
| @@ -149,6 +185,7 @@ void CertLoader::InitializeTokenAndLoadCertificates() { |
| } |
| void CertLoader::RetryTokenInitializationLater() { |
| + CHECK(thread_checker_.CalledOnValidThread()); |
| LOG(WARNING) << "Re-Requesting Certificates later."; |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| @@ -158,6 +195,22 @@ void CertLoader::RetryTokenInitializationLater() { |
| tpm_request_delay_ = GetNextRequestDelayMs(tpm_request_delay_); |
| } |
| +void CertLoader::CallOpenPersistentNSSDB() { |
|
pneubeck (no reviews)
2013/06/07 14:00:49
could be a global function in anonymous namespace,
stevenjb
2013/06/07 20:48:14
Good point. Done.
|
| + // Called from crypto_task_runner_. |
| + VLOG(1) << "CallOpenPersistentNSSDB"; |
| + |
| + // Ensure we've opened the user's key/certificate database. |
| + crypto::OpenPersistentNSSDB(); |
| + if (base::chromeos::IsRunningOnChromeOS()) |
| + crypto::EnableTPMTokenForNSS(); |
| +} |
| + |
| +void CertLoader::OnPersistentNSSDBOpened() { |
| + VLOG(1) << "PersistentNSSDBOpened"; |
| + tpm_token_state_ = TPM_DB_OPENED; |
| + InitializeTokenAndLoadCertificates(); |
| +} |
| + |
| // For background see this discussion on dev-tech-crypto.lists.mozilla.org: |
| // http://web.archiveorange.com/archive/v/6JJW7E40sypfZGtbkzxX |
| // |
| @@ -234,21 +287,19 @@ void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, |
| InitializeTokenAndLoadCertificates(); |
| } |
| -void CertLoader::InitializeNSSForTPMToken() { |
| - VLOG(1) << "InitializeNSSForTPMToken"; |
| - |
| - if (base::chromeos::IsRunningOnChromeOS() && |
| - !crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { |
| +void CertLoader::OnTPMTokenInitialized(bool success) { |
| + VLOG(1) << "OnTPMTokenInitialized: " << success; |
| + if (!success) { |
| RetryTokenInitializationLater(); |
| return; |
| } |
| - |
| - tpm_token_state_ = TPM_TOKEN_NSS_INITIALIZED; |
| + tpm_token_state_ = TPM_TOKEN_INITIALIZED; |
| InitializeTokenAndLoadCertificates(); |
| } |
| void CertLoader::StartLoadCertificates() { |
| - VLOG(1) << "StartLoadCertificates"; |
| + CHECK(thread_checker_.CalledOnValidThread()); |
| + VLOG(1) << "StartLoadCertificates: " << certificates_update_running_; |
| if (certificates_update_running_) { |
| certificates_update_required_ = true; |