Implement key generation and JWK import for RSASSA-PKCS1-v1_5
authorap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Nov 2013 09:31:51 +0000 (09:31 +0000)
committerap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Nov 2013 09:31:51 +0000 (09:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124236

Reviewed by Sam Weinig.

Source/WebCore:

Tests: crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html
       crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html

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

* bindings/js/JSCryptoAlgorithmBuilder.cpp:
(WebCore::JSCryptoAlgorithmBuilder::add):
* bindings/js/JSCryptoAlgorithmBuilder.h:
* crypto/CryptoAlgorithmDescriptionBuilder.h:
Added a way to add an Uint8Array, as needed for RSA key.algorithm.publicExponent.

* bindings/js/JSCryptoAlgorithmDictionary.cpp:
(WebCore::createAesCbcParams): Removed unneeded JSC prefixes.
(WebCore::createAesKeyGenParams): Ditto.
(WebCore::createHmacParams): Ditto.
(WebCore::createHmacKeyParams): Ditto.
(WebCore::createRsaKeyGenParams): Added.
(WebCore::createRsaSsaKeyParams): Added. WebCrypto currently doesn't specify any
parameters for importKey, so the structure remains blank (unlike with JWK).
(WebCore::createRsaSsaParams): Added (currently unused, will be sued for sign/verify soon).
(WebCore::JSCryptoAlgorithmDictionary::createParametersForEncrypt): Removed unneeded JSC prefixes.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDecrypt): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForSign): Added support for RSAES_PKCS1_v1_5.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForVerify): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDigest): Removed unneeded JSC prefixes.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForGenerateKey): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveKey): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveBits): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey): Added support for RSAES_PKCS1_v1_5.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForExportKey): Removed unneeded JSC prefixes.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForWrapKey): Ditto.
(WebCore::JSCryptoAlgorithmDictionary::createParametersForUnwrapKey): Ditto.

* bindings/js/JSCryptoKeySerializationJWK.h:
* bindings/js/JSCryptoKeySerializationJWK.cpp:
(WebCore::getJSArrayFromJSON): Added.
(WebCore::getBigIntegerVectorFromJSON): Added.
(WebCore::createRSASSAKeyParameters): Create parameters for key import. The key
will remember which algorithm it's allowed to be used with.
(WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm): Added support for
RS256...RS512 (tha is, RSAES_PKCS1_v1_5 with SHA-256...SHA-512).
(WebCore::JSCryptoKeySerializationJWK::keyDataOctetSequence): Split out of keyData().
(WebCore::JSCryptoKeySerializationJWK::keyDataRSAComponents): Added code to read
RSA key components from JWK.
(WebCore::JSCryptoKeySerializationJWK::keyData): Call one of the above functions.

* crypto/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp: Added.
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::sign):
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::verify):
Placeholders.

* crypto/CryptoKey.h: (WebCore::CryptoKeyClass): Added RSA key class for poor man's RTTI.

* crypto/CryptoKeyData.h: (WebCore::CryptoKeyData::FormatRSAComponents): Added RSAComponents
for poor man's RTTI.

* crypto/algorithms/CryptoAlgorithmAES_CBC.cpp: (WebCore::CryptoAlgorithmAES_CBC::importKey):
* crypto/algorithms/CryptoAlgorithmHMAC.cpp: (WebCore::CryptoAlgorithmHMAC::importKey):
* crypto/keys/CryptoKeyAES.h:
(WebCore::isCryptoKeyAES):
(WebCore::toCryptoKeyAES):
* crypto/keys/CryptoKeyDataOctetSequence.h:
(WebCore::toCryptoKeyDataOctetSequence):
* crypto/keys/CryptoKeyHMAC.h:
(WebCore::isCryptoKeyHMAC):
(WebCore::toCryptoKeyHMAC):
* crypto/mac/CryptoAlgorithmAES_CBCMac.cpp:
(WebCore::CryptoAlgorithmAES_CBC::encrypt):
(WebCore::CryptoAlgorithmAES_CBC::decrypt):
* crypto/mac/CryptoAlgorithmHMACMac.cpp:
(WebCore::CryptoAlgorithmHMAC::sign):
(WebCore::CryptoAlgorithmHMAC::verify):
Switched from "as" functions to "is" and "to" ones, as that's more idiomatic.

* crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp: Added.
* crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h: Added.
Glue code for importKey/generateKey for now.

* crypto/keys/CryptoKeyDataRSAComponents.cpp: Added.
(WebCore::CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents):
(WebCore::CryptoKeyDataRSAComponents::~CryptoKeyDataRSAComponents):
* crypto/keys/CryptoKeyDataRSAComponents.h: Added.
(WebCore::toCryptoKeyDataRSAComponents):
Added a structure to hold RSA key components, extracted from JWK or another format.

* crypto/keys/CryptoKeyRSA.h: Added.
* crypto/mac/CryptoKeyRSAMac.cpp: Added.

* crypto/mac/CryptoAlgorithmRegistryMac.cpp:
(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):
Register RSASSA_PKCS1_v1_5.

* crypto/parameters/CryptoAlgorithmHmacKeyParams.h: Added a constructor to make
sure that hasLength is never left uninitialized, even when reading formats that
don't contain a length.

* crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h: Added.
* crypto/parameters/CryptoAlgorithmRsaSsaKeyParams.h: Added.
* crypto/parameters/CryptoAlgorithmRsaSsaParams.h: Added.
Added parameter structures that are needed for RSASSA_PKCS1_v1_5.

LayoutTests:

* crypto/subtle/resources/common.js:
(hexToArrayBuffer): Fixed a typo
(Base64URL.stringify):
(Base64URL.parse):
Added helpers to deal with Base64URL, as needed for JWK.

* crypto/subtle/rsassa-pkcs1-v1_5-generate-key-expected.txt: Added.
* crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html: Added.
* crypto/subtle/rsassa-pkcs1-v1_5-import-jwk-expected.txt: Added.
* crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html: Added.

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

35 files changed:
LayoutTests/ChangeLog
LayoutTests/crypto/subtle/resources/common.js
LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSCryptoAlgorithmBuilder.cpp
Source/WebCore/bindings/js/JSCryptoAlgorithmBuilder.h
Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.h
Source/WebCore/crypto/CryptoAlgorithmDescriptionBuilder.h
Source/WebCore/crypto/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp [new file with mode: 0644]
Source/WebCore/crypto/CryptoKey.h
Source/WebCore/crypto/CryptoKeyData.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_CBC.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmHMAC.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp [new file with mode: 0644]
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h [new file with mode: 0644]
Source/WebCore/crypto/keys/CryptoKeyAES.h
Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h
Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp [new file with mode: 0644]
Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h [new file with mode: 0644]
Source/WebCore/crypto/keys/CryptoKeyHMAC.h
Source/WebCore/crypto/keys/CryptoKeyRSA.h [new file with mode: 0644]
Source/WebCore/crypto/mac/CryptoAlgorithmAES_CBCMac.cpp
Source/WebCore/crypto/mac/CryptoAlgorithmHMACMac.cpp
Source/WebCore/crypto/mac/CryptoAlgorithmRegistryMac.cpp
Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp [new file with mode: 0644]
Source/WebCore/crypto/parameters/CryptoAlgorithmHmacKeyParams.h
Source/WebCore/crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h [new file with mode: 0644]
Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaKeyParams.h [new file with mode: 0644]
Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaParams.h [new file with mode: 0644]

index 7f96acc..c99196d 100644 (file)
@@ -1,3 +1,21 @@
+2013-11-13  Alexey Proskuryakov  <ap@apple.com>
+
+        Implement key generation and JWK import for RSASSA-PKCS1-v1_5
+        https://bugs.webkit.org/show_bug.cgi?id=124236
+
+        Reviewed by Sam Weinig.
+
+        * crypto/subtle/resources/common.js:
+        (hexToArrayBuffer): Fixed a typo
+        (Base64URL.stringify):
+        (Base64URL.parse):
+        Added helpers to deal with Base64URL, as needed for JWK.
+
+        * crypto/subtle/rsassa-pkcs1-v1_5-generate-key-expected.txt: Added.
+        * crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html: Added.
+        * crypto/subtle/rsassa-pkcs1-v1_5-import-jwk-expected.txt: Added.
+        * crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html: Added.
+
 2013-11-12  Alexey Proskuryakov  <ap@apple.com>
 
         Disable WebCrypto on Mountain Lion
index 384a502..8a40f42 100644 (file)
@@ -48,13 +48,24 @@ function asciiToArrayBuffer(str)
 function hexToArrayBuffer(str)
 {
     if (str.length % 2)
-        throw "Hex string lenght must be even";
+        throw "Hex string length must be even";
     var chars = [];
     for (var i = 0; i < str.length; i += 2)
         chars.push(parseInt(str.substr(i, 2), 16));
     return new Uint8Array(chars);
 }
 
