[GTK] Crash on https://diafygi.github.io/webcrypto-examples with ENABLE_SUBTLE_CRYPTO
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Jul 2016 08:03:36 +0000 (08:03 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Jul 2016 08:03:36 +0000 (08:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159189

Reviewed by Michael Catanzaro.

Source/WebCore:

Currently, we explicitly release the pointers of std::unique_ptr<CryptoAlgorithm> and std::unique_ptr<CryptoAlgorithmParameters>,
and delete them in the asynchronously called lambdas. In GnuTLS version, callback function is accidentally called twice,
and it incurs the double free problem.
In SubtleCrypto code, we have the rule that we must not call failureCallback when the error code is filled in synchronous execution.
So we drop the failureCallback calling code in GnuTLS subtle crypto code.

But, rather than carefully handling un-smart-pointer-managed raw pointer's life time, we should use ref counted pointer for that.
Using the raw delete is error-prone.

This patch also changes CryptoAlgorithm and CryptoAlgorithmParameters to RefCounted. And use Ref and RefPtr instead.
The change eliminates the ad-hoc delete code. And now, the lambdas can be called multiple times since once the result of the promise
is resolved or rejected, subsequent resolve / reject calls are ignored.

And this patch also fixes the incorrect call to the lambda that is already WTFMoved.

While we can see several `return WTFMove(...)`, they are necessary since it uses implicit type conversions, like,
`Ref<A>` => `RefPtr<A>`, and `Ref<Derived>` => `Ref<Base>`.

* bindings/js/JSCryptoAlgorithmDictionary.cpp:
(WebCore::createAesCbcParams):
(WebCore::createAesKeyGenParams):
(WebCore::createHmacParams):
(WebCore::createHmacKeyParams):
(WebCore::createRsaKeyGenParams):
(WebCore::createRsaKeyParamsWithHash):
(WebCore::createRsaOaepParams):
(WebCore::createRsaSsaParams):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForEncrypt):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDecrypt):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForSign):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForVerify):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDigest):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForGenerateKey):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveKey):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveBits):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForExportKey):
* bindings/js/JSCryptoAlgorithmDictionary.h:
* bindings/js/JSCryptoKeySerializationJWK.cpp:
(WebCore::createHMACParameters):
(WebCore::createRSAKeyParametersWithHash):
(WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm):
* bindings/js/JSCryptoKeySerializationJWK.h:
* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::createAlgorithmFromJSValue):
(WebCore::importKey):
(WebCore::JSSubtleCrypto::importKey):
(WebCore::JSSubtleCrypto::wrapKey):
(WebCore::JSSubtleCrypto::unwrapKey):
* crypto/CryptoAlgorithm.h:
* crypto/CryptoAlgorithmParameters.h:
* crypto/CryptoAlgorithmRegistry.cpp:
(WebCore::CryptoAlgorithmRegistry::create):
* crypto/CryptoAlgorithmRegistry.h:
* crypto/CryptoKeySerialization.h:
* crypto/algorithms/CryptoAlgorithmAES_CBC.cpp:
(WebCore::CryptoAlgorithmAES_CBC::create):
* crypto/algorithms/CryptoAlgorithmAES_CBC.h:
* crypto/algorithms/CryptoAlgorithmAES_KW.cpp:
(WebCore::CryptoAlgorithmAES_KW::create):
* crypto/algorithms/CryptoAlgorithmAES_KW.h:
* crypto/algorithms/CryptoAlgorithmHMAC.cpp:
(WebCore::CryptoAlgorithmHMAC::create):
* crypto/algorithms/CryptoAlgorithmHMAC.h:
* crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::create):
* crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h:
* crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::create):
* crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h:
* crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:
(WebCore::CryptoAlgorithmRSA_OAEP::create):
* crypto/algorithms/CryptoAlgorithmRSA_OAEP.h:
* crypto/algorithms/CryptoAlgorithmSHA1.cpp:
(WebCore::CryptoAlgorithmSHA1::create):
* crypto/algorithms/CryptoAlgorithmSHA1.h:
* crypto/algorithms/CryptoAlgorithmSHA224.cpp:
(WebCore::CryptoAlgorithmSHA224::create):
* crypto/algorithms/CryptoAlgorithmSHA224.h:
* crypto/algorithms/CryptoAlgorithmSHA256.cpp:
(WebCore::CryptoAlgorithmSHA256::create):
* crypto/algorithms/CryptoAlgorithmSHA256.h:
* crypto/algorithms/CryptoAlgorithmSHA384.cpp:
(WebCore::CryptoAlgorithmSHA384::create):
* crypto/algorithms/CryptoAlgorithmSHA384.h:
* crypto/algorithms/CryptoAlgorithmSHA512.cpp:
(WebCore::CryptoAlgorithmSHA512::create):
* crypto/algorithms/CryptoAlgorithmSHA512.h:
* crypto/gnutls/CryptoAlgorithmAES_CBCGnuTLS.cpp:
(WebCore::CryptoAlgorithmAES_CBC::platformEncrypt):
(WebCore::CryptoAlgorithmAES_CBC::platformDecrypt):
* crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp:
(WebCore::CryptoAlgorithmAES_KW::platformEncrypt):
(WebCore::CryptoAlgorithmAES_KW::platformDecrypt):
* crypto/gnutls/CryptoAlgorithmHMACGnuTLS.cpp:
(WebCore::CryptoAlgorithmHMAC::platformSign):
(WebCore::CryptoAlgorithmHMAC::platformVerify):
* crypto/gnutls/CryptoAlgorithmRSAES_PKCS1_v1_5GnuTLS.cpp:
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt):
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::platformDecrypt):
* crypto/gnutls/CryptoAlgorithmRSASSA_PKCS1_v1_5GnuTLS.cpp:
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign):
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::platformVerify):
* crypto/gnutls/CryptoAlgorithmRSA_OAEPGnuTLS.cpp:
(WebCore::CryptoAlgorithmRSA_OAEP::platformEncrypt):
(WebCore::CryptoAlgorithmRSA_OAEP::platformDecrypt):
* crypto/keys/CryptoKeySerializationRaw.cpp:
(WebCore::CryptoKeySerializationRaw::reconcileAlgorithm):
* crypto/keys/CryptoKeySerializationRaw.h:

LayoutTests:

If you execute the added test with subtle-crypto-enabled GTK environment without this patch, this causes the crash.

* crypto/subtle/unimplemented-unwrap-crash-expected.txt: Added.
* crypto/subtle/unimplemented-unwrap-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203036 268f45cc-cd09-0410-ab3c-d52691b4dbfc

