Skip to content

Commit fc5b670

Browse files
committed
lib,crypto: validate HkdfParams info length early
Enforces a 1024-byte maximum on `HkdfParams.info` at the WebIDL layer using refactored `validateMaxBufferLength`. Its error message is also fixed. Oversized `info` was already rejected via a different code path. It just relocates the rejection earlier into the WebIDL conversion step so the failure reproduces the OpenSSL's limitation early. Signed-off-by: Filip Skokan <[email protected]>
1 parent 0cb66d0 commit fc5b670

3 files changed

Lines changed: 28 additions & 16 deletions

File tree

lib/internal/crypto/util.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,10 +526,10 @@ const simpleAlgorithmDictionaries = {
526526
TurboShakeParams: {},
527527
};
528528

529-
function validateMaxBufferLength(data, name) {
530-
if (data.byteLength > kMaxBufferLength) {
529+
function validateMaxBufferLength(data, name, max = kMaxBufferLength) {
530+
if (data.byteLength > max) {
531531
throw lazyDOMException(
532-
`${name} must be less than ${kMaxBufferLength + 1} bits`,
532+
`${name} must be at most ${max} bytes`,
533533
'OperationError');
534534
}
535535
}

lib/internal/crypto/webidl.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ converters.HkdfParams = createDictionaryConverter(
567567
{
568568
key: 'info',
569569
converter: converters.BufferSource,
570+
validator: (V, dict) => validateMaxBufferLength(V, 'algorithm.info', 1024),
570571
required: true,
571572
},
572573
]);

test/parallel/test-webcrypto-derivebits-hkdf.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -628,16 +628,27 @@ async function testWrongKeyType(
628628
})().then(common.mustCall());
629629

630630
// https://github.com/w3c/webcrypto/pull/380
631-
{
632-
crypto.subtle.importKey('raw', new Uint8Array(0), 'HKDF', false, ['deriveBits']).then((key) => {
633-
return crypto.subtle.deriveBits({
634-
name: 'HKDF',
635-
hash: { name: 'SHA-256' },
636-
info: new Uint8Array(0),
637-
salt: new Uint8Array(0),
638-
}, key, 0);
639-
}).then((bits) => {
640-
assert.deepStrictEqual(bits, new ArrayBuffer(0));
641-
})
642-
.then(common.mustCall());
643-
}
631+
(async function() {
632+
const key = await crypto.subtle.importKey('raw', new Uint8Array(0), 'HKDF', false, ['deriveBits']);
633+
const bits = await crypto.subtle.deriveBits({
634+
name: 'HKDF',
635+
hash: { name: 'SHA-256' },
636+
info: new Uint8Array(0),
637+
salt: new Uint8Array(0),
638+
}, key, 0);
639+
assert.deepStrictEqual(bits, new ArrayBuffer(0));
640+
})().then(common.mustCall());
641+
642+
// OpenSSL limits info to 1024 bytes
643+
(async function() {
644+
const key = await crypto.subtle.importKey('raw', new Uint8Array(0), 'HKDF', false, ['deriveBits']);
645+
await assert.rejects(crypto.subtle.deriveBits({
646+
name: 'HKDF',
647+
hash: { name: 'SHA-256' },
648+
info: new Uint8Array(1025),
649+
salt: new Uint8Array(0),
650+
}, key, 0), {
651+
name: 'OperationError',
652+
message: 'algorithm.info must be at most 1024 bytes',
653+
});
654+
})().then(common.mustCall());

0 commit comments

Comments
 (0)