size_t iter;
char* key;
size_t keylen;
- Persistent<Function> callback;
+ Persistent<Object> obj;
};
-void
-EIO_PBKDF2(uv_work_t* req) {
- pbkdf2_req* request = (pbkdf2_req*)req->data;
- request->err = PKCS5_PBKDF2_HMAC_SHA1(
- request->pass,
- request->passlen,
- (unsigned char*)request->salt,
- request->saltlen,
- request->iter,
- request->keylen,
- (unsigned char*)request->key);
- memset(request->pass, 0, request->passlen);
- memset(request->salt, 0, request->saltlen);
+
+void EIO_PBKDF2(pbkdf2_req* req) {
+ req->err = PKCS5_PBKDF2_HMAC_SHA1(
+ req->pass,
+ req->passlen,
+ (unsigned char*)req->salt,
+ req->saltlen,
+ req->iter,
+ req->keylen,
+ (unsigned char*)req->key);
+ memset(req->pass, 0, req->passlen);
+ memset(req->salt, 0, req->saltlen);
}
-void
-EIO_PBKDF2After(uv_work_t* req) {
- HandleScope scope;
- pbkdf2_req* request = (pbkdf2_req*)req->data;
- delete req;
+void EIO_PBKDF2(uv_work_t* work_req) {
+ pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
+ EIO_PBKDF2(req);
+}
- Local<Value> argv[2];
- if (request->err) {
+
+void EIO_PBKDF2After(pbkdf2_req* req, Local<Value> argv[2]) {
+ if (req->err) {
argv[0] = Local<Value>::New(Undefined());
- argv[1] = Encode(request->key, request->keylen, BINARY);
- memset(request->key, 0, request->keylen);
+ argv[1] = Encode(req->key, req->keylen, BINARY);
+ memset(req->key, 0, req->keylen);
} else {
argv[0] = Exception::Error(String::New("PBKDF2 error"));
argv[1] = Local<Value>::New(Undefined());
}
- MakeCallback(request->obj, "ondone", ARRAY_SIZE(argv), argv);
+ delete[] req->pass;
+ delete[] req->salt;
+ delete[] req->key;
+ delete req;
+}
+
- delete[] request->pass;
- delete[] request->salt;
- delete[] request->key;
- request->obj.Dispose();
- request->obj.Clear();
+void EIO_PBKDF2After(uv_work_t* work_req) {
+ pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
- delete request;
+ HandleScope scope;
+ Local<Value> argv[2];
- Persistent<Function> cb = req->callback;
++ Persistent<Object> obj = req->obj;
+ EIO_PBKDF2After(req, argv);
-
- // XXX There should be an object connected to this that
- // we can attach a domain onto.
- MakeCallback(Context::GetCurrent()->Global(), cb, ARRAY_SIZE(argv), argv);
- cb.Dispose();
++ MakeCallback(obj, "ondone", ARRAY_SIZE(argv), argv);
++ obj.Dispose();
}
-Handle<Value>
-PBKDF2(const Arguments& args) {
+
+Handle<Value> PBKDF2(const Arguments& args) {
HandleScope scope;
const char* type_error = NULL;
ssize_t pass_written = -1;
ssize_t salt_written = -1;
ssize_t iter = -1;
-- Local<Function> callback;
- pbkdf2_req* request = NULL;
- uv_work_t* req = NULL;
- Persistent<Object> obj;
+ pbkdf2_req* req = NULL;
- if (args.Length() != 5) {
+ if (args.Length() != 4 && args.Length() != 5) {
type_error = "Bad parameter";
goto err;
}
goto err;
}
- key = new char[keylen];
+ req = new pbkdf2_req;
+ 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()) {
- type_error = "Callback not a function";
- goto err;
+ if (args[4]->IsFunction()) {
- callback = Local<Function>::Cast(args[4]);
- req->callback = Persistent<Function>::New(callback);
++ req->obj = Persistent<Object>::New(Object::New());
++ req->obj->Set(String::New("ondone"), args[4]);
+ uv_queue_work(uv_default_loop(),
+ &req->work_req,
+ EIO_PBKDF2,
+ EIO_PBKDF2After);
+ return Undefined();
+ } else {
+ Local<Value> argv[2];
+ EIO_PBKDF2(req);
+ EIO_PBKDF2After(req, argv);
+ if (argv[0]->IsObject()) return ThrowException(argv[0]);
+ return scope.Close(argv[1]);
}
- obj = Persistent<Object>::New(Object::New());
- obj->Set(String::New("ondone"), args[4]);
-
- request = new pbkdf2_req;
- request->err = 0;
- request->pass = pass;
- request->passlen = passlen;
- request->salt = salt;
- request->saltlen = saltlen;
- request->iter = iter;
- request->key = key;
- request->keylen = keylen;
- request->obj = obj;
-
- req = new uv_work_t();
- req->data = request;
- uv_queue_work(uv_default_loop(), req, EIO_PBKDF2, EIO_PBKDF2After);
- return Undefined();
-
err:
- delete[] key;
delete[] salt;
delete[] pass;
return ThrowException(Exception::TypeError(String::New(type_error)));