crypto: copy derived bits without species

Use the byte-copy helper for truncated ECDH results so ArrayBuffer
species cannot replace or resize the returned key material.

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:16 +00:00
1 parent fb602d182d
commit f930e3ad44
2 files changed
+28 -6

No files matched your search

+2 -6
View File
@@ -2,7 +2,6 @@
const {
ArrayBufferPrototypeGetByteLength,
ArrayBufferPrototypeSlice,
FunctionPrototypeCall,
ObjectDefineProperty,
TypedArrayPrototypeGetBuffer,
@@ -381,11 +380,8 @@ function ecdhDeriveBits(algorithm, baseKey, length) {
if (byteLength < sliceLength)
throw lazyDOMException('derived bit length is too small', 'OperationError');
if (length % 8 === 0) {
if (byteLength === sliceLength)
return bits;
return ArrayBufferPrototypeSlice(bits, 0, sliceLength);
}
if (length % 8 === 0 && byteLength === sliceLength)
return bits;
return TypedArrayPrototypeGetBuffer(truncateToBitLength(length, bits));
});
@@ -0,0 +1,26 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const { subtle } = globalThis.crypto;
(async () => {
const keys = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveBits']);
const algorithm = { name: 'ECDH', public: keys.publicKey };
const expected = await subtle.deriveBits(algorithm, keys.privateKey, 128);
const species = Object.getOwnPropertyDescriptor(ArrayBuffer, Symbol.species);
Object.defineProperty(ArrayBuffer, Symbol.species, {
configurable: true,
get: common.mustNotCall(),
});
try {
const actual = await subtle.deriveBits(algorithm, keys.privateKey, 128);
assert.deepStrictEqual(actual, expected);
assert.strictEqual(Object.getPrototypeOf(actual), ArrayBuffer.prototype);
} finally {
Object.defineProperty(ArrayBuffer, Symbol.species, species);
}
})().then(common.mustCall());