Skip to content

Commit 75f3b28

Browse files
committed
crypto: refactor array buffer view validation
This is just a refactoring to reduce code and computational overhead. PR-URL: #29683 Reviewed-By: James M Snell <[email protected]>
1 parent 3153dd6 commit 75f3b28

File tree

7 files changed

+36
-63
lines changed

7 files changed

+36
-63
lines changed

lib/internal/crypto/certificate.js

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ const {
99
validateBuffer
1010
} = require('internal/validators');
1111

12-
const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes;
13-
const { isArrayBufferView } = require('internal/util/types');
14-
1512
const {
16-
toBuf
13+
getArrayBufferView
1714
} = require('internal/crypto/util');
1815

1916
function verifySpkac(spkac) {
@@ -22,27 +19,15 @@ function verifySpkac(spkac) {
2219
}
2320

2421
function exportPublicKey(spkac, encoding) {
25-
spkac = toBuf(spkac, encoding);
26-
if (!isArrayBufferView(spkac)) {
27-
throw new ERR_INVALID_ARG_TYPE(
28-
'spkac',
29-
['string', 'Buffer', 'TypedArray', 'DataView'],
30-
spkac
31-
);
32-
}
33-
return certExportPublicKey(spkac);
22+
return certExportPublicKey(
23+
getArrayBufferView(spkac, 'spkac', encoding)
24+
);
3425
}
3526

3627
function exportChallenge(spkac, encoding) {
37-
spkac = toBuf(spkac, encoding);
38-
if (!isArrayBufferView(spkac)) {
39-
throw new ERR_INVALID_ARG_TYPE(
40-
'spkac',
41-
['string', 'Buffer', 'TypedArray', 'DataView'],
42-
spkac
43-
);
44-
}
45-
return certExportChallenge(spkac);
28+
return certExportChallenge(
29+
getArrayBufferView(spkac, 'spkac', encoding)
30+
);
4631
}
4732

4833
// For backwards compatibility reasons, this cannot be converted into a

lib/internal/crypto/cipher.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const {
2222
const {
2323
getDefaultEncoding,
2424
kHandle,
25-
toBuf
25+
getArrayBufferView
2626
} = require('internal/crypto/util');
2727

2828
const { isArrayBufferView } = require('internal/util/types');
@@ -105,31 +105,17 @@ function createCipherBase(cipher, credential, options, decipher, iv) {
105105
LazyTransform.call(this, options);
106106
}
107107

108-
function invalidArrayBufferView(name, value) {
109-
return new ERR_INVALID_ARG_TYPE(
110-
name,
111-
['string', 'Buffer', 'TypedArray', 'DataView'],
112-
value
113-
);
114-
}
115-
116108
function createCipher(cipher, password, options, decipher) {
117109
validateString(cipher, 'cipher');
118-
password = toBuf(password);
119-
if (!isArrayBufferView(password)) {
120-
throw invalidArrayBufferView('password', password);
121-
}
110+
password = getArrayBufferView(password, 'password');
122111

123112
createCipherBase.call(this, cipher, password, options, decipher);
124113
}
125114

126115
function createCipherWithIV(cipher, key, options, decipher, iv) {
127116
validateString(cipher, 'cipher');
128117
key = prepareSecretKey(key);
129-
iv = toBuf(iv);
130-
if (iv !== null && !isArrayBufferView(iv)) {
131-
throw invalidArrayBufferView('iv', iv);
132-
}
118+
iv = iv === null ? null : getArrayBufferView(iv, 'iv');
133119
createCipherBase.call(this, cipher, key, options, decipher, iv);
134120
}
135121

@@ -164,7 +150,8 @@ Cipher.prototype.update = function update(data, inputEncoding, outputEncoding) {
164150
outputEncoding = outputEncoding || encoding;
165151

166152
if (typeof data !== 'string' && !isArrayBufferView(data)) {
167-
throw invalidArrayBufferView('data', data);
153+
throw new ERR_INVALID_ARG_TYPE(
154+
'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data);
168155
}
169156

170157
const ret = this[kHandle].update(data, inputEncoding);

lib/internal/crypto/pbkdf2.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const {
1313
} = require('internal/errors').codes;
1414
const {
1515
getDefaultEncoding,
16-
validateArrayBufferView,
16+
getArrayBufferView,
1717
} = require('internal/crypto/util');
1818

1919
function pbkdf2(password, salt, iterations, keylen, digest, callback) {
@@ -64,8 +64,8 @@ function check(password, salt, iterations, keylen, digest) {
6464
digest = defaultDigest();
6565
}
6666

67-
password = validateArrayBufferView(password, 'password');
68-
salt = validateArrayBufferView(salt, 'salt');
67+
password = getArrayBufferView(password, 'password');
68+
salt = getArrayBufferView(salt, 'salt');
6969
validateUint32(iterations, 'iterations', 0);
7070
validateUint32(keylen, 'keylen', 0);
7171

lib/internal/crypto/scrypt.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const {
1111
} = require('internal/errors').codes;
1212
const {
1313
getDefaultEncoding,
14-
validateArrayBufferView,
14+
getArrayBufferView,
1515
} = require('internal/crypto/util');
1616

1717
const defaults = {
@@ -72,8 +72,8 @@ function check(password, salt, keylen, options) {
7272
if (_scrypt === undefined)
7373
throw new ERR_CRYPTO_SCRYPT_NOT_SUPPORTED();
7474

75-
password = validateArrayBufferView(password, 'password');
76-
salt = validateArrayBufferView(salt, 'salt');
75+
password = getArrayBufferView(password, 'password');
76+
salt = getArrayBufferView(salt, 'salt');
7777
validateUint32(keylen, 'keylen');
7878

7979
let { N, r, p, maxmem } = defaults;

lib/internal/crypto/sig.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ const {
1717
const {
1818
getDefaultEncoding,
1919
kHandle,
20-
toBuf,
21-
validateArrayBufferView,
20+
getArrayBufferView,
2221
} = require('internal/crypto/util');
2322
const {
2423
preparePrivateKey,
@@ -47,8 +46,7 @@ Sign.prototype._write = function _write(chunk, encoding, callback) {
4746

4847
Sign.prototype.update = function update(data, encoding) {
4948
encoding = encoding || getDefaultEncoding();
50-
data = validateArrayBufferView(toBuf(data, encoding),
51-
'data');
49+
data = getArrayBufferView(data, 'data', encoding);
5250
this[kHandle].update(data);
5351
return this;
5452
};
@@ -154,8 +152,7 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) {
154152

155153
const pssSaltLength = getSaltLength(options);
156154

157-
signature = validateArrayBufferView(toBuf(signature, sigEncoding),
158-
'signature');
155+
signature = getArrayBufferView(signature, 'signature', sigEncoding);
159156

160157
return this[kHandle].verify(data, format, type, passphrase, signature,
161158
rsaPadding, pssSaltLength);

lib/internal/crypto/util.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ const {
1313
} = internalBinding('constants').crypto;
1414

1515
const {
16-
ERR_CRYPTO_ENGINE_UNKNOWN,
17-
ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH,
18-
ERR_INVALID_ARG_TYPE,
19-
} = require('internal/errors').codes;
16+
hideStackFrames,
17+
codes: {
18+
ERR_CRYPTO_ENGINE_UNKNOWN,
19+
ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH,
20+
ERR_INVALID_ARG_TYPE,
21+
}
22+
} = require('internal/errors');
2023
const { validateString } = require('internal/validators');
2124
const { Buffer } = require('buffer');
2225
const {
@@ -84,8 +87,12 @@ function timingSafeEqual(buf1, buf2) {
8487
return _timingSafeEqual(buf1, buf2);
8588
}
8689

87-
function validateArrayBufferView(buffer, name) {
88-
buffer = toBuf(buffer);
90+
const getArrayBufferView = hideStackFrames((buffer, name, encoding) => {
91+
if (typeof buffer === 'string') {
92+
if (encoding === 'buffer')
93+
encoding = 'utf8';
94+
return Buffer.from(buffer, encoding);
95+
}
8996
if (!isArrayBufferView(buffer)) {
9097
throw new ERR_INVALID_ARG_TYPE(
9198
name,
@@ -94,10 +101,10 @@ function validateArrayBufferView(buffer, name) {
94101
);
95102
}
96103
return buffer;
97-
}
104+
});
98105

99106
module.exports = {
100-
validateArrayBufferView,
107+
getArrayBufferView,
101108
getCiphers,
102109
getCurves,
103110
getDefaultEncoding,

lib/internal/validators.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,6 @@ function validateSignalName(signal, name = 'signal') {
131131
}
132132
}
133133

134-
// TODO(BridgeAR): We have multiple validation functions that call
135-
// `require('internal/utils').toBuf()` before validating for array buffer views.
136-
// Those should likely also be consolidated in here.
137134
const validateBuffer = hideStackFrames((buffer, name = 'buffer') => {
138135
if (!isArrayBufferView(buffer)) {
139136
throw new ERR_INVALID_ARG_TYPE(name,

0 commit comments

Comments
 (0)