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

Unified Diff: Source/modules/crypto/SubtleCrypto.cpp

Issue 19885002: WebCrypto: Add interfaces for importKey(). (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 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: Source/modules/crypto/SubtleCrypto.cpp
diff --git a/Source/modules/crypto/SubtleCrypto.cpp b/Source/modules/crypto/SubtleCrypto.cpp
index e0e75ccb25244f1a819295c82288f3ccc6ddaa04..e567a443bb6dc91afd7c32eaf7a6e5a39b751cf5 100644
--- a/Source/modules/crypto/SubtleCrypto.cpp
+++ b/Source/modules/crypto/SubtleCrypto.cpp
@@ -31,12 +31,16 @@
#include "config.h"
#include "modules/crypto/SubtleCrypto.h"
+#include "V8Key.h" // NOTE: This must appear before ScriptPromiseResolver to define toV8()
+#include "bindings/v8/ScriptPromiseResolver.h"
#include "core/dom/ExceptionCode.h"
#include "modules/crypto/CryptoOperation.h"
+#include "modules/crypto/Key.h"
#include "modules/crypto/NormalizeAlgorithm.h"
#include "public/platform/Platform.h"
#include "public/platform/WebArrayBuffer.h" // FIXME: temporary
#include "public/platform/WebCrypto.h"
+#include "public/platform/WebCryptoAlgorithmParams.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
#include "wtf/SHA1.h" // FIXME: temporary
@@ -113,6 +117,25 @@ public:
result->initializationSucceded(new DummyOperation(result));
}
}
+
+ virtual void importKey(WebKit::WebCryptoKeyFormat, const unsigned char* keyData, size_t keyDataSize, const WebKit::WebCryptoAlgorithm& algorithm, bool extractable, WebKit::WebCryptoKeyUsageMask usages, WebKit::WebCryptoKeyOperationResult* result)
+ {
+ String keyDataString(keyData, keyDataSize);
+
+ WebKit::WebCryptoKeyType type;
+ if (keyDataString == "reject") {
+ result->completeWithError();
+ } else if (keyDataString == "throw") {
+ result->initializationFailed();
+ } else {
+ if (keyDataString == "public") {
+ type = WebKit::WebCryptoKeyTypePublic;
+ } else if (keyDataString == "private") {
+ type = WebKit::WebCryptoKeyTypePrivate;
+ }
+ result->completeWithKey(WebKit::WebCryptoKey::create(0, type, extractable, algorithm, usages));
+ }
+ }
};
WebKit::WebCrypto* mockPlatformCrypto()
@@ -132,6 +155,102 @@ PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, Alg
return op.release();
}
//------------------------------------------------------------------------------
+//
+//
+class KeyOperation : public WebKit::WebCryptoKeyOperationResult {
+public:
+ KeyOperation(ScriptPromiseResolver* resolver, ExceptionCode* ec)
+ : m_state(Initializing)
+ , m_impl(0)
+ , m_promiseResolver(resolver)
+ , m_exceptionCode(ec)
+ {
+ }
+
+ ~KeyOperation();
+
+ // Implementation of WebKit::WebCryptoKeyOperationResult.
+ virtual void initializationFailed() OVERRIDE;
+ virtual void initializationSucceeded(WebKit::WebCryptoKeyOperation*) OVERRIDE;
+ virtual void completeWithError() OVERRIDE;
+ virtual void completeWithKey(const WebKit::WebCryptoKey&) OVERRIDE;
+
+private:
+ enum State {
+ Initializing,
+ InProgress,
+ Done,
+ };
+
+ State m_state;
+ WebKit::WebCryptoKeyOperation* m_impl;
+ ExceptionCode* m_exceptionCode;
+ RefPtr<ScriptPromiseResolver> m_promiseResolver;
+};
+
+KeyOperation::~KeyOperation()
+{
+ // Abort any inprogress operation.
+ switch (m_state) {
+ case Initializing:
+ ASSERT_NOT_REACHED();
+ break;
+ case InProgress:
+ // This will cause m_impl to be deleted.
+ m_state = Done;
+ m_impl->abort();
+ m_impl = 0;
+ case Done:
+ ASSERT(!m_impl);
+ break;
+ }
+}
+
+void KeyOperation::initializationFailed()
+{
+ ASSERT(m_state == Initializing);
+
+ *m_exceptionCode = NotSupportedError;
+
+ m_exceptionCode = 0;
+ m_state = Done;
+ delete this;
+}
+
+void KeyOperation::initializationSucceeded(WebKit::WebCryptoKeyOperation* operationImpl)
+{
+ ASSERT(m_state == Initializing);
+ ASSERT(operationImpl);
+ ASSERT(!m_impl);
+
+ m_exceptionCode = 0;
+ m_impl = operationImpl;
+ m_state = InProgress;
+}
+
+void KeyOperation::completeWithError()
+{
+ ASSERT(m_state == Initializing || m_state == InProgress);
+
+ m_exceptionCode = 0;
+ m_impl = 0;
+ m_state = Done;
+
+ m_promiseResolver->reject(ScriptValue::createNull());
+ delete this;
+}
+
+void KeyOperation::completeWithKey(const WebKit::WebCryptoKey& key)
+{
+ ASSERT(m_state == Initializing || m_state == InProgress);
+
+ m_exceptionCode = 0;
+ m_impl = 0;
+ m_state = Done;
+
+ m_promiseResolver->fulfill(Key::create(key));
+ delete this;
+}
} // namespace
@@ -177,4 +296,45 @@ PassRefPtr<CryptoOperation> SubtleCrypto::digest(const Dictionary& rawAlgorithm,
return op.release();
}
+ScriptObject SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionCode& ec)
+{
+ WebKit::WebCrypto* platformCrypto = mockPlatformCrypto();
+ if (!platformCrypto) {
+ ec = NotSupportedError;
+ return ScriptObject();
+ }
+
+ WebKit::WebCryptoKeyUsageMask keyUsages;
+ if (!Key::parseUsageMask(rawKeyUsages, keyUsages)) {
+ ec = TypeError;
+ return ScriptObject();
+ }
+
+ WebKit::WebCryptoKeyFormat format;
+ if (!Key::parseFormat(rawFormat, format)) {
+ ec = TypeError;
+ return ScriptObject();
+ }
+
+ WebKit::WebCryptoAlgorithm algorithm;
+ if (!normalizeAlgorithmForImportKey(rawAlgorithm, algorithm, ec))
+ return ScriptObject();
+
+ const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->baseAddress());
+
+ RefPtr<ScriptPromiseResolver> promiseResolver = ScriptPromiseResolver::create();
+
+ // The |op| object is deleted upon completion of the underlying operation
+ // (i.e. when platformCrypto->importKey() notifies completion).
+ //
+ // FIXME: KeyOperation is never aborted. It should probably be aborted when
+ // the SubtleCrypto object that started it gets deleted. The concern being
+ // if the operation eventually does complete, the ScriptPromiseResolver
+ // might no longer be valid because the context it belonged to got torn
+ // down.
+ KeyOperation* op = new KeyOperation(promiseResolver.get(), &ec);
+ platformCrypto->importKey(format, keyDataBytes, keyData->byteLength(), algorithm, extractable, keyUsages, op);
+ return promiseResolver->promise();
+}
+
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698