mirror of https://github.com/nodejs/node.git
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: https://github.com/nodejs/node/pull/5397 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp> Reviewed-By: Ben Noorhduis <info@bnoordhuis.nl>pull/5503/head
parent
610bd8d567
commit
da3f425506
|
@ -19,6 +19,7 @@
|
|||
#include "CNNICHashWhitelist.inc"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h> // INT_MAX
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -4955,12 +4956,12 @@ class PBKDF2Request : public AsyncWrap {
|
|||
PBKDF2Request(Environment* env,
|
||||
Local<Object> object,
|
||||
const EVP_MD* digest,
|
||||
ssize_t passlen,
|
||||
int passlen,
|
||||
char* pass,
|
||||
ssize_t saltlen,
|
||||
int saltlen,
|
||||
char* salt,
|
||||
ssize_t iter,
|
||||
ssize_t keylen)
|
||||
int iter,
|
||||
int keylen)
|
||||
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
|
||||
digest_(digest),
|
||||
error_(0),
|
||||
|
@ -4989,7 +4990,7 @@ class PBKDF2Request : public AsyncWrap {
|
|||
return digest_;
|
||||
}
|
||||
|
||||
inline ssize_t passlen() const {
|
||||
inline int passlen() const {
|
||||
return passlen_;
|
||||
}
|
||||
|
||||
|
@ -4997,7 +4998,7 @@ class PBKDF2Request : public AsyncWrap {
|
|||
return pass_;
|
||||
}
|
||||
|
||||
inline ssize_t saltlen() const {
|
||||
inline int saltlen() const {
|
||||
return saltlen_;
|
||||
}
|
||||
|
||||
|
@ -5005,7 +5006,7 @@ class PBKDF2Request : public AsyncWrap {
|
|||
return salt_;
|
||||
}
|
||||
|
||||
inline ssize_t keylen() const {
|
||||
inline int keylen() const {
|
||||
return keylen_;
|
||||
}
|
||||
|
||||
|
@ -5013,7 +5014,7 @@ class PBKDF2Request : public AsyncWrap {
|
|||
return key_;
|
||||
}
|
||||
|
||||
inline ssize_t iter() const {
|
||||
inline int iter() const {
|
||||
return iter_;
|
||||
}
|
||||
|
||||
|
@ -5046,13 +5047,13 @@ class PBKDF2Request : public AsyncWrap {
|
|||
private:
|
||||
const EVP_MD* digest_;
|
||||
int error_;
|
||||
ssize_t passlen_;
|
||||
int passlen_;
|
||||
char* pass_;
|
||||
ssize_t saltlen_;
|
||||
int saltlen_;
|
||||
char* salt_;
|
||||
ssize_t keylen_;
|
||||
int keylen_;
|
||||
char* key_;
|
||||
ssize_t iter_;
|
||||
int iter_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -5109,10 +5110,11 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||
const char* type_error = nullptr;
|
||||
char* pass = nullptr;
|
||||
char* salt = nullptr;
|
||||
ssize_t passlen = -1;
|
||||
ssize_t saltlen = -1;
|
||||
double keylen = -1;
|
||||
ssize_t iter = -1;
|
||||
int passlen = -1;
|
||||
int saltlen = -1;
|
||||
double raw_keylen = -1;
|
||||
int keylen = -1;
|
||||
int iter = -1;
|
||||
PBKDF2Request* req = nullptr;
|
||||
Local<Object> obj;
|
||||
|
||||
|
@ -5164,12 +5166,15 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||
goto err;
|
||||
}
|
||||
|
||||
keylen = args[3]->NumberValue();
|
||||
if (keylen < 0 || isnan(keylen) || isinf(keylen)) {
|
||||
raw_keylen = args[3]->NumberValue();
|
||||
if (raw_keylen < 0.0 || isnan(raw_keylen) || isinf(raw_keylen) ||
|
||||
raw_keylen > INT_MAX) {
|
||||
type_error = "Bad key length";
|
||||
goto err;
|
||||
}
|
||||
|
||||
keylen = static_cast<int>(raw_keylen);
|
||||
|
||||
if (args[4]->IsString()) {
|
||||
node::Utf8Value digest_name(env->isolate(), args[4]);
|
||||
digest = EVP_get_digestbyname(*digest_name);
|
||||
|
@ -5192,7 +5197,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||
saltlen,
|
||||
salt,
|
||||
iter,
|
||||
static_cast<ssize_t>(keylen));
|
||||
keylen);
|
||||
|
||||
if (args[5]->IsFunction()) {
|
||||
obj->Set(env->ondone_string(), args[5]);
|
||||
|
|
|
@ -63,27 +63,24 @@ assert.throws(function() {
|
|||
// Should not work with Infinity key length
|
||||
assert.throws(function() {
|
||||
crypto.pbkdf2('password', 'salt', 1, Infinity, 'sha256', common.fail);
|
||||
}, function(err) {
|
||||
return err instanceof Error && err.message === 'Bad key length';
|
||||
});
|
||||
}, /Bad key length/);
|
||||
|
||||
// Should not work with negative Infinity key length
|
||||
assert.throws(function() {
|
||||
crypto.pbkdf2('password', 'salt', 1, -Infinity, 'sha256', common.fail);
|
||||
}, function(err) {
|
||||
return err instanceof Error && err.message === 'Bad key length';
|
||||
});
|
||||
}, /Bad key length/);
|
||||
|
||||
// Should not work with NaN key length
|
||||
assert.throws(function() {
|
||||
crypto.pbkdf2('password', 'salt', 1, NaN, 'sha256', common.fail);
|
||||
}, function(err) {
|
||||
return err instanceof Error && err.message === 'Bad key length';
|
||||
});
|
||||
}, /Bad key length/);
|
||||
|
||||
// Should not work with negative key length
|
||||
assert.throws(function() {
|
||||
crypto.pbkdf2('password', 'salt', 1, -1, 'sha256', common.fail);
|
||||
}, function(err) {
|
||||
return err instanceof Error && err.message === 'Bad key length';
|
||||
});
|
||||
}, /Bad key length/);
|
||||
|
||||
// Should not work with key length that does not fit into 32 signed bits
|
||||
assert.throws(function() {
|
||||
crypto.pbkdf2('password', 'salt', 1, 4073741824, 'sha256', common.fail);
|
||||
}, /Bad key length/);
|
||||
|
|
Loading…
Reference in New Issue