Skip to content

Commit 97e95d0

Browse files
indutnyMyles Borins
authored and
Myles Borins
committed
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 <ohtsu@iij.ad.jp> Reviewed-By: Ben Noorhduis <info@bnoordhuis.nl>
1 parent dff7091 commit 97e95d0

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

src/node_crypto.cc

+24-19
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>
@@ -4737,12 +4738,12 @@ class PBKDF2Request : public AsyncWrap {
47374738
PBKDF2Request(Environment* env,
47384739
Local<Object> object,
47394740
const EVP_MD* digest,
4740-
ssize_t passlen,
4741+
int passlen,
47414742
char* pass,
4742-
ssize_t saltlen,
4743+
int saltlen,
47434744
char* salt,
4744-
ssize_t iter,
4745-
ssize_t keylen)
4745+
int iter,
4746+
int keylen)
47464747
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
47474748
digest_(digest),
47484749
error_(0),
@@ -4771,31 +4772,31 @@ class PBKDF2Request : public AsyncWrap {
47714772
return digest_;
47724773
}
47734774

4774-
inline ssize_t passlen() const {
4775+
inline int passlen() const {
47754776
return passlen_;
47764777
}
47774778

47784779
inline char* pass() const {
47794780
return pass_;
47804781
}
47814782

4782-
inline ssize_t saltlen() const {
4783+
inline int saltlen() const {
47834784
return saltlen_;
47844785
}
47854786

47864787
inline char* salt() const {
47874788
return salt_;
47884789
}
47894790

4790-
inline ssize_t keylen() const {
4791+
inline int keylen() const {
47914792
return keylen_;
47924793
}
47934794

47944795
inline char* key() const {
47954796
return key_;
47964797
}
47974798

4798-
inline ssize_t iter() const {
4799+
inline int iter() const {
47994800
return iter_;
48004801
}
48014802

@@ -4828,13 +4829,13 @@ class PBKDF2Request : public AsyncWrap {
48284829
private:
48294830
const EVP_MD* digest_;
48304831
int error_;
4831-
ssize_t passlen_;
4832+
int passlen_;
48324833
char* pass_;
4833-
ssize_t saltlen_;
4834+
int saltlen_;
48344835
char* salt_;
4835-
ssize_t keylen_;
4836+
int keylen_;
48364837
char* key_;
4837-
ssize_t iter_;
4838+
int iter_;
48384839
};
48394840

48404841

@@ -4891,10 +4892,11 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
48914892
const char* type_error = nullptr;
48924893
char* pass = nullptr;
48934894
char* salt = nullptr;
4894-
ssize_t passlen = -1;
4895-
ssize_t saltlen = -1;
4896-
double keylen = -1;
4897-
ssize_t iter = -1;
4895+
int passlen = -1;
4896+
int saltlen = -1;
4897+
double raw_keylen = -1;
4898+
int keylen = -1;
4899+
int iter = -1;
48984900
PBKDF2Request* req = nullptr;
48994901
Local<Object> obj;
49004902

@@ -4946,12 +4948,15 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
49464948
goto err;
49474949
}
49484950

4949-
keylen = args[3]->NumberValue();
4950-
if (keylen < 0 || isnan(keylen) || isinf(keylen)) {
4951+
raw_keylen = args[3]->NumberValue();
4952+
if (raw_keylen < 0.0 || isnan(raw_keylen) || isinf(raw_keylen) ||
4953+
raw_keylen > INT_MAX) {
49514954
type_error = "Bad key length";
49524955
goto err;
49534956
}
49544957

4958+
keylen = static_cast<int>(raw_keylen);
4959+
49554960
if (args[4]->IsString()) {
49564961
node::Utf8Value digest_name(env->isolate(), args[4]);
49574962
digest = EVP_get_digestbyname(*digest_name);
@@ -4974,7 +4979,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
49744979
saltlen,
49754980
salt,
49764981
iter,
4977-
static_cast<ssize_t>(keylen));
4982+
keylen);
49784983

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

test/parallel/test-crypto-pbkdf2.js

+4-12
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,19 @@ 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/);

0 commit comments

Comments
 (0)