crypto: convert importKey data as a union

Choose the BufferSource or JsonWebKey branch from the value, then
check the requested format after algorithm normalization.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/66237
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
This commit is contained in:
Filip Skokan authored and Node.js GitHub Bot committed 2026-09-25 13:23:11 +00:00
1 parent 8a899d1231
commit 09b8c8be0a
2 files changed
+45 -1

No files matched your search

+10 -1
View File
@@ -1,6 +1,7 @@
'use strict';
const {
ArrayBufferIsView,
ArrayIsArray,
ArrayPrototypeSlice,
FunctionPrototypeCall,
@@ -39,6 +40,7 @@ const {
const {
codes: {
ERR_ILLEGAL_CONSTRUCTOR,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_THIS,
},
} = require('internal/errors');
@@ -85,6 +87,7 @@ const {
} = require('internal/crypto/random');
const {
isArrayBuffer,
isPromise,
} = require('internal/util/types');
@@ -1114,7 +1117,8 @@ function importKeyImpl(
const prefix = prepareSubtleMethod(this, 'importKey', arguments.length, 5);
let i = 0;
format = convertSubtleArgument(prefix, 'KeyFormat', format, i++);
const type = format === 'jwk' ? 'JsonWebKey' : 'BufferSource';
const type = ArrayBufferIsView(keyData) || isArrayBuffer(keyData) ?
'BufferSource' : 'JsonWebKey';
keyData = convertSubtleArgument(prefix, type, keyData, i++);
algorithm = convertSubtleArgument(
prefix, 'AlgorithmIdentifier', algorithm, i++);
@@ -1124,6 +1128,11 @@ function importKeyImpl(
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'importKey');
if ((format === 'jwk') !== (type === 'JsonWebKey')) {
throw new ERR_INVALID_ARG_TYPE(
'keyData', format === 'jwk' ? 'JsonWebKey' : 'BufferSource', keyData);
}
return FunctionPrototypeCall(
importKeySync,
this,
@@ -0,0 +1,35 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const { subtle } = globalThis.crypto;
const jwk = { kty: 'oct', k: 'AAAAAAAAAAAAAAAAAAAAAA' };
(async () => {
for (const data of [new ArrayBuffer(16), new Uint8Array(16),
new DataView(new ArrayBuffer(16)), Buffer.alloc(16)]) {
await assert.rejects(subtle.importKey('jwk', data, 'AES-GCM', true, ['encrypt']),
TypeError);
Object.assign(data, jwk);
await assert.rejects(subtle.importKey('jwk', data, 'AES-GCM', true, ['encrypt']),
TypeError);
await assert.rejects(subtle.importKey('jwk', data, 'unknown', true, ['encrypt']),
{ name: 'NotSupportedError' });
}
await assert.rejects(subtle.importKey('raw', {}, 'unknown', true, ['encrypt']),
{ name: 'NotSupportedError' });
await assert.rejects(subtle.importKey('raw', {}, 'AES-GCM', true, ['encrypt']),
TypeError);
for (const data of [null, new SharedArrayBuffer(16)]) {
await assert.rejects(subtle.importKey('jwk', data, 'AES-GCM', true, ['encrypt']),
{ name: 'DataError' });
}
assert.strictEqual((await subtle.importKey('jwk', jwk, 'AES-GCM', true,
['encrypt'])).type, 'secret');
await assert.rejects(subtle.importKey('raw', {
get kty() { throw new Error('converted JWK'); },
}, 'unknown', true, ['encrypt']), { message: 'converted JWK' });
})().then(common.mustCall());