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

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

Issue 23164012: WebCrypto: Remove support for multi-part operations. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 4 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 f800a50d42a5ad1758a56abd58b0f2c98aa8ce5e..dddc30cc0572b7796f1edc7603590534e3d6a781 100644
--- a/Source/modules/crypto/SubtleCrypto.cpp
+++ b/Source/modules/crypto/SubtleCrypto.cpp
@@ -31,26 +31,102 @@
#include "config.h"
#include "modules/crypto/SubtleCrypto.h"
+#include "V8Key.h" // NOTE: This must appear before ScriptPromiseResolver to define toV8()
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/custom/V8ArrayBufferCustom.h" // MUST precede ScriptPromiseResolver for compilation to work.
abarth-chromium 2013/08/16 04:53:07 We should fix these include order dependencies.
eroman 2013/08/16 22:59:41 The issue is that the header file inlines this tem
+#include "bindings/v8/ScriptPromiseResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/platform/NotImplemented.h"
-#include "modules/crypto/CryptoOperation.h"
#include "modules/crypto/Key.h"
-#include "modules/crypto/KeyOperation.h"
#include "modules/crypto/NormalizeAlgorithm.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebArrayBuffer.h"
#include "public/platform/WebCrypto.h"
#include "public/platform/WebCryptoAlgorithmParams.h"
#include "wtf/ArrayBufferView.h"
namespace WebCore {
-// FIXME: Outstanding KeyOperations and CryptoOperations should be aborted when
-// tearing down SubtleCrypto (to avoid problems completing a
-// ScriptPromiseResolver which is no longer valid).
+// FIXME: Orphan outstanding CryptoOperationResults once SubtleCrypto gets deleted
+// (to avoid problems completing a ScriptPromiseResolver which is no longer valid).
+
+// FIXME: Asynchronous completion needs to re-enter the v8::Context before trying
+// to fulfill the Promise or it will hit
+// ASSERT(v8::Context::InContext());
namespace {
+// Wrapper around the Promise which the embedder calls into.
+class CryptoOperationResult : public WebKit::WebCryptoOperationResult {
+public:
+ CryptoOperationResult()
+ : m_completed(false)
+ , m_async(false)
+ , m_promiseResolver(ScriptPromiseResolver::create()) { }
+
+ virtual void completeWithError() OVERRIDE
+ {
+ m_promiseResolver->reject(WebCore::ScriptValue::createNull());
+ finish();
+ }
+
+ virtual void completeWithBuffer(const WebKit::WebArrayBuffer& buffer) OVERRIDE
+ {
+ m_promiseResolver->fulfill(PassRefPtr<ArrayBuffer>(buffer));
+ finish();
+ }
+
+ virtual void completeWithBoolean(bool b) OVERRIDE
+ {
+ m_promiseResolver->fulfill(WebCore::ScriptValue::createBoolean(b));
+ finish();
+ }
+
+ virtual void completeWithKey(const WebKit::WebCryptoKey& key) OVERRIDE
+ {
+ m_promiseResolver->fulfill(WebCore::Key::create(key));
abarth-chromium 2013/08/16 04:53:07 WebCore::Key -> Key We're in the WebCore namespac
+ finish();
+ }
+
+ virtual void willFinishLater() OVERRIDE
+ {
+ ASSERT(!m_completed);
+ ASSERT(!m_async);
+ m_async = true;
+ }
+
+ ScriptObject releasePromise()
+ {
+ if (!m_completed && !m_async) {
+ // The embedder forgot to set the result.
+ ASSERT_NOT_REACHED();
abarth-chromium 2013/08/16 04:53:07 Rather than handling this unreachable condition, w
+ completeWithError();
+ }
+
+ ScriptObject promise = m_promiseResolver->promise();
+
+ if (m_completed)
+ delete this;
abarth-chromium 2013/08/16 04:53:07 :( I don't understand why we keep needing this |d
eroman 2013/08/16 06:45:58 This is the same model as callbacks, in which the
+
+ return promise;
+ }
+
+private:
+ void finish()
+ {
+ ASSERT(!m_completed);
+ m_completed = true;
+
+ if (m_async)
+ delete this;
+ }
+
+ bool m_completed;
+ bool m_async;
+
+ RefPtr<ScriptPromiseResolver> m_promiseResolver;
+};
+
WebKit::WebCryptoKeyUsageMask toKeyUsage(AlgorithmOperation operation)
{
switch (operation) {
@@ -101,64 +177,71 @@ bool keyCanBeUsedForAlgorithm(const WebKit::WebCryptoKey& key, const WebKit::Web
return false;
}
-PassRefPtr<CryptoOperation> createCryptoOperation(const Dictionary& rawAlgorithm, Key* key, AlgorithmOperation operationType, ArrayBufferView* signature, ExceptionState& es)
+ScriptObject startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, AlgorithmOperation operationType, ArrayBufferView* signature, ArrayBufferView* dataBuffer, ExceptionState& es)
{
WebKit::WebCrypto* platformCrypto = WebKit::Platform::current()->crypto();
if (!platformCrypto) {
es.throwDOMException(NotSupportedError);
- return 0;
+ return ScriptObject();
}
WebKit::WebCryptoAlgorithm algorithm;
if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, es))
- return 0;
+ return ScriptObject();
// All operations other than Digest require a valid Key.
if (operationType != Digest) {
if (!key) {
es.throwTypeError();
- return 0;
+ return ScriptObject();
}
if (!keyCanBeUsedForAlgorithm(key->key(), algorithm, operationType)) {
es.throwDOMException(NotSupportedError);
- return 0;
+ return ScriptObject();
}
}
// Only Verify takes a signature.
if (operationType == Verify && !signature) {
es.throwTypeError();
- return 0;
+ return ScriptObject();
}
- RefPtr<CryptoOperationImpl> opImpl = CryptoOperationImpl::create();
- WebKit::WebCryptoOperationResult result(opImpl.get());
+ if (!dataBuffer) {
+ es.throwTypeError();
+ return ScriptObject();
+ }
+
+ const unsigned char* data = static_cast<const unsigned char*>(dataBuffer->baseAddress());
+ size_t dataSize = dataBuffer->byteLength();
+
+ // This is deleted either by releasePromise() below, or on asynchronous
+ // completion of the request.
+ CryptoOperationResult* result = new CryptoOperationResult();
abarth-chromium 2013/08/16 04:53:07 This is a naked call to |new|. We shouldn't have
eroman 2013/08/16 06:45:58 This was to enable the implementations of encrypt(
switch (operationType) {
case Encrypt:
- platformCrypto->encrypt(algorithm, key->key(), result);
+ platformCrypto->encrypt(algorithm, key->key(), data, dataSize, result);
break;
case Decrypt:
- platformCrypto->decrypt(algorithm, key->key(), result);
+ platformCrypto->decrypt(algorithm, key->key(), data, dataSize, result);
break;
case Sign:
- platformCrypto->sign(algorithm, key->key(), result);
+ platformCrypto->sign(algorithm, key->key(), data, dataSize, result);
break;
case Verify:
- platformCrypto->verifySignature(algorithm, key->key(), reinterpret_cast<const unsigned char*>(signature->baseAddress()), signature->byteLength(), result);
+ platformCrypto->verifySignature(algorithm, key->key(), reinterpret_cast<const unsigned char*>(signature->baseAddress()), signature->byteLength(), data, dataSize, result);
break;
case Digest:
- platformCrypto->digest(algorithm, result);
+ platformCrypto->digest(algorithm, data, dataSize, result);
break;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return ScriptObject();
}
- if (opImpl->throwInitializationError(es))
- return 0;
- return CryptoOperation::create(algorithm, opImpl.get());
+ return result->releasePromise();
}
} // namespace
@@ -168,29 +251,29 @@ SubtleCrypto::SubtleCrypto()
ScriptWrappable::init(this);
}
-PassRefPtr<CryptoOperation> SubtleCrypto::encrypt(const Dictionary& rawAlgorithm, Key* key, ExceptionState& es)
+ScriptObject SubtleCrypto::encrypt(const Dictionary& rawAlgorithm, Key* key, ArrayBufferView* data, ExceptionState& es)
{
- return createCryptoOperation(rawAlgorithm, key, Encrypt, 0, es);
+ return startCryptoOperation(rawAlgorithm, key, Encrypt, 0, data, es);
}
-PassRefPtr<CryptoOperation> SubtleCrypto::decrypt(const Dictionary& rawAlgorithm, Key* key, ExceptionState& es)
+ScriptObject SubtleCrypto::decrypt(const Dictionary& rawAlgorithm, Key* key, ArrayBufferView* data, ExceptionState& es)
{
- return createCryptoOperation(rawAlgorithm, key, Decrypt, 0, es);
+ return startCryptoOperation(rawAlgorithm, key, Decrypt, 0, data, es);
}
-PassRefPtr<CryptoOperation> SubtleCrypto::sign(const Dictionary& rawAlgorithm, Key* key, ExceptionState& es)
+ScriptObject SubtleCrypto::sign(const Dictionary& rawAlgorithm, Key* key, ArrayBufferView* data, ExceptionState& es)
{
- return createCryptoOperation(rawAlgorithm, key, Sign, 0, es);
+ return startCryptoOperation(rawAlgorithm, key, Sign, 0, data, es);
}
-PassRefPtr<CryptoOperation> SubtleCrypto::verifySignature(const Dictionary& rawAlgorithm, Key* key, ArrayBufferView* signature, ExceptionState& es)
+ScriptObject SubtleCrypto::verifySignature(const Dictionary& rawAlgorithm, Key* key, ArrayBufferView* signature, ArrayBufferView* data, ExceptionState& es)
{
- return createCryptoOperation(rawAlgorithm, key, Verify, signature, es);
+ return startCryptoOperation(rawAlgorithm, key, Verify, signature, data, es);
}
-PassRefPtr<CryptoOperation> SubtleCrypto::digest(const Dictionary& rawAlgorithm, ExceptionState& es)
+ScriptObject SubtleCrypto::digest(const Dictionary& rawAlgorithm, ArrayBufferView* data, ExceptionState& es)
{
- return createCryptoOperation(rawAlgorithm, 0, Digest, 0, es);
+ return startCryptoOperation(rawAlgorithm, 0, Digest, 0, data, es);
}
ScriptObject SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& es)
@@ -211,10 +294,13 @@ ScriptObject SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool extr
if (!normalizeAlgorithm(rawAlgorithm, GenerateKey, algorithm, es))
return ScriptObject();
- RefPtr<KeyOperation> keyOp = KeyOperation::create();
- WebKit::WebCryptoKeyOperationResult result(keyOp.get());
+ // This is deleted either by releasePromise() below, or on asynchronous
+ // completion of the request.
+ CryptoOperationResult* result = new CryptoOperationResult();
abarth-chromium 2013/08/16 04:53:07 Another naked |new|. None of these should be nece
+
platformCrypto->generateKey(algorithm, extractable, keyUsages, result);
- return keyOp->returnValue(es);
+
+ return result->releasePromise();
}
ScriptObject SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& es)
@@ -248,10 +334,13 @@ ScriptObject SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* k
const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->baseAddress());
- RefPtr<KeyOperation> keyOp = KeyOperation::create();
- WebKit::WebCryptoKeyOperationResult result(keyOp.get());
+ // This is deleted either by releasePromise() below, or on asynchronous
+ // completion of the request.
+ CryptoOperationResult* result = new CryptoOperationResult();
+
platformCrypto->importKey(format, keyDataBytes, keyData->byteLength(), algorithm, extractable, keyUsages, result);
- return keyOp->returnValue(es);
+
+ return result->releasePromise();
}
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698