Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Unified Diff: chromeos/cert_loader.cc

Issue 135193007: Use user specific NSSDatabase in CertLoader. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromeos/cert_loader.cc
diff --git a/chromeos/cert_loader.cc b/chromeos/cert_loader.cc
index 70e49819d0840705d1a5c2b65e0f5e93612f2e5f..0eb179119f58ff207f3e88e4c5045cb12c5a6ba3 100644
--- a/chromeos/cert_loader.cc
+++ b/chromeos/cert_loader.cc
@@ -8,19 +8,61 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/message_loop/message_loop_proxy.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"
#include "crypto/nss_util.h"
-#include "net/cert/nss_cert_database.h"
+#include "crypto/nss_util_internal.h"
+#include "net/cert/nss_cert_database_chromeos.h"
#include "net/cert/x509_certificate.h"
namespace chromeos {
namespace {
+typedef base::Callback<void(scoped_ptr<net::NSSCertDatabaseChromeOS> db)>
+ DatabaseCreatedCallback;
+
+void RelayToMessageLoop(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
+ const DatabaseCreatedCallback& callback,
+ scoped_ptr<net::NSSCertDatabaseChromeOS> database) {
+ message_loop_proxy->PostTask(FROM_HERE,
+ base::Bind(callback, base::Passed(&database)));
+}
+
+void DidGetPrivateSlot(const DatabaseCreatedCallback& callback,
+ const std::string& userhash,
+ crypto::ScopedPK11Slot private_slot) {
+ scoped_ptr<net::NSSCertDatabaseChromeOS> database(
+ new net::NSSCertDatabaseChromeOS(
+ crypto::GetPublicSlotForChromeOSUser(userhash),
+ private_slot.Pass()));
+ callback.Run(database.Pass());
+}
+
+void CreateDBForUser(const std::string& userhash,
+ const DatabaseCreatedCallback& callback) {
+ CHECK(crypto::GetPublicSlotForChromeOSUser(userhash))
+ << "Trying to create user's NSS db instance before the NSS has been "
+ << "initialized for the user";
+
+ base::Callback<void(crypto::ScopedPK11Slot private_slot)> on_private_slot =
+ base::Bind(&DidGetPrivateSlot, callback, userhash);
+
+ // Note that callback passed to |crypto::GetPrivateSlotForChromeOSUser| is
+ // called only if the function returns NULL.
+ crypto::ScopedPK11Slot private_slot(
+ crypto::GetPrivateSlotForChromeOSUser(userhash, on_private_slot));
+
+ if (private_slot)
+ on_private_slot.Run(private_slot.Pass());
+}
+
// Loads certificates from |cert_database| into |cert_list|.
-void LoadNSSCertificates(net::NSSCertDatabase* cert_database,
+void LoadNSSCertificates(net::NSSCertDatabaseChromeOS* cert_database,
net::CertificateList* cert_list) {
cert_database->ListCerts(cert_list);
}
@@ -59,36 +101,13 @@ CertLoader::CertLoader()
certificates_update_required_(false),
certificates_update_running_(false),
tpm_token_slot_id_(-1),
+ is_hardware_backed_(false),
+ hardware_backed_for_test_(false),
weak_factory_(this) {
- if (TPMTokenLoader::IsInitialized())
- TPMTokenLoader::Get()->AddObserver(this);
-}
-
-void CertLoader::SetSlowTaskRunnerForTest(
- const scoped_refptr<base::TaskRunner>& task_runner) {
- slow_task_runner_for_test_ = task_runner;
}
CertLoader::~CertLoader() {
net::CertDatabase::GetInstance()->RemoveObserver(this);
- if (TPMTokenLoader::IsInitialized())
- TPMTokenLoader::Get()->RemoveObserver(this);
-}
-
-void CertLoader::AddObserver(CertLoader::Observer* observer) {
- observers_.AddObserver(observer);
-}
-
-void CertLoader::RemoveObserver(CertLoader::Observer* observer) {
- observers_.RemoveObserver(observer);
-}
-
-bool CertLoader::IsHardwareBacked() const {
- return !tpm_token_name_.empty();
-}
-
-bool CertLoader::CertificatesLoading() const {
- return certificates_requested_ && !certificates_loaded_;
}
// This is copied from chrome/common/net/x509_certificate_model_nss.cc.
@@ -120,13 +139,78 @@ std::string CertLoader::GetPkcs11IdForCert(const net::X509Certificate& cert) {
return pkcs11_id;
}
+void CertLoader::StartWithUser(const std::string& userhash) {
+ VLOG(1) << "Start CertLoader with user " << userhash;
+
+ CHECK(userhash_.empty());
+ CHECK(!userhash.empty());
+ userhash_ = userhash;
+ RequestCertificates();
+}
+
+void CertLoader::SetCryptoTaskRunner(
+ const scoped_refptr<base::SequencedTaskRunner>& crypto_task_runner) {
+ crypto_task_runner_ = crypto_task_runner;
+}
+
+void CertLoader::SetSlowTaskRunnerForTest(
+ const scoped_refptr<base::TaskRunner>& task_runner) {
+ slow_task_runner_for_test_ = task_runner;
+}
+
+void CertLoader::AddObserver(CertLoader::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void CertLoader::RemoveObserver(CertLoader::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool CertLoader::IsCertificateInPrivateSlot(
+ const net::X509Certificate& cert) const {
+ if (!certificates_loaded_)
+ return false;
+ if (!cert.os_cert_handle() || !cert.os_cert_handle()->slot)
+ return false;
+ int cert_slot = static_cast<int>(PK11_GetSlotID(cert.os_cert_handle()->slot));
+ return cert_slot == tpm_token_slot_id_;
+}
+
+bool CertLoader::CertificatesLoading() const {
+ return certificates_requested_ && !certificates_loaded_;
+}
+
void CertLoader::RequestCertificates() {
if (certificates_requested_)
return;
certificates_requested_ = true;
+ CHECK(crypto_task_runner_) << "Crypto task runner not set.";
DCHECK(!certificates_loaded_ && !certificates_update_running_);
+
+ DatabaseCreatedCallback on_db_ready =
+ base::Bind(&RelayToMessageLoop,
+ base::MessageLoopProxy::current(),
+ base::Bind(&CertLoader::OnDatabaseReady,
+ weak_factory_.GetWeakPtr()));
+ crypto_task_runner_->PostTask(FROM_HERE,
+ base::Bind(&CreateDBForUser, userhash_, on_db_ready));
+}
+
+void CertLoader::OnDatabaseReady(
+ scoped_ptr<net::NSSCertDatabaseChromeOS> database) {
+ database_ = database.Pass();
+ tpm_token_slot_id_ =
+ static_cast<int>(PK11_GetSlotID(database_->GetPrivateSlot().get()));
+
+ int software_slot_id =
+ static_cast<int>(PK11_GetSlotID(database_->GetPublicSlot().get()));
+ is_hardware_backed_ = hardware_backed_for_test_ ||
+ tpm_token_slot_id_ != software_slot_id;
+
+ // Start observing cert database for changes.
net::CertDatabase::GetInstance()->AddObserver(this);
+
LoadCertificates();
}
@@ -149,7 +233,11 @@ void CertLoader::LoadCertificates() {
task_runner->PostTaskAndReply(
FROM_HERE,
base::Bind(LoadNSSCertificates,
- net::NSSCertDatabase::GetInstance(),
+ // Create a copy of the database so it can be used on the
+ // worker pool.
+ base::Owned(new net::NSSCertDatabaseChromeOS(
mattm 2014/01/23 01:45:55 hmm.. I think it would be preferable to have the N
tbarzic 2014/01/23 04:45:28 I'm not sure that by itself would help here. Unles
mattm 2014/01/23 19:46:52 Yeah, what I meant was NSSCertDatabase would inter
tbarzic 2014/01/23 19:52:03 OK, then I'll keep creating new instance NSSCertDa
+ database_->GetPublicSlot(),
+ database_->GetPrivateSlot())),
cert_list),
base::Bind(&CertLoader::UpdateCertificates,
weak_factory_.GetWeakPtr(),
@@ -195,15 +283,4 @@ void CertLoader::OnCertRemoved(const net::X509Certificate* cert) {
LoadCertificates();
}
-void CertLoader::OnTPMTokenReady(const std::string& tpm_user_pin,
- const std::string& tpm_token_name,
- int tpm_token_slot_id) {
- tpm_user_pin_ = tpm_user_pin;
- tpm_token_name_ = tpm_token_name;
- tpm_token_slot_id_ = tpm_token_slot_id;
-
- VLOG(1) << "TPM token ready.";
- RequestCertificates();
-}
-
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698