mirror of
https://github.com/nodejs/node.git
synced 2025-05-09 23:06:47 +00:00

PR-URL: https://github.com/nodejs/node/pull/19137 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
101 lines
2.6 KiB
JavaScript
101 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ERR_INVALID_ARG_TYPE,
|
|
ERR_INVALID_CALLBACK,
|
|
ERR_CRYPTO_INVALID_DIGEST,
|
|
ERR_OUT_OF_RANGE
|
|
} = require('internal/errors').codes;
|
|
const {
|
|
getDefaultEncoding,
|
|
toBuf
|
|
} = require('internal/crypto/util');
|
|
const { isArrayBufferView } = require('internal/util/types');
|
|
const {
|
|
PBKDF2
|
|
} = process.binding('crypto');
|
|
const {
|
|
INT_MAX
|
|
} = process.binding('constants').crypto;
|
|
|
|
function pbkdf2(password, salt, iterations, keylen, digest, callback) {
|
|
if (typeof digest === 'function') {
|
|
callback = digest;
|
|
digest = undefined;
|
|
}
|
|
|
|
if (typeof callback !== 'function')
|
|
throw new ERR_INVALID_CALLBACK();
|
|
|
|
return _pbkdf2(password, salt, iterations, keylen, digest, callback);
|
|
}
|
|
|
|
function pbkdf2Sync(password, salt, iterations, keylen, digest) {
|
|
return _pbkdf2(password, salt, iterations, keylen, digest);
|
|
}
|
|
|
|
function _pbkdf2(password, salt, iterations, keylen, digest, callback) {
|
|
|
|
if (digest !== null && typeof digest !== 'string')
|
|
throw new ERR_INVALID_ARG_TYPE('digest', ['string', 'null']);
|
|
|
|
password = toBuf(password);
|
|
salt = toBuf(salt);
|
|
|
|
if (!isArrayBufferView(password)) {
|
|
throw new ERR_INVALID_ARG_TYPE('password',
|
|
['string', 'Buffer', 'TypedArray']);
|
|
}
|
|
|
|
if (!isArrayBufferView(salt)) {
|
|
throw new ERR_INVALID_ARG_TYPE('salt', ['string', 'Buffer', 'TypedArray']);
|
|
}
|
|
|
|
if (typeof iterations !== 'number')
|
|
throw new ERR_INVALID_ARG_TYPE('iterations', 'number');
|
|
|
|
if (iterations < 0)
|
|
throw new ERR_OUT_OF_RANGE('iterations',
|
|
'a non-negative number',
|
|
iterations);
|
|
|
|
if (typeof keylen !== 'number')
|
|
throw new ERR_INVALID_ARG_TYPE('keylen', 'number');
|
|
|
|
if (keylen < 0 ||
|
|
!Number.isFinite(keylen) ||
|
|
keylen > INT_MAX) {
|
|
throw new ERR_OUT_OF_RANGE('keylen');
|
|
}
|
|
|
|
const encoding = getDefaultEncoding();
|
|
|
|
if (encoding === 'buffer') {
|
|
const ret = PBKDF2(password, salt, iterations, keylen, digest, callback);
|
|
if (ret === -1)
|
|
throw new ERR_CRYPTO_INVALID_DIGEST(digest);
|
|
return ret;
|
|
}
|
|
|
|
// at this point, we need to handle encodings.
|
|
if (callback) {
|
|
function next(er, ret) {
|
|
if (ret)
|
|
ret = ret.toString(encoding);
|
|
callback(er, ret);
|
|
}
|
|
if (PBKDF2(password, salt, iterations, keylen, digest, next) === -1)
|
|
throw new ERR_CRYPTO_INVALID_DIGEST(digest);
|
|
} else {
|
|
const ret = PBKDF2(password, salt, iterations, keylen, digest);
|
|
if (ret === -1)
|
|
throw new ERR_CRYPTO_INVALID_DIGEST(digest);
|
|
return ret.toString(encoding);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
pbkdf2,
|
|
pbkdf2Sync
|
|
};
|