◐ Shell
clean mode source ↗

crypto: refactor pbkdf2() and pbkdf2Sync() methods · nodejs/node@6262fa4

11

'use strict';

223+

const { AsyncWrap, Providers } = process.binding('async_wrap');

4+

const { Buffer } = require('buffer');

5+

const { pbkdf2: _pbkdf2 } = process.binding('crypto');

36

const {

7+

ERR_CRYPTO_INVALID_DIGEST,

8+

ERR_CRYPTO_PBKDF2_ERROR,

49

ERR_INVALID_ARG_TYPE,

510

ERR_INVALID_CALLBACK,

6-

ERR_CRYPTO_INVALID_DIGEST,

711

} = require('internal/errors').codes;

812

const {

913

checkIsArrayBufferView,

1014

checkIsUint,

1115

getDefaultEncoding,

1216

} = require('internal/crypto/util');

13-

const {

14-

PBKDF2

15-

} = process.binding('crypto');

16171718

function pbkdf2(password, salt, iterations, keylen, digest, callback) {

1819

if (typeof digest === 'function') {

1920

callback = digest;

2021

digest = undefined;

2122

}

222324+

({ password, salt, iterations, keylen, digest } =

25+

check(password, salt, iterations, keylen, digest, callback));

26+2327

if (typeof callback !== 'function')

2428

throw new ERR_INVALID_CALLBACK();

252926-

return _pbkdf2(password, salt, iterations, keylen, digest, callback);

30+

const encoding = getDefaultEncoding();

31+

const keybuf = Buffer.alloc(keylen);

32+33+

const wrap = new AsyncWrap(Providers.PBKDF2REQUEST);

34+

wrap.ondone = (ok) => { // Retains keybuf while request is in flight.

35+

if (!ok) return callback.call(wrap, new ERR_CRYPTO_PBKDF2_ERROR());

36+

if (encoding === 'buffer') return callback.call(wrap, null, keybuf);

37+

callback.call(wrap, null, keybuf.toString(encoding));

38+

};

39+40+

handleError(keybuf, password, salt, iterations, digest, wrap);

2741

}

28422943

function pbkdf2Sync(password, salt, iterations, keylen, digest) {

30-

return _pbkdf2(password, salt, iterations, keylen, digest);

44+

({ password, salt, iterations, keylen, digest } =

45+

check(password, salt, iterations, keylen, digest, pbkdf2Sync));

46+

const keybuf = Buffer.alloc(keylen);

47+

handleError(keybuf, password, salt, iterations, digest);

48+

const encoding = getDefaultEncoding();

49+

if (encoding === 'buffer') return keybuf;

50+

return keybuf.toString(encoding);

3151

}

325233-

function _pbkdf2(password, salt, iterations, keylen, digest, callback) {

34-35-

if (digest !== null && typeof digest !== 'string')

36-

throw new ERR_INVALID_ARG_TYPE('digest', ['string', 'null'], digest);

53+

function check(password, salt, iterations, keylen, digest, callback) {

54+

if (typeof digest !== 'string') {

55+

if (digest !== null)

56+

throw new ERR_INVALID_ARG_TYPE('digest', ['string', 'null'], digest);

57+

digest = 'sha1';

58+

}

37593860

password = checkIsArrayBufferView('password', password);

3961

salt = checkIsArrayBufferView('salt', salt);

@@ -42,30 +64,17 @@ function _pbkdf2(password, salt, iterations, keylen, digest, callback) {

4264

iterations = checkIsUint('iterations', iterations, 'a non-negative number');

4365

keylen = checkIsUint('keylen', keylen);

446645-

const encoding = getDefaultEncoding();

67+

return { password, salt, iterations, keylen, digest };

68+

}

466947-

if (encoding === 'buffer') {

48-

const ret = PBKDF2(password, salt, iterations, keylen, digest, callback);

49-

if (ret === -1)

50-

throw new ERR_CRYPTO_INVALID_DIGEST(digest);

51-

return ret;

52-

}

70+

function handleError(keybuf, password, salt, iterations, digest, wrap) {

71+

const rc = _pbkdf2(keybuf, password, salt, iterations, digest, wrap);

537254-

// at this point, we need to handle encodings.

55-

if (callback) {

56-

function next(er, ret) {

57-

if (ret)

58-

ret = ret.toString(encoding);

59-

callback(er, ret);

60-

}

61-

if (PBKDF2(password, salt, iterations, keylen, digest, next) === -1)

62-

throw new ERR_CRYPTO_INVALID_DIGEST(digest);

63-

} else {

64-

const ret = PBKDF2(password, salt, iterations, keylen, digest);

65-

if (ret === -1)

66-

throw new ERR_CRYPTO_INVALID_DIGEST(digest);

67-

return ret.toString(encoding);

68-

}

73+

if (rc === -1)

74+

throw new ERR_CRYPTO_INVALID_DIGEST(digest);

75+76+

if (rc === false)

77+

throw new ERR_CRYPTO_PBKDF2_ERROR();

6978

}

70797180

module.exports = {