Skip to content

Commit

Permalink
crypto: check webcrypto asymmetric key types during importKey
Browse files Browse the repository at this point in the history
PR-URL: #39962
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
panva authored and BethGriggs committed Sep 21, 2021
1 parent 7bddaec commit 105c9e6
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 3 deletions.
3 changes: 3 additions & 0 deletions lib/internal/crypto/dsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ async function dsaImportKey(
'NotSupportedError');
}

if (keyObject.asymmetricKeyType !== 'dsa')
throw lazyDOMException('Invalid key type', 'DataError');

const {
modulusLength,
divisorLength,
Expand Down
33 changes: 33 additions & 0 deletions lib/internal/crypto/ec.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,39 @@ async function ecImportKey(
}
}

switch (algorithm.name) {
case 'ECDSA':
if (keyObject.asymmetricKeyType !== 'ec')
throw lazyDOMException('Invalid key type', 'DataError');
break;
case 'ECDH':
if (
algorithm.namedCurve === 'NODE-X25519' &&
keyObject.asymmetricKeyType !== 'x25519'
) {
throw lazyDOMException('Invalid key type', 'DataError');
} else if (
algorithm.namedCurve === 'NODE-X448' &&
keyObject.asymmetricKeyType !== 'x448'
) {
throw lazyDOMException('Invalid key type', 'DataError');
} else if (
algorithm.namedCurve.startsWith('P') &&
keyObject.asymmetricKeyType !== 'ec'
) {
throw lazyDOMException('Invalid key type', 'DataError');
}
break;
case 'NODE-ED25519':
if (keyObject.asymmetricKeyType !== 'ed25519')
throw lazyDOMException('Invalid key type', 'DataError');
break;
case 'NODE-ED448':
if (keyObject.asymmetricKeyType !== 'ed448')
throw lazyDOMException('Invalid key type', 'DataError');
break;
}

if (checkNamedCurve) {
const {
namedCurve: checkNamedCurve
Expand Down
11 changes: 11 additions & 0 deletions lib/internal/crypto/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,17 @@ async function rsaImportKey(
'NotSupportedError');
}

if (algorithm.name === 'RSA-PSS') {
if (
keyObject.asymmetricKeyType !== 'rsa' &&
keyObject.asymmetricKeyType !== 'rsa-pss'
) {
throw lazyDOMException('Invalid key type', 'DataError');
}
} else if (keyObject.asymmetricKeyType !== 'rsa') {
throw lazyDOMException('Invalid key type', 'DataError');
}

const {
modulusLength,
publicExponent,
Expand Down
32 changes: 31 additions & 1 deletion test/parallel/test-webcrypto-export-import-dsa.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
'use strict';

const common = require('../common');
const fixtures = require('../common/fixtures');

if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const crypto = require('crypto');
const { subtle } = crypto.webcrypto;

const sizes = [1024];

Expand Down Expand Up @@ -132,3 +134,31 @@ const testVectors = [
});
await Promise.all(variations);
})().then(common.mustCall());

{
const ecPublic = crypto.createPublicKey(
fixtures.readKey('ec_p256_public.pem'));
const ecPrivate = crypto.createPrivateKey(
fixtures.readKey('ec_p256_private.pem'));

assert.rejects(subtle.importKey(
'node.keyObject',
ecPublic,
{ name: 'NODE-DSA', hash: 'SHA-256' },
true, ['verify']), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'node.keyObject',
ecPrivate,
{ name: 'NODE-DSA', hash: 'SHA-256' },
true, ['sign']), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'spki',
ecPublic.export({ format: 'der', type: 'spki' }),
{ name: 'NODE-DSA', hash: 'SHA-256' },
true, ['verify']), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'pkcs8',
ecPrivate.export({ format: 'der', type: 'pkcs8' }),
{ name: 'NODE-DSA', hash: 'SHA-256' },
true, ['sign']), { message: /Invalid key type/ });
}
37 changes: 36 additions & 1 deletion test/parallel/test-webcrypto-export-import-ec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
'use strict';

const common = require('../common');
const fixtures = require('../common/fixtures');

if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const crypto = require('crypto');
const { subtle } = crypto.webcrypto;

const curves = ['P-256', 'P-384', 'P-521'];

Expand Down Expand Up @@ -274,3 +276,36 @@ async function testImportJwk(

await Promise.all(tests);
})().then(common.mustCall());

{
const rsaPublic = crypto.createPublicKey(
fixtures.readKey('rsa_public_2048.pem'));
const rsaPrivate = crypto.createPrivateKey(
fixtures.readKey('rsa_private_2048.pem'));

for (const [name, [publicUsage, privateUsage]] of Object.entries({
'ECDSA': ['verify', 'sign'],
'ECDH': ['deriveBits', 'deriveBits'],
})) {
assert.rejects(subtle.importKey(
'node.keyObject',
rsaPublic,
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
true, [publicUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'node.keyObject',
rsaPrivate,
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
true, [privateUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'spki',
rsaPublic.export({ format: 'der', type: 'spki' }),
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
true, [publicUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'pkcs8',
rsaPrivate.export({ format: 'der', type: 'pkcs8' }),
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
true, [privateUsage]), { message: /Invalid key type/ });
}
}
37 changes: 36 additions & 1 deletion test/parallel/test-webcrypto-export-import-rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { subtle } = require('crypto').webcrypto;
const crypto = require('crypto');
const { subtle } = crypto.webcrypto;

const sizes = [1024, 2048, 4096];

Expand Down Expand Up @@ -521,3 +522,37 @@ const testVectors = [
assert.strictEqual(jwk.alg, 'PS256');
})().then(common.mustCall());
}

{
const ecPublic = crypto.createPublicKey(
fixtures.readKey('ec_p256_public.pem'));
const ecPrivate = crypto.createPrivateKey(
fixtures.readKey('ec_p256_private.pem'));

for (const [name, [publicUsage, privateUsage]] of Object.entries({
'RSA-PSS': ['verify', 'sign'],
'RSASSA-PKCS1-v1_5': ['verify', 'sign'],
'RSA-OAEP': ['encrypt', 'decrypt'],
})) {
assert.rejects(subtle.importKey(
'node.keyObject',
ecPublic,
{ name, hash: 'SHA-256' },
true, [publicUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'node.keyObject',
ecPrivate,
{ name, hash: 'SHA-256' },
true, [privateUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'spki',
ecPublic.export({ format: 'der', type: 'spki' }),
{ name, hash: 'SHA-256' },
true, [publicUsage]), { message: /Invalid key type/ });
assert.rejects(subtle.importKey(
'pkcs8',
ecPrivate.export({ format: 'der', type: 'pkcs8' }),
{ name, hash: 'SHA-256' },
true, [privateUsage]), { message: /Invalid key type/ });
}
}

0 comments on commit 105c9e6

Please sign in to comment.