Skip to content

Commit 88f3935

Browse files
indutnyFishrock123
authored andcommitted
crypto: PBKDF2 works with int not ssize_t
Change types of all PBKDF2 params to `int` as they are `int` in `evp.h`. Check that `raw_keylen` fits into `int` before passing it to OpenSSL. Fix: #5396 PR-URL: #5397 Reviewed-By: Shigeki Ohtsu <[email protected]> Reviewed-By: Ben Noorhduis <[email protected]> Conflicts: test/parallel/test-crypto-pbkdf2.js
1 parent 9424fa5 commit 88f3935

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

src/node_crypto.cc

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "CNNICHashWhitelist.inc"
2020

2121
#include <errno.h>
22+
#include <limits.h> // INT_MAX
2223
#include <math.h>
2324
#include <stdlib.h>
2425
#include <string.h>
@@ -4940,12 +4941,12 @@ class PBKDF2Request : public AsyncWrap {
49404941
PBKDF2Request(Environment* env,
49414942
Local<Object> object,
49424943
const EVP_MD* digest,
4943-
ssize_t passlen,
4944+
int passlen,
49444945
char* pass,
4945-
ssize_t saltlen,
4946+
int saltlen,
49464947
char* salt,
4947-
ssize_t iter,
4948-
ssize_t keylen)
4948+
int iter,
4949+
int keylen)
49494950
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
49504951
digest_(digest),
49514952
error_(0),
@@ -4974,31 +4975,31 @@ class PBKDF2Request : public AsyncWrap {
49744975
return digest_;
49754976
}
49764977

4977-
inline ssize_t passlen() const {
4978+
inline int passlen() const {
49784979
return passlen_;
49794980
}
49804981

49814982
inline char* pass() const {
49824983
return pass_;
49834984
}
49844985

4985-
inline ssize_t saltlen() const {
4986+
inline int saltlen() const {
49864987
return saltlen_;
49874988
}
49884989

49894990
inline char* salt() const {
49904991
return salt_;
49914992
}
49924993

4993-
inline ssize_t keylen() const {
4994+
inline int keylen() const {
49944995
return keylen_;
49954996
}
49964997

49974998
inline char* key() const {
49984999
return key_;
49995000
}
50005001

5001-
inline ssize_t iter() const {
5002+
inline int iter() const {
50025003
return iter_;
50035004
}
50045005

@@ -5031,13 +5032,13 @@ class PBKDF2Request : public AsyncWrap {
50315032
private:
50325033
const EVP_MD* digest_;
50335034
int error_;
5034-
ssize_t passlen_;
5035+
int passlen_;
50355036
char* pass_;
5036-
ssize_t saltlen_;
5037+
int saltlen_;
50375038
char* salt_;
5038-
ssize_t keylen_;
5039+
int keylen_;
50395040
char* key_;
5040-
ssize_t iter_;
5041+
int iter_;
50415042
};
50425043

50435044

@@ -5094,10 +5095,11 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
50945095
const char* type_error = nullptr;
50955096
char* pass = nullptr;
50965097
char* salt = nullptr;
5097-
ssize_t passlen = -1;
5098-
ssize_t saltlen = -1;
5099-
double keylen = -1;
5100-
ssize_t iter = -1;
5098+
int passlen = -1;
5099+
int saltlen = -1;
5100+
double raw_keylen = -1;
5101+
int keylen = -1;
5102+
int iter = -1;
51015103
PBKDF2Request* req = nullptr;
51025104
Local<Object> obj;
51035105

@@ -5149,12 +5151,15 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
51495151
goto err;
51505152
}
51515153

5152-
keylen = args[3]->NumberValue();
5153-
if (keylen < 0 || isnan(keylen) || isinf(keylen)) {
5154+
raw_keylen = args[3]->NumberValue();
5155+
if (raw_keylen < 0.0 || isnan(raw_keylen) || isinf(raw_keylen) ||
5156+
raw_keylen > INT_MAX) {
51545157
type_error = "Bad key length";
51555158
goto err;
51565159
}
51575160

5161+
keylen = static_cast<int>(raw_keylen);
5162+
51585163
if (args[4]->IsString()) {
51595164
node::Utf8Value digest_name(env->isolate(), args[4]);
51605165
digest = EVP_get_digestbyname(*digest_name);
@@ -5177,7 +5182,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
51775182
saltlen,
51785183
salt,
51795184
iter,
5180-
static_cast<ssize_t>(keylen));
5185+
keylen);
51815186

51825187
if (args[5]->IsFunction()) {
51835188
obj->Set(env->ondone_string(), args[5]);

test/parallel/test-crypto-pbkdf2.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,24 @@ assert.throws(function() {
6363
// Should not work with Infinity key length
6464
assert.throws(function() {
6565
crypto.pbkdf2('password', 'salt', 1, Infinity, common.fail);
66-
}, function(err) {
67-
return err instanceof Error && err.message === 'Bad key length';
68-
});
66+
}, /Bad key length/);
6967

7068
// Should not work with negative Infinity key length
7169
assert.throws(function() {
7270
crypto.pbkdf2('password', 'salt', 1, -Infinity, common.fail);
73-
}, function(err) {
74-
return err instanceof Error && err.message === 'Bad key length';
75-
});
71+
}, /Bad key length/);
7672

7773
// Should not work with NaN key length
7874
assert.throws(function() {
7975
crypto.pbkdf2('password', 'salt', 1, NaN, common.fail);
80-
}, function(err) {
81-
return err instanceof Error && err.message === 'Bad key length';
82-
});
76+
}, /Bad key length/);
8377

8478
// Should not work with negative key length
8579
assert.throws(function() {
8680
crypto.pbkdf2('password', 'salt', 1, -1, common.fail);
87-
}, function(err) {
88-
return err instanceof Error && err.message === 'Bad key length';
89-
});
81+
}, /Bad key length/);
82+
83+
// Should not work with key length that does not fit into 32 signed bits
84+
assert.throws(function() {
85+
crypto.pbkdf2('password', 'salt', 1, 4073741824, common.fail);
86+
}, /Bad key length/);

0 commit comments

Comments
 (0)