[WebCrypto] Support RSA-PSS
authorjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 May 2017 00:33:23 +0000 (00:33 +0000)
committerjiewen_tan@apple.com <jiewen_tan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 May 2017 00:33:23 +0000 (00:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170869
<rdar://problem/31640672>

Reviewed by Brent Fulgham.

Source/WebCore:

This patch implements RSA-PSS according to the spec: https://www.w3.org/TR/WebCryptoAPI/#rsa-pss.
Supported operations include sign, verify, generateKey, importKey and exportKey.

Tests: crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html
       crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html
       crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html
       crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html
       crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html
       crypto/subtle/rsa-pss-generate-export-key-pkcs8.html
       crypto/subtle/rsa-pss-generate-export-key-spki.html
       crypto/subtle/rsa-pss-generate-key.html
       crypto/subtle/rsa-pss-import-jwk-private-key.html
       crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html
       crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html
       crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html
       crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html
       crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html
       crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html
       crypto/subtle/rsa-pss-import-key-sign-large-salt.html
       crypto/subtle/rsa-pss-import-key-sign.html
       crypto/subtle/rsa-pss-import-key-verify.html
       crypto/subtle/rsa-pss-import-pkcs8-key.html
       crypto/subtle/rsa-pss-import-spki-key-empty-usages.html
       crypto/subtle/rsa-pss-import-spki-key.html
       crypto/workers/subtle/rsa-pss-import-key-sign.html
       crypto/workers/subtle/rsa-pss-import-key-verify.html

* CMakeLists.txt:
* DerivedSources.make:
* PlatformGTK.cmake:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSSubtleCryptoCustom.cpp:
(WebCore::normalizeCryptoAlgorithmParameters):
* crypto/CryptoAlgorithmParameters.h:
* crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp: Added.
(WebCore::CryptoAlgorithmRSA_PSS::create):
(WebCore::CryptoAlgorithmRSA_PSS::identifier):
(WebCore::CryptoAlgorithmRSA_PSS::sign):
(WebCore::CryptoAlgorithmRSA_PSS::verify):
(WebCore::CryptoAlgorithmRSA_PSS::generateKey):
(WebCore::CryptoAlgorithmRSA_PSS::importKey):
(WebCore::CryptoAlgorithmRSA_PSS::exportKey):
* crypto/algorithms/CryptoAlgorithmRSA_PSS.h: Added.
* crypto/mac/CryptoAlgorithmECDSAMac.cpp:
(WebCore::cryptoDigestAlgorithm): Deleted.
Extract function cryptoDigestAlgorithm to a separate file.
* crypto/mac/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp:
(WebCore::cryptoDigestAlgorithm): Deleted.
Extract function cryptoDigestAlgorithm to a separate file.
* crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp: Added.
(WebCore::signRSA_PSS):
(WebCore::verifyRSA_PSS):
(WebCore::CryptoAlgorithmRSA_PSS::platformSign):
(WebCore::CryptoAlgorithmRSA_PSS::platformVerify):
* crypto/mac/CryptoAlgorithmRegistryMac.cpp:
(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):
* crypto/mac/CryptoDigestAlgorithm.h: Added.
(WebCore::cryptoDigestAlgorithm):
Have cryptoDigestAlgorithm in a separate file.
* crypto/parameters/CryptoAlgorithmRsaPssParams.h: Added.
* crypto/parameters/RsaPssParams.idl: Added.

Source/WTF:

* wtf/Platform.h:
Add a flag to enable RSA-PSS in the future.

LayoutTests:

* TestExpectations:
Skip tests related to RSA-PSS for now.
* crypto/subtle/rsa-generate-key-malformed-parameters-expected.txt:
* crypto/subtle/rsa-generate-key-malformed-parameters.html:
* crypto/subtle/rsa-import-key-malformed-parameters-expected.txt:
* crypto/subtle/rsa-import-key-malformed-parameters.html:
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha1-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha224-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha256-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha384-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha512-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-pkcs8-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-pkcs8.html: Added.
* crypto/subtle/rsa-pss-generate-export-key-spki-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-export-key-spki.html: Added.
* crypto/subtle/rsa-pss-generate-key-expected.txt: Added.
* crypto/subtle/rsa-pss-generate-key.html: Added.
* crypto/subtle/rsa-pss-import-jwk-private-key-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-private-key.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha1-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha224-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha256-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha384-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha512-expected.txt: Added.
* crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html: Added.
* crypto/subtle/rsa-pss-import-key-sign-expected.txt: Added.
* crypto/subtle/rsa-pss-import-key-sign-large-salt-expected.txt: Added.
* crypto/subtle/rsa-pss-import-key-sign-large-salt.html: Added.
* crypto/subtle/rsa-pss-import-key-sign.html: Added.
* crypto/subtle/rsa-pss-import-key-verify-expected.txt: Added.
* crypto/subtle/rsa-pss-import-key-verify.html: Added.
* crypto/subtle/rsa-pss-import-pkcs8-key-expected.txt: Added.
* crypto/subtle/rsa-pss-import-pkcs8-key.html: Added.
* crypto/subtle/rsa-pss-import-spki-key-empty-usages-expected.txt: Added.
* crypto/subtle/rsa-pss-import-spki-key-empty-usages.html: Added.
* crypto/subtle/rsa-pss-import-spki-key-expected.txt: Added.
* crypto/subtle/rsa-pss-import-spki-key.html: Added.
* crypto/workers/subtle/resources/rsa-pss-import-key-sign.js: Added.
* crypto/workers/subtle/resources/rsa-pss-import-key-verify.js: Added.
* crypto/workers/subtle/rsa-pss-import-key-sign-expected.txt: Added.
* crypto/workers/subtle/rsa-pss-import-key-sign.html: Added.
* crypto/workers/subtle/rsa-pss-import-key-verify-expected.txt: Added.
* crypto/workers/subtle/rsa-pss-import-key-verify.html: Added.

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

72 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/crypto/subtle/rsa-generate-key-malformed-parameters-expected.txt
LayoutTests/crypto/subtle/rsa-generate-key-malformed-parameters.html
LayoutTests/crypto/subtle/rsa-import-key-malformed-parameters-expected.txt
LayoutTests/crypto/subtle/rsa-import-key-malformed-parameters.html
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-key-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-generate-key.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-sign-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-sign.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-verify-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-key-verify.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages.html [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-spki-key-expected.txt [new file with mode: 0644]
LayoutTests/crypto/subtle/rsa-pss-import-spki-key.html [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-sign.js [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-verify.js [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign-expected.txt [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign.html [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify-expected.txt [new file with mode: 0644]
LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify.html [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources.make
Source/WebCore/PlatformGTK.cmake
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp
Source/WebCore/crypto/CryptoAlgorithmParameters.h
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp [new file with mode: 0644]
Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.h [new file with mode: 0644]
Source/WebCore/crypto/mac/CryptoAlgorithmECDSAMac.cpp
Source/WebCore/crypto/mac/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp
Source/WebCore/crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp [new file with mode: 0644]
Source/WebCore/crypto/mac/CryptoAlgorithmRegistryMac.cpp
Source/WebCore/crypto/mac/CryptoDigestAlgorithm.h [new file with mode: 0644]
Source/WebCore/crypto/parameters/CryptoAlgorithmRsaPssParams.h [new file with mode: 0644]
Source/WebCore/crypto/parameters/RsaPssParams.idl [new file with mode: 0644]

index c9c6bc4..c73c82a 100644 (file)
@@ -1,3 +1,66 @@
+2017-05-22  Jiewen Tan  <jiewen_tan@apple.com>
+
+        [WebCrypto] Support RSA-PSS
+        https://bugs.webkit.org/show_bug.cgi?id=170869
+        <rdar://problem/31640672>
+
+        Reviewed by Brent Fulgham.
+
+        * TestExpectations:
+        Skip tests related to RSA-PSS for now.
+        * crypto/subtle/rsa-generate-key-malformed-parameters-expected.txt:
+        * crypto/subtle/rsa-generate-key-malformed-parameters.html:
+        * crypto/subtle/rsa-import-key-malformed-parameters-expected.txt:
+        * crypto/subtle/rsa-import-key-malformed-parameters.html:
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha1-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha224-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha256-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha384-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha512-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-pkcs8-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-pkcs8.html: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-spki-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-export-key-spki.html: Added.
+        * crypto/subtle/rsa-pss-generate-key-expected.txt: Added.
+        * crypto/subtle/rsa-pss-generate-key.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-private-key-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-private-key.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha1-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha224-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha256-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha384-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha512-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html: Added.
+        * crypto/subtle/rsa-pss-import-key-sign-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-key-sign-large-salt-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-key-sign-large-salt.html: Added.
+        * crypto/subtle/rsa-pss-import-key-sign.html: Added.
+        * crypto/subtle/rsa-pss-import-key-verify-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-key-verify.html: Added.
+        * crypto/subtle/rsa-pss-import-pkcs8-key-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-pkcs8-key.html: Added.
+        * crypto/subtle/rsa-pss-import-spki-key-empty-usages-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-spki-key-empty-usages.html: Added.
+        * crypto/subtle/rsa-pss-import-spki-key-expected.txt: Added.
+        * crypto/subtle/rsa-pss-import-spki-key.html: Added.
+        * crypto/workers/subtle/resources/rsa-pss-import-key-sign.js: Added.
+        * crypto/workers/subtle/resources/rsa-pss-import-key-verify.js: Added.
+        * crypto/workers/subtle/rsa-pss-import-key-sign-expected.txt: Added.
+        * crypto/workers/subtle/rsa-pss-import-key-sign.html: Added.
+        * crypto/workers/subtle/rsa-pss-import-key-verify-expected.txt: Added.
+        * crypto/workers/subtle/rsa-pss-import-key-verify.html: Added.
+
 2017-05-23  Chris Dumez  <cdumez@apple.com>
 
         Some async tests ignore jsTestIsAsync when ported from js-test-pre.js / js-test-post.js to js-test.js
index 74b29f2..10dd422 100644 (file)
@@ -1039,8 +1039,31 @@ imported/w3c/web-platform-tests/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-
 imported/w3c/web-platform-tests/WebCryptoAPI/import_export/rsa_importKey.worker.html [ Slow ]
 imported/w3c/web-platform-tests/WebCryptoAPI/import_export/test_rsa_importKey.https.html [ Slow ]
 
-# WebCryptoAPI tests that we haven't fully supported yet
+# WebCryptoAPI features that haven't been enabled for current OS
 imported/w3c/web-platform-tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.worker.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-pkcs8.html [ Skip ]
+crypto/subtle/rsa-pss-generate-export-key-spki.html [ Skip ]
+crypto/subtle/rsa-pss-generate-key.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-private-key.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html [ Skip ]
+crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html [ Skip ]
+crypto/subtle/rsa-pss-import-key-sign-large-salt.html [ Skip ]
+crypto/subtle/rsa-pss-import-key-sign.html [ Skip ]
+crypto/subtle/rsa-pss-import-key-verify.html [ Skip ]
+crypto/subtle/rsa-pss-import-pkcs8-key.html [ Skip ]
+crypto/subtle/rsa-pss-import-spki-key-empty-usages.html [ Skip ]
+crypto/subtle/rsa-pss-import-spki-key.html [ Skip ]
+crypto/workers/subtle/rsa-pss-import-key-sign.html [ Skip ]
+crypto/workers/subtle/rsa-pss-import-key-verify.html [ Skip ]
 
 # WebCryptoAPI superset tests
 imported/w3c/web-platform-tests/WebCryptoAPI/generateKey/successes.worker.html [ Skip ]
index 1659002..2f95d25 100644 (file)
@@ -33,6 +33,12 @@ PASS crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExp
 PASS crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["verify"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveBits"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["encrypt"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["decrypt"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveKey"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveBits"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["wrapKey"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["unwrapKey"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.generateKey({name: "RSASSA-PKCS1-v1_5", modulusLength: 0, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["sign", "verify"]) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
 PASS successfullyParsed is true
 
index bfb4d65..70d483b 100644 (file)
@@ -49,6 +49,12 @@ shouldReject('crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048,
 shouldReject('crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["verify"])');
 shouldReject('crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveKey"])');
 shouldReject('crypto.subtle.generateKey({name: "RSA-OAEP", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveBits"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["encrypt"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["decrypt"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveKey"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["deriveBits"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["wrapKey"])');
+shouldReject('crypto.subtle.generateKey({name: "RSA-PSS", modulusLength: 2048, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["unwrapKey"])');
 // modulusLength = 0
 shouldReject('crypto.subtle.generateKey({name: "RSASSA-PKCS1-v1_5", modulusLength: 0, publicExponent: publicExponent, hash: "sha-1"}, extractable, ["sign", "verify"])').then(finishJSTest);
 </script>
index 8fe790f..866e7f1 100644 (file)
@@ -12,12 +12,17 @@ PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {name: "RSA
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["decrypt", "unwrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "sig"}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "enc"}, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "sig"}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "enc"}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "foo"}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "RS224"}, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
@@ -40,6 +45,16 @@ PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "R
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-256"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-384"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-512"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS224"}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS256"}, {name: "RSA-PSS", hash: "sha-224"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS384"}, {name: "RSA-PSS", hash: "sha-256"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS512"}, {name: "RSA-PSS", hash: "sha-384"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS1"}, {name: "RSA-PSS", hash: "sha-512"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-224"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-256"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-384"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-512"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.importKey("jwk", {kty: "oct", n: n, e: e}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, key_ops: ["sign", "verify"]}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, key_ops: [ ]}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
@@ -58,9 +73,11 @@ PASS crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d, p: "", q: q,
 PASS crypto.subtle.importKey("spki", spkiKey, "RSAES-PKCS1-v1_5", extractable, ["decrypt"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("spki", spkiKey, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["sign"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("spki", spkiKey, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["decrypt", "unwrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey("spki", spkiKey, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.importKey("pkcs8", pkcs8Key, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
 PASS crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"]) rejected promise  with SyntaxError (DOM Exception 12): A required parameter was missing or out-of-range.
+PASS crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]) rejected promise  with NotSupportedError (DOM Exception 9): The operation is not supported..
 PASS crypto.subtle.importKey("spki", malformedKey0, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("spki", malformedKey1, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
 PASS crypto.subtle.importKey("spki", malformedKey2, "RSAES-PKCS1-v1_5", extractable, ["encrypt"]) rejected promise  with DataError (DOM Exception 30): Data provided to an operation does not meet requirements.
index 321f7b9..22e7bf1 100644 (file)
@@ -42,6 +42,9 @@ shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {n
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["decrypt", "unwrapKey"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
 // Jwk: Wrong use
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "sig"}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
@@ -49,6 +52,8 @@ shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "enc"
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "sig"}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: "enc"}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, use: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
 // Jwk: Wrong alg
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "foo"}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
@@ -72,6 +77,16 @@ shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""},
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-256"}, extractable, ["encrypt", "wrapKey"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-384"}, extractable, ["encrypt", "wrapKey"])');
 shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-OAEP", hash: "sha-512"}, extractable, ["encrypt", "wrapKey"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS224"}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS256"}, {name: "RSA-PSS", hash: "sha-224"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS384"}, {name: "RSA-PSS", hash: "sha-256"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS512"}, {name: "RSA-PSS", hash: "sha-384"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: "PS1"}, {name: "RSA-PSS", hash: "sha-512"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-224"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-256"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-384"}, extractable, ["verify"])');
+shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, alg: ""}, {name: "RSA-PSS", hash: "sha-512"}, extractable, ["verify"])');
 // Jwk: Wrong kty
 shouldReject('crypto.subtle.importKey("jwk", {kty: "oct", n: n, e: e}, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
 // Jwk: Wrong key_ops
@@ -98,10 +113,12 @@ shouldReject('crypto.subtle.importKey("jwk", {kty: "RSA", n: n, e: e, d: d, p: "
 shouldReject('crypto.subtle.importKey("spki", spkiKey, "RSAES-PKCS1-v1_5", extractable, ["decrypt"])');
 shouldReject('crypto.subtle.importKey("spki", spkiKey, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["sign"])');
 shouldReject('crypto.subtle.importKey("spki", spkiKey, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["decrypt", "unwrapKey"])');
+shouldReject('crypto.subtle.importKey("spki", spkiKey, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"])');
 // Pkcs8: Wrong usages
 shouldReject('crypto.subtle.importKey("pkcs8", pkcs8Key, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
 shouldReject('crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSASSA-PKCS1-v1_5", hash: "sha-1"}, extractable, ["verify"])');
 shouldReject('crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-OAEP", hash: "sha-1"}, extractable, ["encrypt", "wrapKey"])');
+shouldReject('crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"])');
 // Malformed Key for Spki and Pkcs8
 shouldReject('crypto.subtle.importKey("spki", malformedKey0, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
 shouldReject('crypto.subtle.importKey("spki", malformedKey1, "RSAES-PKCS1-v1_5", extractable, ["encrypt"])');
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1-expected.txt
new file mode 100644 (file)
index 0000000..482cd75
--- /dev/null
@@ -0,0 +1,25 @@
+Test exporting a SHA-1 RSA-PSS key pair with JWK format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.kty is 'RSA'
+PASS publicKey.key_ops is ['verify']
+PASS publicKey.alg is 'PS1'
+PASS publicKey.ext is true
+PASS Base64URL.parse(publicKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(publicKey.e)) is '010001'
+Exporting the private key...
+PASS privateKey.kty is 'RSA'
+PASS privateKey.key_ops is ['sign']
+PASS privateKey.alg is 'PS1'
+PASS privateKey.ext is true
+PASS Base64URL.parse(privateKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(privateKey.e)) is '010001'
+PASS privateKey.oth is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html
new file mode 100644 (file)
index 0000000..bdedafb
--- /dev/null
@@ -0,0 +1,60 @@
+<!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 SHA-1 RSA-PSS key pair with JWK format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-1",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("jwk", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.kty", "'RSA'");
+    shouldBe("publicKey.key_ops", "['verify']");
+    shouldBe("publicKey.alg", "'PS1'");
+    shouldBe("publicKey.ext", "true");
+    shouldBe("Base64URL.parse(publicKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(publicKey.e))", "'010001'");
+
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("jwk", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.kty", "'RSA'");
+    shouldBe("privateKey.key_ops", "['sign']");
+    shouldBe("privateKey.alg", "'PS1'");
+    shouldBe("privateKey.ext", "true");
+    shouldBe("Base64URL.parse(privateKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(privateKey.e))", "'010001'");
+    shouldBeUndefined("privateKey.oth");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224-expected.txt
new file mode 100644 (file)
index 0000000..cb66104
--- /dev/null
@@ -0,0 +1,25 @@
+Test exporting a SHA-224 RSA-PSS key pair with JWK format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.kty is 'RSA'
+PASS publicKey.key_ops is ['verify']
+PASS publicKey.alg is 'PS224'
+PASS publicKey.ext is true
+PASS Base64URL.parse(publicKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(publicKey.e)) is '010001'
+Exporting the private key...
+PASS privateKey.kty is 'RSA'
+PASS privateKey.key_ops is ['sign']
+PASS privateKey.alg is 'PS224'
+PASS privateKey.ext is true
+PASS Base64URL.parse(privateKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(privateKey.e)) is '010001'
+PASS privateKey.oth is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html
new file mode 100644 (file)
index 0000000..955feed
--- /dev/null
@@ -0,0 +1,60 @@
+<!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 SHA-224 RSA-PSS key pair with JWK format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-224",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("jwk", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.kty", "'RSA'");
+    shouldBe("publicKey.key_ops", "['verify']");
+    shouldBe("publicKey.alg", "'PS224'");
+    shouldBe("publicKey.ext", "true");
+    shouldBe("Base64URL.parse(publicKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(publicKey.e))", "'010001'");
+
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("jwk", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.kty", "'RSA'");
+    shouldBe("privateKey.key_ops", "['sign']");
+    shouldBe("privateKey.alg", "'PS224'");
+    shouldBe("privateKey.ext", "true");
+    shouldBe("Base64URL.parse(privateKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(privateKey.e))", "'010001'");
+    shouldBeUndefined("privateKey.oth");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256-expected.txt
new file mode 100644 (file)
index 0000000..86388f0
--- /dev/null
@@ -0,0 +1,25 @@
+Test exporting a SHA-256 RSA-PSS key pair with JWK format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.kty is 'RSA'
+PASS publicKey.key_ops is ['verify']
+PASS publicKey.alg is 'PS256'
+PASS publicKey.ext is true
+PASS Base64URL.parse(publicKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(publicKey.e)) is '010001'
+Exporting the private key...
+PASS privateKey.kty is 'RSA'
+PASS privateKey.key_ops is ['sign']
+PASS privateKey.alg is 'PS256'
+PASS privateKey.ext is true
+PASS Base64URL.parse(privateKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(privateKey.e)) is '010001'
+PASS privateKey.oth is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html
new file mode 100644 (file)
index 0000000..10a8fac
--- /dev/null
@@ -0,0 +1,60 @@
+<!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 SHA-256 RSA-PSS key pair with JWK format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-256",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("jwk", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.kty", "'RSA'");
+    shouldBe("publicKey.key_ops", "['verify']");
+    shouldBe("publicKey.alg", "'PS256'");
+    shouldBe("publicKey.ext", "true");
+    shouldBe("Base64URL.parse(publicKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(publicKey.e))", "'010001'");
+
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("jwk", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.kty", "'RSA'");
+    shouldBe("privateKey.key_ops", "['sign']");
+    shouldBe("privateKey.alg", "'PS256'");
+    shouldBe("privateKey.ext", "true");
+    shouldBe("Base64URL.parse(privateKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(privateKey.e))", "'010001'");
+    shouldBeUndefined("privateKey.oth");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384-expected.txt
new file mode 100644 (file)
index 0000000..c117270
--- /dev/null
@@ -0,0 +1,25 @@
+Test exporting a SHA-384 RSA-PSS key pair with JWK format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.kty is 'RSA'
+PASS publicKey.key_ops is ['verify']
+PASS publicKey.alg is 'PS384'
+PASS publicKey.ext is true
+PASS Base64URL.parse(publicKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(publicKey.e)) is '010001'
+Exporting the private key...
+PASS privateKey.kty is 'RSA'
+PASS privateKey.key_ops is ['sign']
+PASS privateKey.alg is 'PS384'
+PASS privateKey.ext is true
+PASS Base64URL.parse(privateKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(privateKey.e)) is '010001'
+PASS privateKey.oth is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html
new file mode 100644 (file)
index 0000000..4bfc7e8
--- /dev/null
@@ -0,0 +1,60 @@
+<!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 SHA-384 RSA-PSS key pair with JWK format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-384",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("jwk", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.kty", "'RSA'");
+    shouldBe("publicKey.key_ops", "['verify']");
+    shouldBe("publicKey.alg", "'PS384'");
+    shouldBe("publicKey.ext", "true");
+    shouldBe("Base64URL.parse(publicKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(publicKey.e))", "'010001'");
+
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("jwk", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.kty", "'RSA'");
+    shouldBe("privateKey.key_ops", "['sign']");
+    shouldBe("privateKey.alg", "'PS384'");
+    shouldBe("privateKey.ext", "true");
+    shouldBe("Base64URL.parse(privateKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(privateKey.e))", "'010001'");
+    shouldBeUndefined("privateKey.oth");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512-expected.txt
new file mode 100644 (file)
index 0000000..d5206b8
--- /dev/null
@@ -0,0 +1,25 @@
+Test exporting a SHA-512 RSA-PSS key pair with JWK format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.kty is 'RSA'
+PASS publicKey.key_ops is ['verify']
+PASS publicKey.alg is 'PS512'
+PASS publicKey.ext is true
+PASS Base64URL.parse(publicKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(publicKey.e)) is '010001'
+Exporting the private key...
+PASS privateKey.kty is 'RSA'
+PASS privateKey.key_ops is ['sign']
+PASS privateKey.alg is 'PS512'
+PASS privateKey.ext is true
+PASS Base64URL.parse(privateKey.n).byteLength is 256
+PASS bytesToHexString(Base64URL.parse(privateKey.e)) is '010001'
+PASS privateKey.oth is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html
new file mode 100644 (file)
index 0000000..bb42fdc
--- /dev/null
@@ -0,0 +1,60 @@
+<!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 SHA-512 RSA-PSS key pair with JWK format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-512",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("jwk", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.kty", "'RSA'");
+    shouldBe("publicKey.key_ops", "['verify']");
+    shouldBe("publicKey.alg", "'PS512'");
+    shouldBe("publicKey.ext", "true");
+    shouldBe("Base64URL.parse(publicKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(publicKey.e))", "'010001'");
+
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("jwk", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.kty", "'RSA'");
+    shouldBe("privateKey.key_ops", "['sign']");
+    shouldBe("privateKey.alg", "'PS512'");
+    shouldBe("privateKey.ext", "true");
+    shouldBe("Base64URL.parse(privateKey.n).byteLength", "256");
+    shouldBe("bytesToHexString(Base64URL.parse(privateKey.e))", "'010001'");
+    shouldBeUndefined("privateKey.oth");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8-expected.txt
new file mode 100644 (file)
index 0000000..a15b638
--- /dev/null
@@ -0,0 +1,12 @@
+Test exporting a RSA-PSS private key with PKCS8 format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the private key...
+PASS privateKey is an instance of ArrayBuffer
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-pkcs8.html
new file mode 100644 (file)
index 0000000..f250eb1
--- /dev/null
@@ -0,0 +1,42 @@
+<!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 RSA-PSS private key with PKCS8 format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-1",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the private key...");
+    return crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
+}).then(function(result) {
+    privateKey = result;
+
+    shouldBeType("privateKey", "ArrayBuffer");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki-expected.txt
new file mode 100644 (file)
index 0000000..b6a4324
--- /dev/null
@@ -0,0 +1,12 @@
+Test exporting a RSA-PSS public key with SPKI format.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+Exporting the public key...
+PASS publicKey.byteLength is 294
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki.html b/LayoutTests/crypto/subtle/rsa-pss-generate-export-key-spki.html
new file mode 100644 (file)
index 0000000..4d986a7
--- /dev/null
@@ -0,0 +1,42 @@
+<!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 RSA-PSS public key with SPKI format.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-1",
+};
+var extractable = true;
+
+var keyPair;
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, extractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    debug("Exporting the public key...");
+    return crypto.subtle.exportKey("spki", keyPair.publicKey);
+}).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.byteLength", "294");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-key-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-generate-key-expected.txt
new file mode 100644 (file)
index 0000000..c00d012
--- /dev/null
@@ -0,0 +1,25 @@
+Test generating an RSA key using RSA-PSS algorithm.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Generating a key pair...
+PASS keyPair.toString() is '[object Object]'
+PASS keyPair.publicKey.type is 'public'
+PASS keyPair.publicKey.extractable is true
+PASS keyPair.publicKey.algorithm.name is 'RSA-PSS'
+PASS keyPair.publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(keyPair.publicKey.algorithm.publicExponent) is '010001'
+PASS keyPair.publicKey.algorithm.hash.name is 'SHA-1'
+PASS keyPair.publicKey.usages is ['verify']
+PASS keyPair.privateKey.type is 'private'
+PASS keyPair.privateKey.extractable is false
+PASS keyPair.privateKey.algorithm.name is 'RSA-PSS'
+PASS keyPair.privateKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(keyPair.privateKey.algorithm.publicExponent) is '010001'
+PASS keyPair.privateKey.algorithm.hash.name is 'SHA-1'
+PASS keyPair.privateKey.usages is ['sign']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-generate-key.html b/LayoutTests/crypto/subtle/rsa-pss-generate-key.html
new file mode 100644 (file)
index 0000000..5742dc5
--- /dev/null
@@ -0,0 +1,50 @@
+<!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 using RSA-PSS algorithm.");
+
+jsTestIsAsync = true;
+
+var algorithmKeyGen = {
+    name: "RSA-PSS",
+    // RsaKeyGenParams
+    modulusLength: 2048,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
+    hash: "sha-1",
+};
+var nonExtractable = false;
+
+debug("Generating a key pair...");
+crypto.subtle.generateKey(algorithmKeyGen, nonExtractable, ["sign", "verify"]).then(function(result) {
+    keyPair = result;
+    shouldBe("keyPair.toString()", "'[object Object]'");
+    shouldBe("keyPair.publicKey.type", "'public'");
+    shouldBe("keyPair.publicKey.extractable", "true");
+    shouldBe("keyPair.publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("keyPair.publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(keyPair.publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("keyPair.publicKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("keyPair.publicKey.usages", "['verify']");
+    shouldBe("keyPair.privateKey.type", "'private'");
+    shouldBe("keyPair.privateKey.extractable", "false");
+    shouldBe("keyPair.privateKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("keyPair.privateKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(keyPair.privateKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("keyPair.privateKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("keyPair.privateKey.usages", "['sign']");
+
+    finishJSTest();
+});
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key-expected.txt
new file mode 100644 (file)
index 0000000..c9a198c
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS private key with SHA-1
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS privateKey.toString() is '[object CryptoKey]'
+PASS privateKey.type is 'private'
+PASS privateKey.extractable is true
+PASS privateKey.algorithm.name is 'RSA-PSS'
+PASS privateKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(privateKey.algorithm.publicExponent) is '010001'
+PASS privateKey.algorithm.hash.name is 'SHA-1'
+PASS privateKey.usages is ['sign']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-private-key.html
new file mode 100644 (file)
index 0000000..ff1d5a4
--- /dev/null
@@ -0,0 +1,53 @@
+<!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 a JWK RSA-PSS private key with SHA-1");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["sign"],
+    ext: true,
+    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",
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-1"}, extractable, ["sign"]).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.toString()", "'[object CryptoKey]'");
+    shouldBe("privateKey.type", "'private'");
+    shouldBe("privateKey.extractable", "true");
+    shouldBe("privateKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("privateKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(privateKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("privateKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("privateKey.usages", "['sign']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages-expected.txt
new file mode 100644 (file)
index 0000000..e0f5ae9
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-1 and empty usages
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-1'
+PASS publicKey.usages is [ ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html
new file mode 100644 (file)
index 0000000..6d779fa
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-1 and empty usages");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-1"}, extractable, [ ]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("publicKey.usages", "[ ]");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1-expected.txt
new file mode 100644 (file)
index 0000000..ba8c84b
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-1
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-1'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html
new file mode 100644 (file)
index 0000000..93c2012
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-1");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-1"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224-expected.txt
new file mode 100644 (file)
index 0000000..aacae50
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-224
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-224'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html
new file mode 100644 (file)
index 0000000..57f158b
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-224");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS224",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-224"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-224'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256-expected.txt
new file mode 100644 (file)
index 0000000..8763caf
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-256
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-256'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html
new file mode 100644 (file)
index 0000000..98e985e
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-256");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS256",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-256"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-256'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384-expected.txt
new file mode 100644 (file)
index 0000000..22b4889
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-384
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-384'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html
new file mode 100644 (file)
index 0000000..0f4c64e
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-384");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS384",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-384"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-384'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512-expected.txt
new file mode 100644 (file)
index 0000000..1797320
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a JWK RSA-PSS public key with SHA-512
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-512'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html b/LayoutTests/crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html
new file mode 100644 (file)
index 0000000..080d980
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 a JWK RSA-PSS public key with SHA-512");
+
+jsTestIsAsync = true;
+
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS512",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB"
+};
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("jwk", jwkKey, {name: "RSA-PSS", hash: "SHA-512"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-512'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-expected.txt
new file mode 100644 (file)
index 0000000..6b58a63
--- /dev/null
@@ -0,0 +1,10 @@
+Test signing with RSA-PSS SHA-1 using an imported key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS signature.byteLength is 256
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt-expected.txt
new file mode 100644 (file)
index 0000000..e398b6f
--- /dev/null
@@ -0,0 +1,14 @@
+Test RSA-PSS signing using an imported key with salt length larger than hash size
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS crypto.subtle.sign({ name: "RSA-PSS", saltLength: 21 }, key, text) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS crypto.subtle.sign({ name: "RSA-PSS", saltLength: 29 }, key, text) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS crypto.subtle.sign({ name: "RSA-PSS", saltLength: 33 }, key, text) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS crypto.subtle.sign({ name: "RSA-PSS", saltLength: 49 }, key, text) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS crypto.subtle.sign({ name: "RSA-PSS", saltLength: 65 }, key, text) rejected promise  with OperationError (DOM Exception 34): The operation failed for an operation-specific reason.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt.html b/LayoutTests/crypto/subtle/rsa-pss-import-key-sign-large-salt.html
new file mode 100644 (file)
index 0000000..9db9db5
--- /dev/null
@@ -0,0 +1,49 @@
+<!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 RSA-PSS signing using an imported key with salt length larger than hash size");
+
+jsTestIsAsync = true;
+
+var text = asciiToUint8Array("Hello, World!");
+var pkcs8Key = hexStringToUint8Array("308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ca6ee8ec62b6a02e187b70c19ca15a13c386a470ee8816c7340a270f96f905511f93362f8f7aae3e60394dac34cb29ea5f540d6ef80b1df7155b66a2d6d6e44092bcbafbf69b061b3f4d927060c81d0fa07d22f481ff503c0581ffa444f57345204ddf0a93a225979c61aeb9686557f7632002e165430452868d010d505e3ccfed7315432a298a9b6d1a6ede98ee746c2c8bd22f5495cee563e2db24f1e33d91ced83af1baac754dba4ddba430f6cf3d4ac7edb0bf69891140854e8700056a7ef6d06ed5a605a05e74ecb3b246ce9cb310b39b00c707af3a637862e3d2914013de212ff09a36db84d99b8d610d0cfd36a4411dbf1b62e06ebff1bee50f040ca502030100010282010024706483309db925b3087d5a8cac4abfa60195963289d2b7d6f940e0c08760daa279685695583b074560eb47655570dd1c7dcfd13adb1d70bdaa6f463eaffdf455b59d5eff9c16344f67d2456256834cadd1f8b9d4b0b5aba83e275b55826d567323315401113dfd158c4bdc5a1b6c033f17a30d19a23fa3ef4e70730a157c928b1c7840a34401d19daab52cfa9b424cc8e1084254ca597304be22547b7221e875bf1fdca2386ba1e855d5e0bcaba03376bfd73de8513c07ab0e67cb3554dc8c8f7a67d231f99a2b653ad471ee2f8bd3b8fad51b02f807d131b6b71ab17e45a5faf161ce3b919d96b5e78e9e4e1202d6398a954def4c1980da1fcc30d56167e102818100ee24b92668d38465fdd9a2262e64be56846be561e4cfbcedc82496a3190b549636923d61c3e5a2d40cc6d2c46a3e89ac23eb44ac40c777147e3e49a80bd382bae06e284f1cc553f89d78f0c7bf20fd3a33ee598ce2caf61e3f5457cd228ff03fe009f10952206bf248e161d17950c6655af75b097bbda1b909038d4d752cd11d02818100d99cb65195a399f9a3aca1ef1593592992e7d91cc028b713ec5b661b9976fcffdb086f523f042699cb910321fe7b67a27dd4a72822e6fbb98d005280721efc32d889d431d2737c92a4f34d4885c7a9c6244e081a1264a283d07744b752a68ebb6fbff3492a039e3e3a0cc5b94537582a7d11cc6b8678e4c338671f96be029b2902818100a1a2a7509ca1c4217db4f3cbba7d827b32921134ea9add7efef36692f8f2a9ccf2e93b645a1448fa6859a2c0d1e3f489b42f8182f0ccf1d425039df6c360224139074bb0b6b47094343ddc1f97688ab7b07bbca8555eb0c242f5ba4a6f8506ea33e44b87aa087b7c0d5f7c8733325216853192c6d30818f68059bad4b20d633902818034b3bf7402c99c80d922f614f124be735320d3742315b94119fd08bda66d2ad8cc333ec2ac8054d8ea74344e0753dbc57eb401c7b6ac3a4ab5db5e1fbd83c3908ce0d4833c74bbb6c83c247b6beaef330d97d85e7815e7460536dd6d8896cdfa9715e5d5d2570dfc041313cfcaf39c66ade3a19e68f2de7469349071f192b00102818060a8271f45161d8ecf62c3ac5f0fa8539b6d86a35123aafcc37541e2d5e5b62715777db0ef75f3cdf67506b8fcad6baed862eaf88fa1f280f42736b69a41ea7a3fea31ce62aa0563c85df1d9b02b83839c4ab9453e420c5c401cce979f6fb7b6ac12baf1e9140546eed24e92e383b8f2d37b3e4410844d235c7175112e751ee0");
+var extractable = true;
+
+crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"]).then(function(result) {
+    key = result;
+    return shouldReject('crypto.subtle.sign({ name: "RSA-PSS", saltLength: 21 }, key, text)');
+}).then(function(result) {
+    return crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-224"}, extractable, ["sign"]);
+}).then(function(result) {
+    key = result;
+    return shouldReject('crypto.subtle.sign({ name: "RSA-PSS", saltLength: 29 }, key, text)');
+}).then(function(result) {
+    return crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-256"}, extractable, ["sign"]);
+}).then(function(result) {
+    key = result;
+    return shouldReject('crypto.subtle.sign({ name: "RSA-PSS", saltLength: 33 }, key, text)');
+}).then(function(result) {
+    return crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-384"}, extractable, ["sign"]);
+}).then(function(result) {
+    key = result;
+    return shouldReject('crypto.subtle.sign({ name: "RSA-PSS", saltLength: 49 }, key, text)');
+}).then(function(result) {
+    return crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-512"}, extractable, ["sign"]);
+}).then(function(result) {
+    key = result;
+    return shouldReject('crypto.subtle.sign({ name: "RSA-PSS", saltLength: 65 }, key, text)');
+}).then(finishJSTest);
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-sign.html b/LayoutTests/crypto/subtle/rsa-pss-import-key-sign.html
new file mode 100644 (file)
index 0000000..bd60779
--- /dev/null
@@ -0,0 +1,52 @@
+<!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 signing with RSA-PSS SHA-1 using an imported key");
+
+jsTestIsAsync = true;
+
+var extractable = false;
+var text = asciiToUint8Array("Hello, World!");
+var rsaImportParams = {
+    name: "RSA-PSS",
+    hash: "SHA-1",
+}
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["sign"],
+    ext: true,
+    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",
+};
+
+crypto.subtle.importKey("jwk", jwkKey, rsaImportParams, extractable, ["sign"]).then(function(key) {
+    return crypto.subtle.sign({ name: "RSA-PSS", saltLength: 16 }, key, text);
+}).then(function(result) {
+    signature = result;
+
+    shouldBe("signature.byteLength", "256");
+
+    finishJSTest();
+}, failAndFinishJSTest);
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-verify-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-key-verify-expected.txt
new file mode 100644 (file)
index 0000000..d3979f0
--- /dev/null
@@ -0,0 +1,10 @@
+Test verification with RSA-PSS SHA-1 using an imported key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS verified is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-key-verify.html b/LayoutTests/crypto/subtle/rsa-pss-import-key-verify.html
new file mode 100644 (file)
index 0000000..97abebb
--- /dev/null
@@ -0,0 +1,47 @@
+<!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 verification with RSA-PSS SHA-1 using an imported key");
+
+jsTestIsAsync = true;
+
+var extractable = false;
+var text = asciiToUint8Array("Hello, World!");
+var rsaImportParams = {
+    name: "RSA-PSS",
+    hash: "SHA-1",
+}
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB",
+};
+var signature = hexStringToUint8Array("3119faeed99f4ef0516f9f8e8429bf9bd98aba7d0a89a8ca9331513094f4a2ab9cfdc003d618ef10254263b5631355d8a5a0bb082584f33db8da8a1f9283c2ee70c821d0feac3d7e63b0c612fb9aef003000a423b650e80858b2eb8b4cea8f61822344f816dc1f325c305e3d547f6b19f172703b47639d41c84dce94b33b58a3a9b6c0b6a5ce43087cc0ed2a06e5c525cdaa80d856c1e4316a792ad4af795936594c35c985c11c3eb2bb37013d2e3ce67a74664ef58bbf0b0f16e2b68d29180006b6a17abd95c444aac723ac7213d57bea714882c6c8b139ef007d6157dea01d8d2573aef64ac912958aeae7fa1b59633c8526220d7db6a8e362774243156a01");
+
+crypto.subtle.importKey("jwk", jwkKey, rsaImportParams, extractable, ["verify"]).then(function(key) {
+    return crypto.subtle.verify({ name: "RSA-PSS", saltLength: 16 }, key, signature, text);
+}).then(function(result) {
+    verified = result;
+
+    shouldBeTrue("verified");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key-expected.txt
new file mode 100644 (file)
index 0000000..b418d45
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a PKCS8 RSA-PSS key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS privateKey.toString() is '[object CryptoKey]'
+PASS privateKey.type is 'private'
+PASS privateKey.extractable is true
+PASS privateKey.algorithm.name is 'RSA-PSS'
+PASS privateKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(privateKey.algorithm.publicExponent) is '010001'
+PASS privateKey.algorithm.hash.name is 'SHA-1'
+PASS privateKey.usages is ['sign']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key.html b/LayoutTests/crypto/subtle/rsa-pss-import-pkcs8-key.html
new file mode 100644 (file)
index 0000000..3b51141
--- /dev/null
@@ -0,0 +1,39 @@
+<!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 a PKCS8 RSA-PSS key");
+
+jsTestIsAsync = true;
+
+var pkcs8Key = hexStringToUint8Array("308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ca6ee8ec62b6a02e187b70c19ca15a13c386a470ee8816c7340a270f96f905511f93362f8f7aae3e60394dac34cb29ea5f540d6ef80b1df7155b66a2d6d6e44092bcbafbf69b061b3f4d927060c81d0fa07d22f481ff503c0581ffa444f57345204ddf0a93a225979c61aeb9686557f7632002e165430452868d010d505e3ccfed7315432a298a9b6d1a6ede98ee746c2c8bd22f5495cee563e2db24f1e33d91ced83af1baac754dba4ddba430f6cf3d4ac7edb0bf69891140854e8700056a7ef6d06ed5a605a05e74ecb3b246ce9cb310b39b00c707af3a637862e3d2914013de212ff09a36db84d99b8d610d0cfd36a4411dbf1b62e06ebff1bee50f040ca502030100010282010024706483309db925b3087d5a8cac4abfa60195963289d2b7d6f940e0c08760daa279685695583b074560eb47655570dd1c7dcfd13adb1d70bdaa6f463eaffdf455b59d5eff9c16344f67d2456256834cadd1f8b9d4b0b5aba83e275b55826d567323315401113dfd158c4bdc5a1b6c033f17a30d19a23fa3ef4e70730a157c928b1c7840a34401d19daab52cfa9b424cc8e1084254ca597304be22547b7221e875bf1fdca2386ba1e855d5e0bcaba03376bfd73de8513c07ab0e67cb3554dc8c8f7a67d231f99a2b653ad471ee2f8bd3b8fad51b02f807d131b6b71ab17e45a5faf161ce3b919d96b5e78e9e4e1202d6398a954def4c1980da1fcc30d56167e102818100ee24b92668d38465fdd9a2262e64be56846be561e4cfbcedc82496a3190b549636923d61c3e5a2d40cc6d2c46a3e89ac23eb44ac40c777147e3e49a80bd382bae06e284f1cc553f89d78f0c7bf20fd3a33ee598ce2caf61e3f5457cd228ff03fe009f10952206bf248e161d17950c6655af75b097bbda1b909038d4d752cd11d02818100d99cb65195a399f9a3aca1ef1593592992e7d91cc028b713ec5b661b9976fcffdb086f523f042699cb910321fe7b67a27dd4a72822e6fbb98d005280721efc32d889d431d2737c92a4f34d4885c7a9c6244e081a1264a283d07744b752a68ebb6fbff3492a039e3e3a0cc5b94537582a7d11cc6b8678e4c338671f96be029b2902818100a1a2a7509ca1c4217db4f3cbba7d827b32921134ea9add7efef36692f8f2a9ccf2e93b645a1448fa6859a2c0d1e3f489b42f8182f0ccf1d425039df6c360224139074bb0b6b47094343ddc1f97688ab7b07bbca8555eb0c242f5ba4a6f8506ea33e44b87aa087b7c0d5f7c8733325216853192c6d30818f68059bad4b20d633902818034b3bf7402c99c80d922f614f124be735320d3742315b94119fd08bda66d2ad8cc333ec2ac8054d8ea74344e0753dbc57eb401c7b6ac3a4ab5db5e1fbd83c3908ce0d4833c74bbb6c83c247b6beaef330d97d85e7815e7460536dd6d8896cdfa9715e5d5d2570dfc041313cfcaf39c66ade3a19e68f2de7469349071f192b00102818060a8271f45161d8ecf62c3ac5f0fa8539b6d86a35123aafcc37541e2d5e5b62715777db0ef75f3cdf67506b8fcad6baed862eaf88fa1f280f42736b69a41ea7a3fea31ce62aa0563c85df1d9b02b83839c4ab9453e420c5c401cce979f6fb7b6ac12baf1e9140546eed24e92e383b8f2d37b3e4410844d235c7175112e751ee0");
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("pkcs8", pkcs8Key, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["sign"]).then(function(result) {
+    privateKey = result;
+
+    shouldBe("privateKey.toString()", "'[object CryptoKey]'");
+    shouldBe("privateKey.type", "'private'");
+    shouldBe("privateKey.extractable", "true");
+    shouldBe("privateKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("privateKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(privateKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("privateKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("privateKey.usages", "['sign']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages-expected.txt
new file mode 100644 (file)
index 0000000..926b7b1
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a SPKI RSA-PSS key with empty usages
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-1'
+PASS publicKey.usages is [ ]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages.html b/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-empty-usages.html
new file mode 100644 (file)
index 0000000..7a7b73a
--- /dev/null
@@ -0,0 +1,40 @@
+<!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 a SPKI RSA-PSS key with empty usages");
+
+jsTestIsAsync = true;
+
+// Generated from OpenSSL
+var spkiKey = Base64URL.parse("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCjRCtFwvSNYMZ07u5SxARxglJl75T7bUZXFsDVxHkMhpNC2RaN4jWE5bwYUDMeD2fVmxhpaUQn/6AbFLh6gHxtwrCfc7rIo/SfDdGd3GkRlXK5xXwGuM6MvP9nuZHaarIyArRFh2U2UZxFlVsKI0pSHo6n58W1fPZ1syOoVEZ/WYE6gLhMMwfpeAm97mro7mekRdMULOV/mR5Ul3CHm9Zt93Dc8GpnPA8bhLiB0VNyGTEMa06nJul4gj1sjxLDoUvZY2EWq7oUUnfLBUYMfiqK0kQcW94wvBrIq2DQUApLyTTbaAOY46TLwX6c8LtubJriYKTC5a9Bb0/7ovTWB0wIDAQAB");
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("spki", spkiKey, {name: "RSA-PSS", hash: "sha-1"}, extractable, [ ]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("publicKey.usages", "[ ]");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-expected.txt b/LayoutTests/crypto/subtle/rsa-pss-import-spki-key-expected.txt
new file mode 100644 (file)
index 0000000..6bdd87b
--- /dev/null
@@ -0,0 +1,18 @@
+Test importing a SPKI RSA-PSS key
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Importing a key...
+PASS publicKey.toString() is '[object CryptoKey]'
+PASS publicKey.type is 'public'
+PASS publicKey.extractable is true
+PASS publicKey.algorithm.name is 'RSA-PSS'
+PASS publicKey.algorithm.modulusLength is 2048
+PASS bytesToHexString(publicKey.algorithm.publicExponent) is '010001'
+PASS publicKey.algorithm.hash.name is 'SHA-1'
+PASS publicKey.usages is ['verify']
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/subtle/rsa-pss-import-spki-key.html b/LayoutTests/crypto/subtle/rsa-pss-import-spki-key.html
new file mode 100644 (file)
index 0000000..a143f15
--- /dev/null
@@ -0,0 +1,40 @@
+<!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 a SPKI RSA-PSS key");
+
+jsTestIsAsync = true;
+
+// Generated from OpenSSL
+var spkiKey = Base64URL.parse("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCjRCtFwvSNYMZ07u5SxARxglJl75T7bUZXFsDVxHkMhpNC2RaN4jWE5bwYUDMeD2fVmxhpaUQn/6AbFLh6gHxtwrCfc7rIo/SfDdGd3GkRlXK5xXwGuM6MvP9nuZHaarIyArRFh2U2UZxFlVsKI0pSHo6n58W1fPZ1syOoVEZ/WYE6gLhMMwfpeAm97mro7mekRdMULOV/mR5Ul3CHm9Zt93Dc8GpnPA8bhLiB0VNyGTEMa06nJul4gj1sjxLDoUvZY2EWq7oUUnfLBUYMfiqK0kQcW94wvBrIq2DQUApLyTTbaAOY46TLwX6c8LtubJriYKTC5a9Bb0/7ovTWB0wIDAQAB");
+var extractable = true;
+
+debug("Importing a key...");
+crypto.subtle.importKey("spki", spkiKey, {name: "RSA-PSS", hash: "sha-1"}, extractable, ["verify"]).then(function(result) {
+    publicKey = result;
+
+    shouldBe("publicKey.toString()", "'[object CryptoKey]'");
+    shouldBe("publicKey.type", "'public'");
+    shouldBe("publicKey.extractable", "true");
+    shouldBe("publicKey.algorithm.name", "'RSA-PSS'");
+    shouldBe("publicKey.algorithm.modulusLength", "2048");
+    shouldBe("bytesToHexString(publicKey.algorithm.publicExponent)", "'010001'");
+    shouldBe("publicKey.algorithm.hash.name", "'SHA-1'");
+    shouldBe("publicKey.usages", "['verify']");
+
+    finishJSTest();
+});
+
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-sign.js b/LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-sign.js
new file mode 100644 (file)
index 0000000..43eb31a
--- /dev/null
@@ -0,0 +1,38 @@
+importScripts('../../../../resources/js-test-pre.js');
+importScripts('../../../resources/common.js');
+
+description("Test signing with RSA-PSS SHA-1 using an imported key in workers");
+
+jsTestIsAsync = true;
+
+var extractable = false;
+var text = asciiToUint8Array("Hello, World!");
+var rsaImportParams = {
+    name: "RSA-PSS",
+    hash: "SHA-1",
+}
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["sign"],
+    ext: true,
+    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",
+};
+
+crypto.subtle.importKey("jwk", jwkKey, rsaImportParams, extractable, ["sign"]).then(function(key) {
+    return crypto.subtle.sign({ name: "RSA-PSS", saltLength: 16 }, key, text);
+}).then(function(result) {
+    signature = result;
+
+    shouldBe("signature.byteLength", "256");
+
+    finishJSTest();
+}, failAndFinishJSTest);
diff --git a/LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-verify.js b/LayoutTests/crypto/workers/subtle/resources/rsa-pss-import-key-verify.js
new file mode 100644 (file)
index 0000000..88d150b
--- /dev/null
@@ -0,0 +1,33 @@
+importScripts('../../../../resources/js-test-pre.js');
+importScripts('../../../resources/common.js');
+
+description("Test verification with RSA-PSS SHA-1 using an imported key in workers");
+
+jsTestIsAsync = true;
+
+var extractable = false;
+var text = asciiToUint8Array("Hello, World!");
+var rsaImportParams = {
+    name: "RSA-PSS",
+    hash: "SHA-1",
+}
+var jwkKey = {
+    kty: "RSA",
+    alg: "PS1",
+    use: "sig",
+    key_ops: ["verify"],
+    ext: true,
+    n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw",
+    e: "AQAB",
+};
+var signature = hexStringToUint8Array("3119faeed99f4ef0516f9f8e8429bf9bd98aba7d0a89a8ca9331513094f4a2ab9cfdc003d618ef10254263b5631355d8a5a0bb082584f33db8da8a1f9283c2ee70c821d0feac3d7e63b0c612fb9aef003000a423b650e80858b2eb8b4cea8f61822344f816dc1f325c305e3d547f6b19f172703b47639d41c84dce94b33b58a3a9b6c0b6a5ce43087cc0ed2a06e5c525cdaa80d856c1e4316a792ad4af795936594c35c985c11c3eb2bb37013d2e3ce67a74664ef58bbf0b0f16e2b68d29180006b6a17abd95c444aac723ac7213d57bea714882c6c8b139ef007d6157dea01d8d2573aef64ac912958aeae7fa1b59633c8526220d7db6a8e362774243156a01");
+
+crypto.subtle.importKey("jwk", jwkKey, rsaImportParams, extractable, ["verify"]).then(function(key) {
+    return crypto.subtle.verify({ name: "RSA-PSS", saltLength: 16 }, key, signature, text);
+}).then(function(result) {
+    verified = result;
+
+    shouldBeTrue("verified");
+
+    finishJSTest();
+});
diff --git a/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign-expected.txt b/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign-expected.txt
new file mode 100644 (file)
index 0000000..6c1fd2e
--- /dev/null
@@ -0,0 +1,11 @@
+[Worker] Test signing with RSA-PSS SHA-1 using an imported key in workers
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Starting worker: resources/rsa-pss-import-key-sign.js
+PASS [Worker] signature.byteLength is 256
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign.html b/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-sign.html
new file mode 100644 (file)
index 0000000..05d591a
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+    <script>
+        worker = startWorker('resources/rsa-pss-import-key-sign.js');
+    </script>
+    <script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify-expected.txt b/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify-expected.txt
new file mode 100644 (file)
index 0000000..de64c0f
--- /dev/null
@@ -0,0 +1,11 @@
+[Worker] Test verification with RSA-PSS SHA-1 using an imported key in workers
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Starting worker: resources/rsa-pss-import-key-verify.js
+PASS [Worker] verified is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify.html b/LayoutTests/crypto/workers/subtle/rsa-pss-import-key-verify.html
new file mode 100644 (file)
index 0000000..d2144f5
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+    <script>
+        worker = startWorker('resources/rsa-pss-import-key-verify.js');
+    </script>
+    <script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index db6421a..a09604c 100644 (file)
@@ -1,3 +1,14 @@
+2017-05-22  Jiewen Tan  <jiewen_tan@apple.com>
+
+        [WebCrypto] Support RSA-PSS
+        https://bugs.webkit.org/show_bug.cgi?id=170869
+        <rdar://problem/31640672>
+
+        Reviewed by Brent Fulgham.
+
+        * wtf/Platform.h:
+        Add a flag to enable RSA-PSS in the future.
+
 2017-05-23  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Remove dead ENABLE(FONT_LOAD_EVENTS) code
index 1c4f26a..ae1b9d8 100644 (file)
 #define USE_LIBWEBRTC 1
 #endif
 
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
+#define HAVE_RSA_PSS 1
+#endif
+
 #endif /* WTF_Platform_h */
index 7907fdb..e11040d 100644 (file)
@@ -359,6 +359,7 @@ set(WebCore_NON_SVG_IDL_FILES
     crypto/parameters/RsaHashedKeyGenParams.idl
     crypto/parameters/RsaKeyGenParams.idl
     crypto/parameters/RsaOaepParams.idl
+    crypto/parameters/RsaPssParams.idl
 
     css/CSSFontFaceRule.idl
     css/CSSImportRule.idl
index 27c5e25..d6ab991 100644 (file)
@@ -1,3 +1,73 @@
+2017-05-22  Jiewen Tan  <jiewen_tan@apple.com>
+
+        [WebCrypto] Support RSA-PSS
+        https://bugs.webkit.org/show_bug.cgi?id=170869
+        <rdar://problem/31640672>
+
+        Reviewed by Brent Fulgham.
+
+        This patch implements RSA-PSS according to the spec: https://www.w3.org/TR/WebCryptoAPI/#rsa-pss.
+        Supported operations include sign, verify, generateKey, importKey and exportKey.
+
+        Tests: crypto/subtle/rsa-pss-generate-export-key-jwk-sha1.html
+               crypto/subtle/rsa-pss-generate-export-key-jwk-sha224.html
+               crypto/subtle/rsa-pss-generate-export-key-jwk-sha256.html
+               crypto/subtle/rsa-pss-generate-export-key-jwk-sha384.html
+               crypto/subtle/rsa-pss-generate-export-key-jwk-sha512.html
+               crypto/subtle/rsa-pss-generate-export-key-pkcs8.html
+               crypto/subtle/rsa-pss-generate-export-key-spki.html
+               crypto/subtle/rsa-pss-generate-key.html
+               crypto/subtle/rsa-pss-import-jwk-private-key.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-empty-usages.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-sha1.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-sha224.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-sha256.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-sha384.html
+               crypto/subtle/rsa-pss-import-jwk-public-key-sha512.html
+               crypto/subtle/rsa-pss-import-key-sign-large-salt.html
+               crypto/subtle/rsa-pss-import-key-sign.html
+               crypto/subtle/rsa-pss-import-key-verify.html
+               crypto/subtle/rsa-pss-import-pkcs8-key.html
+               crypto/subtle/rsa-pss-import-spki-key-empty-usages.html
+               crypto/subtle/rsa-pss-import-spki-key.html
+               crypto/workers/subtle/rsa-pss-import-key-sign.html
+               crypto/workers/subtle/rsa-pss-import-key-verify.html
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * PlatformGTK.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSSubtleCryptoCustom.cpp:
+        (WebCore::normalizeCryptoAlgorithmParameters):
+        * crypto/CryptoAlgorithmParameters.h:
+        * crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp: Added.
+        (WebCore::CryptoAlgorithmRSA_PSS::create):
+        (WebCore::CryptoAlgorithmRSA_PSS::identifier):
+        (WebCore::CryptoAlgorithmRSA_PSS::sign):
+        (WebCore::CryptoAlgorithmRSA_PSS::verify):
+        (WebCore::CryptoAlgorithmRSA_PSS::generateKey):
+        (WebCore::CryptoAlgorithmRSA_PSS::importKey):
+        (WebCore::CryptoAlgorithmRSA_PSS::exportKey):
+        * crypto/algorithms/CryptoAlgorithmRSA_PSS.h: Added.
+        * crypto/mac/CryptoAlgorithmECDSAMac.cpp:
+        (WebCore::cryptoDigestAlgorithm): Deleted.
+        Extract function cryptoDigestAlgorithm to a separate file.
+        * crypto/mac/CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp:
+        (WebCore::cryptoDigestAlgorithm): Deleted.
+        Extract function cryptoDigestAlgorithm to a separate file.
+        * crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp: Added.
+        (WebCore::signRSA_PSS):
+        (WebCore::verifyRSA_PSS):
+        (WebCore::CryptoAlgorithmRSA_PSS::platformSign):
+        (WebCore::CryptoAlgorithmRSA_PSS::platformVerify):
+        * crypto/mac/CryptoAlgorithmRegistryMac.cpp:
+        (WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms):
+        * crypto/mac/CryptoDigestAlgorithm.h: Added.
+        (WebCore::cryptoDigestAlgorithm):
+        Have cryptoDigestAlgorithm in a separate file.
+        * crypto/parameters/CryptoAlgorithmRsaPssParams.h: Added.
+        * crypto/parameters/RsaPssParams.idl: Added.
+
 2017-05-23  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Allow transition from autoplay to play when a capture stream begins.
index c9bb182..d673fb6 100644 (file)
@@ -300,6 +300,7 @@ JS_BINDING_IDLS = \
     $(WebCore)/crypto/parameters/RsaHashedKeyGenParams.idl \
     $(WebCore)/crypto/parameters/RsaKeyGenParams.idl \
     $(WebCore)/crypto/parameters/RsaOaepParams.idl \
+    $(WebCore)/crypto/parameters/RsaPssParams.idl \
     $(WebCore)/css/CSSFontFaceRule.idl \
     $(WebCore)/css/CSSImportRule.idl \
     $(WebCore)/css/CSSKeyframeRule.idl \
index 0866c5a..9826cc4 100644 (file)
@@ -394,6 +394,7 @@ if (ENABLE_SUBTLE_CRYPTO)
         crypto/algorithms/CryptoAlgorithmRSAES_PKCS1_v1_5.cpp
         crypto/algorithms/CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp
         crypto/algorithms/CryptoAlgorithmRSA_OAEP.cpp
+        crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp
         crypto/algorithms/CryptoAlgorithmSHA1.cpp
         crypto/algorithms/CryptoAlgorithmSHA224.cpp
         crypto/algorithms/CryptoAlgorithmSHA256.cpp
index 1ea98e1..85618f5 100644 (file)
                571F21891DA57C54005C9EFD /* JSSubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 571F21881DA57C54005C9EFD /* JSSubtleCrypto.h */; };
                571F218B1DA57C7B005C9EFD /* JSSubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 571F218A1DA57C7A005C9EFD /* JSSubtleCrypto.cpp */; };
                572093D31DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 572093D21DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h */; };
+               5721A9851ECE4FB90081295A /* CryptoAlgorithmRSA_PSSMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5721A9831ECE4FB90081295A /* CryptoAlgorithmRSA_PSSMac.cpp */; };
+               5721A9871ECE53B10081295A /* CryptoDigestAlgorithm.h in Headers */ = {isa = PBXBuildFile; fileRef = 5721A9861ECE53B10081295A /* CryptoDigestAlgorithm.h */; };
+               5721A98B1ECE57040081295A /* CryptoAlgorithmRsaPssParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5721A9881ECE57040081295A /* CryptoAlgorithmRsaPssParams.h */; };
                572A7F211C6E5719009C6149 /* SimulatedClick.h in Headers */ = {isa = PBXBuildFile; fileRef = 572A7F201C6E5719009C6149 /* SimulatedClick.h */; };
                572A7F231C6E5A66009C6149 /* SimulatedClick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 572A7F221C6E5A66009C6149 /* SimulatedClick.cpp */; };
                573489391DAC6B6E00DC0667 /* CryptoAlgorithmParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */; };
                5750A9821E6A150800705C4A /* JSEcKeyParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9801E6A150800705C4A /* JSEcKeyParams.h */; };
                5750A9861E6A216800705C4A /* CryptoAlgorithmECDH.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5750A9841E6A216800705C4A /* CryptoAlgorithmECDH.cpp */; };
                5750A9871E6A216800705C4A /* CryptoAlgorithmECDH.h in Headers */ = {isa = PBXBuildFile; fileRef = 5750A9851E6A216800705C4A /* CryptoAlgorithmECDH.h */; };
+               5754719F1ECE628300DD63B2 /* JSRsaPssParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 575471991ECE5D2A00DD63B2 /* JSRsaPssParams.h */; };
+               575471A01ECE628700DD63B2 /* JSRsaPssParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5754719A1ECE5D2A00DD63B2 /* JSRsaPssParams.cpp */; };
                5768142A1E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */; };
                576814351E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */; };
                576814401E709FA100E77754 /* JSEcdhKeyDeriveParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5768143D1E709C3600E77754 /* JSEcdhKeyDeriveParams.cpp */; };
                57777E391E71217D00EE1A8D /* CryptoAlgorithmPBKDF2.h in Headers */ = {isa = PBXBuildFile; fileRef = 57777E371E71217D00EE1A8D /* CryptoAlgorithmPBKDF2.h */; };
                5778BD821DA4806C009E3009 /* SubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 5778BD811DA4802C009E3009 /* SubtleCrypto.h */; };
                5778BD841DA4817B009E3009 /* SubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5778BD831DA4817B009E3009 /* SubtleCrypto.cpp */; };
+               5790996D1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h in Headers */ = {isa = PBXBuildFile; fileRef = 5790996B1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h */; };
+               5790996E1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5790996C1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp */; };
                57957CA81E971DE0008072AB /* CryptoAlgorithmHKDF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57957CA61E971DE0008072AB /* CryptoAlgorithmHKDF.cpp */; };
                57957CA91E971DE0008072AB /* CryptoAlgorithmHKDF.h in Headers */ = {isa = PBXBuildFile; fileRef = 57957CA71E971DE0008072AB /* CryptoAlgorithmHKDF.h */; };
                57957CAC1E97247B008072AB /* CryptoAlgorithmHKDFMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57957CAA1E97247B008072AB /* CryptoAlgorithmHKDFMac.cpp */; };
                571F218A1DA57C7A005C9EFD /* JSSubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSubtleCrypto.cpp; sourceTree = "<group>"; };
                572093D11DDCEA4B00310AB0 /* AesCbcCfbParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AesCbcCfbParams.idl; sourceTree = "<group>"; };
                572093D21DDCEB9A00310AB0 /* CryptoAlgorithmAesCbcCfbParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmAesCbcCfbParams.h; sourceTree = "<group>"; };
+               5721A9831ECE4FB90081295A /* CryptoAlgorithmRSA_PSSMac.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRSA_PSSMac.cpp; sourceTree = "<group>"; };
+               5721A9861ECE53B10081295A /* CryptoDigestAlgorithm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoDigestAlgorithm.h; sourceTree = "<group>"; };
+               5721A9881ECE57040081295A /* CryptoAlgorithmRsaPssParams.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRsaPssParams.h; sourceTree = "<group>"; };
+               5721A98A1ECE57040081295A /* RsaPssParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RsaPssParams.idl; sourceTree = "<group>"; };
                572A7F201C6E5719009C6149 /* SimulatedClick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimulatedClick.h; sourceTree = "<group>"; };
                572A7F221C6E5A66009C6149 /* SimulatedClick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimulatedClick.cpp; sourceTree = "<group>"; };
                573489381DAC6B6D00DC0667 /* CryptoAlgorithmParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmParameters.h; sourceTree = "<group>"; };
                5750A9801E6A150800705C4A /* JSEcKeyParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEcKeyParams.h; sourceTree = "<group>"; };
                5750A9841E6A216800705C4A /* CryptoAlgorithmECDH.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmECDH.cpp; sourceTree = "<group>"; };
                5750A9851E6A216800705C4A /* CryptoAlgorithmECDH.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmECDH.h; sourceTree = "<group>"; };
+               575471991ECE5D2A00DD63B2 /* JSRsaPssParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRsaPssParams.h; sourceTree = "<group>"; };
+               5754719A1ECE5D2A00DD63B2 /* JSRsaPssParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRsaPssParams.cpp; sourceTree = "<group>"; };
                576814281E6F98AD00E77754 /* EcdhKeyDeriveParams.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = EcdhKeyDeriveParams.idl; sourceTree = "<group>"; };
                576814291E6F99C100E77754 /* CryptoAlgorithmEcdhKeyDeriveParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmEcdhKeyDeriveParams.h; sourceTree = "<group>"; };
                576814341E6FE3E800E77754 /* CryptoAlgorithmECDHMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmECDHMac.cpp; sourceTree = "<group>"; };
                5778BD801DA4733E009E3009 /* SubtleCrypto.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SubtleCrypto.idl; sourceTree = "<group>"; };
                5778BD811DA4802C009E3009 /* SubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtleCrypto.h; sourceTree = "<group>"; };
                5778BD831DA4817B009E3009 /* SubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtleCrypto.cpp; sourceTree = "<group>"; };
+               5790996B1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRSA_PSS.h; sourceTree = "<group>"; };
+               5790996C1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRSA_PSS.cpp; sourceTree = "<group>"; };
                57957CA61E971DE0008072AB /* CryptoAlgorithmHKDF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmHKDF.cpp; sourceTree = "<group>"; };
                57957CA71E971DE0008072AB /* CryptoAlgorithmHKDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmHKDF.h; sourceTree = "<group>"; };
                57957CAA1E97247B008072AB /* CryptoAlgorithmHKDFMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmHKDFMac.cpp; sourceTree = "<group>"; };
                                57E657E81E714D1A00F941CA /* CryptoAlgorithmPBKDF2Mac.cpp */,
                                E1BB84AC1822CA7400525043 /* CryptoAlgorithmRegistryMac.cpp */,
                                E1FE136E183FECF000892F13 /* CryptoAlgorithmRSA_OAEPMac.cpp */,
