Title: [159637] trunk
Revision
159637
Author
[email protected]
Date
2013-11-21 11:05:43 -0800 (Thu, 21 Nov 2013)

Log Message

Implement WebCrypto unwrapKey
https://bugs.webkit.org/show_bug.cgi?id=124725

Reviewed by Anders Carlsson.

Source/WebCore: 

Tests: crypto/subtle/aes-cbc-unwrap-failure.html
       crypto/subtle/aes-cbc-unwrap-rsa.html

* bindings/js/JSCryptoAlgorithmDictionary.cpp:
* bindings/js/JSCryptoAlgorithmDictionary.h:
Removed calls for wrap/unwrap parameter parsing, these are just the same as encrypt/decrypt.

* bindings/js/JSCryptoOperationData.cpp:
(WebCore::cryptoOperationDataFromJSValue):
* bindings/js/JSCryptoOperationData.h:
* crypto/CryptoKeySerialization.h:
More Vector<char> elimination.

* bindings/js/JSDOMPromise.cpp:
* bindings/js/JSDOMPromise.h:
Removed unneccessary copy constructor and assignment operator, they are no diffdrent
than compiler generated ones.

* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::cryptoKeyUsagesFromJSValue): Minor style fixes.
(WebCore::JSSubtleCrypto::encrypt): Ditto.
(WebCore::JSSubtleCrypto::decrypt): Ditto.
(WebCore::JSSubtleCrypto::sign): Ditto.
(WebCore::JSSubtleCrypto::verify): Ditto.
(WebCore::JSSubtleCrypto::generateKey): Ditto.
(WebCore::importKey): Separated actual import operation and the parts that read
arguments from ExecState, and call the promise. Logically, this should be outside
of bindings code even, but JWK makes that quite challenging.
(WebCore::JSSubtleCrypto::importKey): This only does the more mundane arguments
and return parts now.
(WebCore::JSSubtleCrypto::exportKey): Minor style fixes.
(WebCore::JSSubtleCrypto::unwrapKey): Chain decrypt and import.

* crypto/CryptoAlgorithm.cpp:
(WebCore::CryptoAlgorithm::encryptForWrapKey):
(WebCore::CryptoAlgorithm::decryptForUnwrapKey):
* crypto/CryptoAlgorithm.h:
There are algorithms that expose wrap/unwrap, but not encrypt/decrypt. These will
override these new functions, and leave encrypt/decrypt to raise NOT_SUPPORTED_ERR.

* crypto/SubtleCrypto.idl: Added unwrapKey.

LayoutTests: 

* crypto/subtle/aes-cbc-unwrap-failure-expected.txt: Added.
* crypto/subtle/aes-cbc-unwrap-failure.html: Added.
* crypto/subtle/aes-cbc-unwrap-rsa-expected.txt: Added.
* crypto/subtle/aes-cbc-unwrap-rsa.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (159636 => 159637)


--- trunk/LayoutTests/ChangeLog	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/LayoutTests/ChangeLog	2013-11-21 19:05:43 UTC (rev 159637)
@@ -1,3 +1,15 @@
+2013-11-21  Alexey Proskuryakov  <[email protected]>
+
+        Implement WebCrypto unwrapKey
+        https://bugs.webkit.org/show_bug.cgi?id=124725
+
+        Reviewed by Anders Carlsson.
+
+        * crypto/subtle/aes-cbc-unwrap-failure-expected.txt: Added.
+        * crypto/subtle/aes-cbc-unwrap-failure.html: Added.
+        * crypto/subtle/aes-cbc-unwrap-rsa-expected.txt: Added.
+        * crypto/subtle/aes-cbc-unwrap-rsa.html: Added.
+
 2013-11-21  Radu Stavila  <[email protected]>
 
         Added test for the overflow of a region being painted across multiple tiles.

Added: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure-expected.txt (0 => 159637)


--- trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure-expected.txt	2013-11-21 19:05:43 UTC (rev 159637)
@@ -0,0 +1,13 @@
+Test unwrapping an RSA key with AES-CBC.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing an unwrapping key...
+PASS unwrappingKey.algorithm.name is 'aes-cbc'
+Unwrapping a key...
+PASS Promise rejected
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure-expected.txt
___________________________________________________________________

Added: svn:mime-type

Added: svn:eol-style

Added: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure.html (0 => 159637)


--- trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure.html	                        (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure.html	2013-11-21 19:05:43 UTC (rev 159637)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+description("Test unwrapping an RSA key with AES-CBC.");
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var nonExtractable = false;
+
+var unwrappingKeyOctets = hexStringToUint8Array("2a00e0e776e94e4dc89bf947cebdebe1");
+var wrappedKey = hexStringToUint8Array("b490dedb3abc3fd545e146538e6cc3ca"); // An empty encrypted JSON.
+
+debug("Importing an unwrapping key...");
+crypto.subtle.importKey("raw", unwrappingKeyOctets, "AES-CBC", nonExtractable, ["unwrapKey"]).then(function(result) {
+    unwrappingKey = result;
+    shouldBe("unwrappingKey.algorithm.name", "'aes-cbc'");
+    var unwrapAlgorithm = {name: "AES-CBC", iv: hexStringToUint8Array("000102030405060708090a0b0c0d0e0f")};
+    debug("Unwrapping a key...");
+    return crypto.subtle.unwrapKey("jwk", wrappedKey, unwrappingKey, unwrapAlgorithm, null, extractable, ["sign", "verify", "encrypt", "decrypt", "wrap", "unwrap"]);
+}).then(undefined, function(result) {
+    testPassed("Promise rejected");
+    finishJSTest();
+});
+
+</script>
+
+<script src=""
+</body>
+</html>
Property changes on: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-failure.html
___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa-expected.txt (0 => 159637)


--- trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa-expected.txt	2013-11-21 19:05:43 UTC (rev 159637)
@@ -0,0 +1,20 @@
+Test unwrapping an RSA key with AES-CBC.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing an unwrapping key...
+PASS unwrappingKey.algorithm.name is 'aes-cbc'
+Unwrapping a key...
+PASS unwrappedKey.toString() is '[object Key]'
+PASS unwrappedKey.type is 'public'
+PASS unwrappedKey.usages is ['sign','verify']
+PASS unwrappedKey.algorithm.name is 'rsassa-pkcs1-v1_5'
+PASS unwrappedKey.algorithm.modulusLength is 2048
+PASS Base64URL.stringify(unwrappedKey.algorithm.publicExponent) is publicKeyJSON.e
+PASS unwrappedKey.algorithm.hash.name is 'sha-256'
+PASS unwrappedKey.extractable is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa-expected.txt
___________________________________________________________________

Added: svn:mime-type

Added: svn:eol-style

Added: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa.html (0 => 159637)


--- trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa.html	                        (rev 0)
+++ trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa.html	2013-11-21 19:05:43 UTC (rev 159637)
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+description("Test unwrapping an RSA key with AES-CBC.");
+
+jsTestIsAsync = true;
+
+var extractable = true;
+var nonExtractable = false;
+
+var publicKeyJSON = {
+    kty: "RSA",
+    alg: "RS256",
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB",
+    extractable: false,
+    use: "sig"
+};
+
+var unwrappingKeyOctets = hexStringToUint8Array("2a00e0e776e94e4dc89bf947cebdebe1");
+var wrappedKey = hexStringToUint8Array("3511f6028db04ea97e7cfad3c4cc60837bceff25cb6c88292fbcb4547570afdc32e4003fe4d65f1e7df60dc1fdb3df36c3f58ab228e33aa31005852d46d0c2ad1318435a071bbb5bbb05650ea63d551698b0c040dd95ed0d379b5e2eccb545ae5620acb8051174cd2ad647328ad99dcd462fec40748724eb1e68f209f779faa2c35b4d4d1b6604a74e62a1846249ea6192954a5af10c71ebfea79948142441ed307e9f52e797a51a8007a6f87b57c51f9e7eef54b7e4a1f818ba6ac25ee5935c23b3253d6d9d222262c79ccdb7147d9c07527c22fe7a4ab91af20479edf5930b3c053c0a0b27092cfb53203633d01dcf6e333b5be7c1933c321c953f962b934ebefd9df8cca6c0a25fcd5fb96105435c42d9902406f82bc8daa8ec12fa85d9afa65adbfe3f60828ef64adaf43ad8e3b0af104cbfafd994323732bba08f84d5cac1d157b276233dffecafe47942b83c85ead6d5886c6badf534d4a32d3f545e8032dd5e419d7bff3acde2c37a96fc34fda8747d89500bf9f7ef45873c6b3b274197c184fe91badeeddf5045f982ecc66b61e0c4d75fd496c61ffcbb36e079faf20aa0c05cd12742aefdf1f6a39c4a9c5a");
+
+debug("Importing an unwrapping key...");
+crypto.subtle.importKey("raw", unwrappingKeyOctets, "AES-CBC", nonExtractable, ["unwrapKey"]).then(function(result) {
+    unwrappingKey = result;
+    shouldBe("unwrappingKey.algorithm.name", "'aes-cbc'");
+    var unwrapAlgorithm = {name: "AES-CBC", iv: hexStringToUint8Array("000102030405060708090a0b0c0d0e0f")};
+    debug("Unwrapping a key...");
+    return crypto.subtle.unwrapKey("jwk", wrappedKey, unwrappingKey, unwrapAlgorithm, null, extractable, ["sign", "verify", "encrypt", "decrypt", "wrap", "unwrap"]);
+}).then(function(result) {
+    unwrappedKey = result;
+
+    shouldBe("unwrappedKey.toString()", "'[object Key]'");
+    shouldBe("unwrappedKey.type", "'public'");
+    shouldBe("unwrappedKey.usages", "['sign','verify']");
+    shouldBe("unwrappedKey.algorithm.name", "'rsassa-pkcs1-v1_5'");
+    shouldBe("unwrappedKey.algorithm.modulusLength", "2048");
+    shouldBe("Base64URL.stringify(unwrappedKey.algorithm.publicExponent)", "publicKeyJSON.e");
+    shouldBe("unwrappedKey.algorithm.hash.name", "'sha-256'");
+    shouldBe("unwrappedKey.extractable", "false");
+    finishJSTest();
+});
+
+</script>
+
+<script src=""
+</body>
+</html>
Property changes on: trunk/LayoutTests/crypto/subtle/aes-cbc-unwrap-rsa.html
___________________________________________________________________

Added: svn:mime-type

Modified: trunk/Source/WebCore/ChangeLog (159636 => 159637)


--- trunk/Source/WebCore/ChangeLog	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/ChangeLog	2013-11-21 19:05:43 UTC (rev 159637)
@@ -1,3 +1,52 @@
+2013-11-21  Alexey Proskuryakov  <[email protected]>
+
+        Implement WebCrypto unwrapKey
+        https://bugs.webkit.org/show_bug.cgi?id=124725
+
+        Reviewed by Anders Carlsson.
+
+        Tests: crypto/subtle/aes-cbc-unwrap-failure.html
+               crypto/subtle/aes-cbc-unwrap-rsa.html
+
+        * bindings/js/JSCryptoAlgorithmDictionary.cpp:
+        * bindings/js/JSCryptoAlgorithmDictionary.h:
+        Removed calls for wrap/unwrap parameter parsing, these are just the same as encrypt/decrypt.
+
+        * bindings/js/JSCryptoOperationData.cpp:
+        (WebCore::cryptoOperationDataFromJSValue):
+        * bindings/js/JSCryptoOperationData.h:
+        * crypto/CryptoKeySerialization.h:
+        More Vector<char> elimination.
+
+        * bindings/js/JSDOMPromise.cpp:
+        * bindings/js/JSDOMPromise.h:
+        Removed unneccessary copy constructor and assignment operator, they are no diffdrent
+        than compiler generated ones.
+
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::cryptoKeyUsagesFromJSValue): Minor style fixes.
+        (WebCore::JSSubtleCrypto::encrypt): Ditto.
+        (WebCore::JSSubtleCrypto::decrypt): Ditto.
+        (WebCore::JSSubtleCrypto::sign): Ditto.
+        (WebCore::JSSubtleCrypto::verify): Ditto.
+        (WebCore::JSSubtleCrypto::generateKey): Ditto.
+        (WebCore::importKey): Separated actual import operation and the parts that read
+        arguments from ExecState, and call the promise. Logically, this should be outside
+        of bindings code even, but JWK makes that quite challenging.
+        (WebCore::JSSubtleCrypto::importKey): This only does the more mundane arguments
+        and return parts now.
+        (WebCore::JSSubtleCrypto::exportKey): Minor style fixes.
+        (WebCore::JSSubtleCrypto::unwrapKey): Chain decrypt and import.
+
+        * crypto/CryptoAlgorithm.cpp:
+        (WebCore::CryptoAlgorithm::encryptForWrapKey):
+        (WebCore::CryptoAlgorithm::decryptForUnwrapKey):
+        * crypto/CryptoAlgorithm.h:
+        There are algorithms that expose wrap/unwrap, but not encrypt/decrypt. These will
+        override these new functions, and leave encrypt/decrypt to raise NOT_SUPPORTED_ERR.
+
+        * crypto/SubtleCrypto.idl: Added unwrapKey.
+
 2013-11-21  Robert Sipka  <[email protected]>
 
         [curl]Improve ssl certificate storage and check

