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

Unified Diff: chrome/browser/profiles/profile_io_data.cc

Issue 53763003: Initialize per-ChromeOS-user NSS slots and provide the functions to access them. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix CertificateManagerBrowserTest Created 7 years 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: chrome/browser/profiles/profile_io_data.cc
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 46129e6f7cb12110364cf6a76e5d25c6078f6636..e50779ce5fb9da6df15836c34fc522493e7cec96 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -89,11 +89,17 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/drive_protocol_handler.h"
+#include "chrome/browser/chromeos/login/user.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chromeos/dbus/cryptohome_client.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/settings/cros_settings_names.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
#endif // defined(OS_CHROMEOS)
#if defined(USE_NSS)
@@ -228,6 +234,112 @@ class DebugDevToolsInterceptor
};
#endif // defined(DEBUG_DEVTOOLS)
+#if defined(OS_CHROMEOS)
+// The following four functions are responsible for initializing NSS for each
+// profile on ChromeOS, which has a separate NSS database and TPM slot
+// per-profile.
+//
+// Initialization basically follows these steps:
+// 1) Get some info from chromeos::UserManager about the User for this profile.
+// 2) Tell nss_util to initialize the software slot for this profile.
+// 3) Wait for the TPM module to be loaded by nss_util if it isn't already.
+// 4) Ask CryptohomeClient which TPM slot id corresponds to this profile.
+// 5) Tell nss_util to use that slot id on the TPM module.
+//
+// Some of these steps must happen on the UI thread, others must happen on the
+// IO thread:
+// UI thread IO Thread
+//
+// ProfileIOData::InitializeOnUIThread
+// |
+// chromeos::UserManager::GetUserByProfile
+// \---------------------------------------v
+// StartNSSInitOnIOThread
+// |
+// crypto::InitializeNSSForChromeOSUser
+// |
+// crypto::IsTPMTokenReady
+// |
+// StartTPMSlotInitializationOnIOThread
+// v---------------------------------------/
+// GetTPMInfoForUserOnUIThread
+// |
+// CryptohomeClient::Pkcs11GetTpmTokenInfoForUser
+// |
+// DidGetTPMInfoForUserOnUIThread
+// \---------------------------------------v
+// crypto::InitializeTPMForChromeOSUser
+
+void DidGetTPMInfoForUserOnUIThread(const std::string& username_hash,
+ chromeos::DBusMethodCallStatus call_status,
+ const std::string& label,
+ const std::string& user_pin,
+ int slot_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (call_status == chromeos::DBUS_METHOD_CALL_FAILURE) {
+ NOTREACHED() << "dbus error getting TPM info for " << username_hash;
+ return;
+ }
+ DVLOG(1) << "Got TPM slot for " << username_hash << ": " << slot_id;
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(
+ &crypto::InitializeTPMForChromeOSUser, username_hash, slot_id));
+}
+
+void GetTPMInfoForUserOnUIThread(const std::string& username,
+ const std::string& username_hash) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DVLOG(1) << "Getting TPM info from cryptohome for "
+ << " " << username << " " << username_hash;
+ chromeos::DBusThreadManager::Get()
+ ->GetCryptohomeClient()
+ ->Pkcs11GetTpmTokenInfoForUser(
+ username,
+ base::Bind(&DidGetTPMInfoForUserOnUIThread, username_hash));
+}
+
+void StartTPMSlotInitializationOnIOThread(const std::string& username,
+ const std::string& username_hash) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&GetTPMInfoForUserOnUIThread, username, username_hash));
+}
+
+void StartNSSInitOnIOThread(const std::string& username,
+ const std::string& username_hash,
+ const base::FilePath& path,
+ bool is_primary_user) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DVLOG(1) << "Starting NSS init for " << username
+ << " hash:" << username_hash
+ << " is_primary_user:" << is_primary_user;
+
+ if (!crypto::InitializeNSSForChromeOSUser(
+ username, username_hash, is_primary_user, path)) {
+ // If the user already exists in nss_util's map, it is already initialized
+ // or in the process of being initialized. In either case, there's no need
+ // to do anything.
+ return;
+ }
+
+ if (crypto::IsTPMTokenEnabledForNSS()) {
+ if (crypto::IsTPMTokenReady(base::Bind(
+ &StartTPMSlotInitializationOnIOThread, username, username_hash))) {
+ StartTPMSlotInitializationOnIOThread(username, username_hash);
+ } else {
+ DVLOG(1) << "Waiting for tpm ready ...";
+ }
+ } else {
+ crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash);
+ }
+}
+#endif // defined(OS_CHROMEOS)
+
} // namespace
void ProfileIOData::InitializeOnUIThread(Profile* profile) {
@@ -278,6 +390,25 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) {
params->managed_mode_url_filter =
managed_user_service->GetURLFilterForIOThread();
#endif
+#if defined(OS_CHROMEOS)
+ chromeos::UserManager* user_manager = chromeos::UserManager::Get();
+ if (user_manager) {
+ chromeos::User* user = user_manager->GetUserByProfile(profile);
+ if (user) {
+ params->username_hash = user->username_hash();
+ bool is_primary_user = (user_manager->GetPrimaryUser() == user);
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&StartNSSInitOnIOThread,
+ user->email(),
+ user->username_hash(),
+ profile->GetPath(),
+ is_primary_user));
+ }
+ }
+ if (params->username_hash.empty())
+ LOG(WARNING) << "no username_hash";
+#endif
params->profile = profile;
profile_params_.reset(params.release());
@@ -833,6 +964,7 @@ void ProfileIOData::Init(content::ProtocolHandlerMap* protocol_handlers) const {
main_request_context_->set_cert_verifier(
io_thread_globals->cert_verifier.get());
}
+ username_hash_ = profile_params_->username_hash;
#else
main_request_context_->set_cert_verifier(
io_thread_globals->cert_verifier.get());
« no previous file with comments | « chrome/browser/profiles/profile_io_data.h ('k') | chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698