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..b51ab9a2c1387464d3d4e7675cf814a76cb1e66e 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" |
| @@ -46,6 +48,16 @@ void LoadNSSCertificates(net::CertificateList* cert_list) { |
| net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); |
| } |
| +void CallOpenPersistentNSSDB() { |
| + // 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(); |
| +} |
| + |
| } // namespace |
| CertLoader::CertLoader() |
| @@ -58,10 +70,18 @@ CertLoader::CertLoader() |
| base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)), |
| initialize_token_factory_(this), |
| update_certificates_factory_(this) { |
| +} |
| + |
| +void CertLoader::Init() { |
| net::CertDatabase::GetInstance()->AddObserver(this); |
| if (LoginState::IsInitialized()) |
| LoginState::Get()->AddObserver(this); |
| - RequestCertificates(); |
| +} |
| + |
| +void CertLoader::SetCryptoTaskRunner( |
| + const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner) { |
| + crypto_task_runner_ = crypto_task_runner; |
| + MaybeRequestCertificates(); |
| } |
| CertLoader::~CertLoader() { |
| @@ -86,36 +106,44 @@ bool CertLoader::IsHardwareBacked() const { |
| return !tpm_token_name_.empty(); |
| } |
| -void CertLoader::RequestCertificates() { |
| +void CertLoader::MaybeRequestCertificates() { |
| CHECK(thread_checker_.CalledOnValidThread()); |
| + if (certificates_requested_ || |
| + !LoginState::Get()->IsUserLoggedIn() || |
|
Ryan Sleevi
2013/06/12 20:58:50
Is this check safe, considering the check on line
stevenjb
2013/06/12 21:08:31
Good catch, thanks. (This is a merge bug, the code
|
| + !crypto_task_runner_.get()) |
| + return; |
| + |
| const bool logged_in = LoginState::IsInitialized() ? |
| LoginState::Get()->IsUserLoggedIn() : false; |
| VLOG(1) << "RequestCertificates: " << logged_in; |
| - if (certificates_requested_ || !logged_in) |
| + if (!logged_in) |
| return; |
| 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(&CallOpenPersistentNSSDB), |
| + 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 +166,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 +187,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 +197,12 @@ void CertLoader::RetryTokenInitializationLater() { |
| tpm_request_delay_ = GetNextRequestDelayMs(tpm_request_delay_); |
| } |
| +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 +279,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; |
| @@ -303,7 +346,7 @@ void CertLoader::OnCertRemoved(const net::X509Certificate* cert) { |
| void CertLoader::LoggedInStateChanged(LoginState::LoggedInState state) { |
| VLOG(1) << "LoggedInStateChanged: " << state; |
| - RequestCertificates(); |
| + MaybeRequestCertificates(); |
| } |
| } // namespace chromeos |