44 files changed:
LayoutTests/ChangeLog
LayoutTests/crypto/subtle/unimplemented-unwrap-crash-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/unimplemented-unwrap-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp
Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.h
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.h
Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp
Source/WebCore/crypto/CryptoAlgorithm.h
Source/WebCore/crypto/CryptoAlgorithmParameters.h
Source/WebCore/crypto/CryptoAlgorithmRegistry.cpp
Source/WebCore/crypto/CryptoAlgorithmRegistry.h
Source/WebCore/crypto/CryptoKeySerialization.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_CBC.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_CBC.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_OAEP.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA1.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA1.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA224.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA224.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA256.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA256.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA384.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA384.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA512.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmSHA512.h
Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_CBCGnuTLS.cpp
Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp
Source/WebCore/crypto/gnutls/CryptoAlgorithmHMACGnuTLS.cpp
Source/WebCore/crypto/gnutls/CryptoAlgorithmRSAES_PKCS1_v1_5GnuTLS.cpp
Source/WebCore/crypto/gnutls/CryptoAlgorithmRSASSA_PKCS1_v1_5GnuTLS.cpp
Source/WebCore/crypto/gnutls/CryptoAlgorithmRSA_OAEPGnuTLS.cpp
Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp
Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h

index 851ccb8..a2a082a 100644 (file)
@@ -1,3 +1,15 @@
+2016-07-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [GTK] Crash on https://diafygi.github.io/webcrypto-examples with ENABLE_SUBTLE_CRYPTO
+        https://bugs.webkit.org/show_bug.cgi?id=159189
+
+        Reviewed by Michael Catanzaro.
+
+        If you execute the added test with subtle-crypto-enabled GTK environment without this patch, this causes the crash.
+
+        * crypto/subtle/unimplemented-unwrap-crash-expected.txt: Added.
+        * crypto/subtle/unimplemented-unwrap-crash.html: Added.
+
 2016-07-09  Keith Miller  <keith_miller@apple.com>
 
         appendMemcpy might fail in concatAppendOne
diff --git a/LayoutTests/crypto/subtle/unimplemented-unwrap-crash-expected.txt b/LayoutTests/crypto/subtle/unimplemented-unwrap-crash-expected.txt
new file mode 100644 (file)
index 0000000..708e8df
--- /dev/null
@@ -0,0 +1,9 @@
+Make sure that unwrap does not cause a crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/unimplemented-unwrap-crash.html b/LayoutTests/crypto/subtle/unimplemented-unwrap-crash.html
new file mode 100644 (file)
index 0000000..e3bacb4
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="resources/common.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+description("Make sure that unwrap does not cause a crash.");
+
+jsTestIsAsync = true;
+
+crypto.subtle.generateKey({name: "AES-KW", length: 256}, false, ["wrapKey"]).then(function(wrappingKey) {
+    return crypto.subtle.generateKey({name: "HMAC", hash: {name: "SHA-256"}}, true, ["sign", "verify"]).then(function(aesKey) {
+        return crypto.subtle.wrapKey("raw", aesKey, wrappingKey, {name: "AES-KW"});
+    });
+}).then(finishJSTest, finishJSTest); // OK if the browser does not crash.
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index 1393abe..ac5cc90 100644 (file)
@@ -1,3 +1,120 @@
+2016-07-10  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [GTK] Crash on https://diafygi.github.io/webcrypto-examples with ENABLE_SUBTLE_CRYPTO
+        https://bugs.webkit.org/show_bug.cgi?id=159189
+
+        Reviewed by Michael Catanzaro.
+
+        Currently, we explicitly release the pointers of std::unique_ptr<CryptoAlgorithm> and std::unique_ptr<CryptoAlgorithmParameters>,
+        and delete them in the asynchronously called lambdas. In GnuTLS version, callback function is accidentally called twice,
+        and it incurs the double free problem.
+        In SubtleCrypto code, we have the rule that we must not call failureCallback when the error code is filled in synchronous execution.
+        So we drop the failureCallback calling code in GnuTLS subtle crypto code.
+
+        But, rather than carefully handling un-smart-pointer-managed raw pointer's life time, we should use ref counted pointer for that.
+        Using the raw delete is error-prone.
+
+        This patch also changes CryptoAlgorithm and CryptoAlgorithmParameters to RefCounted. And use Ref and RefPtr instead.
+        The change eliminates the ad-hoc delete code. And now, the lambdas can be called multiple times since once the result of the promise
+        is resolved or rejected, subsequent resolve / reject calls are ignored.
+
+        And this patch also fixes the incorrect call to the lambda that is already WTFMoved.
+
+        While we can see several `return WTFMove(...)`, they are necessary since it uses implicit type conversions, like,
+        `Ref<A>` => `RefPtr<A>`, and `Ref<Derived>` => `Ref<Base>`.
+
+        * bindings/js/JSCryptoAlgorithmDictionary.cpp:
+        (WebCore::createAesCbcParams):
+        (WebCore::createAesKeyGenParams):
+        (WebCore::createHmacParams):
+        (WebCore::createHmacKeyParams):
+        (WebCore::createRsaKeyGenParams):
+        (WebCore::createRsaKeyParamsWithHash):
+        (WebCore::createRsaOaepParams):
+        (WebCore::createRsaSsaParams):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForEncrypt):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDecrypt):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForSign):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForVerify):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDigest):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForGenerateKey):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveKey):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveBits):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForExportKey):
+        * bindings/js/JSCryptoAlgorithmDictionary.h:
+        * bindings/js/JSCryptoKeySerializationJWK.cpp:
+        (WebCore::createHMACParameters):
+        (WebCore::createRSAKeyParametersWithHash):
+        (WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm):
+        * bindings/js/JSCryptoKeySerializationJWK.h:
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::createAlgorithmFromJSValue):
+        (WebCore::importKey):
+        (WebCore::JSSubtleCrypto::importKey):
+        (WebCore::JSSubtleCrypto::wrapKey):
+        (WebCore::JSSubtleCrypto::unwrapKey):
+        * crypto/CryptoAlgorithm.h:
+        * crypto/CryptoAlgorithmParameters.h:
+        * crypto/CryptoAlgorithmRegistry.cpp:
+        (WebCore::CryptoAlgorithmRegistry::create):
+        * crypto/CryptoAlgorithmRegistry.h:
+        * crypto/CryptoKeySerialization.h:
+        * crypto/algorithms/CryptoAlgorithmAES_CBC.cpp:
+        (WebCore::CryptoAlgorithmAES_CBC::create):
+        * crypto/algorithms/CryptoAlgorithmAES_CBC.h:
+        * crypto/algorithms/CryptoAlgorithmAES_KW.cpp:
+        (WebCore::CryptoAlgorithmAES_KW::create):
+        * crypto/algorithms/CryptoAlgorithmAES_KW.h:
+        * crypto/algorithms/CryptoAlgorithmHMAC.cpp:
+        (WebCore::CryptoAlgorithmHMAC::create):
+        * crypto/algorithms/CryptoAlgorithmHMAC.h:
+        * crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:
+        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::create):
+        * crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.h:
+        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::create):
+        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h:
+        * crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:
+        (WebCore::CryptoAlgorithmRSA_OAEP::create):
+        * crypto/algorithms/CryptoAlgorithmRSA_OAEP.h:
+        * crypto/algorithms/CryptoAlgorithmSHA1.cpp:
+        (WebCore::CryptoAlgorithmSHA1::create):
+        * crypto/algorithms/CryptoAlgorithmSHA1.h:
+        * crypto/algorithms/CryptoAlgorithmSHA224.cpp:
+        (WebCore::CryptoAlgorithmSHA224::create):
+        * crypto/algorithms/CryptoAlgorithmSHA224.h:
+        * crypto/algorithms/CryptoAlgorithmSHA256.cpp:
+        (WebCore::CryptoAlgorithmSHA256::create):
+        * crypto/algorithms/CryptoAlgorithmSHA256.h:
+        * crypto/algorithms/CryptoAlgorithmSHA384.cpp:
+        (WebCore::CryptoAlgorithmSHA384::create):
+        * crypto/algorithms/CryptoAlgorithmSHA384.h:
+        * crypto/algorithms/CryptoAlgorithmSHA512.cpp:
+        (WebCore::CryptoAlgorithmSHA512::create):
+        * crypto/algorithms/CryptoAlgorithmSHA512.h:
+        * crypto/gnutls/CryptoAlgorithmAES_CBCGnuTLS.cpp:
+        (WebCore::CryptoAlgorithmAES_CBC::platformEncrypt):
+        (WebCore::CryptoAlgorithmAES_CBC::platformDecrypt):
+        * crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp:
+        (WebCore::CryptoAlgorithmAES_KW::platformEncrypt):
+        (WebCore::CryptoAlgorithmAES_KW::platformDecrypt):
+        * crypto/gnutls/CryptoAlgorithmHMACGnuTLS.cpp:
+        (WebCore::CryptoAlgorithmHMAC::platformSign):
+        (WebCore::CryptoAlgorithmHMAC::platformVerify):
+        * crypto/gnutls/CryptoAlgorithmRSAES_PKCS1_v1_5GnuTLS.cpp:
+        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt):
+        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::platformDecrypt):
+        * crypto/gnutls/CryptoAlgorithmRSASSA_PKCS1_v1_5GnuTLS.cpp:
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign):
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::platformVerify):
+        * crypto/gnutls/CryptoAlgorithmRSA_OAEPGnuTLS.cpp:
+        (WebCore::CryptoAlgorithmRSA_OAEP::platformEncrypt):
+        (WebCore::CryptoAlgorithmRSA_OAEP::platformDecrypt):
+        * crypto/keys/CryptoKeySerializationRaw.cpp:
+        (WebCore::CryptoKeySerializationRaw::reconcileAlgorithm):
+        * crypto/keys/CryptoKeySerializationRaw.h:
+
 2016-07-09  Antti Koivisto  <antti@apple.com>
 
         REGRESSION (r202931): breaks release builds with ASSERT_WITH_SECURITY_IMPLICATION for fuzzing