Modified: trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp	2013-11-21 19:05:43 UTC (rev 159637)
@@ -584,64 +584,6 @@
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForWrapKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
-{
-    switch (algorithm) {
-    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
-    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
-    case CryptoAlgorithmIdentifier::RSA_PSS:
-    case CryptoAlgorithmIdentifier::RSA_OAEP:
-    case CryptoAlgorithmIdentifier::ECDSA:
-    case CryptoAlgorithmIdentifier::ECDH:
-    case CryptoAlgorithmIdentifier::AES_CTR:
-    case CryptoAlgorithmIdentifier::AES_CBC:
-    case CryptoAlgorithmIdentifier::AES_CMAC:
-    case CryptoAlgorithmIdentifier::AES_GCM:
-    case CryptoAlgorithmIdentifier::AES_CFB:
-    case CryptoAlgorithmIdentifier::HMAC:
-    case CryptoAlgorithmIdentifier::DH:
-    case CryptoAlgorithmIdentifier::SHA_1:
-    case CryptoAlgorithmIdentifier::SHA_224:
-    case CryptoAlgorithmIdentifier::SHA_256:
-    case CryptoAlgorithmIdentifier::SHA_384:
-    case CryptoAlgorithmIdentifier::SHA_512:
-    case CryptoAlgorithmIdentifier::CONCAT:
-    case CryptoAlgorithmIdentifier::HKDF_CTR:
-    case CryptoAlgorithmIdentifier::PBKDF2:
-        setDOMException(exec, NOT_SUPPORTED_ERR);
-        return nullptr;
-    }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForUnwrapKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
-{
-    switch (algorithm) {
-    case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
-    case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
-    case CryptoAlgorithmIdentifier::RSA_PSS:
-    case CryptoAlgorithmIdentifier::RSA_OAEP:
-    case CryptoAlgorithmIdentifier::ECDSA:
-    case CryptoAlgorithmIdentifier::ECDH:
-    case CryptoAlgorithmIdentifier::AES_CTR:
-    case CryptoAlgorithmIdentifier::AES_CBC:
-    case CryptoAlgorithmIdentifier::AES_CMAC:
-    case CryptoAlgorithmIdentifier::AES_GCM:
-    case CryptoAlgorithmIdentifier::AES_CFB:
-    case CryptoAlgorithmIdentifier::HMAC:
-    case CryptoAlgorithmIdentifier::DH:
-    case CryptoAlgorithmIdentifier::SHA_1:
-    case CryptoAlgorithmIdentifier::SHA_224:
-    case CryptoAlgorithmIdentifier::SHA_256:
-    case CryptoAlgorithmIdentifier::SHA_384:
-    case CryptoAlgorithmIdentifier::SHA_512:
-    case CryptoAlgorithmIdentifier::CONCAT:
-    case CryptoAlgorithmIdentifier::HKDF_CTR:
-    case CryptoAlgorithmIdentifier::PBKDF2:
-        setDOMException(exec, NOT_SUPPORTED_ERR);
-        return nullptr;
-    }
-}
-
-}
-
 #endif // ENABLE(SUBTLE_CRYPTO)

