1
1
'use strict' ;
2
2
3
+ const { AsyncWrap, Providers } = process . binding ( 'async_wrap' ) ;
4
+ const { Buffer } = require ( 'buffer' ) ;
5
+ const { pbkdf2 : _pbkdf2 } = process . binding ( 'crypto' ) ;
3
6
const {
7
+ ERR_CRYPTO_INVALID_DIGEST ,
8
+ ERR_CRYPTO_PBKDF2_ERROR ,
4
9
ERR_INVALID_ARG_TYPE ,
5
10
ERR_INVALID_CALLBACK ,
6
- ERR_CRYPTO_INVALID_DIGEST ,
7
11
} = require ( 'internal/errors' ) . codes ;
8
12
const {
9
13
checkIsArrayBufferView,
10
14
checkIsUint,
11
15
getDefaultEncoding,
12
16
} = require ( 'internal/crypto/util' ) ;
13
- const {
14
- PBKDF2
15
- } = process . binding ( 'crypto' ) ;
16
17
17
18
function pbkdf2 ( password , salt , iterations , keylen , digest , callback ) {
18
19
if ( typeof digest === 'function' ) {
19
20
callback = digest ;
20
21
digest = undefined ;
21
22
}
22
23
24
+ ( { password, salt, iterations, keylen, digest } =
25
+ check ( password , salt , iterations , keylen , digest , callback ) ) ;
26
+
23
27
if ( typeof callback !== 'function' )
24
28
throw new ERR_INVALID_CALLBACK ( ) ;
25
29
26
- 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 ) ;
27
41
}
28
42
29
43
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 ) ;
31
51
}
32
52
33
- 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
+ }
37
59
38
60
password = checkIsArrayBufferView ( 'password' , password ) ;
39
61
salt = checkIsArrayBufferView ( 'salt' , salt ) ;
@@ -42,30 +64,17 @@ function _pbkdf2(password, salt, iterations, keylen, digest, callback) {
42
64
iterations = checkIsUint ( 'iterations' , iterations , 'a non-negative number' ) ;
43
65
keylen = checkIsUint ( 'keylen' , keylen ) ;
44
66
45
- const encoding = getDefaultEncoding ( ) ;
67
+ return { password, salt, iterations, keylen, digest } ;
68
+ }
46
69
47
- 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 ) ;
53
72
54
- // 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 ( ) ;
69
78
}
70
79
71
80
module . exports = {
0 commit comments