Source/WebCore:
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Nov 2015 04:44:02 +0000 (04:44 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Nov 2015 04:44:02 +0000 (04:44 +0000)
Allow an optional hash algorithm to be passed to generateKey for RSA keys.
https://bugs.webkit.org/show_bug.cgi?id=144938

Unreviewed initial submission.

Test: crypto/subtle/rsa-export-generated-keys.html

This changeset allows an optional hash parameter to be passed to the generate
key function for RSA type keys. Previously, there was no way to export generated
keys, as no hash function could be associated with the key (required for JWK).

The current WebCrypto API draft requires the hash function to be specified in the
algorithm object passed to generateKey (http://www.w3.org/TR/WebCryptoAPI 20.4),
however, they were made optional in this implementation to maintain compatiblity.

Patch by Scott Valentine <svalentine@ikayzo.com> on 2015-11-06

* bindings/js/JSCryptoAlgorithmDictionary.cpp:
(WebCore::getHashAlgorithm):
(WebCore::createHmacParams):
(WebCore::createHmacKeyParams):
(WebCore::createRsaKeyGenParams):
(WebCore::createRsaOaepParams):
(WebCore::createRsaSsaParams):
(WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey): Deleted.
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::readRSAKey):
* crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::generateKey):
(WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::importKey):
* crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey):
(WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey):
* crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:
(WebCore::CryptoAlgorithmRSA_OAEP::generateKey):
(WebCore::CryptoAlgorithmRSA_OAEP::importKey):
* crypto/gnutls/CryptoKeyRSAGnuTLS.cpp:
(WebCore::CryptoKeyRSA::CryptoKeyRSA):
(WebCore::CryptoKeyRSA::create):
(WebCore::CryptoKeyRSA::generatePair):
(WebCore::CryptoKeyRSA::restrictToHash): Deleted.
* crypto/keys/CryptoKeyRSA.h:
* crypto/mac/CryptoKeyRSAMac.cpp:
(WebCore::CryptoKeyRSA::CryptoKeyRSA):
(WebCore::CryptoKeyRSA::create):
(WebCore::CryptoKeyRSA::generatePair):
(WebCore::CryptoKeyRSA::restrictToHash): Deleted.
* crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h:

LayoutTests:
Adding new tests for exporting generated RSA keys.
https://bugs.webkit.org/show_bug.cgi?id=144938

Unreviewed initial submission.

Patch by Scott Valentine <svalentine@ikayzo.com> on 2015-11-06

* crypto/subtle/rsa-export-generated-keys-expected.txt: Added.
* crypto/subtle/rsa-export-generated-keys.html: Added.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/crypto/subtle/rsa-export-generated-keys-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-export-generated-keys.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSCryptoAlgorithmDictionary.cpp
Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp
Source/WebCore/crypto/gnutls/CryptoKeyRSAGnuTLS.cpp
Source/WebCore/crypto/keys/CryptoKeyRSA.h
Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp
Source/WebCore/crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h

index 8d62b99..37d9e3a 100644 (file)
@@ -1,3 +1,13 @@
+2015-11-06  Scott Valentine  <svalentine@ikayzo.com>
+
+        Adding new tests for exporting generated RSA keys.
+        https://bugs.webkit.org/show_bug.cgi?id=144938
+
+        Unreviewed initial submission.
+
+        * crypto/subtle/rsa-export-generated-keys-expected.txt: Added.
+        * crypto/subtle/rsa-export-generated-keys.html: Added.
+
 2015-11-06  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Scrolling iframe inside scrollable div does not work with trackpad