Modified: trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.h (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.h	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.h	2013-11-21 19:05:43 UTC (rev 159637)
@@ -53,8 +53,6 @@
     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 std::unique_ptr<CryptoAlgorithmParameters> createParametersForWrapKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
-    static std::unique_ptr<CryptoAlgorithmParameters> createParametersForUnwrapKey(JSC::ExecState*, CryptoAlgorithmIdentifier, JSC::JSValue);
 };
 
 }

Modified: trunk/Source/WebCore/bindings/js/JSCryptoOperationData.cpp (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSCryptoOperationData.cpp	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSCryptoOperationData.cpp	2013-11-21 19:05:43 UTC (rev 159637)
@@ -37,9 +37,9 @@
 bool cryptoOperationDataFromJSValue(ExecState* exec, JSValue value, CryptoOperationData& result)
 {
     if (ArrayBuffer* buffer = toArrayBuffer(value))
-        result = std::make_pair(static_cast<char*>(buffer->data()), buffer->byteLength());
+        result = std::make_pair(static_cast<uint8_t*>(buffer->data()), buffer->byteLength());
     else if (RefPtr<ArrayBufferView> bufferView = toArrayBufferView(value))
-        result = std::make_pair(static_cast<char*>(bufferView->baseAddress()), bufferView->byteLength());
+        result = std::make_pair(static_cast<uint8_t*>(bufferView->baseAddress()), bufferView->byteLength());
     else {
         throwTypeError(exec, "Only ArrayBuffer and ArrayBufferView objects can be passed as CryptoOperationData");
         return false;

Modified: trunk/Source/WebCore/bindings/js/JSCryptoOperationData.h (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSCryptoOperationData.h	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSCryptoOperationData.h	2013-11-21 19:05:43 UTC (rev 159637)
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-typedef std::pair<const char*, size_t> CryptoOperationData;
+typedef std::pair<const uint8_t*, size_t> CryptoOperationData;
 
 bool cryptoOperationDataFromJSValue(JSC::ExecState*, JSC::JSValue, CryptoOperationData&);
 

Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp	2013-11-21 19:05:43 UTC (rev 159637)
@@ -34,17 +34,4 @@
 {
 }
 
-PromiseWrapper::PromiseWrapper(const PromiseWrapper& other)
-    : m_globalObject(other.m_globalObject)
-    , m_promise(other.m_promise)
-{
 }
-
-PromiseWrapper& PromiseWrapper::operator=(const PromiseWrapper& other)
-{
-    m_globalObject = other.m_globalObject;
-    m_promise = other.m_promise;
-    return *this;
-}
-
-}

Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.h (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSDOMPromise.h	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.h	2013-11-21 19:05:43 UTC (rev 159637)
@@ -40,9 +40,6 @@
 public:
     PromiseWrapper(JSDOMGlobalObject*, JSC::JSPromise*);
 
-    PromiseWrapper(const PromiseWrapper&);
-    PromiseWrapper& operator=(const PromiseWrapper&);
-
     template<class FulfillResultType>
     void fulfill(const FulfillResultType&);
 

Modified: trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp (159636 => 159637)


--- trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp	2013-11-21 19:05:43 UTC (rev 159637)
@@ -102,9 +102,9 @@
 
     result = 0;
 
-    JSC::JSArray* array = asArray(value);
+    JSArray* array = asArray(value);
     for (size_t i = 0; i < array->length(); ++i) {
-        JSC::JSValue element = array->getIndex(exec, i);
+        JSValue element = array->getIndex(exec, i);
         String usageString = element.toString(exec)->value(exec);
         if (exec->hadException())
             return false;
@@ -150,7 +150,7 @@
         return throwTypeError(exec);
 
     if (!key->allows(CryptoKeyUsageEncrypt)) {
-        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'encrypt'");
+        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages do not include 'encrypt'");
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return jsUndefined();
     }
@@ -202,7 +202,7 @@
         return throwTypeError(exec);
 
     if (!key->allows(CryptoKeyUsageDecrypt)) {
-        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'decrypt'");
+        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages do not include 'decrypt'");
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return jsUndefined();
     }
@@ -254,7 +254,7 @@
         return throwTypeError(exec);
 
     if (!key->allows(CryptoKeyUsageSign)) {
-        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'sign'");
+        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages do not include 'sign'");
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return jsUndefined();
     }
@@ -306,7 +306,7 @@
         return throwTypeError(exec);
 
     if (!key->allows(CryptoKeyUsageVerify)) {
-        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages does not include 'verify'");
+        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages do not include 'verify'");
         setDOMException(exec, NOT_SUPPORTED_ERR);
         return jsUndefined();
     }
@@ -384,7 +384,7 @@
     return promise;
 }
 
-JSValue JSSubtleCrypto::generateKey(JSC::ExecState* exec)
+JSValue JSSubtleCrypto::generateKey(ExecState* exec)
 {
     if (exec->argumentCount() < 1)
         return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
@@ -440,38 +440,11 @@
     return promise;
 }
 
-JSValue JSSubtleCrypto::importKey(JSC::ExecState* exec)
+static void importKey(ExecState* exec, CryptoKeyFormat keyFormat, CryptoOperationData data, CryptoAlgorithm* algorithmPtr, CryptoAlgorithmParameters* parametersPtr, bool extractable, CryptoKeyUsage keyUsages, CryptoAlgorithm::KeyCallback callback, CryptoAlgorithm::VoidCallback failureCallback)
 {
-    if (exec->argumentCount() < 3)
-        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
+    std::unique_ptr<CryptoAlgorithm> algorithm(algorithmPtr);
+    std::unique_ptr<CryptoAlgorithmParameters> parameters(parametersPtr);
 
-    CryptoKeyFormat keyFormat;
-    if (!cryptoKeyFormatFromJSValue(exec, exec->argument(0), keyFormat)) {
-        ASSERT(exec->hadException());
-        return jsUndefined();
-    }
-
-    CryptoOperationData data;
-    if (!cryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(1), data)) {
-        ASSERT(exec->hadException());
-        return jsUndefined();
-    }
-
-    std::unique_ptr<CryptoAlgorithm> algorithm;
-    std::unique_ptr<CryptoAlgorithmParameters> parameters;
-    if (!exec->uncheckedArgument(2).isNull()) {
-        algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(2));
-        if (!algorithm) {
-            ASSERT(exec->hadException());
-            return jsUndefined();
-        }
-        parameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(exec, algorithm->identifier(), exec->uncheckedArgument(2));
-        if (!parameters) {
-            ASSERT(exec->hadException());
-            return jsUndefined();
-        }
-    }
-
     std::unique_ptr<CryptoKeySerialization> keySerialization;
     switch (keyFormat) {
     case CryptoKeyFormat::Raw:
@@ -481,16 +454,16 @@
         String jwkString = String::fromUTF8(data.first, data.second);
         if (jwkString.isNull()) {
             throwTypeError(exec, "JWK JSON serialization is not valid UTF-8");
-            return jsUndefined();
+            return;
         }
         keySerialization = JSCryptoKeySerializationJWK::create(exec, jwkString);
         if (exec->hadException())
-            return jsUndefined();
+            return;
         break;
     }
     default:
         throwTypeError(exec, "Unsupported key format for import");
-        return jsUndefined();
+        return;
     }
 
     ASSERT(keySerialization);
@@ -498,26 +471,73 @@
     if (!keySerialization->reconcileAlgorithm(algorithm, parameters)) {
         if (!exec->hadException())
             throwTypeError(exec, "Algorithm specified in key is not compatible with one passed to importKey as argument");
-        return jsUndefined();
+        return;
     }
     if (exec->hadException())
-        return jsUndefined();
+        return;
 
     if (!algorithm) {
         throwTypeError(exec, "Neither key nor function argument has crypto algorithm specified");
-        return jsUndefined();
+        return;
     }
     ASSERT(parameters);
 
+    keySerialization->reconcileExtractable(extractable);
+    if (exec->hadException())
+        return;
+
+    keySerialization->reconcileUsages(keyUsages);
+    if (exec->hadException())
+        return;
+
+    auto keyData = keySerialization->keyData();
+    if (exec->hadException())
+        return;
+
+    ExceptionCode ec = 0;
+    algorithm->importKey(*parameters, *keyData, extractable, keyUsages, std::move(callback), std::move(failureCallback), ec);
+    if (ec)
+        setDOMException(exec, ec);
+}
+
+JSValue JSSubtleCrypto::importKey(ExecState* exec)
+{
+    if (exec->argumentCount() < 3)
+        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
+
+    CryptoKeyFormat keyFormat;
+    if (!cryptoKeyFormatFromJSValue(exec, exec->argument(0), keyFormat)) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+
+    CryptoOperationData data;
+    if (!cryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(1), data)) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+
+    std::unique_ptr<CryptoAlgorithm> algorithm;
+    std::unique_ptr<CryptoAlgorithmParameters> parameters;
+    if (!exec->uncheckedArgument(2).isNull()) {
+        algorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(2));
+        if (!algorithm) {
+            ASSERT(exec->hadException());
+            return jsUndefined();
+        }
+        parameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(exec, algorithm->identifier(), exec->uncheckedArgument(2));
+        if (!parameters) {
+            ASSERT(exec->hadException());
+            return jsUndefined();
+        }
+    }
+
     bool extractable = false;
     if (exec->argumentCount() >= 4) {
         extractable = exec->uncheckedArgument(3).toBoolean(exec);
         if (exec->hadException())
             return jsUndefined();
     }