+var Base64URL = {
+    stringify: function (a) {
+        var base64string = btoa(String.fromCharCode.apply(0, a));
+        return base64string.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
+    },
+    parse: function (s) {
+        s = s.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, '');
+        return new Uint8Array(Array.prototype.map.call(atob(s), function (c) { return c.charCodeAt(0) }));
+    }
+};
+
 function printRejectedResult(value)
 {
     debug("    rejected with value of " + value);
diff --git a/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key-expected.txt b/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key-expected.txt
new file mode 100644 (file)
index 0000000..fe03780
--- /dev/null
@@ -0,0 +1,24 @@
+Test generating an RSA key pair for RSASSA-PKCS1-v1_5.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+PASS keyPair.toString() is '[object KeyPair]'
+PASS keyPair.publicKey.type is 'public'
+PASS keyPair.publicKey.algorithm.name is 'rsassa-pkcs1-v1_5'
+PASS keyPair.publicKey.algorithm.modulusLength is 2048
+PASS byteArrayToHexString(keyPair.publicKey.algorithm.publicExponent) is '[01 00 01]'
+PASS keyPair.publicKey.algorithm.hash is undefined.
+PASS keyPair.privateKey.type is 'private'
+PASS keyPair.privateKey.algorithm.name is 'rsassa-pkcs1-v1_5'
+PASS keyPair.privateKey.algorithm.modulusLength is 2048
+PASS byteArrayToHexString(keyPair.privateKey.algorithm.publicExponent) is '[01 00 01]'
+PASS keyPair.privateKey.algorithm.hash is undefined.
+
+Testing that custom attributes on keys survive garbage collection...
+PASS keyPair.publicKey.foo is 'bar'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html b/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html
new file mode 100644 (file)
index 0000000..5ba6ccc
--- /dev/null
@@ -0,0 +1,57 @@
+<!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 an RSA key pair for RSASSA-PKCS1-v1_5.");
+
+jsTestIsAsync = true;
+
+if (!window.subtle)
+    window.crypto.subtle = window.crypto.webkitSubtle;
+
+var algorithmKeyGen = {
+    name: "RSASSA-PKCS1-v1_5",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+};
+var extractable = true;
+
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    shouldBe("keyPair.toString()", "'[object KeyPair]'");
+    shouldBe("keyPair.publicKey.type", "'public'");
+    shouldBe("keyPair.publicKey.algorithm.name", "'rsassa-pkcs1-v1_5'");
+    shouldBe("keyPair.publicKey.algorithm.modulusLength", "2048");
+    shouldBe("byteArrayToHexString(keyPair.publicKey.algorithm.publicExponent)", "'[01 00 01]'");
+    shouldBeUndefined("keyPair.publicKey.algorithm.hash");
+    shouldBe("keyPair.privateKey.type", "'private'");
+    shouldBe("keyPair.privateKey.algorithm.name", "'rsassa-pkcs1-v1_5'");
+    shouldBe("keyPair.privateKey.algorithm.modulusLength", "2048");
+    shouldBe("byteArrayToHexString(keyPair.privateKey.algorithm.publicExponent)", "'[01 00 01]'");
+    shouldBeUndefined("keyPair.privateKey.algorithm.hash");
+
+    debug("\nTesting that custom attributes on keys survive garbage collection...");
+    keyPair.publicKey.foo = "bar";
+    gc();
+    setTimeout(function() {
+        gc();
+        setTimeout(function() {
+            shouldBe("keyPair.publicKey.foo", "'bar'");
+            finishJSTest();
+        }, 0);
+    }, 0);
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk-expected.txt b/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk-expected.txt
new file mode 100644 (file)
index 0000000..963a9ed
--- /dev/null
@@ -0,0 +1,26 @@
+Test importing an RSA key for RSASSA-PKCS1-v1_5.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a public key...
+PASS publicKey.toString() is '[object Key]'
+PASS publicKey.type is 'public'
+PASS publicKey.usages is ['sign','verify']
+PASS publicKey.algorithm.name is 'rsassa-pkcs1-v1_5'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS byteArrayToHexString(publicKey.algorithm.publicExponent) is '[01 00 01]'
+PASS publicKey.algorithm.hash.name is 'sha-256'
+
+Importing a private key...
+PASS privateKey.toString() is '[object Key]'
+PASS privateKey.type is 'private'
+PASS privateKey.usages is ['sign','verify']
+PASS privateKey.algorithm.name is 'rsassa-pkcs1-v1_5'
+PASS privateKey.algorithm.modulusLength is 2048
+PASS byteArrayToHexString(privateKey.algorithm.publicExponent) is '[01 00 01]'
+PASS privateKey.algorithm.hash.name is 'sha-256'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html b/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html
new file mode 100644 (file)
index 0000000..34f7306
--- /dev/null
@@ -0,0 +1,68 @@
+<!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 importing an RSA key for RSASSA-PKCS1-v1_5.");
+
+jsTestIsAsync = true;
+
+if (!window.subtle)
+    window.crypto.subtle = window.crypto.webkitSubtle;
+
+var extractable = true;
+
+var publicKeyJSON = {
+    kty: "RSA",
+    alg: "RS256",
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+
+var privateKeyJSON = {
+    kty: "RSA",
+    alg: "RS256",
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB",
+    d: "eNLS37aCz7RXSNPD_DtLBJ6j5T8cSxdzRBCjPaI6WcGqJp16lq3UTwuoDLAqlA9oGYm238dsIWpuucP_lQtbWe-7SpxoI6_vmYGf7YVUHv1-DF9qiOmSrMmdxMnVOzYXY8RaT6thPjn_J5cfLV2xI_LwsrMtmpdSyNlgX0zTUhwtuahgAKMEChYjH2EnjHdHw6sY2-wApdcQI7ULE0oo5RzbQZpmuhcN9hiBc0L3hhF0qo50mbl02_65_GQ7DpVkXBxNgRBLzlPabmzzG2oAhfefLgYmSC1opaCkXE6vRWQNWNL45RZNZFYM3uoJghOMqGeocM0BpjdChHrPOlFvSQ",
+    p: "4miTuAjKMeH5uJ5KB397QUwhbkYEgSbcA2mifmSkvE2018gb55qkBHK1eVryf1_m43LNlc6O_ak6gfzdZIZvS5NCGjPl0q09plUpu8qFOSspBwA67qGH76lFlZLn_d4yglS7wfLru4_5Ys8qLLs-DqVLviwposOnyyWqwM5AXp0",
+    q: "xHYrzkivtmnz_sGchnWGc0q-pDOkKicptRpv2pMFIIXxnFX5aMeEXIZjVujXtwUy1UlFIN2GZJSvy5KJ79mu_XyNnFHMzedH-A3ee3u8h1UUrZF-vUu1_e4U_x67NN1dedzUSKynN7pFl3OkuShMBWGV-cwzOPdcVAfVuZlxUMc",
+    dp: "fBzDzYDUBmBQGop7Hn0dvf_T27V6RqpctWo074CQZcFbP2atFVtKSj3viWT3xid2VHzcgiDHdfpM3nEVlEO1wwIonGCSvdjGEOZiiFVOjrZAOVxA8guOjyyFvqbXke06VwPIIVvfKeSU2zuhbP__1tt6F_fxow4Kb2xonGT0GGk",
+    dq: "jmE2DiIPdhwDgLXAQpIaBqQ81bO3XfVT_LRULAwwwwlPuQV148H04zlh9TJ6Y2GZHYokV1U0eOBpJxfkb7dLYtpJpuiBjRf4yIUEoGlkkI_QlJnFSFr-YjGRdfNHqWBkxlSMZL770R9mIATndGkH7z5x-r9KwBZFC4FCG2hg_zE",
+    qi: "YCX_pLwbMBA1ThVH0WcwmnytqNcrMCEwTm7ByA2eU6nWbQrULvf7m9_kzfLUcjsnpAVlBQG5JMXMy0Sq4ptwbywsa5-G8KAOOOR2L3v4hC-Eys9ftgFM_3i0o40eeQH4b3haPbntrIeMg8IzlOuVYKf9-2QuKDoWeRdd7NsdxTk"
+};
+
+debug("Importing a public key...");
+crypto.subtle.importKey("jwk", asciiToArrayBuffer(JSON.stringify(publicKeyJSON)), null, extractable, ["sign", "verify"]).then(function(result) {
+    publicKey = result;
+    shouldBe("publicKey.toString()", "'[object Key]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.usages", "['sign','verify']");
+    shouldBe("publicKey.algorithm.name", "'rsassa-pkcs1-v1_5'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("byteArrayToHexString(publicKey.algorithm.publicExponent)", "'[01 00 01]'");
+    shouldBe("publicKey.algorithm.hash.name", "'sha-256'");
+    debug("\nImporting a private key...");
+    return crypto.subtle.importKey("jwk", asciiToArrayBuffer(JSON.stringify(privateKeyJSON)), null, extractable, ["sign", "verify"]);
+}).then(function(result) {
+    privateKey = result;
+    shouldBe("privateKey.toString()", "'[object Key]'");
+    shouldBe("privateKey.type", "'private'");
+    shouldBe("privateKey.usages", "['sign','verify']");
+    shouldBe("privateKey.algorithm.name", "'rsassa-pkcs1-v1_5'");
+    shouldBe("privateKey.algorithm.modulusLength", "2048");
+    shouldBe("byteArrayToHexString(privateKey.algorithm.publicExponent)", "'[01 00 01]'");
+    shouldBe("privateKey.algorithm.hash.name", "'sha-256'");
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index d44f0df..39ddc23 100644 (file)
@@ -1,3 +1,111 @@
+2013-11-13  Alexey Proskuryakov  <ap@apple.com>
+
+        Implement key generation and JWK import for RSASSA-PKCS1-v1_5
+        https://bugs.webkit.org/show_bug.cgi?id=124236
+
+        Reviewed by Sam Weinig.
+
+        Tests: crypto/subtle/rsassa-pkcs1-v1_5-generate-key.html
+               crypto/subtle/rsassa-pkcs1-v1_5-import-jwk.html
+
+        * WebCore.xcodeproj/project.pbxproj: Added new files.
+
+        * bindings/js/JSCryptoAlgorithmBuilder.cpp:
+        (WebCore::JSCryptoAlgorithmBuilder::add):
+        * bindings/js/JSCryptoAlgorithmBuilder.h:
+        * crypto/CryptoAlgorithmDescriptionBuilder.h:
+        Added a way to add an Uint8Array, as needed for RSA key.algorithm.publicExponent.
+
+        * bindings/js/JSCryptoAlgorithmDictionary.cpp:
+        (WebCore::createAesCbcParams): Removed unneeded JSC prefixes.
+        (WebCore::createAesKeyGenParams): Ditto.
+        (WebCore::createHmacParams): Ditto.
+        (WebCore::createHmacKeyParams): Ditto.
+        (WebCore::createRsaKeyGenParams): Added. 
+        (WebCore::createRsaSsaKeyParams): Added. WebCrypto currently doesn't specify any
+        parameters for importKey, so the structure remains blank (unlike with JWK).
+        (WebCore::createRsaSsaParams): Added (currently unused, will be sued for sign/verify soon).
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForEncrypt): Removed unneeded JSC prefixes.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDecrypt): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForSign): Added support for RSAES_PKCS1_v1_5.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForVerify): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDigest): Removed unneeded JSC prefixes.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForGenerateKey): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveKey): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForDeriveBits): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey): Added support for RSAES_PKCS1_v1_5.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForExportKey): Removed unneeded JSC prefixes.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForWrapKey): Ditto.
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForUnwrapKey): Ditto.
+
+        * bindings/js/JSCryptoKeySerializationJWK.h:
+        * bindings/js/JSCryptoKeySerializationJWK.cpp:
+        (WebCore::getJSArrayFromJSON): Added.
+        (WebCore::getBigIntegerVectorFromJSON): Added.
+        (WebCore::createRSASSAKeyParameters): Create parameters for key import. The key
+        will remember which algorithm it's allowed to be used with.
+        (WebCore::JSCryptoKeySerializationJWK::reconcileAlgorithm): Added support for
+        RS256...RS512 (tha is, RSAES_PKCS1_v1_5 with SHA-256...SHA-512).
+        (WebCore::JSCryptoKeySerializationJWK::keyDataOctetSequence): Split out of keyData().
+        (WebCore::JSCryptoKeySerializationJWK::keyDataRSAComponents): Added code to read
+        RSA key components from JWK.
+        (WebCore::JSCryptoKeySerializationJWK::keyData): Call one of the above functions.
+
+        * crypto/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp: Added.
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::sign):
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::verify):
+        Placeholders.
+
+        * crypto/CryptoKey.h: (WebCore::CryptoKeyClass): Added RSA key class for poor man's RTTI.
+
+        * crypto/CryptoKeyData.h: (WebCore::CryptoKeyData::FormatRSAComponents): Added RSAComponents
+        for poor man's RTTI.
+
+        * crypto/algorithms/CryptoAlgorithmAES_CBC.cpp: (WebCore::CryptoAlgorithmAES_CBC::importKey): 
+        * crypto/algorithms/CryptoAlgorithmHMAC.cpp: (WebCore::CryptoAlgorithmHMAC::importKey):
+        * crypto/keys/CryptoKeyAES.h:
+        (WebCore::isCryptoKeyAES):
+        (WebCore::toCryptoKeyAES):
+        * crypto/keys/CryptoKeyDataOctetSequence.h:
+        (WebCore::toCryptoKeyDataOctetSequence):
+        * crypto/keys/CryptoKeyHMAC.h:
+        (WebCore::isCryptoKeyHMAC):
+        (WebCore::toCryptoKeyHMAC):
+        * crypto/mac/CryptoAlgorithmAES_CBCMac.cpp:
+        (WebCore::CryptoAlgorithmAES_CBC::encrypt):
+        (WebCore::CryptoAlgorithmAES_CBC::decrypt):
+        * crypto/mac/CryptoAlgorithmHMACMac.cpp:
+        (WebCore::CryptoAlgorithmHMAC::sign):
+        (WebCore::CryptoAlgorithmHMAC::verify):
+        Switched from "as" functions to "is" and "to" ones, as that's more idiomatic.
+
+        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp: Added.
+        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h: Added.
+        Glue code for importKey/generateKey for now.
+
+        * crypto/keys/CryptoKeyDataRSAComponents.cpp: Added.
+        (WebCore::CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents):
+        (WebCore::CryptoKeyDataRSAComponents::~CryptoKeyDataRSAComponents):
+        * crypto/keys/CryptoKeyDataRSAComponents.h: Added.
+        (WebCore::toCryptoKeyDataRSAComponents):
+        Added a structure to hold RSA key components, extracted from JWK or another format.
+
+        * crypto/keys/CryptoKeyRSA.h: Added.
+        * crypto/mac/CryptoKeyRSAMac.cpp: Added.
+
+        * crypto/mac/CryptoAlgorithmRegistryMac.cpp:
+        (WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):
+        Register RSASSA_PKCS1_v1_5.
+
+        * crypto/parameters/CryptoAlgorithmHmacKeyParams.h: Added a constructor to make
+        sure that hasLength is never left uninitialized, even when reading formats that
+        don't contain a length.
+
+        * crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h: Added.
+        * crypto/parameters/CryptoAlgorithmRsaSsaKeyParams.h: Added.
+        * crypto/parameters/CryptoAlgorithmRsaSsaParams.h: Added.
+        Added parameter structures that are needed for RSASSA_PKCS1_v1_5.
+
 2013-11-12  Alexey Proskuryakov  <ap@apple.com>
 
         Disable WebCrypto on Mountain Lion
