Skip to content

Commit 105c9e6

Browse files
panvaBethGriggs
authored andcommittedSep 21, 2021
crypto: check webcrypto asymmetric key types during importKey
PR-URL: #39962 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 7bddaec commit 105c9e6

6 files changed

+150
-3
lines changed
 

‎lib/internal/crypto/dsa.js

+3
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ async function dsaImportKey(
230230
'NotSupportedError');
231231
}
232232

233+
if (keyObject.asymmetricKeyType !== 'dsa')
234+
throw lazyDOMException('Invalid key type', 'DataError');
235+
233236
const {
234237
modulusLength,
235238
divisorLength,

‎lib/internal/crypto/ec.js

+33
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,39 @@ async function ecImportKey(
430430
}
431431
}
432432

433+
switch (algorithm.name) {
434+
case 'ECDSA':
435+
if (keyObject.asymmetricKeyType !== 'ec')
436+
throw lazyDOMException('Invalid key type', 'DataError');
437+
break;
438+
case 'ECDH':
439+
if (
440+
algorithm.namedCurve === 'NODE-X25519' &&
441+
keyObject.asymmetricKeyType !== 'x25519'
442+
) {
443+
throw lazyDOMException('Invalid key type', 'DataError');
444+
} else if (
445+
algorithm.namedCurve === 'NODE-X448' &&
446+
keyObject.asymmetricKeyType !== 'x448'
447+
) {
448+
throw lazyDOMException('Invalid key type', 'DataError');
449+
} else if (
450+
algorithm.namedCurve.startsWith('P') &&
451+
keyObject.asymmetricKeyType !== 'ec'
452+
) {
453+
throw lazyDOMException('Invalid key type', 'DataError');
454+
}
455+
break;
456+
case 'NODE-ED25519':
457+
if (keyObject.asymmetricKeyType !== 'ed25519')
458+
throw lazyDOMException('Invalid key type', 'DataError');
459+
break;
460+
case 'NODE-ED448':
461+
if (keyObject.asymmetricKeyType !== 'ed448')
462+
throw lazyDOMException('Invalid key type', 'DataError');
463+
break;
464+
}
465+
433466
if (checkNamedCurve) {
434467
const {
435468
namedCurve: checkNamedCurve

‎lib/internal/crypto/rsa.js

+11
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,17 @@ async function rsaImportKey(
326326
'NotSupportedError');
327327
}
328328

329+
if (algorithm.name === 'RSA-PSS') {
330+
if (
331+
keyObject.asymmetricKeyType !== 'rsa' &&
332+
keyObject.asymmetricKeyType !== 'rsa-pss'
333+
) {
334+
throw lazyDOMException('Invalid key type', 'DataError');
335+
}
336+
} else if (keyObject.asymmetricKeyType !== 'rsa') {
337+
throw lazyDOMException('Invalid key type', 'DataError');
338+
}
339+
329340
const {
330341
modulusLength,
331342
publicExponent,

‎test/parallel/test-webcrypto-export-import-dsa.js

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
'use strict';
22

33
const common = require('../common');
4+
const fixtures = require('../common/fixtures');
45

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

89
const assert = require('assert');
9-
const { subtle } = require('crypto').webcrypto;
10+
const crypto = require('crypto');
11+
const { subtle } = crypto.webcrypto;
1012

1113
const sizes = [1024];
1214

@@ -132,3 +134,31 @@ const testVectors = [
132134
});
133135
await Promise.all(variations);
134136
})().then(common.mustCall());
137+
138+
{
139+
const ecPublic = crypto.createPublicKey(
140+
fixtures.readKey('ec_p256_public.pem'));
141+
const ecPrivate = crypto.createPrivateKey(
142+
fixtures.readKey('ec_p256_private.pem'));
143+
144+
assert.rejects(subtle.importKey(
145+
'node.keyObject',
146+
ecPublic,
147+
{ name: 'NODE-DSA', hash: 'SHA-256' },
148+
true, ['verify']), { message: /Invalid key type/ });
149+
assert.rejects(subtle.importKey(
150+
'node.keyObject',
151+
ecPrivate,
152+
{ name: 'NODE-DSA', hash: 'SHA-256' },
153+
true, ['sign']), { message: /Invalid key type/ });
154+
assert.rejects(subtle.importKey(
155+
'spki',
156+
ecPublic.export({ format: 'der', type: 'spki' }),
157+
{ name: 'NODE-DSA', hash: 'SHA-256' },
158+
true, ['verify']), { message: /Invalid key type/ });
159+
assert.rejects(subtle.importKey(
160+
'pkcs8',
161+
ecPrivate.export({ format: 'der', type: 'pkcs8' }),
162+
{ name: 'NODE-DSA', hash: 'SHA-256' },
163+
true, ['sign']), { message: /Invalid key type/ });
164+
}

