Skip to content

Commit 622f4e1

Browse files
panvaaduh95
authored andcommitted
crypto: make webcrypto aliasKeyFormat directional
The helper no longer treats every raw alias the same way and unintended values were accepted for some algorithms. Signed-off-by: Filip Skokan <[email protected]> PR-URL: #63910 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
1 parent 1bac086 commit 622f4e1

2 files changed

Lines changed: 77 additions & 12 deletions

File tree

lib/internal/crypto/webcrypto.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -839,14 +839,8 @@ function parseJwk(data) {
839839
return key;
840840
}
841841

842-
function aliasKeyFormat(format) {
843-
switch (format) {
844-
case 'raw-public':
845-
case 'raw-secret':
846-
return 'raw';
847-
default:
848-
return format;
849-
}
842+
function aliasKeyFormat(format, alias) {
843+
return format === alias ? 'raw' : format;
850844
}
851845

852846
function importKeySync(format, keyData, algorithm, extractable, usages) {
@@ -857,7 +851,6 @@ function importKeySync(format, keyData, algorithm, extractable, usages) {
857851
case 'RSA-PSS':
858852
// Fall through
859853
case 'RSA-OAEP':
860-
format = aliasKeyFormat(format);
861854
result = require('internal/crypto/rsa')
862855
.rsaImportKey(
863856
format,
@@ -869,7 +862,7 @@ function importKeySync(format, keyData, algorithm, extractable, usages) {
869862
case 'ECDSA':
870863
// Fall through
871864
case 'ECDH':
872-
format = aliasKeyFormat(format);
865+
format = aliasKeyFormat(format, 'raw-public');
873866
result = require('internal/crypto/ec')
874867
.ecImportKey(
875868
format,
@@ -885,7 +878,7 @@ function importKeySync(format, keyData, algorithm, extractable, usages) {
885878
case 'X25519':
886879
// Fall through
887880
case 'X448':
888-
format = aliasKeyFormat(format);
881+
format = aliasKeyFormat(format, 'raw-public');
889882
result = require('internal/crypto/cfrg')
890883
.cfrgImportKey(
891884
format,
@@ -936,7 +929,7 @@ function importKeySync(format, keyData, algorithm, extractable, usages) {
936929
case 'HKDF':
937930
// Fall through
938931
case 'PBKDF2':
939-
format = aliasKeyFormat(format);
932+
format = aliasKeyFormat(format, 'raw-secret');
940933
result = importGenericSecretKey(
941934
algorithm,
942935
format,
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const assert = require('assert');
9+
const { subtle } = globalThis.crypto;
10+
11+
function getAlgorithmName(algorithm) {
12+
return typeof algorithm === 'string' ? algorithm : algorithm.name;
13+
}
14+
15+
function assertImportNotSupported(format, keyData, algorithm, extractable, usages) {
16+
return assert.rejects(
17+
subtle.importKey(format, keyData, algorithm, extractable, usages),
18+
{
19+
name: 'NotSupportedError',
20+
message: `Unable to import ${getAlgorithmName(algorithm)} using ${format} format`,
21+
});
22+
}
23+
24+
async function assertSecretKeyDoesNotAcceptRawPublic(algorithm) {
25+
const keyData = new Uint8Array(32);
26+
await assertImportNotSupported(
27+
'raw-public',
28+
keyData,
29+
algorithm,
30+
false,
31+
['deriveBits']);
32+
}
33+
34+
async function assertPublicKeyDoesNotAcceptRawSecret(
35+
algorithm,
36+
generateUsages,
37+
importUsages,
38+
) {
39+
const { publicKey } = await subtle.generateKey(
40+
algorithm,
41+
true,
42+
generateUsages);
43+
const keyData = await subtle.exportKey('raw', publicKey);
44+
45+
await assertImportNotSupported(
46+
'raw-secret',
47+
keyData,
48+
algorithm,
49+
true,
50+
importUsages);
51+
}
52+
53+
Promise.all([
54+
assertSecretKeyDoesNotAcceptRawPublic('HKDF'),
55+
assertSecretKeyDoesNotAcceptRawPublic('PBKDF2'),
56+
assertPublicKeyDoesNotAcceptRawSecret(
57+
{ name: 'ECDSA', namedCurve: 'P-256' },
58+
['sign', 'verify'],
59+
['verify']),
60+
assertPublicKeyDoesNotAcceptRawSecret(
61+
{ name: 'ECDH', namedCurve: 'P-256' },
62+
['deriveBits'],
63+
[]),
64+
assertPublicKeyDoesNotAcceptRawSecret(
65+
'Ed25519',
66+
['sign', 'verify'],
67+
['verify']),
68+
assertPublicKeyDoesNotAcceptRawSecret(
69+
'X25519',
70+
['deriveBits'],
71+
[]),
72+
]).then(common.mustCall());

0 commit comments

Comments
 (0)