Commit 24ef25bb authored by ap@apple.com's avatar ap@apple.com

Support WebCrypto AES-KW

https://bugs.webkit.org/show_bug.cgi?id=125105

Reviewed by Sam Weinig.

Source/WebCore: 

Tests: crypto/subtle/aes-kw-key-manipulation.html
       crypto/subtle/aes-kw-wrap-unwrap-aes.html

* WebCore.xcodeproj/project.pbxproj: Added new files.

* crypto/CryptoAlgorithmIdentifier.h: (WebCore::CryptoAlgorithmIdentifier): Added AES-KW.
It's not standardized yet, but there appears to be a consensus that it will be specified.

* bindings/js/JSCryptoAlgorithmDictionary.cpp:
(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):
Added AES-KW cases everywhere.

* bindings/js/JSCryptoKeySerializationJWK.cpp:
(WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm):
(WebCore::JSCryptoKeySerializationJWK::keySizeIsValid):
(WebCore::JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON):
Support importing/exporting AES-KW keys in JWK.

* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::JSSubtleCrypto::importKey):
(WebCore::JSSubtleCrypto::exportKey):
(WebCore::JSSubtleCrypto::wrapKey):
(WebCore::JSSubtleCrypto::unwrapKey):
Added some accidentally forgotten std::moves.

* crypto/algorithms/CryptoAlgorithmAES_KW.cpp: Added.
* crypto/algorithms/CryptoAlgorithmAES_KW.h: Added.
* crypto/mac/CryptoAlgorithmAES_KWMac.cpp: Added.

* crypto/keys/CryptoKeyAES.cpp: (WebCore::CryptoKeyAES::CryptoKeyAES): Allow AES-KW
as valid algorithm for AES keys.

* crypto/mac/CryptoAlgorithmRegistryMac.cpp:
(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms): Register AES-KW.

LayoutTests: 