index 6d50a56..66f1bf3 100644 (file)
                E157A8F118185425009F821D /* JSCryptoAlgorithmBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E157A8EF18185425009F821D /* JSCryptoAlgorithmBuilder.h */; };
                E15A36D71104572000B7B639 /* XMLNSNames.h in Headers */ = {isa = PBXBuildFile; fileRef = E15A36D61104572000B7B639 /* XMLNSNames.h */; };
                E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E15A36D81104572700B7B639 /* XMLNSNames.cpp */; };
+               E164FAA318315BF400DB4E61 /* CryptoKeyRSA.h in Headers */ = {isa = PBXBuildFile; fileRef = E164FAA218315BF400DB4E61 /* CryptoKeyRSA.h */; };
+               E164FAA518315E1A00DB4E61 /* CryptoKeyRSAMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */; };
                E169803D1133542D00894115 /* CRuntimeObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E169803C1133542D00894115 /* CRuntimeObject.h */; };
                E16980491133644700894115 /* CRuntimeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E16980481133644700894115 /* CRuntimeObject.cpp */; };
                E16982551134629D00894115 /* ObjCRuntimeObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E16982541134629D00894115 /* ObjCRuntimeObject.h */; };
                E1BA67181742BEE600C20251 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5C2869402846DCD018635CA /* Carbon.framework */; };
                E1BA671A1742BEF400C20251 /* WebCoreTestShimLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BA67191742BEF400C20251 /* WebCoreTestShimLibrary.cpp */; };
                E1BB84AD1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */; };
+               E1BD3319182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BD3317182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp */; };
+               E1BD331A182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BD3318182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.h */; };
+               E1BD331C182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BD331B182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParams.h */; };
+               E1BD331E182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BD331D182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParams.h */; };
                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */; };
                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */; };
+               E1C266D818317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C266D618317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp */; };
+               E1C266DB18319935003F8B33 /* CryptoAlgorithmRsaSsaKeyParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C266DA18319935003F8B33 /* CryptoAlgorithmRsaSsaKeyParams.h */; };
+               E1C266DE18319F31003F8B33 /* CryptoKeyDataRSAComponents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C266DC18319F31003F8B33 /* CryptoKeyDataRSAComponents.cpp */; };
+               E1C266DF18319F31003F8B33 /* CryptoKeyDataRSAComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C266DD18319F31003F8B33 /* CryptoKeyDataRSAComponents.h */; };
                E1C2F24A1533A2120083F974 /* SettingsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1C2F2481533A2120083F974 /* SettingsMac.mm */; };
                E1C362EF0EAF2AA9007410BC /* JSWorkerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C362ED0EAF2AA9007410BC /* JSWorkerLocation.h */; };
                E1C362F00EAF2AA9007410BC /* JSWorkerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C362EE0EAF2AA9007410BC /* JSWorkerLocation.cpp */; };
                E157A8EF18185425009F821D /* JSCryptoAlgorithmBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCryptoAlgorithmBuilder.h; sourceTree = "<group>"; };
                E15A36D61104572000B7B639 /* XMLNSNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLNSNames.h; sourceTree = "<group>"; };
                E15A36D81104572700B7B639 /* XMLNSNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLNSNames.cpp; sourceTree = "<group>"; };
+               E164FAA218315BF400DB4E61 /* CryptoKeyRSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoKeyRSA.h; path = keys/CryptoKeyRSA.h; sourceTree = "<group>"; };
+               E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoKeyRSAMac.cpp; path = mac/CryptoKeyRSAMac.cpp; sourceTree = "<group>"; };
                E169803C1133542D00894115 /* CRuntimeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRuntimeObject.h; sourceTree = "<group>"; };
                E16980481133644700894115 /* CRuntimeObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRuntimeObject.cpp; sourceTree = "<group>"; };
                E16982541134629D00894115 /* ObjCRuntimeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCRuntimeObject.h; sourceTree = "<group>"; };
                E1BA67161742BDE000C20251 /* libWebCoreTestShim.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWebCoreTestShim.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                E1BA67191742BEF400C20251 /* WebCoreTestShimLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreTestShimLibrary.cpp; sourceTree = "<group>"; };
                E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoAlgorithmRegistryMac.cpp; path = mac/CryptoAlgorithmRegistryMac.cpp; sourceTree = "<group>"; };
+               E1BD3317182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp; sourceTree = "<group>"; };
+               E1BD3318182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRSASSA_PKCS1_v1_5.h; sourceTree = "<group>"; };
+               E1BD331B182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoAlgorithmRsaSsaParams.h; path = parameters/CryptoAlgorithmRsaSsaParams.h; sourceTree = "<group>"; };
+               E1BD331D182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoAlgorithmRsaKeyGenParams.h; path = parameters/CryptoAlgorithmRsaKeyGenParams.h; sourceTree = "<group>"; };
                E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XSLTUnicodeSort.cpp; sourceTree = "<group>"; };
                E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XSLTUnicodeSort.h; sourceTree = "<group>"; };
+               E1C266D618317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp; sourceTree = "<group>"; };
+               E1C266DA18319935003F8B33 /* CryptoAlgorithmRsaSsaKeyParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoAlgorithmRsaSsaKeyParams.h; path = parameters/CryptoAlgorithmRsaSsaKeyParams.h; sourceTree = "<group>"; };
+               E1C266DC18319F31003F8B33 /* CryptoKeyDataRSAComponents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoKeyDataRSAComponents.cpp; path = keys/CryptoKeyDataRSAComponents.cpp; sourceTree = "<group>"; };
+               E1C266DD18319F31003F8B33 /* CryptoKeyDataRSAComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoKeyDataRSAComponents.h; path = keys/CryptoKeyDataRSAComponents.h; sourceTree = "<group>"; };
                E1C2F2481533A2120083F974 /* SettingsMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SettingsMac.mm; sourceTree = "<group>"; };
                E1C362ED0EAF2AA9007410BC /* JSWorkerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerLocation.h; sourceTree = "<group>"; };
                E1C362EE0EAF2AA9007410BC /* JSWorkerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerLocation.cpp; sourceTree = "<group>"; };
                                E125F8371822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp */,
                                E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */,
                                E125F82D1822CFFF00D84CD9 /* CryptoAlgorithmSHA1Mac.cpp */,
+                               E1C266D618317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp */,
                                E19AC3DE1824DC6900349426 /* CryptoAlgorithmSHA224Mac.cpp */,
                                E19AC3DF1824DC6900349426 /* CryptoAlgorithmSHA256Mac.cpp */,
                                E19AC3E01824DC6900349426 /* CryptoAlgorithmSHA384Mac.cpp */,
                                E19AC3E11824DC6900349426 /* CryptoAlgorithmSHA512Mac.cpp */,
                                E19AC3F8182566F700349426 /* CryptoKeyMac.cpp */,
+                               E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */,
                        );
                        name = mac;
                        sourceTree = "<group>";
                                E125F8401824253A00D84CD9 /* CryptoAlgorithmAES_CBC.h */,
                                E125F82F1822F11B00D84CD9 /* CryptoAlgorithmHMAC.cpp */,
                                E125F8301822F11B00D84CD9 /* CryptoAlgorithmHMAC.h */,
+                               E1BD3317182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp */,
+                               E1BD3318182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.h */,
                                E125F8291822CFEC00D84CD9 /* CryptoAlgorithmSHA1.cpp */,
                                E125F82A1822CFEC00D84CD9 /* CryptoAlgorithmSHA1.h */,
                                E19AC3E61824DC7900349426 /* CryptoAlgorithmSHA224.cpp */,
                                E125F84C1824289D00D84CD9 /* CryptoKeyAES.h */,
                                E125F861182C303A00D84CD9 /* CryptoKeyDataOctetSequence.cpp */,
                                E125F862182C303A00D84CD9 /* CryptoKeyDataOctetSequence.h */,
+                               E1C266DC18319F31003F8B33 /* CryptoKeyDataRSAComponents.cpp */,
+                               E1C266DD18319F31003F8B33 /* CryptoKeyDataRSAComponents.h */,
                                E125F8331822F18A00D84CD9 /* CryptoKeyHMAC.cpp */,
                                E125F8341822F18A00D84CD9 /* CryptoKeyHMAC.h */,
+                               E164FAA218315BF400DB4E61 /* CryptoKeyRSA.h */,
                                E125F857182C1AA600D84CD9 /* CryptoKeySerializationRaw.cpp */,
                                E125F858182C1AA600D84CD9 /* CryptoKeySerializationRaw.h */,
                        );
                                E19AC3F61824E5D100349426 /* CryptoAlgorithmAesKeyGenParams.h */,
                                E19DA29B18189ADD00088BC8 /* CryptoAlgorithmHmacKeyParams.h */,
                                E1C6571E1816E50300256CDD /* CryptoAlgorithmHmacParams.h */,