‎test/parallel/test-webcrypto-export-import-ec.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
'use strict';
22

33
const common = require('../common');
4+
const fixtures = require('../common/fixtures');
45

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

89
const assert = require('assert');
9-
const { subtle } = require('crypto').webcrypto;
10+
const crypto = require('crypto');
11+
const { subtle } = crypto.webcrypto;
1012

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

@@ -274,3 +276,36 @@ async function testImportJwk(
274276

275277
await Promise.all(tests);
276278
})().then(common.mustCall());
279+
280+
{
281+
const rsaPublic = crypto.createPublicKey(
282+
fixtures.readKey('rsa_public_2048.pem'));
283+
const rsaPrivate = crypto.createPrivateKey(
284+
fixtures.readKey('rsa_private_2048.pem'));
285+
286+
for (const [name, [publicUsage, privateUsage]] of Object.entries({
287+
'ECDSA': ['verify', 'sign'],
288+
'ECDH': ['deriveBits', 'deriveBits'],
289+
})) {
290+
assert.rejects(subtle.importKey(
291+
'node.keyObject',
292+
rsaPublic,
293+
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
294+
true, [publicUsage]), { message: /Invalid key type/ });
295+
assert.rejects(subtle.importKey(
296+
'node.keyObject',
297+
rsaPrivate,
298+
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
299+
true, [privateUsage]), { message: /Invalid key type/ });
300+
assert.rejects(subtle.importKey(
301+
'spki',
302+
rsaPublic.export({ format: 'der', type: 'spki' }),
303+
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
304+
true, [publicUsage]), { message: /Invalid key type/ });
305+
assert.rejects(subtle.importKey(
306+
'pkcs8',
307+
rsaPrivate.export({ format: 'der', type: 'pkcs8' }),
308+
{ name, hash: 'SHA-256', namedCurve: 'P-256' },
309+
true, [privateUsage]), { message: /Invalid key type/ });
310+
}
311+
}

‎test/parallel/test-webcrypto-export-import-rsa.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ if (!common.hasCrypto)
77
common.skip('missing crypto');
88

99
const assert = require('assert');
10-
const { subtle } = require('crypto').webcrypto;
10+
const crypto = require('crypto');
11+
const { subtle } = crypto.webcrypto;
1112

1213
const sizes = [1024, 2048, 4096];
1314

@@ -521,3 +522,37 @@ const testVectors = [
521522
assert.strictEqual(jwk.alg, 'PS256');
522523
})().then(common.mustCall());
523524
}
525+
526+
{
527+
const ecPublic = crypto.createPublicKey(
528+
fixtures.readKey('ec_p256_public.pem'));
529+
const ecPrivate = crypto.createPrivateKey(
530+
fixtures.readKey('ec_p256_private.pem'));
531+
532+
for (const [name, [publicUsage, privateUsage]] of Object.entries({
533+
'RSA-PSS': ['verify', 'sign'],
534+
'RSASSA-PKCS1-v1_5': ['verify', 'sign'],
535+
'RSA-OAEP': ['encrypt', 'decrypt'],
536+
})) {
537+
assert.rejects(subtle.importKey(
538+
'node.keyObject',
539+
ecPublic,
540+
{ name, hash: 'SHA-256' },
541+
true, [publicUsage]), { message: /Invalid key type/ });
542+
assert.rejects(subtle.importKey(
543+
'node.keyObject',
544+
ecPrivate,
545+
{ name, hash: 'SHA-256' },
546+
true, [privateUsage]), { message: /Invalid key type/ });
547+
assert.rejects(subtle.importKey(
548+
'spki',
549+
ecPublic.export({ format: 'der', type: 'spki' }),
550+
{ name, hash: 'SHA-256' },
551+
true, [publicUsage]), { message: /Invalid key type/ });
552+
assert.rejects(subtle.importKey(
553+
'pkcs8',
554+
ecPrivate.export({ format: 'der', type: 'pkcs8' }),
555+
{ name, hash: 'SHA-256' },
556+
true, [privateUsage]), { message: /Invalid key type/ });
557+
}
558+
}

0 commit comments

Comments
 (0)
Please sign in to comment.