Skip to content

Commit c9ea6a9

Browse files
aduh95sxa
authored andcommitted
crypto: validate this value for webcrypto.getRandomValues
PR-URL: #41760 Reviewed-By: Mestery <mestery@protonmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 2b35422 commit c9ea6a9

10 files changed

Lines changed: 59 additions & 36 deletions

‎benchmark/crypto/webcrypto-digest.js‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
constcommon=require('../common.js');
44
const{
55
createHash,
6-
webcrypto: {
7-
subtle,
8-
getRandomValues
9-
}
6+
webcrypto,
107
}=require('crypto');
8+
const{ subtle }=webcrypto;
119

1210
constbench=common.createBenchmark(main,{
1311
sync: ['createHash','subtle'],
@@ -50,7 +48,7 @@ function measureSubtle(n, data, method) {
5048
}
5149

5250
functionmain({ n, sync, data, method }){
53-
data=getRandomValues(Buffer.alloc(data));
51+
data=webcrypto.getRandomValues(Buffer.alloc(data));
5452
switch(sync){
5553
case'createHash': returnmeasureLegacy(n,data,method);
5654
case'subtle': returnmeasureSubtle(n,data,method);

‎doc/api/webcrypto.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,14 @@ async function generateRsaKey(modulusLength = 2048, hash = 'SHA-256') {
128128
### Encryption and decryption
129129

130130
```js
131-
const{ subtle, getRandomValues }=require('crypto').webcrypto;
131+
constcrypto=require('crypto').webcrypto;
132132

133133
asyncfunctionaesEncrypt(plaintext) {
134134
constec=newTextEncoder();
135135
constkey=awaitgenerateAesKey();
136-
constiv=getRandomValues(newUint8Array(16));
136+
constiv=crypto.getRandomValues(newUint8Array(16));
137137

138-
constciphertext=awaitsubtle.encrypt({
138+
constciphertext=awaitcrypto.subtle.encrypt({
139139
name:'AES-CBC',
140140
iv,
141141
}, key, ec.encode(plaintext));
@@ -149,7 +149,7 @@ async function aesEncrypt(plaintext) {
149149

150150
asyncfunctionaesDecrypt(ciphertext, key, iv) {
151151
constdec=newTextDecoder();
152-
constplaintext=awaitsubtle.decrypt({
152+
constplaintext=awaitcrypto.subtle.decrypt({
153153
name:'AES-CBC',
154154
iv,
155155
}, key, ciphertext);

‎lib/internal/crypto/webcrypto.js‎

Lines changed: 10 additions & 1 deletion
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

@@ -64,7 +66,7 @@ const {
6466
}=require('internal/util');
6567

6668
const{
67-
getRandomValues,
69+
getRandomValues: _getRandomValues,
6870
randomUUID: _randomUUID,
6971
}=require('internal/crypto/random');
7072

@@ -695,6 +697,13 @@ class Crypto {
695697
}
696698
constcrypto=newCrypto();
697699

700+
functiongetRandomValues(array){
701+
if(!(thisinstanceofCrypto)){
702+
thrownewERR_INVALID_THIS('Crypto');
703+
}
704+
returnReflectApply(_getRandomValues,this,arguments);
705+
}
706+
698707
ObjectDefineProperties(
699708
Crypto.prototype,{
700709
[SymbolToStringTag]: {

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

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

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

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

251252
{
252253
// Public is a secret key
253-
constkeyData=getRandomValues(newUint8Array(32));
254+
constkeyData=webcrypto.getRandomValues(newUint8Array(32));
254255
constkey=awaitsubtle.importKey(
255256
'raw',
256257
keyData,

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

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

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

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

227228
{
228229
// Public is a secret key
229-
constkeyData=getRandomValues(newUint8Array(32));
230+
constkeyData=webcrypto.getRandomValues(newUint8Array(32));
230231
constkey=awaitsubtle.importKey(
231232
'raw',
232233
keyData,

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

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

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

1112
asyncfunctiontestEncrypt({ 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-
constiv=getRandomValues(newUint8Array(12));
217-
constaad=getRandomValues(newUint8Array(32));
217+
constiv=webcrypto.getRandomValues(newUint8Array(12));
218+
constaad=webcrypto.getRandomValues(newUint8Array(32));
218219

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

230231
awaitsubtle.decrypt(

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

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

88
constassert=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-
constbuf=getRandomValues(newUint8Array(50));
17+
constbuf=webcrypto.getRandomValues(newUint8Array(50));
1718

1819
asyncfunctiontest(){
1920
constec=newTextEncoder();
@@ -44,8 +45,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
4445

4546
// Test Encrypt/Decrypt AES-CTR
4647
{
47-
constbuf=getRandomValues(newUint8Array(50));
48-
constcounter=getRandomValues(newUint8Array(16));
48+
constbuf=webcrypto.getRandomValues(newUint8Array(50));
49+
constcounter=webcrypto.getRandomValues(newUint8Array(16));
4950

5051
asyncfunctiontest(){
5152
constkey=awaitsubtle.generateKey({
@@ -71,8 +72,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
7172

7273
// Test Encrypt/Decrypt AES-CBC
7374
{
74-
constbuf=getRandomValues(newUint8Array(50));
75-
constiv=getRandomValues(newUint8Array(16));
75+
constbuf=webcrypto.getRandomValues(newUint8Array(50));
76+
constiv=webcrypto.getRandomValues(newUint8Array(16));
7677

7778
asyncfunctiontest(){
7879
constkey=awaitsubtle.generateKey({
@@ -98,8 +99,8 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
9899

99100
// Test Encrypt/Decrypt AES-GCM
100101
{
101-
constbuf=getRandomValues(newUint8Array(50));
102-
constiv=getRandomValues(newUint8Array(12));
102+
constbuf=webcrypto.getRandomValues(newUint8Array(50));
103+
constiv=webcrypto.getRandomValues(newUint8Array(12));
103104

104105
asyncfunctiontest(){
105106
constkey=awaitsubtle.generateKey({

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

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

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

1112
{
1213
asyncfunctiontest(){
13-
constkeyData=getRandomValues(newUint8Array(32));
14+
constkeyData=webcrypto.getRandomValues(newUint8Array(32));
1415
awaitPromise.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
asyncfunctiontest(){
85-
constkeyData=getRandomValues(newUint8Array(32));
86+
constkeyData=webcrypto.getRandomValues(newUint8Array(32));
8687
constkey=awaitsubtle.importKey(
8788
'raw',
8889
keyData,{
@@ -112,7 +113,7 @@ const { subtle, getRandomValues } = require('crypto').webcrypto;
112113
// Import/Export AES Secret Key
113114
{
114115
asyncfunctiontest(){
115-
constkeyData=getRandomValues(newUint8Array(32));
116+
constkeyData=webcrypto.getRandomValues(newUint8Array(32));
116117
constkey=awaitsubtle.importKey(
117118
'raw',
118119
keyData,{
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
5+
if(!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
constassert=require('assert');
9+
const{ getRandomValues }=require('crypto').webcrypto;
10+
11+
assert.throws(()=>getRandomValues(newUint8Array()),{code: 'ERR_INVALID_THIS'});

‎test/parallel/test-webcrypto-random.js‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!common.hasCrypto)
77

88
const{ Buffer }=require('buffer');
99
constassert=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
newDataView(newArrayBuffer(1)),
1717
].forEach((i)=>{
1818
assert.throws(
19-
()=>getRandomValues(i),
19+
()=>webcrypto.getRandomValues(i),
2020
{name: 'TypeMismatchError',code: 17},
2121
);
2222
});
2323

2424
{
2525
constbuf=newUint8Array(0);
26-
getRandomValues(buf);
26+
webcrypto.getRandomValues(buf);
2727
}
2828

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

4949
{
5050
constbuf=newUint16Array(10);
5151
constbefore=Buffer.from(buf).toString('hex');
52-
getRandomValues(buf);
52+
webcrypto.getRandomValues(buf);
5353
constafter=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)