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);
};