+                               5721A9831ECE4FB90081295A /* CryptoAlgorithmRSA_PSSMac.cpp */,
                                E1233F0E185A4130008DFAF5 /* CryptoAlgorithmRSAES_PKCS1_v1_5Mac.cpp */,
                                E1C266D618317AB4003F8B33 /* CryptoAlgorithmRSASSA_PKCS1_v1_5Mac.cpp */,
+                               5721A9861ECE53B10081295A /* CryptoDigestAlgorithm.h */,
                                5750A97A1E69161600705C4A /* CryptoKeyECMac.cpp */,
                                E19AC3F8182566F700349426 /* CryptoKeyMac.cpp */,
                                E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */,
                                57777E371E71217D00EE1A8D /* CryptoAlgorithmPBKDF2.h */,
                                E1FE1368183FE1AB00892F13 /* CryptoAlgorithmRSA_OAEP.cpp */,
                                E1FE1369183FE1AB00892F13 /* CryptoAlgorithmRSA_OAEP.h */,
+                               5790996B1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h */,
+                               5790996C1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp */,
                                E1233F0A185A3E3B008DFAF5 /* CryptoAlgorithmRSAES_PKCS1_v1_5.cpp */,
                                E1233F0B185A3E3B008DFAF5 /* CryptoAlgorithmRSAES_PKCS1_v1_5.h */,
                                E1BD3317182D8DDD00C05D9F /* CryptoAlgorithmRSASSA_PKCS1_v1_5.cpp */,
                                E1BD331D182D8F4200C05D9F /* CryptoAlgorithmRsaKeyGenParamsDeprecated.h */,
                                E1C266DA18319935003F8B33 /* CryptoAlgorithmRsaKeyParamsWithHashDeprecated.h */,
                                5706A6951DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h */,