diff --git a/LayoutTests/crypto/subtle/rsa-export-generated-keys-expected.txt b/LayoutTests/crypto/subtle/rsa-export-generated-keys-expected.txt
new file mode 100644 (file)
index 0000000..544b847
--- /dev/null
@@ -0,0 +1,32 @@
+Test exporting a generated RSA keypair with hash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Generating RSA-PKCS1-v1.5 keyPair...
+PASS crypto.subtle.exportKey(null, key) threw exception TypeError: Unknown key format.
+PASS crypto.subtle.exportKey(undefined, key) threw exception TypeError: Unknown key format.
+PASS crypto.subtle.exportKey({}, key) threw exception TypeError: Unknown key format.
+PASS crypto.subtle.exportKey("", key) threw exception TypeError: Unknown key format.
+PASS crypto.subtle.exportKey("foobar", key) threw exception TypeError: Unknown key format.
+PASS key.publicKey.algorithm.hash.name is defined.
+PASS key.privateKey.algorithm.hash.name is defined.
+
+Exporting public key as JWK...
+PASS exportedJWK.kty is 'RSA'
+PASS exportedJWK.alg is 'RS256'
+PASS exportedJWK.ext is true
+PASS exportedJWK.use is undefined
+PASS exportedJWK.key_ops is ['sign', 'verify']
+
+Exporting private key as JWK...
+PASS exportedJWK.kty is 'RSA'
+PASS exportedJWK.alg is 'RS256'
+PASS exportedJWK.ext is true
+PASS exportedJWK.use is undefined
+PASS exportedJWK.key_ops is ['sign', 'verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-export-generated-keys.html b/LayoutTests/crypto/subtle/rsa-export-generated-keys.html
new file mode 100644 (file)
index 0000000..8a637c3
--- /dev/null
@@ -0,0 +1,66 @@
+<!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 exporting a generated RSA keypair with hash.");
+
+jsTestIsAsync = true;
+
+var extractable = true;
+
+var algorithm = {
+    name: "RSASSA-PKCS1-v1_5",
+    modulusLength: "4096",
+    publicExponent: new Uint8Array([1, 0, 1]), // 2^16 + 1 (65537)
+    hash: { name: "SHA-256" }
+};
+
+debug("\nGenerating RSA-PKCS1-v1.5 keyPair...");
+crypto.subtle.generateKey(algorithm, extractable, ['sign', 'verify'])
+.then(function(result) {
+    key = result;
+
+    shouldThrow('crypto.subtle.exportKey(null, key)');
+    shouldThrow('crypto.subtle.exportKey(undefined, key)');
+    shouldThrow('crypto.subtle.exportKey({}, key)');
+    shouldThrow('crypto.subtle.exportKey("", key)');
+    shouldThrow('crypto.subtle.exportKey("foobar", key)');
+    shouldBeDefined('key.publicKey.algorithm.hash.name');
+    shouldBeDefined('key.privateKey.algorithm.hash.name');
+
+    debug("\nExporting public key as JWK...");
+    return crypto.subtle.exportKey("jwk", key.publicKey);
+}).then(function(result) {
+    exportedJWK = JSON.parse(bytesToASCIIString(result));
+
+    shouldBe("exportedJWK.kty", "'RSA'");
+    shouldBe("exportedJWK.alg", "'RS256'");
+    shouldBe("exportedJWK.ext", "true");
+    shouldBe("exportedJWK.use", "undefined");
+    shouldBe("exportedJWK.key_ops", "['sign', 'verify']");
+
+    debug("\nExporting private key as JWK...");
+    return crypto.subtle.exportKey("jwk", key.privateKey);
+}).then(function(result) {
+    exportedJWK = JSON.parse(bytesToASCIIString(result));
+
+    shouldBe("exportedJWK.kty", "'RSA'");
+    shouldBe("exportedJWK.alg", "'RS256'");
+    shouldBe("exportedJWK.ext", "true");
+    shouldBe("exportedJWK.use", "undefined");
+    shouldBe("exportedJWK.key_ops", "['sign', 'verify']");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index 7caa83c..44d0642 100644 (file)
@@ -1,3 +1,52 @@
+2015-11-06  Scott Valentine  <svalentine@ikayzo.com>
+
+        Allow an optional hash algorithm to be passed to generateKey for RSA keys.
+        https://bugs.webkit.org/show_bug.cgi?id=144938
+
+        Unreviewed initial submission.
+
+        Test: crypto/subtle/rsa-export-generated-keys.html
+
+        This changeset allows an optional hash parameter to be passed to the generate
+        key function for RSA type keys. Previously, there was no way to export generated
+        keys, as no hash function could be associated with the key (required for JWK).
+
+        The current WebCrypto API draft requires the hash function to be specified in the
+        algorithm object passed to generateKey (http://www.w3.org/TR/WebCryptoAPI 20.4),
+        however, they were made optional in this implementation to maintain compatiblity.
+
+        * bindings/js/JSCryptoAlgorithmDictionary.cpp:
+        (WebCore::getHashAlgorithm):
+        (WebCore::createHmacParams):
+        (WebCore::createHmacKeyParams):
+        (WebCore::createRsaKeyGenParams):
+        (WebCore::createRsaOaepParams):
+        (WebCore::createRsaSsaParams):
+        (WebCore::JSCryptoAlgorithmDictionary::createParametersForImportKey): Deleted.
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::readRSAKey):
+        * crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp:
+        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::generateKey):
+        (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::importKey):
+        * crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp:
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey):
+        (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey):
+        * crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp:
+        (WebCore::CryptoAlgorithmRSA_OAEP::generateKey):
+        (WebCore::CryptoAlgorithmRSA_OAEP::importKey):
+        * crypto/gnutls/CryptoKeyRSAGnuTLS.cpp:
+        (WebCore::CryptoKeyRSA::CryptoKeyRSA):
+        (WebCore::CryptoKeyRSA::create):
+        (WebCore::CryptoKeyRSA::generatePair):
+        (WebCore::CryptoKeyRSA::restrictToHash): Deleted.
+        * crypto/keys/CryptoKeyRSA.h:
+        * crypto/mac/CryptoKeyRSAMac.cpp:
+        (WebCore::CryptoKeyRSA::CryptoKeyRSA):
+        (WebCore::CryptoKeyRSA::create):
+        (WebCore::CryptoKeyRSA::generatePair):
+        (WebCore::CryptoKeyRSA::restrictToHash): Deleted.
+        * crypto/parameters/CryptoAlgorithmRsaKeyGenParams.h:
+
 2015-11-06  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Scrolling iframe inside scrollable div does not work with trackpad
index 4ae6ae5..f01f3ea 100644 (file)
@@ -46,6 +46,11 @@ using namespace JSC;
 
 namespace WebCore {
 
+enum class HashRequirement {
+    Optional,
+    Required, 
+};
+
 bool JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(ExecState* exec, JSValue value, CryptoAlgorithmIdentifier& algorithmIdentifier)
 {
     // typedef (Algorithm or DOMString) AlgorithmIdentifier;
@@ -98,7 +103,7 @@ static JSValue getProperty(ExecState* exec, JSObject* object, const char* name)
     return jsUndefined();
 }
 
-static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier& result)
+static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier& result, HashRequirement isRequired)
 {
     // FXIME: Teach JSDictionary how to return JSValues, and use that to get hash element value.
 
@@ -113,7 +118,8 @@ static bool getHashAlgorithm(JSDictionary& dictionary, CryptoAlgorithmIdentifier
         return false;
 
     if (hash.isUndefinedOrNull()) {
-        setDOMException(exec, NOT_SUPPORTED_ERR);
+        if (isRequired == HashRequirement::Required)
+            setDOMException(exec, NOT_SUPPORTED_ERR);
         return false;
     }
 
@@ -177,7 +183,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacParams(ExecState* ex
     JSDictionary jsDictionary(exec, value.getObject());
     auto result = std::make_unique<CryptoAlgorithmHmacParams>();
 
-    if (!getHashAlgorithm(jsDictionary, result->hash)) {
+    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(exec->hadException());
         return nullptr;
     }
@@ -195,7 +201,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createHmacKeyParams(ExecState*
     JSDictionary jsDictionary(exec, value.getObject());
     auto result = std::make_unique<CryptoAlgorithmHmacKeyParams>();
 
-    if (!getHashAlgorithm(jsDictionary, result->hash)) {
+    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(exec->hadException());
         return nullptr;
     }
@@ -214,6 +220,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecStat
         return nullptr;
     }
 
+    JSDictionary jsDictionary(exec, value.getObject());
     auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>();
 
     JSValue modulusLengthValue = getProperty(exec, value.getObject(), "modulusLength");
@@ -236,6 +243,8 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecStat
     }
     result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());
 
+    result->hasHash = getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Optional); 
+
     return WTF::move(result);
 }
 
