From 188c3ab91868c2398db68da6494aee98de553756 Mon Sep 17 00:00:00 2001 From: LiviaMedeiros Date: Wed, 12 Jan 2022 00:49:56 +0800 Subject: [PATCH] crypto: adjust types for getRandomValues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit prevents Web Crypto API's getRandomValues from accepting DataView Fixes: https://github.com/nodejs/node/issues/41480 Refs: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues PR-URL: https://github.com/nodejs/node/pull/41481 Reviewed-By: Derek Lewis Reviewed-By: Luigi Pinca Reviewed-By: Zeyu Yang Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- doc/api/webcrypto.md | 7 +++++-- lib/internal/crypto/random.js | 3 ++- test/parallel/test-webcrypto-random.js | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 191041d50034e1..3d7bf0f946ff05 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -357,12 +357,15 @@ Provides access to the `SubtleCrypto` API. added: v15.0.0 --> -* `typedArray` {Buffer|TypedArray|DataView|ArrayBuffer} -* Returns: {Buffer|TypedArray|DataView|ArrayBuffer} Returns `typedArray`. +* `typedArray` {Buffer|TypedArray} +* Returns: {Buffer|TypedArray} Generates cryptographically strong random values. The given `typedArray` is filled with random values, and a reference to `typedArray` is returned. +The given `typedArray` must be an integer-based instance of {TypedArray}, +i.e. `Float32Array` and `Float64Array` are not accepted. + An error will be thrown if the given `typedArray` is larger than 65,536 bytes. ### `crypto.randomUUID()` diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 8812120091f930..1423ea4295443e 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -50,6 +50,7 @@ const { const { isArrayBufferView, isAnyArrayBuffer, + isTypedArray, isFloat32Array, isFloat64Array, } = require('internal/util/types'); @@ -307,7 +308,7 @@ function onJobDone(buf, callback, error) { // not allowed to exceed 65536 bytes, and can only // be an integer-type TypedArray. function getRandomValues(data) { - if (!isArrayBufferView(data) || + if (!isTypedArray(data) || isFloat32Array(data) || isFloat64Array(data)) { // Ordinarily this would be an ERR_INVALID_ARG_TYPE. However, diff --git a/test/parallel/test-webcrypto-random.js b/test/parallel/test-webcrypto-random.js index f2bf2c396fd20a..e17cc834b6c2bf 100644 --- a/test/parallel/test-webcrypto-random.js +++ b/test/parallel/test-webcrypto-random.js @@ -13,6 +13,7 @@ const { getRandomValues } = require('crypto').webcrypto; undefined, null, '', 1, {}, [], new Float32Array(1), new Float64Array(1), + new DataView(new ArrayBuffer(1)), ].forEach((i) => { assert.throws( () => getRandomValues(i), @@ -32,6 +33,7 @@ const intTypedConstructors = [ Uint8Array, Uint16Array, Uint32Array, + Uint8ClampedArray, BigInt64Array, BigUint64Array, ]; @@ -47,7 +49,7 @@ for (const ctor of intTypedConstructors) { { const buf = new Uint16Array(10); const before = Buffer.from(buf).toString('hex'); - getRandomValues(new DataView(buf.buffer)); + getRandomValues(buf); const after = Buffer.from(buf).toString('hex'); assert.notStrictEqual(before, after); }