+                               5721A9881ECE57040081295A /* CryptoAlgorithmRsaPssParams.h */,
                                E1FE1376184D1E3300892F13 /* CryptoAlgorithmRsaOaepParamsDeprecated.h */,
                                E1BD331B182D8EE900C05D9F /* CryptoAlgorithmRsaSsaParamsDeprecated.h */,
                                576814281E6F98AD00E77754 /* EcdhKeyDeriveParams.idl */,
                                57F827391DB72C22009D2BF4 /* RsaHashedKeyGenParams.idl */,
                                57FEDD3D1DB6D47F00EB96F5 /* RsaKeyGenParams.idl */,
                                5706A6941DDE5BF800A03B14 /* RsaOaepParams.idl */,
+                               5721A98A1ECE57040081295A /* RsaPssParams.idl */,
                        );
                        path = parameters;
                        sourceTree = "<group>";
                                57FEDD401DB6D73A00EB96F5 /* JSRsaKeyGenParams.h */,
                                5706A6991DDE5E8500A03B14 /* JSRsaOaepParams.cpp */,
                                5706A6971DDE5E4600A03B14 /* JSRsaOaepParams.h */,
+                               5754719A1ECE5D2A00DD63B2 /* JSRsaPssParams.cpp */,
+                               575471991ECE5D2A00DD63B2 /* JSRsaPssParams.h */,
                                57E233601DC7D6AA00F28D01 /* JSRsaOtherPrimesInfo.cpp */,
                                57E2335C1DC7D60800F28D01 /* JSRsaOtherPrimesInfo.h */,
                                571F218A1DA57C7A005C9EFD /* JSSubtleCrypto.cpp */,
                                A80E6CE90A1989CA007FB8C5 /* CSSValueList.h in Headers */,
                                E49BD9FA131FD2ED003C56F0 /* CSSValuePool.h in Headers */,
                                9444CBE81D8861C20073A074 /* CSSVariableData.h in Headers */,