@@ -255,7 +264,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState*
     JSDictionary jsDictionary(exec, value.getObject());
     auto result = std::make_unique<CryptoAlgorithmRsaOaepParams>();
 
-    if (!getHashAlgorithm(jsDictionary, result->hash)) {
+    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(exec->hadException());
         return nullptr;
     }
@@ -289,7 +298,7 @@ static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState*
     JSDictionary jsDictionary(exec, value.getObject());
     auto result = std::make_unique<CryptoAlgorithmRsaSsaParams>();
 
-    if (!getHashAlgorithm(jsDictionary, result->hash)) {
+    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
         ASSERT(exec->hadException());
         return nullptr;
     }
@@ -597,11 +606,8 @@ std::unique_ptr<CryptoAlgorithmParameters> JSCryptoAlgorithmDictionary::createPa
 {
     switch (algorithm) {
     case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
-        return std::make_unique<CryptoAlgorithmParameters>();
     case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
-        return createRsaKeyParamsWithHash(exec, value);
     case CryptoAlgorithmIdentifier::RSA_PSS:
-        return std::make_unique<CryptoAlgorithmParameters>();
     case CryptoAlgorithmIdentifier::RSA_OAEP:
         return createRsaKeyParamsWithHash(exec, value);
     case CryptoAlgorithmIdentifier::ECDSA:
index 835057b..a120c92 100644 (file)
@@ -193,7 +193,7 @@ bool JSCryptoKeySerializationJWK::reconcileAlgorithm(std::unique_ptr<CryptoAlgor
         parameters = createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier::SHA_512);
     } else if (m_jwkAlgorithmName == "RSA1_5") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5);
