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

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: Move test stuff into MockWebCrypto 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..247d3eff0938c14827c383217fe35d0cc89b1f58 100644
--- a/Source/modules/crypto/SubtleCrypto.cpp
+++ b/Source/modules/crypto/SubtleCrypto.cpp
@@ -31,107 +31,132 @@
#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 "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
-#include "wtf/SHA1.h" // FIXME: temporary
-
namespace WebCore {
namespace {
-// FIXME: The following are temporary implementations of what *should* go on the
-// embedder's side. Since SHA1 is easily implemented, this serves as
-// a useful proof of concept to get layout tests up and running and
-// returning correct results, until the embedder's side is implemented.
-//------------------------------------------------------------------------------
-class DummyOperation : public WebKit::WebCryptoOperation {
-public:
- explicit DummyOperation(WebKit::WebCryptoOperationResult* result) : m_result(result) { }
-
- virtual void process(const unsigned char* bytes, size_t size) OVERRIDE
- {
- m_result->completeWithError();
- delete this;
- }
-
- virtual void abort() OVERRIDE
- {
- delete this;
+// FIXME: Temporary
+PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, AlgorithmOperation operationType, ExceptionCode& ec)
abarth-chromium 2013/07/23 06:22:07 Like "get", "do" is a weak verb. Perhaps "dummyOp
+{
+ WebKit::WebCrypto* platformCrypto = WebKit::Platform::current()->crypto();
+ if (!platformCrypto) {
+ ec = NotSupportedError;
+ return 0;
}
- virtual void finish() OVERRIDE
- {
- m_result->completeWithError();
- delete this;
- }
+ WebKit::WebCryptoAlgorithm algorithm;
+ if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec))
+ return 0;
-protected:
- WebKit::WebCryptoOperationResult* m_result;
-};
+ RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec);
+ platformCrypto->digest(algorithm, op.get());
+ return op.release();
+}
-class MockSha1Operation : public DummyOperation {
+class KeyOperation : public WebKit::WebCryptoKeyOperationResult {
public:
- explicit MockSha1Operation(WebKit::WebCryptoOperationResult* result) : DummyOperation(result) { }
-
- virtual void process(const unsigned char* bytes, size_t size) OVERRIDE
+ KeyOperation(ScriptPromiseResolver* resolver, ExceptionCode* ec)
+ : m_state(Initializing)
+ , m_impl(0)
+ , m_promiseResolver(resolver)
+ , m_exceptionCode(ec)
{
- m_sha1.addBytes(bytes, size);
}
- virtual void finish() OVERRIDE
- {
- Vector<uint8_t, 20> hash;
- m_sha1.computeHash(hash);
+ ~KeyOperation();
- WebKit::WebArrayBuffer buffer = WebKit::WebArrayBuffer::create(hash.size(), 1);
- memcpy(buffer.data(), hash.data(), hash.size());
-
- m_result->completeWithArrayBuffer(buffer);
- delete this;
- }
+ // 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:
- SHA1 m_sha1;
+ enum State {
+ Initializing,
+ InProgress,
+ Done,
+ };
+
+ State m_state;
+ WebKit::WebCryptoKeyOperation* m_impl;
+ ExceptionCode* m_exceptionCode;
abarth-chromium 2013/07/23 06:22:07 I don't understand how KeyOperation can hold a poi
eroman 2013/07/23 06:53:41 It is a little bit tricky, but the m_exceptionCode
abarth-chromium 2013/07/23 07:06:14 That's too tricky. Is there a simpler design?
+ RefPtr<ScriptPromiseResolver> m_promiseResolver;
};
-class MockPlatformCrypto : public WebKit::WebCrypto {
-public:
- virtual void digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::WebCryptoOperationResult* result) OVERRIDE
- {
- if (algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1) {
- result->initializationSucceded(new MockSha1Operation(result));
- } else {
- // Don't fail synchronously, since existing layout tests rely on
- // digest for testing algorithm normalization.
- result->initializationSucceded(new DummyOperation(result));
- }
+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;
}
-};
+}
-WebKit::WebCrypto* mockPlatformCrypto()
+void KeyOperation::initializationFailed()
{
- DEFINE_STATIC_LOCAL(MockPlatformCrypto, crypto, ());
- return &crypto;
+ ASSERT(m_state == Initializing);
+
+ *m_exceptionCode = NotSupportedError;
+
+ m_exceptionCode = 0;
+ m_state = Done;
+ delete this;
abarth-chromium 2013/07/23 06:22:07 This line is suspicious and indicates a bad memory
}
-PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, AlgorithmOperation operationType, ExceptionCode& ec)
+void KeyOperation::initializationSucceeded(WebKit::WebCryptoKeyOperation* operationImpl)
{
- WebKit::WebCryptoAlgorithm algorithm;
- if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec))
- return 0;
+ ASSERT(m_state == Initializing);
+ ASSERT(operationImpl);
+ ASSERT(!m_impl);
- RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec);
- op->initializationSucceded(new DummyOperation(op.get()));
- return op.release();
+ 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
@@ -162,7 +187,7 @@ PassRefPtr<CryptoOperation> SubtleCrypto::verifySignature(const Dictionary& rawA
PassRefPtr<CryptoOperation> SubtleCrypto::digest(const Dictionary& rawAlgorithm, ExceptionCode& ec)
{
- WebKit::WebCrypto* platformCrypto = mockPlatformCrypto();
+ WebKit::WebCrypto* platformCrypto = WebKit::Platform::current()->crypto();
if (!platformCrypto) {
ec = NotSupportedError;
return 0;
@@ -177,4 +202,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 = WebKit::Platform::current()->crypto();
+ 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);
abarth-chromium 2013/07/23 06:22:07 This is a "naked new", which is where the bad memo
eroman 2013/07/23 06:53:41 I'll think about this some more and see what else
abarth-chromium 2013/07/23 07:06:14 We might want to change CryptoOperation to follow
+ platformCrypto->importKey(format, keyDataBytes, keyData->byteLength(), algorithm, extractable, keyUsages, op);
+ return promiseResolver->promise();
+}
+
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698