crypto: convert pbkdf2_req to a class
pbkdf2_req has been renamed to PBKDF2Request and converted to a class. It now uses AsyncWrap::MakeCallback. Also includes, using env()->ondone_string() instead of "ondone" and using malloc instead of new char[].
This commit is contained in:
parent
66d908f09a
commit
95c38107c2
@ -3275,74 +3275,141 @@ bool DiffieHellman::VerifyContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO(bnoordhuis) Turn into proper RAII class.
|
class PBKDF2Request : public AsyncWrap {
|
||||||
struct pbkdf2_req {
|
public:
|
||||||
uv_work_t work_req;
|
PBKDF2Request(Environment* env,
|
||||||
Environment* env;
|
Local<Object> object,
|
||||||
int err;
|
ssize_t passlen,
|
||||||
char* pass;
|
char* pass,
|
||||||
size_t passlen;
|
ssize_t saltlen,
|
||||||
char* salt;
|
char* salt,
|
||||||
size_t saltlen;
|
ssize_t iter,
|
||||||
size_t iter;
|
ssize_t keylen)
|
||||||
char* key;
|
: AsyncWrap(env, object),
|
||||||
size_t keylen;
|
error_(0),
|
||||||
Persistent<Object> obj;
|
passlen_(passlen),
|
||||||
|
pass_(pass),
|
||||||
|
saltlen_(saltlen),
|
||||||
|
salt_(salt),
|
||||||
|
keylen_(keylen),
|
||||||
|
key_(static_cast<char*>(malloc(keylen))),
|
||||||
|
iter_(iter) {
|
||||||
|
if (key() == NULL)
|
||||||
|
FatalError("node::PBKDF2Request()", "Out of Memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
~PBKDF2Request() {
|
||||||
|
persistent().Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_work_t* work_req() {
|
||||||
|
return &work_req_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t passlen() const {
|
||||||
|
return passlen_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char* pass() const {
|
||||||
|
return pass_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t saltlen() const {
|
||||||
|
return saltlen_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char* salt() const {
|
||||||
|
return salt_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t keylen() const {
|
||||||
|
return keylen_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char* key() const {
|
||||||
|
return key_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t iter() const {
|
||||||
|
return iter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void release() {
|
||||||
|
free(pass_);
|
||||||
|
passlen_ = 0;
|
||||||
|
free(salt_);
|
||||||
|
saltlen_ = 0;
|
||||||
|
free(key_);
|
||||||
|
keylen_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int error() const {
|
||||||
|
return error_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_error(int err) {
|
||||||
|
error_ = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(trevnorris): Make private and make work with container_of macro.
|
||||||
|
uv_work_t work_req_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int error_;
|
||||||
|
ssize_t passlen_;
|
||||||
|
char* pass_;
|
||||||
|
ssize_t saltlen_;
|
||||||
|
char* salt_;
|
||||||
|
ssize_t keylen_;
|
||||||
|
char* key_;
|
||||||
|
ssize_t iter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void EIO_PBKDF2(pbkdf2_req* req) {
|
void EIO_PBKDF2(PBKDF2Request* req) {
|
||||||
req->err = PKCS5_PBKDF2_HMAC_SHA1(
|
req->set_error(PKCS5_PBKDF2_HMAC_SHA1(
|
||||||
req->pass,
|
req->pass(),
|
||||||
req->passlen,
|
req->passlen(),
|
||||||
(unsigned char*)req->salt,
|
reinterpret_cast<unsigned char*>(req->salt()),
|
||||||
req->saltlen,
|
req->saltlen(),
|
||||||
req->iter,
|
req->iter(),
|
||||||
req->keylen,
|
req->keylen(),
|
||||||
(unsigned char*)req->key);
|
reinterpret_cast<unsigned char*>(req->key())));
|
||||||
memset(req->pass, 0, req->passlen);
|
memset(req->pass(), 0, req->passlen());
|
||||||
memset(req->salt, 0, req->saltlen);
|
memset(req->salt(), 0, req->saltlen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EIO_PBKDF2(uv_work_t* work_req) {
|
void EIO_PBKDF2(uv_work_t* work_req) {
|
||||||
pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
|
PBKDF2Request* req = container_of(work_req, PBKDF2Request, work_req_);
|
||||||
EIO_PBKDF2(req);
|
EIO_PBKDF2(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EIO_PBKDF2After(pbkdf2_req* req, Local<Value> argv[2]) {
|
void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
|
||||||
if (req->err) {
|
if (req->error()) {
|
||||||
argv[0] = Undefined(node_isolate);
|
argv[0] = Undefined(node_isolate);
|
||||||
argv[1] = Encode(req->key, req->keylen, BUFFER);
|
argv[1] = Encode(req->key(), req->keylen(), BUFFER);
|
||||||
memset(req->key, 0, req->keylen);
|
memset(req->key(), 0, req->keylen());
|
||||||
} else {
|
} else {
|
||||||
argv[0] = Exception::Error(
|
argv[0] = Exception::Error(
|
||||||
FIXED_ONE_BYTE_STRING(node_isolate, "PBKDF2 error"));
|
FIXED_ONE_BYTE_STRING(node_isolate, "PBKDF2 error"));
|
||||||
argv[1] = Undefined(node_isolate);
|
argv[1] = Undefined(node_isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] req->pass;
|
|
||||||
delete[] req->salt;
|
|
||||||
delete[] req->key;
|
|
||||||
delete req;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EIO_PBKDF2After(uv_work_t* work_req, int status) {
|
void EIO_PBKDF2After(uv_work_t* work_req, int status) {
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
|
PBKDF2Request* req = container_of(work_req, PBKDF2Request, work_req_);
|
||||||
Environment* env = req->env;
|
Environment* env = req->env();
|
||||||
Context::Scope context_scope(env->context());
|
Context::Scope context_scope(env->context());
|
||||||
HandleScope handle_scope(env->isolate());
|
HandleScope handle_scope(env->isolate());
|
||||||
// Create a new Local that's associated with the current HandleScope.
|
|
||||||
// PersistentToLocal() returns a handle that gets zeroed when we call
|
|
||||||
// Dispose() so don't use that.
|
|
||||||
Local<Object> obj = Local<Object>::New(node_isolate, req->obj);
|
|
||||||
req->obj.Dispose();
|
|
||||||
Local<Value> argv[2];
|
Local<Value> argv[2];
|
||||||
EIO_PBKDF2After(req, argv);
|
EIO_PBKDF2After(req, argv);
|
||||||
MakeCallback(env, obj, env->ondone_string(), ARRAY_SIZE(argv), argv);
|
req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
|
||||||
|
req->release();
|
||||||
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3359,7 +3426,8 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||||||
ssize_t pass_written = -1;
|
ssize_t pass_written = -1;
|
||||||
ssize_t salt_written = -1;
|
ssize_t salt_written = -1;
|
||||||
ssize_t iter = -1;
|
ssize_t iter = -1;
|
||||||
pbkdf2_req* req = NULL;
|
PBKDF2Request* req = NULL;
|
||||||
|
Local<Object> obj;
|
||||||
|
|
||||||
if (args.Length() != 4 && args.Length() != 5) {
|
if (args.Length() != 4 && args.Length() != 5) {
|
||||||
type_error = "Bad parameter";
|
type_error = "Bad parameter";
|
||||||
@ -3373,7 +3441,10 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass = new char[passlen];
|
pass = static_cast<char*>(malloc(passlen));
|
||||||
|
if (pass == NULL) {
|
||||||
|
FatalError("node::PBKDF2()", "Out of Memory");
|
||||||
|
}
|
||||||
pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
|
pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
|
||||||
assert(pass_written == passlen);
|
assert(pass_written == passlen);
|
||||||
|
|
||||||
@ -3384,7 +3455,10 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
salt = new char[saltlen];
|
salt = static_cast<char*>(malloc(saltlen));
|
||||||
|
if (salt == NULL) {
|
||||||
|
FatalError("node::PBKDF2()", "Out of Memory");
|
||||||
|
}
|
||||||
salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
|
salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
|
||||||
assert(salt_written == saltlen);
|
assert(salt_written == saltlen);
|
||||||
|
|
||||||
@ -3410,26 +3484,16 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
req = new pbkdf2_req;
|
obj = Object::New();
|
||||||
req->env = env;
|
req = new PBKDF2Request(env, obj, passlen, pass, saltlen, salt, iter, keylen);
|
||||||
req->err = 0;
|
|
||||||
req->pass = pass;
|
|
||||||
req->passlen = passlen;
|
|
||||||
req->salt = salt;
|
|
||||||
req->saltlen = saltlen;
|
|
||||||
req->iter = iter;
|
|
||||||
req->key = new char[keylen];
|
|
||||||
req->keylen = keylen;
|
|
||||||
|
|
||||||
if (args[4]->IsFunction()) {
|
if (args[4]->IsFunction()) {
|
||||||
Local<Object> obj = Object::New();
|
obj->Set(env->ondone_string(), args[4]);
|
||||||
obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ondone"), args[4]);
|
// XXX(trevnorris): This will need to go with the rest of domains.
|
||||||
if (env->in_domain()) {
|
if (env->in_domain())
|
||||||
obj->Set(env->domain_string(), env->domain_array()->Get(0));
|
obj->Set(env->domain_string(), env->domain_array()->Get(0));
|
||||||
}
|
|
||||||
req->obj.Reset(node_isolate, obj);
|
|
||||||
uv_queue_work(env->event_loop(),
|
uv_queue_work(env->event_loop(),
|
||||||
&req->work_req,
|
req->work_req(),
|
||||||
EIO_PBKDF2,
|
EIO_PBKDF2,
|
||||||
EIO_PBKDF2After);
|
EIO_PBKDF2After);
|
||||||
} else {
|
} else {
|
||||||
@ -3444,8 +3508,8 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
delete[] salt;
|
free(salt);
|
||||||
delete[] pass;
|
free(pass);
|
||||||
return ThrowTypeError(type_error);
|
return ThrowTypeError(type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3590,10 +3654,8 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
|
|||||||
if (args[1]->IsFunction()) {
|
if (args[1]->IsFunction()) {
|
||||||
obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ondone"), args[1]);
|
obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ondone"), args[1]);
|
||||||
// XXX(trevnorris): This will need to go with the rest of domains.
|
// XXX(trevnorris): This will need to go with the rest of domains.
|
||||||
if (env->in_domain()) {
|
if (env->in_domain())
|
||||||
obj->Set(env->domain_string(), env->domain_array()->Get(0));
|
obj->Set(env->domain_string(), env->domain_array()->Get(0));
|
||||||
}
|
|
||||||
|
|
||||||
uv_queue_work(env->event_loop(),
|
uv_queue_work(env->event_loop(),
|
||||||
req->work_req(),
|
req->work_req(),
|
||||||
RandomBytesWork<pseudoRandom>,
|
RandomBytesWork<pseudoRandom>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user