summaryrefslogtreecommitdiff
path: root/test/parallel/test-crypto-key-objects.js
diff options
context:
space:
mode:
authorTobias Nießen <tniessen@tnie.de>2019-03-16 23:51:26 +0100
committerDaniel Bevenius <daniel.bevenius@gmail.com>2019-04-08 09:22:32 +0200
commit969bd1eb7b56fda3573ad3d41745a491f2b06dde (patch)
treeeb6a429995c6bc99105ab944a72cc0b85c463043 /test/parallel/test-crypto-key-objects.js
parentd834275a48bc1f85e2289bf7e52a5035a4d97f7e (diff)
downloadandroid-node-v8-969bd1eb7b56fda3573ad3d41745a491f2b06dde.tar.gz
android-node-v8-969bd1eb7b56fda3573ad3d41745a491f2b06dde.tar.bz2
android-node-v8-969bd1eb7b56fda3573ad3d41745a491f2b06dde.zip
crypto: add support for RSA-PSS keys
This commit adds support for RSA-PSS keys, including - KeyObjects of type rsa-pss, - key pair generation for RSA-PSS, and - signing and verification using RSA-PSS keys. PR-URL: https://github.com/nodejs/node/pull/26960 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Diffstat (limited to 'test/parallel/test-crypto-key-objects.js')
-rw-r--r--test/parallel/test-crypto-key-objects.js149
1 files changed, 142 insertions, 7 deletions
diff --git a/test/parallel/test-crypto-key-objects.js b/test/parallel/test-crypto-key-objects.js
index 8d4767f617..ab9005f859 100644
--- a/test/parallel/test-crypto-key-objects.js
+++ b/test/parallel/test-crypto-key-objects.js
@@ -8,6 +8,8 @@ const assert = require('assert');
const {
createCipheriv,
createDecipheriv,
+ createSign,
+ createVerify,
createSecretKey,
createPublicKey,
createPrivateKey,
@@ -178,13 +180,6 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
});
}
-{
- // This should not cause a crash: https://github.com/nodejs/node/pull/26786
- const pem = fixtures.readSync('test_unknown_privkey.pem', 'ascii');
- const key = createPrivateKey(pem);
- assert.strictEqual(key.asymmetricKeyType, undefined);
-}
-
[
{ private: fixtures.readSync('test_ed25519_privkey.pem', 'ascii'),
public: fixtures.readSync('test_ed25519_pubkey.pem', 'ascii'),
@@ -264,6 +259,146 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
assert.strictEqual(privateKey.type, 'private');
assert.strictEqual(privateKey.asymmetricKeyType, 'dsa');
assert.strictEqual(privateKey.symmetricKeySize, undefined);
+
+}
+
+{
+ // Test RSA-PSS.
+ {
+ // This key pair does not restrict the message digest algorithm or salt
+ // length.
+ const publicPem = fixtures.readKey('rsa_pss_public_2048.pem');
+ const privatePem = fixtures.readKey('rsa_pss_private_2048.pem');
+
+ const publicKey = createPublicKey(publicPem);
+ const privateKey = createPrivateKey(privatePem);
+
+ assert.strictEqual(publicKey.type, 'public');
+ assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
+
+ assert.strictEqual(privateKey.type, 'private');
+ assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
+
+ for (const key of [privatePem, privateKey]) {
+ // Any algorithm should work.
+ for (const algo of ['sha1', 'sha256']) {
+ // Any salt length should work.
+ for (const saltLength of [undefined, 8, 10, 12, 16, 18, 20]) {
+ const signature = createSign(algo)
+ .update('foo')
+ .sign({ key, saltLength });
+
+ for (const pkey of [key, publicKey, publicPem]) {
+ const okay = createVerify(algo)
+ .update('foo')
+ .verify({ key: pkey, saltLength }, signature);
+
+ assert.ok(okay);
+ }
+ }
+ }
+ }
+
+ // Exporting the key using PKCS#1 should not work since this would discard
+ // any algorithm restrictions.
+ common.expectsError(() => {
+ publicKey.export({ format: 'pem', type: 'pkcs1' });
+ }, {
+ code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS'
+ });
+ }
+
+ {
+ // This key pair enforces sha256 as the message digest and the MGF1
+ // message digest and a salt length of at least 16 bytes.
+ const publicPem =
+ fixtures.readKey('rsa_pss_public_2048_sha256_sha256_16.pem');
+ const privatePem =
+ fixtures.readKey('rsa_pss_private_2048_sha256_sha256_16.pem');
+
+ const publicKey = createPublicKey(publicPem);
+ const privateKey = createPrivateKey(privatePem);
+
+ assert.strictEqual(publicKey.type, 'public');
+ assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
+
+ assert.strictEqual(privateKey.type, 'private');
+ assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
+
+ for (const key of [privatePem, privateKey]) {
+ // Signing with anything other than sha256 should fail.
+ assert.throws(() => {
+ createSign('sha1').sign(key);
+ }, /digest not allowed/);
+
+ // Signing with salt lengths less than 16 bytes should fail.
+ for (const saltLength of [8, 10, 12]) {
+ assert.throws(() => {
+ createSign('sha1').sign({ key, saltLength });
+ }, /pss saltlen too small/);
+ }
+
+ // Signing with sha256 and appropriate salt lengths should work.
+ for (const saltLength of [undefined, 16, 18, 20]) {
+ const signature = createSign('sha256')
+ .update('foo')
+ .sign({ key, saltLength });
+
+ for (const pkey of [key, publicKey, publicPem]) {
+ const okay = createVerify('sha256')
+ .update('foo')
+ .verify({ key: pkey, saltLength }, signature);
+
+ assert.ok(okay);
+ }
+ }
+ }
+ }
+
+ {
+ // This key enforces sha512 as the message digest and sha256 as the MGF1
+ // message digest.
+ const publicPem =
+ fixtures.readKey('rsa_pss_public_2048_sha512_sha256_20.pem');
+ const privatePem =
+ fixtures.readKey('rsa_pss_private_2048_sha512_sha256_20.pem');
+
+ const publicKey = createPublicKey(publicPem);
+ const privateKey = createPrivateKey(privatePem);
+
+ assert.strictEqual(publicKey.type, 'public');
+ assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
+
+ assert.strictEqual(privateKey.type, 'private');
+ assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
+
+ // Node.js usually uses the same hash function for the message and for MGF1.
+ // However, when a different MGF1 message digest algorithm has been
+ // specified as part of the key, it should automatically switch to that.
+ // This behavior is required by sections 3.1 and 3.3 of RFC4055.
+ for (const key of [privatePem, privateKey]) {
+ // sha256 matches the MGF1 hash function and should be used internally,
+ // but it should not be permitted as the main message digest algorithm.
+ for (const algo of ['sha1', 'sha256']) {
+ assert.throws(() => {
+ createSign(algo).sign(key);
+ }, /digest not allowed/);
+ }
+
+ // sha512 should produce a valid signature.
+ const signature = createSign('sha512')
+ .update('foo')
+ .sign(key);
+
+ for (const pkey of [key, publicKey, publicPem]) {
+ const okay = createVerify('sha512')
+ .update('foo')
+ .verify(pkey, signature);
+
+ assert.ok(okay);
+ }
+ }
+ }
}
{