+                               5754719F1ECE628300DD63B2 /* JSRsaPssParams.h in Headers */,
                                9444CBDA1D88483A0073A074 /* CSSVariableParser.h in Headers */,
                                9444CBEA1D8861CA0073A074 /* CSSVariableReferenceValue.h in Headers */,
                                93F1992F08245E59001E9ABC /* Cursor.h in Headers */,
                                7A54881714E432A1006AE05A /* DOMPatchSupport.h in Headers */,
                                FB91392416AE4C17001FE682 /* DOMPath.h in Headers */,
                                A9C6E4EC0D745E2B006442E9 /* DOMPlugin.h in Headers */,
+                               5721A9871ECE53B10081295A /* CryptoDigestAlgorithm.h in Headers */,
                                A9C6E4F00D745E38006442E9 /* DOMPluginArray.h in Headers */,
                                0F49669D1DB408C100A274BB /* DOMPoint.h in Headers */,
                                0F4966A31DB4091000A274BB /* DOMPointInit.h in Headers */,
                                B8DBDB4C130B0F8A00F5CDB1 /* SetSelectionCommand.h in Headers */,
                                93F1994F08245E59001E9ABC /* Settings.h in Headers */,
                                53EF766B16530A61004CBE49 /* SettingsMacros.h in Headers */,