+                               E1BD331D182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParams.h */,
+                               E1C266DA18319935003F8B33 /* CryptoAlgorithmRsaSsaKeyParams.h */,
+                               E1BD331B182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParams.h */,
                        );
                        name = parameters;
                        sourceTree = "<group>";
                                FD31600212B0267600C1A359 /* ChannelSplitterNode.h in Headers */,
                                6550B6A0099DF0270090D781 /* CharacterData.h in Headers */,
                                97B8FFD116AE7F960038388D /* CharacterReferenceParserInlines.h in Headers */,
+                               E164FAA318315BF400DB4E61 /* CryptoKeyRSA.h in Headers */,
                                B2C3DA2A0D006C1D00EF6F26 /* CharsetData.h in Headers */,
                                F55B3DB21251F12D003EF269 /* CheckboxInputType.h in Headers */,
                                93F925430F7EF5B8007E37C9 /* CheckedRadioButtons.h in Headers */,
                                F55B3DB61251F12D003EF269 /* DateInputType.h in Headers */,
                                453EB637159C570400001BB7 /* DateTimeFormat.h in Headers */,
                                0705850317FA10D0005F2BCB /* JSAllVideoCapabilities.h in Headers */,
+                               E1BD331A182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.h in Headers */,
                                F55B3DB81251F12D003EF269 /* DateTimeInputType.h in Headers */,
                                F55B3DBA1251F12D003EF269 /* DateTimeLocalInputType.h in Headers */,
                                45FEA5D0156DDE8C00654101 /* Decimal.h in Headers */,
                                B275356B0B053814002CE64F /* FloatRect.h in Headers */,
                                B275356D0B053814002CE64F /* FloatSize.h in Headers */,
                                D72F6D7A153159A3001EE44E /* FlowThreadController.h in Headers */,
+                               E1BD331E182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParams.h in Headers */,
                                14993BE60B2F2B1C0050497F /* FocusController.h in Headers */,
                                062287840B4DB322000C34DF /* FocusDirection.h in Headers */,
                                B6D9D23514EABD260090D75E /* FocusEvent.h in Headers */,
                                A80E7B0C0A19D606007FB8C5 /* JSHTMLTitleElement.h in Headers */,
                                070756D414239A4F00414161 /* JSHTMLTrackElement.h in Headers */,
                                1A85B2110A1B258700D8C87C /* JSHTMLUListElement.h in Headers */,
+                               E1C266DF18319F31003F8B33 /* CryptoKeyDataRSAComponents.h in Headers */,
                                6E4ABCD5138EA0B70071D291 /* JSHTMLUnknownElement.h in Headers */,
                                078E092717D14D1C00420AA1 /* RTCSessionDescriptionCallback.h in Headers */,
                                E44614170CD6826900FADA75 /* JSHTMLVideoElement.h in Headers */,
                                B2FA3DDD0AB75A6F000E5AC4 /* JSSVGPathSegMovetoAbs.h in Headers */,
                                B2FA3DDF0AB75A6F000E5AC4 /* JSSVGPathSegMovetoRel.h in Headers */,
                                0705852117FDC140005F2BCB /* MediaTrackConstraint.h in Headers */,
+                               E1C266DB18319935003F8B33 /* CryptoAlgorithmRsaSsaKeyParams.h in Headers */,
                                CD8B5A46180DFF4E008B8E65 /* VideoTrackMediaSource.h in Headers */,
                                B2FA3DE10AB75A6F000E5AC4 /* JSSVGPatternElement.h in Headers */,
                                8542A7950AE5C94100DF58DF /* JSSVGPoint.h in Headers */,
                                078E091B17D14D1C00420AA1 /* NavigatorUserMediaError.h in Headers */,
                                BC5EB5DD0E81B8DD00B25965 /* OutlineValue.h in Headers */,
                                1A0D57370A5C77FE007EDD4C /* OverflowEvent.h in Headers */,
+                               E1BD331C182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParams.h in Headers */,
                                3774ABA50FA21EB400AD7DE9 /* OverlapTestRequestClient.h in Headers */,
                                65A21468097A329100B9050A /* Page.h in Headers */,
                                9B50B1DE17CD4C0F0087F63C /* FormNamedItem.h in Headers */,
                                50D40611147D49DE00D30BB5 /* CustomFilterCompiledProgram.cpp in Sources */,
                                50987C26157D676D00BDA835 /* CustomFilterGlobalContext.cpp in Sources */,
                                50D405F9147D31F300D30BB5 /* CustomFilterMesh.cpp in Sources */,
+                               E1C266DE18319F31003F8B33 /* CryptoKeyDataRSAComponents.cpp in Sources */,
                                7E12E91015FA5D3A005E4126 /* CustomFilterMeshGenerator.cpp in Sources */,
                                50CC0A3914C6F5B10017AB51 /* CustomFilterOperation.cpp in Sources */,
                                5093334F163B0E4300099A60 /* CustomFilterParameterList.cpp in Sources */,
                                E125F8381822F1EB00D84CD9 /* CryptoAlgorithmHMACMac.cpp in Sources */,
                                BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */,
                                977B3879122883E900B81FF8 /* HTMLViewSourceParser.cpp in Sources */,
+                               E1C266D818317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp in Sources */,
                                0B8C56D40F28627F000502E1 /* HTTPHeaderMap.cpp in Sources */,
                                514C76720CE923A1007EF3CD /* HTTPParsers.cpp in Sources */,
                                371A67CB11C6C7DB00047B8B /* HyphenationCF.cpp in Sources */,
                                C6F420A216B7164E0052A9F2 /* JSMutationCallback.cpp in Sources */,
                                65DF31FB09D1CC60000BE325 /* JSMutationEvent.cpp in Sources */,
                                C6F0902C14327D4F00685849 /* JSMutationObserver.cpp in Sources */,
+                               E164FAA518315E1A00DB4E61 /* CryptoKeyRSAMac.cpp in Sources */,
                                C6F0917F143A2BB900685849 /* JSMutationObserverCustom.cpp in Sources */,
                                C6F08FC91431000D00685849 /* JSMutationRecord.cpp in Sources */,
                                078E090117D14CEE00420AA1 /* MediaStreamRegistry.cpp in Sources */,
                                93F1D5C012D5335600832BEC /* JSWebGLLoseContext.cpp in Sources */,
                                49C7B99B1042D2D30009D447 /* JSWebGLProgram.cpp in Sources */,
                                49C7B99D1042D2D30009D447 /* JSWebGLRenderbuffer.cpp in Sources */,
+                               E1BD3319182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp in Sources */,
                                49EED1461051969400099FAB /* JSWebGLRenderingContext.cpp in Sources */,
                                49EED14F1051971A00099FAB /* JSWebGLRenderingContextCustom.cpp in Sources */,
                                49C7B9A21042D2D30009D447 /* JSWebGLShader.cpp in Sources */,
index 7b9327f..13c063b 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <runtime/ObjectConstructor.h>
 #include <runtime/Operations.h>
+#include <runtime/TypedArrays.h>
+#include <runtime/TypedArrayInlines.h>
 
 using namespace JSC;
 
@@ -64,6 +66,14 @@ void JSCryptoAlgorithmBuilder::add(const char* key, const String& value)
     m_dictionary->putDirect(vm, identifier, jsString(m_exec, value));
 }
 