-        parameters = std::make_unique<CryptoAlgorithmParameters>();
+        parameters = std::make_unique<CryptoAlgorithmRsaKeyParamsWithHash>();
     } else if (m_jwkAlgorithmName == "RSA-OAEP") {
         algorithm = algorithmRegisty.create(CryptoAlgorithmIdentifier::RSA_OAEP);
         parameters = createRSAKeyParametersWithHash(CryptoAlgorithmIdentifier::SHA_1);
index 8210762..adb07b2 100644 (file)
@@ -2023,9 +2023,7 @@ private:
 
         if (type == CryptoKeyAsymmetricTypeSubtag::Public) {
             auto keyData = CryptoKeyDataRSAComponents::createPublic(modulus, exponent);
-            auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
-            if (isRestrictedToHash)
-                key->restrictToHash(hash);
+            auto key = CryptoKeyRSA::create(algorithm, hash, isRestrictedToHash, *keyData, extractable, usages);
             result = WTF::move(key);
             return true;
         }
@@ -2040,9 +2038,7 @@ private:
 
         if (!primeCount) {
             auto keyData = CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
-            auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
-            if (isRestrictedToHash)
-                key->restrictToHash(hash);
+            auto key = CryptoKeyRSA::create(algorithm, hash, isRestrictedToHash, *keyData, extractable, usages);
             result = WTF::move(key);
             return true;
         }
@@ -2074,9 +2070,7 @@ private:
         }
 
         auto keyData = CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
-        auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages);
-        if (isRestrictedToHash)
-            key->restrictToHash(hash);
+        auto key = CryptoKeyRSA::create(algorithm, hash, isRestrictedToHash, *keyData, extractable, usages);
         result = WTF::move(key);
         return true;
     }
index 7a977e8..476b951 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(SUBTLE_CRYPTO)
 
 #include "CryptoAlgorithmRsaKeyGenParams.h"
