Skip to content

Commit 6262fa4

Browse files
bnoordhuistargos
authored andcommitted
crypto: refactor pbkdf2() and pbkdf2Sync() methods
Use the scrypt() infrastructure to reimplement pbkdf2() in a simpler manner. PR-URL: #20816 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
1 parent c9b4592 commit 6262fa4

File tree

6 files changed

+121
-180
lines changed

6 files changed

+121
-180
lines changed

‎doc/api/errors.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ An invalid [crypto digest algorithm][] was specified.
739739
A crypto method was used on an object that was in an invalid state. For
740740
instance, calling [`cipher.getAuthTag()`][] before calling `cipher.final()`.
741741

742+
<aid="ERR_CRYPTO_PBKDF2_ERROR"></a>
743+
### ERR_CRYPTO_PBKDF2_ERROR
744+
745+
The PBKDF2 algorithm failed for unspecified reasons. OpenSSL does not provide
746+
more details and therefore neither does Node.js.
747+
742748
<aid="ERR_CRYPTO_SCRYPT_INVALID_PARAMETER"></a>
743749
### ERR_CRYPTO_SCRYPT_INVALID_PARAMETER
744750

‎lib/internal/crypto/pbkdf2.js‎

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,61 @@
11
'use strict';
22

3+
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');
1617

1718
functionpbkdf2(password,salt,iterations,keylen,digest,callback){
1819
if(typeofdigest==='function'){
1920
callback=digest;
2021
digest=undefined;
2122
}
2223

24+
({ password, salt, iterations, keylen, digest }=
25+
check(password,salt,iterations,keylen,digest,callback));
26+
2327
if(typeofcallback!=='function')
2428
thrownewERR_INVALID_CALLBACK();
2529

26-
return_pbkdf2(password,salt,iterations,keylen,digest,callback);
30+
constencoding=getDefaultEncoding();
31+
constkeybuf=Buffer.alloc(keylen);
32+
33+
constwrap=newAsyncWrap(Providers.PBKDF2REQUEST);
34+
wrap.ondone=(ok)=>{// Retains keybuf while request is in flight.
35+
if(!ok)returncallback.call(wrap,newERR_CRYPTO_PBKDF2_ERROR());
36+
if(encoding==='buffer')returncallback.call(wrap,null,keybuf);
37+
callback.call(wrap,null,keybuf.toString(encoding));
38+
};
39+
40+
handleError(keybuf,password,salt,iterations,digest,wrap);
2741
}
2842

2943
functionpbkdf2Sync(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+
constkeybuf=Buffer.alloc(keylen);
47+
handleError(keybuf,password,salt,iterations,digest);
48+
constencoding=getDefaultEncoding();
49+
if(encoding==='buffer')returnkeybuf;
50+
returnkeybuf.toString(encoding);
3151
}
3252

33-
function_pbkdf2(password,salt,iterations,keylen,digest,callback){
34-
35-
if(digest!==null&&typeofdigest!=='string')
36-
thrownewERR_INVALID_ARG_TYPE('digest',['string','null'],digest);
53+
functioncheck(password,salt,iterations,keylen,digest,callback){
54+
if(typeofdigest!=='string'){
55+
if(digest!==null)
56+
thrownewERR_INVALID_ARG_TYPE('digest',['string','null'],digest);
57+
digest='sha1';
58+
}
3759

3860
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);
4466

45-
constencoding=getDefaultEncoding();
67+
return{ password, salt, iterations, keylen, digest };
68+
}
4669

47-
if(encoding==='buffer'){
48-
constret=PBKDF2(password,salt,iterations,keylen,digest,callback);
49-
if(ret===-1)
50-
thrownewERR_CRYPTO_INVALID_DIGEST(digest);
51-
returnret;
52-
}
70+
functionhandleError(keybuf,password,salt,iterations,digest,wrap){
71+
constrc=_pbkdf2(keybuf,password,salt,iterations,digest,wrap);
5372

54-
// at this point, we need to handle encodings.
55-
if(callback){
56-
functionnext(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-
thrownewERR_CRYPTO_INVALID_DIGEST(digest);
63-
}else{
64-
constret=PBKDF2(password,salt,iterations,keylen,digest);
65-
if(ret===-1)
66-
thrownewERR_CRYPTO_INVALID_DIGEST(digest);
67-
returnret.toString(encoding);
68-
}
73+
if(rc===-1)
74+
thrownewERR_CRYPTO_INVALID_DIGEST(digest);
75+
76+
if(rc===false)
77+
thrownewERR_CRYPTO_PBKDF2_ERROR();
6978
}
7079

7180
module.exports={

‎lib/internal/errors.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,8 @@ E('ERR_CRYPTO_HASH_FINALIZED', 'Digest already called', Error);
503503
E('ERR_CRYPTO_HASH_UPDATE_FAILED','Hash update failed',Error);
504504
E('ERR_CRYPTO_INVALID_DIGEST','Invalid digest: %s',TypeError);
505505
E('ERR_CRYPTO_INVALID_STATE','Invalid state for operation %s',Error);
506+
// TODO(bnoordhuis) Decapitalize: s/PBKDF2 Error/PBKDF2 error/
507+
E('ERR_CRYPTO_PBKDF2_ERROR','PBKDF2 Error',Error);
506508
E('ERR_CRYPTO_SCRYPT_INVALID_PARAMETER','Invalid scrypt parameter',Error);
507509
E('ERR_CRYPTO_SCRYPT_NOT_SUPPORTED','Scrypt algorithm not supported',Error);
508510
// Switch to TypeError. The current implementation does not seem right.

‎src/env.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ struct PackageConfig{
244244
V(password_string, "password") \
245245
V(path_string, "path") \
246246
V(pending_handle_string, "pendingHandle") \
247-
V(pbkdf2_error_string, "PBKDF2 Error") \
248247
V(pid_string, "pid") \
249248
V(pipe_string, "pipe") \
250249
V(pipe_target_string, "pipeTarget") \
@@ -337,7 +336,6 @@ struct PackageConfig{
337336
V(inspector_console_api_object, v8::Object) \
338337
V(message_port, v8::Object) \
339338
V(message_port_constructor_template, v8::FunctionTemplate) \
340-
V(pbkdf2_constructor_template, v8::ObjectTemplate) \
341339
V(pipe_constructor_template, v8::FunctionTemplate) \
342340
V(performance_entry_callback, v8::Function) \
343341
V(performance_entry_template, v8::Function) \

0 commit comments

Comments
(0)