+void JSCryptoAlgorithmBuilder::add(const char* key, const Vector<uint8_t>& buffer)
+{
+    VM& vm = m_exec->vm();
+    Identifier identifier(&vm, key);
+    RefPtr<Uint8Array> arrayView = Uint8Array::create(buffer.data(), buffer.size());
+    m_dictionary->putDirect(vm, identifier, arrayView->wrap(m_exec, vm.dynamicGlobalObject));
+}
+
 void JSCryptoAlgorithmBuilder::add(const char* key, const CryptoAlgorithmDescriptionBuilder& nestedBuilder)
 {
     VM& vm = m_exec->vm();
index d2f3d58..e08c8fe 100644 (file)
@@ -48,6 +48,7 @@ public:
 
     virtual void add(const char*, unsigned) OVERRIDE;
     virtual void add(const char*, const String&) OVERRIDE;
+    virtual void add(const char*, const Vector<uint8_t>&) OVERRIDE;
     virtual void add(const char*, const CryptoAlgorithmDescriptionBuilder&) OVERRIDE;
 
 private:
index 509f5cb..d9b354f 100644 (file)
@@ -33,6 +33,9 @@
 #include "CryptoAlgorithmHmacKeyParams.h"
 #include "CryptoAlgorithmHmacParams.h"
 #include "CryptoAlgorithmRegistry.h"
+#include "CryptoAlgorithmRsaKeyGenParams.h"
+#include "CryptoAlgorithmRsaSsaKeyParams.h"
+#include "CryptoAlgorithmRsaSsaParams.h"
 #include "ExceptionCode.h"
 #include "JSCryptoOperationData.h"
 #include "JSDOMBinding.h"
@@ -116,7 +119,7 @@ static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier
     return JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(exec, hash, result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(JSC::ExecState* exec, JSC::JSValue value)
+static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -145,7 +148,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createAesCbcParams(JSC::ExecSt
     return std::move(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(JSC::ExecState* exec, JSC::JSValue value)
+static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -163,7 +166,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createAesKeyGenParams(JSC::Exe
     return std::move(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(JSC::ExecState* exec, JSC::JSValue value)
+static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -181,7 +184,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(JSC::ExecStat
     return std::move(result);
 }
 
-static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(JSC::ExecState* exec, JSC::JSValue value)
+static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState* exec, JSValue value)
 {
     if (!value.isObject()) {
         throwTypeError(exec);
@@ -203,7 +206,63 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(JSC::ExecS
     return std::move(result);
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForEncrypt(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState* exec, JSValue value)
+{
+    if (!value.isObject()) {
+        throwTypeError(exec);
+        return nullptr;
+    }
+
+    auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>();
+
+    JSValue modulusLengthValue = getProperty(exec, value.getObject(), "modulusLength");
+    if (exec->hadException())
+        return nullptr;
+
+    // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>.
+    result->modulusLength = toUInt32(exec, modulusLengthValue, NormalConversion);
+    if (exec->hadException())
+        return nullptr;
+
+    JSValue publicExponentValue = getProperty(exec, value.getObject(), "publicExponent");
+    if (exec->hadException())
+        return nullptr;
+
+    RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue);
+    if (!publicExponentArray) {
+        throwTypeError(exec, "Expected a Uint8Array in publicExponent");
+        return nullptr;
+    }
+    result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());
+
+    return std::move(result);
+}
+
+static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaKeyParams(ExecState*, JSValue)
+{
+    // WebCrypto RSASSA-PKCS1-v1_5 algorithm currently does not take any parameters to importKey.
+    return std::make_unique<CryptoAlgorithmRsaSsaKeyParams>();
+}
+
+static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState* exec, JSValue value)
+{
+    if (!value.isObject()) {
+        throwTypeError(exec);
+        return nullptr;
+    }
+
+    JSDictionary jsDictionary(exec, value.getObject());
+    auto result = std::make_unique<CryptoAlgorithmRsaSsaParams>();
+
+    if (!getHashAlgorithm(jsDictionary, result->hash)) {
+        ASSERT(exec->hadException());
+        return nullptr;
+    }
+
+    return std::move(result);
+}
+
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForEncrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -235,7 +294,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDecrypt(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDecrypt(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -267,11 +326,14 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForSign(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForSign(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+        setDOMException(exec, NOT_SUPPORTED_ERR);
+        return nullptr;
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+        return createRsaSsaParams(exec, value);
     case CryptoAlgorithmIdentifier::RSA_PSS:
     case CryptoAlgorithmIdentifier::RSA_OAEP:
     case CryptoAlgorithmIdentifier::ECDSA:
@@ -299,11 +361,14 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForVerify(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForVerify(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+        setDOMException(exec, NOT_SUPPORTED_ERR);
+        return nullptr;
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+        return createRsaSsaParams(exec, value);
     case CryptoAlgorithmIdentifier::RSA_PSS:
     case CryptoAlgorithmIdentifier::RSA_OAEP:
     case CryptoAlgorithmIdentifier::ECDSA:
@@ -331,7 +396,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDigest(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDigest(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -363,13 +428,14 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForGenerateKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForGenerateKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
     case CryptoAlgorithmIdentifier::RSA_PSS:
     case CryptoAlgorithmIdentifier::RSA_OAEP:
+        return createRsaKeyGenParams(exec, value);
     case CryptoAlgorithmIdentifier::ECDSA:
     case CryptoAlgorithmIdentifier::ECDH:
         setDOMException(exec, NOT_SUPPORTED_ERR);
@@ -396,7 +462,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -425,7 +491,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveBits(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForDeriveBits(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -454,11 +520,13 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForImportKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue value)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForImportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue value)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
+        return std::make_unique<CryptoAlgorithmParameters>();
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
+        return createRsaSsaKeyParams(exec, value);
     case CryptoAlgorithmIdentifier::RSA_PSS:
     case CryptoAlgorithmIdentifier::RSA_OAEP:
     case CryptoAlgorithmIdentifier::ECDSA:
@@ -486,7 +554,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForExportKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForExportKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -516,7 +584,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForWrapKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForWrapKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
@@ -545,7 +613,7 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
     }
 }
 
-std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForUnwrapKey(JSC::ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSC::JSValue)
+std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createParametersForUnwrapKey(ExecState* exec, CryptoAlgorithmIdentifier algorithm, JSValue)
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
index 7dbe489..0226925 100644 (file)
@@ -31,7 +31,9 @@
 #include "CryptoAlgorithm.h"
 #include "CryptoAlgorithmHmacParams.h"
 #include "CryptoAlgorithmRegistry.h"
+#include "CryptoAlgorithmRsaSsaKeyParams.h"
 #include "CryptoKeyDataOctetSequence.h"
+#include "CryptoKeyDataRSAComponents.h"
 #include "ExceptionCode.h"
 #include "JSDOMBinding.h"
 #include <heap/StrongInlines.h>
@@ -42,6 +44,26 @@ using namespace JSC;
 
 namespace WebCore {
 
+static bool getJSArrayFromJSON(ExecState* exec, JSObject* json, const char* key, JSArray*& result)
+{
+    Identifier identifier(exec, key);
+    PropertySlot slot(json);
+
+    if (!json->getPropertySlot(exec, identifier, slot))
+        return false;
+
+    JSValue value = slot.getValue(exec, identifier);
+    ASSERT(!exec->hadException());
+    if (isJSArray(value)) {
+        throwTypeError(exec, String::format("Expected an array for \"%s\" JSON key",  key));
+        return false;
+    }
+
+    result = asArray(value);
+
+    return true;
+}
+
 static bool getStringFromJSON(ExecState* exec, JSObject* json, const char* key, String& result)
 {
     Identifier identifier(exec, key);
@@ -82,6 +104,25 @@ static bool getBooleanFromJSON(ExecState* exec, JSObject* json, const char* key,
     return true;
 }
 
+static bool getBigIntegerVectorFromJSON(ExecState* exec, JSObject* json, const char* key, Vector<char>& result)
+{
+    String base64urlEncodedNumber;
+    if (!getStringFromJSON(exec, json, key, base64urlEncodedNumber))
+        return false;
+
+    if (!base64URLDecode(base64urlEncodedNumber, result)) {
+        throwTypeError(exec, "Cannot decode base64url key data in JWK");
+        return false;
+    }
+
+    if (result[0] == 0) {
+        throwTypeError(exec, "JWK BigInteger must utilize the minimum number of octets to represent the value");
+        return false;
+    }
+
+    return true;
+}
+
 JSCryptoKeySerializationJWK::JSCryptoKeySerializationJWK(ExecState* exec, const String& jsonString)
     : m_exec(exec)
 {
@@ -108,6 +149,15 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHMACParameters(CryptoAlg
     return std::move(hmacParameters);
 }
 
+static std::unique_ptr<CryptoAlgorithmParameters> createRSASSAKeyParameters(CryptoAlgorithmIdentifier hashFunction)
+{
+    std::unique_ptr<CryptoAlgorithmRsaSsaKeyParams> rsaSSAParameters = std::make_unique<CryptoAlgorithmRsaSsaKeyParams>();
+    rsaSSAParameters->hasHash = true;
+    rsaSSAParameters->hash = hashFunction;
+    return std::move(rsaSSAParameters);
+}
+
+
 bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>& suggestedAlgorithm, std::unique_ptr<CryptoAlgorithmParameters>& suggestedParameters) const
 {
     if (!getStringFromJSON(m_exec, m_json.get(), "alg", m_jwkAlgorithmName)) {
@@ -126,6 +176,15 @@ bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgor
     } else if (m_jwkAlgorithmName == "HS512") {
         algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::HMAC);
         parameters = createHMACParameters(CryptoAlgorithmIdentifier::SHA_512);
+    } else if (m_jwkAlgorithmName == "RS256") {
+        algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5);
+        parameters = createRSASSAKeyParameters(CryptoAlgorithmIdentifier::SHA_256);
+    } else if (m_jwkAlgorithmName == "RS384") {
+        algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5);
+        parameters = createRSASSAKeyParameters(CryptoAlgorithmIdentifier::SHA_384);
+    } else if (m_jwkAlgorithmName == "RS512") {
+        algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5);
+        parameters = createRSASSAKeyParameters(CryptoAlgorithmIdentifier::SHA_512);
     } else if (m_jwkAlgorithmName == "A128CBC") {
         algorithm = CryptoAlgorithmRegistry::shared().create(CryptoAlgorithmIdentifier::AES_CBC);
         parameters = std::make_unique<CryptoAlgorithmParameters>();
@@ -152,11 +211,20 @@ bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgor
     if (algorithm->identifier() != suggestedAlgorithm->identifier())
         return false;
 
-    // HMAC is the only algorithm that has parameters in importKey.
-    if (algorithm->identifier() != CryptoAlgorithmIdentifier::HMAC)
-        return true;
+    if (algorithm->identifier() == CryptoAlgorithmIdentifier::HMAC)
+        return static_cast<CryptoAlgorithmHmacParams&>(*parameters).hash == static_cast<CryptoAlgorithmHmacParams&>(*suggestedParameters).hash;
+    if (algorithm->identifier() == CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5) {
+        CryptoAlgorithmRsaSsaKeyParams& rsaSSAParameters = static_cast<CryptoAlgorithmRsaSsaKeyParams&>(*parameters);
+        CryptoAlgorithmRsaSsaKeyParams& suggestedRSASSAParameters = static_cast<CryptoAlgorithmRsaSsaKeyParams&>(*suggestedParameters);
+        ASSERT(rsaSSAParameters.hasHash);
+        if (suggestedRSASSAParameters.hasHash)
+            return suggestedRSASSAParameters.hash == rsaSSAParameters.hash;
+        suggestedRSASSAParameters.hasHash = true;
+        suggestedRSASSAParameters.hash = rsaSSAParameters.hash;
+    }
 
-    return static_cast<CryptoAlgorithmHmacParams&>(*parameters).hash == static_cast<CryptoAlgorithmHmacParams&>(*suggestedParameters).hash;
+    // Other algorithms don't have parameters.
+    return true;
 }
 
 void JSCryptoKeySerializationJWK::reconcileUsages(CryptoKeyUsage& suggestedUsage) const
@@ -207,20 +275,8 @@ bool JSCryptoKeySerializationJWK::keySizeIsValid(size_t sizeInBits) const
     return true;
 }
 
-std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyData() const
+std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataOctetSequence() const
 {
-    String jwkKeyType;
-    if (!getStringFromJSON(m_exec, m_json.get(), "kty", jwkKeyType)) {
-        if (!m_exec->hadException())
-            throwTypeError(m_exec, "Required JWK \"kty\" member is missing");
-        return nullptr;
-    }
-
-    if (jwkKeyType != "oct") {
-        throwTypeError(m_exec, "Unsupported JWK key type " + jwkKeyType);
-        return nullptr;
-    }
-
     String keyBase64URL;
     if (!getStringFromJSON(m_exec, m_json.get(), "k", keyBase64URL)) {
         if (!m_exec->hadException())
@@ -242,6 +298,119 @@ std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyData() const
     return CryptoKeyDataOctetSequence::create(octetSequence);
 }
 
+std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents() const
+{
+    Vector<char> modulus;
+    Vector<char> exponent;
+    Vector<char> privateExponent;
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "n", modulus)) {
+        if (!m_exec->hadException())
+            throwTypeError(m_exec, "Required JWK \"n\" member is missing");
+        return nullptr;
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "e", exponent)) {
+        if (!m_exec->hadException())
+            throwTypeError(m_exec, "Required JWK \"e\" member is missing");
+        return nullptr;
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "d", modulus)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPublic(modulus, exponent);
+    }
+
+    CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo;
+    CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo;
+    Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos;
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "p", firstPrimeInfo.primeFactor)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dp", firstPrimeInfo.factorCRTExponent)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "q", secondPrimeInfo.primeFactor)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dq", secondPrimeInfo.factorCRTExponent)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
+    }
+
+    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "qi", secondPrimeInfo.factorCRTCoefficient)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
+    }
+
+    JSArray* otherPrimeInfoJSArray;
+    if (!getJSArrayFromJSON(m_exec, m_json.get(), "oth", otherPrimeInfoJSArray)) {
+        if (m_exec->hadException())
+            return nullptr;
+        return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
+    }
+
+    for (size_t i = 0; i < otherPrimeInfoJSArray->length(); ++i) {
+        CryptoKeyDataRSAComponents::PrimeInfo info;
+        JSValue element = otherPrimeInfoJSArray->getIndex(m_exec, i);
+        if (m_exec->hadException())
+            return nullptr;
+        if (!element.isObject()) {
+            throwTypeError(m_exec, "JWK \"oth\" array member is not an object");
+            return nullptr;
+        }
+        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "r", info.primeFactor)) {
+            if (!m_exec->hadException())
+                throwTypeError(m_exec, "Cannot get prime factor for a prime in \"oth\" dictionary");
+            return nullptr;
+        }
+        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "d", info.factorCRTExponent)) {
+            if (!m_exec->hadException())
+                throwTypeError(m_exec, "Cannot get factor CRT exponent for a prime in \"oth\" dictionary");
+            return nullptr;
+        }
+        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "t", info.factorCRTCoefficient)) {
+            if (!m_exec->hadException())
+                throwTypeError(m_exec, "Cannot get factor CRT coefficient for a prime in \"oth\" dictionary");
+            return nullptr;
+        }
+        otherPrimeInfos.append(info);
+    }
+
+    return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
+}
+
+std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyData() const
+{
+    String jwkKeyType;
+    if (!getStringFromJSON(m_exec, m_json.get(), "kty", jwkKeyType)) {
+        if (!m_exec->hadException())
+            throwTypeError(m_exec, "Required JWK \"kty\" member is missing");
+        return nullptr;
+    }
+
+    if (jwkKeyType == "oct")
+        return keyDataOctetSequence();
+
+    if (jwkKeyType == "RSA")
+        return keyDataRSAComponents();
+
+    throwTypeError(m_exec, "Unsupported JWK key type " + jwkKeyType);
+    return nullptr;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SUBTLE_CRYPTO)
index 5d5e820..ad05170 100644 (file)
@@ -63,6 +63,8 @@ private:
     JSCryptoKeySerializationJWK(JSC::ExecState*, const String&);
 
     bool keySizeIsValid(size_t sizeInBits) const;