+#include "CryptoAlgorithmRsaKeyParamsWithHash.h"
 #include "CryptoKeyDataRSAComponents.h"
 #include "CryptoKeyRSA.h"
 #include "ExceptionCode.h"
@@ -92,14 +93,15 @@ void CryptoAlgorithmRSAES_PKCS1_v1_5::generateKey(const CryptoAlgorithmParameter
         callback(nullptr, &pair);
     };
 
-    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
+    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, rsaParameters.hash, rsaParameters.hasHash, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
 }
 
-void CryptoAlgorithmRSAES_PKCS1_v1_5::importKey(const CryptoAlgorithmParameters&, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, KeyCallback&& callback, VoidCallback&& failureCallback, ExceptionCode&)
+void CryptoAlgorithmRSAES_PKCS1_v1_5::importKey(const CryptoAlgorithmParameters& parameters, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, KeyCallback&& callback, VoidCallback&& failureCallback, ExceptionCode&)
 {
+    const CryptoAlgorithmRsaKeyParamsWithHash& rsaParameters = downcast<CryptoAlgorithmRsaKeyParamsWithHash>(parameters);
     const CryptoKeyDataRSAComponents& rsaComponents = downcast<CryptoKeyDataRSAComponents>(keyData);
 
-    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, rsaComponents, extractable, usage);
+    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5, rsaParameters.hash, rsaParameters.hasHash, rsaComponents, extractable, usage);
     if (!result) {
         failureCallback();
         return;
index cbcb95b..2fbacf5 100644 (file)
@@ -101,7 +101,7 @@ void CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey(const CryptoAlgorithmParamete
         callback(nullptr, &pair);
     };
 
-    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
+    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaParameters.hash, rsaParameters.hasHash, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
 }
 
 void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(const CryptoAlgorithmParameters& parameters, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, KeyCallback&& callback, VoidCallback&& failureCallback, ExceptionCode&)
@@ -109,15 +109,12 @@ void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(const CryptoAlgorithmParameters
     const CryptoAlgorithmRsaKeyParamsWithHash& rsaKeyParameters = downcast<CryptoAlgorithmRsaKeyParamsWithHash>(parameters);
     const CryptoKeyDataRSAComponents& rsaComponents = downcast<CryptoKeyDataRSAComponents>(keyData);
 
-    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaComponents, extractable, usage);
+    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaKeyParameters.hash, rsaKeyParameters.hasHash, rsaComponents, extractable, usage);
     if (!result) {
         failureCallback();
         return;
     }
 
-    if (rsaKeyParameters.hasHash)
-        result->restrictToHash(rsaKeyParameters.hash);
-
     callback(*result);
 }
 
index 7f72dd6..7f819d0 100644 (file)
@@ -101,7 +101,7 @@ void CryptoAlgorithmRSA_OAEP::generateKey(const CryptoAlgorithmParameters& param
         callback(nullptr, &pair);
     };
 
-    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_OAEP, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
+    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_OAEP, rsaParameters.hash, rsaParameters.hasHash, rsaParameters.modulusLength, rsaParameters.publicExponent, extractable, usages, WTF::move(keyPairCallback), WTF::move(failureCallback));
 }
 
 void CryptoAlgorithmRSA_OAEP::importKey(const CryptoAlgorithmParameters& parameters, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsage usage, KeyCallback&& callback, VoidCallback&& failureCallback, ExceptionCode&)
@@ -109,15 +109,12 @@ void CryptoAlgorithmRSA_OAEP::importKey(const CryptoAlgorithmParameters& paramet
     const CryptoAlgorithmRsaKeyParamsWithHash& rsaKeyParameters = downcast<CryptoAlgorithmRsaKeyParamsWithHash>(parameters);
     const CryptoKeyDataRSAComponents& rsaComponents = downcast<CryptoKeyDataRSAComponents>(keyData);
 
-    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSA_OAEP, rsaComponents, extractable, usage);
+    RefPtr<CryptoKeyRSA> result = CryptoKeyRSA::create(CryptoAlgorithmIdentifier::RSA_OAEP, rsaKeyParameters.hash, rsaKeyParameters.hasHash, rsaComponents, extractable, usage);
     if (!result) {
         failureCallback();
         return;
     }
 