index 62ccd17..82d2e04 100644 (file)
@@ -120,7 +120,7 @@ static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier
     return JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(exec, hash, result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -131,7 +131,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(ExecState*
     if (exec->hadException())
         return nullptr;
 
-    auto result = std::make_unique<CryptoAlgorithmAesCbcParams>();
+    auto result = adoptRef(*new CryptoAlgorithmAesCbcParams);
 
     CryptoOperationData ivData;
     if (!cryptoOperationDataFromJSValue(exec, iv, ivData)) {
@@ -149,14 +149,14 @@ static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(ExecState*
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createAesKeyGenParams(ExecState& state, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(&state);
         return nullptr;
     }
 
-    auto result = std::make_unique<CryptoAlgorithmAesKeyGenParams>();
+    auto result = adoptRef(*new CryptoAlgorithmAesKeyGenParams);
 
     JSValue lengthValue = getProperty(&state, value.getObject(), "length");
     if (state.hadException())
@@ -167,7 +167,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(ExecStat
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createHmacParams(ExecState& state, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(&state);
@@ -175,7 +175,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState& st
     }
 
     JSDictionary jsDictionary(&state, value.getObject());
-    auto result = std::make_unique<CryptoAlgorithmHmacParams>();
+    auto result = adoptRef(*new CryptoAlgorithmHmacParams);
 
     if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(state.hadException());
@@ -185,7 +185,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState& st
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState& state, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(&state);
@@ -193,7 +193,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState&
     }
 
     JSDictionary jsDictionary(&state, value.getObject());
-    auto result = std::make_unique<CryptoAlgorithmHmacKeyParams>();
+    auto result = adoptRef(*new CryptoAlgorithmHmacKeyParams);
 
     if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(state.hadException());
@@ -207,7 +207,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState&
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState& state, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(&state);
@@ -215,7 +215,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecStat
     }
 
     JSDictionary jsDictionary(&state, value.getObject());
-    auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>();
+    auto result = adoptRef(*new CryptoAlgorithmRsaKeyGenParams);
 
     JSValue modulusLengthValue = getProperty(&state, value.getObject(), "modulusLength");
     if (state.hadException())
@@ -242,13 +242,13 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecStat
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyParamsWithHash(ExecState&, JSValue)
+static RefPtr<CryptoAlgorithmParameters> createRsaKeyParamsWithHash(ExecState&, JSValue)
 {
     // WebCrypto RSA algorithms currently do not take any parameters to importKey.
-    return std::make_unique<CryptoAlgorithmRsaKeyParamsWithHash>();
+    return adoptRef(*new CryptoAlgorithmRsaKeyParamsWithHash);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -256,7 +256,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState*
     }
 
     JSDictionary jsDictionary(exec, value.getObject());
-    auto result = std::make_unique<CryptoAlgorithmRsaOaepParams>();
+    auto result = adoptRef(*new CryptoAlgorithmRsaOaepParams);
 
     if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(exec->hadException());
@@ -282,7 +282,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState*
     return WTFMove(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState& state, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(&state);
@@ -290,7 +290,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState&
     }
 
     JSDictionary jsDictionary(&state, value.getObject());
-    auto result = std::make_unique<CryptoAlgorithmRsaSsaParams>();
+    auto result = adoptRef(*new CryptoAlgorithmRsaSsaParams);
 
     if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(state.hadException());
@@ -300,11 +300,11 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState&
     return WTFMove(result);
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForEncrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForEncrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
     case CryptoAlgorithmIdentifier::RSA_PSS:
         setDOMException(exec, NOT_SUPPORTED_ERR);
@@ -324,7 +324,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return nullptr;
     case CryptoAlgorithmIdentifier::AES_KW:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::HMAC:
     case CryptoAlgorithmIdentifier::DH:
     case CryptoAlgorithmIdentifier::SHA_1:
@@ -342,11 +342,11 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDecrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDecrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
     case CryptoAlgorithmIdentifier::RSA_PSS:
         setDOMException(exec, NOT_SUPPORTED_ERR);
@@ -366,7 +366,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return nullptr;
     case CryptoAlgorithmIdentifier::AES_KW:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::HMAC:
     case CryptoAlgorithmIdentifier::DH:
     case CryptoAlgorithmIdentifier::SHA_1:
@@ -384,7 +384,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForSign(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForSign(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -422,7 +422,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForVerify(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForVerify(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -460,7 +460,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDigest(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDigest(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -484,7 +484,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     case CryptoAlgorithmIdentifier::SHA_256:
     case CryptoAlgorithmIdentifier::SHA_384:
     case CryptoAlgorithmIdentifier::SHA_512:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::CONCAT:
     case CryptoAlgorithmIdentifier::HKDF_CTR:
     case CryptoAlgorithmIdentifier::PBKDF2:
@@ -495,7 +495,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForGenerateKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForGenerateKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -532,7 +532,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -564,7 +564,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveBits(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveBits(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -596,7 +596,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForImportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForImportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -612,11 +612,11 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     case CryptoAlgorithmIdentifier::AES_GCM:
     case CryptoAlgorithmIdentifier::AES_CFB:
     case CryptoAlgorithmIdentifier::AES_KW:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::HMAC:
         return createHmacParams(*exec, value);
     case CryptoAlgorithmIdentifier::DH:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::SHA_1:
     case CryptoAlgorithmIdentifier::SHA_224:
     case CryptoAlgorithmIdentifier::SHA_256:
@@ -632,7 +632,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     return nullptr;
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForExportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
+RefPtr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForExportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -649,7 +649,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     case CryptoAlgorithmIdentifier::AES_KW:
     case CryptoAlgorithmIdentifier::HMAC:
     case CryptoAlgorithmIdentifier::DH:
-        return std::make_unique<CryptoAlgorithmParameters>();
+        return adoptRef(*new CryptoAlgorithmParameters);
     case CryptoAlgorithmIdentifier::SHA_1:
     case CryptoAlgorithmIdentifier::SHA_224:
     case CryptoAlgorithmIdentifier::SHA_256:
index 4d83686..b5facd0 100644 (file)
@@ -27,6 +27,7 @@
 #define JSCryptoAlgorithmDictionary_h
 
 #include "CryptoAlgorithmIdentifier.h"
+#include <wtf/RefPtr.h>
 
 #if ENABLE(SUBTLE_CRYPTO)
 
@@ -43,16 +44,16 @@ class JSCryptoAlgorithmDictionary {
 public:
     static bool getAlgorithmIdentifier(JSC::ExecState*, JSC::JSValue, CryptoAlgorithmIdentifier&);
 
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForEncrypt(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForDecrypt(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForSign(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForVerify(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForDigest(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForGenerateKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForDeriveKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForDeriveBits(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForImportKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForExportKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForEncrypt(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForDecrypt(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForSign(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForVerify(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForDigest(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForGenerateKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForDeriveKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForDeriveBits(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForImportKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
+    static RefPtr<CryptoAlgorithmParameters> createParametersForExportKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
 };
 
 }
index 10aa914..61b26c0 100644 (file)
@@ -148,31 +148,31 @@ JSCryptoKeySerializationJWK::~JSCryptoKeySerializationJWK()
 {
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createHMACParameters(CryptoAlgorithmIdentifier hashFunction)
+static Ref<CryptoAlgorithmParameters> createHMACParameters(CryptoAlgorithmIdentifier hashFunction)
 {
-    std::unique_ptr<CryptoAlgorithmHmacParams> hmacParameters = std::make_unique<CryptoAlgorithmHmacParams>();
+    auto hmacParameters = adoptRef(*new CryptoAlgorithmHmacParams);
     hmacParameters->hash = hashFunction;
     return WTFMove(hmacParameters);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier hashFunction)
+static Ref<CryptoAlgorithmParameters> createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier hashFunction)
 {
-    std::unique_ptr<CryptoAlgorithmRsaKeyParamsWithHash> rsaKeyParameters = std::make_unique<CryptoAlgorithmRsaKeyParamsWithHash>();
+    auto rsaKeyParameters = adoptRef(*new CryptoAlgorithmRsaKeyParamsWithHash);
     rsaKeyParameters->hasHash = true;
     rsaKeyParameters->hash = hashFunction;
     return WTFMove(rsaKeyParameters);
 }
 
-bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>& suggestedAlgorithm, std::unique_ptr<CryptoAlgorithmParameters>& suggestedParameters) const
+Optional<CryptoAlgorithmPair> JSCryptoKeySerializationJWK::reconcileAlgorithm(CryptoAlgorithm* suggestedAlgorithm, CryptoAlgorithmParameters* suggestedParameters) const
 {
     if (!getStringFromJSON(m_exec, m_json.get(), "alg", m_jwkAlgorithmName)) {
         // Algorithm is optional in JWK.
-        return true;
+        return CryptoAlgorithmPair { suggestedAlgorithm, suggestedParameters };
     }
 
     auto& algorithmRegisty = CryptoAlgorithmRegistry::singleton();
-    std::unique_ptr<CryptoAlgorithm> algorithm;
-    std::unique_ptr<CryptoAlgorithmParameters> parameters;
+    RefPtr<CryptoAlgorithm> algorithm;
+    RefPtr<CryptoAlgorithmParameters> parameters;
     if (m_jwkAlgorithmName == "HS256") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::HMAC);
         parameters = createHMACParameters(CryptoAlgorithmIdentifier::SHA_256);
@@ -193,60 +193,63 @@ bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgor
         parameters = createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier::SHA_512);
     } else if (m_jwkAlgorithmName == "RSA1_5") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5);
-        parameters = std::make_unique<CryptoAlgorithmRsaKeyParamsWithHash>();
+        parameters = adoptRef(*new CryptoAlgorithmRsaKeyParamsWithHash);
     } else if (m_jwkAlgorithmName == "RSA-OAEP") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::RSA_OAEP);
         parameters = createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier::SHA_1);
     } else if (m_jwkAlgorithmName == "A128CBC") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_CBC);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else if (m_jwkAlgorithmName == "A192CBC") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_CBC);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else if (m_jwkAlgorithmName == "A256CBC") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_CBC);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else if (m_jwkAlgorithmName == "A128KW") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_KW);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else if (m_jwkAlgorithmName == "A192KW") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_KW);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else if (m_jwkAlgorithmName == "A256KW") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::AES_KW);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = adoptRef(*new CryptoAlgorithmParameters);
     } else {
         throwTypeError(m_exec, "Unsupported JWK algorithm " + m_jwkAlgorithmName);
-        return false;
+        return Nullopt;
     }
 
-    if (!suggestedAlgorithm) {
-        suggestedAlgorithm = WTFMove(algorithm);
-        suggestedParameters =  WTFMove(parameters);
-        return true;
-    }
+    if (!suggestedAlgorithm)
+        return CryptoAlgorithmPair { algorithm, parameters };
 
     if (!algorithm)
-        return true;
+        return CryptoAlgorithmPair { suggestedAlgorithm, suggestedParameters };
 
     if (algorithm->identifier() != suggestedAlgorithm->identifier())
-        return false;
+        return Nullopt;
 
-    if (algorithm->identifier() == CryptoAlgorithmIdentifier::HMAC)
-        return downcast<CryptoAlgorithmHmacParams>(*parameters).hash == downcast<CryptoAlgorithmHmacParams>(*suggestedParameters).hash;
+    if (algorithm->identifier() == CryptoAlgorithmIdentifier::HMAC) {
+        if (downcast<CryptoAlgorithmHmacParams>(*parameters).hash != downcast<CryptoAlgorithmHmacParams>(*suggestedParameters).hash)
+            return Nullopt;
+        return CryptoAlgorithmPair { suggestedAlgorithm, suggestedParameters };
+    }
     if (algorithm->identifier() == CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5
         || algorithm->identifier() == CryptoAlgorithmIdentifier::RSA_OAEP) {
         CryptoAlgorithmRsaKeyParamsWithHash& rsaKeyParameters = downcast<CryptoAlgorithmRsaKeyParamsWithHash>(*parameters);
         CryptoAlgorithmRsaKeyParamsWithHash& suggestedRSAKeyParameters = downcast<CryptoAlgorithmRsaKeyParamsWithHash>(*suggestedParameters);
         ASSERT(rsaKeyParameters.hasHash);
-        if (suggestedRSAKeyParameters.hasHash)
-            return suggestedRSAKeyParameters.hash == rsaKeyParameters.hash;
+        if (suggestedRSAKeyParameters.hasHash) {
+            if (suggestedRSAKeyParameters.hash != rsaKeyParameters.hash)
+                return Nullopt;
+            return CryptoAlgorithmPair { suggestedAlgorithm, suggestedParameters };
+        }
         suggestedRSAKeyParameters.hasHash = true;
         suggestedRSAKeyParameters.hash = rsaKeyParameters.hash;
     }
 
     // Other algorithms don't have parameters.
-    return true;
+    return CryptoAlgorithmPair { suggestedAlgorithm, suggestedParameters };
 }
 
 static bool tryJWKKeyOpsValue(ExecState* exec, CryptoKeyUsage& usages, const String& operation, const String& tryOperation, CryptoKeyUsage tryUsage)
index b7e6275..0955ccf 100644 (file)
@@ -53,7 +53,7 @@ public:
     static String serialize(JSC::ExecState* exec, const CryptoKey&);
 
 private:
-    bool reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>&, std::unique_ptr<CryptoAlgorithmParameters>&) const override;
+    Optional<CryptoAlgorithmPair> reconcileAlgorithm(CryptoAlgorithm*, CryptoAlgorithmParameters*) const override;
 
     void reconcileUsages(CryptoKeyUsage&) const override;
     void reconcileExtractable(bool&) const override;
index 03351d5..69e1578 100644 (file)
@@ -61,7 +61,7 @@ enum class CryptoKeyFormat {
     JWK
 };
 
-static std::unique_ptr<CryptoAlgorithm> createAlgorithmFromJSValue(ExecState& state, JSValue value)
+static RefPtr<CryptoAlgorithm> createAlgorithmFromJSValue(ExecState& state, JSValue value)
 {
     CryptoAlgorithmIdentifier algorithmIdentifier;
     if (!JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(&state, value, algorithmIdentifier)) {
@@ -443,7 +443,7 @@ JSValue JSSubtleCrypto::generateKey(ExecState& state)
     return promiseDeferred->promise();
 }
 
-static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperationData data, std::unique_ptr<CryptoAlgorithm> algorithm, std::unique_ptr<CryptoAlgorithmParameters> parameters, bool extractable, CryptoKeyUsage keyUsages, CryptoAlgorithm::KeyCallback callback, CryptoAlgorithm::VoidCallback failureCallback)
+static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperationData data, RefPtr<CryptoAlgorithm> algorithm, RefPtr<CryptoAlgorithmParameters> parameters, bool extractable, CryptoKeyUsage keyUsages, CryptoAlgorithm::KeyCallback callback, CryptoAlgorithm::VoidCallback failureCallback)
 {
     std::unique_ptr<CryptoKeySerialization> keySerialization;
     switch (keyFormat) {
@@ -468,7 +468,8 @@ static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperati
 
     ASSERT(keySerialization);
 
-    if (!keySerialization->reconcileAlgorithm(algorithm, parameters)) {
+    Optional<CryptoAlgorithmPair> reconciledResult = keySerialization->reconcileAlgorithm(algorithm.get(), parameters.get());
+    if (!reconciledResult) {
         if (!state.hadException())
             throwTypeError(&state, ASCIILiteral("Algorithm specified in key is not compatible with one passed to importKey as argument"));
         return;
@@ -476,6 +477,8 @@ static void importKey(ExecState& state, CryptoKeyFormat keyFormat, CryptoOperati
     if (state.hadException())
         return;
 
+    algorithm = reconciledResult->algorithm;
+    parameters = reconciledResult->parameters;
     if (!algorithm) {
         throwTypeError(&state, ASCIILiteral("Neither key nor function argument has crypto algorithm specified"));
         return;
@@ -517,8 +520,8 @@ JSValue JSSubtleCrypto::importKey(ExecState& state)
         return jsUndefined();
     }
 
-    std::unique_ptr<CryptoAlgorithm> algorithm;
-    std::unique_ptr<CryptoAlgorithmParameters> parameters;
+    RefPtr<CryptoAlgorithm> algorithm;
+    RefPtr<CryptoAlgorithmParameters> parameters;
     if (!state.uncheckedArgument(2).isNull()) {
         algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(2));
         if (!algorithm) {
@@ -666,39 +669,28 @@ JSValue JSSubtleCrypto::wrapKey(ExecState& state)
     JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(&state, globalObject());
     DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
 
-    CryptoAlgorithm* algorithmPtr = algorithm.release();
-    CryptoAlgorithmParameters* parametersPtr = parameters.release();
-
-    auto exportSuccessCallback = [keyFormat, algorithmPtr, parametersPtr, wrappingKey, wrapper](const Vector<uint8_t>& exportedKeyData) mutable {
-        auto encryptSuccessCallback = [wrapper, algorithmPtr, parametersPtr](const Vector<uint8_t>& encryptedData) mutable {
-            delete algorithmPtr;
-            delete parametersPtr;
+    auto exportSuccessCallback = [keyFormat, algorithm, parameters, wrappingKey, wrapper](const Vector<uint8_t>& exportedKeyData) mutable {
+        auto encryptSuccessCallback = [wrapper](const Vector<uint8_t>& encryptedData) mutable {
             fulfillPromiseWithArrayBuffer(wrapper, encryptedData.data(), encryptedData.size());
         };
-        auto encryptFailureCallback = [wrapper, algorithmPtr, parametersPtr]() mutable {
-            delete algorithmPtr;
-            delete parametersPtr;
+        auto encryptFailureCallback = [wrapper]() mutable {
             wrapper.reject(nullptr);
         };
         ExceptionCode ec = 0;
-        algorithmPtr->encryptForWrapKey(*parametersPtr, *wrappingKey, std::make_pair(exportedKeyData.data(), exportedKeyData.size()), WTFMove(encryptSuccessCallback), WTFMove(encryptFailureCallback), ec);
+        algorithm->encryptForWrapKey(*parameters, *wrappingKey, std::make_pair(exportedKeyData.data(), exportedKeyData.size()), WTFMove(encryptSuccessCallback), WTFMove(encryptFailureCallback), ec);
         if (ec) {
             // FIXME: Report failure details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions.
-            encryptFailureCallback();
+            wrapper.reject(nullptr);
         }
     };
 
-    auto exportFailureCallback = [wrapper, algorithmPtr, parametersPtr]() mutable {
-        delete algorithmPtr;
-        delete parametersPtr;
+    auto exportFailureCallback = [wrapper]() mutable {
         wrapper.reject(nullptr);
     };
 
     ExceptionCode ec = 0;
     WebCore::exportKey(state, keyFormat, *key, WTFMove(exportSuccessCallback), WTFMove(exportFailureCallback));
     if (ec) {
-        delete algorithmPtr;
-        delete parametersPtr;
         setDOMException(&state, ec);
         return jsUndefined();
     }
@@ -733,21 +725,19 @@ JSValue JSSubtleCrypto::unwrapKey(ExecState& state)
         return jsUndefined();
     }
 
-    std::unique_ptr<CryptoAlgorithm> unwrapAlgorithm;
-    std::unique_ptr<CryptoAlgorithmParameters> unwrapAlgorithmParameters;
-    unwrapAlgorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(3));
+    auto unwrapAlgorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(3));
     if (!unwrapAlgorithm) {
         ASSERT(state.hadException());
         return jsUndefined();
     }
-    unwrapAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForDecrypt(&state, unwrapAlgorithm->identifier(), state.uncheckedArgument(3));
+    auto unwrapAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForDecrypt(&state, unwrapAlgorithm->identifier(), state.uncheckedArgument(3));
     if (!unwrapAlgorithmParameters) {
         ASSERT(state.hadException());
         return jsUndefined();
     }
 
-    std::unique_ptr<CryptoAlgorithm> unwrappedKeyAlgorithm;
-    std::unique_ptr<CryptoAlgorithmParameters> unwrappedKeyAlgorithmParameters;
+    RefPtr<CryptoAlgorithm> unwrappedKeyAlgorithm;
+    RefPtr<CryptoAlgorithmParameters> unwrappedKeyAlgorithmParameters;
     if (!state.uncheckedArgument(4).isNull()) {
         unwrappedKeyAlgorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(4));
         if (!unwrappedKeyAlgorithm) {
@@ -780,10 +770,7 @@ JSValue JSSubtleCrypto::unwrapKey(ExecState& state)
     DeferredWrapper wrapper(&state, globalObject(), promiseDeferred);
     Strong<JSDOMGlobalObject> domGlobalObject(state.vm(), globalObject());
 
-    CryptoAlgorithm* unwrappedKeyAlgorithmPtr = unwrappedKeyAlgorithm.release();
-    CryptoAlgorithmParameters* unwrappedKeyAlgorithmParametersPtr = unwrappedKeyAlgorithmParameters.release();
-
-    auto decryptSuccessCallback = [domGlobalObject, keyFormat, unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr, extractable, keyUsages, wrapper](const Vector<uint8_t>& result) mutable {
+    auto decryptSuccessCallback = [domGlobalObject, keyFormat, unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, wrapper](const Vector<uint8_t>& result) mutable {
         auto importSuccessCallback = [wrapper](CryptoKey& key) mutable {
             wrapper.resolve(key);
         };
@@ -791,25 +778,21 @@ JSValue JSSubtleCrypto::unwrapKey(ExecState& state)
             wrapper.reject(nullptr);
         };
         ExecState& state = *domGlobalObject->globalExec();
-        WebCore::importKey(state, keyFormat, std::make_pair(result.data(), result.size()), std::unique_ptr<CryptoAlgorithm>(unwrappedKeyAlgorithmPtr), std::unique_ptr<CryptoAlgorithmParameters>(unwrappedKeyAlgorithmParametersPtr), extractable, keyUsages, WTFMove(importSuccessCallback), WTFMove(importFailureCallback));
+        WebCore::importKey(state, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithm, unwrappedKeyAlgorithmParameters, extractable, keyUsages, WTFMove(importSuccessCallback), WTFMove(importFailureCallback));
         if (state.hadException()) {
             // FIXME: Report exception details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions.
             state.clearException();
-            importFailureCallback();
+            wrapper.reject(nullptr);
         }
     };
 
-    auto decryptFailureCallback = [wrapper, unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr]() mutable {
-        delete unwrappedKeyAlgorithmPtr;
-        delete unwrappedKeyAlgorithmParametersPtr;
+    auto decryptFailureCallback = [wrapper]() mutable {
         wrapper.reject(nullptr);
     };
 
     ExceptionCode ec = 0;
     unwrapAlgorithm->decryptForUnwrapKey(*unwrapAlgorithmParameters, *unwrappingKey, wrappedKeyData, WTFMove(decryptSuccessCallback), WTFMove(decryptFailureCallback), ec);
     if (ec) {
-        delete unwrappedKeyAlgorithmPtr;
-        delete unwrappedKeyAlgorithmParametersPtr;
         setDOMException(&state, ec);
         return jsUndefined();
     }
index cecd22b..8ba83b3 100644 (file)
@@ -30,6 +30,7 @@
 #include "CryptoKeyUsage.h"
 #include <functional>
 #include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 #if ENABLE(SUBTLE_CRYPTO)
@@ -46,7 +47,7 @@ class CryptoKeyData;
 // Data is mutable, so async operations should copy it first.
 typedef std::pair<const uint8_t*, size_t> CryptoOperationData;
 
-class CryptoAlgorithm {
+class CryptoAlgorithm : public RefCounted<CryptoAlgorithm> {
     WTF_MAKE_NONCOPYABLE(CryptoAlgorithm)
 public:
     virtual ~CryptoAlgorithm();
index 2424bbd..3703e46 100644 (file)
 #define CryptoAlgorithmParameters_h
 
 #include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
 #include <wtf/TypeCasts.h>
 
 #if ENABLE(SUBTLE_CRYPTO)
 
 namespace WebCore {
 
-class CryptoAlgorithmParameters {
+class CryptoAlgorithmParameters : public RefCounted<CryptoAlgorithmParameters> {
     WTF_MAKE_NONCOPYABLE(CryptoAlgorithmParameters);
 public:
     CryptoAlgorithmParameters() { }
index 90ba83c..307e356 100644 (file)
@@ -70,7 +70,7 @@ String CryptoAlgorithmRegistry::nameForIdentifier(CryptoAlgorithmIdentifier iden
     return m_identifierToNameMap.get(static_cast<unsigned>(identifier)).isolatedCopy();
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmRegistry::create(CryptoAlgorithmIdentifier identifier)
+RefPtr<CryptoAlgorithm> CryptoAlgorithmRegistry::create(CryptoAlgorithmIdentifier identifier)
 {
     std::lock_guard<StaticLock> lock(registryMutex);
 
index ed972c6..0515c21 100644 (file)
@@ -50,13 +50,13 @@ public:
     bool getIdentifierForName(const String&, CryptoAlgorithmIdentifier&);
     String nameForIdentifier(CryptoAlgorithmIdentifier);
 
-    std::unique_ptr<CryptoAlgorithm> create(CryptoAlgorithmIdentifier);
+    RefPtr<CryptoAlgorithm> create(CryptoAlgorithmIdentifier);
 
 private:
     CryptoAlgorithmRegistry();
     void platformRegisterAlgorithms();
 
-    typedef std::unique_ptr<CryptoAlgorithm> (*CryptoAlgorithmConstructor)();
+    typedef Ref<CryptoAlgorithm> (*CryptoAlgorithmConstructor)();
 
     template<typename AlgorithmClass> void registerAlgorithm()
     {
index f37353a..ad06402 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "CryptoKeyUsage.h"
 #include <wtf/Noncopyable.h>
+#include <wtf/Optional.h>
+#include <wtf/RefPtr.h>
 
 #if ENABLE(SUBTLE_CRYPTO)
 
@@ -39,6 +41,11 @@ class CryptoKeyData;
 
 typedef std::pair<const uint8_t*, size_t> CryptoOperationData;
 
+struct CryptoAlgorithmPair {
+    RefPtr<CryptoAlgorithm> algorithm;
+    RefPtr<CryptoAlgorithmParameters> parameters;
+};
+
 class CryptoKeySerialization {
     WTF_MAKE_NONCOPYABLE(CryptoKeySerialization);
 public:
@@ -46,7 +53,7 @@ public:
     virtual ~CryptoKeySerialization() { }
 
     // Returns false if suggested algorithm was not compatible with one stored in the serialization.
-    virtual bool reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>&, std::unique_ptr<CryptoAlgorithmParameters>&) const = 0;
+    virtual Optional<CryptoAlgorithmPair> reconcileAlgorithm(CryptoAlgorithm*, CryptoAlgorithmParameters*) const = 0;
 
     virtual void reconcileUsages(CryptoKeyUsage&) const = 0;
     virtual void reconcileExtractable(bool&) const = 0;
index 902a20f..0890863 100644 (file)
@@ -46,9 +46,9 @@ CryptoAlgorithmAES_CBC::~CryptoAlgorithmAES_CBC()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmAES_CBC::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_CBC::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmAES_CBC);
+    return adoptRef(*new CryptoAlgorithmAES_CBC);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmAES_CBC::identifier() const
index 1646364..a61ba3a 100644 (file)
@@ -40,7 +40,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_CBC;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 455a939..c177443 100644 (file)
@@ -45,9 +45,9 @@ CryptoAlgorithmAES_KW::~CryptoAlgorithmAES_KW()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmAES_KW::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmAES_KW::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmAES_KW);
+    return adoptRef(*new CryptoAlgorithmAES_KW);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmAES_KW::identifier() const
index 10e9b2e..5143cb9 100644 (file)
@@ -39,7 +39,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::AES_KW;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 7cb329e..96d9da3 100644 (file)
@@ -46,9 +46,9 @@ CryptoAlgorithmHMAC::~CryptoAlgorithmHMAC()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmHMAC::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmHMAC::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmHMAC);
+    return adoptRef(*new CryptoAlgorithmHMAC);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmHMAC::identifier() const
index 500916a..3175460 100644 (file)
@@ -40,7 +40,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::HMAC;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 6a81eea..fefaa35 100644 (file)
@@ -46,9 +46,9 @@ CryptoAlgorithmRSAES_PKCS1_v1_5::~CryptoAlgorithmRSAES_PKCS1_v1_5()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmRSAES_PKCS1_v1_5::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmRSAES_PKCS1_v1_5::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmRSAES_PKCS1_v1_5);
+    return adoptRef(*new CryptoAlgorithmRSAES_PKCS1_v1_5);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmRSAES_PKCS1_v1_5::identifier() const
index 54ba465..e1d8e33 100644 (file)
@@ -40,7 +40,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 3ca237e..ab156cf 100644 (file)
@@ -47,9 +47,9 @@ CryptoAlgorithmRSASSA_PKCS1_v1_5::~CryptoAlgorithmRSASSA_PKCS1_v1_5()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmRSASSA_PKCS1_v1_5::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmRSASSA_PKCS1_v1_5::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmRSASSA_PKCS1_v1_5);
+    return adoptRef(*new CryptoAlgorithmRSASSA_PKCS1_v1_5);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmRSASSA_PKCS1_v1_5::identifier() const
index be067af..dc2bfd6 100644 (file)
@@ -40,7 +40,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 53ebd9c..5b0994d 100644 (file)
@@ -47,9 +47,9 @@ CryptoAlgorithmRSA_OAEP::~CryptoAlgorithmRSA_OAEP()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmRSA_OAEP::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmRSA_OAEP::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmRSA_OAEP);
+    return adoptRef(*new CryptoAlgorithmRSA_OAEP);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmRSA_OAEP::identifier() const
index ae83a4d..840be0b 100644 (file)
@@ -40,7 +40,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSA_OAEP;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 54dcd03..578b66b 100644 (file)
@@ -42,9 +42,9 @@ CryptoAlgorithmSHA1::~CryptoAlgorithmSHA1()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmSHA1::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA1::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmSHA1);
+    return adoptRef(*new CryptoAlgorithmSHA1);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmSHA1::identifier() const
index 5de1d5d..8292437 100644 (file)
@@ -37,7 +37,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_1;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 3878227..30d2b13 100644 (file)
@@ -42,9 +42,9 @@ CryptoAlgorithmSHA224::~CryptoAlgorithmSHA224()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmSHA224::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA224::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmSHA224);
+    return adoptRef(*new CryptoAlgorithmSHA224);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmSHA224::identifier() const
index d4041d3..a4f4308 100644 (file)
@@ -37,7 +37,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_224;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 0acaf09..eb2ada2 100644 (file)
@@ -42,9 +42,9 @@ CryptoAlgorithmSHA256::~CryptoAlgorithmSHA256()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmSHA256::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA256::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmSHA256);
+    return adoptRef(*new CryptoAlgorithmSHA256);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmSHA256::identifier() const
index 7ff7fbd..41d0779 100644 (file)
@@ -37,7 +37,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_256;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index b1bfbe1..d7d4102 100644 (file)
@@ -42,9 +42,9 @@ CryptoAlgorithmSHA384::~CryptoAlgorithmSHA384()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmSHA384::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA384::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmSHA384);
+    return adoptRef(*new CryptoAlgorithmSHA384);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmSHA384::identifier() const
index 9461f1c..8327003 100644 (file)
@@ -37,7 +37,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_384;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 7ddf1d4..161bf73 100644 (file)
@@ -42,9 +42,9 @@ CryptoAlgorithmSHA512::~CryptoAlgorithmSHA512()
 {
 }
 
-std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmSHA512::create()
+Ref<CryptoAlgorithm> CryptoAlgorithmSHA512::create()
 {
-    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmSHA512);
+    return adoptRef(*new CryptoAlgorithmSHA512);
 }
 
 CryptoAlgorithmIdentifier CryptoAlgorithmSHA512::identifier() const
index 7e03460..f316183 100644 (file)
@@ -37,7 +37,7 @@ public:
     static const char* const s_name;
     static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA_512;
 
-    static std::unique_ptr<CryptoAlgorithm> create();
+    static Ref<CryptoAlgorithm> create();
 
     CryptoAlgorithmIdentifier identifier() const override;
 
index 731718b..548a3ec 100644 (file)
@@ -39,24 +39,24 @@ void CryptoAlgorithmAES_CBC::platformEncrypt(const CryptoAlgorithmAesCbcParams&
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 void CryptoAlgorithmAES_CBC::platformDecrypt(const CryptoAlgorithmAesCbcParams& parameters, const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 } // namespace WebCore
index cf7bf95..9454c83 100644 (file)
@@ -38,22 +38,22 @@ void CryptoAlgorithmAES_KW::platformEncrypt(const CryptoKeyAES& key, const Crypt
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 void CryptoAlgorithmAES_KW::platformDecrypt(const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 } // namespace WebCore
index cc98561..ba91311 100644 (file)
@@ -70,10 +70,10 @@ static Vector<uint8_t> calculateSignature(gnutls_mac_algorithm_t algorithm, cons
 
 void CryptoAlgorithmHMAC::platformSign(const CryptoAlgorithmHmacParams& parameters, const CryptoKeyHMAC& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
+    UNUSED_PARAM(failureCallback);
     gnutls_mac_algorithm_t algorithm = getGnutlsDigestAlgorithm(parameters.hash);
     if (algorithm == GNUTLS_MAC_UNKNOWN) {
         ec = NOT_SUPPORTED_ERR;
-        failureCallback();
         return;
     }
 
@@ -84,10 +84,10 @@ void CryptoAlgorithmHMAC::platformSign(const CryptoAlgorithmHmacParams& paramete
 
 void CryptoAlgorithmHMAC::platformVerify(const CryptoAlgorithmHmacParams& parameters, const CryptoKeyHMAC& key, const CryptoOperationData& expectedSignature, const CryptoOperationData& data, BoolCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
+    UNUSED_PARAM(failureCallback);
     gnutls_mac_algorithm_t algorithm = getGnutlsDigestAlgorithm(parameters.hash);
     if (algorithm == GNUTLS_MAC_UNKNOWN) {
         ec = NOT_SUPPORTED_ERR;
-        failureCallback();
         return;
     }
 
index fbfe1c4..7a5e84b 100644 (file)
@@ -38,22 +38,22 @@ void CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt(const CryptoKeyRSA& key, c
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 void CryptoAlgorithmRSAES_PKCS1_v1_5::platformDecrypt(const CryptoKeyRSA& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 } // namespace WebCore
index 3e606bc..cf5667f 100644 (file)
@@ -39,27 +39,25 @@ void CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign(const CryptoAlgorithmRsaSsaP
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
-    UNUSED_PARAM(ec);
+    UNUSED_PARAM(failureCallback);
 }
 
 void CryptoAlgorithmRSASSA_PKCS1_v1_5::platformVerify(const CryptoAlgorithmRsaSsaParams& parameters, const CryptoKeyRSA& key, const CryptoOperationData& signature, const CryptoOperationData& data, BoolCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(signature);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
-    UNUSED_PARAM(ec);
+    UNUSED_PARAM(failureCallback);
 }
 
 } // namespace WebCore
index 5e5b436..3024bec 100644 (file)
@@ -39,24 +39,24 @@ void CryptoAlgorithmRSA_OAEP::platformEncrypt(const CryptoAlgorithmRsaOaepParams
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 void CryptoAlgorithmRSA_OAEP::platformDecrypt(const CryptoAlgorithmRsaOaepParams& parameters, const CryptoKeyRSA& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback, ExceptionCode& ec)
 {
     notImplemented();
     ec = NOT_SUPPORTED_ERR;
-    failureCallback();
 
     UNUSED_PARAM(parameters);
     UNUSED_PARAM(key);
     UNUSED_PARAM(data);
     UNUSED_PARAM(callback);
+    UNUSED_PARAM(failureCallback);
 }
 
 } // namespace WebCore
index 5a0f44c..ff08730 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(SUBTLE_CRYPTO)
 
 #include "CryptoAlgorithm.h"
+#include "CryptoAlgorithmParameters.h"
 #include "CryptoKey.h"
 #include "CryptoKeyDataOctetSequence.h"
 
@@ -43,9 +44,9 @@ CryptoKeySerializationRaw::~CryptoKeySerializationRaw()
 {
 }
 
-bool CryptoKeySerializationRaw::reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>&, std::unique_ptr<CryptoAlgorithmParameters>&) const
+Optional<CryptoAlgorithmPair> CryptoKeySerializationRaw::reconcileAlgorithm(CryptoAlgorithm* algorithm, CryptoAlgorithmParameters* parameters) const
 {
-    return true;
+    return CryptoAlgorithmPair { algorithm, parameters };
 }
 
 void CryptoKeySerializationRaw::reconcileUsages(CryptoKeyUsage&) const
index 266b6ff..08ead82 100644 (file)
@@ -51,7 +51,7 @@ public:
 private:
     CryptoKeySerializationRaw(const CryptoOperationData&);
 
-    bool reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>&, std::unique_ptr<CryptoAlgorithmParameters>&) const override;
+    Optional<CryptoAlgorithmPair> reconcileAlgorithm(CryptoAlgorithm*, CryptoAlgorithmParameters*) const override;
 
     void reconcileUsages(CryptoKeyUsage&) const override;
     void reconcileExtractable(bool&) const override;