+    std::unique_ptr<CryptoKeyData> keyDataOctetSequence() const;
+    std::unique_ptr<CryptoKeyData> keyDataRSAComponents() const;
 
     JSC::ExecState* m_exec;
     JSC::Strong<JSC::JSObject> m_json;
index 77aa2e2..a7fe14b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
 
 #if ENABLE(SUBTLE_CRYPTO)
 
@@ -43,6 +44,7 @@ public:
 
     virtual void add(const char*, unsigned) = 0;
     virtual void add(const char*, const String&) = 0;
+    virtual void add(const char*, const Vector<uint8_t>&) = 0;
     virtual void add(const char*, const CryptoAlgorithmDescriptionBuilder&) = 0;
 };
 
diff --git a/Source/WebCore/crypto/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp b/Source/WebCore/crypto/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp
new file mode 100644 (file)
index 0000000..60a31c7
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include "ExceptionCode.h"
+
+namespace WebCore {
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::sign(const CryptoAlgorithmParameters&, const CryptoKey&, const Vector<CryptoOperationData>&, std::unique_ptr<PromiseWrapper>, ExceptionCode& ec)
+{
+    ec = NOT_SUPPORTED_ERR;
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::verify(const CryptoAlgorithmParameters&, const CryptoKey&, const CryptoOperationData& /*signature*/, const Vector<CryptoOperationData>& /*data*/, std::unique_ptr<PromiseWrapper>, ExceptionCode& ec)
+{
+    ec = NOT_SUPPORTED_ERR;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
index f698bb3..7362dc7 100644 (file)
@@ -41,7 +41,8 @@ class CryptoAlgorithmDescriptionBuilder;
 
 ENUM_CLASS(CryptoKeyClass) {
     HMAC,
-    AES
+    AES,
+    RSA
 };
 
 class CryptoKey : public RefCounted<CryptoKey> {
index 2e54512..54106b3 100644 (file)
@@ -36,7 +36,8 @@ class CryptoKeyData {
 WTF_MAKE_NONCOPYABLE(CryptoKeyData);
 public:
     ENUM_CLASS(Format) {
-        OctetSequence
+        OctetSequence,
+        RSAComponents
     };
 
     CryptoKeyData(Format format)
index 2836cb7..083a3fe 100644 (file)
@@ -75,7 +75,7 @@ void CryptoAlgorithmAES_CBC::importKey(const CryptoAlgorithmParameters&, const C
         ec = NOT_SUPPORTED_ERR;
         return;
     }
-    const CryptoKeyDataOctetSequence& keyDataOctetSequence = asCryptoKeyDataOctetSequence(keyData);
+    const CryptoKeyDataOctetSequence& keyDataOctetSequence = toCryptoKeyDataOctetSequence(keyData);
     RefPtr<CryptoKeyAES> result = CryptoKeyAES::create(CryptoAlgorithmIdentifier::AES_CBC, keyDataOctetSequence.octetSequence(), extractable, usage);
     promise->fulfill(result.release());
 }
index f2ed2ce..3c1a38c 100644 (file)
@@ -76,7 +76,7 @@ void CryptoAlgorithmHMAC::importKey(const CryptoAlgorithmParameters& parameters,
         ec = NOT_SUPPORTED_ERR;
         return;
     }
-    const CryptoKeyDataOctetSequence& keyDataOctetSequence = asCryptoKeyDataOctetSequence(keyData);
+    const CryptoKeyDataOctetSequence& keyDataOctetSequence = toCryptoKeyDataOctetSequence(keyData);
 
     const CryptoAlgorithmHmacParams& hmacParameters = static_cast<const CryptoAlgorithmHmacParams&>(parameters);
 
diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
new file mode 100644 (file)
index 0000000..c8c977f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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 "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include "CryptoAlgorithmRsaKeyGenParams.h"
+#include "CryptoAlgorithmRsaSsaKeyParams.h"
+#include "CryptoKeyDataRSAComponents.h"
+#include "CryptoKeyRSA.h"
+#include "JSDOMPromise.h"
+
+namespace WebCore {
+
+const char* const CryptoAlgorithmRSASSA_PKCS1_v1_5::s_name = "rsassa-pkcs1-v1_5";
+
+CryptoAlgorithmRSASSA_PKCS1_v1_5::CryptoAlgorithmRSASSA_PKCS1_v1_5()
+{
+}
+
+CryptoAlgorithmRSASSA_PKCS1_v1_5::~CryptoAlgorithmRSASSA_PKCS1_v1_5()
+{
+}
+
+std::unique_ptr<CryptoAlgorithm> CryptoAlgorithmRSASSA_PKCS1_v1_5::create()
+{
+    return std::unique_ptr<CryptoAlgorithm>(new CryptoAlgorithmRSASSA_PKCS1_v1_5);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSASSA_PKCS1_v1_5::identifier() const
+{
+    return s_identifier;
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(const CryptoAlgorithmParameters& parameters, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, std::unique_ptr<PromiseWrapper> promise, ExceptionCode&)
+{
+    const CryptoAlgorithmRsaSsaKeyParams& rsaSSAParameters = static_cast<const CryptoAlgorithmRsaSsaKeyParams&>(parameters);
+    const CryptoKeyDataRSAComponents& rsaComponents = toCryptoKeyDataRSAComponents(keyData);
+
+    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaComponents, extractable, usage);
+    if (!result) {
+        promise->reject(nullptr);
+        return;
+    }
+
+    if (rsaSSAParameters.hasHash)
+        result->restrictToHash(rsaSSAParameters.hash);
+
+    promise->fulfill(result.release());
+}
+
+void CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsage usages, std::unique_ptr<PromiseWrapper> promise, ExceptionCode&)
+{
+    const CryptoAlgorithmRsaKeyGenParams& rsaParameters = static_cast<const CryptoAlgorithmRsaKeyGenParams&>(parameters);
+
+    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, std::move(promise));
+}
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.h
new file mode 100644 (file)
index 0000000..2c5da8e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoAlgorithmRSASSA_PKCS1_v1_5_h
+#define CryptoAlgorithmRSASSA_PKCS1_v1_5_h
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRSASSA_PKCS1_v1_5 FINAL : public CryptoAlgorithm {
+public:
+    static const char* const s_name;
+    static const CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5;
+
+    static std::unique_ptr<CryptoAlgorithm> create();
+
+    virtual CryptoAlgorithmIdentifier identifier() const OVERRIDE;
+
+    virtual void sign(const CryptoAlgorithmParameters&, const CryptoKey&, const Vector<CryptoOperationData>&, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
+    virtual void verify(const CryptoAlgorithmParameters&, const CryptoKey&, const CryptoOperationData& signature, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
+    virtual void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
+    virtual void importKey(const CryptoAlgorithmParameters&, const CryptoKeyData&, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>, ExceptionCode&) OVERRIDE;
+
+private:
+    CryptoAlgorithmRSASSA_PKCS1_v1_5();
+    virtual ~CryptoAlgorithmRSASSA_PKCS1_v1_5();
+};
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoAlgorithmRSASSA_PKCS1_v1_5_h
index f77747f..9aa4b6b 100644 (file)
@@ -56,18 +56,21 @@ private:
     Vector<char> m_key;
 };
 
-inline const CryptoKeyAES* asCryptoKeyAES(const CryptoKey& key)
+inline bool isCryptoKeyAES(const CryptoKey& key)
 {
-    if (key.keyClass() != CryptoKeyClass::AES)
-        return nullptr;
-    return static_cast<const CryptoKeyAES*>(&key);
+    return key.keyClass() == CryptoKeyClass::AES;
 }
 
-inline CryptoKeyAES* asCryptoKeyAES(CryptoKey& key)
+inline const CryptoKeyAES& toCryptoKeyAES(const CryptoKey& key)
 {
-    if (key.keyClass() != CryptoKeyClass::AES)
-        return nullptr;
-    return static_cast<CryptoKeyAES*>(&key);
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyAES(key));
+    return static_cast<const CryptoKeyAES&>(key);
+}
+
+inline CryptoKeyAES& toCryptoKeyAES(CryptoKey& key)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyAES(key));
+    return static_cast<CryptoKeyAES&>(key);
 }
 
 } // namespace WebCore
index 0396f4c..2f559a6 100644 (file)
@@ -49,7 +49,7 @@ private:
     Vector<char> m_keyData;
 };
 