+                               5790996D1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.h in Headers */,
                                0F3DD45012F5EA1B000D9190 /* ShadowBlur.h in Headers */,
                                BC5EB8C40E82031B00B25965 /* ShadowData.h in Headers */,
                                A6D169641346B4C1000EB770 /* ShadowRoot.h in Headers */,
                                BC5EB8B90E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.h in Headers */,
                                319AE064142D6B24006563A1 /* StyleFilterData.h in Headers */,
                                5317612313C516690026E454 /* StyleFlexibleBoxData.h in Headers */,
+                               5721A98B1ECE57040081295A /* CryptoAlgorithmRsaPssParams.h in Headers */,
                                E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */,
                                BCEF444A0E6745E0001C1287 /* StyleGeneratedImage.h in Headers */,
                                A10DC76B14747BAB005E2471 /* StyleGridData.h in Headers */,
                                371F53EA0D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp in Sources */,
                                BC7D8FEF1BD03B6400FFE540 /* CSSUnsetValue.cpp in Sources */,
                                AD03AAFA1468455300A39B5B /* CSSValue.cpp in Sources */,
+                               5790996E1ECD23DA00FC0768 /* CryptoAlgorithmRSA_PSS.cpp in Sources */,
                                1ABA76CB11D20E57004C201C /* CSSValueKeywords.cpp in Sources */,
                                A80E6CE40A1989CA007FB8C5 /* CSSValueList.cpp in Sources */,
                                E49BDA0B131FD3E5003C56F0 /* CSSValuePool.cpp in Sources */,
                                B2FA3DFE0AB75A6F000E5AC4 /* JSSVGSwitchElement.cpp in Sources */,
                                B2FA3E000AB75A6F000E5AC4 /* JSSVGSymbolElement.cpp in Sources */,
                                B2FA3E020AB75A6F000E5AC4 /* JSSVGTextContentElement.cpp in Sources */,
