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

Unified Diff: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc

Issue 430563002: Enable system token in platformKeys api. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
index f3a02087d69096dbc8923449d4fcb26acf01f42d..5b0f6b800476125f66a751fb80377ef6b43ecd8a 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -72,10 +72,12 @@ class NSSOperationState {
typedef base::Callback<void(net::NSSCertDatabase* cert_db)> GetCertDBCallback;
-// Called back with the NSSCertDatabase associated to the given |token_id|.
-// Calls |callback| if the database was successfully retrieved. Used by
+// Called back with the NSSCertDatabase associated to the given |context|.
Joao da Silva 2014/07/30 08:46:38 There is no |context| here
pneubeck (no reviews) 2014/07/30 13:53:45 Done.
+// If |token_id| is not empty, sets |slot_| of the state accordingly and calls
+// |callback| if the database was successfully retrieved. Used by
// GetCertDatabaseOnIOThread.
-void DidGetCertDBOnIOThread(const GetCertDBCallback& callback,
+void DidGetCertDBOnIOThread(const std::string& token_id,
+ const GetCertDBCallback& callback,
NSSOperationState* state,
net::NSSCertDatabase* cert_db) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -85,42 +87,50 @@ void DidGetCertDBOnIOThread(const GetCertDBCallback& callback,
return;
}
- state->slot_ = cert_db->GetPrivateSlot();
- if (!state->slot_) {
- LOG(ERROR) << "No private slot";
- state->OnError(FROM_HERE, kErrorInternal);
- return;
+ if (!token_id.empty()) {
+ if (token_id == kTokenIdUser)
+ state->slot_ = cert_db->GetPrivateSlot();
+ else if (token_id == kTokenIdSystem)
Joao da Silva 2014/07/30 08:46:38 Why isn't kTokenIdUser and kTokenIdSystem an enum?
pneubeck (no reviews) 2014/07/30 13:53:45 Explained now at the declaration comment.
+ state->slot_ = cert_db->GetSystemSlot();
+
+ if (!state->slot_) {
+ LOG(ERROR) << "Slot for token id '" << token_id << "' not available.";
+ state->OnError(FROM_HERE, kErrorInternal);
+ return;
+ }
}
callback.Run(cert_db);
}
-// Retrieves the NSSCertDatabase from |context|. Must be called on the IO
-// thread.
-void GetCertDatabaseOnIOThread(content::ResourceContext* context,
+// Retrieves the NSSCertDatabase from |context| and, if |token_id| is not empty,
+// the slot for |token_id|.
+// Must be called on the IO thread.
+void GetCertDatabaseOnIOThread(const std::string& token_id,
const GetCertDBCallback& callback,
+ content::ResourceContext* context,
NSSOperationState* state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext(
- context, base::Bind(&DidGetCertDBOnIOThread, callback, state));
+ context, base::Bind(&DidGetCertDBOnIOThread, token_id, callback, state));
if (cert_db)
- DidGetCertDBOnIOThread(callback, state, cert_db);
+ DidGetCertDBOnIOThread(token_id, callback, state, cert_db);
}
-// Asynchronously fetches the NSSCertDatabase and PK11Slot for |token_id|.
-// Stores the slot in |state| and passes the database to |callback|. Will run
-// |callback| on the IO thread.
+// Asynchronously fetches the NSSCertDatabase for |browser_context| and, if
+// |token| is not empty, the slot for |token_id|. Stores the slot in |state|
Joao da Silva 2014/07/30 08:46:39 |token| -> |token_id|
pneubeck (no reviews) 2014/07/30 13:53:45 Done.
+// and passes the database to |callback|. Will run |callback| on the IO thread.
void GetCertDatabase(const std::string& token_id,
const GetCertDBCallback& callback,
BrowserContext* browser_context,
NSSOperationState* state) {
- // TODO(pneubeck): Decide which DB to retrieve depending on |token_id|.
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&GetCertDatabaseOnIOThread,
- browser_context->GetResourceContext(),
+ token_id,
callback,
+ browser_context->GetResourceContext(),
state));
}
@@ -250,6 +260,30 @@ class RemoveCertificateState : public NSSOperationState {
RemoveCertificateCallback callback_;
};
+class GetTokensState : public NSSOperationState {
+ public:
+ explicit GetTokensState(const GetTokensCallback& callback);
+ virtual ~GetTokensState() {}
+
+ virtual void OnError(const tracked_objects::Location& from,
+ const std::string& error_message) OVERRIDE {
+ CallBack(from,
+ scoped_ptr<std::vector<std::string> >() /* no token ids */,
+ error_message);
+ }
+
+ void CallBack(const tracked_objects::Location& from,
+ scoped_ptr<std::vector<std::string> > token_ids,
+ const std::string& error_message) {
+ origin_task_runner_->PostTask(
+ from, base::Bind(callback_, base::Passed(&token_ids), error_message));
+ }
+
+ private:
+ // Must be called on origin thread, use CallBack() therefore.
Joao da Silva 2014/07/30 08:46:38 , therefore use Callback().
pneubeck (no reviews) 2014/07/30 13:53:45 Done.
+ GetTokensCallback callback_;
+};
+
NSSOperationState::NSSOperationState()
: origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
}
@@ -287,6 +321,10 @@ RemoveCertificateState::RemoveCertificateState(
: certificate_(certificate), callback_(callback) {
}
+GetTokensState::GetTokensState(const GetTokensCallback& callback)
+ : callback_(callback) {
+}
+
// Does the actual key generation on a worker thread. Used by
// GenerateRSAKeyWithDB().
void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) {
@@ -447,6 +485,14 @@ void ImportCertificateWithDB(scoped_ptr<ImportCertificateState> state,
return;
}
+ // Check that the private key is in the correct slot.
+ PK11SlotInfo* slot =
+ PK11_KeyForCertExists(state->certificate_->os_cert_handle(), NULL, NULL);
+ if (slot != state->slot_) {
+ state->OnError(FROM_HERE, kErrorKeyNotFound);
+ return;
+ }
+
const net::Error import_status =
static_cast<net::Error>(db->AddUserCert(state->certificate_.get()));
if (import_status != net::OK) {
@@ -490,6 +536,20 @@ void RemoveCertificateWithDB(scoped_ptr<RemoveCertificateState> state,
&DidRemoveCertificate, base::Passed(&state), certificate_found));
}
+// Does the actual work to determine which tokens are available.
+void GetTokensWithDB(scoped_ptr<GetTokensState> state,
+ net::NSSCertDatabase* cert_db) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ scoped_ptr<std::vector<std::string> > token_ids(new std::vector<std::string>);
+
+ // The user's token is always available.
+ token_ids->push_back(kTokenIdUser);
+ if (cert_db->GetSystemSlot())
+ token_ids->push_back(kTokenIdSystem);
Joao da Silva 2014/07/30 08:46:39 Doesn't this depend on state->slot_, based on what
pneubeck (no reviews) 2014/07/30 13:53:45 GetCertDatabase always gets the DB for the browser
+
+ state->CallBack(FROM_HERE, token_ids.Pass(), std::string() /* no error */);
+}
+
} // namespace
namespace subtle {
@@ -588,6 +648,18 @@ void RemoveCertificate(const std::string& token_id,
state_ptr);
}
+void GetTokens(const GetTokensCallback& callback,
+ content::BrowserContext* browser_context) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ scoped_ptr<GetTokensState> state(new GetTokensState(callback));
+ // Get the pointer to |state| before base::Passed releases |state|.
+ NSSOperationState* state_ptr = state.get();
+ GetCertDatabase(std::string() /* don't get any specific slot */,
+ base::Bind(&GetTokensWithDB, base::Passed(&state)),
+ browser_context,
+ state_ptr);
+}
+
} // namespace platform_keys
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698