* crypto/subtle/aes-kw-key-manipulation-expected.txt: Added.
* crypto/subtle/aes-kw-key-manipulation.html: Added.
* crypto/subtle/aes-kw-wrap-unwrap-aes-expected.txt: Added.
* crypto/subtle/aes-kw-wrap-unwrap-aes.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159966 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8dbbe83a
2013-12-02 Alexey Proskuryakov <ap@apple.com>
Support WebCrypto AES-KW
https://bugs.webkit.org/show_bug.cgi?id=125105
Reviewed by Sam Weinig.
* crypto/subtle/aes-kw-key-manipulation-expected.txt: Added.
* crypto/subtle/aes-kw-key-manipulation.html: Added.
* crypto/subtle/aes-kw-wrap-unwrap-aes-expected.txt: Added.
* crypto/subtle/aes-kw-wrap-unwrap-aes.html: Added.
2013-12-02 Rob Buis <rob.buis@samsung.com>
[css shapes] Parse new ellipse shape syntax
......
Test generating, importing and exporting keys for AES-KW. Test that they can't be used with another algorithm.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Generating a key...
PASS key.toString() is '[object Key]'
PASS key.type is 'secret'
PASS key.algorithm.name is 'aes-kw'
PASS key.algorithm.length is 256
Testing that the key can't be used with AES-CBC...
PASS crypto.subtle.encrypt({name: "aes-cbc", iv: iv}, key, hexStringToUint8Array("00")) threw exception Error: NotSupportedError: DOM Exception 9.
Exporting the key to raw...
PASS exportedKey.toString() is '[object ArrayBuffer]'
Importing it back...
PASS importedKey.toString() is '[object Key]'
PASS importedKey.type is 'secret'
PASS importedKey.algorithm.name is 'aes-kw'
PASS importedKey.algorithm.length is 256
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<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("Test generating, importing and exporting keys for AES-KW. Test that they can't be used with another algorithm.");
jsTestIsAsync = true;
var extractable = true;
debug("Generating a key...");
crypto.subtle.generateKey({name: "aes-kw", length: 256}, extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]).then(function(result) {
key = result;
shouldBe("key.toString()", "'[object Key]'");
shouldBe("key.type", "'secret'");
shouldBe("key.algorithm.name", "'aes-kw'");
shouldBe("key.algorithm.length", "256");
debug("\nTesting that the key can't be used with AES-CBC...");
iv = hexStringToUint8Array("000102030405060708090a0b0c0d0e0f");
shouldThrow('crypto.subtle.encrypt({name: "aes-cbc", iv: iv}, key, hexStringToUint8Array("00"))');
debug("\nExporting the key to raw...");
return crypto.subtle.exportKey('raw', key);
}).then(function(result) {
exportedKey = result;
shouldBe("exportedKey.toString()", "'[object ArrayBuffer]'");
debug("Importing it back...");
return crypto.subtle.importKey('raw', exportedKey, "aes-kw", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);
}).then(function(result) {
importedKey = result;
shouldBe("importedKey.toString()", "'[object Key]'");
shouldBe("importedKey.type", "'secret'");
shouldBe("importedKey.algorithm.name", "'aes-kw'");
shouldBe("importedKey.algorithm.length", "256");
finishJSTest();
});
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
Test wrapping and unwrapping keys with AES-KW.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Importing key encryption key...
Importing a key to be wrapped...
Wrapping it...
PASS bytesToHexString(wrappedKey) is '1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5'
Unwrapping it...
PASS unwrappedKey.toString() is '[object Key]'
PASS unwrappedKey.type is 'secret'
PASS unwrappedKey.extractable is true
PASS unwrappedKey.algorithm.name is 'aes-cbc'
PASS unwrappedKey.algorithm.length is 128
PASS unwrappedKey.usages is ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']
Exporting it...
PASS bytesToHexString(unwrappedKeyData) is bytesToHexString(keyData)
Wrapping it as JWK...
Unwrapping it...
PASS unwrappedKey.toString() is '[object Key]'
PASS unwrappedKey.type is 'secret'
PASS unwrappedKey.extractable is true
PASS unwrappedKey.algorithm.name is 'aes-cbc'
PASS unwrappedKey.algorithm.length is 128
PASS unwrappedKey.usages is ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']
Exporting it...
PASS bytesToHexString(unwrappedKeyData) is bytesToHexString(keyData)
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<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("Test wrapping and unwrapping keys with AES-KW.");
jsTestIsAsync = true;
var kekData = hexStringToUint8Array("000102030405060708090A0B0C0D0E0F");
var keyData = hexStringToUint8Array("00112233445566778899AABBCCDDEEFF");
var extractable = true;
debug("Importing key encryption key...");
crypto.subtle.importKey("raw", kekData, "aes-kw", extractable, ["wrapKey", "unwrapKey"]).then(function(result) {
kek = result;
debug("Importing a key to be wrapped...");
return crypto.subtle.importKey("raw", keyData, "aes-cbc", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);
}).then(function(result) {
key = result;
debug("Wrapping it...");
return crypto.subtle.wrapKey("raw", key, kek, "aes-kw");
}).then(function(result) {
wrappedKey = result;
shouldBe("bytesToHexString(wrappedKey)", "'1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5'"); // Result from RFC 3394.
debug("Unwrapping it...");
return crypto.subtle.unwrapKey("raw", wrappedKey, kek, "aes-kw", "aes-cbc", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);
}).then(function(result) {
unwrappedKey = result;
shouldBe("unwrappedKey.toString()", "'[object Key]'");
shouldBe("unwrappedKey.type", "'secret'");
shouldBe("unwrappedKey.extractable", "true");
shouldBe("unwrappedKey.algorithm.name", "'aes-cbc'");
shouldBe("unwrappedKey.algorithm.length", "128");
shouldBe("unwrappedKey.usages", "['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']");
debug("Exporting it...");
return crypto.subtle.exportKey("raw", unwrappedKey);
}).then(function(result) {
unwrappedKeyData = result;
shouldBe("bytesToHexString(unwrappedKeyData)", "bytesToHexString(keyData)");
debug("\nWrapping it as JWK...");
return crypto.subtle.wrapKey("jwk", key, kek, "aes-kw");
}).then(function(result) {
wrappedKey = result;
debug("Unwrapping it...");
return crypto.subtle.unwrapKey("jwk", wrappedKey, kek, "aes-kw", "aes-cbc", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);
}).then(function(result) {
unwrappedKey = result;
shouldBe("unwrappedKey.toString()", "'[object Key]'");
shouldBe("unwrappedKey.type", "'secret'");
shouldBe("unwrappedKey.extractable", "true");
shouldBe("unwrappedKey.algorithm.name", "'aes-cbc'");
shouldBe("unwrappedKey.algorithm.length", "128");
shouldBe("unwrappedKey.usages", "['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']");
debug("Exporting it...");
return crypto.subtle.exportKey("raw", unwrappedKey);
}).then(function(result) {
unwrappedKeyData = result;
shouldBe("bytesToHexString(unwrappedKeyData)", "bytesToHexString(keyData)");
finishJSTest();
});
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
2013-12-02 Alexey Proskuryakov <ap@apple.com>
Support WebCrypto AES-KW
https://bugs.webkit.org/show_bug.cgi?id=125105
Reviewed by Sam Weinig.
Tests: crypto/subtle/aes-kw-key-manipulation.html
crypto/subtle/aes-kw-wrap-unwrap-aes.html
* WebCore.xcodeproj/project.pbxproj: Added new files.
* crypto/CryptoAlgorithmIdentifier.h: (WebCore::CryptoAlgorithmIdentifier): Added AES-KW.
It's not standardized yet, but there appears to be a consensus that it will be specified.
* bindings/js/JSCryptoAlgorithmDictionary.cpp:
(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):
Added AES-KW cases everywhere.
* bindings/js/JSCryptoKeySerializationJWK.cpp:
(WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm):
(WebCore::JSCryptoKeySerializationJWK::keySizeIsValid):
(WebCore::JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON):
Support importing/exporting AES-KW keys in JWK.
* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::JSSubtleCrypto::importKey):
(WebCore::JSSubtleCrypto::exportKey):
(WebCore::JSSubtleCrypto::wrapKey):
(WebCore::JSSubtleCrypto::unwrapKey):
Added some accidentally forgotten std::moves.
* crypto/algorithms/CryptoAlgorithmAES_KW.cpp: Added.
* crypto/algorithms/CryptoAlgorithmAES_KW.h: Added.
* crypto/mac/CryptoAlgorithmAES_KWMac.cpp: Added.
* crypto/keys/CryptoKeyAES.cpp: (WebCore::CryptoKeyAES::CryptoKeyAES): Allow AES-KW
as valid algorithm for AES keys.
* crypto/mac/CryptoAlgorithmRegistryMac.cpp:
(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms): Register AES-KW.
2013-12-02 Beth Dakin <bdakin@apple.com>
Add a setting to opt into a mode where the background extends and fixed elements
......@@ -5734,6 +5734,9 @@
E1FE137418402A6700892F13 /* CommonCryptoUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FE137218402A6700892F13 /* CommonCryptoUtilities.cpp */; };
E1FE137518402A6700892F13 /* CommonCryptoUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FE137318402A6700892F13 /* CommonCryptoUtilities.h */; };
E1FE1377184D1E3300892F13 /* CryptoAlgorithmRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FE1376184D1E3300892F13 /* CryptoAlgorithmRsaOaepParams.h */; };
E1FE137A184D21BB00892F13 /* CryptoAlgorithmAES_KW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FE1378184D21BB00892F13 /* CryptoAlgorithmAES_KW.cpp */; };
E1FE137B184D21BB00892F13 /* CryptoAlgorithmAES_KW.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FE1379184D21BB00892F13 /* CryptoAlgorithmAES_KW.h */; };
E1FE137E184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FE137C184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp */; };
E1FF57A30F01255B00891EBB /* ThreadGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FF57A20F01255B00891EBB /* ThreadGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1FF57A60F01256B00891EBB /* ThreadGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF57A50F01256B00891EBB /* ThreadGlobalData.cpp */; };
E1FF8F5F1807442100132674 /* SubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F5D1807442100132674 /* SubtleCrypto.cpp */; };
......@@ -12860,6 +12863,9 @@
E1FE137218402A6700892F13 /* CommonCryptoUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommonCryptoUtilities.cpp; sourceTree = "<group>"; };
E1FE137318402A6700892F13 /* CommonCryptoUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonCryptoUtilities.h; sourceTree = "<group>"; };
E1FE1376184D1E3300892F13 /* CryptoAlgorithmRsaOaepParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoAlgorithmRsaOaepParams.h; path = parameters/CryptoAlgorithmRsaOaepParams.h; sourceTree = "<group>"; };
E1FE1378184D21BB00892F13 /* CryptoAlgorithmAES_KW.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmAES_KW.cpp; sourceTree = "<group>"; };
E1FE1379184D21BB00892F13 /* CryptoAlgorithmAES_KW.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmAES_KW.h; sourceTree = "<group>"; };
E1FE137C184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoAlgorithmAES_KWMac.cpp; path = mac/CryptoAlgorithmAES_KWMac.cpp; sourceTree = "<group>"; };
E1FF57A20F01255B00891EBB /* ThreadGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadGlobalData.h; sourceTree = "<group>"; };
E1FF57A50F01256B00891EBB /* ThreadGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadGlobalData.cpp; sourceTree = "<group>"; };
E1FF8F5C1807364B00132674 /* SubtleCrypto.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = SubtleCrypto.idl; sourceTree = "<group>"; };
......@@ -20421,6 +20427,7 @@
E1FE137218402A6700892F13 /* CommonCryptoUtilities.cpp */,
E1FE137318402A6700892F13 /* CommonCryptoUtilities.h */,
E125F843182425C900D84CD9 /* CryptoAlgorithmAES_CBCMac.cpp */,
E1FE137C184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp */,
E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */,
E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */,
E1C266D618317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp */,
......@@ -20437,6 +20444,8 @@
children = (
E125F83F1824253A00D84CD9 /* CryptoAlgorithmAES_CBC.cpp */,
E125F8401824253A00D84CD9 /* CryptoAlgorithmAES_CBC.h */,
E1FE1378184D21BB00892F13 /* CryptoAlgorithmAES_KW.cpp */,
E1FE1379184D21BB00892F13 /* CryptoAlgorithmAES_KW.h */,
E125F82F1822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp */,
E125F8301822F11B00D84CD9 /* CryptoAlgorithmHMAC.h */,
E1FE1368183FE1AB00892F13 /* CryptoAlgorithmRSA_OAEP.cpp */,
......@@ -24326,6 +24335,7 @@
BCC52FD6151298D2003F914B /* RenderMultiColumnBlock.h in Headers */,
1A3586E015264C450022A659 /* RenderMultiColumnFlowThread.h in Headers */,
BCE32B9C1517C0B200F542EC /* RenderMultiColumnSet.h in Headers */,
E1FE137B184D21BB00892F13 /* CryptoAlgorithmAES_KW.h in Headers */,
BC85F23D151915E000BC17BE /* RenderNamedFlowThread.h in Headers */,
BCEA4880097D93020094C9E4 /* RenderObject.h in Headers */,
BCFA930810333193007B25D1 /* RenderOverflow.h in Headers */,
......@@ -25636,6 +25646,7 @@
37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */,
512DD8FA0D91E6AF000F89EE /* ArchiveFactory.cpp in Sources */,
512DD8FB0D91E6AF000F89EE /* ArchiveResource.cpp in Sources */,
E1FE137A184D21BB00892F13 /* CryptoAlgorithmAES_KW.cpp in Sources */,
512DD8F70D91E6AF000F89EE /* ArchiveResourceCollection.cpp in Sources */,
49B3760C15C6C6840059131D /* ArrayValue.cpp in Sources */,
FD5686C913AC180200B69C68 /* AsyncAudioDecoder.cpp in Sources */,
......@@ -28294,6 +28305,7 @@
7E99AF510B13846468FB01A5 /* WindowFocusAllowedIndicator.cpp in Sources */,
379919961200DDF400EA041C /* WOFFFileFormat.cpp in Sources */,
2E4346450F546A8200B0F1BA /* Worker.cpp in Sources */,
E1FE137E184D270200892F13 /* CryptoAlgorithmAES_KWMac.cpp in Sources */,
51059DDD1820B17600DFF9B1 /* IDBTransactionBackendOperations.cpp in Sources */,
F3820896147D35F90010BC06 /* WorkerConsoleAgent.cpp in Sources */,
F34742E01343631F00531BC2 /* WorkerDebuggerAgent.cpp in Sources */,
......@@ -329,6 +329,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::PBKDF2:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
case CryptoAlgorithmIdentifier::AES_KW:
return std::make_unique<CryptoAlgorithmParameters>();
}
}
......@@ -364,6 +366,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::PBKDF2:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
case CryptoAlgorithmIdentifier::AES_KW:
return std::make_unique<CryptoAlgorithmParameters>();
}
}
......@@ -397,6 +401,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::CONCAT:
case CryptoAlgorithmIdentifier::HKDF_CTR:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::AES_KW:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
}
......@@ -432,6 +437,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::CONCAT:
case CryptoAlgorithmIdentifier::HKDF_CTR:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::AES_KW:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
}
......@@ -464,6 +470,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::CONCAT:
case CryptoAlgorithmIdentifier::HKDF_CTR:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::AES_KW:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
}
......@@ -500,6 +507,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::PBKDF2:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
case CryptoAlgorithmIdentifier::AES_KW:
return createAesKeyGenParams(exec, value);
}
}
......@@ -527,6 +536,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::CONCAT:
case CryptoAlgorithmIdentifier::HKDF_CTR:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::AES_KW:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
}
......@@ -556,6 +566,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::CONCAT:
case CryptoAlgorithmIdentifier::HKDF_CTR:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::AES_KW:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
}
......@@ -594,6 +605,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::PBKDF2:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
case CryptoAlgorithmIdentifier::AES_KW:
return std::make_unique<CryptoAlgorithmParameters>();
}
}
......@@ -624,6 +637,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
case CryptoAlgorithmIdentifier::PBKDF2:
setDOMException(exec, NOT_SUPPORTED_ERR);
return nullptr;
case CryptoAlgorithmIdentifier::AES_KW:
return std::make_unique<CryptoAlgorithmParameters>();
}
}
......
......@@ -202,6 +202,15 @@ bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgor
} else if (m_jwkAlgorithmName == "A256CBC") {
algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::AES_CBC);
parameters = std::make_unique<CryptoAlgorithmParameters>();
} else if (m_jwkAlgorithmName == "A128KW") {
algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::AES_KW);
parameters = std::make_unique<CryptoAlgorithmParameters>();
} else if (m_jwkAlgorithmName == "A192KW") {
algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::AES_KW);
parameters = std::make_unique<CryptoAlgorithmParameters>();
} else if (m_jwkAlgorithmName == "A256KW") {
algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::AES_KW);
parameters = std::make_unique<CryptoAlgorithmParameters>();
} else {
throwTypeError(m_exec, "Unsupported JWK algorithm " + m_jwkAlgorithmName);
return false;
......@@ -281,6 +290,12 @@ bool JSCryptoKeySerializationJWK::keySizeIsValid(size_t sizeInBits) const
return sizeInBits == 192;
if (m_jwkAlgorithmName == "A256CBC")
return sizeInBits == 256;
if (m_jwkAlgorithmName == "A128KW")
return sizeInBits == 128;
if (m_jwkAlgorithmName == "A192KW")
return sizeInBits == 192;
if (m_jwkAlgorithmName == "A256KW")
return sizeInBits == 256;
if (m_jwkAlgorithmName == "RS256")
return sizeInBits >= 2048;
if (m_jwkAlgorithmName == "RS384")
......@@ -522,6 +537,19 @@ void JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON(ExecState* exec, JSObjec
break;
}
break;
case CryptoAlgorithmIdentifier::AES_KW:
switch (toCryptoKeyAES(key).key().size() * 8) {
case 128:
jwkAlgorithm = "A128KW";
break;
case 192:
jwkAlgorithm = "A192KW";
break;
case 256:
jwkAlgorithm = "A256KW";
break;
}
break;
case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: {
const CryptoKeyRSA& rsaKey = toCryptoKeyRSA(key);
CryptoAlgorithmIdentifier hash;
......
......@@ -556,7 +556,7 @@ JSValue JSSubtleCrypto::importKey(ExecState* exec)
promiseWrapper.reject(nullptr);
};
WebCore::importKey(exec, keyFormat, data, algorithm.release(), parameters.release(), extractable, keyUsages, successCallback, failureCallback);
WebCore::importKey(exec, keyFormat, data, algorithm.release(), parameters.release(), extractable, keyUsages, std::move(successCallback), std::move(failureCallback));
if (exec->hadException())
return jsUndefined();
......@@ -620,7 +620,7 @@ JSValue JSSubtleCrypto::exportKey(ExecState* exec)
promiseWrapper.reject(nullptr);
};
WebCore::exportKey(exec, keyFormat, *key, successCallback, failureCallback);
WebCore::exportKey(exec, keyFormat, *key, std::move(successCallback), std::move(failureCallback));
if (exec->hadException())
return jsUndefined();
......@@ -687,7 +687,7 @@ JSValue JSSubtleCrypto::wrapKey(ExecState* exec)
};
ExceptionCode ec = 0;
WebCore::exportKey(exec, keyFormat, *key, exportSuccessCallback, exportFailureCallback);
WebCore::exportKey(exec, keyFormat, *key, std::move(exportSuccessCallback), std::move(exportFailureCallback));
if (ec) {
setDOMException(exec, ec);
return jsUndefined();
......@@ -781,7 +781,7 @@ JSValue JSSubtleCrypto::unwrapKey(ExecState* exec)
promiseWrapper.reject(nullptr);
};
ExecState* exec = domGlobalObject->globalExec();
WebCore::importKey(exec, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr, extractable, keyUsages, importSuccessCallback, importFailureCallback);
WebCore::importKey(exec, keyFormat, std::make_pair(result.data(), result.size()), unwrappedKeyAlgorithmPtr, unwrappedKeyAlgorithmParametersPtr, extractable, keyUsages, std::move(importSuccessCallback), std::move(importFailureCallback));
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();
......
......@@ -51,7 +51,8 @@ ENUM_CLASS(CryptoAlgorithmIdentifier) {
SHA_512,
CONCAT,
HKDF_CTR,
PBKDF2
PBKDF2,
AES_KW // Not yet standardized.
};
}
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "CryptoAlgorithmAES_KW.h"
#if ENABLE(SUBTLE_CRYPTO)
#include "CryptoAlgorithmAesKeyGenParams.h"
#include "CryptoKeyAES.h"
#include "CryptoKeyDataOctetSequence.h"
#include "ExceptionCode.h"
namespace WebCore {
const char* const CryptoAlgorithmAES_KW::s_name = "aes-kw";
CryptoAlgorithmAES_KW::CryptoAlgorithmAES_KW()
{
}
CryptoAlgorithmAES_KW::~CryptoAlgorithmAES_KW()
{
}
std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmAES_KW::create()
{
return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmAES_KW);
}
CryptoAlgorithmIdentifier CryptoAlgorithmAES_KW::identifier() const
{
return s_identifier;
}
bool CryptoAlgorithmAES_KW::keyAlgorithmMatches(const CryptoAlgorithmParameters&, const CryptoKey& key) const
{
if (key.algorithmIdentifier() != s_identifier)
return false;
ASSERT(isCryptoKeyAES(key));
return true;
}
void CryptoAlgorithmAES_KW::encryptForWrapKey(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode& ec)
{
if (!keyAlgorithmMatches(parameters, key)) {
ec = NOT_SUPPORTED_ERR;
return;
}
platformEncrypt(toCryptoKeyAES(key), data, std::move(callback), std::move(failureCallback), ec);
}
void CryptoAlgorithmAES_KW::decryptForUnwrapKey(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode& ec)
{
if (!keyAlgorithmMatches(parameters, key)) {
ec = NOT_SUPPORTED_ERR;
return;
}
platformDecrypt(toCryptoKeyAES(key), data, std::move(callback), std::move(failureCallback), ec);
}
void CryptoAlgorithmAES_KW::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsage usages, KeyOrKeyPairCallback callback, VoidCallback failureCallback, ExceptionCode&)
{
const CryptoAlgorithmAesKeyGenParams& aesParameters = toCryptoAlgorithmAesKeyGenParams(parameters);
RefPtr<CryptoKeyAES> result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_KW, aesParameters.length, extractable, usages);
if (!result) {
failureCallback();
return;
}
callback(result.get(), nullptr);
}
void CryptoAlgorithmAES_KW::importKey(const CryptoAlgorithmParameters&, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, KeyCallback callback, VoidCallback, ExceptionCode& ec)
{
if (keyData.format() != CryptoKeyData::Format::OctetSequence) {
ec = NOT_SUPPORTED_ERR;
return;
}
const CryptoKeyDataOctetSequence& keyDataOctetSequence = toCryptoKeyDataOctetSequence(keyData);
RefPtr<CryptoKeyAES> result = CryptoKeyAES::create(CryptoAlgorithmIdentifier::AES_KW, keyDataOctetSequence.octetSequence(), extractable, usage);
callback(*result);
}
}
#endif // ENABLE(SUBTLE_CRYPTO)
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.