-inline const CryptoKeyDataOctetSequence& asCryptoKeyDataOctetSequence(const CryptoKeyData& data)
+inline const CryptoKeyDataOctetSequence& toCryptoKeyDataOctetSequence(const CryptoKeyData& data)
 {
     ASSERT(data.format() == CryptoKeyData::Format::OctetSequence);
     return static_cast<const CryptoKeyDataOctetSequence&>(data);
diff --git a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp
new file mode 100644 (file)
index 0000000..5d8d511
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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 "CryptoKeyDataRSAComponents.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent)
+    : CryptoKeyData(CryptoKeyData::Format::RSAComponents)
+    , m_type(Type::Public)
+    , m_modulus(modulus)
+    , m_exponent(exponent)
+{
+}
+
+CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent)
+    : CryptoKeyData(CryptoKeyData::Format::RSAComponents)
+    , m_type(Type::Private)
+    , m_modulus(modulus)
+    , m_exponent(exponent)
+    , m_privateExponent(privateExponent)
+    , m_hasAdditionalPrivateKeyParameters(false)
+{
+}
+
+CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos)
+    : CryptoKeyData(CryptoKeyData::Format::RSAComponents)
+    , m_type(Type::Private)
+    , m_modulus(modulus)
+    , m_exponent(exponent)
+    , m_privateExponent(privateExponent)
+    , m_hasAdditionalPrivateKeyParameters(true)
+    , m_firstPrimeInfo(firstPrimeInfo)
+    , m_secondPrimeInfo(secondPrimeInfo)
+    , m_otherPrimeInfos(otherPrimeInfos)
+{
+}
+
+CryptoKeyDataRSAComponents::~CryptoKeyDataRSAComponents()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
diff --git a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h
new file mode 100644 (file)
index 0000000..347e08d
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoKeyDataRSAComponents_h
+#define CryptoKeyDataRSAComponents_h
+
+#include "CryptoKeyData.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoKeyDataRSAComponents FINAL : public CryptoKeyData {
+public:
+    ENUM_CLASS(Type) {
+        Public,
+        Private
+    };
+
+    struct PrimeInfo {
+        Vector<char> primeFactor;
+        Vector<char> factorCRTExponent;
+        Vector<char> factorCRTCoefficient;
+    };
+
+    static std::unique_ptr<CryptoKeyDataRSAComponents> createPublic(const Vector<char>& modulus, const Vector<char>& exponent)
+    {
+        return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent));
+    }
+
+    static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivate(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent)
+    {
+        return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent, privateExponent));
+    }
+
+    static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivateWithAdditionalData(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos)
+    {
+        return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos));
+    }
+
+    virtual ~CryptoKeyDataRSAComponents();
+
+    Type type() const { return m_type; }
+
+    // Private and public keys.
+    const Vector<char>& modulus() const { return m_modulus; }
+    const Vector<char>& exponent() const { return m_exponent; }
+
+    // Only private keys.
+    const Vector<char>& privateExponent() const { return m_privateExponent; }
+    bool hasAdditionalPrivateKeyParameters() const { return m_hasAdditionalPrivateKeyParameters; }
+    const PrimeInfo& firstPrimeInfo() const { return m_firstPrimeInfo; }
+    const PrimeInfo& secondPrimeInfo() const { return m_secondPrimeInfo; }
+    const Vector<PrimeInfo>& otherPrimeInfos() const { return m_otherPrimeInfos; }
+
+private:
+    CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent);
+    CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent);
+    CryptoKeyDataRSAComponents(const Vector<char>& modulus, const Vector<char>& exponent, const Vector<char>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos);
+
+    Type m_type;
+
+    // Private and public keys.
+    Vector<char> m_modulus;
+    Vector<char> m_exponent;
+
+    // Only private keys.
+    Vector<char> m_privateExponent;
+    bool m_hasAdditionalPrivateKeyParameters;
+    PrimeInfo m_firstPrimeInfo;
+    PrimeInfo m_secondPrimeInfo;
+    Vector<PrimeInfo> m_otherPrimeInfos; // When three or more primes have been used, the number of array elements is be the number of primes used minus two.
+};
+
+inline const CryptoKeyDataRSAComponents& toCryptoKeyDataRSAComponents(const CryptoKeyData& data)
+{
+    ASSERT(data.format() == CryptoKeyData::Format::RSAComponents);
+    return static_cast<const CryptoKeyDataRSAComponents&>(data);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoKeyDataRSAComponents_h
index 682e54c..a0a60e0 100644 (file)
@@ -57,18 +57,21 @@ private:
     Vector<char> m_key;
 };
 
-inline const CryptoKeyHMAC* asCryptoKeyHMAC(const CryptoKey& key)
+inline bool isCryptoKeyHMAC(const CryptoKey& key)
 {
-    if (key.keyClass() != CryptoKeyClass::HMAC)
-        return nullptr;
-    return static_cast<const CryptoKeyHMAC*>(&key);
+    return key.keyClass() == CryptoKeyClass::HMAC;
 }
 
