Skip to content

Commit 62e34b5

Browse files
committed
crypto: validate this value for webcrypto.getRandomValues
1 parent 05e9cb6 commit 62e34b5

8 files changed

+52
-27
lines changed

lib/internal/crypto/webcrypto.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
JSONParse,
66
JSONStringify,
77
ObjectDefineProperties,
8+
ReflectApply,
89
SafeSet,
910
SymbolToStringTag,
1011
StringPrototypeRepeat,
@@ -31,6 +32,7 @@ const { TextDecoder, TextEncoder } = require('internal/encoding');
3132
const {
3233
codes: {
3334
ERR_INVALID_ARG_TYPE,
35+
ERR_INVALID_THIS,
3436
}
3537
} = require('internal/errors');
3638

@@ -63,7 +65,7 @@ const {
6365
} = require('internal/util');
6466

6567
const {
66-
getRandomValues,
68+
getRandomValues: _getRandomValues,
6769
randomUUID: _randomUUID,
6870
} = require('internal/crypto/random');
6971

@@ -690,6 +692,13 @@ const subtle = new SubtleCrypto();
690692
class Crypto {}
691693
const crypto = new Crypto();
692694

695+
function getRandomValues(array) {
696+
if (!(this instanceof Crypto)) {
697+
throw new ERR_INVALID_THIS('Crypto');
698+
}
699+
return ReflectApply(_getRandomValues, this, arguments);
700+
}
701+
693702
ObjectDefineProperties(
694703
Crypto.prototype, {
695704
[SymbolToStringTag]: {

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ if (!common.hasCrypto)
66
common.skip('missing crypto');
77

88
const assert = require('assert');
9-
const { subtle, getRandomValues } = require('crypto').webcrypto;
9+
const { webcrypto } = require('crypto');
10+
const { subtle } = webcrypto;
1011

1112
const kTests = [
1213
{
@@ -250,7 +251,7 @@ async function prepareKeys() {
250251

251252
{
252253
// Public is a secret key
253-
const keyData = getRandomValues(new Uint8Array(32));
254+
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
254255
const key = await subtle.importKey(
255256
'raw',
256257
keyData,

test/parallel/test-webcrypto-derivekey-ecdh.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ if (!common.hasCrypto)
66
common.skip('missing crypto');
77

88
const assert = require('assert');
9-
const { subtle, getRandomValues } = require('crypto').webcrypto;
9+
const { webcrypto } = require('crypto');
10+
const { subtle } = webcrypto;
1011

1112
const kTests = [
1213
{
@@ -226,7 +227,7 @@ async function prepareKeys() {
226227

227228
{
228229
// Public is a secret key
229-
const keyData = getRandomValues(new Uint8Array(32));
230+
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
230231
const key = await subtle.importKey(
231232
'raw',
232233
keyData,

test/parallel/test-webcrypto-encrypt-decrypt-aes.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ if (!common.hasCrypto)
66
common.skip('missing crypto');
77

88
const assert = require('assert');
9-
const { getRandomValues, subtle } = require('crypto').webcrypto;
9+
const { webcrypto } = require('crypto');
10+
const { subtle } = webcrypto;
1011

1112
async function testEncrypt({ keyBuffer, algorithm, plaintext, result }) {
1213
// Using a copy of plaintext to prevent tampering of the original
@@ -213,8 +214,8 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
213214
['encrypt', 'decrypt'],
214215
);
215216

216-
const iv = getRandomValues(new Uint8Array(12));
217-
const aad = getRandomValues(new Uint8Array(32));
217+
const iv = webcrypto.getRandomValues(new Uint8Array(12));
218+
const aad = webcrypto.getRandomValues(new Uint8Array(32));
218219

219220
const encrypted = await subtle.encrypt(
220221
{
@@ -224,7 +225,7 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
224225
tagLength: 128
225226
},
226227
secretKey,
227-
getRandomValues(new Uint8Array(32))
228+
webcrypto.getRandomValues(new Uint8Array(32))
228229
);
229230

230231
await subtle.decrypt(

test/parallel/test-webcrypto-encrypt-decrypt.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ if (!common.hasCrypto)
66
common.skip('missing crypto');
77

88
const assert = require('assert');
9-
const { subtle, getRandomValues } = require('crypto').webcrypto;
9+
const { webcrypto } = require('crypto');
10+
const { subtle } = webcrypto;
1011

1112
// This is only a partial test. The WebCrypto Web Platform Tests
1213
// will provide much greater coverage.
1314

1415
// Test Encrypt/Decrypt RSA-OAEP
1516
{
16-
const buf = getRandomValues(new Uint8Array(50));
17+
const buf = webcrypto.getRandomValues(new Uint8Array(50));
1718

1819
async function test() {
1920
const ec = new TextEncoder();
@@ -44,8 +45,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
4445

4546
// Test Encrypt/Decrypt AES-CTR
4647
{
47-
const buf = getRandomValues(new Uint8Array(50));
48-
const counter = getRandomValues(new Uint8Array(16));
48+
const buf = webcrypto.getRandomValues(new Uint8Array(50));
49+
const counter = webcrypto.getRandomValues(new Uint8Array(16));
4950

5051
async function test() {
5152
const key = await subtle.generateKey({
@@ -71,8 +72,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
7172

7273
// Test Encrypt/Decrypt AES-CBC
7374
{
74-
const buf = getRandomValues(new Uint8Array(50));
75-
const iv = getRandomValues(new Uint8Array(16));
75+
const buf = webcrypto.getRandomValues(new Uint8Array(50));
76+
const iv = webcrypto.getRandomValues(new Uint8Array(16));
7677

7778
async function test() {
7879
const key = await subtle.generateKey({
@@ -98,8 +99,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
9899

99100
// Test Encrypt/Decrypt AES-GCM
100101
{
101-
const buf = getRandomValues(new Uint8Array(50));
102-
const iv = getRandomValues(new Uint8Array(12));
102+
const buf = webcrypto.getRandomValues(new Uint8Array(50));
103+
const iv = webcrypto.getRandomValues(new Uint8Array(12));
103104

104105
async function test() {
105106
const key = await subtle.generateKey({

test/parallel/test-webcrypto-export-import.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ if (!common.hasCrypto)
66
common.skip('missing crypto');
77

88
const assert = require('assert');
9-
const { subtle, getRandomValues } = require('crypto').webcrypto;
9+
const { webcrypto } = require('crypto');
10+
const { subtle } = webcrypto;
1011

1112
{
1213
async function test() {
13-
const keyData = getRandomValues(new Uint8Array(32));
14+
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
1415
await Promise.all([1, null, undefined, {}, []].map((format) =>
1516
assert.rejects(
1617
subtle.importKey(format, keyData, {}, false, ['wrapKey']), {
@@ -82,7 +83,7 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
8283
// Import/Export HMAC Secret Key
8384
{
8485
async function test() {
85-
const keyData = getRandomValues(new Uint8Array(32));
86+
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
8687
const key = await subtle.importKey(
8788
'raw',
8889
keyData, {
@@ -112,7 +113,7 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
112113
// Import/Export AES Secret Key
113114
{
114115
async function test() {
115-
const keyData = getRandomValues(new Uint8Array(32));
116+
const keyData = webcrypto.getRandomValues(new Uint8Array(32));
116117
const key = await subtle.importKey(
117118
'raw',
118119
keyData, {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 { getRandomValues } = require('crypto').webcrypto;
10+
11+
assert.throws(() => getRandomValues(new Uint8Array()), { code: 'ERR_INVALID_THIS' });

test/parallel/test-webcrypto-random.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!common.hasCrypto)
77

88
const { Buffer } = require('buffer');
99
const assert = require('assert');
10-
const { getRandomValues } = require('crypto').webcrypto;
10+
const { webcrypto } = require('crypto');
1111

1212
[
1313
undefined, null, '', 1, {}, [],
@@ -16,14 +16,14 @@ const { getRandomValues } = require('crypto').webcrypto;
1616
new DataView(new ArrayBuffer(1)),
1717
].forEach((i) => {
1818
assert.throws(
19-
() => getRandomValues(i),
19+
() => webcrypto.getRandomValues(i),
2020
{ name: 'TypeMismatchError', code: 17 },
2121
);
2222
});
2323

2424
{
2525
const buf = new Uint8Array(0);
26-
getRandomValues(buf);
26+
webcrypto.getRandomValues(buf);
2727
}
2828

2929
const intTypedConstructors = [
@@ -41,15 +41,15 @@ const intTypedConstructors = [
4141
for (const ctor of intTypedConstructors) {
4242
const buf = new ctor(10);
4343
const before = Buffer.from(buf.buffer).toString('hex');
44-
getRandomValues(buf);
44+
webcrypto.getRandomValues(buf);
4545
const after = Buffer.from(buf.buffer).toString('hex');
4646
assert.notStrictEqual(before, after);
4747
}
4848

4949
{
5050
const buf = new Uint16Array(10);
5151
const before = Buffer.from(buf).toString('hex');
52-
getRandomValues(buf);
52+
webcrypto.getRandomValues(buf);
5353
const after = Buffer.from(buf).toString('hex');
5454
assert.notStrictEqual(before, after);
5555
}
@@ -63,7 +63,7 @@ for (const ctor of intTypedConstructors) {
6363
}
6464

6565
if (kData !== undefined) {
66-
assert.throws(() => getRandomValues(kData), {
66+
assert.throws(() => webcrypto.getRandomValues(kData), {
6767
code: 22
6868
});
6969
}

0 commit comments

Comments
 (0)