+                               5721A9851ECE4FB90081295A /* CryptoAlgorithmRSA_PSSMac.cpp in Sources */,
                                B2FA3E040AB75A6F000E5AC4 /* JSSVGTextElement.cpp in Sources */,
                                B22362280C3AF04A0008CA9B /* JSSVGTextPathElement.cpp in Sources */,
                                B2FA3E060AB75A6F000E5AC4 /* JSSVGTextPositioningElement.cpp in Sources */,
                                31955A86160D199000858025 /* RenderSnapshottedPlugIn.cpp in Sources */,
                                BC8C8FAD0DDCD31B00B592F4 /* RenderStyle.cpp in Sources */,
                                0FEF20D01BD4A64F00128E5D /* RenderStyleConstants.cpp in Sources */,
+                               575471A01ECE628700DD63B2 /* JSRsaPssParams.cpp in Sources */,
                                0F4E57171313276200CF85AF /* RenderSVGAllInOne.cpp in Sources */,
                                A8DF4AEC0980C42C0052981B /* RenderTable.cpp in Sources */,
                                6ED878C4147493F4004C3597 /* RenderTableCaption.cpp in Sources */,
index 555ea67..664e69b 100644 (file)
@@ -50,6 +50,7 @@
 #include "JSRsaHashedKeyGenParams.h"
 #include "JSRsaKeyGenParams.h"
 #include "JSRsaOaepParams.h"