-    if (rsaKeyParameters.hasHash)
-        result->restrictToHash(rsaKeyParameters.hash);
-
     callback(*result);
 }
 
index f48224b..d7045a5 100644 (file)
@@ -39,18 +39,21 @@ namespace WebCore {
 struct _PlatformRSAKeyGnuTLS {
 };
 
-CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
+CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
     : CryptoKey(identifier, type, extractable, usage)
     , m_platformKey(platformKey)
-    , m_restrictedToSpecificHash(false)
+    , m_restrictedToSpecificHash(hasHash)
+    , m_hash(hash)
 {
     notImplemented();
 }
 
-RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, const CryptoKeyDataRSAComponents& keyData, bool extractable, CryptoKeyUsage usage)
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyDataRSAComponents& keyData, bool extractable, CryptoKeyUsage usage)
 {
     notImplemented();
     UNUSED_PARAM(identifier);
+    UNUSED_PARAM(hash);
+    UNUSED_PARAM(hasHash);
     UNUSED_PARAM(keyData);
     UNUSED_PARAM(extractable);
     UNUSED_PARAM(usage);
@@ -63,12 +66,6 @@ CryptoKeyRSA::~CryptoKeyRSA()
     notImplemented();
 }
 
-void CryptoKeyRSA::restrictToHash(CryptoAlgorithmIdentifier identifier)
-{
-    m_restrictedToSpecificHash = true;
-    m_hash = identifier;
-}
-
 bool CryptoKeyRSA::isRestrictedToHash(CryptoAlgorithmIdentifier& identifier) const
 {
     if (!m_restrictedToSpecificHash)
@@ -98,12 +95,14 @@ std::unique_ptr<CryptoKeyData> CryptoKeyRSA::exportData() const
     return nullptr;
 }
 
-void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, KeyPairCallback callback, VoidCallback failureCallback)
+void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, KeyPairCallback callback, VoidCallback failureCallback)
 {
     notImplemented();
     failureCallback();
 
     UNUSED_PARAM(algorithm);
+    UNUSED_PARAM(hash);
+    UNUSED_PARAM(hasHash);
     UNUSED_PARAM(modulusLength);
     UNUSED_PARAM(publicExponent);
     UNUSED_PARAM(extractable);
index 98e0107..17d24a9 100644 (file)
@@ -49,26 +49,25 @@ class PromiseWrapper;
 
 class CryptoKeyRSA final : public CryptoKey {
 public:
-    static Ref<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
+    static Ref<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
     {
-        return adoptRef(*new CryptoKeyRSA(identifier, type, platformKey, extractable, usage));
+        return adoptRef(*new CryptoKeyRSA(identifier, hash, hasHash, type, platformKey, extractable, usage));
     }
-    static RefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, const CryptoKeyDataRSAComponents&, bool extractable, CryptoKeyUsage);
+    static RefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyDataRSAComponents&, bool extractable, CryptoKeyUsage);
     virtual ~CryptoKeyRSA();
 
-    void restrictToHash(CryptoAlgorithmIdentifier);
     bool isRestrictedToHash(CryptoAlgorithmIdentifier&) const;
 
     size_t keySizeInBits() const;
 
     typedef std::function<void(CryptoKeyPair&)> KeyPairCallback;
     typedef std::function<void()> VoidCallback;
-    static void generatePair(CryptoAlgorithmIdentifier, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage, KeyPairCallback, VoidCallback failureCallback);
+    static void generatePair(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage, KeyPairCallback, VoidCallback failureCallback);
 
     PlatformRSAKey platformKey() const { return m_platformKey; }
 
 private:
-    CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsage);
+    CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsage);
 
     virtual CryptoKeyClass keyClass() const override { return CryptoKeyClass::RSA; }
 