-    keySerialization->reconcileExtractable(extractable);
-    if (exec->hadException())
-        return jsUndefined();
 
     CryptoKeyUsage keyUsages = 0;
     if (exec->argumentCount() >= 5) {
@@ -526,14 +546,7 @@
             return jsUndefined();
         }
     }
-    keySerialization->reconcileUsages(keyUsages);
-    if (exec->hadException())
-        return jsUndefined();
 
-    auto keyData = keySerialization->keyData();
-    if (exec->hadException())
-        return jsUndefined();
-
     JSPromise* promise = JSPromise::createWithResolver(exec->vm(), globalObject());
     PromiseWrapper promiseWrapper(globalObject(), promise);
     auto successCallback = [promiseWrapper](CryptoKey& result) mutable {
@@ -543,17 +556,14 @@
         promiseWrapper.reject(nullptr);
     };
 
-    ExceptionCode ec = 0;
-    algorithm->importKey(*parameters, *keyData, extractable, keyUsages, std::move(successCallback), std::move(failureCallback), ec);
-    if (ec) {
-        setDOMException(exec, ec);
+    WebCore::importKey(exec, keyFormat, data, algorithm.release(), parameters.release(), extractable, keyUsages, successCallback, failureCallback);
+    if (exec->hadException())
         return jsUndefined();
-    }
 
     return promise;
 }
 