-inline CryptoKeyHMAC* asCryptoKeyHMAC(CryptoKey& key)
+inline const CryptoKeyHMAC& toCryptoKeyHMAC(const CryptoKey& key)
 {
-    if (key.keyClass() != CryptoKeyClass::HMAC)
-        return nullptr;
-    return static_cast<CryptoKeyHMAC*>(&key);
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyHMAC(key));
+    return static_cast<const CryptoKeyHMAC&>(key);
+}
+
+inline CryptoKeyHMAC& toCryptoKeyHMAC(CryptoKey& key)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyHMAC(key));
+    return static_cast<CryptoKeyHMAC&>(key);
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/crypto/keys/CryptoKeyRSA.h b/Source/WebCore/crypto/keys/CryptoKeyRSA.h
new file mode 100644 (file)
index 0000000..6512930
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoKeyRSA_h
+#define CryptoKeyRSA_h
+
+#include "CryptoKey.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+typedef struct _CCRSACryptor *CCRSACryptorRef;
+typedef CCRSACryptorRef PlatformRSAKey;
+#endif
+
+namespace WebCore {
+
+class CryptoKeyDataRSAComponents;
+class CryptoKeyPair;
+class PromiseWrapper;
+
+class CryptoKeyRSA FINAL : public CryptoKey {
+public:
+    static PassRefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
+    {
+        return adoptRef(new CryptoKeyRSA(identifier, type, platformKey, extractable, usage));
+    }
+    static PassRefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, const CryptoKeyDataRSAComponents&, bool extractable, CryptoKeyUsage);
+    virtual ~CryptoKeyRSA();
+
+    void restrictToHash(CryptoAlgorithmIdentifier);
+
+    static void generatePair(CryptoAlgorithmIdentifier, unsigned modulusLength, const Vector<char>& publicExponent, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>);
+
+    virtual CryptoKeyClass keyClass() const OVERRIDE { return CryptoKeyClass::RSA; }
+
+    PlatformRSAKey platformKey() const { return m_platformKey; }
+
+    virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const OVERRIDE;
+
+private:
+    CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsage);
+
+    PlatformRSAKey m_platformKey;
+
+    bool m_restrictedToSpecificHash;
+    CryptoAlgorithmIdentifier m_hash;
+};
+
+inline bool isCryptoKeyRSA(const CryptoKey& key)
+{
+    return key.keyClass() == CryptoKeyClass::RSA;
+}
+
+inline const CryptoKeyRSA& toCryptoKeyRSA(const CryptoKey& key)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyRSA(key));
+    return static_cast<const CryptoKeyRSA&>(key);
+}
+
+inline CryptoKeyRSA& asCryptoKeyRSA(CryptoKey& key)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isCryptoKeyRSA(key));
+    return static_cast<CryptoKeyRSA&>(key);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoKeyRSA_h
index dc48ad4..daab812 100644 (file)
@@ -92,27 +92,27 @@ static void transformAES_CBC(CCOperation operation, const CryptoAlgorithmAesCbcP
 void CryptoAlgorithmAES_CBC::encrypt(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper> promise, ExceptionCode& ec)
 {
     const CryptoAlgorithmAesCbcParams& aesCBCParameters = static_cast<const CryptoAlgorithmAesCbcParams&>(parameters);
-    const CryptoKeyAES* aesKey = asCryptoKeyAES(key);
 
-    if (!aesKey) {
+    if (!isCryptoKeyAES(key)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
+    const CryptoKeyAES& aesKey = toCryptoKeyAES(key);
 
-    transformAES_CBC(kCCEncrypt, aesCBCParameters, *aesKey, data, std::move(promise));
+    transformAES_CBC(kCCEncrypt, aesCBCParameters, aesKey, data, std::move(promise));
 }
 
 void CryptoAlgorithmAES_CBC::decrypt(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper> promise, ExceptionCode& ec)
 {
     const CryptoAlgorithmAesCbcParams& aesCBCParameters = static_cast<const CryptoAlgorithmAesCbcParams&>(parameters);
-    const CryptoKeyAES* aesKey = asCryptoKeyAES(key);
 
-    if (!aesKey) {
+    if (!isCryptoKeyAES(key)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
+    const CryptoKeyAES& aesKey = toCryptoKeyAES(key);
 
-    transformAES_CBC(kCCDecrypt, aesCBCParameters, *aesKey, data, std::move(promise));
+    transformAES_CBC(kCCDecrypt, aesCBCParameters, aesKey, data, std::move(promise));
 }
 
 } // namespace WebCore
index a09f90b..c1c42b0 100644 (file)
@@ -95,20 +95,20 @@ static Vector<unsigned char> calculateSignature(CCHmacAlgorithm algorithm, const
 void CryptoAlgorithmHMAC::sign(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper> promise, ExceptionCode& ec)
 {
     const CryptoAlgorithmHmacParams& hmacParameters = static_cast<const CryptoAlgorithmHmacParams&>(parameters);
-    const CryptoKeyHMAC* hmacKey = asCryptoKeyHMAC(key);
 
-    CCHmacAlgorithm algorithm;
-    if (!getCommonCryptoAlgorithm(hmacParameters.hash, algorithm)) {
+    if (!isCryptoKeyHMAC(key)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
+    const CryptoKeyHMAC& hmacKey = toCryptoKeyHMAC(key);
 
-    if (!hmacKey) {
+    CCHmacAlgorithm algorithm;
+    if (!getCommonCryptoAlgorithm(hmacParameters.hash, algorithm)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
 
-    Vector<unsigned char> signature = calculateSignature(algorithm, hmacKey->key(), data);
+    Vector<unsigned char> signature = calculateSignature(algorithm, hmacKey.key(), data);
 
     promise->fulfill(signature);
 }
@@ -116,20 +116,20 @@ void CryptoAlgorithmHMAC::sign(const CryptoAlgorithmParameters& parameters, cons
 void CryptoAlgorithmHMAC::verify(const CryptoAlgorithmParameters& parameters, const CryptoKey& key, const CryptoOperationData& expectedSignature, const Vector<CryptoOperationData>& data, std::unique_ptr<PromiseWrapper> promise, ExceptionCode& ec)
 {
     const CryptoAlgorithmHmacParams& hmacParameters = static_cast<const CryptoAlgorithmHmacParams&>(parameters);
-    const CryptoKeyHMAC* hmacKey = asCryptoKeyHMAC(key);
 
-    CCHmacAlgorithm algorithm;
-    if (!getCommonCryptoAlgorithm(hmacParameters.hash, algorithm)) {
+    if (!isCryptoKeyHMAC(key)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
+    const CryptoKeyHMAC& hmacKey = toCryptoKeyHMAC(key);
 
-    if (!hmacKey) {
+    CCHmacAlgorithm algorithm;
+    if (!getCommonCryptoAlgorithm(hmacParameters.hash, algorithm)) {
         ec = NOT_SUPPORTED_ERR;
         return;
     }
 
-    Vector<unsigned char> signature = calculateSignature(algorithm, hmacKey->key(), data);
+    Vector<unsigned char> signature = calculateSignature(algorithm, hmacKey.key(), data);
 
     bool result = signature.size() == expectedSignature.second && !memcmp(signature.data(), expectedSignature.first, signature.size());
 
index 8f6cd64..31168e7 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "CryptoAlgorithmAES_CBC.h"
 #include "CryptoAlgorithmHMAC.h"
+#include "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
 #include "CryptoAlgorithmSHA1.h"
 #include "CryptoAlgorithmSHA224.h"
 #include "CryptoAlgorithmSHA256.h"
@@ -42,6 +43,7 @@ void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
 {
     registerAlgorithm(CryptoAlgorithmAES_CBC::s_name, CryptoAlgorithmAES_CBC::s_identifier, CryptoAlgorithmAES_CBC::create);
     registerAlgorithm(CryptoAlgorithmHMAC::s_name, CryptoAlgorithmHMAC::s_identifier, CryptoAlgorithmHMAC::create);
+    registerAlgorithm(CryptoAlgorithmRSASSA_PKCS1_v1_5::s_name, CryptoAlgorithmRSASSA_PKCS1_v1_5::s_identifier, CryptoAlgorithmRSASSA_PKCS1_v1_5::create);
     registerAlgorithm(CryptoAlgorithmSHA1::s_name, CryptoAlgorithmSHA1::s_identifier, CryptoAlgorithmSHA1::create);
     registerAlgorithm(CryptoAlgorithmSHA224::s_name, CryptoAlgorithmSHA224::s_identifier, CryptoAlgorithmSHA224::create);
     registerAlgorithm(CryptoAlgorithmSHA256::s_name, CryptoAlgorithmSHA256::s_identifier, CryptoAlgorithmSHA256::create);
diff --git a/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp b/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp
new file mode 100644 (file)
index 0000000..4857262
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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 "CryptoKeyRSA.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include "CryptoAlgorithmDescriptionBuilder.h"
+#include "CryptoAlgorithmRegistry.h"
+#include "CryptoKeyDataRSAComponents.h"
+#include "CryptoKeyPair.h"
+#include "JSDOMPromise.h"
+#include <CommonCrypto/CommonCryptor.h>
+
+#if defined(__has_include)
+#if __has_include(<CommonCrypto/CommonRSACryptor.h>)
+#include <CommonCrypto/CommonRSACryptor.h>
+#endif
+#endif
+
+#ifndef _CC_RSACRYPTOR_H_
+enum {
+    ccRSAKeyPublic          = 0,
+    ccRSAKeyPrivate         = 1
+};
+typedef uint32_t CCRSAKeyType;
+#endif
+
+extern "C" CCCryptorStatus CCRSACryptorCreateFromData(CCRSAKeyType keyType, uint8_t *modulus, size_t modulusLength, uint8_t *exponent, size_t exponentLength, uint8_t *p, size_t pLength, uint8_t *q, size_t qLength, CCRSACryptorRef *ref);
+extern "C" CCCryptorStatus CCRSACryptorGeneratePair(size_t keysize, uint32_t e, CCRSACryptorRef *publicKey, CCRSACryptorRef *privateKey);
+extern "C" CCRSACryptorRef CCRSACryptorGetPublicKeyFromPrivateKey(CCRSACryptorRef privkey);
+extern "C" void CCRSACryptorRelease(CCRSACryptorRef key);
+extern "C" CCCryptorStatus CCRSAGetKeyComponents(CCRSACryptorRef rsaKey, uint8_t *modulus, size_t *modulusLength, uint8_t *exponent, size_t *exponentLength, uint8_t *p, size_t *pLength, uint8_t *q, size_t *qLength);
+extern "C" CCRSAKeyType CCRSAGetKeyType(CCRSACryptorRef key);
+
+namespace WebCore {
+
+CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
+    : CryptoKey(identifier, type, extractable, usage)
+    , m_platformKey(platformKey)
+    , m_restrictedToSpecificHash(false)
+{
+}
+
+PassRefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, const CryptoKeyDataRSAComponents& keyData, bool extractable, CryptoKeyUsage usage)
+{
+    if (keyData.type() == CryptoKeyDataRSAComponents::Type::Private && !keyData.hasAdditionalPrivateKeyParameters()) {
+        WTFLogAlways("Private keys without additional data are not supported");
+        return nullptr;
+    }
+    if (keyData.otherPrimeInfos().size()) {
+        // <rdar://problem/15444074> tracks adding support.
+        WTFLogAlways("Keys with more than two primes are not supported");
+        return nullptr;
+    }
+    CCRSACryptorRef cryptor;
+    CCCryptorStatus status = CCRSACryptorCreateFromData(
+        keyData.type() == CryptoKeyDataRSAComponents::Type::Public ? ccRSAKeyPublic : ccRSAKeyPrivate,
+        (uint8_t*)keyData.modulus().data(), keyData.modulus().size(),
+        (uint8_t*)keyData.exponent().data(), keyData.exponent().size(),
+        (uint8_t*)keyData.firstPrimeInfo().primeFactor.data(), keyData.firstPrimeInfo().primeFactor.size(),
+        (uint8_t*)keyData.secondPrimeInfo().primeFactor.data(), keyData.secondPrimeInfo().primeFactor.size(),
+        &cryptor);
+
+    if (status) {
+        LOG_ERROR("Couldn't create RSA key from data, error %d", status);
+        return nullptr;
+    }
+
+    return adoptRef(new CryptoKeyRSA(identifier, keyData.type() == CryptoKeyDataRSAComponents::Type::Public ? CryptoKeyType::Public : CryptoKeyType::Private, cryptor, extractable, usage));
+}
+
+CryptoKeyRSA::~CryptoKeyRSA()
+{
+    CCRSACryptorRelease(m_platformKey);
+}
+
+void CryptoKeyRSA::restrictToHash(CryptoAlgorithmIdentifier identifier)
+{
+    m_restrictedToSpecificHash = true;
+    m_hash = identifier;
+}
+
+void CryptoKeyRSA::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const
+{
+    CryptoKey::buildAlgorithmDescription(builder);
+
+    ASSERT(CCRSAGetKeyType(m_platformKey) == ccRSAKeyPublic || CCRSAGetKeyType(m_platformKey) == ccRSAKeyPrivate);
+    bool platformKeyIsPublic = CCRSAGetKeyType(m_platformKey) == ccRSAKeyPublic;
+    CCRSACryptorRef publicKey = platformKeyIsPublic ? m_platformKey : CCRSACryptorGetPublicKeyFromPrivateKey(m_platformKey);
+
+    size_t modulusLength;
+    size_t exponentLength;
+    uint8_t publicExponent[16384];
+    size_t dummy;
+    uint8_t buf[16384];
+    CCCryptorStatus status = CCRSAGetKeyComponents(publicKey, buf, &modulusLength, publicExponent, &exponentLength, buf, &dummy, buf, &dummy);
+    if (!platformKeyIsPublic) {
+        // CCRSACryptorGetPublicKeyFromPrivateKey has "Get" in the name, but its result needs to be released (see <rdar://problem/15449697>).
+        CCRSACryptorRelease(publicKey);
+    }
+    if (status) {
+        WTFLogAlways("Couldn't get RSA key components, status %d", status);
+        return;
+    }
+
+    builder.add("modulusLength", modulusLength * 8);
+
+    Vector<unsigned char> publicExponentVector;
+    publicExponentVector.append(publicExponent, exponentLength);
+    builder.add("publicExponent", publicExponentVector);
+
+    if (m_restrictedToSpecificHash) {
+        auto hashDescriptionBuilder = builder.createEmptyClone();
+        hashDescriptionBuilder->add("name", CryptoAlgorithmRegistry::shared().nameForIdentifier(m_hash));
+        builder.add("hash", *hashDescriptionBuilder);
+    }
+}
+
+static bool bigIntegerToUInt32(const Vector<char>& bigInteger, uint32_t& result)
+{
+    result = 0;
+    for (size_t i = 0; i + 4 < bigInteger.size(); ++i) {
+        if (bigInteger[i])
+            return false; // Too big to fit in 32 bits.
+    }
+
+    for (size_t i = bigInteger.size() > 4 ? bigInteger.size() - 4 : 0; i < bigInteger.size(); ++i) {
+        result <<= 8;
+        result += static_cast<unsigned char>(bigInteger[i]);
+    }
+    return true;
+}
+
+void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned modulusLength, const Vector<char>& publicExponent, bool extractable, CryptoKeyUsage usage, std::unique_ptr<PromiseWrapper> promise)
+{
+    uint32_t e;
+    if (!bigIntegerToUInt32(publicExponent, e)) {
+        // Adding support is tracked as <rdar://problem/15444034>.
+        WTFLogAlways("Public exponent is too big, not supported by CommonCrypto");
+        promise->reject(nullptr);
+        return;
+    }
+
+    PromiseWrapper* localPromise = promise.release();
+
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        CCRSACryptorRef ccPublicKey;
+        CCRSACryptorRef ccPrivateKey;
+        CCCryptorStatus status = CCRSACryptorGeneratePair(modulusLength, e, &ccPublicKey, &ccPrivateKey);
+        if (status) {
+            WTFLogAlways("Could not generate a key pair, status %d", status);
+            dispatch_async(dispatch_get_main_queue(), ^{
+                localPromise->reject(nullptr);
+                delete localPromise;
+            });
+            return;
+        }
+        dispatch_async(dispatch_get_main_queue(), ^{
+            RefPtr<CryptoKeyRSA> publicKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Public, ccPublicKey, extractable, usage);
+            RefPtr<CryptoKeyRSA> privateKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Private, ccPrivateKey, extractable, usage);
+            localPromise->fulfill(CryptoKeyPair::create(publicKey.release(), privateKey.release()));
+            delete localPromise;
+        });
+    });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
index 37d4ce3..cd23af1 100644 (file)
@@ -35,6 +35,11 @@ namespace WebCore {
 
 class CryptoAlgorithmHmacKeyParams FINAL : public CryptoAlgorithmParameters {
 public:
+    CryptoAlgorithmHmacKeyParams()
+        : hasLength(false)
+    {
+    }
+
     // The inner hash function to use.
     CryptoAlgorithmIdentifier hash;
 
diff --git a/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h b/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h
new file mode 100644 (file)
index 0000000..c0e27dd
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoAlgorithmRsaKeyGenParams_h
+#define CryptoAlgorithmRsaKeyGenParams_h
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaKeyGenParams FINAL : public CryptoAlgorithmParameters {
+public:
+    // The length, in bits, of the RSA modulus.
+    unsigned modulusLength;
+    // The RSA public exponent, encoded as BigInteger.
+    Vector<char> publicExponent;
+};
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoAlgorithmRsaKeyGenParams_h
diff --git a/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaKeyParams.h b/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaKeyParams.h
new file mode 100644 (file)
index 0000000..555a7bf
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoAlgorithmRsaSsaKeyParams_h
+#define CryptoAlgorithmRsaSsaKey
+
+#include "CryptoAlgorithmIdentifier.h"
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+// This parameters class is currently not specified in WebCrypto.
+// It is necessary to support import from JWK, which treats hash function as part of algorithm
+// identifier, so we need to remember it to compare with one passed to sign or verify functions.
+class CryptoAlgorithmRsaSsaKeyParams FINAL : public CryptoAlgorithmParameters {
+public:
+    CryptoAlgorithmRsaSsaKeyParams()
+        : hasHash(false)
+    {
+    }
+
+    // The hash algorithm to use.
+    bool hasHash;
+    CryptoAlgorithmIdentifier hash;
+};
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoAlgorithmRsaSsaParams_h
diff --git a/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaParams.h b/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaSsaParams.h
new file mode 100644 (file)
index 0000000..6e8e0fd
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef CryptoAlgorithmRsaSsaParams_h
+#define CryptoAlgorithmRsaSsaParams_h
+
+#include "CryptoAlgorithmIdentifier.h"
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaSsaParams FINAL : public CryptoAlgorithmParameters {
+public:
+    // The hash algorithm to use.
+    CryptoAlgorithmIdentifier hash;
+};
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO)
+#endif // CryptoAlgorithmRsaSsaParams_h