index dae0bec..ae5ae1f 100644 (file)
@@ -96,14 +96,15 @@ static CCCryptorStatus getPrivateKeyComponents(CCRSACryptorRef rsaKey, Vector<ui
     return status;
 }
 
-CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
+CryptoKeyRSA::CryptoKeyRSA(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage)
     : CryptoKey(identifier, type, extractable, usage)
     , m_platformKey(platformKey)
-    , m_restrictedToSpecificHash(false)
+    , m_restrictedToSpecificHash(hasHash)
+    , m_hash(hash)
 {
 }
 
-RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, const CryptoKeyDataRSAComponents& keyData, bool extractable, CryptoKeyUsage usage)
+RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyDataRSAComponents& keyData, bool extractable, CryptoKeyUsage usage)
 {
     if (keyData.type() == CryptoKeyDataRSAComponents::Type::Private && !keyData.hasAdditionalPrivateKeyParameters()) {
         // <rdar://problem/15452324> tracks adding support.
@@ -129,7 +130,7 @@ RefPtr<CryptoKeyRSA> CryptoKeyRSA::create(CryptoAlgorithmIdentifier identifier,
         return nullptr;
     }
 
-    return adoptRef(new CryptoKeyRSA(identifier, keyData.type() == CryptoKeyDataRSAComponents::Type::Public ? CryptoKeyType::Public : CryptoKeyType::Private, cryptor, extractable, usage));
+    return adoptRef(new CryptoKeyRSA(identifier, hash, hasHash, keyData.type() == CryptoKeyDataRSAComponents::Type::Public ? CryptoKeyType::Public : CryptoKeyType::Private, cryptor, extractable, usage));
 }
 
 CryptoKeyRSA::~CryptoKeyRSA()
@@ -137,12 +138,6 @@ CryptoKeyRSA::~CryptoKeyRSA()
     CCRSACryptorRelease(m_platformKey);
 }
 
-void CryptoKeyRSA::restrictToHash(CryptoAlgorithmIdentifier identifier)
-{
-    m_restrictedToSpecificHash = true;
-    m_hash = identifier;
-}
-
 bool CryptoKeyRSA::isRestrictedToHash(CryptoAlgorithmIdentifier& identifier) const
 {
     if (!m_restrictedToSpecificHash)
@@ -239,7 +234,7 @@ static bool bigIntegerToUInt32(const Vector<uint8_t>& bigInteger, uint32_t& resu
     return true;
 }
 
-void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, KeyPairCallback callback, VoidCallback failureCallback)
+void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, KeyPairCallback callback, VoidCallback failureCallback)
 {
     uint32_t e;
     if (!bigIntegerToUInt32(publicExponent, e)) {
@@ -267,8 +262,8 @@ void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned mo
             return;
         }
         callOnWebThreadOrDispatchAsyncOnMainThread(^{
-            RefPtr<CryptoKeyRSA> publicKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Public, ccPublicKey, true, usage);
-            RefPtr<CryptoKeyRSA> privateKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Private, ccPrivateKey, extractable, usage);
+            RefPtr<CryptoKeyRSA> publicKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Public, ccPublicKey, true, usage);
+            RefPtr<CryptoKeyRSA> privateKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Private, ccPrivateKey, extractable, usage);
             (*localCallback)(CryptoKeyPair::create(publicKey.release(), privateKey.release()));
             delete localCallback;
             delete localFailureCallback;
index 41d235e..f607dad 100644 (file)
@@ -35,10 +35,17 @@ namespace WebCore {
 
 class CryptoAlgorithmRsaKeyGenParams final : public CryptoAlgorithmParameters {
 public:
+    CryptoAlgorithmRsaKeyGenParams()
+        : hasHash(false)
+    {
+    }
     // The length, in bits, of the RSA modulus.
     unsigned modulusLength;
     // The RSA public exponent, encoded as BigInteger.
     Vector<uint8_t> publicExponent;
+    // The hash algorith identifier
+    bool hasHash;
+    CryptoAlgorithmIdentifier hash;
 
     virtual Class parametersClass() const override { return Class::RsaKeyGenParams; }
 };