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

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

Issue 323093003: Add the Sign-At-Most-Once restriction the enterprise.platformKeys API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 6 years, 6 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_service.cc
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..124cb7a6db1e1d44b1df720d7db8a3f42b2f3a51
--- /dev/null
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -0,0 +1,224 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
+
+#include "base/base64.h"
+#include "base/callback.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
+#include "chrome/browser/extensions/state_store.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace chromeos {
+
+namespace {
+
+const char kErrorInternal[] = "Internal Error.";
+const char kErrorKeyNotAllowedForSigning[] =
+ "This key is not allowed for signing. Either it was used for signing "
+ "before or it was not correctly generated.";
+const char kStateStorePlatformKeys[] = "PlatformKeys";
+
+scoped_ptr<base::StringValue> GetPublicKeyValue(
+ const std::string& public_key_spki_der) {
+ std::string public_key_spki_der_b64;
+ base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64);
+ return make_scoped_ptr(new base::StringValue(public_key_spki_der_b64));
+}
+
+// Wraps |callback| into a void(bool) callback which forwards
+// |public_key_spki_der| if |true| is passed to it.
+void WrapGenerateKeyCallback(
+ const PlatformKeysService::GenerateKeyCallback& callback,
+ const std::string& public_key_spki_der,
+ bool success) {
+ if (success)
+ callback.Run(public_key_spki_der, std::string() /* no error */);
+ else
+ callback.Run(std::string() /* no public key */, kErrorInternal);
+}
+
+// Callback used by |PlatformKeysService::Sign|.
+// Is called with the old validity of |public_key_spki_der| (or false if an
+// error occurred during reading the StateStore). If allowed, starts the actual
+// signing operation which will call back |callback|. If not allowed, calls
+// |callback| with an error.
+void CheckValidityAndSign(const std::string& token_id,
+ const std::string& public_key_spki_der,
+ const std::string& data,
+ const PlatformKeysService::SignCallback& callback,
+ content::BrowserContext* browser_context,
+ bool key_is_valid) {
+ if (!key_is_valid) {
+ callback.Run(std::string() /* no signature */,
+ kErrorKeyNotAllowedForSigning);
+ return;
+ }
+ platform_keys::subtle::Sign(
+ token_id, public_key_spki_der, data, callback, browser_context);
+}
+
+} // namespace
+
+PlatformKeysService::PlatformKeysService(
+ content::BrowserContext* browser_context,
+ extensions::StateStore* state_store)
+ : browser_context_(browser_context),
+ state_store_(state_store),
+ weak_factory_(this) {
+ DCHECK(state_store);
+}
+
+PlatformKeysService::~PlatformKeysService() {
+}
+
+void PlatformKeysService::GenerateRSAKey(const std::string& token_id,
+ unsigned int modulus_length,
+ const std::string& extension_id,
+ const GenerateKeyCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ platform_keys::subtle::GenerateRSAKey(
+ token_id,
+ modulus_length,
+ base::Bind(&PlatformKeysService::GenerateRSAKeyCallback,
+ weak_factory_.GetWeakPtr(),
+ extension_id,
+ callback),
+ browser_context_);
+}
+
+void PlatformKeysService::Sign(const std::string& token_id,
+ const std::string& public_key_spki_der,
+ const std::string& data,
+ const std::string& extension_id,
+ const SignCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ReadValidityAndInvalidateKey(extension_id,
+ public_key_spki_der,
+ base::Bind(&CheckValidityAndSign,
+ token_id,
+ public_key_spki_der,
+ data,
+ callback,
+ browser_context_));
+}
+
+void PlatformKeysService::RegisterPublicKey(
+ const std::string& extension_id,
+ const std::string& public_key_spki_der,
+ const base::Callback<void(bool)>& callback) {
+ GetPlatformKeysOfExtension(
+ extension_id,
+ base::Bind(&PlatformKeysService::RegisterPublicKeyGotPlatformKeys,
+ weak_factory_.GetWeakPtr(),
+ extension_id,
+ public_key_spki_der,
+ callback));
+}
+
+void PlatformKeysService::ReadValidityAndInvalidateKey(
+ const std::string& extension_id,
+ const std::string& public_key_spki_der,
+ const base::Callback<void(bool)>& callback) {
+ GetPlatformKeysOfExtension(extension_id,
+ base::Bind(&PlatformKeysService::InvalidateKey,
+ weak_factory_.GetWeakPtr(),
+ extension_id,
+ public_key_spki_der,
+ callback));
+}
+
+void PlatformKeysService::GetPlatformKeysOfExtension(
+ const std::string& extension_id,
+ const GetPlatformKeysCallback& callback) {
+ state_store_->GetExtensionValue(
+ extension_id,
+ kStateStorePlatformKeys,
+ base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension,
+ weak_factory_.GetWeakPtr(),
+ extension_id,
+ callback));
+}
+
+void PlatformKeysService::GenerateRSAKeyCallback(
+ const std::string& extension_id,
+ const GenerateKeyCallback& callback,
+ const std::string& public_key_spki_der,
+ const std::string& error_message) {
+ if (!error_message.empty()) {
+ callback.Run(std::string() /* no public key */, error_message);
+ return;
+ }
+ base::Callback<void(bool)> wrapped_callback(
+ base::Bind(&WrapGenerateKeyCallback, callback, public_key_spki_der));
+ RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback);
+}
+
+void PlatformKeysService::RegisterPublicKeyGotPlatformKeys(
+ const std::string& extension_id,
+ const std::string& public_key_spki_der,
+ const base::Callback<void(bool)>& callback,
+ scoped_ptr<base::ListValue> platform_keys) {
+ if (!platform_keys) {
+ LOG(ERROR) << "Error while reading the platform keys.";
+ callback.Run(false);
+ return;
+ }
+
+ scoped_ptr<base::StringValue> key_value(
+ GetPublicKeyValue(public_key_spki_der));
+
+ DCHECK(platform_keys->end() == platform_keys->Find(*key_value))
+ << "Keys are assumed to be generated and not to be registered multiple "
+ "times.";
+ platform_keys->Append(key_value.release());
+
+ state_store_->SetExtensionValue(extension_id,
+ kStateStorePlatformKeys,
+ platform_keys.PassAs<base::Value>());
+ callback.Run(true);
+}
+
+void PlatformKeysService::InvalidateKey(
+ const std::string& extension_id,
+ const std::string& public_key_spki_der,
+ const base::Callback<void(bool)>& callback,
+ scoped_ptr<base::ListValue> platform_keys) {
+ scoped_ptr<base::StringValue> key_value(
+ GetPublicKeyValue(public_key_spki_der));
+
+ size_t index = 0;
+ if (!platform_keys->Remove(*key_value, &index)) {
+ // The key is not found, so it's not valid to use it for signing.
+ callback.Run(false);
+ return;
+ }
+
+ state_store_->SetExtensionValue(extension_id,
+ kStateStorePlatformKeys,
+ platform_keys.PassAs<base::Value>());
+ callback.Run(true);
+}
+
+void PlatformKeysService::GotPlatformKeysOfExtension(
+ const std::string& extension_id,
+ const GetPlatformKeysCallback& callback,
+ scoped_ptr<base::Value> value) {
+ if (!value)
+ value.reset(new base::ListValue);
+
+ base::ListValue* keys = NULL;
+ if (!value->GetAsList(&keys)) {
+ LOG(ERROR) << "Found a value of wrong type.";
+ value.reset();
+ }
+ ignore_result(value.release());
+ callback.Run(make_scoped_ptr(keys));
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698