+#include "JSRsaPssParams.h"
 #include "ScriptState.h"
 #include <runtime/Error.h>
 #include <runtime/JSArray.h>
@@ -158,7 +159,12 @@ static std::unique_ptr<CryptoAlgorithmParameters> normalizeCryptoAlgorithmParame
                 RETURN_IF_EXCEPTION(scope, nullptr);
                 result = std::make_unique<CryptoAlgorithmEcdsaParams>(params);
                 break;
-
+            }
+            case CryptoAlgorithmIdentifier::RSA_PSS: {
+                auto params = convertDictionary<CryptoAlgorithmRsaPssParams>(state, value);
+                RETURN_IF_EXCEPTION(scope, nullptr);
+                result = std::make_unique<CryptoAlgorithmRsaPssParams>(params);
+                break;
             }
             default:
                 throwNotSupportedError(state, scope);
index 503ed4a..0c15485 100644 (file)
@@ -51,6 +51,7 @@ public:
         RsaHashedImportParams,
         RsaKeyGenParams,
         RsaOaepParams,
+        RsaPssParams,
     };
 
     // FIXME: Consider merging name and identifier.
diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp b/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.cpp
new file mode 100644 (file)
index 0000000..c049ec9
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2017 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 "CryptoAlgorithmRSA_PSS.h"
+
+#if ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
+
+#include "CryptoAlgorithmRsaHashedImportParams.h"
+#include "CryptoAlgorithmRsaHashedKeyGenParams.h"
+#include "CryptoKeyPair.h"
+#include "CryptoKeyRSA.h"
+#include "ExceptionCode.h"
+#include <wtf/Variant.h>
+
+namespace WebCore {
+
+static const char* const ALG1 = "PS1";
+static const char* const ALG224 = "PS224";
+static const char* const ALG256 = "PS256";
+static const char* const ALG384 = "PS384";
+static const char* const ALG512 = "PS512";
+
+Ref<CryptoAlgorithm> CryptoAlgorithmRSA_PSS::create()
+{
+    return adoptRef(*new CryptoAlgorithmRSA_PSS);
+}
+
+CryptoAlgorithmIdentifier CryptoAlgorithmRSA_PSS::identifier() const
+{
+    return s_identifier;
+}
+
+void CryptoAlgorithmRSA_PSS::sign(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+    if (key->type() != CryptoKeyType::Private) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+    platformSign(WTFMove(parameters), WTFMove(key), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), context, workQueue);
+}
+
+void CryptoAlgorithmRSA_PSS::verify(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+    if (key->type() != CryptoKeyType::Public) {
+        exceptionCallback(INVALID_ACCESS_ERR);
+        return;
+    }
+    platformVerify(WTFMove(parameters), WTFMove(key), WTFMove(signature), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), context, workQueue);
+}
+
+void CryptoAlgorithmRSA_PSS::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context)
+{
+    const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedKeyGenParams>(parameters);
+
+    if (usages & (CryptoKeyUsageDecrypt | CryptoKeyUsageEncrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) {
+        exceptionCallback(SYNTAX_ERR);
+        return;
+    }
+
+    auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) {
+        pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify);
+        pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign);
+        capturedCallback(WTFMove(pair));
+    };
+    auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() {
+        capturedCallback(OperationError);
+    };
+    CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSA_PSS, rsaParameters.hashIdentifier, true, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context);
+}
+
+void CryptoAlgorithmRSA_PSS::importKey(SubtleCrypto::KeyFormat format, KeyData&& data, const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+    ASSERT(parameters);
+    const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedImportParams>(*parameters);
+
+    RefPtr<CryptoKeyRSA> result;
+    switch (format) {
+    case SubtleCrypto::KeyFormat::Jwk: {
+        JsonWebKey key = WTFMove(WTF::get<JsonWebKey>(data));
+
+        if (usages && ((!key.d.isNull() && (usages ^ CryptoKeyUsageSign)) || (key.d.isNull() && (usages ^ CryptoKeyUsageVerify)))) {
+            exceptionCallback(SYNTAX_ERR);
+            return;
+        }
+        if (usages && !key.use.isNull() && key.use != "sig") {
+            exceptionCallback(DataError);
+            return;
+        }
+
+        bool isMatched = false;
+        switch (rsaParameters.hashIdentifier) {
+        case CryptoAlgorithmIdentifier::SHA_1:
+            isMatched = key.alg.isNull() || key.alg == ALG1;
+            break;
+        case CryptoAlgorithmIdentifier::SHA_224:
+            isMatched = key.alg.isNull() || key.alg == ALG224;
+            break;
+        case CryptoAlgorithmIdentifier::SHA_256:
+            isMatched = key.alg.isNull() || key.alg == ALG256;
+            break;
+        case CryptoAlgorithmIdentifier::SHA_384:
+            isMatched = key.alg.isNull() || key.alg == ALG384;
+            break;
+        case CryptoAlgorithmIdentifier::SHA_512:
+            isMatched = key.alg.isNull() || key.alg == ALG512;
+            break;
+        default:
+            break;
+        }
+        if (!isMatched) {
+            exceptionCallback(DataError);
+            return;
+        }
+
+        result = CryptoKeyRSA::importJwk(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(key), extractable, usages);
+        break;
+    }
+    case SubtleCrypto::KeyFormat::Spki: {
+        if (usages && (usages ^ CryptoKeyUsageVerify)) {
+            exceptionCallback(SYNTAX_ERR);
+            return;
+        }
+        // FIXME: <webkit.org/b/165436>
+        result = CryptoKeyRSA::importSpki(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
+        break;
+    }
+    case SubtleCrypto::KeyFormat::Pkcs8: {
+        if (usages && (usages ^ CryptoKeyUsageSign)) {
+            exceptionCallback(SYNTAX_ERR);
+            return;
+        }
+        // FIXME: <webkit.org/b/165436>
+        result = CryptoKeyRSA::importPkcs8(parameters->identifier, rsaParameters.hashIdentifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
+        break;
+    }
+    default:
+        exceptionCallback(NOT_SUPPORTED_ERR);
+        return;
+    }
+    if (!result) {
+        exceptionCallback(DataError);
+        return;
+    }
+
+    callback(*result);
+}
+
+void CryptoAlgorithmRSA_PSS::exportKey(SubtleCrypto::KeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
+{
+    const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+
+    if (!rsaKey.keySizeInBits()) {
+        exceptionCallback(OperationError);
+        return;
+    }
+
+    KeyData result;
+    switch (format) {
+    case SubtleCrypto::KeyFormat::Jwk: {
+        JsonWebKey jwk = rsaKey.exportJwk();
+        switch (rsaKey.hashAlgorithmIdentifier()) {
+        case CryptoAlgorithmIdentifier::SHA_1:
+            jwk.alg = String(ALG1);
+            break;
+        case CryptoAlgorithmIdentifier::SHA_224:
+            jwk.alg = String(ALG224);
+            break;
+        case CryptoAlgorithmIdentifier::SHA_256:
+            jwk.alg = String(ALG256);
+            break;
+        case CryptoAlgorithmIdentifier::SHA_384:
+            jwk.alg = String(ALG384);
+            break;
+        case CryptoAlgorithmIdentifier::SHA_512:
+            jwk.alg = String(ALG512);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        result = WTFMove(jwk);
+        break;
+    }
+    case SubtleCrypto::KeyFormat::Spki: {
+        auto spki = rsaKey.exportSpki();
+        if (spki.hasException()) {
+            exceptionCallback(spki.releaseException().code());
+            return;
+        }
+        result = spki.releaseReturnValue();
+        break;
+    }
+    case SubtleCrypto::KeyFormat::Pkcs8: {
+        auto pkcs8 = rsaKey.exportPkcs8();
+        if (pkcs8.hasException()) {
+            exceptionCallback(pkcs8.releaseException().code());
+            return;
+        }
+        result = pkcs8.releaseReturnValue();
+        break;
+    }
+    default:
+        exceptionCallback(NOT_SUPPORTED_ERR);
+        return;
+    }
+
+    callback(format, WTFMove(result));
+}
+
+}
+
+#endif // ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
diff --git a/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.h b/Source/WebCore/crypto/algorithms/CryptoAlgorithmRSA_PSS.h
new file mode 100644 (file)
index 0000000..79e97ed
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithm.h"
+
+#if ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
+
+namespace WebCore {
+
+class CryptoKeyRSA;
+
+class CryptoAlgorithmRSA_PSS final : public CryptoAlgorithm {
+public:
+    static constexpr const char* s_name = "RSA-PSS";
+    static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::RSA_PSS;
+    static Ref<CryptoAlgorithm> create();
+
+private:
+    CryptoAlgorithmRSA_PSS() = default;
+    CryptoAlgorithmIdentifier identifier() const final;
+
+    void sign(std::unique_ptr<CryptoAlgorithmParameters>&&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+    void verify(std::unique_ptr<CryptoAlgorithmParameters>&&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
+    void generateKey(const CryptoAlgorithmParameters&, bool extractable, CryptoKeyUsageBitmap, KeyOrKeyPairCallback&&, ExceptionCallback&&, ScriptExecutionContext&) final;
+    void importKey(SubtleCrypto::KeyFormat, KeyData&&, const std::unique_ptr<CryptoAlgorithmParameters>&&, bool extractable, CryptoKeyUsageBitmap, KeyCallback&&, ExceptionCallback&&) final;
+    void exportKey(SubtleCrypto::KeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final;
+
+    void platformSign(std::unique_ptr<CryptoAlgorithmParameters>&&, Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+    void platformVerify(std::unique_ptr<CryptoAlgorithmParameters>&&, Ref<CryptoKey>&&, Vector<uint8_t>&& signature, Vector<uint8_t>&&, BoolCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
index 56d6493..8b6faf1 100644 (file)
 #include "CommonCryptoDERUtilities.h"
 #include "CommonCryptoUtilities.h"
 #include "CryptoAlgorithmEcdsaParams.h"
+#include "CryptoDigestAlgorithm.h"
 #include "CryptoKeyEC.h"
 #include "ExceptionCode.h"
 #include "ScriptExecutionContext.h"
-#include <pal/crypto/CryptoDigest.h>
 
 namespace WebCore {
 
-inline std::optional<PAL::CryptoDigest::Algorithm> cryptoDigestAlgorithm(CryptoAlgorithmIdentifier hashFunction)
-{
-    switch (hashFunction) {
-    case CryptoAlgorithmIdentifier::SHA_1:
-        return PAL::CryptoDigest::Algorithm::SHA_1;
-    case CryptoAlgorithmIdentifier::SHA_224:
-        return PAL::CryptoDigest::Algorithm::SHA_224;
-    case CryptoAlgorithmIdentifier::SHA_256:
-        return PAL::CryptoDigest::Algorithm::SHA_256;
-    case CryptoAlgorithmIdentifier::SHA_384:
-        return PAL::CryptoDigest::Algorithm::SHA_384;
-    case CryptoAlgorithmIdentifier::SHA_512:
-        return PAL::CryptoDigest::Algorithm::SHA_512;
-    default:
-        return std::nullopt;
-    }
-}
-
 static ExceptionOr<Vector<uint8_t>> signECDSA(CryptoAlgorithmIdentifier hash, const PlatformECKey key, size_t keyLengthInBytes, const Vector<uint8_t>& data)
 {
     CCDigestAlgorithm digestAlgorithm;
index 0f0bf93..b6c33dc 100644 (file)
 
 #include "CommonCryptoUtilities.h"
 #include "CryptoAlgorithmRsaSsaParamsDeprecated.h"
+#include "CryptoDigestAlgorithm.h"
 #include "CryptoKeyRSA.h"
 #include "ExceptionCode.h"
 #include "ScriptExecutionContext.h"
-#include <pal/crypto/CryptoDigest.h>
 
 namespace WebCore {
 
-inline std::optional<PAL::CryptoDigest::Algorithm> cryptoDigestAlgorithm(CryptoAlgorithmIdentifier hashFunction)
-{
-    switch (hashFunction) {
-    case CryptoAlgorithmIdentifier::SHA_1:
-        return PAL::CryptoDigest::Algorithm::SHA_1;
-    case CryptoAlgorithmIdentifier::SHA_224:
-        return PAL::CryptoDigest::Algorithm::SHA_224;
-    case CryptoAlgorithmIdentifier::SHA_256:
-        return PAL::CryptoDigest::Algorithm::SHA_256;
-    case CryptoAlgorithmIdentifier::SHA_384:
-        return PAL::CryptoDigest::Algorithm::SHA_384;
-    case CryptoAlgorithmIdentifier::SHA_512:
-        return PAL::CryptoDigest::Algorithm::SHA_512;
-    default:
-        return std::nullopt;
-    }
-}
-
 // FIXME: We should change data to Vector<uint8_t> type once WebKitSubtleCrypto is deprecated.
 // https://bugs.webkit.org/show_bug.cgi?id=164939
 static ExceptionOr<Vector<uint8_t>> signRSASSA_PKCS1_v1_5(CryptoAlgorithmIdentifier hash, const PlatformRSAKey key, size_t keyLength, const uint8_t* data, size_t dataLength)
diff --git a/Source/WebCore/crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp b/Source/WebCore/crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp
new file mode 100644 (file)
index 0000000..34cc2d7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 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 "CryptoAlgorithmRSA_PSS.h"
+
+#if ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
+
+#include "CommonCryptoUtilities.h"
+#include "CryptoAlgorithmRsaPssParams.h"
+#include "CryptoDigestAlgorithm.h"
+#include "CryptoKeyRSA.h"
+#include "ExceptionCode.h"
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+static ExceptionOr<Vector<uint8_t>> signRSA_PSS(CryptoAlgorithmIdentifier hash, const PlatformRSAKey key, size_t keyLength, const Vector<uint8_t>& data, size_t saltLength)
+{
+    CCDigestAlgorithm digestAlgorithm;
+    if (!getCommonCryptoDigestAlgorithm(hash, digestAlgorithm))
+        return Exception { OperationError };
+
+    auto cryptoDigestAlgorithm = WebCore::cryptoDigestAlgorithm(hash);
+    if (!cryptoDigestAlgorithm)
+        return Exception { OperationError };
+    auto digest = PAL::CryptoDigest::create(*cryptoDigestAlgorithm);
+    if (!digest)
+        return Exception { OperationError };
+    digest->addBytes(data.data(), data.size());
+    auto digestData = digest->computeHash();
+
+    Vector<uint8_t> signature(keyLength / 8); // Per https://tools.ietf.org/html/rfc3447#section-8.1.1
+    size_t signatureSize = signature.size();
+
+    CCCryptorStatus status = CCRSACryptorSign(key, ccRSAPSSPadding, digestData.data(), digestData.size(), digestAlgorithm, saltLength, signature.data(), &signatureSize);
+    if (status)
+        return Exception { OperationError };
+
+    return WTFMove(signature);
+}
+
+static ExceptionOr<bool> verifyRSA_PSS(CryptoAlgorithmIdentifier hash, const PlatformRSAKey key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data, size_t saltLength)
+{
+    CCDigestAlgorithm digestAlgorithm;
+    if (!getCommonCryptoDigestAlgorithm(hash, digestAlgorithm))
+        return Exception { OperationError };
+
+    auto cryptoDigestAlgorithm = WebCore::cryptoDigestAlgorithm(hash);
+    if (!cryptoDigestAlgorithm)
+        return Exception { OperationError };
+    auto digest = PAL::CryptoDigest::create(*cryptoDigestAlgorithm);
+    if (!digest)
+        return Exception { OperationError };
+    digest->addBytes(data.data(), data.size());
+    auto digestData = digest->computeHash();
+
+    auto status = CCRSACryptorVerify(key, ccRSAPSSPadding, digestData.data(), digestData.size(), digestAlgorithm, saltLength, signature.data(), signature.size());
+    if (!status)
+        return true;
+    return false;
+}
+
+void CryptoAlgorithmRSA_PSS::platformSign(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+    context.ref();
+    workQueue.dispatch([parameters = WTFMove(parameters), key = WTFMove(key), data = WTFMove(data), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), &context]() mutable {
+        auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+        auto& rsaParams = downcast<CryptoAlgorithmRsaPssParams>(*parameters);
+        auto result = signRSA_PSS(rsaKey.hashAlgorithmIdentifier(), rsaKey.platformKey(), rsaKey.keySizeInBits(), data, rsaParams.saltLength);
+        if (result.hasException()) {
+            // We should only dereference callbacks after being back to the Document/Worker threads.
+            context.postTask([exceptionCallback = WTFMove(exceptionCallback), ec = result.releaseException().code(), callback = WTFMove(callback)](ScriptExecutionContext& context) {
+                exceptionCallback(ec);
+                context.deref();
+            });
+            return;
+        }
+        // We should only dereference callbacks after being back to the Document/Worker threads.
+        context.postTask([callback = WTFMove(callback), result = result.releaseReturnValue(), exceptionCallback = WTFMove(exceptionCallback)](ScriptExecutionContext& context) {
+            callback(result);
+            context.deref();
+        });
+    });
+}
+
+void CryptoAlgorithmRSA_PSS::platformVerify(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
+{
+    context.ref();
+    workQueue.dispatch([parameters = WTFMove(parameters), key = WTFMove(key), signature = WTFMove(signature), data = WTFMove(data), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), &context]() mutable {
+        auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
+        auto& rsaParams = downcast<CryptoAlgorithmRsaPssParams>(*parameters);
+        auto result = verifyRSA_PSS(rsaKey.hashAlgorithmIdentifier(), rsaKey.platformKey(), signature, data, rsaParams.saltLength);
+        if (result.hasException()) {
+            // We should only dereference callbacks after being back to the Document/Worker threads.
+            context.postTask([exceptionCallback = WTFMove(exceptionCallback), ec = result.releaseException().code(), callback = WTFMove(callback)](ScriptExecutionContext& context) {
+                exceptionCallback(ec);
+                context.deref();
+            });
+            return;
+        }
+        // We should only dereference callbacks after being back to the Document/Worker threads.
+        context.postTask([callback = WTFMove(callback), result = result.releaseReturnValue(), exceptionCallback = WTFMove(exceptionCallback)](ScriptExecutionContext& context) {
+            callback(result);
+            context.deref();
+        });
+    });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO) && HAVE(RSA_PSS)
index 918e480..fc2c87a 100644 (file)
@@ -41,6 +41,7 @@
 #include "CryptoAlgorithmRSAES_PKCS1_v1_5.h"
 #include "CryptoAlgorithmRSASSA_PKCS1_v1_5.h"
 #include "CryptoAlgorithmRSA_OAEP.h"
+#include "CryptoAlgorithmRSA_PSS.h"
 #include "CryptoAlgorithmSHA1.h"
 #include "CryptoAlgorithmSHA224.h"
 #include "CryptoAlgorithmSHA256.h"
@@ -64,6 +65,9 @@ void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
     registerAlgorithm<CryptoAlgorithmRSAES_PKCS1_v1_5>();
     registerAlgorithm<CryptoAlgorithmRSASSA_PKCS1_v1_5>();
     registerAlgorithm<CryptoAlgorithmRSA_OAEP>();
+#if HAVE(RSA_PSS)
+    registerAlgorithm<CryptoAlgorithmRSA_PSS>();
+#endif
     registerAlgorithm<CryptoAlgorithmSHA1>();
     registerAlgorithm<CryptoAlgorithmSHA224>();
     registerAlgorithm<CryptoAlgorithmSHA256>();
diff --git a/Source/WebCore/crypto/mac/CryptoDigestAlgorithm.h b/Source/WebCore/crypto/mac/CryptoDigestAlgorithm.h
new file mode 100644 (file)
index 0000000..4e180e7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include <pal/crypto/CryptoDigest.h>
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+#include "CryptoAlgorithm.h"
+
+namespace WebCore {
+
+static std::optional<PAL::CryptoDigest::Algorithm> cryptoDigestAlgorithm(CryptoAlgorithmIdentifier hashFunction)
+{
+    switch (hashFunction) {
+    case CryptoAlgorithmIdentifier::SHA_1:
+        return PAL::CryptoDigest::Algorithm::SHA_1;
+    case CryptoAlgorithmIdentifier::SHA_224:
+        return PAL::CryptoDigest::Algorithm::SHA_224;
+    case CryptoAlgorithmIdentifier::SHA_256:
+        return PAL::CryptoDigest::Algorithm::SHA_256;
+    case CryptoAlgorithmIdentifier::SHA_384:
+        return PAL::CryptoDigest::Algorithm::SHA_384;
+    case CryptoAlgorithmIdentifier::SHA_512:
+        return PAL::CryptoDigest::Algorithm::SHA_512;
+    default:
+        return std::nullopt;
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SUBTLE_CRYPTO)
diff --git a/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaPssParams.h b/Source/WebCore/crypto/parameters/CryptoAlgorithmRsaPssParams.h
new file mode 100644 (file)
index 0000000..61f3a26
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "CryptoAlgorithmParameters.h"
+
+#if ENABLE(SUBTLE_CRYPTO)
+
+namespace WebCore {
+
+class CryptoAlgorithmRsaPssParams final : public CryptoAlgorithmParameters {
+public:
+    size_t saltLength;
+
+    Class parametersClass() const final { return Class::RsaPssParams; }
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CRYPTO_ALGORITHM_PARAMETERS(RsaPssParams)
+
+#endif // ENABLE(SUBTLE_CRYPTO)
diff --git a/Source/WebCore/crypto/parameters/RsaPssParams.idl b/Source/WebCore/crypto/parameters/RsaPssParams.idl
new file mode 100644 (file)
index 0000000..981f8e3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+[
+    Conditional=SUBTLE_CRYPTO,
+    ImplementedAs=CryptoAlgorithmRsaPssParams
+] dictionary RsaPssParams : CryptoAlgorithmParameters {
+    // The desired length of the random salt
+    required [EnforceRange] unsigned long saltLength;
+};