-JSValue JSSubtleCrypto::exportKey(JSC::ExecState* exec)
+JSValue JSSubtleCrypto::exportKey(ExecState* exec)
 {
     if (exec->argumentCount() < 2)
         return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
@@ -579,7 +589,7 @@
 
     switch (keyFormat) {
     case CryptoKeyFormat::Raw: {
-        Vector<unsigned char> result;
+        Vector<uint8_t> result;
         if (CryptoKeySerializationRaw::serialize(*key, result))
             promiseWrapper.fulfill(result);
         else {
@@ -593,7 +603,7 @@
         if (exec->hadException())
             return jsUndefined();
         CString utf8String = result.utf8(StrictConversion);
-        Vector<unsigned char> resultBuffer;
+        Vector<uint8_t> resultBuffer;
         resultBuffer.append(utf8String.data(), utf8String.length());
         promiseWrapper.fulfill(resultBuffer);
         break;
@@ -606,6 +616,110 @@
     return promise;
 }
 
+JSValue JSSubtleCrypto::unwrapKey(ExecState* exec)
+{
+    if (exec->argumentCount() < 5)
+        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
+
+    CryptoKeyFormat keyFormat;
+    if (!cryptoKeyFormatFromJSValue(exec, exec->argument(0), keyFormat)) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+
+    CryptoOperationData wrappedKeyData;
+    if (!cryptoOperationDataFromJSValue(exec, exec->uncheckedArgument(1), wrappedKeyData)) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+
+    RefPtr<CryptoKey> unwrappingKey = toCryptoKey(exec->uncheckedArgument(2));
+    if (!unwrappingKey)
+        return throwTypeError(exec);
+
+    if (!unwrappingKey->allows(CryptoKeyUsageUnwrapKey)) {
+        m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key usages do not include 'unwrapKey'");
+        setDOMException(exec, NOT_SUPPORTED_ERR);
+        return jsUndefined();
+    }
+
+    std::unique_ptr<CryptoAlgorithm> unwrapAlgorithm;
+    std::unique_ptr<CryptoAlgorithmParameters> unwrapAlgorithmParameters;
+    unwrapAlgorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(3));
+    if (!unwrapAlgorithm) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+    unwrapAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForDecrypt(exec, unwrapAlgorithm->identifier(), exec->uncheckedArgument(3));
+    if (!unwrapAlgorithmParameters) {
+        ASSERT(exec->hadException());
+        return jsUndefined();
+    }
+
+    std::unique_ptr<CryptoAlgorithm> unwrappedKeyAlgorithm;
+    std::unique_ptr<CryptoAlgorithmParameters> unwrappedKeyAlgorithmParameters;
+    if (!exec->uncheckedArgument(4).isNull()) {
+        unwrappedKeyAlgorithm = createAlgorithmFromJSValue(exec, exec->uncheckedArgument(4));
+        if (!unwrappedKeyAlgorithm) {
+            ASSERT(exec->hadException());
+            return jsUndefined();
+        }
+        unwrappedKeyAlgorithmParameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(exec, unwrappedKeyAlgorithm->identifier(), exec->uncheckedArgument(4));
+        if (!unwrappedKeyAlgorithmParameters) {
+            ASSERT(exec->hadException());
+            return jsUndefined();
+        }
+    }
+
+    bool extractable = false;
+    if (exec->argumentCount() >= 6) {
+        extractable = exec->uncheckedArgument(5).toBoolean(exec);
+        if (exec->hadException())
+            return jsUndefined();
+    }
+
+    CryptoKeyUsage keyUsages = 0;
+    if (exec->argumentCount() >= 7) {
+        if (!cryptoKeyUsagesFromJSValue(exec, exec->argument(6), keyUsages)) {
+            ASSERT(exec->hadException());
+            return jsUndefined();
+        }
+    }
+
+    JSPromise* promise = JSPromise::createWithResolver(exec->vm(), globalObject());
+    PromiseWrapper promiseWrapper(globalObject(), promise);
+    Strong<JSDOMGlobalObject> domGlobalObject(exec->vm(), globalObject());
+
+    CryptoAlgorithm* unwrappedKeyAlgorithmPtr = unwrappedKeyAlgorithm.release();
+    CryptoAlgorithmParameters* unwrappedKeyAlgorithmParametersPtr = unwrappedKeyAlgorithmParameters.release();
+
+    auto failureCallback = [promiseWrapper]() mutable {
+        promiseWrapper.reject(nullptr);
+    };
+
+    auto successCallback = [domGlobalObject, keyFormat, unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr, extractable, keyUsages, promiseWrapper, failureCallback](const Vector<uint8_t>& result) mutable {
+        auto importSuccessCallback = [promiseWrapper](CryptoKey& key) mutable {
+            promiseWrapper.fulfill(&key);
+        };
+        ExecState* exec = domGlobalObject->globalExec();
+        WebCore::importKey(exec, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr, extractable, keyUsages, importSuccessCallback, failureCallback);
+        if (exec->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.
+            exec->clearException();
+            failureCallback();
+        }
+    };
+
+    ExceptionCode ec = 0;
+    unwrapAlgorithm->decryptForUnwrapKey(*unwrapAlgorithmParameters, *unwrappingKey, wrappedKeyData, std::move(successCallback), std::move(failureCallback), ec);
+    if (ec) {
+        setDOMException(exec, ec);
+        return jsUndefined();
+    }
+
+    return promise;
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp (159636 => 159637)


--- trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp	2013-11-21 19:05:43 UTC (rev 159637)
@@ -85,6 +85,16 @@
     ec = NOT_SUPPORTED_ERR;
 }
 
+void CryptoAlgorithm::encryptForWrapKey(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode& ec)
+{
+    encrypt(parameters, key, data, callback, failureCallback, ec);
 }
 
+void CryptoAlgorithm::decryptForUnwrapKey(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode& ec)
+{
+    decrypt(parameters, key, data, callback, failureCallback, ec);
+}
+
+}
+
 #endif

Modified: trunk/Source/WebCore/crypto/CryptoAlgorithm.h (159636 => 159637)


--- trunk/Source/WebCore/crypto/CryptoAlgorithm.h	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/crypto/CryptoAlgorithm.h	2013-11-21 19:05:43 UTC (rev 159637)
@@ -44,7 +44,7 @@
 class CryptoKeyData;
 
 // Data is mutable, so async operations should copy it first.
-typedef std::pair<const char*, size_t> CryptoOperationData;
+typedef std::pair<const uint8_t*, size_t> CryptoOperationData;
 
 class CryptoAlgorithm {
     WTF_MAKE_NONCOPYABLE(CryptoAlgorithm)
@@ -69,6 +69,10 @@
     virtual void deriveBits(const CryptoAlgorithmParameters&, const CryptoKey& baseKey, unsigned long length, VectorCallback, VoidCallback failureCallback, ExceptionCode&);
     virtual void importKey(const CryptoAlgorithmParameters&, const CryptoKeyData&, bool extractable, CryptoKeyUsage, KeyCallback, VoidCallback failureCallback, ExceptionCode&);
 
+    // These are only different from encrypt/decrypt because some algorithms may not expose encrypt/decrypt.
+    virtual void encryptForWrapKey(const CryptoAlgorithmParameters&, const CryptoKey&, const CryptoOperationData&, VectorCallback, VoidCallback failureCallback, ExceptionCode&);
+    virtual void decryptForUnwrapKey(const CryptoAlgorithmParameters&, const CryptoKey&, const CryptoOperationData&, VectorCallback, VoidCallback failureCallback, ExceptionCode&);
+
 protected:
     CryptoAlgorithm();
 };

Modified: trunk/Source/WebCore/crypto/CryptoKeySerialization.h (159636 => 159637)


--- trunk/Source/WebCore/crypto/CryptoKeySerialization.h	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/crypto/CryptoKeySerialization.h	2013-11-21 19:05:43 UTC (rev 159637)
@@ -37,7 +37,7 @@
 class CryptoAlgorithmParameters;
 class CryptoKeyData;
 
-typedef std::pair<const char*, size_t> CryptoOperationData;
+typedef std::pair<const uint8_t*, size_t> CryptoOperationData;
 
 class CryptoKeySerialization {
     WTF_MAKE_NONCOPYABLE(CryptoKeySerialization);

Modified: trunk/Source/WebCore/crypto/SubtleCrypto.idl (159636 => 159637)


--- trunk/Source/WebCore/crypto/SubtleCrypto.idl	2013-11-21 19:02:08 UTC (rev 159636)
+++ trunk/Source/WebCore/crypto/SubtleCrypto.idl	2013-11-21 19:05:43 UTC (rev 159637)
@@ -37,4 +37,5 @@
     [Custom] Promise generateKey(AlgorithmIdentifier algorithm, optional boolean extractable, optional KeyUsage[] keyUsages);
     [Custom] Promise importKey(KeyFormat format, CryptoOperationData keyData, AlgorithmIdentifier? algorithm, optional boolean extractable, optional KeyUsage[] keyUsages);
     [Custom] Promise exportKey(KeyFormat format, Key key);
+    [Custom] Promise unwrapKey(KeyFormat format, CryptoOperationData wrappedKey, Key unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier? unwrappedKeyAlgorithm, optional boolean extractable, optional KeyUsage[] keyUsages);
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to