diff --git a/binding.gyp b/binding.gyp index d7e552c..bb34d66 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,56 +1,19 @@ { - "variables": { - }, - "targets": [ - { - "include_dirs": [ - " 1) { - this.nativeStack = messages.slice(1).join("\n"); - - const matches = /(\w+):\d+/.exec(this.nativeStack); +const util = require("node:util"); + +// pkcs11.PKCS11.prototype.C_EncryptAsync = util.promisify(pkcs11.PKCS11.prototype.C_Encrypt); +// pkcs11.PKCS11.prototype.C_DecryptAsync = util.promisify(pkcs11.PKCS11.prototype.C_Decrypt); +// pkcs11.PKCS11.prototype.C_DigestAsync = util.promisify(pkcs11.PKCS11.prototype.C_Digest); +// pkcs11.PKCS11.prototype.C_SignAsync = util.promisify(pkcs11.PKCS11.prototype.C_Sign); +// pkcs11.PKCS11.prototype.C_VerifyAsync = util.promisify(pkcs11.PKCS11.prototype.C_Verify); +// pkcs11.PKCS11.prototype.C_GenerateKeyAsync = util.promisify(pkcs11.PKCS11.prototype.C_GenerateKey); +// pkcs11.PKCS11.prototype.C_GenerateKeyPairAsync = util.promisify(pkcs11.PKCS11.prototype.C_GenerateKeyPair); +// pkcs11.PKCS11.prototype.C_WrapKeyAsync = util.promisify(pkcs11.PKCS11.prototype.C_WrapKey); +// pkcs11.PKCS11.prototype.C_UnwrapKeyAsync = util.promisify(pkcs11.PKCS11.prototype.C_UnwrapKey); +// pkcs11.PKCS11.prototype.C_DeriveKeyAsync = util.promisify(pkcs11.PKCS11.prototype.C_DeriveKey); + +class NativeError extends Error { + constructor(message, method) { + super(message || ""); + + this.name = NativeError.name; + this.method = method || ""; + this.nativeStack = ""; + + const messages = this.message.split("\n"); + const matches = /(\w+):(\d+)/.exec(this.message); if (matches) { - this.method = matches[1]; + this.message = matches[1]; + this.code = +matches[2]; + if (messages.length > 1) { + // at PKCS11.C_Finalize (/Users/microshine/g + const stackMatch = /at PKCS11\.(\w+) \(/.exec(messages[1]); + if (stackMatch) { + this.method = stackMatch[1]; + } + this.nativeStack = messages.slice(1).join("\n"); + } + } else { + this.message = messages[0]; + this.code = 0; } } } -util.inherits(NativeError, Error); pkcs11.NativeError = NativeError; -function Pkcs11Error(message, code, method) { - NativeError.call(this, message, method); +class Pkcs11Error extends NativeError { + constructor(message, code, method) { + super(message, method); - this.name = Pkcs11Error.name; - this.code = code || 0; + this.name = Pkcs11Error.name; + this.code = code || 0; - const matches = new RegExp(Pkcs11Error.messageReg).exec(message); - if (matches) { - this.message = matches[1]; - this.code = +matches[2]; + const matches = new RegExp(Pkcs11Error.messageReg).exec(message); + if (matches) { + this.message = matches[1]; + this.code = +matches[2]; + } } } -util.inherits(Pkcs11Error, NativeError); Pkcs11Error.messageReg = /(CKR_[^:]+):(\d+)/; @@ -59,6 +69,28 @@ Pkcs11Error.isPkcs11 = function isPkcs11(message) { pkcs11.Pkcs11Error = Pkcs11Error; +function prepareError(e) { + if (Pkcs11Error.isPkcs11(e.stack)) { + return new Pkcs11Error(e.stack); + } + if (e instanceof TypeError) { + return e; + } + return new NativeError(e.message); +} + +function handleError(e) { + throw prepareError(e); +} + +function modifyMethodWithSubarray(methodName, argIndex, prototype) { + const old = prototype[methodName]; + prototype[methodName] = function (...args) { + const res = old.apply(this, args); + return args[argIndex].subarray(0, res); + }; +} + /** * Catches and wraps PKCS#11 errors to Pkcs11Error * @param {*} fn @@ -69,26 +101,505 @@ function catchError(fn) { const res = fn.apply(this, args); if (res instanceof Promise) { return res.catch((e) => { - if (Pkcs11Error.isPkcs11(e.message)) { - throw new Pkcs11Error(e.message); - } - throw new NativeError(e.message); + handleError(e); }); } return res; } catch (e) { - if (Pkcs11Error.isPkcs11(e.message)) { - throw new Pkcs11Error(e.message); - } - throw new NativeError(e.message); + handleError(e); } }; } +function fixCallbackArgs(cb, dataToSubarray) { + if (typeof cb === "function") { + return function (err, data) { + if (err) { + return cb(prepareError(err), null); + } + cb(null, dataToSubarray.subarray(0, data)); + }; + } +} + // Customize native exceptions for (const key in pkcs11.PKCS11.prototype) { if (pkcs11.PKCS11.prototype.hasOwnProperty(key)) { pkcs11.PKCS11.prototype[key] = catchError(pkcs11.PKCS11.prototype[key]); + + switch (key) { + case "C_FindObjects": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 2) { + args.push(1); + return old.apply(this, args)[0] || null; + } + return old.apply(this, args); + }; + break; + } + case "C_Digest": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + const res = old.apply(this, args); + return args[2].subarray(0, res); + } else { + // callback + return this.C_DigestCallback(...args); + } + }; + break; + } + case "C_DigestCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = fixCallbackArgs(oldCallback, args[2]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_DigestFinal": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 3) { + // sync + const res = old.apply(this, args); + return args[1].subarray(0, res); + } else { + // callback + return this.C_DigestFinalCallback(...args); + } + }; + break; + } + case "C_DigestFinalCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[2]; + if (typeof oldCallback === "function") { + args[2] = fixCallbackArgs(oldCallback, args[1]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_Sign": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + const res = old.apply(this, args); + return args[2].subarray(0, res); + } else { + // callback + return this.C_SignCallback(...args); + } + }; + break; + } + case "C_SignCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = fixCallbackArgs(oldCallback, args[2]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_SignFinal": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 3) { + // sync + const res = old.apply(this, args); + return args[1].subarray(0, res); + } else { + // callback + return this.C_SignFinalCallback(...args); + } + }; + break; + } + case "C_SignFinalCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[2]; + if (typeof oldCallback === "function") { + args[2] = fixCallbackArgs(oldCallback, args[1]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_Encrypt": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + const res = old.apply(this, args); + return args[2].subarray(0, res); + } else { + // callback + return this.C_EncryptCallback(...args); + } + }; + break; + } + case "C_EncryptCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = fixCallbackArgs(oldCallback, args[2]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + } + case "C_EncryptUpdate": { + modifyMethodWithSubarray(key, 2, pkcs11.PKCS11.prototype); + break; + } + case "C_EncryptFinal": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 3) { + // sync + const res = old.apply(this, args); + return args[1].subarray(0, res); + } else { + // callback + return this.C_EncryptFinalCallback(...args); + } + }; + break; + } + case "C_EncryptFinalCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[2]; + if (typeof oldCallback === "function") { + args[2] = fixCallbackArgs(oldCallback, args[1]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_Decrypt": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + const res = old.apply(this, args); + return args[2].subarray(0, res); + } else { + // callback + return this.C_DecryptCallback(...args); + } + }; + break; + } + case "C_DecryptCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = fixCallbackArgs(oldCallback, args[2]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + } + case "C_DecryptUpdate": { + modifyMethodWithSubarray(key, 2, pkcs11.PKCS11.prototype); + break; + } + case "C_DecryptFinal": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 3) { + // sync + const res = old.apply(this, args); + return args[1].subarray(0, res); + } else { + // callback + return this.C_DecryptFinalCallback(...args); + } + }; + break; + } + case "C_DecryptFinalCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[2]; + if (typeof oldCallback === "function") { + args[2] = fixCallbackArgs(oldCallback, args[1]); + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_Verify": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + return old.apply(this, args); + } else { + // callback + return this.C_VerifyCallback(...args); + } + }; + break; + } + case "C_VerifyCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_VerifyFinal": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 3) { + // sync + return old.apply(this, args); + } else { + // callback + return this.C_VerifyFinalCallback(...args); + } + }; + break; + } + case "C_VerifyFinalCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[2]; + if (typeof oldCallback === "function") { + args[2] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + }; + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_GenerateKey": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 4) { + // sync + return old.apply(this, args); + } + // callback + return this.C_GenerateKeyCallback(...args); + } + break; + } + case "C_GenerateKeyCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[3]; + if (typeof oldCallback === "function") { + args[3] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + } + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_GenerateKeyPair": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 5) { + // sync + return old.apply(this, args); + } + // callback + return this.C_GenerateKeyPairCallback(...args); + } + break; + } + case "C_GenerateKeyPairCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[4]; + if (typeof oldCallback === "function") { + args[4] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + } + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_DeriveKey": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 5) { + // sync + return old.apply(this, args); + } + // callback + return this.C_DeriveKeyCallback(...args); + } + break; + } + case "C_DeriveKeyCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[5]; + if (typeof oldCallback === "function") { + args[5] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + } + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_WrapKey": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 6) { + // sync + const res = old.apply(this, args); + return args[4].subarray(0, res); + } + // callback + return this.C_WrapKeyCallback(...args); + } + break; + } + case "C_WrapKeyCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + + const oldCallback = args[4]; + if (typeof oldCallback === "function") { + args[4] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + } + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + break; + } + case "C_UnwrapKey": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + if (args.length < 6) { + // sync + return old.apply(this, args); + } + // callback + return this.C_UnwrapKeyCallback(...args); + } + break; + } + case "C_UnwrapKeyCallback": { + const old = pkcs11.PKCS11.prototype[key]; + pkcs11.PKCS11.prototype[key] = function (...args) { + const oldCallback = args[5]; + if (typeof oldCallback === "function") { + args[5] = (err, res) => { + if (err) { + return oldCallback(prepareError(err), null); + } + oldCallback(null, res); + }; + } + return old.apply(this, args); + } + // async + const name = key.replace("Callback", "Async"); + pkcs11.PKCS11.prototype[name] = util.promisify(pkcs11.PKCS11.prototype[key]); + + break; + } + case "C_SignRecover": { + modifyMethodWithSubarray(key, 2, pkcs11.PKCS11.prototype); + break; + } + case "C_VerifyRecover": { + modifyMethodWithSubarray(key, 2, pkcs11.PKCS11.prototype); + break; + } + } } } diff --git a/package-lock.json b/package-lock.json index a095147..4f27bf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "pkcs11js", "version": "1.3.1", "license": "MIT", - "dependencies": { - "nan": "^2.15.0" - }, "devDependencies": { "@types/mocha": "^9.1.0", "@types/node": "^17.0.15", @@ -1829,11 +1826,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -4274,11 +4266,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, "nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", diff --git a/package.json b/package.json index db3a630..dc6bc7a 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,6 @@ }, "author": "PeculiarVentures", "license": "MIT", - "dependencies": { - "nan": "^2.15.0" - }, "devDependencies": { "@types/mocha": "^9.1.0", "@types/node": "^17.0.15", diff --git a/src/async.cpp b/src/async.cpp deleted file mode 100644 index b81305e..0000000 --- a/src/async.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "./async.h" - -static Local handle_to_v8(CK_ULONG handle) { - Nan::EscapableHandleScope scope; - - Local v8Buffer = Nan::NewBuffer(sizeof(CK_ULONG)).ToLocalChecked(); - char* buf = node::Buffer::Data(v8Buffer); - - memcpy(buf, &handle, sizeof(CK_ULONG)); - - return scope.Escape(v8Buffer); -} - -void AsyncGenerateKey::Execute() { - try { - hKey = pkcs11->C_GenerateKey(hSession, mech, tmpl); - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncGenerateKey::HandleOKCallback() { - Nan::HandleScope scope; - - v8::Local argv[] = { - Nan::Null(), - handle_to_v8(hKey) - }; - - callback->Call(2, argv, async_resource); -} - -void AsyncGenerateKeyPair::Execute() { - try { - keyPair = pkcs11->C_GenerateKeyPair(hSession, mech, publicKeyTemplate, privateKeyTemplate); - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncGenerateKeyPair::HandleOKCallback() { - Nan::HandleScope scope; - - Local v8KeyPair = Nan::New(); - Nan::Set(v8KeyPair, Nan::New(STR_PRIVATE_KEY).ToLocalChecked(), handle_to_v8(keyPair->privateKey)); - Nan::Set(v8KeyPair, Nan::New(STR_PUBLIC_KEY).ToLocalChecked(), handle_to_v8(keyPair->publicKey)); - - v8::Local argv[] = { - Nan::Null(), - v8KeyPair - }; - - callback->Call(2, argv, async_resource); -} - -void AsyncCrypto::Execute() { - try { - switch (type) { - case ASYNC_CRYPTO_DIGEST: - result = pkcs11->C_Digest(hSession, input, output); - break; - case ASYNC_CRYPTO_ENCRYPT: - result = pkcs11->C_Encrypt(hSession, input, output); - break; - case ASYNC_CRYPTO_DECRYPT: - result = pkcs11->C_Decrypt(hSession, input, output); - break; - case ASYNC_CRYPTO_SIGN: - result = pkcs11->C_Sign(hSession, input, output); - break; - case ASYNC_CRYPTO_VERIFY: - pkcs11->C_Verify(hSession, input, output); - break; - } - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncCrypto::HandleOKCallback() { - Nan::HandleScope scope; - - Local v8Result; - - if (type == ASYNC_CRYPTO_VERIFY) { - v8Result = Nan::New(true); - } - else { - v8Result = Nan::CopyBuffer(result->c_str(), (uint32_t)result->length()).ToLocalChecked(); - } - - v8::Local argv[] = { - Nan::Null(), - v8Result - }; - - callback->Call(2, argv, async_resource); -} - -void AsyncWrapKey::Execute() { - try { - result = pkcs11->C_WrapKey(hSession, mech, hWrappingKey, hKey, wrappedKey); - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncWrapKey::HandleOKCallback() { - Nan::HandleScope scope; - - Local v8Result; - - v8Result = Nan::CopyBuffer(result->c_str(), (uint32_t)result->length()).ToLocalChecked(); - - v8::Local argv[] = { - Nan::Null(), - v8Result - }; - - callback->Call(2, argv, async_resource); -} - -void AsyncUnwrapKey::Execute() { - try { - result = pkcs11->C_UnwrapKey(hSession, mech, hUnwrappingKey, wrappedKey, tmpl); - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncUnwrapKey::HandleOKCallback() { - Nan::HandleScope scope; - - Local v8Result; - - v8Result = handle_to_v8(result); - - v8::Local argv[] = { - Nan::Null(), - v8Result - }; - - callback->Call(2, argv, async_resource); -} - -void AsyncDeriveKey::Execute() { - try { - result = pkcs11->C_DeriveKey(hSession, mech, hBaseKey, tmpl); - } - catch (Scoped e) { - this->SetErrorMessage(e->ToString()->c_str()); - } -} - -void AsyncDeriveKey::HandleOKCallback() { - Nan::HandleScope scope; - - Local v8Result; - - v8Result = handle_to_v8(result); - - v8::Local argv[] = { - Nan::Null(), - v8Result - }; - - callback->Call(2, argv, async_resource); -} diff --git a/src/async.h b/src/async.h deleted file mode 100644 index c55a2a1..0000000 --- a/src/async.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef INCLUDE_H_ASYNC -#define INCLUDE_H_ASYNC - -#include "pkcs11/pkcs11.h" - -using namespace node; -using namespace v8; - -class AsyncGenerateKey : public Nan::AsyncWorker { -public: - AsyncGenerateKey( - Nan::Callback *callback, - Scoped pkcs11, - CK_SESSION_HANDLE hSession, - Scoped mech, - Scoped tmpl - ) : AsyncWorker(callback), pkcs11(pkcs11), hSession(hSession), mech(mech), tmpl(tmpl) {} - ~AsyncGenerateKey() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - CK_SESSION_HANDLE hSession; - Scoped mech; - Scoped tmpl; - // Result - CK_OBJECT_HANDLE hKey; -}; - -class AsyncGenerateKeyPair : public Nan::AsyncWorker { -public: - AsyncGenerateKeyPair( - Nan::Callback *callback, - Scoped pkcs11, - CK_SESSION_HANDLE hSession, - Scoped mech, - Scoped publicKeyTemplate, - Scoped privateKeyTemplate - ) : AsyncWorker(callback), pkcs11(pkcs11), hSession(hSession), mech(mech), publicKeyTemplate(publicKeyTemplate), privateKeyTemplate(privateKeyTemplate) {} - ~AsyncGenerateKeyPair() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - CK_SESSION_HANDLE hSession; - Scoped mech; - Scoped publicKeyTemplate; - Scoped privateKeyTemplate; - // Result - Scoped keyPair; -}; - -#define ASYNC_CRYPTO_DIGEST 0 -#define ASYNC_CRYPTO_ENCRYPT 1 -#define ASYNC_CRYPTO_DECRYPT 2 -#define ASYNC_CRYPTO_SIGN 3 -#define ASYNC_CRYPTO_VERIFY 4 - -class AsyncCrypto : public Nan::AsyncWorker { -public: - AsyncCrypto( - Nan::Callback *callback, - Scoped pkcs11, - int type, - CK_SESSION_HANDLE hSession, - Scoped input, - Scoped output - ) : AsyncWorker(callback), pkcs11(pkcs11), type(type), hSession(hSession), input(input), output(output) {} - ~AsyncCrypto() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - int type; - CK_SESSION_HANDLE hSession; - Scoped input; - Scoped output; - // Result - Scoped result; -}; - -class AsyncWrapKey : public Nan::AsyncWorker { -public: - AsyncWrapKey( - Nan::Callback *callback, - Scoped pkcs11, - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, - Scoped wrappedKey - ) : AsyncWorker(callback), pkcs11(pkcs11), hSession(hSession), mech(mech), - hWrappingKey(hWrappingKey), hKey(hKey), wrappedKey(wrappedKey) {} - ~AsyncWrapKey() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - CK_SESSION_HANDLE hSession; - Scoped mech; - CK_OBJECT_HANDLE hWrappingKey; - CK_OBJECT_HANDLE hKey; - Scoped wrappedKey; - // Result - Scoped result; -}; - -class AsyncUnwrapKey : public Nan::AsyncWorker { -public: - AsyncUnwrapKey( - Nan::Callback *callback, - Scoped pkcs11, - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hUnwrappingKey, - Scoped wrappedKey, - Scoped tmpl - ) : AsyncWorker(callback), pkcs11(pkcs11), hSession(hSession), mech(mech), - hUnwrappingKey(hUnwrappingKey), wrappedKey(wrappedKey), tmpl(tmpl) {} - ~AsyncUnwrapKey() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - CK_SESSION_HANDLE hSession; - Scoped mech; - CK_OBJECT_HANDLE hUnwrappingKey; - Scoped wrappedKey; - Scoped tmpl; - // Result - CK_OBJECT_HANDLE result; -}; - -class AsyncDeriveKey : public Nan::AsyncWorker { -public: - AsyncDeriveKey( - Nan::Callback *callback, - Scoped pkcs11, - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hBaseKey, - Scoped tmpl - ) : AsyncWorker(callback), pkcs11(pkcs11), hSession(hSession), mech(mech), - hBaseKey(hBaseKey), tmpl(tmpl) {} - ~AsyncDeriveKey() {} - - void Execute(); - void HandleOKCallback(); - -protected: - Scoped pkcs11; - CK_SESSION_HANDLE hSession; - Scoped mech; - CK_OBJECT_HANDLE hBaseKey; - Scoped tmpl; - // Result - CK_OBJECT_HANDLE result; -}; - -#endif // INCLUDE_H_ASYNC \ No newline at end of file diff --git a/src/common.cpp b/src/common.cpp new file mode 100644 index 0000000..c314051 --- /dev/null +++ b/src/common.cpp @@ -0,0 +1,245 @@ +/** + * @file common.cpp + * @brief Implementation of common functions used in the project. + */ +#include "common.h" + +const char *get_error_name(CK_RV rv) +{ +#define CASE(x) \ + case x: \ + return #x; + switch (rv) + { + CASE(CKR_OK) + CASE(CKR_CANCEL) + CASE(CKR_HOST_MEMORY) + CASE(CKR_SLOT_ID_INVALID) + CASE(CKR_GENERAL_ERROR) + CASE(CKR_FUNCTION_FAILED) + CASE(CKR_ARGUMENTS_BAD) + CASE(CKR_NO_EVENT) + CASE(CKR_NEED_TO_CREATE_THREADS) + CASE(CKR_CANT_LOCK) + CASE(CKR_ATTRIBUTE_READ_ONLY) + CASE(CKR_ATTRIBUTE_SENSITIVE) + CASE(CKR_ATTRIBUTE_TYPE_INVALID) + CASE(CKR_ATTRIBUTE_VALUE_INVALID) + CASE(CKR_DATA_INVALID) + CASE(CKR_DATA_LEN_RANGE) + CASE(CKR_DEVICE_ERROR) + CASE(CKR_DEVICE_MEMORY) + CASE(CKR_DEVICE_REMOVED) + CASE(CKR_ENCRYPTED_DATA_INVALID) + CASE(CKR_ENCRYPTED_DATA_LEN_RANGE) + CASE(CKR_FUNCTION_CANCELED) + CASE(CKR_FUNCTION_NOT_PARALLEL) + CASE(CKR_FUNCTION_NOT_SUPPORTED) + CASE(CKR_KEY_HANDLE_INVALID) + CASE(CKR_KEY_SIZE_RANGE) + CASE(CKR_KEY_TYPE_INCONSISTENT) + CASE(CKR_KEY_NOT_NEEDED) + CASE(CKR_KEY_CHANGED) + CASE(CKR_KEY_NEEDED) + CASE(CKR_KEY_INDIGESTIBLE) + CASE(CKR_KEY_FUNCTION_NOT_PERMITTED) + CASE(CKR_KEY_NOT_WRAPPABLE) + CASE(CKR_KEY_UNEXTRACTABLE) + CASE(CKR_MECHANISM_INVALID) + CASE(CKR_MECHANISM_PARAM_INVALID) + CASE(CKR_OBJECT_HANDLE_INVALID) + CASE(CKR_OPERATION_ACTIVE) + CASE(CKR_OPERATION_NOT_INITIALIZED) + CASE(CKR_PIN_INCORRECT) + CASE(CKR_PIN_INVALID) + CASE(CKR_PIN_LEN_RANGE) + CASE(CKR_PIN_EXPIRED) + CASE(CKR_PIN_LOCKED) + CASE(CKR_SESSION_CLOSED) + CASE(CKR_SESSION_COUNT) + CASE(CKR_SESSION_HANDLE_INVALID) + CASE(CKR_SESSION_PARALLEL_NOT_SUPPORTED) + CASE(CKR_SESSION_READ_ONLY) + CASE(CKR_SESSION_EXISTS) + CASE(CKR_SESSION_READ_ONLY_EXISTS) + CASE(CKR_SESSION_READ_WRITE_SO_EXISTS) + CASE(CKR_SIGNATURE_INVALID) + CASE(CKR_SIGNATURE_LEN_RANGE) + CASE(CKR_TEMPLATE_INCOMPLETE) + CASE(CKR_TEMPLATE_INCONSISTENT) + CASE(CKR_TOKEN_NOT_PRESENT) + CASE(CKR_TOKEN_NOT_RECOGNIZED) + CASE(CKR_TOKEN_WRITE_PROTECTED) + CASE(CKR_UNWRAPPING_KEY_HANDLE_INVALID) + CASE(CKR_UNWRAPPING_KEY_SIZE_RANGE) + CASE(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT) + CASE(CKR_USER_ALREADY_LOGGED_IN) + CASE(CKR_USER_NOT_LOGGED_IN) + CASE(CKR_USER_PIN_NOT_INITIALIZED) + CASE(CKR_USER_TYPE_INVALID) + CASE(CKR_USER_ANOTHER_ALREADY_LOGGED_IN) + CASE(CKR_USER_TOO_MANY_TYPES) + CASE(CKR_WRAPPED_KEY_INVALID) + CASE(CKR_WRAPPED_KEY_LEN_RANGE) + CASE(CKR_WRAPPING_KEY_HANDLE_INVALID) + CASE(CKR_WRAPPING_KEY_SIZE_RANGE) + CASE(CKR_WRAPPING_KEY_TYPE_INCONSISTENT) + CASE(CKR_RANDOM_SEED_NOT_SUPPORTED) + CASE(CKR_RANDOM_NO_RNG) + CASE(CKR_DOMAIN_PARAMS_INVALID) + CASE(CKR_BUFFER_TOO_SMALL) + CASE(CKR_SAVED_STATE_INVALID) + CASE(CKR_INFORMATION_SENSITIVE) + CASE(CKR_STATE_UNSAVEABLE) + CASE(CKR_CRYPTOKI_NOT_INITIALIZED) + CASE(CKR_CRYPTOKI_ALREADY_INITIALIZED) + CASE(CKR_MUTEX_BAD) + CASE(CKR_MUTEX_NOT_LOCKED) + CASE(CKR_NEW_PIN_MODE) + CASE(CKR_NEXT_OTP) + CASE(CKR_EXCEEDED_MAX_ITERATIONS) + CASE(CKR_FIPS_SELF_TEST_FAILED) + CASE(CKR_LIBRARY_LOAD_FAILED) + CASE(CKR_PIN_TOO_WEAK) + CASE(CKR_PUBLIC_KEY_INVALID) + CASE(CKR_FUNCTION_REJECTED) + default: + return "CKR_VENDOR_DEFINED"; + } +#undef CASE +} + +void throw_rv_error(napi_env env, CK_RV rv) +{ + const char *errorName = get_error_name(rv); + char error_message[100]; + snprintf(error_message, sizeof(error_message), "%s:%lu", errorName, rv); + napi_throw_error(env, nullptr, error_message); +} + +void throw_type_errorf(napi_env env, const char *format, ...) +{ + char error_message[100]; + va_list args; + va_start(args, format); + vsnprintf(error_message, sizeof(error_message), format, args); + va_end(args); + napi_throw_type_error(env, nullptr, error_message); +} + +bool is_object(napi_env env, napi_value value) +{ + napi_valuetype type; + napi_typeof(env, value, &type); + return type == napi_object; +} + +bool is_string(napi_env env, napi_value value) +{ + napi_valuetype type; + napi_typeof(env, value, &type); + return type == napi_string; +} + +bool is_number(napi_env env, napi_value value) +{ + napi_valuetype type; + napi_typeof(env, value, &type); + return type == napi_number; +} + +bool is_array(napi_env env, napi_value value) +{ + bool is_array; + napi_is_array(env, value, &is_array); + return is_array; +} + +bool is_buffer(napi_env env, napi_value value) +{ + bool is_buffer; + napi_is_buffer(env, value, &is_buffer); + return is_buffer; +} + +bool is_empty(napi_env env, napi_value value) +{ + napi_valuetype type; + napi_typeof(env, value, &type); + return type == napi_undefined || type == napi_null; +} + +bool is_function(napi_env env, napi_value value) +{ + napi_valuetype type; + napi_typeof(env, value, &type); + return type == napi_function; +} + +MechanismWrapper::MechanismWrapper(CK_MECHANISM *mechanism, bool dispose) +{ + this->value = mechanism; + this->dispose = dispose; +} + +MechanismWrapper::MechanismWrapper() +{ + this->value = (CK_MECHANISM_PTR)malloc(sizeof(CK_MECHANISM)); + this->dispose = true; +} + +MechanismWrapper::~MechanismWrapper() +{ + if (this->dispose && this->value != nullptr) + { + if (this->value->pParameter != nullptr) + { + free(this->value->pParameter); + } + free(this->value); + } +} + +AttributesWrapper::AttributesWrapper(CK_ATTRIBUTE_PTR attributes, CK_ULONG length, bool dispose) +{ + this->attributes = attributes; + this->length = length; + this->dispose = dispose; +} + +AttributesWrapper::AttributesWrapper(CK_ULONG length) +{ + this->length = length; + this->attributes = (CK_ATTRIBUTE_PTR)malloc(sizeof(CK_ATTRIBUTE) * length); + this->dispose = true; +} + +AttributesWrapper::~AttributesWrapper() +{ + if (dispose) + { + for (int i = 0; i < int(length); i++) + { + if (attributes[i].pValue != nullptr) + { + free(attributes[i].pValue); + } + } + free(attributes); + } +} + +void AttributesWrapper::allocValue(CK_ULONG index, CK_ULONG length) +{ + attributes[index].pValue = malloc(sizeof(CK_BYTE) * length); + attributes[index].ulValueLen = length; + this->dispose = true; +} + +void AttributesWrapper::allocAllValues() +{ + for (int i = 0; i < int(length); i++) + { + allocValue(i, attributes[i].ulValueLen); + } +} diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..ef908f3 --- /dev/null +++ b/src/common.h @@ -0,0 +1,202 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#else +#include "dl.h" +#endif + +// Types of parameters +#define CK_PARAMS_BUFFER 0 +#define CK_PARAMS_AES_CBC 1 +#define CK_PARAMS_AES_CCM 2 +#define CK_PARAMS_AES_GCM 3 +#define CK_PARAMS_RSA_OAEP 4 +#define CK_PARAMS_RSA_PSS 5 +#define CK_PARAMS_EC_DH 6 +#define CK_PARAMS_AES_GCM_v240 7 + +/** + * @brief Retrieves the name of the error code. + * + * This function takes a CK_RV error code as input and returns the corresponding + * name of the error. The error name is a string representation of the error code. + * + * @param rv The CK_RV error code. + * @return The name of the error code as a const char pointer. + */ +const char *get_error_name(CK_RV rv); + +/** + * @brief Throws an error based on the CK_RV error code. + * + * This function takes a CK_RV error code as input and throws an error based on + * the error code. The error message is a string representation of the error name + * and the error code separated by a colon (e.g. "CKR_ARGUMENTS_BAD:5"). + * + * @param env The n-api environment. + * @param rv The CK_RV error code. + */ +void throw_rv_error(napi_env env, CK_RV rv); +/** + * @brief Throws a type error with a formatted message. + * + * @param env The N-API environment. + * @param format The format string for the error message. + * @param ... The arguments to be formatted into the error message. + */ +void throw_type_errorf(napi_env env, const char *format, ...); + +/** + * @brief Macro for throwing a type error with a formatted message and returning a value. + * + * @param returnValue The value to be returned. + * @param format The format string for the error message. + * @param ... The arguments to be formatted into the error message. + */ +#define THROW_TYPE_ERRORF(returnValue, format, ...) \ + throw_type_errorf(env, format, __VA_ARGS__); \ + return returnValue; +/** + * Checks if the given value is an Object. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is an object, false otherwise. + */ +bool is_object(napi_env env, napi_value value); +/** + * Checks if the given value is a String. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is a string, false otherwise. + */ +bool is_string(napi_env env, napi_value value); +/** + * Checks if the given value is a Number. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is a number, false otherwise. + */ +bool is_number(napi_env env, napi_value value); +/** + * Checks if the given value is an Array. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is an array, false otherwise. + */ +bool is_array(napi_env env, napi_value value); +/** + * Checks if the given value is a Buffer. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is a buffer, false otherwise. + */ +bool is_buffer(napi_env env, napi_value value); +/** + * Checks if the given value is an empty value (Null or Undefined) + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is a boolean, false otherwise. + */ +bool is_empty(napi_env env, napi_value value); +/** + * Checks if the given value is a Function. + * + * @param env The N-API environment. + * @param value The value to be checked. + * @return True if the value is a function, false otherwise. + */ +bool is_function(napi_env env, napi_value value); + +/** + * @brief A wrapper class for CK_MECHANISM structure. + * + * This class provides a convenient way to manage CK_MECHANISM objects by automatically disposing them when they are no longer needed. + */ +class MechanismWrapper +{ +public: + CK_MECHANISM *value; // Pointer to the CK_MECHANISM object. + bool dispose; // Flag indicating whether the CK_MECHANISM object should be disposed. + + /** + * @brief Constructs a MechanismWrapper object with the specified CK_MECHANISM object and disposal flag. + * + * @param mechanism Pointer to the CK_MECHANISM object. + * @param dispose Flag indicating whether the CK_MECHANISM object should be disposed. Default is false. + */ + MechanismWrapper(CK_MECHANISM *mechanism, bool dispose = false); + + /** + * @brief Default constructor for MechanismWrapper. + * + * Initializes the CK_MECHANISM object to NULL and sets the dispose flag to true. + */ + MechanismWrapper(); + + /** + * @brief Destructor for MechanismWrapper. + * + * Automatically disposes the CK_MECHANISM object and its members if the dispose flag is set to true. + */ + ~MechanismWrapper(); +}; + +/** + * @brief A class that wraps CK_ATTRIBUTE_PTR and provides utility functions for managing attributes. + */ +class AttributesWrapper +{ +public: + CK_ATTRIBUTE_PTR attributes; // Pointer to the CK_ATTRIBUTE array. + CK_ULONG length; // The length of the attributes array. + bool dispose; // Flag indicating whether the attributes should be disposed. + + /** + * @brief Constructs an AttributesWrapper object with the given attributes and length. + * @param attributes The pointer to the CK_ATTRIBUTE array. + * @param length The length of the attributes array. + * @param dispose Flag indicating whether the attributes should be disposed. + */ + AttributesWrapper(CK_ATTRIBUTE_PTR attributes, CK_ULONG length, bool dispose = false); + + /** + * @brief Constructs an AttributesWrapper object with the given length. + * @param length The length of the attributes array. + */ + AttributesWrapper(CK_ULONG length); + + /** + * @brief Destructor for the AttributesWrapper object. Automatically disposes the attributes + * if the dispose flag is set to true. + */ + ~AttributesWrapper(); + + /** + * @brief Allocates memory for the value of the attribute at the specified index. + * @param index The index of the attribute. + * @param length The length of the value to be allocated. + */ + void allocValue(CK_ULONG index, CK_ULONG length); + + /** + * @brief Allocates memory for the values of all attributes. + */ + void allocAllValues(); +}; + +#endif // COMMON_H \ No newline at end of file diff --git a/src/const.cpp b/src/const.cpp index 832e816..37aaea7 100644 --- a/src/const.cpp +++ b/src/const.cpp @@ -1,680 +1,815 @@ -#include "const.h" +/** + * @file const.cpp + * @brief Constants for PKCS11JS module. + * + * This file contains functions to set constant values in the exports object for the PKCS11JS module. + * The constants include CKR_* (Cryptoki Return Codes), CKP_* (Cryptoki Parameters), CKF_* (Cryptoki Flags), + * CKA_* (Cryptoki Attributes), CKO_* (Cryptoki Object Classes), and CKM_* (Cryptoki Mechanisms). + */ -void declare_attributes(Local target) { - Nan::HandleScope scope; +#include "common.h" - SET_CONST(target, CKA_CLASS); - SET_CONST(target, CKA_TOKEN); - SET_CONST(target, CKA_PRIVATE); - SET_CONST(target, CKA_LABEL); - SET_CONST(target, CKA_APPLICATION); - SET_CONST(target, CKA_VALUE); - SET_CONST(target, CKA_OBJECT_ID); - SET_CONST(target, CKA_CERTIFICATE_TYPE); - SET_CONST(target, CKA_ISSUER); - SET_CONST(target, CKA_SERIAL_NUMBER); - SET_CONST(target, CKA_AC_ISSUER); - SET_CONST(target, CKA_OWNER); - SET_CONST(target, CKA_ATTR_TYPES); - SET_CONST(target, CKA_TRUSTED); - SET_CONST(target, CKA_CERTIFICATE_CATEGORY); - SET_CONST(target, CKA_JAVA_MIDP_SECURITY_DOMAIN); - SET_CONST(target, CKA_URL); - SET_CONST(target, CKA_HASH_OF_SUBJECT_PUBLIC_KEY); - SET_CONST(target, CKA_HASH_OF_ISSUER_PUBLIC_KEY); - SET_CONST(target, CKA_NAME_HASH_ALGORITHM); - SET_CONST(target, CKA_CHECK_VALUE); - SET_CONST(target, CKA_KEY_TYPE); - SET_CONST(target, CKA_SUBJECT); - SET_CONST(target, CKA_ID); - SET_CONST(target, CKA_SENSITIVE); - SET_CONST(target, CKA_ENCRYPT); - SET_CONST(target, CKA_DECRYPT); - SET_CONST(target, CKA_WRAP); - SET_CONST(target, CKA_UNWRAP); - SET_CONST(target, CKA_SIGN); - SET_CONST(target, CKA_SIGN_RECOVER); - SET_CONST(target, CKA_VERIFY); - SET_CONST(target, CKA_VERIFY_RECOVER); - SET_CONST(target, CKA_DERIVE); - SET_CONST(target, CKA_START_DATE); - SET_CONST(target, CKA_END_DATE); - SET_CONST(target, CKA_MODULUS); - SET_CONST(target, CKA_MODULUS_BITS); - SET_CONST(target, CKA_PUBLIC_EXPONENT); - SET_CONST(target, CKA_PRIVATE_EXPONENT); - SET_CONST(target, CKA_PRIME_1); - SET_CONST(target, CKA_PRIME_2); - SET_CONST(target, CKA_EXPONENT_1); - SET_CONST(target, CKA_EXPONENT_2); - SET_CONST(target, CKA_COEFFICIENT); - SET_CONST(target, CKA_PRIME); - SET_CONST(target, CKA_SUBPRIME); - SET_CONST(target, CKA_BASE); - SET_CONST(target, CKA_PRIME_BITS); - SET_CONST(target, CKA_SUBPRIME_BITS); - SET_CONST(target, CKA_SUB_PRIME_BITS); - SET_CONST(target, CKA_VALUE_BITS); - SET_CONST(target, CKA_VALUE_LEN); - SET_CONST(target, CKA_EXTRACTABLE); - SET_CONST(target, CKA_LOCAL); - SET_CONST(target, CKA_NEVER_EXTRACTABLE); - SET_CONST(target, CKA_ALWAYS_SENSITIVE); - SET_CONST(target, CKA_KEY_GEN_MECHANISM); - SET_CONST(target, CKA_MODIFIABLE); - SET_CONST(target, CKA_COPYABLE); - SET_CONST(target, CKA_DESTROYABLE); - SET_CONST(target, CKA_ECDSA_PARAMS); - SET_CONST(target, CKA_EC_PARAMS); - SET_CONST(target, CKA_EC_POINT); - SET_CONST(target, CKA_SECONDARY_AUTH); - SET_CONST(target, CKA_AUTH_PIN_FLAGS); - SET_CONST(target, CKA_ALWAYS_AUTHENTICATE); - SET_CONST(target, CKA_WRAP_WITH_TRUSTED); - SET_CONST(target, CKA_WRAP_TEMPLATE); - SET_CONST(target, CKA_UNWRAP_TEMPLATE); - SET_CONST(target, CKA_DERIVE_TEMPLATE); - SET_CONST(target, CKA_OTP_FORMAT); - SET_CONST(target, CKA_OTP_LENGTH); - SET_CONST(target, CKA_OTP_TIME_INTERVAL); - SET_CONST(target, CKA_OTP_USER_FRIENDLY_MODE); - SET_CONST(target, CKA_OTP_CHALLENGE_REQUIREMENT); - SET_CONST(target, CKA_OTP_TIME_REQUIREMENT); - SET_CONST(target, CKA_OTP_COUNTER_REQUIREMENT); - SET_CONST(target, CKA_OTP_PIN_REQUIREMENT); - SET_CONST(target, CKA_OTP_COUNTER); - SET_CONST(target, CKA_OTP_TIME); - SET_CONST(target, CKA_OTP_USER_IDENTIFIER); - SET_CONST(target, CKA_OTP_SERVICE_IDENTIFIER); - SET_CONST(target, CKA_OTP_SERVICE_LOGO); - SET_CONST(target, CKA_OTP_SERVICE_LOGO_TYPE); - SET_CONST(target, CKA_GOSTR3410_PARAMS); - SET_CONST(target, CKA_GOSTR3411_PARAMS); - SET_CONST(target, CKA_GOST28147_PARAMS); - SET_CONST(target, CKA_HW_FEATURE_TYPE); - SET_CONST(target, CKA_RESET_ON_INIT); - SET_CONST(target, CKA_HAS_RESET); - SET_CONST(target, CKA_PIXEL_X); - SET_CONST(target, CKA_PIXEL_Y); - SET_CONST(target, CKA_RESOLUTION); - SET_CONST(target, CKA_CHAR_ROWS); - SET_CONST(target, CKA_CHAR_COLUMNS); - SET_CONST(target, CKA_COLOR); - SET_CONST(target, CKA_BITS_PER_PIXEL); - SET_CONST(target, CKA_CHAR_SETS); - SET_CONST(target, CKA_ENCODING_METHODS); - SET_CONST(target, CKA_MIME_TYPES); - SET_CONST(target, CKA_MECHANISM_TYPE); - SET_CONST(target, CKA_REQUIRED_CMS_ATTRIBUTES); - SET_CONST(target, CKA_DEFAULT_CMS_ATTRIBUTES); - SET_CONST(target, CKA_SUPPORTED_CMS_ATTRIBUTES); - SET_CONST(target, CKA_ALLOWED_MECHANISMS); - SET_CONST(target, CKA_VENDOR_DEFINED); +/** + * @brief Sets a constant value in the exports object. + * + * This function sets a constant value with the specified name and value in the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + * @param name The name of the constant. + * @param value The value of the constant. + */ +void set_const(napi_env env, napi_value exports, const char *name, uint32_t value) +{ + napi_value constant; + napi_create_uint32(env, value, &constant); + napi_set_named_property(env, exports, name, constant); } -void declare_flags(Local target) { - Nan::HandleScope scope; +/** + * @brief Macro to simplify setting a constant value in the exports object. + * This macro expands to a call to the `set_const` function with the specified constant name. + * + * @param name The name of the constant. + */ +#define SET_CONST(name) set_const(env, exports, #name, name) - SET_CONST(target, CKF_RW_SESSION); - SET_CONST(target, CKF_SERIAL_SESSION); - SET_CONST(target, CKF_HW); - SET_CONST(target, CKF_ENCRYPT); - SET_CONST(target, CKF_DECRYPT); - SET_CONST(target, CKF_DIGEST); - SET_CONST(target, CKF_SIGN); - SET_CONST(target, CKF_SIGN_RECOVER); - SET_CONST(target, CKF_VERIFY); - SET_CONST(target, CKF_VERIFY_RECOVER); - SET_CONST(target, CKF_GENERATE); - SET_CONST(target, CKF_GENERATE_KEY_PAIR); - SET_CONST(target, CKF_WRAP); - SET_CONST(target, CKF_UNWRAP); - SET_CONST(target, CKF_DERIVE); - - // Token Information Flags - SET_CONST(target, CKF_RNG); - SET_CONST(target, CKF_WRITE_PROTECTED); - SET_CONST(target, CKF_LOGIN_REQUIRED); - SET_CONST(target, CKF_USER_PIN_INITIALIZED); - SET_CONST(target, CKF_RESTORE_KEY_NOT_NEEDED); - SET_CONST(target, CKF_CLOCK_ON_TOKEN); - SET_CONST(target, CKF_PROTECTED_AUTHENTICATION_PATH); - SET_CONST(target, CKF_DUAL_CRYPTO_OPERATIONS); - SET_CONST(target, CKF_TOKEN_INITIALIZED); - SET_CONST(target, CKF_SECONDARY_AUTHENTICATION); - SET_CONST(target, CKF_USER_PIN_COUNT_LOW); - SET_CONST(target, CKF_USER_PIN_FINAL_TRY); - SET_CONST(target, CKF_USER_PIN_LOCKED); - SET_CONST(target, CKF_USER_PIN_TO_BE_CHANGED); - SET_CONST(target, CKF_SO_PIN_COUNT_LOW); - SET_CONST(target, CKF_SO_PIN_FINAL_TRY); - SET_CONST(target, CKF_SO_PIN_LOCKED); - SET_CONST(target, CKF_SO_PIN_TO_BE_CHANGED); - SET_CONST(target, CKF_ERROR_STATE); +/** + * @brief Set CKR_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckr(napi_env env, napi_value exports) +{ + SET_CONST(CKR_OK); + SET_CONST(CKR_CANCEL); + SET_CONST(CKR_HOST_MEMORY); + SET_CONST(CKR_SLOT_ID_INVALID); + SET_CONST(CKR_GENERAL_ERROR); + SET_CONST(CKR_FUNCTION_FAILED); + SET_CONST(CKR_ARGUMENTS_BAD); + SET_CONST(CKR_NO_EVENT); + SET_CONST(CKR_NEED_TO_CREATE_THREADS); + SET_CONST(CKR_CANT_LOCK); + SET_CONST(CKR_ATTRIBUTE_READ_ONLY); + SET_CONST(CKR_ATTRIBUTE_SENSITIVE); + SET_CONST(CKR_ATTRIBUTE_TYPE_INVALID); + SET_CONST(CKR_ATTRIBUTE_VALUE_INVALID); + SET_CONST(CKR_DATA_INVALID); + SET_CONST(CKR_DATA_LEN_RANGE); + SET_CONST(CKR_DEVICE_ERROR); + SET_CONST(CKR_DEVICE_MEMORY); + SET_CONST(CKR_DEVICE_REMOVED); + SET_CONST(CKR_ENCRYPTED_DATA_INVALID); + SET_CONST(CKR_ENCRYPTED_DATA_LEN_RANGE); + SET_CONST(CKR_FUNCTION_CANCELED); + SET_CONST(CKR_FUNCTION_NOT_PARALLEL); + SET_CONST(CKR_FUNCTION_NOT_SUPPORTED); + SET_CONST(CKR_KEY_HANDLE_INVALID); + SET_CONST(CKR_KEY_SIZE_RANGE); + SET_CONST(CKR_KEY_TYPE_INCONSISTENT); + SET_CONST(CKR_KEY_NOT_NEEDED); + SET_CONST(CKR_KEY_CHANGED); + SET_CONST(CKR_KEY_NEEDED); + SET_CONST(CKR_KEY_INDIGESTIBLE); + SET_CONST(CKR_KEY_FUNCTION_NOT_PERMITTED); + SET_CONST(CKR_KEY_NOT_WRAPPABLE); + SET_CONST(CKR_KEY_UNEXTRACTABLE); + SET_CONST(CKR_MECHANISM_INVALID); + SET_CONST(CKR_MECHANISM_PARAM_INVALID); + SET_CONST(CKR_OBJECT_HANDLE_INVALID); + SET_CONST(CKR_OPERATION_ACTIVE); + SET_CONST(CKR_OPERATION_NOT_INITIALIZED); + SET_CONST(CKR_PIN_INCORRECT); + SET_CONST(CKR_PIN_INVALID); + SET_CONST(CKR_PIN_LEN_RANGE); + SET_CONST(CKR_PIN_EXPIRED); + SET_CONST(CKR_PIN_LOCKED); + SET_CONST(CKR_SESSION_CLOSED); + SET_CONST(CKR_SESSION_COUNT); + SET_CONST(CKR_SESSION_HANDLE_INVALID); + SET_CONST(CKR_SESSION_PARALLEL_NOT_SUPPORTED); + SET_CONST(CKR_SESSION_READ_ONLY); + SET_CONST(CKR_SESSION_EXISTS); + SET_CONST(CKR_SESSION_READ_ONLY_EXISTS); + SET_CONST(CKR_SESSION_READ_WRITE_SO_EXISTS); + SET_CONST(CKR_SIGNATURE_INVALID); + SET_CONST(CKR_SIGNATURE_LEN_RANGE); + SET_CONST(CKR_TEMPLATE_INCOMPLETE); + SET_CONST(CKR_TEMPLATE_INCONSISTENT); + SET_CONST(CKR_TOKEN_NOT_PRESENT); + SET_CONST(CKR_TOKEN_NOT_RECOGNIZED); + SET_CONST(CKR_TOKEN_WRITE_PROTECTED); + SET_CONST(CKR_UNWRAPPING_KEY_HANDLE_INVALID); + SET_CONST(CKR_UNWRAPPING_KEY_SIZE_RANGE); + SET_CONST(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT); + SET_CONST(CKR_USER_ALREADY_LOGGED_IN); + SET_CONST(CKR_USER_NOT_LOGGED_IN); + SET_CONST(CKR_USER_PIN_NOT_INITIALIZED); + SET_CONST(CKR_USER_TYPE_INVALID); + SET_CONST(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); + SET_CONST(CKR_USER_TOO_MANY_TYPES); + SET_CONST(CKR_WRAPPED_KEY_INVALID); + SET_CONST(CKR_WRAPPED_KEY_LEN_RANGE); + SET_CONST(CKR_WRAPPING_KEY_HANDLE_INVALID); + SET_CONST(CKR_WRAPPING_KEY_SIZE_RANGE); + SET_CONST(CKR_WRAPPING_KEY_TYPE_INCONSISTENT); + SET_CONST(CKR_RANDOM_SEED_NOT_SUPPORTED); + SET_CONST(CKR_RANDOM_NO_RNG); + SET_CONST(CKR_DOMAIN_PARAMS_INVALID); + SET_CONST(CKR_BUFFER_TOO_SMALL); + SET_CONST(CKR_SAVED_STATE_INVALID); + SET_CONST(CKR_INFORMATION_SENSITIVE); + SET_CONST(CKR_STATE_UNSAVEABLE); + SET_CONST(CKR_CRYPTOKI_NOT_INITIALIZED); + SET_CONST(CKR_CRYPTOKI_ALREADY_INITIALIZED); + SET_CONST(CKR_MUTEX_BAD); + SET_CONST(CKR_MUTEX_NOT_LOCKED); + SET_CONST(CKR_NEW_PIN_MODE); + SET_CONST(CKR_NEXT_OTP); + SET_CONST(CKR_EXCEEDED_MAX_ITERATIONS); + SET_CONST(CKR_FIPS_SELF_TEST_FAILED); + SET_CONST(CKR_LIBRARY_LOAD_FAILED); + SET_CONST(CKR_PIN_TOO_WEAK); + SET_CONST(CKR_PUBLIC_KEY_INVALID); + SET_CONST(CKR_FUNCTION_REJECTED); +} - // Event flags - SET_CONST(target, CKF_DONT_BLOCK); +/** + * @brief Set CKP_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckp(napi_env env, napi_value exports) +{ + SET_CONST(CK_PARAMS_BUFFER); + SET_CONST(CK_PARAMS_AES_CBC); + SET_CONST(CK_PARAMS_AES_CCM); + SET_CONST(CK_PARAMS_AES_GCM); + SET_CONST(CK_PARAMS_RSA_OAEP); + SET_CONST(CK_PARAMS_RSA_PSS); + SET_CONST(CK_PARAMS_EC_DH); + SET_CONST(CK_PARAMS_AES_GCM_v240); } -void declare_objects(Local target) { - Nan::HandleScope scope; +/** + * @brief Set CKF_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckf(napi_env env, napi_value exports) +{ + // Slot flags + SET_CONST(CKF_TOKEN_PRESENT); + SET_CONST(CKF_REMOVABLE_DEVICE); + SET_CONST(CKF_HW_SLOT); + + // Token flags + SET_CONST(CKF_RNG); + SET_CONST(CKF_WRITE_PROTECTED); + SET_CONST(CKF_LOGIN_REQUIRED); + SET_CONST(CKF_USER_PIN_INITIALIZED); + SET_CONST(CKF_RESTORE_KEY_NOT_NEEDED); + SET_CONST(CKF_CLOCK_ON_TOKEN); + SET_CONST(CKF_PROTECTED_AUTHENTICATION_PATH); + SET_CONST(CKF_DUAL_CRYPTO_OPERATIONS); + SET_CONST(CKF_TOKEN_INITIALIZED); + SET_CONST(CKF_SECONDARY_AUTHENTICATION); + SET_CONST(CKF_USER_PIN_COUNT_LOW); + SET_CONST(CKF_USER_PIN_FINAL_TRY); + SET_CONST(CKF_USER_PIN_LOCKED); + SET_CONST(CKF_USER_PIN_TO_BE_CHANGED); + SET_CONST(CKF_SO_PIN_COUNT_LOW); + SET_CONST(CKF_SO_PIN_FINAL_TRY); + SET_CONST(CKF_SO_PIN_LOCKED); + SET_CONST(CKF_SO_PIN_TO_BE_CHANGED); + SET_CONST(CKF_ERROR_STATE); + + // Session flags + SET_CONST(CKF_RW_SESSION); + SET_CONST(CKF_SERIAL_SESSION); + + // Attribute flags + SET_CONST(CKF_ARRAY_ATTRIBUTE); + + // Mechanism flags + SET_CONST(CKF_HW); + SET_CONST(CKF_ENCRYPT); + SET_CONST(CKF_DECRYPT); + SET_CONST(CKF_DIGEST); + SET_CONST(CKF_SIGN); + SET_CONST(CKF_SIGN_RECOVER); + SET_CONST(CKF_VERIFY); + SET_CONST(CKF_VERIFY_RECOVER); + SET_CONST(CKF_GENERATE); + SET_CONST(CKF_GENERATE_KEY_PAIR); + SET_CONST(CKF_WRAP); + SET_CONST(CKF_UNWRAP); + SET_CONST(CKF_DERIVE); + SET_CONST(CKF_EC_F_P); + SET_CONST(CKF_EC_F_2M); + SET_CONST(CKF_EC_ECPARAMETERS); + SET_CONST(CKF_EC_NAMEDCURVE); + SET_CONST(CKF_EC_UNCOMPRESS); + SET_CONST(CKF_EC_COMPRESS); + SET_CONST(CKF_EXTENSION); + + // Initialization flags + SET_CONST(CKF_LIBRARY_CANT_CREATE_OS_THREADS); + SET_CONST(CKF_OS_LOCKING_OK); + + // Wait flags + SET_CONST(CKF_DONT_BLOCK); - SET_CONST(target, CKO_DATA); - SET_CONST(target, CKO_CERTIFICATE); - SET_CONST(target, CKO_PUBLIC_KEY); - SET_CONST(target, CKO_PRIVATE_KEY); - SET_CONST(target, CKO_SECRET_KEY); - SET_CONST(target, CKO_HW_FEATURE); - SET_CONST(target, CKO_DOMAIN_PARAMETERS); - SET_CONST(target, CKO_MECHANISM); - SET_CONST(target, CKO_OTP_KEY); - SET_CONST(target, CKO_VENDOR_DEFINED); + // OTP flags + SET_CONST(CKF_NEXT_OTP); + SET_CONST(CKF_EXCLUDE_TIME); + SET_CONST(CKF_EXCLUDE_COUNTER); + SET_CONST(CKF_EXCLUDE_CHALLENGE); + SET_CONST(CKF_EXCLUDE_PIN); + SET_CONST(CKF_USER_FRIENDLY_OTP); } -void declare_ket_types(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKK_RSA); - SET_CONST(target, CKK_DSA); - SET_CONST(target, CKK_DH); - SET_CONST(target, CKK_ECDSA); - SET_CONST(target, CKK_EC); - SET_CONST(target, CKK_X9_42_DH); - SET_CONST(target, CKK_KEA); - SET_CONST(target, CKK_GENERIC_SECRET); - SET_CONST(target, CKK_RC2); - SET_CONST(target, CKK_RC4); - SET_CONST(target, CKK_DES); - SET_CONST(target, CKK_DES2); - SET_CONST(target, CKK_DES3); - SET_CONST(target, CKK_CAST); - SET_CONST(target, CKK_CAST3); - SET_CONST(target, CKK_CAST5); - SET_CONST(target, CKK_CAST128); - SET_CONST(target, CKK_RC5); - SET_CONST(target, CKK_IDEA); - SET_CONST(target, CKK_SKIPJACK); - SET_CONST(target, CKK_BATON); - SET_CONST(target, CKK_JUNIPER); - SET_CONST(target, CKK_CDMF); - SET_CONST(target, CKK_AES); - SET_CONST(target, CKK_BLOWFISH); - SET_CONST(target, CKK_TWOFISH); - SET_CONST(target, CKK_SECURID); - SET_CONST(target, CKK_HOTP); - SET_CONST(target, CKK_ACTI); - SET_CONST(target, CKK_CAMELLIA); - SET_CONST(target, CKK_ARIA); - SET_CONST(target, CKK_MD5_HMAC); - SET_CONST(target, CKK_SHA_1_HMAC); - SET_CONST(target, CKK_RIPEMD128_HMAC); - SET_CONST(target, CKK_RIPEMD160_HMAC); - SET_CONST(target, CKK_SHA256_HMAC); - SET_CONST(target, CKK_SHA384_HMAC); - SET_CONST(target, CKK_SHA512_HMAC); - SET_CONST(target, CKK_SHA224_HMAC); - SET_CONST(target, CKK_SEED); - SET_CONST(target, CKK_GOSTR3410); - SET_CONST(target, CKK_GOSTR3411); - SET_CONST(target, CKK_GOST28147); - SET_CONST(target, CKK_VENDOR_DEFINED); +/** + * @brief Set CKA_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_cka(napi_env env, napi_value exports) +{ + SET_CONST(CKA_CLASS); + SET_CONST(CKA_TOKEN); + SET_CONST(CKA_PRIVATE); + SET_CONST(CKA_LABEL); + SET_CONST(CKA_APPLICATION); + SET_CONST(CKA_VALUE); + SET_CONST(CKA_OBJECT_ID); + SET_CONST(CKA_CERTIFICATE_TYPE); + SET_CONST(CKA_ISSUER); + SET_CONST(CKA_SERIAL_NUMBER); + SET_CONST(CKA_AC_ISSUER); + SET_CONST(CKA_OWNER); + SET_CONST(CKA_ATTR_TYPES); + SET_CONST(CKA_TRUSTED); + SET_CONST(CKA_CERTIFICATE_CATEGORY); + SET_CONST(CKA_JAVA_MIDP_SECURITY_DOMAIN); + SET_CONST(CKA_URL); + SET_CONST(CKA_HASH_OF_SUBJECT_PUBLIC_KEY); + SET_CONST(CKA_HASH_OF_ISSUER_PUBLIC_KEY); + SET_CONST(CKA_NAME_HASH_ALGORITHM); + SET_CONST(CKA_CHECK_VALUE); + SET_CONST(CKA_KEY_TYPE); + SET_CONST(CKA_SUBJECT); + SET_CONST(CKA_ID); + SET_CONST(CKA_SENSITIVE); + SET_CONST(CKA_ENCRYPT); + SET_CONST(CKA_DECRYPT); + SET_CONST(CKA_WRAP); + SET_CONST(CKA_UNWRAP); + SET_CONST(CKA_SIGN); + SET_CONST(CKA_SIGN_RECOVER); + SET_CONST(CKA_VERIFY); + SET_CONST(CKA_VERIFY_RECOVER); + SET_CONST(CKA_DERIVE); + SET_CONST(CKA_START_DATE); + SET_CONST(CKA_END_DATE); + SET_CONST(CKA_MODULUS); + SET_CONST(CKA_MODULUS_BITS); + SET_CONST(CKA_PUBLIC_EXPONENT); + SET_CONST(CKA_PRIVATE_EXPONENT); + SET_CONST(CKA_PRIME_1); + SET_CONST(CKA_PRIME_2); + SET_CONST(CKA_EXPONENT_1); + SET_CONST(CKA_EXPONENT_2); + SET_CONST(CKA_COEFFICIENT); + SET_CONST(CKA_PRIME); + SET_CONST(CKA_SUBPRIME); + SET_CONST(CKA_BASE); + SET_CONST(CKA_PRIME_BITS); + SET_CONST(CKA_SUBPRIME_BITS); + SET_CONST(CKA_SUB_PRIME_BITS); + SET_CONST(CKA_VALUE_BITS); + SET_CONST(CKA_VALUE_LEN); + SET_CONST(CKA_EXTRACTABLE); + SET_CONST(CKA_LOCAL); + SET_CONST(CKA_NEVER_EXTRACTABLE); + SET_CONST(CKA_ALWAYS_SENSITIVE); + SET_CONST(CKA_KEY_GEN_MECHANISM); + SET_CONST(CKA_MODIFIABLE); + SET_CONST(CKA_COPYABLE); + SET_CONST(CKA_DESTROYABLE); + SET_CONST(CKA_ECDSA_PARAMS); + SET_CONST(CKA_EC_PARAMS); + SET_CONST(CKA_EC_POINT); + SET_CONST(CKA_SECONDARY_AUTH); + SET_CONST(CKA_AUTH_PIN_FLAGS); + SET_CONST(CKA_ALWAYS_AUTHENTICATE); + SET_CONST(CKA_WRAP_WITH_TRUSTED); + SET_CONST(CKA_WRAP_TEMPLATE); + SET_CONST(CKA_UNWRAP_TEMPLATE); + SET_CONST(CKA_DERIVE_TEMPLATE); + SET_CONST(CKA_OTP_FORMAT); + SET_CONST(CKA_OTP_LENGTH); + SET_CONST(CKA_OTP_TIME_INTERVAL); + SET_CONST(CKA_OTP_USER_FRIENDLY_MODE); + SET_CONST(CKA_OTP_CHALLENGE_REQUIREMENT); + SET_CONST(CKA_OTP_TIME_REQUIREMENT); + SET_CONST(CKA_OTP_COUNTER_REQUIREMENT); + SET_CONST(CKA_OTP_PIN_REQUIREMENT); + SET_CONST(CKA_OTP_COUNTER); + SET_CONST(CKA_OTP_TIME); + SET_CONST(CKA_OTP_USER_IDENTIFIER); + SET_CONST(CKA_OTP_SERVICE_IDENTIFIER); + SET_CONST(CKA_OTP_SERVICE_LOGO); + SET_CONST(CKA_OTP_SERVICE_LOGO_TYPE); + SET_CONST(CKA_GOSTR3410_PARAMS); + SET_CONST(CKA_GOSTR3411_PARAMS); + SET_CONST(CKA_GOST28147_PARAMS); + SET_CONST(CKA_HW_FEATURE_TYPE); + SET_CONST(CKA_RESET_ON_INIT); + SET_CONST(CKA_HAS_RESET); + SET_CONST(CKA_PIXEL_X); + SET_CONST(CKA_PIXEL_Y); + SET_CONST(CKA_RESOLUTION); + SET_CONST(CKA_CHAR_ROWS); + SET_CONST(CKA_CHAR_COLUMNS); + SET_CONST(CKA_COLOR); + SET_CONST(CKA_BITS_PER_PIXEL); + SET_CONST(CKA_CHAR_SETS); + SET_CONST(CKA_ENCODING_METHODS); + SET_CONST(CKA_MIME_TYPES); + SET_CONST(CKA_MECHANISM_TYPE); + SET_CONST(CKA_REQUIRED_CMS_ATTRIBUTES); + SET_CONST(CKA_DEFAULT_CMS_ATTRIBUTES); + SET_CONST(CKA_SUPPORTED_CMS_ATTRIBUTES); + SET_CONST(CKA_ALLOWED_MECHANISMS); + SET_CONST(CKA_VENDOR_DEFINED); } -void declare_mechanisms(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKM_RSA_PKCS_KEY_PAIR_GEN); - SET_CONST(target, CKM_RSA_PKCS); - SET_CONST(target, CKM_RSA_9796); - SET_CONST(target, CKM_RSA_X_509); - SET_CONST(target, CKM_MD2_RSA_PKCS); - SET_CONST(target, CKM_MD5_RSA_PKCS); - SET_CONST(target, CKM_SHA1_RSA_PKCS); - SET_CONST(target, CKM_RIPEMD128_RSA_PKCS); - SET_CONST(target, CKM_RIPEMD160_RSA_PKCS); - SET_CONST(target, CKM_RSA_PKCS_OAEP); - SET_CONST(target, CKM_RSA_X9_31_KEY_PAIR_GEN); - SET_CONST(target, CKM_RSA_X9_31); - SET_CONST(target, CKM_SHA1_RSA_X9_31); - SET_CONST(target, CKM_RSA_PKCS_PSS); - SET_CONST(target, CKM_SHA1_RSA_PKCS_PSS); - SET_CONST(target, CKM_DSA_KEY_PAIR_GEN); - SET_CONST(target, CKM_DSA); - SET_CONST(target, CKM_DSA_SHA1); - SET_CONST(target, CKM_DSA_SHA224); - SET_CONST(target, CKM_DSA_SHA256); - SET_CONST(target, CKM_DSA_SHA384); - SET_CONST(target, CKM_DSA_SHA512); - SET_CONST(target, CKM_DH_PKCS_KEY_PAIR_GEN); - SET_CONST(target, CKM_DH_PKCS_DERIVE); - SET_CONST(target, CKM_X9_42_DH_KEY_PAIR_GEN); - SET_CONST(target, CKM_X9_42_DH_DERIVE); - SET_CONST(target, CKM_X9_42_DH_HYBRID_DERIVE); - SET_CONST(target, CKM_X9_42_MQV_DERIVE); - SET_CONST(target, CKM_SHA256_RSA_PKCS); - SET_CONST(target, CKM_SHA384_RSA_PKCS); - SET_CONST(target, CKM_SHA512_RSA_PKCS); - SET_CONST(target, CKM_SHA256_RSA_PKCS_PSS); - SET_CONST(target, CKM_SHA384_RSA_PKCS_PSS); - SET_CONST(target, CKM_SHA512_RSA_PKCS_PSS); - SET_CONST(target, CKM_SHA224_RSA_PKCS); - SET_CONST(target, CKM_SHA224_RSA_PKCS_PSS); - SET_CONST(target, CKM_RC2_KEY_GEN); - SET_CONST(target, CKM_RC2_ECB); - SET_CONST(target, CKM_RC2_CBC); - SET_CONST(target, CKM_RC2_MAC); - SET_CONST(target, CKM_RC2_MAC_GENERAL); - SET_CONST(target, CKM_RC2_CBC_PAD); - SET_CONST(target, CKM_RC4_KEY_GEN); - SET_CONST(target, CKM_RC4); - SET_CONST(target, CKM_DES_KEY_GEN); - SET_CONST(target, CKM_DES_ECB); - SET_CONST(target, CKM_DES_CBC); - SET_CONST(target, CKM_DES_MAC); - SET_CONST(target, CKM_DES_MAC_GENERAL); - SET_CONST(target, CKM_DES_CBC_PAD); - SET_CONST(target, CKM_DES2_KEY_GEN); - SET_CONST(target, CKM_DES3_KEY_GEN); - SET_CONST(target, CKM_DES3_ECB); - SET_CONST(target, CKM_DES3_CBC); - SET_CONST(target, CKM_DES3_MAC); - SET_CONST(target, CKM_DES3_MAC_GENERAL); - SET_CONST(target, CKM_DES3_CBC_PAD); - SET_CONST(target, CKM_DES3_CMAC_GENERAL); - SET_CONST(target, CKM_DES3_CMAC); - SET_CONST(target, CKM_CDMF_KEY_GEN); - SET_CONST(target, CKM_CDMF_ECB); - SET_CONST(target, CKM_CDMF_CBC); - SET_CONST(target, CKM_CDMF_MAC); - SET_CONST(target, CKM_CDMF_MAC_GENERAL); - SET_CONST(target, CKM_CDMF_CBC_PAD); - SET_CONST(target, CKM_DES_OFB64); - SET_CONST(target, CKM_DES_OFB8); - SET_CONST(target, CKM_DES_CFB64); - SET_CONST(target, CKM_DES_CFB8); - SET_CONST(target, CKM_MD2); - SET_CONST(target, CKM_MD2_HMAC); - SET_CONST(target, CKM_MD2_HMAC_GENERAL); - SET_CONST(target, CKM_MD5); - SET_CONST(target, CKM_MD5_HMAC); - SET_CONST(target, CKM_MD5_HMAC_GENERAL); - SET_CONST(target, CKM_SHA_1); - SET_CONST(target, CKM_SHA_1_HMAC); - SET_CONST(target, CKM_SHA_1_HMAC_GENERAL); - SET_CONST(target, CKM_RIPEMD128); - SET_CONST(target, CKM_RIPEMD128_HMAC); - SET_CONST(target, CKM_RIPEMD128_HMAC_GENERAL); - SET_CONST(target, CKM_RIPEMD160); - SET_CONST(target, CKM_RIPEMD160_HMAC); - SET_CONST(target, CKM_RIPEMD160_HMAC_GENERAL); - SET_CONST(target, CKM_SHA256); - SET_CONST(target, CKM_SHA256_HMAC); - SET_CONST(target, CKM_SHA256_HMAC_GENERAL); - SET_CONST(target, CKM_SHA224); - SET_CONST(target, CKM_SHA224_HMAC); - SET_CONST(target, CKM_SHA224_HMAC_GENERAL); - SET_CONST(target, CKM_SHA384); - SET_CONST(target, CKM_SHA384_HMAC); - SET_CONST(target, CKM_SHA384_HMAC_GENERAL); - SET_CONST(target, CKM_SHA512); - SET_CONST(target, CKM_SHA512_HMAC); - SET_CONST(target, CKM_SHA512_HMAC_GENERAL); - SET_CONST(target, CKM_SECURID_KEY_GEN); - SET_CONST(target, CKM_SECURID); - SET_CONST(target, CKM_HOTP_KEY_GEN); - SET_CONST(target, CKM_HOTP); - SET_CONST(target, CKM_ACTI); - SET_CONST(target, CKM_ACTI_KEY_GEN); - SET_CONST(target, CKM_CAST_KEY_GEN); - SET_CONST(target, CKM_CAST_ECB); - SET_CONST(target, CKM_CAST_CBC); - SET_CONST(target, CKM_CAST_MAC); - SET_CONST(target, CKM_CAST_MAC_GENERAL); - SET_CONST(target, CKM_CAST_CBC_PAD); - SET_CONST(target, CKM_CAST3_KEY_GEN); - SET_CONST(target, CKM_CAST3_ECB); - SET_CONST(target, CKM_CAST3_CBC); - SET_CONST(target, CKM_CAST3_MAC); - SET_CONST(target, CKM_CAST3_MAC_GENERAL); - SET_CONST(target, CKM_CAST3_CBC_PAD); - SET_CONST(target, CKM_CAST5_KEY_GEN); - SET_CONST(target, CKM_CAST128_KEY_GEN); - SET_CONST(target, CKM_CAST5_ECB); - SET_CONST(target, CKM_CAST128_ECB); - SET_CONST(target, CKM_CAST5_CBC); - SET_CONST(target, CKM_CAST128_CBC); - SET_CONST(target, CKM_CAST5_MAC); - SET_CONST(target, CKM_CAST128_MAC); - SET_CONST(target, CKM_CAST5_MAC_GENERAL); - SET_CONST(target, CKM_CAST128_MAC_GENERAL); - SET_CONST(target, CKM_CAST5_CBC_PAD); - SET_CONST(target, CKM_CAST128_CBC_PAD); - SET_CONST(target, CKM_RC5_KEY_GEN); - SET_CONST(target, CKM_RC5_ECB); - SET_CONST(target, CKM_RC5_CBC); - SET_CONST(target, CKM_RC5_MAC); - SET_CONST(target, CKM_RC5_MAC_GENERAL); - SET_CONST(target, CKM_RC5_CBC_PAD); - SET_CONST(target, CKM_IDEA_KEY_GEN); - SET_CONST(target, CKM_IDEA_ECB); - SET_CONST(target, CKM_IDEA_CBC); - SET_CONST(target, CKM_IDEA_MAC); - SET_CONST(target, CKM_IDEA_MAC_GENERAL); - SET_CONST(target, CKM_IDEA_CBC_PAD); - SET_CONST(target, CKM_GENERIC_SECRET_KEY_GEN); - SET_CONST(target, CKM_CONCATENATE_BASE_AND_KEY); - SET_CONST(target, CKM_CONCATENATE_BASE_AND_DATA); - SET_CONST(target, CKM_CONCATENATE_DATA_AND_BASE); - SET_CONST(target, CKM_XOR_BASE_AND_DATA); - SET_CONST(target, CKM_EXTRACT_KEY_FROM_KEY); - SET_CONST(target, CKM_SSL3_PRE_MASTER_KEY_GEN); - SET_CONST(target, CKM_SSL3_MASTER_KEY_DERIVE); - SET_CONST(target, CKM_SSL3_KEY_AND_MAC_DERIVE); - SET_CONST(target, CKM_SSL3_MASTER_KEY_DERIVE_DH); - SET_CONST(target, CKM_TLS_PRE_MASTER_KEY_GEN); - SET_CONST(target, CKM_TLS_MASTER_KEY_DERIVE); - SET_CONST(target, CKM_TLS_KEY_AND_MAC_DERIVE); - SET_CONST(target, CKM_TLS_MASTER_KEY_DERIVE_DH); - SET_CONST(target, CKM_TLS_PRF); - SET_CONST(target, CKM_SSL3_MD5_MAC); - SET_CONST(target, CKM_SSL3_SHA1_MAC); - SET_CONST(target, CKM_MD5_KEY_DERIVATION); - SET_CONST(target, CKM_MD2_KEY_DERIVATION); - SET_CONST(target, CKM_SHA1_KEY_DERIVATION); - SET_CONST(target, CKM_SHA256_KEY_DERIVATION); - SET_CONST(target, CKM_SHA384_KEY_DERIVATION); - SET_CONST(target, CKM_SHA512_KEY_DERIVATION); - SET_CONST(target, CKM_SHA224_KEY_DERIVATION); - SET_CONST(target, CKM_PBE_MD2_DES_CBC); - SET_CONST(target, CKM_PBE_MD5_DES_CBC); - SET_CONST(target, CKM_PBE_MD5_CAST_CBC); - SET_CONST(target, CKM_PBE_MD5_CAST3_CBC); - SET_CONST(target, CKM_PBE_MD5_CAST5_CBC); - SET_CONST(target, CKM_PBE_MD5_CAST128_CBC); - SET_CONST(target, CKM_PBE_SHA1_CAST5_CBC); - SET_CONST(target, CKM_PBE_SHA1_CAST128_CBC); - SET_CONST(target, CKM_PBE_SHA1_RC4_128); - SET_CONST(target, CKM_PBE_SHA1_RC4_40); - SET_CONST(target, CKM_PBE_SHA1_DES3_EDE_CBC); - SET_CONST(target, CKM_PBE_SHA1_DES2_EDE_CBC); - SET_CONST(target, CKM_PBE_SHA1_RC2_128_CBC); - SET_CONST(target, CKM_PBE_SHA1_RC2_40_CBC); - SET_CONST(target, CKM_PKCS5_PBKD2); - SET_CONST(target, CKM_PBA_SHA1_WITH_SHA1_HMAC); - SET_CONST(target, CKM_WTLS_PRE_MASTER_KEY_GEN); - SET_CONST(target, CKM_WTLS_MASTER_KEY_DERIVE); - SET_CONST(target, CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC); - SET_CONST(target, CKM_WTLS_PRF); - SET_CONST(target, CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE); - SET_CONST(target, CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE); - SET_CONST(target, CKM_KEY_WRAP_LYNKS); - SET_CONST(target, CKM_KEY_WRAP_SET_OAEP); - SET_CONST(target, CKM_CAMELLIA_KEY_GEN); - SET_CONST(target, CKM_CAMELLIA_ECB); - SET_CONST(target, CKM_CAMELLIA_CBC); - SET_CONST(target, CKM_CAMELLIA_MAC); - SET_CONST(target, CKM_CAMELLIA_MAC_GENERAL); - SET_CONST(target, CKM_CAMELLIA_CBC_PAD); - SET_CONST(target, CKM_CAMELLIA_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_CAMELLIA_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_CAMELLIA_CTR); - SET_CONST(target, CKM_ARIA_KEY_GEN); - SET_CONST(target, CKM_ARIA_ECB); - SET_CONST(target, CKM_ARIA_CBC); - SET_CONST(target, CKM_ARIA_MAC); - SET_CONST(target, CKM_ARIA_MAC_GENERAL); - SET_CONST(target, CKM_ARIA_CBC_PAD); - SET_CONST(target, CKM_ARIA_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_ARIA_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_SEED_KEY_GEN); - SET_CONST(target, CKM_SEED_ECB); - SET_CONST(target, CKM_SEED_CBC); - SET_CONST(target, CKM_SEED_MAC); - SET_CONST(target, CKM_SEED_MAC_GENERAL); - SET_CONST(target, CKM_SEED_CBC_PAD); - SET_CONST(target, CKM_SEED_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_SEED_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_SKIPJACK_KEY_GEN); - SET_CONST(target, CKM_SKIPJACK_ECB64); - SET_CONST(target, CKM_SKIPJACK_CBC64); - SET_CONST(target, CKM_SKIPJACK_OFB64); - SET_CONST(target, CKM_SKIPJACK_CFB64); - SET_CONST(target, CKM_SKIPJACK_CFB32); - SET_CONST(target, CKM_SKIPJACK_CFB16); - SET_CONST(target, CKM_SKIPJACK_CFB8); - SET_CONST(target, CKM_SKIPJACK_WRAP); - SET_CONST(target, CKM_SKIPJACK_PRIVATE_WRAP); - SET_CONST(target, CKM_SKIPJACK_RELAYX); - SET_CONST(target, CKM_KEA_KEY_PAIR_GEN); - SET_CONST(target, CKM_KEA_KEY_DERIVE); - SET_CONST(target, CKM_FORTEZZA_TIMESTAMP); - SET_CONST(target, CKM_BATON_KEY_GEN); - SET_CONST(target, CKM_BATON_ECB128); - SET_CONST(target, CKM_BATON_ECB96); - SET_CONST(target, CKM_BATON_CBC128); - SET_CONST(target, CKM_BATON_COUNTER); - SET_CONST(target, CKM_BATON_SHUFFLE); - SET_CONST(target, CKM_BATON_WRAP); - SET_CONST(target, CKM_ECDSA_KEY_PAIR_GEN); - SET_CONST(target, CKM_EC_KEY_PAIR_GEN); - SET_CONST(target, CKM_ECDSA); - SET_CONST(target, CKM_ECDSA_SHA1); - SET_CONST(target, CKM_ECDSA_SHA224); - SET_CONST(target, CKM_ECDSA_SHA256); - SET_CONST(target, CKM_ECDSA_SHA384); - SET_CONST(target, CKM_ECDSA_SHA512); - SET_CONST(target, CKM_ECDH1_DERIVE); - SET_CONST(target, CKM_ECDH1_COFACTOR_DERIVE); - SET_CONST(target, CKM_ECMQV_DERIVE); - SET_CONST(target, CKM_JUNIPER_KEY_GEN); - SET_CONST(target, CKM_JUNIPER_ECB128); - SET_CONST(target, CKM_JUNIPER_CBC128); - SET_CONST(target, CKM_JUNIPER_COUNTER); - SET_CONST(target, CKM_JUNIPER_SHUFFLE); - SET_CONST(target, CKM_JUNIPER_WRAP); - SET_CONST(target, CKM_FASTHASH); - SET_CONST(target, CKM_AES_KEY_GEN); - SET_CONST(target, CKM_AES_ECB); - SET_CONST(target, CKM_AES_CBC); - SET_CONST(target, CKM_AES_MAC); - SET_CONST(target, CKM_AES_MAC_GENERAL); - SET_CONST(target, CKM_AES_CBC_PAD); - SET_CONST(target, CKM_AES_CTR); - SET_CONST(target, CKM_AES_CTS); - SET_CONST(target, CKM_AES_CMAC); - SET_CONST(target, CKM_AES_CMAC_GENERAL); - SET_CONST(target, CKM_BLOWFISH_KEY_GEN); - SET_CONST(target, CKM_BLOWFISH_CBC); - SET_CONST(target, CKM_TWOFISH_KEY_GEN); - SET_CONST(target, CKM_TWOFISH_CBC); - SET_CONST(target, CKM_AES_GCM); - SET_CONST(target, CKM_AES_CCM); - SET_CONST(target, CKM_AES_KEY_WRAP); - SET_CONST(target, CKM_AES_KEY_WRAP_PAD); - SET_CONST(target, CKM_BLOWFISH_CBC_PAD); - SET_CONST(target, CKM_TWOFISH_CBC_PAD); - SET_CONST(target, CKM_DES_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_DES_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_DES3_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_DES3_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_AES_ECB_ENCRYPT_DATA); - SET_CONST(target, CKM_AES_CBC_ENCRYPT_DATA); - SET_CONST(target, CKM_GOSTR3410_KEY_PAIR_GEN); - SET_CONST(target, CKM_GOSTR3410); - SET_CONST(target, CKM_GOSTR3410_WITH_GOSTR3411); - SET_CONST(target, CKM_GOSTR3410_KEY_WRAP); - SET_CONST(target, CKM_GOSTR3410_DERIVE); - SET_CONST(target, CKM_GOSTR3411); - SET_CONST(target, CKM_GOSTR3411_HMAC); - SET_CONST(target, CKM_GOST28147_KEY_GEN); - SET_CONST(target, CKM_GOST28147_ECB); - SET_CONST(target, CKM_GOST28147); - SET_CONST(target, CKM_GOST28147_MAC); - SET_CONST(target, CKM_GOST28147_KEY_WRAP); - SET_CONST(target, CKM_DSA_PARAMETER_GEN); - SET_CONST(target, CKM_DH_PKCS_PARAMETER_GEN); - SET_CONST(target, CKM_X9_42_DH_PARAMETER_GEN); - SET_CONST(target, CKM_AES_OFB); - SET_CONST(target, CKM_AES_CFB64); - SET_CONST(target, CKM_AES_CFB8); - SET_CONST(target, CKM_AES_CFB128); - SET_CONST(target, CKM_RSA_PKCS_TPM_1_1); - SET_CONST(target, CKM_RSA_PKCS_OAEP_TPM_1_1); - SET_CONST(target, CKM_VENDOR_DEFINED); +/** + * @brief Set CKO_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_cko(napi_env env, napi_value exports) +{ + SET_CONST(CKO_DATA); + SET_CONST(CKO_CERTIFICATE); + SET_CONST(CKO_PUBLIC_KEY); + SET_CONST(CKO_PRIVATE_KEY); + SET_CONST(CKO_SECRET_KEY); + SET_CONST(CKO_HW_FEATURE); + SET_CONST(CKO_DOMAIN_PARAMETERS); + SET_CONST(CKO_MECHANISM); + SET_CONST(CKO_OTP_KEY); + SET_CONST(CKO_VENDOR_DEFINED); } -void declare_certificates(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKC_WTLS); - SET_CONST(target, CKC_X_509); - SET_CONST(target, CKC_X_509_ATTR_CERT); +/** + * @brief Set CKM_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckm(napi_env env, napi_value exports) +{ + SET_CONST(CKM_RSA_PKCS_KEY_PAIR_GEN); + SET_CONST(CKM_RSA_PKCS); + SET_CONST(CKM_RSA_9796); + SET_CONST(CKM_RSA_X_509); + SET_CONST(CKM_MD2_RSA_PKCS); + SET_CONST(CKM_MD5_RSA_PKCS); + SET_CONST(CKM_SHA1_RSA_PKCS); + SET_CONST(CKM_RIPEMD128_RSA_PKCS); + SET_CONST(CKM_RIPEMD160_RSA_PKCS); + SET_CONST(CKM_RSA_PKCS_OAEP); + SET_CONST(CKM_RSA_X9_31_KEY_PAIR_GEN); + SET_CONST(CKM_RSA_X9_31); + SET_CONST(CKM_SHA1_RSA_X9_31); + SET_CONST(CKM_RSA_PKCS_PSS); + SET_CONST(CKM_SHA1_RSA_PKCS_PSS); + SET_CONST(CKM_DSA_KEY_PAIR_GEN); + SET_CONST(CKM_DSA); + SET_CONST(CKM_DSA_SHA1); + SET_CONST(CKM_DSA_SHA224); + SET_CONST(CKM_DSA_SHA256); + SET_CONST(CKM_DSA_SHA384); + SET_CONST(CKM_DSA_SHA512); + SET_CONST(CKM_DH_PKCS_KEY_PAIR_GEN); + SET_CONST(CKM_DH_PKCS_DERIVE); + SET_CONST(CKM_X9_42_DH_KEY_PAIR_GEN); + SET_CONST(CKM_X9_42_DH_DERIVE); + SET_CONST(CKM_X9_42_DH_HYBRID_DERIVE); + SET_CONST(CKM_X9_42_MQV_DERIVE); + SET_CONST(CKM_SHA256_RSA_PKCS); + SET_CONST(CKM_SHA384_RSA_PKCS); + SET_CONST(CKM_SHA512_RSA_PKCS); + SET_CONST(CKM_SHA256_RSA_PKCS_PSS); + SET_CONST(CKM_SHA384_RSA_PKCS_PSS); + SET_CONST(CKM_SHA512_RSA_PKCS_PSS); + SET_CONST(CKM_SHA224_RSA_PKCS); + SET_CONST(CKM_SHA224_RSA_PKCS_PSS); + SET_CONST(CKM_RC2_KEY_GEN); + SET_CONST(CKM_RC2_ECB); + SET_CONST(CKM_RC2_CBC); + SET_CONST(CKM_RC2_MAC); + SET_CONST(CKM_RC2_MAC_GENERAL); + SET_CONST(CKM_RC2_CBC_PAD); + SET_CONST(CKM_RC4_KEY_GEN); + SET_CONST(CKM_RC4); + SET_CONST(CKM_DES_KEY_GEN); + SET_CONST(CKM_DES_ECB); + SET_CONST(CKM_DES_CBC); + SET_CONST(CKM_DES_MAC); + SET_CONST(CKM_DES_MAC_GENERAL); + SET_CONST(CKM_DES_CBC_PAD); + SET_CONST(CKM_DES2_KEY_GEN); + SET_CONST(CKM_DES3_KEY_GEN); + SET_CONST(CKM_DES3_ECB); + SET_CONST(CKM_DES3_CBC); + SET_CONST(CKM_DES3_MAC); + SET_CONST(CKM_DES3_MAC_GENERAL); + SET_CONST(CKM_DES3_CBC_PAD); + SET_CONST(CKM_DES3_CMAC_GENERAL); + SET_CONST(CKM_DES3_CMAC); + SET_CONST(CKM_CDMF_KEY_GEN); + SET_CONST(CKM_CDMF_ECB); + SET_CONST(CKM_CDMF_CBC); + SET_CONST(CKM_CDMF_MAC); + SET_CONST(CKM_CDMF_MAC_GENERAL); + SET_CONST(CKM_CDMF_CBC_PAD); + SET_CONST(CKM_DES_OFB64); + SET_CONST(CKM_DES_OFB8); + SET_CONST(CKM_DES_CFB64); + SET_CONST(CKM_DES_CFB8); + SET_CONST(CKM_MD2); + SET_CONST(CKM_MD2_HMAC); + SET_CONST(CKM_MD2_HMAC_GENERAL); + SET_CONST(CKM_MD5); + SET_CONST(CKM_MD5_HMAC); + SET_CONST(CKM_MD5_HMAC_GENERAL); + SET_CONST(CKM_SHA_1); + SET_CONST(CKM_SHA_1_HMAC); + SET_CONST(CKM_SHA_1_HMAC_GENERAL); + SET_CONST(CKM_RIPEMD128); + SET_CONST(CKM_RIPEMD128_HMAC); + SET_CONST(CKM_RIPEMD128_HMAC_GENERAL); + SET_CONST(CKM_RIPEMD160); + SET_CONST(CKM_RIPEMD160_HMAC); + SET_CONST(CKM_RIPEMD160_HMAC_GENERAL); + SET_CONST(CKM_SHA256); + SET_CONST(CKM_SHA256_HMAC); + SET_CONST(CKM_SHA256_HMAC_GENERAL); + SET_CONST(CKM_SHA224); + SET_CONST(CKM_SHA224_HMAC); + SET_CONST(CKM_SHA224_HMAC_GENERAL); + SET_CONST(CKM_SHA384); + SET_CONST(CKM_SHA384_HMAC); + SET_CONST(CKM_SHA384_HMAC_GENERAL); + SET_CONST(CKM_SHA512); + SET_CONST(CKM_SHA512_HMAC); + SET_CONST(CKM_SHA512_HMAC_GENERAL); + SET_CONST(CKM_SECURID_KEY_GEN); + SET_CONST(CKM_SECURID); + SET_CONST(CKM_HOTP_KEY_GEN); + SET_CONST(CKM_HOTP); + SET_CONST(CKM_ACTI); + SET_CONST(CKM_ACTI_KEY_GEN); + SET_CONST(CKM_CAST_KEY_GEN); + SET_CONST(CKM_CAST_ECB); + SET_CONST(CKM_CAST_CBC); + SET_CONST(CKM_CAST_MAC); + SET_CONST(CKM_CAST_MAC_GENERAL); + SET_CONST(CKM_CAST_CBC_PAD); + SET_CONST(CKM_CAST3_KEY_GEN); + SET_CONST(CKM_CAST3_ECB); + SET_CONST(CKM_CAST3_CBC); + SET_CONST(CKM_CAST3_MAC); + SET_CONST(CKM_CAST3_MAC_GENERAL); + SET_CONST(CKM_CAST3_CBC_PAD); + SET_CONST(CKM_CAST5_KEY_GEN); + SET_CONST(CKM_CAST128_KEY_GEN); + SET_CONST(CKM_CAST5_ECB); + SET_CONST(CKM_CAST128_ECB); + SET_CONST(CKM_CAST5_CBC); + SET_CONST(CKM_CAST128_CBC); + SET_CONST(CKM_CAST5_MAC); + SET_CONST(CKM_CAST128_MAC); + SET_CONST(CKM_CAST5_MAC_GENERAL); + SET_CONST(CKM_CAST128_MAC_GENERAL); + SET_CONST(CKM_CAST5_CBC_PAD); + SET_CONST(CKM_CAST128_CBC_PAD); + SET_CONST(CKM_RC5_KEY_GEN); + SET_CONST(CKM_RC5_ECB); + SET_CONST(CKM_RC5_CBC); + SET_CONST(CKM_RC5_MAC); + SET_CONST(CKM_RC5_MAC_GENERAL); + SET_CONST(CKM_RC5_CBC_PAD); + SET_CONST(CKM_IDEA_KEY_GEN); + SET_CONST(CKM_IDEA_ECB); + SET_CONST(CKM_IDEA_CBC); + SET_CONST(CKM_IDEA_MAC); + SET_CONST(CKM_IDEA_MAC_GENERAL); + SET_CONST(CKM_IDEA_CBC_PAD); + SET_CONST(CKM_GENERIC_SECRET_KEY_GEN); + SET_CONST(CKM_CONCATENATE_BASE_AND_KEY); + SET_CONST(CKM_CONCATENATE_BASE_AND_DATA); + SET_CONST(CKM_CONCATENATE_DATA_AND_BASE); + SET_CONST(CKM_XOR_BASE_AND_DATA); + SET_CONST(CKM_EXTRACT_KEY_FROM_KEY); + SET_CONST(CKM_SSL3_PRE_MASTER_KEY_GEN); + SET_CONST(CKM_SSL3_MASTER_KEY_DERIVE); + SET_CONST(CKM_SSL3_KEY_AND_MAC_DERIVE); + SET_CONST(CKM_SSL3_MASTER_KEY_DERIVE_DH); + SET_CONST(CKM_TLS_PRE_MASTER_KEY_GEN); + SET_CONST(CKM_TLS_MASTER_KEY_DERIVE); + SET_CONST(CKM_TLS_KEY_AND_MAC_DERIVE); + SET_CONST(CKM_TLS_MASTER_KEY_DERIVE_DH); + SET_CONST(CKM_TLS_PRF); + SET_CONST(CKM_SSL3_MD5_MAC); + SET_CONST(CKM_SSL3_SHA1_MAC); + SET_CONST(CKM_MD5_KEY_DERIVATION); + SET_CONST(CKM_MD2_KEY_DERIVATION); + SET_CONST(CKM_SHA1_KEY_DERIVATION); + SET_CONST(CKM_SHA256_KEY_DERIVATION); + SET_CONST(CKM_SHA384_KEY_DERIVATION); + SET_CONST(CKM_SHA512_KEY_DERIVATION); + SET_CONST(CKM_SHA224_KEY_DERIVATION); + SET_CONST(CKM_PBE_MD2_DES_CBC); + SET_CONST(CKM_PBE_MD5_DES_CBC); + SET_CONST(CKM_PBE_MD5_CAST_CBC); + SET_CONST(CKM_PBE_MD5_CAST3_CBC); + SET_CONST(CKM_PBE_MD5_CAST5_CBC); + SET_CONST(CKM_PBE_MD5_CAST128_CBC); + SET_CONST(CKM_PBE_SHA1_CAST5_CBC); + SET_CONST(CKM_PBE_SHA1_CAST128_CBC); + SET_CONST(CKM_PBE_SHA1_RC4_128); + SET_CONST(CKM_PBE_SHA1_RC4_40); + SET_CONST(CKM_PBE_SHA1_DES3_EDE_CBC); + SET_CONST(CKM_PBE_SHA1_DES2_EDE_CBC); + SET_CONST(CKM_PBE_SHA1_RC2_128_CBC); + SET_CONST(CKM_PBE_SHA1_RC2_40_CBC); + SET_CONST(CKM_PKCS5_PBKD2); + SET_CONST(CKM_PBA_SHA1_WITH_SHA1_HMAC); + SET_CONST(CKM_WTLS_PRE_MASTER_KEY_GEN); + SET_CONST(CKM_WTLS_MASTER_KEY_DERIVE); + SET_CONST(CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC); + SET_CONST(CKM_WTLS_PRF); + SET_CONST(CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE); + SET_CONST(CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE); + SET_CONST(CKM_KEY_WRAP_LYNKS); + SET_CONST(CKM_KEY_WRAP_SET_OAEP); + SET_CONST(CKM_CAMELLIA_KEY_GEN); + SET_CONST(CKM_CAMELLIA_ECB); + SET_CONST(CKM_CAMELLIA_CBC); + SET_CONST(CKM_CAMELLIA_MAC); + SET_CONST(CKM_CAMELLIA_MAC_GENERAL); + SET_CONST(CKM_CAMELLIA_CBC_PAD); + SET_CONST(CKM_CAMELLIA_ECB_ENCRYPT_DATA); + SET_CONST(CKM_CAMELLIA_CBC_ENCRYPT_DATA); + SET_CONST(CKM_CAMELLIA_CTR); + SET_CONST(CKM_ARIA_KEY_GEN); + SET_CONST(CKM_ARIA_ECB); + SET_CONST(CKM_ARIA_CBC); + SET_CONST(CKM_ARIA_MAC); + SET_CONST(CKM_ARIA_MAC_GENERAL); + SET_CONST(CKM_ARIA_CBC_PAD); + SET_CONST(CKM_ARIA_ECB_ENCRYPT_DATA); + SET_CONST(CKM_ARIA_CBC_ENCRYPT_DATA); + SET_CONST(CKM_SEED_KEY_GEN); + SET_CONST(CKM_SEED_ECB); + SET_CONST(CKM_SEED_CBC); + SET_CONST(CKM_SEED_MAC); + SET_CONST(CKM_SEED_MAC_GENERAL); + SET_CONST(CKM_SEED_CBC_PAD); + SET_CONST(CKM_SEED_ECB_ENCRYPT_DATA); + SET_CONST(CKM_SEED_CBC_ENCRYPT_DATA); + SET_CONST(CKM_SKIPJACK_KEY_GEN); + SET_CONST(CKM_SKIPJACK_ECB64); + SET_CONST(CKM_SKIPJACK_CBC64); + SET_CONST(CKM_SKIPJACK_OFB64); + SET_CONST(CKM_SKIPJACK_CFB64); + SET_CONST(CKM_SKIPJACK_CFB32); + SET_CONST(CKM_SKIPJACK_CFB16); + SET_CONST(CKM_SKIPJACK_CFB8); + SET_CONST(CKM_SKIPJACK_WRAP); + SET_CONST(CKM_SKIPJACK_PRIVATE_WRAP); + SET_CONST(CKM_SKIPJACK_RELAYX); + SET_CONST(CKM_KEA_KEY_PAIR_GEN); + SET_CONST(CKM_KEA_KEY_DERIVE); + SET_CONST(CKM_FORTEZZA_TIMESTAMP); + SET_CONST(CKM_BATON_KEY_GEN); + SET_CONST(CKM_BATON_ECB128); + SET_CONST(CKM_BATON_ECB96); + SET_CONST(CKM_BATON_CBC128); + SET_CONST(CKM_BATON_COUNTER); + SET_CONST(CKM_BATON_SHUFFLE); + SET_CONST(CKM_BATON_WRAP); + SET_CONST(CKM_ECDSA_KEY_PAIR_GEN); + SET_CONST(CKM_EC_KEY_PAIR_GEN); + SET_CONST(CKM_ECDSA); + SET_CONST(CKM_ECDSA_SHA1); + SET_CONST(CKM_ECDSA_SHA224); + SET_CONST(CKM_ECDSA_SHA256); + SET_CONST(CKM_ECDSA_SHA384); + SET_CONST(CKM_ECDSA_SHA512); + SET_CONST(CKM_ECDH1_DERIVE); + SET_CONST(CKM_ECDH1_COFACTOR_DERIVE); + SET_CONST(CKM_ECMQV_DERIVE); + SET_CONST(CKM_JUNIPER_KEY_GEN); + SET_CONST(CKM_JUNIPER_ECB128); + SET_CONST(CKM_JUNIPER_CBC128); + SET_CONST(CKM_JUNIPER_COUNTER); + SET_CONST(CKM_JUNIPER_SHUFFLE); + SET_CONST(CKM_JUNIPER_WRAP); + SET_CONST(CKM_FASTHASH); + SET_CONST(CKM_AES_KEY_GEN); + SET_CONST(CKM_AES_ECB); + SET_CONST(CKM_AES_CBC); + SET_CONST(CKM_AES_MAC); + SET_CONST(CKM_AES_MAC_GENERAL); + SET_CONST(CKM_AES_CBC_PAD); + SET_CONST(CKM_AES_CTR); + SET_CONST(CKM_AES_CTS); + SET_CONST(CKM_AES_CMAC); + SET_CONST(CKM_AES_CMAC_GENERAL); + SET_CONST(CKM_BLOWFISH_KEY_GEN); + SET_CONST(CKM_BLOWFISH_CBC); + SET_CONST(CKM_TWOFISH_KEY_GEN); + SET_CONST(CKM_TWOFISH_CBC); + SET_CONST(CKM_AES_GCM); + SET_CONST(CKM_AES_CCM); + SET_CONST(CKM_AES_KEY_WRAP); + SET_CONST(CKM_AES_KEY_WRAP_PAD); + SET_CONST(CKM_BLOWFISH_CBC_PAD); + SET_CONST(CKM_TWOFISH_CBC_PAD); + SET_CONST(CKM_DES_ECB_ENCRYPT_DATA); + SET_CONST(CKM_DES_CBC_ENCRYPT_DATA); + SET_CONST(CKM_DES3_ECB_ENCRYPT_DATA); + SET_CONST(CKM_DES3_CBC_ENCRYPT_DATA); + SET_CONST(CKM_AES_ECB_ENCRYPT_DATA); + SET_CONST(CKM_AES_CBC_ENCRYPT_DATA); + SET_CONST(CKM_GOSTR3410_KEY_PAIR_GEN); + SET_CONST(CKM_GOSTR3410); + SET_CONST(CKM_GOSTR3410_WITH_GOSTR3411); + SET_CONST(CKM_GOSTR3410_KEY_WRAP); + SET_CONST(CKM_GOSTR3410_DERIVE); + SET_CONST(CKM_GOSTR3411); + SET_CONST(CKM_GOSTR3411_HMAC); + SET_CONST(CKM_GOST28147_KEY_GEN); + SET_CONST(CKM_GOST28147_ECB); + SET_CONST(CKM_GOST28147); + SET_CONST(CKM_GOST28147_MAC); + SET_CONST(CKM_GOST28147_KEY_WRAP); + SET_CONST(CKM_DSA_PARAMETER_GEN); + SET_CONST(CKM_DH_PKCS_PARAMETER_GEN); + SET_CONST(CKM_X9_42_DH_PARAMETER_GEN); + SET_CONST(CKM_AES_OFB); + SET_CONST(CKM_AES_CFB64); + SET_CONST(CKM_AES_CFB8); + SET_CONST(CKM_AES_CFB128); + SET_CONST(CKM_RSA_PKCS_TPM_1_1); + SET_CONST(CKM_RSA_PKCS_OAEP_TPM_1_1); + SET_CONST(CKM_VENDOR_DEFINED); } -void declare_mgf(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKG_MGF1_SHA1); - SET_CONST(target, CKG_MGF1_SHA256); - SET_CONST(target, CKG_MGF1_SHA384); - SET_CONST(target, CKG_MGF1_SHA512); - SET_CONST(target, CKG_MGF1_SHA224); +/** + * @brief Set CKG_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckg(napi_env env, napi_value exports) +{ + SET_CONST(CKG_MGF1_SHA1); + SET_CONST(CKG_MGF1_SHA256); + SET_CONST(CKG_MGF1_SHA384); + SET_CONST(CKG_MGF1_SHA512); + SET_CONST(CKG_MGF1_SHA224); } -void declare_kdf(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKD_NULL); - SET_CONST(target, CKD_SHA1_KDF); - SET_CONST(target, CKD_SHA1_KDF_ASN1); - SET_CONST(target, CKD_SHA1_KDF_CONCATENATE); - SET_CONST(target, CKD_SHA224_KDF); - SET_CONST(target, CKD_SHA256_KDF); - SET_CONST(target, CKD_SHA384_KDF); - SET_CONST(target, CKD_SHA512_KDF); - SET_CONST(target, CKD_CPDIVERSIFY_KDF); +/** + * @brief Set CKK_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckk(napi_env env, napi_value exports) +{ + SET_CONST(CKK_RSA); + SET_CONST(CKK_DSA); + SET_CONST(CKK_DH); + SET_CONST(CKK_ECDSA); + SET_CONST(CKK_EC); + SET_CONST(CKK_X9_42_DH); + SET_CONST(CKK_KEA); + SET_CONST(CKK_GENERIC_SECRET); + SET_CONST(CKK_RC2); + SET_CONST(CKK_RC4); + SET_CONST(CKK_DES); + SET_CONST(CKK_DES2); + SET_CONST(CKK_DES3); + SET_CONST(CKK_CAST); + SET_CONST(CKK_CAST3); + SET_CONST(CKK_CAST5); + SET_CONST(CKK_CAST128); + SET_CONST(CKK_RC5); + SET_CONST(CKK_IDEA); + SET_CONST(CKK_SKIPJACK); + SET_CONST(CKK_BATON); + SET_CONST(CKK_JUNIPER); + SET_CONST(CKK_CDMF); + SET_CONST(CKK_AES); + SET_CONST(CKK_BLOWFISH); + SET_CONST(CKK_TWOFISH); + SET_CONST(CKK_SECURID); + SET_CONST(CKK_HOTP); + SET_CONST(CKK_ACTI); + SET_CONST(CKK_CAMELLIA); + SET_CONST(CKK_ARIA); + SET_CONST(CKK_MD5_HMAC); + SET_CONST(CKK_SHA_1_HMAC); + SET_CONST(CKK_RIPEMD128_HMAC); + SET_CONST(CKK_RIPEMD160_HMAC); + SET_CONST(CKK_SHA256_HMAC); + SET_CONST(CKK_SHA384_HMAC); + SET_CONST(CKK_SHA512_HMAC); + SET_CONST(CKK_SHA224_HMAC); + SET_CONST(CKK_SEED); + SET_CONST(CKK_GOSTR3410); + SET_CONST(CKK_GOSTR3411); + SET_CONST(CKK_GOST28147); + SET_CONST(CKK_VENDOR_DEFINED); } -void declare_params(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CK_PARAMS_AES_CBC); - SET_CONST(target, CK_PARAMS_AES_CCM); - SET_CONST(target, CK_PARAMS_AES_GCM); - SET_CONST(target, CK_PARAMS_AES_GCM_v240); - SET_CONST(target, CK_PARAMS_RSA_OAEP); - SET_CONST(target, CK_PARAMS_RSA_PSS); - SET_CONST(target, CK_PARAMS_EC_DH); +/** + * @brief Set CKD_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckd(napi_env env, napi_value exports) +{ + SET_CONST(CKD_NULL); + SET_CONST(CKD_SHA1_KDF); + SET_CONST(CKD_SHA1_KDF_ASN1); + SET_CONST(CKD_SHA1_KDF_CONCATENATE); + SET_CONST(CKD_SHA224_KDF); + SET_CONST(CKD_SHA256_KDF); + SET_CONST(CKD_SHA384_KDF); + SET_CONST(CKD_SHA512_KDF); + SET_CONST(CKD_CPDIVERSIFY_KDF); } -void declare_initialize_flags(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKF_LIBRARY_CANT_CREATE_OS_THREADS); - SET_CONST(target, CKF_OS_LOCKING_OK); +/** + * @brief Set CKC_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_ckc(napi_env env, napi_value exports) +{ + SET_CONST(CKC_X_509); + SET_CONST(CKC_X_509_ATTR_CERT); + SET_CONST(CKC_WTLS); + SET_CONST(CKC_VENDOR_DEFINED); } -void declare_user_types(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKU_SO); - SET_CONST(target, CKU_USER); - SET_CONST(target, CKU_CONTEXT_SPECIFIC); +/** + * @brief Set CKU_* constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_cku(napi_env env, napi_value exports) +{ + SET_CONST(CKU_SO); + SET_CONST(CKU_USER); + SET_CONST(CKU_CONTEXT_SPECIFIC); } -void declare_result_values(Local target) { - Nan::HandleScope scope; - - SET_CONST(target, CKR_OK); - SET_CONST(target, CKR_CANCEL); - SET_CONST(target, CKR_HOST_MEMORY); - SET_CONST(target, CKR_SLOT_ID_INVALID); - SET_CONST(target, CKR_GENERAL_ERROR); - SET_CONST(target, CKR_FUNCTION_FAILED); - SET_CONST(target, CKR_ARGUMENTS_BAD); - SET_CONST(target, CKR_NO_EVENT); - SET_CONST(target, CKR_NEED_TO_CREATE_THREADS); - SET_CONST(target, CKR_CANT_LOCK); - SET_CONST(target, CKR_ATTRIBUTE_READ_ONLY); - SET_CONST(target, CKR_ATTRIBUTE_SENSITIVE); - SET_CONST(target, CKR_ATTRIBUTE_TYPE_INVALID); - SET_CONST(target, CKR_ATTRIBUTE_VALUE_INVALID); - SET_CONST(target, CKR_DATA_INVALID); - SET_CONST(target, CKR_DATA_LEN_RANGE); - SET_CONST(target, CKR_DEVICE_ERROR); - SET_CONST(target, CKR_DEVICE_MEMORY); - SET_CONST(target, CKR_DEVICE_REMOVED); - SET_CONST(target, CKR_ENCRYPTED_DATA_INVALID); - SET_CONST(target, CKR_ENCRYPTED_DATA_LEN_RANGE); - SET_CONST(target, CKR_FUNCTION_CANCELED); - SET_CONST(target, CKR_FUNCTION_NOT_PARALLEL); - SET_CONST(target, CKR_FUNCTION_NOT_SUPPORTED); - SET_CONST(target, CKR_KEY_HANDLE_INVALID); - SET_CONST(target, CKR_KEY_SIZE_RANGE); - SET_CONST(target, CKR_KEY_TYPE_INCONSISTENT); - SET_CONST(target, CKR_KEY_NOT_NEEDED); - SET_CONST(target, CKR_KEY_CHANGED); - SET_CONST(target, CKR_KEY_NEEDED); - SET_CONST(target, CKR_KEY_INDIGESTIBLE); - SET_CONST(target, CKR_KEY_FUNCTION_NOT_PERMITTED); - SET_CONST(target, CKR_KEY_NOT_WRAPPABLE); - SET_CONST(target, CKR_KEY_UNEXTRACTABLE); - SET_CONST(target, CKR_MECHANISM_INVALID); - SET_CONST(target, CKR_MECHANISM_PARAM_INVALID); - SET_CONST(target, CKR_OBJECT_HANDLE_INVALID); - SET_CONST(target, CKR_OPERATION_ACTIVE); - SET_CONST(target, CKR_OPERATION_NOT_INITIALIZED); - SET_CONST(target, CKR_PIN_INCORRECT); - SET_CONST(target, CKR_PIN_INVALID); - SET_CONST(target, CKR_PIN_LEN_RANGE); - SET_CONST(target, CKR_PIN_EXPIRED); - SET_CONST(target, CKR_PIN_LOCKED); - SET_CONST(target, CKR_SESSION_CLOSED); - SET_CONST(target, CKR_SESSION_COUNT); - SET_CONST(target, CKR_SESSION_HANDLE_INVALID); - SET_CONST(target, CKR_SESSION_PARALLEL_NOT_SUPPORTED); - SET_CONST(target, CKR_SESSION_READ_ONLY); - SET_CONST(target, CKR_SESSION_EXISTS); - SET_CONST(target, CKR_SESSION_READ_ONLY_EXISTS); - SET_CONST(target, CKR_SESSION_READ_WRITE_SO_EXISTS); - SET_CONST(target, CKR_SIGNATURE_INVALID); - SET_CONST(target, CKR_SIGNATURE_LEN_RANGE); - SET_CONST(target, CKR_TEMPLATE_INCOMPLETE); - SET_CONST(target, CKR_TEMPLATE_INCONSISTENT); - SET_CONST(target, CKR_TOKEN_NOT_PRESENT); - SET_CONST(target, CKR_TOKEN_NOT_RECOGNIZED); - SET_CONST(target, CKR_TOKEN_WRITE_PROTECTED); - SET_CONST(target, CKR_UNWRAPPING_KEY_HANDLE_INVALID); - SET_CONST(target, CKR_UNWRAPPING_KEY_SIZE_RANGE); - SET_CONST(target, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT); - SET_CONST(target, CKR_USER_ALREADY_LOGGED_IN); - SET_CONST(target, CKR_USER_NOT_LOGGED_IN); - SET_CONST(target, CKR_USER_PIN_NOT_INITIALIZED); - SET_CONST(target, CKR_USER_TYPE_INVALID); - SET_CONST(target, CKR_USER_ANOTHER_ALREADY_LOGGED_IN); - SET_CONST(target, CKR_USER_TOO_MANY_TYPES); - SET_CONST(target, CKR_WRAPPED_KEY_INVALID); - SET_CONST(target, CKR_WRAPPED_KEY_LEN_RANGE); - SET_CONST(target, CKR_WRAPPING_KEY_HANDLE_INVALID); - SET_CONST(target, CKR_WRAPPING_KEY_SIZE_RANGE); - SET_CONST(target, CKR_WRAPPING_KEY_TYPE_INCONSISTENT); - SET_CONST(target, CKR_RANDOM_SEED_NOT_SUPPORTED); - SET_CONST(target, CKR_RANDOM_NO_RNG); - SET_CONST(target, CKR_DOMAIN_PARAMS_INVALID); - SET_CONST(target, CKR_BUFFER_TOO_SMALL); - SET_CONST(target, CKR_SAVED_STATE_INVALID); - SET_CONST(target, CKR_INFORMATION_SENSITIVE); - SET_CONST(target, CKR_STATE_UNSAVEABLE); - SET_CONST(target, CKR_CRYPTOKI_NOT_INITIALIZED); - SET_CONST(target, CKR_CRYPTOKI_ALREADY_INITIALIZED); - SET_CONST(target, CKR_MUTEX_BAD); - SET_CONST(target, CKR_MUTEX_NOT_LOCKED); - SET_CONST(target, CKR_NEW_PIN_MODE); - SET_CONST(target, CKR_NEXT_OTP); - SET_CONST(target, CKR_EXCEEDED_MAX_ITERATIONS); - SET_CONST(target, CKR_FIPS_SELF_TEST_FAILED); - SET_CONST(target, CKR_LIBRARY_LOAD_FAILED); - SET_CONST(target, CKR_PIN_TOO_WEAK); - SET_CONST(target, CKR_PUBLIC_KEY_INVALID); - SET_CONST(target, CKR_FUNCTION_REJECTED); +/** + * @brief Set all Cryptoki constants on the exports object. + * + * @param env The N-API environment. + * @param exports The N-API exports object. + */ +void set_all_const(napi_env env, napi_value exports) +{ + set_ckr(env, exports); + set_ckp(env, exports); + set_ckf(env, exports); + set_cka(env, exports); + set_cko(env, exports); + set_ckm(env, exports); + set_ckg(env, exports); + set_ckk(env, exports); + set_ckd(env, exports); + set_ckc(env, exports); + set_cku(env, exports); } diff --git a/src/const.h b/src/const.h deleted file mode 100644 index 08079be..0000000 --- a/src/const.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef INCLUDE_H_CONST - -#define INCLUDE_H_CONST - -#include -#include -#include - -#ifdef WIN32 -#pragma pack(push, cryptoki, 1) -#endif -#include -#ifdef WIN32 -#pragma pack(pop, cryptoki) -#endif - -#include "pkcs11/param.h" - -using namespace v8; -using namespace node; - -#define SET_CONST(target, value) \ - Nan::DefineOwnProperty( \ - target, \ - Nan::New(#value).ToLocalChecked(), \ - Nan::New(value), \ - static_cast(ReadOnly | DontDelete)); - -void declare_attributes(Local target); -void declare_flags(Local target); -void declare_objects(Local target); -void declare_ket_types(Local target); -void declare_mechanisms(Local target); -void declare_certificates(Local target); -void declare_mgf(Local target); -void declare_kdf(Local target); -void declare_params(Local target); -void declare_initialize_flags(Local target); -void declare_user_types(Local target); -void declare_result_values(Local target); - -#endif // INCLUDE_H_CONST diff --git a/src/main.cpp b/src/main.cpp index b119420..ba88084 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,27 +1,109 @@ -#include -#include +#include "common.h" -#include "const.h" -#include "node.h" +#include "const.cpp" +#include "pkcs11.cpp" -NAN_MODULE_INIT(init) +#define DEFINE_PKCS11_METHOD(name) \ + { \ + #name, nullptr, Pkcs11::name, nullptr, nullptr, nullptr, attributes, nullptr \ + } + +napi_value Init(napi_env env, napi_value exports) { - Nan::HandleScope scope; - - WPKCS11::Init(target); - - declare_objects(target); - declare_attributes(target); - declare_ket_types(target); - declare_mechanisms(target); - declare_flags(target); - declare_certificates(target); - declare_mgf(target); - declare_kdf(target); - declare_params(target); - declare_initialize_flags(target); - declare_user_types(target); - declare_result_values(target); + napi_property_descriptor properties[] = {}; + + napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties); + + napi_property_attributes attributes = static_cast(napi_enumerable | napi_writable); + napi_property_descriptor instance_properties[] = { + {"load", nullptr, Pkcs11::Load, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"close", nullptr, Pkcs11::Close, nullptr, nullptr, nullptr, napi_default, nullptr}, + DEFINE_PKCS11_METHOD(C_Initialize), + DEFINE_PKCS11_METHOD(C_Finalize), + DEFINE_PKCS11_METHOD(C_GetInfo), + DEFINE_PKCS11_METHOD(C_GetSlotList), + DEFINE_PKCS11_METHOD(C_GetSlotInfo), + DEFINE_PKCS11_METHOD(C_GetTokenInfo), + DEFINE_PKCS11_METHOD(C_GetMechanismList), + DEFINE_PKCS11_METHOD(C_GetMechanismInfo), + DEFINE_PKCS11_METHOD(C_InitToken), + DEFINE_PKCS11_METHOD(C_InitPIN), + DEFINE_PKCS11_METHOD(C_SetPIN), + DEFINE_PKCS11_METHOD(C_OpenSession), + DEFINE_PKCS11_METHOD(C_CloseSession), + DEFINE_PKCS11_METHOD(C_CloseAllSessions), + DEFINE_PKCS11_METHOD(C_GetSessionInfo), + DEFINE_PKCS11_METHOD(C_GetOperationState), + DEFINE_PKCS11_METHOD(C_SetOperationState), + DEFINE_PKCS11_METHOD(C_Login), + DEFINE_PKCS11_METHOD(C_Logout), + DEFINE_PKCS11_METHOD(C_SeedRandom), + DEFINE_PKCS11_METHOD(C_GenerateRandom), + DEFINE_PKCS11_METHOD(C_CreateObject), + DEFINE_PKCS11_METHOD(C_CopyObject), + DEFINE_PKCS11_METHOD(C_DestroyObject), + DEFINE_PKCS11_METHOD(C_GetObjectSize), + DEFINE_PKCS11_METHOD(C_GetAttributeValue), + DEFINE_PKCS11_METHOD(C_SetAttributeValue), + DEFINE_PKCS11_METHOD(C_FindObjectsInit), + DEFINE_PKCS11_METHOD(C_FindObjects), + DEFINE_PKCS11_METHOD(C_FindObjectsFinal), + DEFINE_PKCS11_METHOD(C_DigestInit), + DEFINE_PKCS11_METHOD(C_Digest), + DEFINE_PKCS11_METHOD(C_DigestCallback), + DEFINE_PKCS11_METHOD(C_DigestUpdate), + DEFINE_PKCS11_METHOD(C_DigestKey), + DEFINE_PKCS11_METHOD(C_DigestFinal), + DEFINE_PKCS11_METHOD(C_DigestFinalCallback), + DEFINE_PKCS11_METHOD(C_GenerateKey), + DEFINE_PKCS11_METHOD(C_GenerateKeyCallback), + DEFINE_PKCS11_METHOD(C_GenerateKeyPair), + DEFINE_PKCS11_METHOD(C_GenerateKeyPairCallback), + DEFINE_PKCS11_METHOD(C_SignInit), + DEFINE_PKCS11_METHOD(C_Sign), + DEFINE_PKCS11_METHOD(C_SignCallback), + DEFINE_PKCS11_METHOD(C_SignUpdate), + DEFINE_PKCS11_METHOD(C_SignFinal), + DEFINE_PKCS11_METHOD(C_SignFinalCallback), + DEFINE_PKCS11_METHOD(C_VerifyInit), + DEFINE_PKCS11_METHOD(C_Verify), + DEFINE_PKCS11_METHOD(C_VerifyCallback), + DEFINE_PKCS11_METHOD(C_VerifyUpdate), + DEFINE_PKCS11_METHOD(C_VerifyFinal), + DEFINE_PKCS11_METHOD(C_VerifyFinalCallback), + DEFINE_PKCS11_METHOD(C_EncryptInit), + DEFINE_PKCS11_METHOD(C_Encrypt), + DEFINE_PKCS11_METHOD(C_EncryptCallback), + DEFINE_PKCS11_METHOD(C_EncryptUpdate), + DEFINE_PKCS11_METHOD(C_EncryptFinal), + DEFINE_PKCS11_METHOD(C_EncryptFinalCallback), + DEFINE_PKCS11_METHOD(C_DecryptInit), + DEFINE_PKCS11_METHOD(C_Decrypt), + DEFINE_PKCS11_METHOD(C_DecryptCallback), + DEFINE_PKCS11_METHOD(C_DecryptUpdate), + DEFINE_PKCS11_METHOD(C_DecryptFinal), + DEFINE_PKCS11_METHOD(C_DecryptFinalCallback), + DEFINE_PKCS11_METHOD(C_DeriveKey), + DEFINE_PKCS11_METHOD(C_DeriveKeyCallback), + DEFINE_PKCS11_METHOD(C_WrapKey), + DEFINE_PKCS11_METHOD(C_WrapKeyCallback), + DEFINE_PKCS11_METHOD(C_UnwrapKey), + DEFINE_PKCS11_METHOD(C_UnwrapKeyCallback), + DEFINE_PKCS11_METHOD(C_SignRecoverInit), + DEFINE_PKCS11_METHOD(C_SignRecover), + DEFINE_PKCS11_METHOD(C_VerifyRecoverInit), + DEFINE_PKCS11_METHOD(C_VerifyRecover), + }; + napi_value constructor; + napi_define_class(env, "PKCS11", NAPI_AUTO_LENGTH, Pkcs11::Constructor, nullptr, sizeof(instance_properties) / sizeof(*instance_properties), instance_properties, &constructor); + napi_create_reference(env, constructor, 1, &constructorRef); + napi_set_named_property(env, exports, "PKCS11", constructor); + + set_all_const(env, exports); + + return exports; } -NODE_MODULE(pkcs11, init) +#undef DEFINE_PKCS11_METHOD + +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) \ No newline at end of file diff --git a/src/node.cpp b/src/node.cpp deleted file mode 100644 index df6585d..0000000 --- a/src/node.cpp +++ /dev/null @@ -1,1391 +0,0 @@ -#include -#include - -#ifdef WIN32 -#include "dl.h" -#else -#include -#endif // WIN32 - -#include "node.h" -#include "async.h" - -#define UNWRAP_PKCS11 auto __pkcs11= WPKCS11::Unwrap(info.This())->pkcs11 - -#define SET_PKCS11_METHOD(name) Nan::SetPrototypeMethod(tpl, #name, name) - -#define THROW_V8_ERROR(text) \ - {Nan::ThrowError(text); \ - return;} - -#define THROW_V8_TYPE_ERROR(text) \ - {Nan::ThrowTypeError(text); \ - return;} - -#define THROW_REQUIRED(argsIndex) \ - {std::string errorMessage = "Parameter " + std::to_string(argsIndex+1) + " is REQUIRED"; \ - Local v8ErrorMessage = Nan::New(errorMessage).ToLocalChecked(); \ - THROW_V8_TYPE_ERROR(v8ErrorMessage)} - -#define CHECK_REQUIRED(argsIndex) \ - if (info[argsIndex]->IsUndefined() /*|| info[argsIndex]->IsNull()*/) \ - THROW_REQUIRED(argsIndex) - -#define THROW_WRONG_TYPE(argsIndex, v8Type) \ - {std::string errorMessage = "Parameter " + std::to_string(argsIndex+1) + " MUST be " + #v8Type; \ - Local v8ErrorMessage = Nan::New(errorMessage).ToLocalChecked(); \ - THROW_V8_TYPE_ERROR(v8ErrorMessage)} - -#define CHECK_BUFFER(argsIndex) \ - if (!node::Buffer::HasInstance(info[argsIndex])) \ - THROW_WRONG_TYPE(argsIndex, Buffer) - -#define CATCH_V8_ERROR catch (Scoped e) {Nan::ThrowError(e->ToString()->c_str());return;} - -#define CHECK_TYPE(argsIndex, v8Type) \ - if (!info[argsIndex]->Is##v8Type()) \ - THROW_WRONG_TYPE(argsIndex, v8Type) - -#define GET_MECHANISM(name, argsIndex) \ - CHECK_REQUIRED(argsIndex) \ - Scoped name(new Mechanism); \ - name->FromV8(info[argsIndex]); - -#define GET_TEMPLATE(name, argsIndex) \ - Scoped name(new Attributes); \ - name->FromV8(info[argsIndex]); - -#define GET_TEMPLATE_R(name, argsIndex) \ - CHECK_REQUIRED(argsIndex) \ - GET_TEMPLATE(name, argsIndex) - -#define GET_BUFFER(name, argsIndex) \ - CHECK_REQUIRED(argsIndex); \ - CHECK_BUFFER(argsIndex); \ - Scoped name = buffer_to_string(info[argsIndex]) - -static Scoped buffer_to_string(Local v8Value) { - Nan::HandleScope scope; - - Local v8Buffer = Nan::To(v8Value).ToLocalChecked(); - auto buf = node::Buffer::Data(v8Buffer); - auto bufLen = node::Buffer::Length(v8Buffer); - return Scoped(new string(buf, bufLen)); -} - -static Local handle_to_v8(CK_ULONG handle) { - Nan::EscapableHandleScope scope; - - Local v8Buffer = Nan::NewBuffer(sizeof(CK_ULONG)).ToLocalChecked(); - char* buf = node::Buffer::Data(v8Buffer); - - memcpy(buf, &handle, sizeof(CK_ULONG)); - - return scope.Escape(v8Buffer); -} - -static CK_ULONG v8_to_handle(Local v8Value) { - Nan::HandleScope scope; - - // Check buffer size - if (node::Buffer::Length(v8Value) < sizeof(CK_ULONG)) { - THROW_ERROR("Buffer size is less than CK_ULONG size", NULL); - } - - CK_ULONG handle = 0; - - char* buf = node::Buffer::Data(v8Value); - handle = *reinterpret_cast(buf); - - return handle; -} - -#define GET_HANDLE(type, name, argsIndex) \ - CHECK_BUFFER(argsIndex); \ - type name = static_cast(v8_to_handle(info[argsIndex])) - -#define GET_SESSION_HANDLE(name, argsIndex) \ - GET_HANDLE(CK_SESSION_HANDLE, name, argsIndex) - -#define GET_OBJECT_HANDLE(name, argsIndex) \ - GET_HANDLE(CK_OBJECT_HANDLE, name, argsIndex) - -#define GET_SLOT_ID_HANDLE(name, argsIndex) \ - GET_HANDLE(CK_SLOT_ID, name, argsIndex) - -static Scoped get_string(Local v8String, const char* defaultValue = "") { - Scoped res; - if (v8String->IsString()) { - res = Scoped(new string(*Nan::Utf8String(v8String))); - } - else - res = Scoped(new string(defaultValue)); - - return res; -} - -#define GET_STRING(name, argsIndex, defaultValue) \ - Scoped name = get_string(info[argsIndex], defaultValue); - -static Local GetVersion(CK_VERSION& version) { - Nan::EscapableHandleScope scope; - - Local v8Version = Nan::New(); - Nan::Set(v8Version, Nan::New(STR_MAJOR).ToLocalChecked(), Nan::New(version.major)); - Nan::Set(v8Version, Nan::New(STR_MINOR).ToLocalChecked(), Nan::New(version.minor)); - - return scope.Escape(v8Version); -} - -static v8::Local FillBuffer(v8::Local buffer, std::string* data) { - Nan::EscapableHandleScope scope; - - v8::Local v8Buffer = Nan::To(buffer).ToLocalChecked(); - - // Copy from data to buffer - for (uint32_t i = 0; i < data->length(); i++) { - Nan::Set(v8Buffer, i, Nan::New((uint32_t)data->at(i))); - } - - // Slice buffer - v8::Local v8Slice = Nan::Get(v8Buffer, Nan::New("slice").ToLocalChecked()).ToLocalChecked(); - v8::Local v8SliceFn = Nan::To(v8Slice).ToLocalChecked(); - v8::Local v8SliceArgs[2]; - v8SliceArgs[0] = Nan::New(0); - v8SliceArgs[1] = Nan::New(data->length()); - v8::Local v8SliceResult = Nan::Call(v8SliceFn, v8Buffer, 2, v8SliceArgs).ToLocalChecked(); - - return scope.Escape(v8SliceResult); -} - -#define CN_PKCS11 "PKCS11" - -NAN_MODULE_INIT(WPKCS11::Init) { - Local tpl = Nan::New(New); - tpl->SetClassName(Nan::New(CN_PKCS11).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - v8::Local itpl = tpl->InstanceTemplate(); - - Nan::SetAccessor(itpl, Nan::New("libPath").ToLocalChecked(), GetLibPath); - - // methods - SetPrototypeMethod(tpl, "load", Load); - SetPrototypeMethod(tpl, "close", Close); - SET_PKCS11_METHOD(C_Initialize); - SET_PKCS11_METHOD(C_Finalize); - SET_PKCS11_METHOD(C_GetInfo); - SET_PKCS11_METHOD(C_GetSlotList); - SET_PKCS11_METHOD(C_GetSlotInfo); - SET_PKCS11_METHOD(C_GetTokenInfo); - SET_PKCS11_METHOD(C_GetMechanismList); - SET_PKCS11_METHOD(C_GetMechanismInfo); - SET_PKCS11_METHOD(C_InitToken); - SET_PKCS11_METHOD(C_InitPIN); - SET_PKCS11_METHOD(C_SetPIN); - SET_PKCS11_METHOD(C_OpenSession); - SET_PKCS11_METHOD(C_CloseSession); - SET_PKCS11_METHOD(C_CloseAllSessions); - SET_PKCS11_METHOD(C_GetSessionInfo); - SET_PKCS11_METHOD(C_Login); - SET_PKCS11_METHOD(C_Logout); - SET_PKCS11_METHOD(C_CreateObject); - SET_PKCS11_METHOD(C_CopyObject); - SET_PKCS11_METHOD(C_DestroyObject); - SET_PKCS11_METHOD(C_GetObjectSize); - SET_PKCS11_METHOD(C_FindObjectsInit); - SET_PKCS11_METHOD(C_FindObjects); - SET_PKCS11_METHOD(C_FindObjectsFinal); - SET_PKCS11_METHOD(C_GetAttributeValue); - SET_PKCS11_METHOD(C_SetAttributeValue); - SET_PKCS11_METHOD(C_EncryptInit); - SET_PKCS11_METHOD(C_Encrypt); - SET_PKCS11_METHOD(C_EncryptUpdate); - SET_PKCS11_METHOD(C_EncryptFinal); - SET_PKCS11_METHOD(C_DecryptInit); - SET_PKCS11_METHOD(C_Decrypt); - SET_PKCS11_METHOD(C_DecryptUpdate); - SET_PKCS11_METHOD(C_DecryptFinal); - SET_PKCS11_METHOD(C_DigestInit); - SET_PKCS11_METHOD(C_Digest); - SET_PKCS11_METHOD(C_DigestUpdate); - SET_PKCS11_METHOD(C_DigestFinal); - SET_PKCS11_METHOD(C_DigestKey); - SET_PKCS11_METHOD(C_SignInit); - SET_PKCS11_METHOD(C_Sign); - SET_PKCS11_METHOD(C_SignUpdate); - SET_PKCS11_METHOD(C_SignFinal); - SET_PKCS11_METHOD(C_SignRecoverInit); - SET_PKCS11_METHOD(C_SignRecover); - SET_PKCS11_METHOD(C_VerifyInit); - SET_PKCS11_METHOD(C_Verify); - SET_PKCS11_METHOD(C_VerifyUpdate); - SET_PKCS11_METHOD(C_VerifyFinal); - SET_PKCS11_METHOD(C_VerifyRecoverInit); - SET_PKCS11_METHOD(C_VerifyRecover); - SET_PKCS11_METHOD(C_GenerateKey); - SET_PKCS11_METHOD(C_GenerateKeyPair); - SET_PKCS11_METHOD(C_WrapKey); - SET_PKCS11_METHOD(C_UnwrapKey); - SET_PKCS11_METHOD(C_DeriveKey); - SET_PKCS11_METHOD(C_SeedRandom); - SET_PKCS11_METHOD(C_GenerateRandom); - SET_PKCS11_METHOD(C_WaitForSlotEvent); - - constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); - - // static methods - // Nan::SetMethod>(tpl->GeFunction(), "generate", Generate); - - Nan::Set(target, Nan::New(CN_PKCS11).ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); -} - -NAN_PROPERTY_GETTER(WPKCS11::GetLibPath) -{ - UNWRAP_PKCS11; - - try { - info.GetReturnValue().Set(Nan::New(__pkcs11->libPath->c_str()).ToLocalChecked()); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::New) { - if (info.IsConstructCall()) { - - WPKCS11* obj = new WPKCS11(); - obj->pkcs11 = Scoped(new PKCS11); - obj->Wrap(info.This()); - - info.GetReturnValue().Set(info.This()); - } - else { - Local cons = Nan::New(constructor()); - info.GetReturnValue().Set(Nan::NewInstance(cons, 0, nullptr).ToLocalChecked()); - } -}; - -NAN_METHOD(WPKCS11::Load) { - CHECK_REQUIRED(0); - CHECK_TYPE(0, String); - GET_STRING(path, 0, ""); - - UNWRAP_PKCS11; - - try { - __pkcs11->Load(path); - } - CATCH_V8_ERROR; -} - -static void free_args(CK_VOID_PTR args) { - if (args) { - if (static_cast(args)) { - CK_NSS_C_INITIALIZE_ARGS_PTR nssArgs = static_cast(args); - free(nssArgs->LibraryParameters); - } - free(args); - args = NULL; - } -} - -NAN_METHOD(WPKCS11::Close) { - UNWRAP_PKCS11; - - try { - __pkcs11->Close(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Initialize) { - UNWRAP_PKCS11; - - CK_VOID_PTR initArgs = NULL; - try { - if (info.Length() == 0 || info[0]->IsUndefined() || info[0]->IsNull()) { - __pkcs11->C_Initialize(NULL); - } else if (info[0]->IsObject()) { - Local obj = Nan::To(info[0]).ToLocalChecked(); - Local v8FlagsProperty = Nan::New("flags").ToLocalChecked(); - Local v8LibraryParametersProperty = Nan::New("libraryParameters").ToLocalChecked(); - - if (Nan::Has(obj, v8LibraryParametersProperty).FromJust()) { - Nan::Utf8String v8LibraryParameters(Nan::Get(obj, v8LibraryParametersProperty).ToLocalChecked()); - Scoped libraryParameters = Scoped(new string(*v8LibraryParameters)); - CK_NSS_C_INITIALIZE_ARGS_PTR args = (CK_NSS_C_INITIALIZE_ARGS_PTR)malloc(sizeof(CK_NSS_C_INITIALIZE_ARGS)); - initArgs = (CK_VOID_PTR)args; - args->CreateMutex = NULL; - args->DestroyMutex = NULL; - args->LibraryParameters = (CK_CHAR_PTR)malloc(libraryParameters->size()); - memcpy(args->LibraryParameters, libraryParameters->c_str(), libraryParameters->size()); - args->LockMutex = NULL; - args->UnlockMutex = NULL; - args->pReserved = NULL; - if (Nan::Has(obj, v8FlagsProperty).FromJust()) { - v8::Local v8Flag = Nan::Get(obj, v8FlagsProperty).ToLocalChecked(); - args->flags = Nan::To(v8Flag).FromJust(); - } else { - args->flags = 0; - } - } else { - CK_C_INITIALIZE_ARGS_PTR args = (CK_C_INITIALIZE_ARGS_PTR)malloc(sizeof(CK_C_INITIALIZE_ARGS)); - initArgs = (CK_VOID_PTR)args; - args->CreateMutex = NULL; - args->DestroyMutex = NULL; - args->LockMutex = NULL; - args->UnlockMutex = NULL; - args->pReserved = NULL; - if (Nan::Has(obj, v8FlagsProperty).FromJust()) { - v8::Local v8Flag = Nan::Get(obj, v8FlagsProperty).ToLocalChecked(); - args->flags = Nan::To(v8Flag).FromJust(); - } else { - args->flags = 0; - } - } - __pkcs11->C_Initialize(initArgs); - free_args(initArgs); - } else { - THROW_ERROR("Parameter has wrong type. Should be empty or Object", NULL); - } - } - catch (Scoped e) { - free_args(initArgs); - Nan::ThrowError(e->ToString()->c_str()); - return; - } -} - -NAN_METHOD(WPKCS11::C_Finalize) { - UNWRAP_PKCS11; - - try { - __pkcs11->C_Finalize(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetInfo) { - UNWRAP_PKCS11; - - try { - Scoped _info = __pkcs11->C_GetInfo(); - - Local v8Object = Nan::New(); - if (_info->cryptokiVersion.major == 2) { - /* Do lots of interesting cryptographic things with the token */ - Nan::Set(v8Object, Nan::New(STR_CRYPTOKI_VERSION).ToLocalChecked(), GetVersion(_info->cryptokiVersion)); - Nan::Set(v8Object, Nan::New(STR_MANUFACTURER_ID).ToLocalChecked(), Nan::New((char*)_info->manufacturerID, 32).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_FLAGS).ToLocalChecked(), Nan::New((uint32_t)_info->flags)); - - Nan::Set(v8Object, Nan::New(STR_LIBRARY_DESCRIPTION).ToLocalChecked(), Nan::New((char*)_info->libraryDescription, 32).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_LIBRARY_VERSION).ToLocalChecked(), GetVersion(_info->libraryVersion)); - } - - info.GetReturnValue().Set(v8Object); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetSlotList) { - try { - - UNWRAP_PKCS11; - - CK_BBOOL tokenPresent = info[0]->IsBoolean() ? Nan::To(info[0]).FromJust() : false; - - auto arSlotList = __pkcs11->C_GetSlotList(tokenPresent); - - Local v8SlotList = Nan::New(); - for (uint32_t i = 0; i < arSlotList.size(); i++) { - Nan::Set(v8SlotList, i, handle_to_v8(arSlotList[i])); - } - - info.GetReturnValue().Set(v8SlotList); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetSlotInfo) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - UNWRAP_PKCS11; - - auto _info = __pkcs11->C_GetSlotInfo(slotID); - - Local v8Object = Nan::New(); - - Nan::Set(v8Object, Nan::New(STR_SLOT_DESCRIPTION).ToLocalChecked(), Nan::New((char*)_info->slotDescription, 64).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_MANUFACTURER_ID).ToLocalChecked(), Nan::New((char*)_info->manufacturerID, 32).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_FLAGS).ToLocalChecked(), Nan::New((uint32_t)_info->flags)); - Nan::Set(v8Object, Nan::New(STR_HARDWARE_VERSION).ToLocalChecked(), GetVersion(_info->hardwareVersion)); - Nan::Set(v8Object, Nan::New(STR_FIRMWARE_VERSION).ToLocalChecked(), GetVersion(_info->firmwareVersion)); - - info.GetReturnValue().Set(v8Object); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetTokenInfo) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - UNWRAP_PKCS11; - - auto _info = __pkcs11->C_GetTokenInfo(slotID); - - Local v8Object = Nan::New(); - Nan::Set(v8Object, Nan::New(STR_LABEL).ToLocalChecked(), Nan::New((char*)_info->label, 32).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_MANUFACTURER_ID).ToLocalChecked(), Nan::New((char*)_info->manufacturerID, 32).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_MODEL).ToLocalChecked(), Nan::New((char*)_info->model, 16).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_SERIAL_NUMER).ToLocalChecked(), Nan::New((char*)_info->serialNumber, 16).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_FLAGS).ToLocalChecked(), Nan::New(_info->flags)); - Nan::Set(v8Object, Nan::New(STR_MAX_SESSION_COUNT).ToLocalChecked(), Nan::New(_info->ulMaxSessionCount)); - Nan::Set(v8Object, Nan::New(STR_SESSION_COUNT).ToLocalChecked(), Nan::New(_info->ulSessionCount)); - Nan::Set(v8Object, Nan::New(STR_MAX_RW_SESSION_COUNT).ToLocalChecked(), Nan::New(_info->ulMaxRwSessionCount)); - Nan::Set(v8Object, Nan::New(STR_RW_SESSION_COUNT).ToLocalChecked(), Nan::New(_info->ulRwSessionCount)); - Nan::Set(v8Object, Nan::New(STR_MAX_PIN_LEN).ToLocalChecked(), Nan::New(_info->ulMaxPinLen)); - Nan::Set(v8Object, Nan::New(STR_MIN_PIN_LEN).ToLocalChecked(), Nan::New(_info->ulMinPinLen)); - Nan::Set(v8Object, Nan::New(STR_HARDWARE_VERSION).ToLocalChecked(), GetVersion(_info->hardwareVersion)); - Nan::Set(v8Object, Nan::New(STR_FIRMWARE_VERSION).ToLocalChecked(), GetVersion(_info->firmwareVersion)); - Nan::Set(v8Object, Nan::New(STR_UTC_TIME).ToLocalChecked(), Nan::New((char*)_info->utcTime, 16).ToLocalChecked()); - Nan::Set(v8Object, Nan::New(STR_TOTAL_PUBLIC_MEMORY).ToLocalChecked(), Nan::New(_info->ulTotalPublicMemory)); - Nan::Set(v8Object, Nan::New(STR_FREE_PUBLIC_MEMORY).ToLocalChecked(), Nan::New(_info->ulFreePublicMemory)); - Nan::Set(v8Object, Nan::New(STR_TOTAL_PRIVATE_MEMORY).ToLocalChecked(), Nan::New(_info->ulTotalPrivateMemory)); - Nan::Set(v8Object, Nan::New(STR_FREE_PRIVATE_MEMORY).ToLocalChecked(), Nan::New(_info->ulFreePrivateMemory)); - - info.GetReturnValue().Set(v8Object); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetMechanismList) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - UNWRAP_PKCS11; - - auto pMechanismList = __pkcs11->C_GetMechanismList(slotID); - - Local v8Res = Nan::New(); - for (uint32_t i = 0; i < pMechanismList.size(); i++) { - Nan::Set(v8Res, i, Nan::New(pMechanismList[i])); - } - info.GetReturnValue().Set(v8Res); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetMechanismInfo) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - CHECK_REQUIRED(1); - CHECK_TYPE(1, Number); - CK_MECHANISM_TYPE type = Nan::To(info[1]).FromJust(); - - UNWRAP_PKCS11; - - auto pInfo = __pkcs11->C_GetMechanismInfo(slotID, type); - - Local v8Res = Nan::New(); - - Nan::Set(v8Res, Nan::New(STR_MIN_KEY_SIZE).ToLocalChecked(), Nan::New(pInfo->ulMinKeySize)); - Nan::Set(v8Res, Nan::New(STR_MAX_KEY_SIZE).ToLocalChecked(), Nan::New(pInfo->ulMaxKeySize)); - Nan::Set(v8Res, Nan::New(STR_FLAGS).ToLocalChecked(), Nan::New(pInfo->flags)); - - info.GetReturnValue().Set(v8Res); - } - CATCH_V8_ERROR; -} - -///* C_InitToken initializes a token. */ - -NAN_METHOD(WPKCS11::C_InitToken) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - GET_STRING(pin, 1, ""); - GET_STRING(label, 2, ""); - UNWRAP_PKCS11; - - Scoped rlabel = __pkcs11->C_InitToken(slotID, pin, label); - - info.GetReturnValue().Set(Nan::New(rlabel->c_str()).ToLocalChecked()); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_InitPIN) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_STRING(pin, 1, ""); - - UNWRAP_PKCS11; - - __pkcs11->C_InitPIN(hSession, pin); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SetPIN) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_STRING(oldPin, 1, ""); - GET_STRING(newPin, 2, ""); - - UNWRAP_PKCS11; - - __pkcs11->C_SetPIN(hSession, oldPin, newPin); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_OpenSession) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - CHECK_REQUIRED(1); - CHECK_TYPE(1, Number); - CK_FLAGS flags = Nan::To(info[1]).FromJust(); - - UNWRAP_PKCS11; - - CK_SESSION_HANDLE hSession = __pkcs11->C_OpenSession(slotID, flags); - - info.GetReturnValue().Set(handle_to_v8(hSession)); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_CloseSession) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - __pkcs11->C_CloseSession(hSession); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_CloseAllSessions) { - try { - GET_SLOT_ID_HANDLE(slotID, 0); - - UNWRAP_PKCS11; - - __pkcs11->C_CloseAllSessions(slotID); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetSessionInfo) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - Scoped _info = __pkcs11->C_GetSessionInfo(hSession); - - Local v8Res = Nan::New(); - - Nan::Set(v8Res, Nan::New(STR_SLOT_ID).ToLocalChecked(), handle_to_v8(_info->slotID)); - Nan::Set(v8Res, Nan::New(STR_STATE).ToLocalChecked(), Nan::New(_info->state)); - Nan::Set(v8Res, Nan::New(STR_FLAGS).ToLocalChecked(), Nan::New(_info->flags)); - Nan::Set(v8Res, Nan::New(STR_DEVICE_ERROR).ToLocalChecked(), Nan::New(_info->ulDeviceError)); - - info.GetReturnValue().Set(v8Res); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Login) { - try { - GET_SESSION_HANDLE(hSession, 0); - - CHECK_REQUIRED(1); - CHECK_TYPE(1, Number); - CK_USER_TYPE userType = Nan::To(info[1]).FromJust(); - - UNWRAP_PKCS11; - - Scoped pin = get_string(info[2]); - - __pkcs11->C_Login(hSession, userType, pin); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Logout) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - __pkcs11->C_Logout(hSession); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_FindObjectsInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - if (!info[1]->IsArray()) { - __pkcs11->C_FindObjectsInit(hSession); - } - else { - Scoped tmpl(new Attributes); - tmpl->FromV8(info[1]); - - __pkcs11->C_FindObjectsInit(hSession, tmpl); - } - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_FindObjects) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - CK_ULONG ulMaxObjectCount = info.Length() > 1 ? Nan::To(info[1]).ToChecked() : 1; - - vector hObjects = __pkcs11->C_FindObjects(hSession, ulMaxObjectCount); - - Local v8Res; - if (info.Length() > 1) { - v8::Local v8Array = Nan::New(hObjects.size()); - for (size_t i = 0; i < hObjects.size(); i++) { - Nan::Set(v8Array, i, handle_to_v8(hObjects[i])); - } - v8Res = v8Array.As(); - } else { - // TODO: Should remove this Return in future - v8Res = (hObjects.size() != 0) ? handle_to_v8(hObjects[0]).As() : Nan::Null().As(); - } - info.GetReturnValue().Set(v8Res); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_FindObjectsFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - - UNWRAP_PKCS11; - - __pkcs11->C_FindObjectsFinal(hSession); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetAttributeValue) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - GET_TEMPLATE_R(tmpl, 2); - - UNWRAP_PKCS11; - - tmpl = __pkcs11->C_GetAttributeValue(hSession, hObject, tmpl); - - info.GetReturnValue().Set(tmpl->ToV8()); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SetAttributeValue) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - - UNWRAP_PKCS11; - - CHECK_REQUIRED(2); - Scoped tmpl(new Attributes()); - tmpl->FromV8(info[2]); - - __pkcs11->C_SetAttributeValue(hSession, hObject, tmpl); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_CreateObject) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_TEMPLATE_R(tmpl, 1); - - UNWRAP_PKCS11; - - CK_OBJECT_HANDLE hObject = __pkcs11->C_CreateObject(hSession, tmpl); - - info.GetReturnValue().Set(handle_to_v8(hObject)); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_CopyObject) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - GET_TEMPLATE_R(tmpl, 2); - - UNWRAP_PKCS11; - - CK_OBJECT_HANDLE hNewObject = __pkcs11->C_CopyObject(hSession, hObject, tmpl); - - info.GetReturnValue().Set(handle_to_v8(hNewObject)); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DestroyObject) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_DestroyObject(hSession, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GetObjectSize) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - - UNWRAP_PKCS11; - - CK_ULONG ulSize = __pkcs11->C_GetObjectSize(hSession, hObject); - - info.GetReturnValue().Set(Nan::New(ulSize)); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_EncryptInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_EncryptInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Encrypt) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - Scoped res = __pkcs11->C_Encrypt(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncCrypto(callback, __pkcs11, ASYNC_CRYPTO_ENCRYPT, hSession, input, output)); - } - } - CATCH_V8_ERROR -} - -NAN_METHOD(WPKCS11::C_EncryptUpdate) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_EncryptUpdate(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_EncryptFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(output, 1); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_EncryptFinal(hSession, output); - - v8::Local v8Result = FillBuffer(info[1], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DecryptInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_DecryptInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Decrypt) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - Scoped res = __pkcs11->C_Decrypt(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncCrypto(callback, __pkcs11, ASYNC_CRYPTO_DECRYPT, hSession, input, output)); - } - } - CATCH_V8_ERROR -} - -NAN_METHOD(WPKCS11::C_DecryptUpdate) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_DecryptUpdate(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DecryptFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(output, 1); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_DecryptFinal(hSession, output); - - v8::Local v8Result = FillBuffer(info[1], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DigestInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_DigestInit(hSession, mech); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Digest) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - Scoped res = __pkcs11->C_Digest(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncCrypto(callback, __pkcs11, ASYNC_CRYPTO_DIGEST, hSession, input, output)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DigestUpdate) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_DigestUpdate(hSession, input); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DigestFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(output, 1); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_DigestFinal(hSession, output); - - v8::Local v8Result = FillBuffer(info[1], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DigestKey) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_OBJECT_HANDLE(hObject, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_DigestKey(hSession, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SignInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_SignInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Sign) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(output, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - Scoped res = __pkcs11->C_Sign(hSession, input, output); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncCrypto(callback, __pkcs11, ASYNC_CRYPTO_SIGN, hSession, input, output)); - } - } - CATCH_V8_ERROR -} - -NAN_METHOD(WPKCS11::C_SignUpdate) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_SignUpdate(hSession, input); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SignFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(output, 1); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_SignFinal(hSession, output); - - v8::Local v8Result = FillBuffer(info[1], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SignRecoverInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_SignRecoverInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SignRecover) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(data, 1); - GET_BUFFER(signature, 2); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_SignRecover(hSession, data, signature); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_VerifyInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_VerifyInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_Verify) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(input, 1); - GET_BUFFER(signature, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - __pkcs11->C_Verify(hSession, input, signature); - - info.GetReturnValue().Set(Nan::New(true)); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncCrypto(callback, __pkcs11, ASYNC_CRYPTO_VERIFY, hSession, input, signature)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_VerifyUpdate) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(data, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_VerifyUpdate(hSession, data); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_VerifyFinal) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(signature, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_VerifyFinal(hSession, signature); - - info.GetReturnValue().Set(Nan::New(true)); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_VerifyRecoverInit) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hObject, 2); - - UNWRAP_PKCS11; - - __pkcs11->C_VerifyRecoverInit(hSession, mech, hObject); - - info.GetReturnValue().SetNull(); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_VerifyRecover) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_BUFFER(signature, 1); - GET_BUFFER(data, 2); - - UNWRAP_PKCS11; - - Scoped res = __pkcs11->C_VerifyRecover(hSession, signature, data); - - v8::Local v8Result = FillBuffer(info[2], res.get()); - - info.GetReturnValue().Set(v8Result); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GenerateKey) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_TEMPLATE_R(tmpl, 2); - - UNWRAP_PKCS11; - - if (!info[3]->IsFunction()) { - - CK_OBJECT_HANDLE hObject = __pkcs11->C_GenerateKey(hSession, mech, tmpl); - info.GetReturnValue().Set(handle_to_v8(hObject)); - } - else { - Nan::Callback *callback = new Nan::Callback(info[3].As()); - - Nan::AsyncQueueWorker(new AsyncGenerateKey(callback, __pkcs11, hSession, mech, tmpl)); - } - - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GenerateKeyPair) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_TEMPLATE_R(publicKey, 2); - GET_TEMPLATE_R(privateKey, 3); - - UNWRAP_PKCS11; - - if (!info[4]->IsFunction()) { - Scoped keyPair = __pkcs11->C_GenerateKeyPair(hSession, mech, publicKey, privateKey); - - // Result - Local v8Result = Nan::New(); - Nan::Set(v8Result, Nan::New(STR_PRIVATE_KEY).ToLocalChecked(), handle_to_v8(keyPair->privateKey)); - Nan::Set(v8Result, Nan::New(STR_PUBLIC_KEY).ToLocalChecked(), handle_to_v8(keyPair->publicKey)); - - info.GetReturnValue().Set(v8Result); - } - else { - Nan::Callback *callback = new Nan::Callback(info[4].As()); - - Nan::AsyncQueueWorker(new AsyncGenerateKeyPair(callback, __pkcs11, hSession, mech, publicKey, privateKey)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_WrapKey) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hWrappingKey, 2); - GET_OBJECT_HANDLE(hKey, 3); - GET_BUFFER(wrappedKey, 4); - - int CALLBACK_INDEX = 5; - - UNWRAP_PKCS11; - - if (!info[CALLBACK_INDEX]->IsFunction()) { - Scoped res = __pkcs11->C_WrapKey(hSession, mech, hWrappingKey, hKey, wrappedKey); - - info.GetReturnValue().Set(Nan::CopyBuffer(res->c_str(), (uint32_t)res->length()).ToLocalChecked()); - } - else { - Nan::Callback *callback = new Nan::Callback(info[CALLBACK_INDEX].As()); - - Nan::AsyncQueueWorker(new AsyncWrapKey(callback, __pkcs11, hSession, mech, hWrappingKey, hKey, wrappedKey)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_UnwrapKey) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hUnwrappingKey, 2); - GET_BUFFER(wrappedKey, 3); - GET_TEMPLATE_R(tmpl, 4); - - int CALLBACK_INDEX = 5; - - UNWRAP_PKCS11; - - if (!info[CALLBACK_INDEX]->IsFunction()) { - CK_OBJECT_HANDLE hKey = __pkcs11->C_UnwrapKey(hSession, mech, hUnwrappingKey, wrappedKey, tmpl); - - info.GetReturnValue().Set(handle_to_v8(hKey)); - } - else { - Nan::Callback *callback = new Nan::Callback(info[CALLBACK_INDEX].As()); - - Nan::AsyncQueueWorker(new AsyncUnwrapKey(callback, __pkcs11, hSession, mech, hUnwrappingKey, wrappedKey, tmpl)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_DeriveKey) { - try { - GET_SESSION_HANDLE(hSession, 0); - GET_MECHANISM(mech, 1); - GET_OBJECT_HANDLE(hBaseKey, 2); - GET_TEMPLATE_R(tmpl, 3); - - int CALLBACK_INDEX = 4; - - UNWRAP_PKCS11; - - if (!info[CALLBACK_INDEX]->IsFunction()) { - CK_OBJECT_HANDLE hDerivedKey = __pkcs11->C_DeriveKey(hSession, mech, hBaseKey, tmpl); - - info.GetReturnValue().Set(handle_to_v8(hDerivedKey)); - } - else { - Nan::Callback *callback = new Nan::Callback(info[CALLBACK_INDEX].As()); - - Nan::AsyncQueueWorker(new AsyncDeriveKey(callback, __pkcs11, hSession, mech, hBaseKey, tmpl)); - } - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_SeedRandom) { - try { - GET_SESSION_HANDLE(hSession, 0); - CHECK_BUFFER(1); - GET_BUFFER_ARGS(seed, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_SeedRandom(hSession, seed, seedLen); - - info.GetReturnValue().Set(info[1]); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_GenerateRandom) { - try { - GET_SESSION_HANDLE(hSession, 0); - CHECK_BUFFER(1); - GET_BUFFER_ARGS(buffer, 1); - - UNWRAP_PKCS11; - - __pkcs11->C_GenerateRandom(hSession, buffer, bufferLen); - - info.GetReturnValue().Set(info[1]); - } - CATCH_V8_ERROR; -} - -NAN_METHOD(WPKCS11::C_WaitForSlotEvent) -{ - try - { - GET_SLOT_ID_HANDLE(slotID, 1); - - CHECK_REQUIRED(0); - CHECK_TYPE(0, Number); - CK_FLAGS flags = Nan::To(info[0]).FromJust(); - - UNWRAP_PKCS11; - - CK_RV rv = __pkcs11->C_WaitForSlotEvent(flags, &slotID); - - info.GetReturnValue().Set(handle_to_v8(rv)); - } - CATCH_V8_ERROR; -} diff --git a/src/node.h b/src/node.h deleted file mode 100644 index 6d3f63d..0000000 --- a/src/node.h +++ /dev/null @@ -1,128 +0,0 @@ -#include -#include - -// From https://github.com/nodejs/nan/issues/807#issuecomment-581536991 -#if defined(__GNUC__) && __GNUC__ >= 8 -#define DISABLE_WCAST_FUNCTION_TYPE _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"") -#define DISABLE_WCAST_FUNCTION_TYPE_END _Pragma("GCC diagnostic pop") -#else -#define DISABLE_WCAST_FUNCTION_TYPE -#define DISABLE_WCAST_FUNCTION_TYPE_END -#endif - -DISABLE_WCAST_FUNCTION_TYPE -#include -DISABLE_WCAST_FUNCTION_TYPE_END - -#include "pkcs11/pkcs11.h" - -using namespace v8; -using namespace node; - -class WPKCS11 : public node::ObjectWrap { -public: - static v8::Local NewInstance() { - v8::Local cons = Nan::New(constructor()); - return Nan::NewInstance(cons).ToLocalChecked(); - } - static v8::Local NewInstance(int argc, v8::Local argv[]) { - v8::Local cons = Nan::New(constructor()); - return Nan::NewInstance(cons, argc, argv).ToLocalChecked(); - } - - static NAN_MODULE_INIT(Init); - - static NAN_PROPERTY_GETTER(GetLibPath); - - static NAN_METHOD(New); - static NAN_METHOD(Load); - static NAN_METHOD(Close); - - // PKCS11 - static NAN_METHOD(C_Initialize); - static NAN_METHOD(C_Finalize); - static NAN_METHOD(C_GetInfo); - static NAN_METHOD(C_GetSlotList); - static NAN_METHOD(C_GetSlotInfo); - static NAN_METHOD(C_GetTokenInfo); - static NAN_METHOD(C_GetMechanismList); - static NAN_METHOD(C_GetMechanismInfo); - static NAN_METHOD(C_InitToken); - static NAN_METHOD(C_InitPIN); - static NAN_METHOD(C_SetPIN); - static NAN_METHOD(C_OpenSession); - static NAN_METHOD(C_CloseSession); - static NAN_METHOD(C_CloseAllSessions); - static NAN_METHOD(C_GetSessionInfo); - // static NAN_METHOD(C_GetOperationState); - // static NAN_METHOD(C_SetOperationState); - static NAN_METHOD(C_Login); - static NAN_METHOD(C_Logout); - - ///* Object management */ - static NAN_METHOD(C_CreateObject); - static NAN_METHOD(C_CopyObject); - static NAN_METHOD(C_DestroyObject); - static NAN_METHOD(C_GetObjectSize); - static NAN_METHOD(C_FindObjectsInit); - static NAN_METHOD(C_FindObjects); - static NAN_METHOD(C_FindObjectsFinal); - static NAN_METHOD(C_GetAttributeValue); - static NAN_METHOD(C_SetAttributeValue); - - ///* Encryption and decryption */ - static NAN_METHOD(C_EncryptInit); - static NAN_METHOD(C_Encrypt); - static NAN_METHOD(C_EncryptUpdate); - static NAN_METHOD(C_EncryptFinal); - static NAN_METHOD(C_DecryptInit); - static NAN_METHOD(C_Decrypt); - static NAN_METHOD(C_DecryptUpdate); - static NAN_METHOD(C_DecryptFinal); - - ///* Message digesting */ - static NAN_METHOD(C_DigestInit); - static NAN_METHOD(C_Digest); - static NAN_METHOD(C_DigestUpdate); - static NAN_METHOD(C_DigestFinal); - static NAN_METHOD(C_DigestKey); - - ///* Signing and MACing */ - static NAN_METHOD(C_SignInit); - static NAN_METHOD(C_Sign); - static NAN_METHOD(C_SignUpdate); - static NAN_METHOD(C_SignFinal); - static NAN_METHOD(C_SignRecoverInit); - static NAN_METHOD(C_SignRecover); - - /* Verifying signatures and MACs */ - static NAN_METHOD(C_VerifyInit); - static NAN_METHOD(C_Verify); - static NAN_METHOD(C_VerifyUpdate); - static NAN_METHOD(C_VerifyFinal); - static NAN_METHOD(C_VerifyRecoverInit); - static NAN_METHOD(C_VerifyRecover); - - /* Key management */ - static NAN_METHOD(C_GenerateKey); - static NAN_METHOD(C_GenerateKeyPair); - static NAN_METHOD(C_WrapKey); - static NAN_METHOD(C_UnwrapKey); - static NAN_METHOD(C_DeriveKey); - - /* Random number generation */ - static NAN_METHOD(C_SeedRandom); - static NAN_METHOD(C_GenerateRandom); - - /* Event slot function */ - static NAN_METHOD(C_WaitForSlotEvent); - - Scoped pkcs11; - -protected: - - static inline Nan::Persistent & constructor() { - static Nan::Persistent my_constructor; - return my_constructor; - } -}; \ No newline at end of file diff --git a/src/params.cpp b/src/params.cpp new file mode 100644 index 0000000..e60b67a --- /dev/null +++ b/src/params.cpp @@ -0,0 +1,406 @@ +/** + * @file params.cpp + * @brief This file contains functions for reading and retrieving mechanism parameters. + */ +#include "common.h" + +/** + * @brief Macro for throwing a type error if a property of a mechanism parameter is not of the expected type. + * + * @param property The name of the property. + * @param paramType The type of the mechanism parameter. + * @param type The name of the mechanism parameter type. + */ +#define THROW_PROPERTY_TYPE(property, paramType, type) \ + THROW_TYPE_ERRORF(false, "Property '%s' of %s mechanism parameter should be %s", property, paramType, type); + +/** + * Checks if the given object has a specified property. + * + * @param env The N-API environment. + * @param object The N-API value representing the object to check. + * @param property The name of the property to check for. + * @return True if the object has the specified property, false otherwise. + */ +bool has_property(napi_env env, napi_value object, const char *property) +{ + napi_value propertyValue; + napi_get_named_property(env, object, property, &propertyValue); + return !is_empty(env, propertyValue); +} + +/** + * @brief Reads an unsigned long property from a given JavaScript object. + * + * @param env The N-API environment. + * @param object The JavaScript object to read the property from. + * @param property The name of the property to read. + * @param value A pointer to store the read value. + * @return Returns true if the property was successfully read, false otherwise. + */ +bool read_property_ulong(napi_env env, napi_value object, const char *property, CK_ULONG *value) +{ + // Get the property value + napi_value propertyValue; + napi_get_named_property(env, object, property, &propertyValue); + + // Check that the property value is a number + napi_valuetype propertyValueType; + napi_typeof(env, propertyValue, &propertyValueType); + if (propertyValueType != napi_number) + { + return false; + } + + // Read the property value + double doubleValue; + napi_get_value_double(env, propertyValue, &doubleValue); + *value = (CK_ULONG)doubleValue; + + return true; +} + +/** + * @brief Macro for reading a required unsigned long property from a given JavaScript object. + * + * Creates a variable with the name of the property and reads the property value into it. + * + * @param property The name of the property to read. + * @param target The JavaScript object to read the property from. + * @param paramType The type of the mechanism parameter. + */ +#define READ_ULONG_REQUIRED(property, target, paramType) \ + CK_ULONG property = 0; \ + if (!read_property_ulong(env, target, #property, &property)) \ + { \ + THROW_PROPERTY_TYPE(#property, #paramType, "Number"); \ + } + +/** + * @brief Macro for reading an optional unsigned long property from a given JavaScript object. + * + * Creates a variable with the name of the property and reads the property value into it + * if the property exists, otherwise the variable is set to 0. + * + * @param property The name of the property to read. + * @param target The JavaScript object to read the property from. + * @param paramType The type of the mechanism parameter. + */ +#define READ_ULONG_OPTIONAL(property, target, paramType) \ + CK_ULONG property = 0; \ + if (has_property(env, target, #property)) \ + { \ + if (!read_property_ulong(env, target, #property, &property)) \ + { \ + THROW_PROPERTY_TYPE(#property, #paramType, "Number"); \ + } \ + } + +/** + * @brief Reads a byte array property from a given JavaScript object. + * + * @param env The N-API environment. + * @param object The JavaScript object to read the property from. + * @param property The name of the property to read. + * @param value A pointer to store the read value. + * @param length A pointer to store the length of the read value. + * @return Returns true if the property was successfully read, false otherwise. + */ +bool read_property_bytes(napi_env env, napi_value object, const char *property, CK_BYTE_PTR *value, CK_ULONG_PTR length) +{ + // Get the property value + napi_value propertyValue; + napi_get_named_property(env, object, property, &propertyValue); + + // Check that the property value is a buffer + bool isBuffer; + napi_is_buffer(env, propertyValue, &isBuffer); + if (!isBuffer) + { + return false; + } + + // Read the property value + void *data; + size_t dataLength; + napi_get_buffer_info(env, propertyValue, &data, &dataLength); + *value = (CK_BYTE_PTR)data; + *length = dataLength; + + return true; +} + +/** + * @brief Macro for reading a required byte array property from a given JavaScript object. + * + * Creates two variables with the name of the property and reads the property value into them + * (one for the data and one for the length Length). + * + * @param property The name of the property to read. + * @param target The JavaScript object to read the property from. + * @param paramType The type of the mechanism parameter. + */ +#define READ_BYTES_REQUIRED(property, target, paramType) \ + CK_BYTE_PTR property; \ + CK_ULONG property##Length; \ + if (!read_property_bytes(env, target, #property, &property, &property##Length)) \ + { \ + THROW_PROPERTY_TYPE(#property, #paramType, "Buffer"); \ + } + +/** + * @brief Macro for reading an optional byte array property from a given JavaScript object. + * + * Creates two variables with the name of the property and reads the property value into them + * (one for the data and one for the length Length). If the property does + * not exist, the variables are set to nullptr and 0 respectively. + * + * @param property The name of the property to read. + * @param target The JavaScript object to read the property from. + * @param paramType The type of the mechanism parameter. + */ +#define READ_BYTES_OPTIONAL(property, target, paramType) \ + CK_BYTE_PTR property = nullptr; \ + CK_ULONG property##Length = 0; \ + if (has_property(env, target, #property)) \ + { \ + if (!read_property_bytes(env, target, #property, &property, &property##Length)) \ + { \ + THROW_PROPERTY_TYPE(#property, #paramType, "Buffer"); \ + } \ + } + +/** + * Reads CK_RSA_PKCS_OAEP_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_rsa_oaep( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_ULONG_REQUIRED(hashAlg, mechanismParameter, CK_RSA_PKCS_OAEP_PARAMS); + READ_ULONG_REQUIRED(mgf, mechanismParameter, CK_RSA_PKCS_OAEP_PARAMS); + READ_ULONG_REQUIRED(source, mechanismParameter, CK_RSA_PKCS_OAEP_PARAMS); + READ_BYTES_OPTIONAL(sourceData, mechanismParameter, CK_RSA_PKCS_OAEP_PARAMS); + + // Create the mechanism parameters structure + CK_RSA_PKCS_OAEP_PARAMS_PTR params = CK_RSA_PKCS_OAEP_PARAMS_PTR(malloc(sizeof(CK_RSA_PKCS_OAEP_PARAMS))); + params->hashAlg = hashAlg; + params->mgf = mgf; + params->source = source; + params->pSourceData = sourceData; + params->ulSourceDataLen = sourceDataLength; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS); + + return true; +} + +/** + * Reads CK_ECDH1_DERIVE_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_ec_dh( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_ULONG_REQUIRED(kdf, mechanismParameter, CK_ECDH1_DERIVE_PARAMS); + READ_BYTES_REQUIRED(publicData, mechanismParameter, CK_ECDH1_DERIVE_PARAMS); + READ_BYTES_OPTIONAL(sharedData, mechanismParameter, CK_ECDH1_DERIVE_PARAMS); + + // Create the mechanism parameters structure + CK_ECDH1_DERIVE_PARAMS_PTR params = CK_ECDH1_DERIVE_PARAMS_PTR(malloc(sizeof(CK_ECDH1_DERIVE_PARAMS))); + params->kdf = kdf; + params->pSharedData = sharedData; + params->ulSharedDataLen = sharedDataLength; + params->pPublicData = publicData; + params->ulPublicDataLen = publicDataLength; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); + + return true; +} + +/** + * Reads CK_AES_CBC_ENCRYPT_DATA_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_aes_cbc( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_BYTES_REQUIRED(iv, mechanismParameter, CK_AES_CBC_ENCRYPT_DATA_PARAMS); + READ_BYTES_OPTIONAL(data, mechanismParameter, CK_AES_CBC_ENCRYPT_DATA_PARAMS); + if (ivLength != 16) + { + THROW_TYPE_ERRORF(false, "Property 'iv' of %s mechanism parameter should be a Buffer of length 16", "CK_AES_CBC_ENCRYPT_DATA_PARAMS"); + } + + // Create the mechanism parameters structure + CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR params = CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR(malloc(sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))); + memcpy(params->iv, iv, 16); + params->pData = data; + params->length = dataLength; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS); + + return true; +} + +/** + * Reads CK_AES_CCM_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_aes_ccm( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_ULONG_REQUIRED(dataLength, mechanismParameter, CK_AES_CCM_PARAMS); + READ_BYTES_OPTIONAL(nonce, mechanismParameter, CK_AES_CCM_PARAMS); + READ_BYTES_OPTIONAL(aad, mechanismParameter, CK_AES_CCM_PARAMS); + READ_ULONG_OPTIONAL(macLength, mechanismParameter, CK_AES_CCM_PARAMS); + + // Create the mechanism parameters structure + CK_AES_CCM_PARAMS_PTR params = CK_AES_CCM_PARAMS_PTR(malloc(sizeof(CK_AES_CCM_PARAMS))); + params->ulDataLen = dataLength; + params->pNonce = nonce; + params->ulNonceLen = nonceLength; + params->pAAD = aad; + params->ulAADLen = aadLength; + params->ulMACLen = macLength; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_AES_CCM_PARAMS); + + return true; +} + +/** + * Reads CK_AES_GCM_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_aes_gcm( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_BYTES_REQUIRED(iv, mechanismParameter, CK_AES_GCM_PARAMS); + READ_BYTES_OPTIONAL(aad, mechanismParameter, CK_AES_GCM_PARAMS); + READ_ULONG_OPTIONAL(tagBits, mechanismParameter, CK_AES_GCM_PARAMS); + + // Create the mechanism parameters structure + CK_AES_GCM_PARAMS_PTR params = CK_AES_GCM_PARAMS_PTR(malloc(sizeof(CK_AES_GCM_PARAMS))); + params->pIv = iv; + params->ulIvLen = ivLength; + params->pAAD = aad; + params->ulAADLen = aadLength; + params->ulTagBits = tagBits; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_AES_GCM_PARAMS); + + return true; +} + +/** + * Reads CK_AES_GCM_240_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool get_params_aes_gcm_240( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_BYTES_REQUIRED(iv, mechanismParameter, CK_AES_GCM_240_PARAMS); + READ_ULONG_REQUIRED(ivBits, mechanismParameter, CK_AES_GCM_240_PARAMS); + READ_BYTES_OPTIONAL(aad, mechanismParameter, CK_AES_GCM_240_PARAMS); + READ_ULONG_OPTIONAL(tagBits, mechanismParameter, CK_AES_GCM_240_PARAMS); + + // Create the mechanism parameters structure + CK_AES_GCM_240_PARAMS_PTR params = CK_AES_GCM_240_PARAMS_PTR(malloc(sizeof(CK_AES_GCM_240_PARAMS))); + params->pIv = iv; + params->ulIvLen = ivLength; + params->ulIvBits = ivBits; + params->pAAD = aad; + params->ulAADLen = aadLength; + params->ulTagBits = tagBits; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_AES_GCM_240_PARAMS); + + return true; +} + +/** + * Reads CK_RSA_PKCS_PSS_PARAMS from a given JavaScript object. + * + * @param env The N-API environment. + * @param mechanismParameter The mechanism parameter value. + * @param mechanism The CK_MECHANISM_PTR structure to store the retrieved parameters. + * @return true if the parameters were successfully retrieved, false otherwise. + */ +bool ge_params_rsa_pss( + napi_env env, + napi_value mechanismParameter, + CK_MECHANISM_PTR mechanism) +{ + // Read the mechanism parameters + READ_ULONG_REQUIRED(hashAlg, mechanismParameter, CK_RSA_PKCS_PSS_PARAMS); + READ_ULONG_REQUIRED(mgf, mechanismParameter, CK_RSA_PKCS_PSS_PARAMS); + READ_ULONG_REQUIRED(saltLen, mechanismParameter, CK_RSA_PKCS_PSS_PARAMS); + + // Create the mechanism parameters structure + CK_RSA_PKCS_PSS_PARAMS_PTR params = CK_RSA_PKCS_PSS_PARAMS_PTR(malloc(sizeof(CK_RSA_PKCS_PSS_PARAMS))); + params->hashAlg = hashAlg; + params->mgf = mgf; + params->sLen = saltLen; + + // Set the mechanism parameters + mechanism->pParameter = params; + mechanism->ulParameterLen = sizeof(CK_RSA_PKCS_PSS_PARAMS); + + return true; +} diff --git a/src/pkcs11.cpp b/src/pkcs11.cpp new file mode 100644 index 0000000..9654dba --- /dev/null +++ b/src/pkcs11.cpp @@ -0,0 +1,2506 @@ +/** + * @file pkcs11.cpp + * @brief Implementation of PKCS11 functions. + * + * This file contains the implementation of various PKCS11 functions. + */ +#include "common.h" + +#include "params.cpp" +#include "worker.cpp" + +napi_ref constructorRef; + +/** + * @brief Creates a PKCS11 version object from a CK_VERSION structure. + * + * @param env The N-API environment. + * @param version The CK_VERSION structure representing the version. + * @return The PKCS11 version object. + */ +napi_value create_version(napi_env env, CK_VERSION version) +{ + // { major: number, minor: number } + napi_value jsVersion; + napi_create_object(env, &jsVersion); + + // major + napi_value major; + napi_create_uint32(env, version.major, &major); + napi_set_named_property(env, jsVersion, "major", major); + + // minor + napi_value minor; + napi_create_uint32(env, version.minor, &minor); + napi_set_named_property(env, jsVersion, "minor", minor); + + return jsVersion; +} + +/** + * @brief Creates a PKCS11 date object from a utcTime string of the format YYYYMMDDhhmmssZ. + * + * @param env The N-API environment. + * @param utcTime A pointer to the UTC time string. + */ +napi_value create_date_utc_property(napi_env env, CK_UTF8CHAR_PTR utcTime) +{ + // create string from utcTime + napi_value utcTimeValue; + napi_create_string_utf8(env, (char *)utcTime, 16, &utcTimeValue); + + // create Date object from utcTime + napi_value utcTimeConstructor; + napi_get_global(env, &utcTimeConstructor); + napi_get_named_property(env, utcTimeConstructor, "Date", &utcTimeConstructor); + + // Date(utcTime) + napi_value utcTimeArgs[1]; + utcTimeArgs[0] = utcTimeValue; + napi_value utcTimeDate; + napi_new_instance(env, utcTimeConstructor, 1, utcTimeArgs, &utcTimeDate); + + return utcTimeDate; +} + +/** + * @brief A macro that checks if a given index is within the range of the argument list size. + * + * If the index is out of range, it throws a type error indicating that the argument at the specified + * index is required. + * + * @param index The index to check. + */ +#define ASSERT_ARGS_INDEX(index) \ + if (argc <= index) \ + { \ + THROW_TYPE_ERRORF(false, "Argument %lu is required", index); \ + } + +/** + * @brief Retrieves an unsigned long argument from a given index in the argument list. + * + * @param env The N-API environment. + * @param arg The argument list. + * @param argc The number of arguments in the list. + * @param index The index of the argument to retrieve. + * @param value Pointer to store the retrieved unsigned long value. + * @return Returns true if the argument was successfully retrieved, false otherwise. + */ +bool get_args_ulong(napi_env env, napi_value *arg, size_t argc, size_t index, CK_ULONG *value) +{ + ASSERT_ARGS_INDEX(index); + + // check type + if (!is_number(env, arg[index])) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Should be a Number", index); + } + + // get value + uint32_t temp; + napi_get_value_uint32(env, arg[index], &temp); + + // set value + *value = temp; + + return true; +} + +/** + * @brief A macro that retrieves an unsigned long integer from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param value The variable to store the retrieved value. + */ +#define GET_ARGS_ULONG(index, value) \ + CK_ULONG value; \ + if (!get_args_ulong(env, &arg[0], argc, index, &value)) \ + { \ + return nullptr; \ + } + +/** + * @brief Retrieves the buffer from the specified argument at the given index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param data A pointer to store the address of the buffer. + * @param length A pointer to store the length of the buffer. + * @return true if the buffer was successfully retrieved, false otherwise. + */ +bool get_args_buffer(napi_env env, napi_value *arg, size_t argc, size_t index, void **data, size_t *length) +{ + ASSERT_ARGS_INDEX(index); + + // check type + bool isBuffer; + napi_is_buffer(env, arg[index], &isBuffer); + if (!isBuffer) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Should be a Buffer", index); + } + + // get buffer info + napi_get_buffer_info(env, arg[index], data, length); + + return true; +} + +/** + * @brief A macro that retrieves a buffer from the argument list at a specified index. + * + * It creates two variables, one for the buffer address () and one for the buffer + * length (Length). + * + * @param index The index of the argument to retrieve. + * @param data The variable to store the retrieved buffer address. + */ +#define GET_ARGS_BUFFER(index, data) \ + void *data; \ + size_t data##Length; \ + if (!get_args_buffer(env, &arg[0], argc, index, &data, &data##Length)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the handle object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param handle A pointer to store the retrieved handle. + * @return true if the handle was successfully retrieved, false otherwise. + */ +bool get_args_handle(napi_env env, napi_value *arg, size_t argc, size_t index, CK_ULONG *handle) +{ + // check type + void *data; + size_t length; + if (!get_args_buffer(env, arg, argc, index, &data, &length)) + { + return false; + } + + // check length + if (length != sizeof(CK_ULONG)) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong length. Should be %lu bytes.", index, sizeof(CK_ULONG)); + } + + // set value + *handle = *(CK_OBJECT_HANDLE *)data; + + return true; +} + +/** + * @brief A macro that retrieves a handle from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param handle The variable to store the retrieved handle. + */ +#define GET_ARGS_HANDLE(index, handle) \ + CK_ULONG handle; \ + if (!get_args_handle(env, &arg[0], argc, index, &handle)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the slot ID object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param slotId A pointer to store the retrieved slot ID. + * @return true if the slot ID was successfully retrieved, false otherwise. + */ +bool get_args_slot_id(napi_env env, napi_value *arg, size_t argc, size_t index, CK_SLOT_ID *slotId) +{ + // check type + CK_ULONG handle; + if (!get_args_handle(env, arg, argc, index, &handle)) + { + return false; + } + + // set value + *slotId = (CK_SLOT_ID)handle; + + return true; +} + +/** + * @brief A macro that retrieves a slot ID from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param slotId The variable to store the retrieved slot ID. + */ +#define GET_ARGS_SLOT_ID(index, slotId) \ + CK_SLOT_ID slotId; \ + if (!get_args_slot_id(env, &arg[0], argc, index, &slotId)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the session handle object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param mechanismType A pointer to store the retrieved session handle. + * @return true if the session handle was successfully retrieved, false otherwise. + */ +bool get_args_mechanism_type(napi_env env, napi_value *arg, size_t argc, size_t index, CK_MECHANISM_TYPE *mechanismType) +{ + // check type + CK_ULONG handle; + if (!get_args_ulong(env, arg, argc, index, &handle)) + { + return false; + } + + *mechanismType = (CK_MECHANISM_TYPE)handle; + + return true; +} + +/** + * @brief A macro that retrieves a mechanism type from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param mechanismType The variable to store the retrieved mechanism type. + */ +#define GET_ARGS_MECHANISM_TYPE(index, mechanismType) \ + CK_MECHANISM_TYPE mechanismType; \ + if (!get_args_mechanism_type(env, &arg[0], argc, index, &mechanismType)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the mechanism object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param sessionHandle A pointer to store the retrieved mechanism. + * @return true if the mechanism was successfully retrieved, false otherwise. + */ +bool get_args_session_handle(napi_env env, napi_value *arg, size_t argc, size_t index, CK_SESSION_HANDLE *sessionHandle) +{ + // get handle + CK_ULONG handle; + if (!get_args_handle(env, arg, argc, index, &handle)) + { + return false; + } + + // set value + *sessionHandle = (CK_SESSION_HANDLE)handle; + + return true; +} + +/** + * @brief A macro that retrieves a session handle from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param sessionHandle The variable to store the retrieved session handle. + */ +#define GET_ARGS_SESSION_HANDLE(index, sessionHandle) \ + CK_SESSION_HANDLE sessionHandle; \ + if (!get_args_session_handle(env, &arg[0], argc, index, &sessionHandle)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the mechanism object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param string A pointer to store the retrieved mechanism. + * @param stringSize The size of the string buffer. + * @param length A pointer to store the length of the string. + * @return true if the mechanism was successfully retrieved, false otherwise. + */ +bool get_args_string(napi_env env, napi_value *arg, size_t argc, size_t index, char *string, size_t stringSize, size_t *length) +{ + ASSERT_ARGS_INDEX(index); + + napi_valuetype type; + napi_typeof(env, arg[index], &type); + if (type != napi_string) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Should be a String", index); + } + + // get value + napi_get_value_string_utf8(env, arg[index], nullptr, 0, length); + if (*length != 0 && string != nullptr) + { + napi_get_value_string_utf8(env, arg[index], string, stringSize, length); + } + + return true; +} + +/** + * @brief A macro that retrieves a string from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param string The variable to store the retrieved string. + */ +#define GET_ARGS_STRING(index, string) \ + size_t string##Length; \ + if (!get_args_string(env, &arg[0], argc, index, nullptr, 0, &string##Length)) \ + { \ + return nullptr; \ + } \ + char string[string##Length + 1]; \ + if (!get_args_string(env, &arg[0], argc, index, string, string##Length + 1, &string##Length)) \ + { \ + return nullptr; \ + } + +bool get_args_mechanism(napi_env env, napi_value *arg, size_t argc, size_t index, CK_MECHANISM *mechanism) +{ + ASSERT_ARGS_INDEX(index); + + // check type + napi_valuetype type; + napi_typeof(env, arg[index], &type); + if (type != napi_object) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Should be an Object", index); + } + + // get mechanism type + napi_value mechanismTypeValue; + napi_get_named_property(env, arg[index], "mechanism", &mechanismTypeValue); + napi_valuetype mechanismTypeValueType; + napi_typeof(env, mechanismTypeValue, &mechanismTypeValueType); + if (mechanismTypeValueType != napi_number) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Property 'mechanism' should be a Number", index); + } + + // get mechanism parameter + napi_value mechanismParameter; + napi_get_named_property(env, arg[index], "parameter", &mechanismParameter); + napi_valuetype mechanismParameterType; + napi_typeof(env, mechanismParameter, &mechanismParameterType); + bool mechanismParameterIsBuffer = false; + napi_is_buffer(env, mechanismParameter, &mechanismParameterIsBuffer); + if (mechanismParameterType != napi_undefined && // undefined + mechanismParameterType != napi_null && // null + mechanismParameterType != napi_object && // Object + !mechanismParameterIsBuffer) // Buffer + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Property 'parameter' should be an Object or Buffer", index); + } + + // set mechanism + CK_MECHANISM_TYPE mechanismType; + uint32_t temp; + napi_get_value_uint32(env, mechanismTypeValue, &temp); + mechanismType = (CK_MECHANISM_TYPE)temp; + mechanism->mechanism = mechanismType; + + // set mechanism parameter + if (mechanismParameterIsBuffer) + { + // Buffer + void *data; + size_t length; + napi_get_buffer_info(env, mechanismParameter, &data, &length); + mechanism->pParameter = malloc(sizeof(CK_BYTE) * length); + memcpy(mechanism->pParameter, data, length); + mechanism->ulParameterLen = length; + } + else if (mechanismParameterType == napi_object) + { + // Object + napi_value typeValue; + napi_get_named_property(env, mechanismParameter, "type", &typeValue); + if (!is_number(env, typeValue)) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Property 'type' should be a Number", index); + } + + uint32_t type; + napi_get_value_uint32(env, typeValue, &type); + switch (type) + { + case CK_PARAMS_AES_CBC: + { + return get_params_aes_cbc(env, mechanismParameter, mechanism); + } + case CK_PARAMS_AES_CCM: + { + return get_params_aes_ccm(env, mechanismParameter, mechanism); + } + case CK_PARAMS_AES_GCM: + { + return get_params_aes_gcm(env, mechanismParameter, mechanism); + } + case CK_PARAMS_AES_GCM_v240: + { + return get_params_aes_gcm_240(env, mechanismParameter, mechanism); + } + case CK_PARAMS_RSA_PSS: + { + return ge_params_rsa_pss(env, mechanismParameter, mechanism); + } + case CK_PARAMS_RSA_OAEP: + { + return get_params_rsa_oaep(env, mechanismParameter, mechanism); + } + case CK_PARAMS_EC_DH: + { + return get_params_ec_dh(env, mechanismParameter, mechanism); + } + } + } + else + { + mechanism->pParameter = nullptr; + mechanism->ulParameterLen = 0; + } + + return true; +} + +/** + * @brief A macro that retrieves a mechanism from the argument list at a specified index. + * + * @param index The index of the argument to retrieve. + * @param mechanism The variable to store the retrieved mechanism. + */ +#define GET_ARGS_MECHANISM(index, mechanism) \ + MechanismWrapper mechanism; \ + if (!get_args_mechanism(env, &arg[0], argc, index, mechanism.value)) \ + { \ + return nullptr; \ + } + +/** + * @brief Get the attributes object from the argument list at a specified index. + * + * @param env The N-API environment. + * @param arg The array of N-API values representing the arguments. + * @param argc The number of arguments in the array. + * @param index The index of the argument to retrieve. + * @param attrs A pointer to store the retrieved attributes. If nullptr, only the length is retrieved. + * @param length A pointer to store the length of the attributes. + * @return true if the attributes were successfully retrieved, false otherwise. + */ +bool get_args_attributes(napi_env env, napi_value *arg, size_t argc, size_t index, AttributesWrapper *attrs, CK_ULONG *length) +{ + ASSERT_ARGS_INDEX(index); + + // check type + // { type: number, value?: number | boolean | string | Buffer }[] + bool isArray; + napi_is_array(env, arg[index], &isArray); + if (!isArray) + { + THROW_TYPE_ERRORF(false, "Argument %lu has wrong type. Should be an Array", index); + } + + // get length + napi_value array = arg[index]; + uint32_t arrayLength; + napi_get_array_length(env, array, &arrayLength); + if (attrs != nullptr && arrayLength != attrs->length) + { + THROW_TYPE_ERRORF(false, "Parameter 'attrs' has wrong length. Should be %lu.", attrs->length); + } + *length = arrayLength; + + if (attrs == nullptr) + { + // only length is required + return true; + } + + // get attributes + for (int i = 0; i < int(arrayLength); i++) + { + napi_value element; + napi_get_element(env, array, i, &element); + + // check element type + if (!is_object(env, element)) + { + THROW_TYPE_ERRORF(false, "Element %d has wrong type. Should be an Object", i); + } + + // type + napi_value typeValue; + napi_get_named_property(env, element, "type", &typeValue); + if (!is_number(env, typeValue)) + { + THROW_TYPE_ERRORF(false, "Element %d has wrong type. Property 'type' should be a Number", i); + } + + // value + napi_value valueValue; + napi_get_named_property(env, element, "value", &valueValue); + napi_valuetype valueValueType; + napi_typeof(env, valueValue, &valueValueType); + bool valueIsBuffer = false; + napi_is_buffer(env, valueValue, &valueIsBuffer); + if (valueValueType != napi_undefined && // undefined + valueValueType != napi_null && // null + valueValueType != napi_number && // Number + valueValueType != napi_boolean && // Boolean + valueValueType != napi_string && // String + !valueIsBuffer) // Buffer + { + THROW_TYPE_ERRORF(false, "Element %d has wrong type. Property 'value' should be a Number, Boolean, String or Buffer", i); + } + + CK_ATTRIBUTE_PTR attr = &attrs->attributes[i]; + + uint32_t type; + napi_get_value_uint32(env, typeValue, &type); + attr->type = (CK_ATTRIBUTE_TYPE)type; + + if (valueValueType == napi_number) + { + attrs->allocValue(i, sizeof(CK_ULONG)); + uint32_t value; + napi_get_value_uint32(env, valueValue, &value); + *(CK_ULONG *)attr->pValue = value; + } + else if (valueValueType == napi_boolean) + { + attrs->allocValue(i, sizeof(CK_BBOOL)); + bool value; + napi_get_value_bool(env, valueValue, &value); + *(CK_BBOOL *)attr->pValue = value ? CK_TRUE : CK_FALSE; + } + else if (valueValueType == napi_string) + { + size_t length; + napi_get_value_string_utf8(env, valueValue, nullptr, 0, &length); + attrs->allocValue(i, length + 1); + attrs->attributes[i].ulValueLen = length; // length without null terminator + napi_get_value_string_utf8(env, valueValue, (char *)attr->pValue, length + 1, &length); + } + else if (valueIsBuffer) + { + void *data; + size_t length; + napi_get_buffer_info(env, valueValue, &data, &length); + attrs->allocValue(i, length); + memcpy(attr->pValue, data, length); + } + } + + return true; +} + +/** + * @brief A macro that retrieves attributes from the argument list at a specified index. + * + * It creates two variables, one for the attributes () and one for the attributes + * length (Length). + * + * @param index The index of the argument to retrieve. + * @param attrs The variable to store the retrieved attributes. + */ +#define GET_ARGS_ATTRIBUTES(index, attrs) \ + CK_ULONG attrs##Length; \ + if (!get_args_attributes(env, &arg[0], argc, index, nullptr, &attrs##Length)) \ + { \ + return nullptr; \ + } \ + AttributesWrapper attrs(attrs##Length); \ + if (!get_args_attributes(env, &arg[0], argc, index, &attrs, &attrs##Length)) \ + { \ + return nullptr; \ + } + +#define GET_ARGS_CALLBACK(index, callback) \ + napi_value callback = arg[index]; \ + if (!is_function(env, callback)) \ + { \ + THROW_TYPE_ERRORF(nullptr, "Argument %lu has wrong type. Should be a Function", index); \ + } + +/** + * @brief Get a list of arguments from the function call. + * + * @param env The N-API environment. + * @param info The N-API callback info. + * @param argc The number of arguments to retrieve. + * @param arg A pointer to store the retrieved arguments. + * @return true if the arguments were successfully retrieved, false otherwise. + */ +bool get_args(napi_env env, napi_callback_info info, size_t argc, napi_value *arg) +{ + napi_value jsthis; + size_t length = 0; + napi_get_cb_info(env, info, &length, nullptr, &jsthis, nullptr); + if (length != argc) + { + THROW_TYPE_ERRORF(false, "Parameters are required. Expected %lu arguments, but received %lu.", argc, length); + } + + napi_get_cb_info(env, info, &length, arg, &jsthis, nullptr); + + return true; +} + +/** + * @brief A macro that retrieves a list of arguments from the function call. + * + * @param expectedArgc The number of arguments to retrieve. + * @param args The variable to store the retrieved arguments. + */ +#define GET_ARGS(expectedArgc, args) \ + size_t argc = expectedArgc; \ + napi_value args[argc]; \ + if (!get_args(env, info, argc, args)) \ + { \ + return nullptr; \ + } + +/** + * @brief A macro that checks if the CK_RV is CKR_OK and throws an error if not. + * + * @param rv The CK_RV to check. + */ +#define ASSERT_RV(rv) \ + if (rv != CKR_OK) \ + { \ + throw_rv_error(env, rv); \ + return nullptr; \ + } + +/** + * @brief A macro that unwraps the PKCS11 object from the function call. + */ +#define UNWRAP_PKCS11() \ + napi_value jsthis; \ + napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr); \ + Pkcs11 *pkcs11; \ + napi_unwrap(env, jsthis, (void **)&pkcs11); \ + if (pkcs11->handle == nullptr) \ + { \ + napi_throw_error(env, nullptr, "PKCS11 module not loaded yet"); \ + return nullptr; \ + } + +class Pkcs11 +{ +public: + void *handle; + CK_FUNCTION_LIST_PTR functionList; + + Pkcs11() : handle(nullptr), functionList(nullptr) {} + + ~Pkcs11() + { + if (handle != nullptr) + { + dlclose(handle); + handle = nullptr; + } + } + + static napi_value Constructor(napi_env env, napi_callback_info info) + { + napi_value target; + napi_get_new_target(env, info, &target); + + bool isConstructor = target != nullptr; + + if (isConstructor) + { + napi_value jsthis; + napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr); + + Pkcs11 *pkcs11 = new Pkcs11(); + napi_wrap(env, jsthis, pkcs11, Pkcs11::Destructor, nullptr, nullptr); + + return jsthis; + } + else + { + napi_value cons; + napi_get_reference_value(env, constructorRef, &cons); + + napi_value instance; + napi_new_instance(env, cons, 0, nullptr, &instance); + + return instance; + } + } + + static void Destructor(napi_env env, void *nativeObject, void *finalize_hint) + { + Pkcs11 *pkcs11 = static_cast(nativeObject); + pkcs11->~Pkcs11(); + } + + /** + * @brief Loads the PKCS11 module. + * + * @param env The N-API environment. + * @param info The N-API callback info. + * @return The loaded PKCS11 module. + */ + static napi_value Load(napi_env env, napi_callback_info info) + { + napi_value jsthis; + napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr); + + Pkcs11 *pkcs11; + napi_unwrap(env, jsthis, (void **)&pkcs11); + + size_t argc = 1; + napi_value arg[1]; + napi_get_cb_info(env, info, &argc, arg, nullptr, nullptr); + + size_t length; + napi_get_value_string_utf8(env, arg[0], nullptr, 0, &length); + + char path[length + 1]; + napi_get_value_string_utf8(env, arg[0], path, length + 1, &length); + + pkcs11->handle = dlopen(path, RTLD_NOW); + if (pkcs11->handle == nullptr) + { + napi_throw_error(env, nullptr, dlerror()); + return nullptr; + } + + CK_C_GetFunctionList pC_GetFunctionList = (CK_C_GetFunctionList)dlsym(pkcs11->handle, "C_GetFunctionList"); + if (pC_GetFunctionList == nullptr) + { + napi_throw_error(env, nullptr, dlerror()); + return nullptr; + } + + CK_RV rv = pC_GetFunctionList(&pkcs11->functionList); + ASSERT_RV(rv); + + return nullptr; + } + + /** + * @brief Closes the PKCS11 module. + * + * @param env The N-API environment. + * @param info The N-API callback info. + * @return Nothing. + */ + static napi_value Close(napi_env env, napi_callback_info info) + { + napi_value jsthis; + napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr); + + Pkcs11 *pkcs11; + napi_unwrap(env, jsthis, (void **)&pkcs11); + + if (pkcs11->handle != nullptr) + { + dlclose(pkcs11->handle); + pkcs11->handle = nullptr; + } + + return nullptr; + } + + static napi_value C_Initialize(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + + // Read arguments + size_t argc = 1; + napi_value arg[1]; + napi_get_cb_info(env, info, &argc, arg, nullptr, nullptr); + + CK_VOID_PTR pInitArgs = nullptr; + CK_NSS_C_INITIALIZE_ARGS nssInitArgs = {nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr}; + CK_C_INITIALIZE_ARGS initArgs = {nullptr, nullptr, nullptr, nullptr, 0, nullptr}; + char *path = nullptr; + if (argc > 0 && !is_empty(env, arg[0])) + { + napi_valuetype type; + napi_typeof(env, arg[0], &type); + + if (type != napi_object) + { + THROW_TYPE_ERRORF(nullptr, "Argument %lu has wrong type. Should be an Object", 0); + } + + // Read common C_Initialize args + napi_value flags; + napi_get_named_property(env, arg[0], "flags", &flags); + uint32_t ckFlags; + napi_get_value_uint32(env, flags, &ckFlags); + + bool hasLibraryParameters; + napi_has_named_property(env, arg[0], "libraryParameters", &hasLibraryParameters); + if (hasLibraryParameters) + { + // Read NSS C_Initialize args + napi_value libraryParameters; + napi_get_named_property(env, arg[0], "libraryParameters", &libraryParameters); + napi_valuetype type; + napi_typeof(env, libraryParameters, &type); + + if (type != napi_string) + { + THROW_TYPE_ERRORF(nullptr, "Argument %lu has wrong type. Property 'libraryParameters' should be a String", 0); + } + + size_t length; + napi_get_value_string_utf8(env, libraryParameters, nullptr, 0, &length); + + path = new char[length + 1]; + napi_get_value_string_utf8(env, libraryParameters, path, length + 1, &length); + + nssInitArgs.LibraryParameters = (CK_CHAR_PTR)path; + nssInitArgs.flags = (CK_FLAGS)ckFlags; + + pInitArgs = &nssInitArgs; + } + else + { + // Read common C_Initialize args + initArgs.flags = (CK_FLAGS)ckFlags; + + pInitArgs = &initArgs; + } + } + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Initialize(pInitArgs); + if (path != nullptr) + { + delete[] path; + } + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Finalize(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Finalize(nullptr); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_GetInfo(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + + // Call PKCS11 function + CK_INFO ckInfo; + CK_RV rv = pkcs11->functionList->C_GetInfo(&ckInfo); + ASSERT_RV(rv); + + // Create result object + napi_value result; + napi_create_object(env, &result); + + napi_value cryptokiVersion = create_version(env, ckInfo.cryptokiVersion); + napi_set_named_property(env, result, "cryptokiVersion", cryptokiVersion); + + napi_value manufacturerID; + napi_create_string_utf8(env, (char *)&ckInfo.manufacturerID[0], sizeof(ckInfo.manufacturerID), &manufacturerID); + napi_set_named_property(env, result, "manufacturerID", manufacturerID); + + napi_value flags; + napi_create_uint32(env, ckInfo.flags, &flags); + napi_set_named_property(env, result, "flags", flags); + + napi_value libraryDescription; + napi_create_string_utf8(env, (char *)&ckInfo.libraryDescription[0], sizeof(ckInfo.libraryDescription), &libraryDescription); + napi_set_named_property(env, result, "libraryDescription", libraryDescription); + + napi_value libraryVersion = create_version(env, ckInfo.libraryVersion); + napi_set_named_property(env, result, "libraryVersion", libraryVersion); + + return result; + } + + static napi_value C_GetSlotList(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + + // Read arguments + CK_BBOOL ckTokenPresent = CK_FALSE; + size_t argc = 1; + napi_value arg[1]; + napi_get_cb_info(env, info, &argc, arg, nullptr, nullptr); + if (argc > 0) + { + napi_valuetype type; + napi_typeof(env, arg[0], &type); + + if (type != napi_boolean) + { + THROW_TYPE_ERRORF(nullptr, "Argument %lu has wrong type. Should be a Boolean", 0); + } + + bool temp; + napi_get_value_bool(env, arg[0], &temp); + ckTokenPresent = temp; + } + + // Call PKCS11 function + CK_ULONG slotCount; + CK_RV rv = pkcs11->functionList->C_GetSlotList(ckTokenPresent, nullptr, &slotCount); // get slot count + ASSERT_RV(rv); + + CK_SLOT_ID slotList[slotCount]; + rv = pkcs11->functionList->C_GetSlotList(ckTokenPresent, slotList, &slotCount); + ASSERT_RV(rv); + + // Create result array + napi_value result; + napi_create_array(env, &result); + for (int i = 0; i < int(slotCount); i++) + { + napi_value slotId; + napi_create_buffer_copy(env, sizeof(slotList[i]), &slotList[i], nullptr, &slotId); + napi_set_element(env, result, i, slotId); + } + + return result; + } + + static napi_value C_GetSlotInfo(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + + // Call PKCS11 function + CK_SLOT_INFO ckSlotInfo; + CK_RV rv = pkcs11->functionList->C_GetSlotInfo(slotId, &ckSlotInfo); + ASSERT_RV(rv); + + // Create result object + napi_value result; + napi_create_object(env, &result); + + napi_value slotDescription; + napi_create_string_utf8(env, (char *)&ckSlotInfo.slotDescription[0], sizeof(ckSlotInfo.slotDescription), &slotDescription); + napi_set_named_property(env, result, "slotDescription", slotDescription); + + napi_value manufacturerID; + napi_create_string_utf8(env, (char *)&ckSlotInfo.manufacturerID[0], sizeof(ckSlotInfo.manufacturerID), &manufacturerID); + napi_set_named_property(env, result, "manufacturerID", manufacturerID); + + napi_value flags; + napi_create_uint32(env, ckSlotInfo.flags, &flags); + napi_set_named_property(env, result, "flags", flags); + + napi_value hardwareVersion = create_version(env, ckSlotInfo.hardwareVersion); + napi_set_named_property(env, result, "hardwareVersion", hardwareVersion); + + napi_value firmwareVersion = create_version(env, ckSlotInfo.firmwareVersion); + napi_set_named_property(env, result, "firmwareVersion", firmwareVersion); + + return result; + } + + static napi_value C_GetTokenInfo(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + + // Call PKCS11 function + CK_TOKEN_INFO ckTokenInfo; + CK_RV rv = pkcs11->functionList->C_GetTokenInfo(slotId, &ckTokenInfo); + ASSERT_RV(rv); + + // Create result object + napi_value result; + napi_create_object(env, &result); + + // label + napi_value label; + napi_create_string_utf8(env, (char *)&ckTokenInfo.label[0], sizeof(ckTokenInfo.label), &label); + napi_set_named_property(env, result, "label", label); + + // manufacturerID + napi_value manufacturerID; + napi_create_string_utf8(env, (char *)&ckTokenInfo.manufacturerID[0], sizeof(ckTokenInfo.manufacturerID), &manufacturerID); + napi_set_named_property(env, result, "manufacturerID", manufacturerID); + + // model + napi_value model; + napi_create_string_utf8(env, (char *)&ckTokenInfo.model[0], sizeof(ckTokenInfo.model), &model); + napi_set_named_property(env, result, "model", model); + + // serialNumber + napi_value serialNumber; + napi_create_string_utf8(env, (char *)&ckTokenInfo.serialNumber[0], sizeof(ckTokenInfo.serialNumber), &serialNumber); + napi_set_named_property(env, result, "serialNumber", serialNumber); + + // flags + napi_value flags; + napi_create_uint32(env, ckTokenInfo.flags, &flags); + napi_set_named_property(env, result, "flags", flags); + + // maxSessionCount + napi_value ulMaxSessionCount; + napi_create_uint32(env, ckTokenInfo.ulMaxSessionCount, &ulMaxSessionCount); + napi_set_named_property(env, result, "maxSessionCount", ulMaxSessionCount); + + // sessionCount + napi_value ulSessionCount; + napi_create_uint32(env, ckTokenInfo.ulSessionCount, &ulSessionCount); + napi_set_named_property(env, result, "sessionCount", ulSessionCount); + + // maxRwSessionCount + napi_value ulMaxRwSessionCount; + napi_create_uint32(env, ckTokenInfo.ulMaxRwSessionCount, &ulMaxRwSessionCount); + napi_set_named_property(env, result, "maxRwSessionCount", ulMaxRwSessionCount); + + // rwSessionCount + napi_value ulRwSessionCount; + napi_create_uint32(env, ckTokenInfo.ulRwSessionCount, &ulRwSessionCount); + napi_set_named_property(env, result, "rwSessionCount", ulRwSessionCount); + + // maxPinLen + napi_value ulMaxPinLen; + napi_create_uint32(env, ckTokenInfo.ulMaxPinLen, &ulMaxPinLen); + napi_set_named_property(env, result, "maxPinLen", ulMaxPinLen); + + // minPinLen + napi_value ulMinPinLen; + napi_create_uint32(env, ckTokenInfo.ulMinPinLen, &ulMinPinLen); + napi_set_named_property(env, result, "minPinLen", ulMinPinLen); + + // hardwareVersion + napi_value hardwareVersion = create_version(env, ckTokenInfo.hardwareVersion); + napi_set_named_property(env, result, "hardwareVersion", hardwareVersion); + + // firmwareVersion + napi_value firmwareVersion = create_version(env, ckTokenInfo.firmwareVersion); + napi_set_named_property(env, result, "firmwareVersion", firmwareVersion); + + // utcTime + napi_value utcTime = create_date_utc_property(env, ckTokenInfo.utcTime); + napi_set_named_property(env, result, "utcTime", utcTime); + + // totalPublicMemory + napi_value totalPublicMemory; + napi_create_bigint_uint64(env, ckTokenInfo.ulTotalPublicMemory, &totalPublicMemory); + napi_set_named_property(env, result, "totalPublicMemory", totalPublicMemory); + + // freePublicMemory + napi_value freePublicMemory; + napi_create_bigint_uint64(env, ckTokenInfo.ulFreePublicMemory, &freePublicMemory); + napi_set_named_property(env, result, "freePublicMemory", freePublicMemory); + + // totalPrivateMemory + napi_value totalPrivateMemory; + napi_create_bigint_uint64(env, ckTokenInfo.ulTotalPrivateMemory, &totalPrivateMemory); + napi_set_named_property(env, result, "totalPrivateMemory", totalPrivateMemory); + + // freePrivateMemory + napi_value freePrivateMemory; + napi_create_bigint_uint64(env, ckTokenInfo.ulFreePrivateMemory, &freePrivateMemory); + napi_set_named_property(env, result, "freePrivateMemory", freePrivateMemory); + + return result; + } + + static napi_value C_GetMechanismList(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + + // Call PKCS11 function + CK_ULONG mechanismCount; + CK_RV rv = pkcs11->functionList->C_GetMechanismList(slotId, nullptr, &mechanismCount); // get mechanism count + ASSERT_RV(rv); + + CK_MECHANISM_TYPE mechanismList[mechanismCount]; + rv = pkcs11->functionList->C_GetMechanismList(slotId, mechanismList, &mechanismCount); + ASSERT_RV(rv); + + // Create result array + napi_value result; + napi_create_array(env, &result); + for (int i = 0; i < int(mechanismCount); i++) + { + napi_value mechanism; + napi_create_uint32(env, mechanismList[i], &mechanism); + napi_set_element(env, result, i, mechanism); + } + + return result; + } + + static napi_value C_GetMechanismInfo(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + GET_ARGS_MECHANISM_TYPE(1, mechanismType) + + // Call PKCS11 function + CK_MECHANISM_INFO ckMechanismInfo; + CK_RV rv = pkcs11->functionList->C_GetMechanismInfo(slotId, mechanismType, &ckMechanismInfo); + ASSERT_RV(rv); + + // Create result object + napi_value result; + napi_create_object(env, &result); + + napi_value minKeySize; + napi_create_uint32(env, ckMechanismInfo.ulMinKeySize, &minKeySize); + napi_set_named_property(env, result, "minKeySize", minKeySize); + + napi_value maxKeySize; + napi_create_uint32(env, ckMechanismInfo.ulMaxKeySize, &maxKeySize); + napi_set_named_property(env, result, "maxKeySize", maxKeySize); + + napi_value flags; + napi_create_uint32(env, ckMechanismInfo.flags, &flags); + napi_set_named_property(env, result, "flags", flags); + + return result; + } + + static napi_value C_InitToken(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + GET_ARGS_STRING(1, pin) + GET_ARGS_STRING(2, label) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_InitToken(slotId, (CK_UTF8CHAR_PTR)pin, (CK_ULONG)pinLength, (CK_UTF8CHAR_PTR)label); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_InitPIN(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_STRING(1, pin) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_InitPIN(sessionHandle, (CK_UTF8CHAR_PTR)pin, (CK_ULONG)pinLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_SetPIN(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_STRING(1, oldPin) + GET_ARGS_STRING(2, newPin) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SetPIN( + sessionHandle, + (CK_UTF8CHAR_PTR)oldPin, (CK_ULONG)oldPinLength, + (CK_UTF8CHAR_PTR)newPin, (CK_ULONG)newPinLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_OpenSession(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + GET_ARGS_ULONG(1, flags) + // GET_FUNCTION_FROM_ARG(2, callback) + + // Call PKCS11 function + CK_SESSION_HANDLE sessionHandle; + CK_RV rv = pkcs11->functionList->C_OpenSession(slotId, (CK_FLAGS)flags, nullptr, nullptr, &sessionHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(sessionHandle), &sessionHandle, nullptr, &result); + + return result; + } + + static napi_value C_CloseSession(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_CloseSession(sessionHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_CloseAllSessions(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SLOT_ID(0, slotId) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_CloseAllSessions(slotId); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_GetSessionInfo(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + + // Call PKCS11 function + CK_SESSION_INFO ckSessionInfo; + CK_RV rv = pkcs11->functionList->C_GetSessionInfo(sessionHandle, &ckSessionInfo); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_object(env, &result); + + napi_value slotID; + napi_create_buffer_copy(env, sizeof(ckSessionInfo.slotID), &ckSessionInfo.slotID, nullptr, &slotID); + napi_set_named_property(env, result, "slotID", slotID); + + napi_value state; + napi_create_uint32(env, ckSessionInfo.state, &state); + napi_set_named_property(env, result, "state", state); + + napi_value flags; + napi_create_uint32(env, ckSessionInfo.flags, &flags); + napi_set_named_property(env, result, "flags", flags); + + napi_value ulDeviceError; + napi_create_uint32(env, ckSessionInfo.ulDeviceError, &ulDeviceError); + napi_set_named_property(env, result, "deviceError", ulDeviceError); + + return result; + } + + static napi_value C_GetOperationState(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + + // Call PKCS11 function + CK_ULONG stateLength; + CK_RV rv = pkcs11->functionList->C_GetOperationState(sessionHandle, nullptr, &stateLength); // get state length + ASSERT_RV(rv); + + CK_BYTE state[stateLength]; + rv = pkcs11->functionList->C_GetOperationState(sessionHandle, state, &stateLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, stateLength, state, nullptr, &result); + + return result; + } + + static napi_value C_SetOperationState(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, state) + GET_ARGS_HANDLE(2, encryptionKeyHandle) + GET_ARGS_HANDLE(3, authenticationKeyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SetOperationState( + sessionHandle, + (CK_BYTE_PTR)state, (CK_ULONG)stateLength, + (CK_OBJECT_HANDLE)encryptionKeyHandle, + (CK_OBJECT_HANDLE)authenticationKeyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Login(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_ULONG(1, userType) + GET_ARGS_STRING(2, pin) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Login(sessionHandle, (CK_USER_TYPE)userType, (CK_UTF8CHAR_PTR)pin, (CK_ULONG)pinLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Logout(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Logout(sessionHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_SeedRandom(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, seed) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SeedRandom(sessionHandle, (CK_BYTE_PTR)seed, (CK_ULONG)seedLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_GenerateRandom(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, randomData) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_GenerateRandom(sessionHandle, (CK_BYTE_PTR)randomData, (CK_ULONG)randomDataLength); + ASSERT_RV(rv); + + return arg[1]; + } + + static napi_value C_CreateObject(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_ATTRIBUTES(1, attrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE objectHandle; + CK_RV rv = pkcs11->functionList->C_CreateObject(sessionHandle, attrs.attributes, attrsLength, &objectHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(objectHandle), &objectHandle, nullptr, &result); + + return result; + } + + static napi_value C_FindObjectsInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_ATTRIBUTES(1, attrs) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_FindObjectsInit(sessionHandle, attrs.attributes, attrsLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_FindObjects(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_ULONG(1, maxObjectCount) + + // Call PKCS11 function + CK_ULONG objectCount; + CK_OBJECT_HANDLE objectHandles[maxObjectCount]; + CK_RV rv = pkcs11->functionList->C_FindObjects(sessionHandle, objectHandles, maxObjectCount, &objectCount); + ASSERT_RV(rv); + + // Create result array + napi_value result; + napi_create_array(env, &result); + for (int i = 0; i < int(objectCount); i++) + { + napi_value objectHandle; + napi_create_buffer_copy(env, sizeof(objectHandles[i]), &objectHandles[i], nullptr, &objectHandle); + napi_set_element(env, result, i, objectHandle); + } + + return result; + } + + static napi_value C_FindObjectsFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(1, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_FindObjectsFinal(sessionHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_CopyObject(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, objectHandle) + GET_ARGS_ATTRIBUTES(2, attrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE newObjectHandle; + CK_RV rv = pkcs11->functionList->C_CopyObject( + sessionHandle, + objectHandle, + attrs.attributes, attrsLength, + &newObjectHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(newObjectHandle), &newObjectHandle, nullptr, &result); + + return result; + } + + static napi_value C_DestroyObject(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, objectHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DestroyObject(sessionHandle, objectHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_GetAttributeValue(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, objectHandle) + GET_ARGS_ATTRIBUTES(2, attrs) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_GetAttributeValue(sessionHandle, objectHandle, attrs.attributes, attrsLength); + ASSERT_RV(rv); + + attrs.allocAllValues(); + + rv = pkcs11->functionList->C_GetAttributeValue(sessionHandle, objectHandle, attrs.attributes, attrsLength); + ASSERT_RV(rv); + + // Create result array + napi_value result = arg[2]; + for (int i = 0; i < int(attrsLength); i++) + { + CK_ATTRIBUTE *attr = &attrs.attributes[i]; + napi_value jsAttr; + napi_get_element(env, arg[2], i, &jsAttr); + + napi_value value; + if (attr->ulValueLen == CK_UNAVAILABLE_INFORMATION) + { + // use undefined for unavailable information + napi_get_undefined(env, &value); + } + else + { + // copy value to Buffer + napi_create_buffer_copy(env, (size_t)attr->ulValueLen, (void *)attr->pValue, nullptr, &value); + } + + napi_set_named_property(env, jsAttr, "value", value); + } + + return result; + } + + static napi_value C_SetAttributeValue(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, objectHandle) + GET_ARGS_ATTRIBUTES(2, attrs) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SetAttributeValue(sessionHandle, objectHandle, attrs.attributes, attrsLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_GetObjectSize(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, objectHandle) + + // Call PKCS11 function + CK_ULONG objectSize; + CK_RV rv = pkcs11->functionList->C_GetObjectSize(sessionHandle, objectHandle, &objectSize); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, objectSize, &result); + + return result; + } + + static napi_value C_DigestInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DigestInit(sessionHandle, mechanism.value); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Digest(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, digest) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Digest(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)digest, (CK_ULONG_PTR)&digestLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, digestLength, &result); + + return result; + } + + static napi_value C_DigestCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, digest) + GET_ARGS_CALLBACK(3, callback) + + // Create worker + new Worker(env, callback, pkcs11->functionList->C_Digest, sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)digest, (CK_ULONG)digestLength); + return nullptr; + } + + static napi_value C_DigestUpdate(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DigestUpdate(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_DigestKey(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_HANDLE(1, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DigestKey(sessionHandle, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_DigestFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, digest) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DigestFinal(sessionHandle, (CK_BYTE_PTR)digest, (CK_ULONG_PTR)&digestLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, digestLength, &result); + + return result; + } + + static napi_value C_DigestFinalCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, digest) + GET_ARGS_CALLBACK(2, callback) + + // Create worker + new Worker2(env, callback, pkcs11->functionList->C_DigestFinal, sessionHandle, (CK_BYTE_PTR)digest, (CK_ULONG)digestLength); + return nullptr; + } + + static napi_value C_GenerateKey(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_ATTRIBUTES(2, attrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE keyHandle; + CK_RV rv = pkcs11->functionList->C_GenerateKey(sessionHandle, mechanism.value, attrs.attributes, attrsLength, &keyHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(keyHandle), &keyHandle, nullptr, &result); + + return result; + } + + static napi_value C_GenerateKeyCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + mechanism.dispose = false; + GET_ARGS_ATTRIBUTES(2, attrs) + attrs.dispose = false; + GET_ARGS_CALLBACK(3, callback) + + // Create worker + newWorkerGenerateKey(env, pkcs11->functionList->C_GenerateKey, callback, sessionHandle, mechanism.value, attrs.attributes, attrsLength); + return nullptr; + } + + static napi_value C_GenerateKeyPair(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_ATTRIBUTES(2, publicKeyAttrs) + GET_ARGS_ATTRIBUTES(3, privateKeyAttrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE publicKeyHandle; + CK_OBJECT_HANDLE privateKeyHandle; + CK_RV rv = pkcs11->functionList->C_GenerateKeyPair( + sessionHandle, + mechanism.value, + publicKeyAttrs.attributes, publicKeyAttrsLength, + privateKeyAttrs.attributes, privateKeyAttrsLength, + &publicKeyHandle, &privateKeyHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_object(env, &result); + + napi_value privateKey; + napi_create_buffer_copy(env, sizeof(privateKeyHandle), &privateKeyHandle, nullptr, &privateKey); + napi_set_named_property(env, result, "privateKey", privateKey); + + napi_value publicKey; + napi_create_buffer_copy(env, sizeof(publicKeyHandle), &publicKeyHandle, nullptr, &publicKey); + napi_set_named_property(env, result, "publicKey", publicKey); + + return result; + } + + static napi_value C_GenerateKeyPairCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(5, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + mechanism.dispose = false; + GET_ARGS_ATTRIBUTES(2, publicKeyAttrs) + publicKeyAttrs.dispose = false; + GET_ARGS_ATTRIBUTES(3, privateKeyAttrs) + privateKeyAttrs.dispose = false; + GET_ARGS_CALLBACK(4, callback) + + newWorkerGenerateKeyPair(env, pkcs11->functionList->C_GenerateKeyPair, callback, sessionHandle, mechanism.value, publicKeyAttrs.attributes, publicKeyAttrsLength, privateKeyAttrs.attributes, privateKeyAttrsLength); + return nullptr; + } + + static napi_value C_SignInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SignInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Sign(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, signature) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Sign(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)signature, (CK_ULONG_PTR)&signatureLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, signatureLength, &result); + + return result; + } + + static napi_value C_SignCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, signature) + GET_ARGS_CALLBACK(3, callback) + + // Create worker + new Worker(env, callback, pkcs11->functionList->C_Sign, sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + return nullptr; + } + + static napi_value C_SignUpdate(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SignUpdate(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_SignFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, signature) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SignFinal(sessionHandle, (CK_BYTE_PTR)signature, (CK_ULONG_PTR)&signatureLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, signatureLength, &result); + + return result; + } + + static napi_value C_SignFinalCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, signature) + GET_ARGS_CALLBACK(2, callback) + + // Create worker + new Worker2(env, callback, pkcs11->functionList->C_SignFinal, sessionHandle, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + return nullptr; + } + + static napi_value C_VerifyInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_VerifyInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Verify(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, signature) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Verify(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_get_boolean(env, true, &result); + + return result; + } + + static napi_value C_VerifyCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, signature) + GET_ARGS_CALLBACK(3, callback) + + // Create worker + new WorkerVerify(env, callback, pkcs11->functionList->C_Verify, sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + return nullptr; + } + + static napi_value C_VerifyUpdate(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_VerifyUpdate(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_VerifyFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, signature) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_VerifyFinal(sessionHandle, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_get_boolean(env, true, &result); + + return result; + } + + static napi_value C_VerifyFinalCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, signature) + GET_ARGS_CALLBACK(2, callback) + + // Create worker + new WorkerVerifyFinal(env, callback, pkcs11->functionList->C_VerifyFinal, sessionHandle, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength); + return nullptr; + } + + static napi_value C_EncryptInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_EncryptInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Encrypt(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, encryptedData) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Encrypt(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)encryptedData, (CK_ULONG_PTR)&encryptedDataLength); + ASSERT_RV(rv); + + // Create result (size of encryptedData) + napi_value result; + napi_create_uint32(env, encryptedDataLength, &result); + + return result; + } + + static napi_value C_EncryptCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, encryptedData) + GET_ARGS_CALLBACK(3, callback) + + new Worker(env, callback, pkcs11->functionList->C_Encrypt, sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)encryptedData, (CK_ULONG)encryptedDataLength); + return nullptr; + } + + static napi_value C_EncryptUpdate(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, encryptedData) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_EncryptUpdate(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)encryptedData, (CK_ULONG_PTR)&encryptedDataLength); + ASSERT_RV(rv); + + // Create result (size of encryptedData) + napi_value result; + napi_create_uint32(env, encryptedDataLength, &result); + + return result; + } + + static napi_value C_EncryptFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, encryptedData) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_EncryptFinal(sessionHandle, (CK_BYTE_PTR)encryptedData, (CK_ULONG_PTR)&encryptedDataLength); + ASSERT_RV(rv); + + // Create result (size of encryptedData) + napi_value result; + napi_create_uint32(env, encryptedDataLength, &result); + + return result; + } + + static napi_value C_EncryptFinalCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, encryptedData) + GET_ARGS_CALLBACK(2, callback) + + // Create worker + new Worker2(env, callback, pkcs11->functionList->C_EncryptFinal, sessionHandle, (CK_BYTE_PTR)encryptedData, (CK_ULONG)encryptedDataLength); + return nullptr; + } + + static napi_value C_DecryptInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DecryptInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_Decrypt(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, encryptedData) + GET_ARGS_BUFFER(2, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_Decrypt(sessionHandle, (CK_BYTE_PTR)encryptedData, (CK_ULONG)encryptedDataLength, (CK_BYTE_PTR)data, (CK_ULONG_PTR)&dataLength); + ASSERT_RV(rv); + + // Create result (size of data) + napi_value result; + napi_create_uint32(env, dataLength, &result); + + return result; + } + + static napi_value C_DecryptCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, encryptedData) + GET_ARGS_BUFFER(2, data) + GET_ARGS_CALLBACK(3, callback) + + // Create worker + new Worker(env, callback, pkcs11->functionList->C_Decrypt, sessionHandle, (CK_BYTE_PTR)encryptedData, (CK_ULONG)encryptedDataLength, (CK_BYTE_PTR)data, (CK_ULONG)dataLength); + return nullptr; + } + + static napi_value C_DecryptUpdate(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, encryptedData) + GET_ARGS_BUFFER(2, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DecryptUpdate(sessionHandle, (CK_BYTE_PTR)encryptedData, (CK_ULONG)encryptedDataLength, (CK_BYTE_PTR)data, (CK_ULONG_PTR)&dataLength); + ASSERT_RV(rv); + + // Create result (size of data) + napi_value result; + napi_create_uint32(env, dataLength, &result); + + return result; + } + + static napi_value C_DecryptFinal(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(2, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_DecryptFinal(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG_PTR)&dataLength); + ASSERT_RV(rv); + + // Create result (size of data) + napi_value result; + napi_create_uint32(env, dataLength, &result); + + return result; + } + + static napi_value C_DecryptFinalCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_CALLBACK(2, callback) + + // Create worker + new Worker2(env, arg[2], pkcs11->functionList->C_DecryptFinal, sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength); + return nullptr; + } + + static napi_value C_DeriveKey(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(4, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, baseKeyHandle) + GET_ARGS_ATTRIBUTES(3, attrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE keyHandle; + CK_RV rv = pkcs11->functionList->C_DeriveKey(sessionHandle, mechanism.value, baseKeyHandle, attrs.attributes, attrsLength, &keyHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(keyHandle), &keyHandle, nullptr, &result); + + return result; + } + + static napi_value C_DeriveKeyCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(5, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + mechanism.dispose = false; + GET_ARGS_HANDLE(2, baseKeyHandle) + GET_ARGS_ATTRIBUTES(3, attrs) + attrs.dispose = false; + GET_ARGS_CALLBACK(4, callback) + + // Create worker + newWorkerDeriveKey(env, pkcs11->functionList->C_DeriveKey, callback, sessionHandle, mechanism.value, baseKeyHandle, attrs.attributes, attrsLength); + return nullptr; + } + + static napi_value C_WrapKey(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(5, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, wrappingKeyHandle) + GET_ARGS_HANDLE(3, keyHandle) + GET_ARGS_BUFFER(4, wrappedKey) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_WrapKey(sessionHandle, mechanism.value, wrappingKeyHandle, keyHandle, (CK_BYTE_PTR)wrappedKey, (CK_ULONG_PTR)&wrappedKeyLength); + ASSERT_RV(rv); + + // Create result (size of wrappedKey) + napi_value result; + napi_create_uint32(env, wrappedKeyLength, &result); + + return result; + } + + static napi_value C_WrapKeyCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(6, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + mechanism.dispose = false; + GET_ARGS_HANDLE(2, wrappingKeyHandle) + GET_ARGS_HANDLE(3, keyHandle) + GET_ARGS_BUFFER(4, wrappedKey) + GET_ARGS_CALLBACK(5, callback) + + // Create worker + newWorkerWrapKey(env, pkcs11->functionList->C_WrapKey, callback, sessionHandle, mechanism.value, wrappingKeyHandle, keyHandle, (CK_BYTE_PTR)wrappedKey, (CK_ULONG)wrappedKeyLength); + return nullptr; + } + + static napi_value C_UnwrapKey(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(5, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, unwrappingKeyHandle) + GET_ARGS_BUFFER(3, wrappedKey) + GET_ARGS_ATTRIBUTES(4, attrs) + + // Call PKCS11 function + CK_OBJECT_HANDLE keyHandle; + CK_RV rv = pkcs11->functionList->C_UnwrapKey(sessionHandle, mechanism.value, unwrappingKeyHandle, (CK_BYTE_PTR)wrappedKey, (CK_ULONG)wrappedKeyLength, attrs.attributes, attrsLength, &keyHandle); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_buffer_copy(env, sizeof(keyHandle), &keyHandle, nullptr, &result); + + return result; + } + + static napi_value C_UnwrapKeyCallback(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(6, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + mechanism.dispose = false; + GET_ARGS_HANDLE(2, unwrappingKeyHandle) + GET_ARGS_BUFFER(3, wrappedKey) + GET_ARGS_ATTRIBUTES(4, attrs) + attrs.dispose = false; + GET_ARGS_CALLBACK(5, callback) + + // Create worker + newWorkerUnwrapKey(env, pkcs11->functionList->C_UnwrapKey, callback, sessionHandle, mechanism.value, unwrappingKeyHandle, (CK_BYTE_PTR)wrappedKey, (CK_ULONG)wrappedKeyLength, attrs.attributes, attrsLength); + return nullptr; + } + + static napi_value C_SignRecoverInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SignRecoverInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_SignRecover(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, data) + GET_ARGS_BUFFER(2, signature) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_SignRecover(sessionHandle, (CK_BYTE_PTR)data, (CK_ULONG)dataLength, (CK_BYTE_PTR)signature, (CK_ULONG_PTR)&signatureLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, signatureLength, &result); + + return result; + } + + static napi_value C_VerifyRecoverInit(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_MECHANISM(1, mechanism) + GET_ARGS_HANDLE(2, keyHandle) + + CK_RV rv = pkcs11->functionList->C_VerifyRecoverInit(sessionHandle, mechanism.value, keyHandle); + ASSERT_RV(rv); + + return nullptr; + } + + static napi_value C_VerifyRecover(napi_env env, napi_callback_info info) + { + UNWRAP_PKCS11(); + GET_ARGS(3, arg) + + // Read arguments + GET_ARGS_SESSION_HANDLE(0, sessionHandle) + GET_ARGS_BUFFER(1, signature) + GET_ARGS_BUFFER(2, data) + + // Call PKCS11 function + CK_RV rv = pkcs11->functionList->C_VerifyRecover(sessionHandle, (CK_BYTE_PTR)signature, (CK_ULONG)signatureLength, (CK_BYTE_PTR)data, (CK_ULONG_PTR)&dataLength); + ASSERT_RV(rv); + + // Create result + napi_value result; + napi_create_uint32(env, dataLength, &result); + + return result; + } +}; diff --git a/src/pkcs11/core.h b/src/pkcs11/core.h deleted file mode 100644 index 727db76..0000000 --- a/src/pkcs11/core.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_CORE -#define INCLUDE_H_PKCS11_CORE - -#define GET_BUFFER_SMPL(varName, v8Object) \ - char* varName = node::Buffer::Data(v8Object); \ - auto varName##Len = node::Buffer::Length(v8Object); - -#define GET_BUFFER_ARGS(varName, argIndex) \ - GET_BUFFER_SMPL(varName, info[argIndex]); - -#endif // INCLUDE_H_PKCS11_CORE \ No newline at end of file diff --git a/src/pkcs11/error.cpp b/src/pkcs11/error.cpp deleted file mode 100644 index f693609..0000000 --- a/src/pkcs11/error.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "error.h" - -Scoped Error::ToString() { - Scoped res(new string("")); - *res += *message; - *res += *Stack(); - return res; -} - -Scoped Error::Stack() { - Scoped res(new string("")); - - *res += string("\n"); - *res += string(" at Error (native) "); - *res += *function; - *res += string(":"); - *res += to_string(line); - if (stack.get()) { - *res += *stack->Stack(); - } - return res; -} \ No newline at end of file diff --git a/src/pkcs11/error.h b/src/pkcs11/error.h deleted file mode 100644 index d9ce71b..0000000 --- a/src/pkcs11/error.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_ERROR -#define INCLUDE_H_PKCS11_ERROR - -#include - -#include "scope.h" - -using namespace std; - -class Error { -protected: - Scoped stack; - Scoped function; - int line; - Scoped Stack(); - -public: - Scoped message; - Error(const char* msg, Scoped stack, const char* function, int line) : - stack(stack), - function(new string(function)), - line(line), - message(Scoped(new string(msg))) - {}; - Error(Scoped msg, Scoped stack, const char* function, int line) : - stack(stack), - function(new string(function)), - line(line), - message(msg) - {}; - ~Error() {}; - Scoped ToString(); -}; - -#define THROW_ERROR(msg, stack) \ - throw Scoped(new Error(msg, stack, __FUNCTION__, __LINE__)) - -#define CATCH_ERROR \ - catch (Scoped e) { throw std::move(e); } \ - catch (...) { THROW_ERROR("Unknown error", NULL); } - -#endif // INCLUDE_H_PKCS11_ERROR diff --git a/src/pkcs11/mech.cpp b/src/pkcs11/mech.cpp deleted file mode 100644 index 5ad3bdf..0000000 --- a/src/pkcs11/mech.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "mech.h" - -Mechanism::Mechanism() { - New(); -} - -Mechanism::~Mechanism() { -} - -void Mechanism::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Object = Nan::To(v8Value).ToLocalChecked(); - - Local v8MechType = Nan::Get(v8Object, Nan::New(STR_MECHANISM).ToLocalChecked()).ToLocalChecked(); - if (!v8MechType->IsNumber()) { - THROW_ERROR("Attribute 'mechanism' MUST be Number", NULL); - } - - Local v8Parameter = Nan::Get(v8Object, Nan::New(STR_PARAMETER).ToLocalChecked()).ToLocalChecked(); - if (!(v8Parameter->IsUndefined() || v8Parameter->IsNull() || node::Buffer::HasInstance(v8Parameter) || v8Parameter->IsObject())) { - THROW_ERROR("Attribute 'parameter' MUST be Null | Buffer | Object", NULL); - } - - New(); - - data.mechanism = Nan::To(v8MechType).FromJust(); - if (!(v8Parameter->IsUndefined() || v8Parameter->IsNull())) { - Local v8Param = Nan::To(v8Parameter).ToLocalChecked(); - if (!node::Buffer::HasInstance(v8Param)) { - // Parameter is Object - Local v8Type = Nan::Get(v8Param, Nan::New(STR_TYPE).ToLocalChecked()).ToLocalChecked(); - CK_ULONG type = v8Type->IsNumber() ? Nan::To(v8Type).FromJust() : 0; - switch (type) { - case CK_PARAMS_EC_DH: { - param = Scoped(new ParamEcdh1); - break; - } - case CK_PARAMS_AES_CBC: { - param = Scoped(new ParamAesCBC); - break; - } - case CK_PARAMS_AES_GCM: { - param = Scoped(new ParamAesGCM); - break; - } - case CK_PARAMS_AES_GCM_v240: { - param = Scoped(new ParamAesGCMv240); - break; - } - case CK_PARAMS_AES_CCM: { - param = Scoped(new ParamAesCCM); - break; - } - case CK_PARAMS_RSA_OAEP: { - param = Scoped(new ParamRsaOAEP); - break; - } - case CK_PARAMS_RSA_PSS: { - param = Scoped(new ParamRsaPSS); - break; - } - default: - THROW_ERROR("Unknown type Mech param in use", NULL); - } - } - else { - // Parameter is buffer - param = Scoped(new ParamBuffer); - } - param->FromV8(v8Parameter); - data.pParameter = param->Get(); - data.ulParameterLen = param->GetSize(); - } - } - CATCH_ERROR; -} - -Local Mechanism::ToV8() { - Nan::EscapableHandleScope scope; - - try { - Local v8Mechanism = Nan::New(); - // Mechanism - Nan::Set(v8Mechanism, Nan::New(STR_MECHANISM).ToLocalChecked(), Nan::New(data.mechanism)); - - // Parameter - if (data.pParameter) { - Local v8Parameter = node::Buffer::Copy(Isolate::GetCurrent(), (char *)data.pParameter, data.ulParameterLen).ToLocalChecked(); - Nan::Set(v8Mechanism, Nan::New(STR_PARAMETER).ToLocalChecked(), v8Parameter); - } - else { - Nan::Set(v8Mechanism, Nan::New(STR_PARAMETER).ToLocalChecked(), Nan::Null()); - } - - return scope.Escape(v8Mechanism); - } - CATCH_ERROR; -} - -CK_MECHANISM_PTR Mechanism::New() { - param = NULL; - data = CK_MECHANISM(); - data.mechanism = 0; - data.pParameter = NULL; - data.ulParameterLen = 0; - return Get(); -} diff --git a/src/pkcs11/mech.h b/src/pkcs11/mech.h deleted file mode 100644 index aea9a63..0000000 --- a/src/pkcs11/mech.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_MECHANISM -#define INCLUDE_H_PKCS11_MECHANISM - -#include "core.h" -#include "v8_convert.h" -#include "param.h" - -class Mechanism : public V8Converter { -protected: - Scoped param; -public: - Mechanism(); - ~Mechanism(); - void FromV8(Local obj); - Local ToV8(); - CK_MECHANISM_PTR New(); -}; - -#endif // INCLUDE_H_PKCS11_MECHANISM diff --git a/src/pkcs11/param.cpp b/src/pkcs11/param.cpp deleted file mode 100644 index 00fd091..0000000 --- a/src/pkcs11/param.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "param.h" - -#define RELEASE_CHECK_PARAM(name) \ -bool check_param_##name(Local obj, const char* paramName) { \ - Nan::HandleScope scope; \ - Local v8Value = Nan::Get(obj, Nan::New(paramName).ToLocalChecked()).ToLocalChecked(); \ - return check_##name(v8Value); \ -} - -static bool check_buffer(Local obj) { - return node::Buffer::HasInstance(obj); -} -RELEASE_CHECK_PARAM(buffer); - -static bool check_number(Local obj) { - return obj->IsNumber(); -} -RELEASE_CHECK_PARAM(number); - -static bool check_empty(Local obj) { - return obj->IsUndefined() || obj->IsNull(); -} -RELEASE_CHECK_PARAM(empty); - -// ParamBuffer - -void ParamBuffer::FromV8(Local v8Obj) -{ - if (!node::Buffer::HasInstance(v8Obj)) { - THROW_ERROR("Cannot create ParamBuffer. Parameter must be of type Buffer", NULL); - } - char* pData = node::Buffer::Data(v8Obj); - size_t ulDataLen = node::Buffer::Length(v8Obj); - - param.resize(ulDataLen); - memcpy(param.data(), pData, ulDataLen); -} diff --git a/src/pkcs11/param.h b/src/pkcs11/param.h deleted file mode 100644 index 1865c52..0000000 --- a/src/pkcs11/param.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_PARAM -#define INCLUDE_H_PKCS11_PARAM - -#include "core.h" -#include "v8_convert.h" - -// HELPERS - -#define DECLARE_CHECK_PARAM(name) bool check_param_##name(Local obj, const char* paramName) - -DECLARE_CHECK_PARAM(buffer); -DECLARE_CHECK_PARAM(number); -DECLARE_CHECK_PARAM(empty); - -#undef DECLARE_CHECK_PARAM - -class ParamBase { -public: - const CK_ULONG type; - - ParamBase(CK_ULONG type) : type(type) { } - virtual ~ParamBase() { } - virtual void FromV8(Local v8Obj) {} - virtual void* Get() = 0; - virtual CK_ULONG GetSize() = 0; -protected: -}; - -template -class Param : public ParamBase { -public: - Param(CK_ULONG type) : ParamBase(type) { } - void* Get() override { return ¶m; } - virtual CK_ULONG GetSize() override { return sizeof(T); } -protected: - T param; -}; - -#define CK_PARAMS_BUFFER 0 -#define CK_PARAMS_AES_CBC 1 -#define CK_PARAMS_AES_CCM 2 -#define CK_PARAMS_AES_GCM 3 -#define CK_PARAMS_RSA_OAEP 4 -#define CK_PARAMS_RSA_PSS 5 -#define CK_PARAMS_EC_DH 6 -#define CK_PARAMS_AES_GCM_v240 7 - -class ParamBuffer : public ParamBase { -public: - ParamBuffer() : ParamBase(CK_PARAMS_BUFFER) {} - void* Get() { return param.data(); } - virtual CK_ULONG GetSize() { return (CK_ULONG)param.size(); } - void FromV8(Local v8Obj); -protected: - std::vector param; -}; - -// AES - -class ParamAesCBC : public Param { -public: - ParamAesCBC() : Param(CK_PARAMS_AES_CBC) { Init(); } - ~ParamAesCBC() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -class ParamAesCCM : public Param { -public: - ParamAesCCM() : Param(CK_PARAMS_AES_CCM) { Init(); } - ~ParamAesCCM() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -class ParamAesGCM : public Param { -public: - ParamAesGCM() : Param(CK_PARAMS_AES_GCM) { Init(); } - ~ParamAesGCM() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - - -class ParamAesGCMv240 : public Param { -public: - ParamAesGCMv240() : Param(CK_PARAMS_AES_GCM_v240) { Init(); } - ~ParamAesGCMv240() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -// RSA - -class ParamRsaOAEP : public Param { -public: - ParamRsaOAEP() : Param(CK_PARAMS_RSA_OAEP) { Init(); } - ~ParamRsaOAEP() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -class ParamRsaPSS : public Param { -public: - ParamRsaPSS() : Param(CK_PARAMS_RSA_PSS) { Init(); } - ~ParamRsaPSS() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -// ECC - -class ParamEcdh1 : public Param { -public: - ParamEcdh1() : Param(CK_PARAMS_EC_DH) { Init(); } - ~ParamEcdh1() { Free(); } - void FromV8(Local v8Obj) override; -protected: - void Init(); - void Free(); -}; - -#endif // INCLUDE_H_PKCS11_PARAM diff --git a/src/pkcs11/param_aes.cpp b/src/pkcs11/param_aes.cpp deleted file mode 100644 index 5e063cd..0000000 --- a/src/pkcs11/param_aes.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "param.h" - -// CBC ======================================================== - -void ParamAesCBC::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_buffer(v8Params, STR_IV)) - THROW_ERROR("Attribute 'iv' MUST be BUFFER", NULL); - if (!(check_param_empty(v8Params, STR_DATA) || check_param_buffer(v8Params, STR_DATA))) - THROW_ERROR("Attribute 'data' MUST be NULL | Buffer", NULL); - - Free(); - Init(); - - // Iv - v8::Local v8Iv =Nan::Get(v8Params, Nan::New(STR_IV).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(iv, Nan::To(v8Iv).ToLocalChecked()); - memcpy(param.iv, iv, ivLen); - - // Data? - if (!check_param_empty(v8Params, STR_DATA)) { - v8::Local v8Data = Nan::Get(v8Params, Nan::New(STR_DATA).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(aesData, Nan::To(v8Data).ToLocalChecked()); - param.pData = (CK_BYTE_PTR)malloc(aesDataLen* sizeof(CK_BYTE)); - memcpy(param.pData, aesData, aesDataLen); - param.length = (CK_ULONG)aesDataLen; - } - } - CATCH_ERROR; -} - -void ParamAesCBC::Init() { - param = CK_AES_CBC_ENCRYPT_DATA_PARAMS(); - param.pData = NULL; - param.length = 0; -} - -void ParamAesCBC::Free() { - if (param.pData) { - free(param.pData); - param.pData = NULL; - } -} - -// CCM ======================================================== - -void ParamAesCCM::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_DATA_LEN)) - THROW_ERROR("Attribute 'dataLen' MUST be NUMBER", NULL); - if (!(check_param_empty(v8Params, STR_NONCE) || check_param_buffer(v8Params, STR_NONCE))) - THROW_ERROR("Attribute 'nonce' MUST be NULL || BUFFER", NULL); - if (!(check_param_empty(v8Params, STR_AAD) || check_param_buffer(v8Params, STR_AAD))) - THROW_ERROR("Attribute 'aad' MUST be NULL || BUFFER", NULL); - if (!check_param_number(v8Params, STR_MAC_LEN)) - THROW_ERROR("Attribute 'macLen' MUST be NUMBER", NULL); - - Free(); - Init(); - - v8::Local v8DataLen = Nan::Get(v8Params, Nan::New(STR_DATA_LEN).ToLocalChecked()).ToLocalChecked(); - param.ulDataLen = Nan::To(v8DataLen).FromJust(); - v8::Local v8MacLen = Nan::Get(v8Params, Nan::New(STR_MAC_LEN).ToLocalChecked()).ToLocalChecked(); - param.ulMACLen = Nan::To(v8MacLen).FromJust(); - - if (!check_param_empty(v8Params,STR_NONCE)) { - v8::Local v8Nonce = Nan::Get(v8Params, Nan::New(STR_NONCE).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(nonce, Nan::To(v8Nonce).ToLocalChecked()); - param.pNonce = (CK_BYTE_PTR)malloc(nonceLen * sizeof(CK_BYTE)); - memcpy(param.pNonce, nonce, nonceLen); - param.ulNonceLen = (CK_ULONG)nonceLen; - } - - if (!check_param_empty(v8Params, STR_AAD)) { - v8::Local v8Aad = Nan::Get(v8Params, Nan::New(STR_AAD).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(aad, Nan::To(v8Aad).ToLocalChecked()); - param.pAAD = (CK_BYTE_PTR)malloc(aadLen * sizeof(CK_BYTE)); - memcpy(param.pAAD, aad, aadLen); - param.ulAADLen = (CK_ULONG)aadLen; - } - } - CATCH_ERROR; -} - -void ParamAesCCM::Init() { - param = CK_AES_CCM_PARAMS(); - param.ulDataLen = 0; - param.pNonce = NULL; - param.ulNonceLen = 0; - param.pAAD = NULL; - param.ulAADLen = 0; - param.ulMACLen = 0; -} - -void ParamAesCCM::Free() { - if (param.pNonce) { - free(param.pNonce); - param.pNonce = NULL; - } - if (param.pAAD) { - free(param.pAAD); - param.pAAD = NULL; - } - -} - -// GCM ======================================================== - -// v2.30 -void ParamAesGCM::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_TAG_BITS)) - THROW_ERROR("Attribute 'tagBits' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_IV_BITS)) - THROW_ERROR("Attribute 'ivBits' MUST be NUMBER", NULL); - if (!(check_param_empty(v8Params, STR_IV) || check_param_buffer(v8Params, STR_IV))) - THROW_ERROR("Attribute 'iv' MUST be NULL || BUFFER", NULL); - if (!(check_param_empty(v8Params, STR_AAD) || check_param_buffer(v8Params, STR_AAD))) - THROW_ERROR("Attribute 'aad' MUST be NULL || BUFFER", NULL); - - Free(); - Init(); - - v8::Local v8TagBits = Nan::Get(v8Params, Nan::New(STR_TAG_BITS).ToLocalChecked()).ToLocalChecked(); - param.ulTagBits = Nan::To(v8TagBits).FromJust(); - - if (!check_param_empty(v8Params, STR_IV)) { - v8::Local v8Iv = Nan::Get(v8Params, Nan::New(STR_IV).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(buffer, Nan::To(v8Iv).ToLocalChecked()); - param.pIv = (CK_BYTE_PTR)malloc(bufferLen * sizeof(CK_BYTE)); - memcpy(param.pIv, buffer, bufferLen); - param.ulIvLen = (CK_ULONG)bufferLen; - } - - if (!check_param_empty(v8Params, STR_AAD)) { - v8::Local v8Aad = Nan::Get(v8Params, Nan::New(STR_AAD).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(buffer, Nan::To(v8Aad).ToLocalChecked()); - param.pAAD = (CK_BYTE_PTR)malloc(bufferLen * sizeof(CK_BYTE)); - memcpy(param.pAAD, buffer, bufferLen); - param.ulAADLen = (CK_ULONG)bufferLen; - } - } - CATCH_ERROR; -} - -void ParamAesGCM::Init() { - param = CK_AES_GCM_PARAMS(); - param.pAAD = NULL; - param.ulAADLen = 0; - param.pIv = NULL; - param.ulIvLen = 0; - param.ulTagBits = 0; -} - -void ParamAesGCM::Free() { - if (param.pIv) { - free(param.pIv); - param.pIv = NULL; - } - if (param.pAAD) { - free(param.pAAD); - param.pAAD = NULL; - } -} - -// v2.30 - -void ParamAesGCMv240::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_TAG_BITS)) - THROW_ERROR("Attribute 'tagBits' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_IV_BITS)) - THROW_ERROR("Attribute 'ivBits' MUST be NUMBER", NULL); - if (!(check_param_empty(v8Params, STR_IV) || check_param_buffer(v8Params, STR_IV))) - THROW_ERROR("Attribute 'iv' MUST be NULL || BUFFER", NULL); - if (!(check_param_empty(v8Params, STR_AAD) || check_param_buffer(v8Params, STR_AAD))) - THROW_ERROR("Attribute 'aad' MUST be NULL || BUFFER", NULL); - - Free(); - Init(); - - v8::Local v8IvBits = Nan::Get(v8Params, Nan::New(STR_IV_BITS).ToLocalChecked()).ToLocalChecked(); - param.ulIvBits = Nan::To(v8IvBits).FromJust(); - v8::Local v8TagBits = Nan::Get(v8Params, Nan::New(STR_TAG_BITS).ToLocalChecked()).ToLocalChecked(); - param.ulTagBits = Nan::To(v8TagBits).FromJust(); - - if (!check_param_empty(v8Params, STR_IV)) { - v8::Local v8Iv = Nan::Get(v8Params, Nan::New(STR_IV).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(buffer, Nan::To(v8Iv).ToLocalChecked()); - param.pIv = (CK_BYTE_PTR)malloc(bufferLen * sizeof(CK_BYTE)); - memcpy(param.pIv, buffer, bufferLen); - param.ulIvLen = (CK_ULONG)bufferLen; - } - - if (!check_param_empty(v8Params, STR_AAD)) { - v8::Local v8Aad = Nan::Get(v8Params, Nan::New(STR_AAD).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(buffer, Nan::To(v8Aad).ToLocalChecked()); - param.pAAD = (CK_BYTE_PTR)malloc(bufferLen * sizeof(CK_BYTE)); - memcpy(param.pAAD, buffer, bufferLen); - param.ulAADLen = (CK_ULONG)bufferLen; - } - } - CATCH_ERROR; -} - -void ParamAesGCMv240::Init() { - param = CK_AES_GCM_240_PARAMS(); - param.pAAD = NULL; - param.ulAADLen = 0; - param.pIv = NULL; - param.ulIvLen = 0; - param.ulIvBits = 0; - param.ulTagBits = 0; -} - -void ParamAesGCMv240::Free() { - if (param.pIv) { - free(param.pIv); - param.pIv = NULL; - } - if (param.pAAD) { - free(param.pAAD); - param.pAAD = NULL; - } -} diff --git a/src/pkcs11/param_ecdh.cpp b/src/pkcs11/param_ecdh.cpp deleted file mode 100644 index b7ee589..0000000 --- a/src/pkcs11/param_ecdh.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "param.h" - -void ParamEcdh1::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_KDF)) - THROW_ERROR("Attribute 'kdf' MUST be NUMBER", NULL); - if (!(check_param_empty(v8Params, STR_SHARED_DATA) || check_param_buffer(v8Params, STR_SHARED_DATA))) - THROW_ERROR("Attribute 'sharedData' MUST be NULL | Buffer", NULL); - if (!check_param_buffer(v8Params, STR_PUBLIC_DATA)) - THROW_ERROR("Attribute 'publicData' MUST be Buffer", NULL); - - Free(); - Init(); - - v8::Local v8Kdf = Nan::Get(v8Params, Nan::New(STR_KDF).ToLocalChecked()).ToLocalChecked(); - param.kdf = Nan::To(v8Kdf).FromJust(); - - if (check_param_buffer(v8Params, STR_SHARED_DATA)) { - v8::Local v8SharedData = Nan::Get(v8Params, Nan::New(STR_SHARED_DATA).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(sharedData, Nan::To(v8SharedData).ToLocalChecked()); - param.pSharedData = (CK_BYTE_PTR)malloc(sharedDataLen * sizeof(CK_BYTE)); - memcpy(param.pSharedData, sharedData, sharedDataLen); - param.ulSharedDataLen = (CK_ULONG) sharedDataLen; - } - - v8::Local v8PublicData =Nan::Get(v8Params, Nan::New(STR_PUBLIC_DATA).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(publicData, Nan::To(v8PublicData).ToLocalChecked()); - param.pPublicData = (CK_BYTE_PTR)malloc(publicDataLen * sizeof(CK_BYTE)); - memcpy(param.pPublicData, publicData, publicDataLen); - param.ulPublicDataLen = (CK_ULONG) publicDataLen; - } - CATCH_ERROR; -} - -void ParamEcdh1::Init() { - param = CK_ECDH1_DERIVE_PARAMS(); - param.kdf = CKD_NULL; - param.pSharedData = NULL; - param.ulSharedDataLen = 0; - param.pPublicData = NULL; - param.ulPublicDataLen = 0; -} - -void ParamEcdh1::Free() { - if (param.pSharedData) { - free(param.pSharedData); - param.pSharedData = NULL; - } - if (param.pPublicData) { - free(param.pPublicData); - param.pPublicData = NULL; - } -} diff --git a/src/pkcs11/param_rsa.cpp b/src/pkcs11/param_rsa.cpp deleted file mode 100644 index 6d512a6..0000000 --- a/src/pkcs11/param_rsa.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "param.h" - -void ParamRsaOAEP::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_MGF)) - THROW_ERROR("Attribute 'mgf' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_SOURCE)) - THROW_ERROR("Attribute 'source' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_HASH_ALG)) - THROW_ERROR("Attribute 'hashAlg' MUST be NUMBER", NULL); - if (!(check_param_empty(v8Params, STR_SOURCE_DATA) || check_param_buffer(v8Params, STR_SOURCE_DATA))) - THROW_ERROR("Attribute 'sourceData' MUST be NULL || BUFFER", NULL); - - Free(); - Init(); - - v8::Local v8Source = Nan::Get(v8Params, Nan::New(STR_SOURCE).ToLocalChecked()).ToLocalChecked(); - param.source = Nan::To(v8Source).FromJust(); - v8::Local v8Mgf = Nan::Get(v8Params, Nan::New(STR_MGF).ToLocalChecked()).ToLocalChecked(); - param.mgf= Nan::To(v8Mgf).FromJust(); - v8::Local v8HashAlg = Nan::Get(v8Params, Nan::New(STR_HASH_ALG).ToLocalChecked()).ToLocalChecked(); - param.hashAlg = Nan::To(v8HashAlg).FromJust(); - - if (!check_param_empty(v8Params, STR_SOURCE_DATA)) { - v8::Local v8SourceData = Nan::Get(v8Params, Nan::New(STR_SOURCE_DATA).ToLocalChecked()).ToLocalChecked(); - GET_BUFFER_SMPL(buffer, Nan::To(v8SourceData).ToLocalChecked()); - param.pSourceData = (CK_BYTE_PTR)malloc(bufferLen * sizeof(CK_BYTE)); - memcpy(param.pSourceData, buffer, bufferLen); - param.ulSourceDataLen = (CK_ULONG)bufferLen; - } - } - CATCH_ERROR; -} - -void ParamRsaOAEP::Init() { - param = CK_RSA_PKCS_OAEP_PARAMS(); - param.hashAlg = 0; - param.source= 0; // CKZ_DATA_SPECIFIED ??? - param.mgf= 0; - param.pSourceData = NULL; - param.ulSourceDataLen = 0; -} - -void ParamRsaOAEP::Free() { - if (param.pSourceData) { - free(param.pSourceData); - param.pSourceData = NULL; - } -} - -// PSS ================================================================================= - -void ParamRsaPSS::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Params = Nan::To(v8Value).ToLocalChecked(); - - // Check data - if (!check_param_number(v8Params, STR_MGF)) - THROW_ERROR("Attribute 'mgf' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_SALT_LEN)) - THROW_ERROR("Attribute 'saltLen' MUST be NUMBER", NULL); - if (!check_param_number(v8Params, STR_HASH_ALG)) - THROW_ERROR("Attribute 'hashAlg' MUST be NUMBER", NULL); - - Free(); - Init(); - - v8::Local v8SaltLen = Nan::Get(v8Params, Nan::New(STR_SALT_LEN).ToLocalChecked()).ToLocalChecked(); - param.sLen = Nan::To(v8SaltLen).FromJust(); - - v8::Local v8Mgf = Nan::Get(v8Params, Nan::New(STR_MGF).ToLocalChecked()).ToLocalChecked(); - param.mgf = Nan::To(v8Mgf).FromJust(); - - v8::Local v8HashAlg = Nan::Get(v8Params, Nan::New(STR_HASH_ALG).ToLocalChecked()).ToLocalChecked(); - param.hashAlg = Nan::To(v8HashAlg).FromJust(); - - } - CATCH_ERROR; -} - -void ParamRsaPSS::Init() { - param = CK_RSA_PKCS_PSS_PARAMS(); - param.hashAlg = 0; - param.mgf = 0; - param.sLen = 0; -} - -void ParamRsaPSS::Free() { -} diff --git a/src/pkcs11/pkcs11.cpp b/src/pkcs11/pkcs11.cpp deleted file mode 100644 index bf40eb4..0000000 --- a/src/pkcs11/pkcs11.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -#include -#include - -#ifdef WIN32 -#include "../dl.h" -#else -#include -#endif // WIN32 - -#ifndef RTLD_NOW -#define RTLD_NOW 0x2 -#endif -#ifndef RTLD_LOCAL -#define RTLD_LOCAL 0x4 -#endif - -#include "pkcs11.h" - -#define CASE_PKCS11_ERROR(_value) \ - case _value: \ - { \ - Scoped res(new string(#_value)); \ - *res += ":"; \ - *res += to_string(_value); \ - return res; \ - } - -static Scoped get_pkcs11_error(CK_ULONG value) -{ - switch (value) - { - CASE_PKCS11_ERROR(CKR_OK); - CASE_PKCS11_ERROR(CKR_CANCEL); - CASE_PKCS11_ERROR(CKR_HOST_MEMORY); - CASE_PKCS11_ERROR(CKR_SLOT_ID_INVALID); - CASE_PKCS11_ERROR(CKR_GENERAL_ERROR); - CASE_PKCS11_ERROR(CKR_FUNCTION_FAILED); - CASE_PKCS11_ERROR(CKR_ARGUMENTS_BAD); - CASE_PKCS11_ERROR(CKR_NO_EVENT); - CASE_PKCS11_ERROR(CKR_NEED_TO_CREATE_THREADS); - CASE_PKCS11_ERROR(CKR_CANT_LOCK); - CASE_PKCS11_ERROR(CKR_ATTRIBUTE_READ_ONLY); - CASE_PKCS11_ERROR(CKR_ATTRIBUTE_SENSITIVE); - CASE_PKCS11_ERROR(CKR_ATTRIBUTE_TYPE_INVALID); - CASE_PKCS11_ERROR(CKR_ATTRIBUTE_VALUE_INVALID); - CASE_PKCS11_ERROR(CKR_DATA_INVALID); - CASE_PKCS11_ERROR(CKR_DATA_LEN_RANGE); - CASE_PKCS11_ERROR(CKR_DEVICE_ERROR); - CASE_PKCS11_ERROR(CKR_DEVICE_MEMORY); - CASE_PKCS11_ERROR(CKR_DEVICE_REMOVED); - CASE_PKCS11_ERROR(CKR_ENCRYPTED_DATA_INVALID); - CASE_PKCS11_ERROR(CKR_ENCRYPTED_DATA_LEN_RANGE); - CASE_PKCS11_ERROR(CKR_FUNCTION_CANCELED); - CASE_PKCS11_ERROR(CKR_FUNCTION_NOT_PARALLEL); - CASE_PKCS11_ERROR(CKR_FUNCTION_NOT_SUPPORTED); - CASE_PKCS11_ERROR(CKR_KEY_HANDLE_INVALID); - CASE_PKCS11_ERROR(CKR_KEY_SIZE_RANGE); - CASE_PKCS11_ERROR(CKR_KEY_TYPE_INCONSISTENT); - CASE_PKCS11_ERROR(CKR_KEY_NOT_NEEDED); - CASE_PKCS11_ERROR(CKR_KEY_CHANGED); - CASE_PKCS11_ERROR(CKR_KEY_NEEDED); - CASE_PKCS11_ERROR(CKR_KEY_INDIGESTIBLE); - CASE_PKCS11_ERROR(CKR_KEY_FUNCTION_NOT_PERMITTED); - CASE_PKCS11_ERROR(CKR_KEY_NOT_WRAPPABLE); - CASE_PKCS11_ERROR(CKR_KEY_UNEXTRACTABLE); - CASE_PKCS11_ERROR(CKR_MECHANISM_INVALID); - CASE_PKCS11_ERROR(CKR_MECHANISM_PARAM_INVALID); - CASE_PKCS11_ERROR(CKR_OBJECT_HANDLE_INVALID); - CASE_PKCS11_ERROR(CKR_OPERATION_ACTIVE); - CASE_PKCS11_ERROR(CKR_OPERATION_NOT_INITIALIZED); - CASE_PKCS11_ERROR(CKR_PIN_INCORRECT); - CASE_PKCS11_ERROR(CKR_PIN_INVALID); - CASE_PKCS11_ERROR(CKR_PIN_LEN_RANGE); - CASE_PKCS11_ERROR(CKR_PIN_EXPIRED); - CASE_PKCS11_ERROR(CKR_PIN_LOCKED); - CASE_PKCS11_ERROR(CKR_SESSION_CLOSED); - CASE_PKCS11_ERROR(CKR_SESSION_COUNT); - CASE_PKCS11_ERROR(CKR_SESSION_HANDLE_INVALID); - CASE_PKCS11_ERROR(CKR_SESSION_PARALLEL_NOT_SUPPORTED); - CASE_PKCS11_ERROR(CKR_SESSION_READ_ONLY); - CASE_PKCS11_ERROR(CKR_SESSION_EXISTS); - CASE_PKCS11_ERROR(CKR_SESSION_READ_ONLY_EXISTS); - CASE_PKCS11_ERROR(CKR_SESSION_READ_WRITE_SO_EXISTS); - CASE_PKCS11_ERROR(CKR_SIGNATURE_INVALID); - CASE_PKCS11_ERROR(CKR_SIGNATURE_LEN_RANGE); - CASE_PKCS11_ERROR(CKR_TEMPLATE_INCOMPLETE); - CASE_PKCS11_ERROR(CKR_TEMPLATE_INCONSISTENT); - CASE_PKCS11_ERROR(CKR_TOKEN_NOT_PRESENT); - CASE_PKCS11_ERROR(CKR_TOKEN_NOT_RECOGNIZED); - CASE_PKCS11_ERROR(CKR_TOKEN_WRITE_PROTECTED); - CASE_PKCS11_ERROR(CKR_UNWRAPPING_KEY_HANDLE_INVALID); - CASE_PKCS11_ERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE); - CASE_PKCS11_ERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT); - CASE_PKCS11_ERROR(CKR_USER_ALREADY_LOGGED_IN); - CASE_PKCS11_ERROR(CKR_USER_NOT_LOGGED_IN); - CASE_PKCS11_ERROR(CKR_USER_PIN_NOT_INITIALIZED); - CASE_PKCS11_ERROR(CKR_USER_TYPE_INVALID); - CASE_PKCS11_ERROR(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); - CASE_PKCS11_ERROR(CKR_USER_TOO_MANY_TYPES); - CASE_PKCS11_ERROR(CKR_WRAPPED_KEY_INVALID); - CASE_PKCS11_ERROR(CKR_WRAPPED_KEY_LEN_RANGE); - CASE_PKCS11_ERROR(CKR_WRAPPING_KEY_HANDLE_INVALID); - CASE_PKCS11_ERROR(CKR_WRAPPING_KEY_SIZE_RANGE); - CASE_PKCS11_ERROR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT); - CASE_PKCS11_ERROR(CKR_RANDOM_SEED_NOT_SUPPORTED); - CASE_PKCS11_ERROR(CKR_RANDOM_NO_RNG); - CASE_PKCS11_ERROR(CKR_DOMAIN_PARAMS_INVALID); - CASE_PKCS11_ERROR(CKR_BUFFER_TOO_SMALL); - CASE_PKCS11_ERROR(CKR_SAVED_STATE_INVALID); - CASE_PKCS11_ERROR(CKR_INFORMATION_SENSITIVE); - CASE_PKCS11_ERROR(CKR_STATE_UNSAVEABLE); - CASE_PKCS11_ERROR(CKR_CRYPTOKI_NOT_INITIALIZED); - CASE_PKCS11_ERROR(CKR_CRYPTOKI_ALREADY_INITIALIZED); - CASE_PKCS11_ERROR(CKR_MUTEX_BAD); - CASE_PKCS11_ERROR(CKR_MUTEX_NOT_LOCKED); - CASE_PKCS11_ERROR(CKR_NEW_PIN_MODE); - CASE_PKCS11_ERROR(CKR_NEXT_OTP); - CASE_PKCS11_ERROR(CKR_EXCEEDED_MAX_ITERATIONS); - CASE_PKCS11_ERROR(CKR_FIPS_SELF_TEST_FAILED); - CASE_PKCS11_ERROR(CKR_LIBRARY_LOAD_FAILED); - CASE_PKCS11_ERROR(CKR_PIN_TOO_WEAK); - CASE_PKCS11_ERROR(CKR_PUBLIC_KEY_INVALID); - CASE_PKCS11_ERROR(CKR_FUNCTION_REJECTED); - default: - Scoped res(new string("CKR_VENDOR_DEFINED")); - *res += ":" + to_string(value); - return res; - } -} - -#define CHECK_PKCS11_RV(func) \ - { \ - CK_RV rv = func; \ - if (rv != CKR_OK) \ - { \ - THROW_ERROR(get_pkcs11_error(rv)->c_str(), NULL); \ - } \ - } - -PKCS11::PKCS11() -{ - libPath = Scoped(new std::string("")); - dlHandle = NULL; -} - -void PKCS11::Load(Scoped path) -{ - try - { - int mode = RTLD_NOW | RTLD_LOCAL; - - dlHandle = dlopen(path->c_str(), mode); - if (!dlHandle) - { - THROW_ERROR(dlerror(), NULL); - } - - // reset errors - dlerror(); - CK_C_GetFunctionList f_C_GetFunctionList = (CK_C_GetFunctionList)dlsym(dlHandle, "C_GetFunctionList"); - const char *dlsym_error = dlerror(); - if (dlsym_error) - { - dlclose(dlHandle); - THROW_ERROR("Cannot load symbol 'C_GetFunctionList'", NULL); - return; - } - - CHECK_PKCS11_RV(f_C_GetFunctionList(&functionList)); - - libPath = path; - } - CATCH_ERROR; -} - -void PKCS11::Close() -{ - try - { - dlclose(dlHandle); - dlHandle = NULL; - } - CATCH_ERROR; -} - -void PKCS11::assertLoaded() -{ - if (!dlHandle) - { - THROW_ERROR("PKCS#11 module is not loaded. Call 'load' method first", NULL); - } -} - -void PKCS11::C_Initialize(CK_VOID_PTR args) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_Initialize( - args)); - } - CATCH_ERROR; -} - -void PKCS11::C_Finalize() -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_Finalize( - NULL_PTR)); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetInfo() -{ - try - { - assertLoaded(); - - Scoped info = make_shared(); - - CHECK_PKCS11_RV(functionList->C_GetInfo( - &*info)); - - return info; - } - CATCH_ERROR; -} - -vector PKCS11::C_GetSlotList(CK_BBOOL tokenPresent) -{ - try - { - assertLoaded(); - - CK_ULONG ulCount = 0; - - CHECK_PKCS11_RV(functionList->C_GetSlotList( - tokenPresent, - NULL_PTR, &ulCount)); - - vector arSlotList(ulCount); - - CHECK_PKCS11_RV(functionList->C_GetSlotList( - tokenPresent, - arSlotList.data(), &ulCount)); - - return arSlotList; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetSlotInfo(CK_SLOT_ID slotId) -{ - try - { - assertLoaded(); - - Scoped info = make_shared(); - - CHECK_PKCS11_RV(functionList->C_GetSlotInfo( - slotId, - info.get())); - - return info; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetTokenInfo(CK_SLOT_ID slotId) -{ - try - { - assertLoaded(); - - Scoped info = make_shared(); - - CHECK_PKCS11_RV(functionList->C_GetTokenInfo( - slotId, - info.get())); - - return info; - } - CATCH_ERROR; -} - -vector PKCS11::C_GetMechanismList(CK_SLOT_ID slotID) -{ - try - { - assertLoaded(); - - CK_ULONG ulCount = 0; - - CHECK_PKCS11_RV(functionList->C_GetMechanismList( - slotID, - NULL_PTR, &ulCount)); - - auto pMechanismList = vector(ulCount); - - CHECK_PKCS11_RV(functionList->C_GetMechanismList( - slotID, - pMechanismList.data(), &ulCount)); - - return pMechanismList; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type) -{ - try - { - assertLoaded(); - - Scoped info = make_shared(); - - CHECK_PKCS11_RV(functionList->C_GetMechanismInfo( - slotID, - type, - info.get())); - - return info; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_InitToken(CK_SLOT_ID slotID, Scoped pin, Scoped label) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_InitToken( - slotID, - pin->length() ? (CK_UTF8CHAR_PTR)pin->c_str() : NULL_PTR, (CK_ULONG)pin->length(), - label->length() ? (CK_UTF8CHAR_PTR)label->c_str() : NULL_PTR)); - - return Scoped(label); - } - CATCH_ERROR; -} - -void PKCS11::C_InitPIN(CK_SESSION_HANDLE session, Scoped pin) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_InitPIN( - session, - pin->length() ? (CK_UTF8CHAR_PTR)pin->c_str() : NULL_PTR, (CK_ULONG)pin->length())); - } - CATCH_ERROR; -} - -void PKCS11::C_SetPIN(CK_SESSION_HANDLE session, Scoped oldPin, Scoped newPin) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_SetPIN( - session, - oldPin->length() ? (CK_UTF8CHAR_PTR)oldPin->c_str() : NULL_PTR, (CK_ULONG)oldPin->length(), - newPin->length() ? (CK_UTF8CHAR_PTR)newPin->c_str() : NULL_PTR, (CK_ULONG)newPin->length())); - } - CATCH_ERROR; -} - -CK_SESSION_HANDLE PKCS11::C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags) -{ - try - { - assertLoaded(); - - CK_SESSION_HANDLE hSession = 0; - - CHECK_PKCS11_RV(functionList->C_OpenSession(slotID, flags, NULL_PTR, NULL_PTR, &hSession)); - - return hSession; - } - CATCH_ERROR; -} - -void PKCS11::C_CloseSession(CK_SESSION_HANDLE session) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_CloseSession(session)); - } - CATCH_ERROR; -} - -void PKCS11::C_CloseAllSessions(CK_SLOT_ID slotID) -{ - try - { - - CHECK_PKCS11_RV(functionList->C_CloseAllSessions(slotID)); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetSessionInfo(CK_SESSION_HANDLE session) -{ - try - { - assertLoaded(); - - Scoped info = make_shared(); - - CHECK_PKCS11_RV(functionList->C_GetSessionInfo(session, info.get())); - - return info; - } - CATCH_ERROR; -} - -void PKCS11::C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, Scoped pin) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_Login( - hSession, - userType, - pin->length() ? (CK_UTF8CHAR_PTR)pin->c_str() : NULL_PTR, (CK_ULONG)pin->length())); - } - CATCH_ERROR; -} - -void PKCS11::C_Logout(CK_SESSION_HANDLE hSession) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_Logout( - hSession)); - } - CATCH_ERROR; -} - -void PKCS11::C_FindObjectsInit(CK_SESSION_HANDLE hSession, Scoped attrs) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_FindObjectsInit( - hSession, - attrs->Get()->size ? attrs->Get()->items : NULL_PTR, attrs->Get()->size)); - } - CATCH_ERROR; -} - -void PKCS11::C_FindObjectsInit(CK_SESSION_HANDLE hSession) -{ - try - { - assertLoaded(); - - C_FindObjectsInit(hSession, Scoped(new Attributes())); - } - CATCH_ERROR; -} - -vector PKCS11::C_FindObjects(CK_SESSION_HANDLE session, CK_ULONG ulMaxObjectCount) -{ - try - { - assertLoaded(); - - CK_ULONG ulObjectCount = 0; - vector hObjects(ulMaxObjectCount); - - CHECK_PKCS11_RV(functionList->C_FindObjects( - session, - hObjects.data(), - ulMaxObjectCount, - &ulObjectCount)); - - hObjects.resize(ulObjectCount); - - return hObjects; - } - CATCH_ERROR; -} - -void PKCS11::C_FindObjectsFinal(CK_SESSION_HANDLE hSession) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_FindObjectsFinal(hSession)); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pTemplate = tmpl->Get(); - - CHECK_PKCS11_RV(functionList->C_GetAttributeValue( - hSession, - hObject, - pTemplate->items, pTemplate->size)); - - // Prepare value blocks for writing - for (uint32_t i = 0; i < pTemplate->size; i++) - { - pTemplate->items[i].pValue = (CK_BYTE_PTR)malloc(pTemplate->items[i].ulValueLen); - } - - CHECK_PKCS11_RV(functionList->C_GetAttributeValue( - hSession, - hObject, - pTemplate->items, pTemplate->size)); - - return tmpl; - } - CATCH_ERROR; -} - -void PKCS11::C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pTemplate = tmpl->Get(); - - CHECK_PKCS11_RV(functionList->C_SetAttributeValue( - hSession, - hObject, - pTemplate->items, pTemplate->size)); - } - CATCH_ERROR; -} - -CK_OBJECT_HANDLE PKCS11::C_CreateObject(CK_SESSION_HANDLE hSession, Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pTemplate = tmpl->Get(); - - CK_OBJECT_HANDLE hObject = 0; - - CHECK_PKCS11_RV(functionList->C_CreateObject( - hSession, - pTemplate->items, pTemplate->size, - &hObject)); - - return hObject; - } - CATCH_ERROR; -} - -CK_OBJECT_HANDLE PKCS11::C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pTemplate = tmpl->Get(); - - CK_OBJECT_HANDLE hNewObject = 0; - - CHECK_PKCS11_RV(functionList->C_CopyObject( - hSession, - hObject, - pTemplate->items, pTemplate->size, - &hNewObject)); - - return hNewObject; - } - CATCH_ERROR; -} - -void PKCS11::C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_DestroyObject( - hSession, - hObject)); - } - CATCH_ERROR; -} - -CK_ULONG PKCS11::C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - try - { - assertLoaded(); - - CK_ULONG ulSize = 0; - - CHECK_PKCS11_RV(functionList->C_GetObjectSize( - hSession, - hObject, - &ulSize)); - - return ulSize; - } - CATCH_ERROR; -} - -static void crypto_init( - CK_ULONG fn( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ - CK_OBJECT_HANDLE hKey /* handle of encryption key */ - ), - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hKey) -{ - try - { - - auto pMechanism = mech->Get(); - - CHECK_PKCS11_RV(fn( - hSession, - pMechanism, - hKey)); - } - CATCH_ERROR; -} - -static Scoped crypto_update( - CK_ULONG fn( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pIn, /* the plaintext data */ - CK_ULONG ulInLen, /* plaintext data len */ - CK_BYTE_PTR pOut, /* gets ciphertext */ - CK_ULONG_PTR pulOutLen /* gets c-text size */ - ), - CK_SESSION_HANDLE hSession, - Scoped input, - Scoped output) -{ - try - { - - auto outLen = output->length(); - - CHECK_PKCS11_RV(fn( - hSession, - (CK_BYTE_PTR)input->c_str(), (CK_ULONG)input->length(), - (CK_BYTE_PTR)output->c_str(), (CK_ULONG_PTR)&outLen)); - - return Scoped(new string(output->substr(0, outLen))); - } - CATCH_ERROR; -} - -static void crypto_update( - CK_ULONG fn( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* data to be digested */ - CK_ULONG ulPartLen /* bytes of data to be digested */ - ), - CK_SESSION_HANDLE hSession, - Scoped part) -{ - try - { - - CHECK_PKCS11_RV(fn( - hSession, - (CK_BYTE_PTR)part->c_str(), - (CK_ULONG)part->length())); - } - CATCH_ERROR; -} - -static Scoped crypto_final( - CK_ULONG fn( - CK_SESSION_HANDLE hSession, /* session handle */ - CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ - CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ - ), - CK_SESSION_HANDLE hSession, - Scoped output) -{ - try - { - - auto outputLen = output->length(); - - CHECK_PKCS11_RV(fn( - hSession, - (CK_BYTE_PTR)output->c_str(), - (CK_ULONG_PTR)&outputLen)); - - return Scoped(new string(output->substr(0, outputLen))); - } - CATCH_ERROR; -} - -void PKCS11::C_EncryptInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_SESSION_HANDLE hObject) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_EncryptInit, hSession, mech, hObject); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_Encrypt(CK_SESSION_HANDLE hSession, Scoped msg, Scoped encMsg) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_Encrypt, hSession, msg, encMsg); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_EncryptUpdate(CK_SESSION_HANDLE hSession, Scoped part, Scoped encPart) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_EncryptUpdate, hSession, part, encPart); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_EncryptFinal(CK_SESSION_HANDLE hSession, Scoped encPart) -{ - try - { - assertLoaded(); - - return crypto_final(functionList->C_EncryptFinal, hSession, encPart); - } - CATCH_ERROR; -} - -void PKCS11::C_DecryptInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_SESSION_HANDLE hObject) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_DecryptInit, hSession, mech, hObject); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_Decrypt(CK_SESSION_HANDLE hSession, Scoped encMsg, Scoped msg) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_Decrypt, hSession, encMsg, msg); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_DecryptUpdate(CK_SESSION_HANDLE hSession, Scoped encPart, Scoped decPart) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_DecryptUpdate, hSession, encPart, decPart); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_DecryptFinal(CK_SESSION_HANDLE hSession, Scoped decPart) -{ - try - { - assertLoaded(); - - return crypto_final(functionList->C_DecryptFinal, hSession, decPart); - } - CATCH_ERROR; -} - -void PKCS11::C_DigestInit(CK_SESSION_HANDLE hSession, Scoped mech) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - - CHECK_PKCS11_RV(functionList->C_DigestInit( - hSession, - pMechanism)); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_Digest(CK_SESSION_HANDLE hSession, Scoped msg, Scoped output) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_Digest, hSession, msg, output); - } - CATCH_ERROR; -} - -void PKCS11::C_DigestUpdate(CK_SESSION_HANDLE hSession, Scoped part) -{ - try - { - assertLoaded(); - - crypto_update(functionList->C_DigestUpdate, hSession, part); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_DigestFinal(CK_SESSION_HANDLE hSession, Scoped output) -{ - try - { - assertLoaded(); - - return crypto_final(functionList->C_DigestFinal, hSession, output); - } - CATCH_ERROR; -} - -void PKCS11::C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_DigestKey(hSession, hObject)); - } - CATCH_ERROR; -} - -void PKCS11::C_SignInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_SignInit, hSession, mech, hKey); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_Sign(CK_SESSION_HANDLE hSession, Scoped msg, Scoped output) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_Sign, hSession, msg, output); - } - CATCH_ERROR; -} - -void PKCS11::C_SignUpdate(CK_SESSION_HANDLE hSession, Scoped part) -{ - try - { - assertLoaded(); - - crypto_update(functionList->C_SignUpdate, hSession, part); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_SignFinal(CK_SESSION_HANDLE hSession, Scoped output) -{ - try - { - assertLoaded(); - - return crypto_final(functionList->C_SignFinal, hSession, output); - } - CATCH_ERROR; -} - -void PKCS11::C_SignRecoverInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_SignRecoverInit, hSession, mech, hKey); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_SignRecover(CK_SESSION_HANDLE hSession, Scoped data, Scoped signature) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_SignRecover, hSession, data, signature); - } - CATCH_ERROR; -} - -void PKCS11::C_VerifyInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_VerifyInit, hSession, mech, hKey); - } - CATCH_ERROR; -} - -void PKCS11::C_Verify(CK_SESSION_HANDLE hSession, Scoped msg, Scoped signature) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_Verify( - hSession, - (CK_BYTE_PTR)msg->c_str(), (CK_ULONG)msg->length(), - (CK_BYTE_PTR)signature->c_str(), (CK_ULONG)signature->length())); - } - CATCH_ERROR; -} - -void PKCS11::C_VerifyUpdate(CK_SESSION_HANDLE hSession, Scoped part) -{ - try - { - assertLoaded(); - - crypto_update(functionList->C_VerifyUpdate, hSession, part); - } - CATCH_ERROR; -} - -void PKCS11::C_VerifyFinal(CK_SESSION_HANDLE hSession, Scoped signature) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_VerifyFinal( - hSession, - (CK_BYTE_PTR)signature->c_str(), (CK_ULONG)signature->length())); - } - CATCH_ERROR; -} - -void PKCS11::C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hObject) -{ - try - { - assertLoaded(); - - crypto_init(functionList->C_SignRecoverInit, hSession, mech, hObject); - } - CATCH_ERROR; -} - -Scoped PKCS11::C_VerifyRecover(CK_SESSION_HANDLE hSession, Scoped signature, Scoped data) -{ - try - { - assertLoaded(); - - return crypto_update(functionList->C_VerifyRecover, hSession, signature, data); - } - CATCH_ERROR; -} - -CK_OBJECT_HANDLE PKCS11::C_GenerateKey(CK_SESSION_HANDLE hSession, Scoped mech, Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - auto pTemplate = tmpl->Get(); - - CK_OBJECT_HANDLE hObject = 0; - - CHECK_PKCS11_RV(functionList->C_GenerateKey( - hSession, - pMechanism, - pTemplate->items, pTemplate->size, - &hObject)); - - return hObject; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_GenerateKeyPair( - CK_SESSION_HANDLE hSession, - Scoped mech, - Scoped publicKeyTemplate, - Scoped privateKeyTemplate) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - auto pPublicKeyTemplate = publicKeyTemplate->Get(); - auto pPrivateKeyTemplate = privateKeyTemplate->Get(); - - CK_OBJECT_HANDLE hPublicKey = 0; - CK_OBJECT_HANDLE hPrivateKey = 0; - - CHECK_PKCS11_RV(functionList->C_GenerateKeyPair( - hSession, - pMechanism, - pPublicKeyTemplate->items, pPublicKeyTemplate->size, - pPrivateKeyTemplate->items, pPrivateKeyTemplate->size, - &hPublicKey, - &hPrivateKey)); - - Scoped keyPair = make_shared(); - keyPair->privateKey = hPrivateKey; - keyPair->publicKey = hPublicKey; - - return keyPair; - } - CATCH_ERROR; -} - -Scoped PKCS11::C_WrapKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, - Scoped wrappedKey) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - auto wrappedKeyLen = wrappedKey->length(); - - CHECK_PKCS11_RV(functionList->C_WrapKey( - hSession, - pMechanism, - hWrappingKey, - hKey, - (CK_BYTE_PTR)wrappedKey->c_str(), (CK_ULONG_PTR)&wrappedKeyLen)); - - return Scoped(new string(wrappedKey->substr(0, wrappedKeyLen))); - } - CATCH_ERROR; -} - -CK_OBJECT_HANDLE PKCS11::C_UnwrapKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hUnwrappingKey, - Scoped wrappedKey, - Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - auto pTemplate = tmpl->Get(); - - CK_OBJECT_HANDLE hKey = 0; - - CHECK_PKCS11_RV(functionList->C_UnwrapKey( - hSession, - pMechanism, - hUnwrappingKey, - (CK_BYTE_PTR)wrappedKey->c_str(), (CK_ULONG)wrappedKey->length(), - pTemplate->items, pTemplate->size, - &hKey)); - - return hKey; - } - CATCH_ERROR; -} - -CK_OBJECT_HANDLE PKCS11::C_DeriveKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hBaseKey, - Scoped tmpl) -{ - try - { - assertLoaded(); - - auto pMechanism = mech->Get(); - auto pTemplate = tmpl->Get(); - - CK_OBJECT_HANDLE hDerivedKey = 0; - - CHECK_PKCS11_RV(functionList->C_DeriveKey( - hSession, - pMechanism, - hBaseKey, - pTemplate->items, pTemplate->size, - &hDerivedKey)); - - return hDerivedKey; - } - CATCH_ERROR; -} - -void PKCS11::C_SeedRandom(CK_SESSION_HANDLE hSession, char *data, size_t dataLen) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_SeedRandom( - hSession, - (CK_BYTE_PTR)data, (CK_ULONG)dataLen)); - } - CATCH_ERROR; -} - -void PKCS11::C_GenerateRandom(CK_SESSION_HANDLE hSession, char *data, size_t dataLen) -{ - try - { - assertLoaded(); - - CHECK_PKCS11_RV(functionList->C_GenerateRandom( - hSession, - (CK_BYTE_PTR)data, (CK_ULONG)dataLen)); - } - CATCH_ERROR; -} - -CK_RV PKCS11::C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR slotID) -{ - try - { - assertLoaded(); - - CK_RV rv = functionList->C_WaitForSlotEvent(flags, slotID, NULL_PTR); - - return rv; - } - CATCH_ERROR; -} diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h deleted file mode 100644 index a5a5016..0000000 --- a/src/pkcs11/pkcs11.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef INCLUDE_H_PKCS11 -#define INCLUDE_H_PKCS11 - -#include - -#include "template.h" -#include "mech.h" -#include "strings.h" - -using namespace v8; -using namespace node; - -struct KEY_PAIR { - CK_OBJECT_HANDLE privateKey; - CK_OBJECT_HANDLE publicKey; -}; - -class PKCS11 { -public: - Scoped libPath; - - PKCS11(); - - void Load(Scoped path); - void Close(); - - // PKCS11 - void C_Initialize(CK_VOID_PTR args); - void C_Finalize(); - Scoped C_GetInfo(); - vector C_GetSlotList(CK_BBOOL tokenPresent); - Scoped C_GetSlotInfo(CK_SLOT_ID slotId); - Scoped C_GetTokenInfo(CK_SLOT_ID slotID); - vector C_GetMechanismList(CK_SLOT_ID slotID); - Scoped C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type); - Scoped C_InitToken(CK_SLOT_ID slotID, Scoped pin, Scoped label); - void C_InitPIN(CK_SESSION_HANDLE session, Scoped pin); - void C_SetPIN(CK_SESSION_HANDLE session, Scoped oldPin, Scoped newPin); - CK_SESSION_HANDLE C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags); - void C_CloseSession(CK_SESSION_HANDLE session); - void C_CloseAllSessions(CK_SLOT_ID slotID); - Scoped C_GetSessionInfo(CK_SESSION_HANDLE session); - // C_GetOperationState); - // C_SetOperationState); - void C_Login(CK_SESSION_HANDLE session, CK_USER_TYPE userType, Scoped pin); - void C_Logout(CK_SESSION_HANDLE session); - // - ///* Object management */ - CK_OBJECT_HANDLE C_CreateObject(CK_SESSION_HANDLE session, Scoped tmpl); - CK_OBJECT_HANDLE C_CopyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, Scoped tmpl); - void C_DestroyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object); - CK_ULONG C_GetObjectSize(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object); - void C_FindObjectsInit(CK_SESSION_HANDLE session, Scoped attrs); - void C_FindObjectsInit(CK_SESSION_HANDLE session); - vector C_FindObjects(CK_SESSION_HANDLE session, CK_ULONG ulMaxObjectCount); - void C_FindObjectsFinal(CK_SESSION_HANDLE session); - Scoped C_GetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, Scoped tmpl); - void C_SetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, Scoped tmpl); - - ///* Encryption and decryption */ - void C_EncryptInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_SESSION_HANDLE hObject); - Scoped C_Encrypt(CK_SESSION_HANDLE hSession, Scoped msg, Scoped encMsg); - Scoped C_EncryptUpdate(CK_SESSION_HANDLE hSession, Scoped part, Scoped encPart); - Scoped C_EncryptFinal(CK_SESSION_HANDLE hSession, Scoped encPart); - void C_DecryptInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_SESSION_HANDLE hObject); - Scoped C_Decrypt(CK_SESSION_HANDLE hSession, Scoped encMsg, Scoped msg); - Scoped C_DecryptUpdate(CK_SESSION_HANDLE hSession, Scoped encPart, Scoped decPart); - Scoped C_DecryptFinal(CK_SESSION_HANDLE hSession, Scoped decPart); - - ///* Message digesting */ - void C_DigestInit(CK_SESSION_HANDLE hSession, Scoped mech); - Scoped C_Digest(CK_SESSION_HANDLE hSession, Scoped msg, Scoped output); - void C_DigestUpdate(CK_SESSION_HANDLE hSession, Scoped part); - Scoped C_DigestFinal(CK_SESSION_HANDLE hSession, Scoped output); - void C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); - - ///* Signing and MACing */ - void C_SignInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey); - Scoped C_Sign(CK_SESSION_HANDLE hSession, Scoped msg, Scoped output); - void C_SignUpdate(CK_SESSION_HANDLE hSession, Scoped part); - Scoped C_SignFinal(CK_SESSION_HANDLE hSession, Scoped output); - void C_SignRecoverInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey); - Scoped C_SignRecover(CK_SESSION_HANDLE hSession, Scopeddata, Scoped signature); - - ///* Verifying signatures and MACs */ - void C_VerifyInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hKey); - void C_Verify(CK_SESSION_HANDLE hSession, Scoped msg, Scoped signature); - void C_VerifyUpdate(CK_SESSION_HANDLE hSession, Scoped part); - void C_VerifyFinal(CK_SESSION_HANDLE hSession, Scoped signature); - void C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, Scoped mech, CK_OBJECT_HANDLE hObject); - Scoped C_VerifyRecover(CK_SESSION_HANDLE hSession, Scoped signature, Scoped data); - - ///* Key management */ - CK_OBJECT_HANDLE C_GenerateKey(CK_SESSION_HANDLE hSession, Scoped mech, Scoped tmpl); - Scoped C_GenerateKeyPair(CK_SESSION_HANDLE hSession, Scoped mech, Scoped publicKeyTemplate, Scoped privateKeyTemplate); - Scoped C_WrapKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, - Scoped wrappedKey - ); - CK_OBJECT_HANDLE C_UnwrapKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hUnwrappingKey, - Scoped wrappedKey, - Scoped tmpl - ); - CK_OBJECT_HANDLE C_DeriveKey( - CK_SESSION_HANDLE hSession, - Scoped mech, - CK_OBJECT_HANDLE hBaseKey, - Scoped tmpl - ); - - ///* Random number generation */ - void C_SeedRandom(CK_SESSION_HANDLE hSession, char *data, size_t dataLen); - void C_GenerateRandom(CK_SESSION_HANDLE hSession, char *data, size_t dataLen); - - /* Event slot function */ - CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR slotID); - -protected: - - void* dlHandle; - CK_FUNCTION_LIST_PTR functionList; - - void assertLoaded(); -}; - -#endif // INCLUDE_H_PKCS11 diff --git a/src/pkcs11/scope.h b/src/pkcs11/scope.h deleted file mode 100644 index c7ea64c..0000000 --- a/src/pkcs11/scope.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_SCOPE -#define INCLUDE_H_PKCS11_SCOPE - -#include - -template -using Scoped = std::shared_ptr; - -#endif // INCLUDE_H_PKCS11_SCOPE \ No newline at end of file diff --git a/src/pkcs11/strings.h b/src/pkcs11/strings.h deleted file mode 100644 index ef9b4cd..0000000 --- a/src/pkcs11/strings.h +++ /dev/null @@ -1,51 +0,0 @@ -#define STR_MAJOR "major" -#define STR_MINOR "minor" -#define STR_FLAGS "flags" -#define STR_CRYPTOKI_VERSION "cryptokiVersion" -#define STR_LIBRARY_VERSION "libraryVersion" -#define STR_LIBRARY_DESCRIPTION "libraryDescription" -#define STR_MANUFACTURER_ID "manufacturerID" -#define STR_SLOT_DESCRIPTION "slotDescription" -#define STR_HARDWARE_VERSION "hardwareVersion" -#define STR_FIRMWARE_VERSION "firmwareVersion" -#define STR_LABEL "label" -#define STR_MODEL "model" -#define STR_SERIAL_NUMER "serialNumber" -#define STR_MAX_SESSION_COUNT "maxSessionCount" -#define STR_SESSION_COUNT "sessionCount" -#define STR_MAX_RW_SESSION_COUNT "maxRwSessionCount" -#define STR_RW_SESSION_COUNT "rwSessionCount" -#define STR_MAX_PIN_LEN "maxPinLen" -#define STR_MIN_PIN_LEN "minPinLen" -#define STR_TOTAL_PUBLIC_MEMORY "totalPublicMemory" -#define STR_FREE_PUBLIC_MEMORY "freePublicMemory" -#define STR_TOTAL_PRIVATE_MEMORY "totalPrivateMemory" -#define STR_FREE_PRIVATE_MEMORY "freePrivateMemory" -#define STR_UTC_TIME "utcTime" -#define STR_MIN_KEY_SIZE "minKeySize" -#define STR_MAX_KEY_SIZE "maxKeySize" -#define STR_SLOT_ID "slotID" -#define STR_STATE "state" -#define STR_DEVICE_ERROR "deviceError" -#define STR_TYPE "type" -#define STR_VALUE "value" -#define STR_MECHANISM "mechanism" -#define STR_PARAMETER "parameter" -#define STR_PRIVATE_KEY "privateKey" -#define STR_PUBLIC_KEY "publicKey" -#define STR_KDF "kdf" -#define STR_SHARED_DATA "sharedData" -#define STR_PUBLIC_DATA "publicData" -#define STR_IV "iv" -#define STR_IV_BITS "ivBits" -#define STR_TAG_BITS "tagBits" -#define STR_DATA "data" -#define STR_DATA_LEN "dataLen" -#define STR_NONCE "nonce" -#define STR_AAD "aad" -#define STR_MAC_LEN "macLen" -#define STR_HASH_ALG "hashAlg" -#define STR_MGF "mgf" -#define STR_SOURCE "source" -#define STR_SOURCE_DATA "sourceData" -#define STR_SALT_LEN "saltLen" diff --git a/src/pkcs11/template.cpp b/src/pkcs11/template.cpp deleted file mode 100644 index 1e3a972..0000000 --- a/src/pkcs11/template.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "template.h" - -static void attr_set_value(CK_ATTRIBUTE_PTR attr, const char* value, uint32_t valueLen) { - try { - attr->pValue = (char*)malloc(valueLen); - memcpy(attr->pValue, value, valueLen); - attr->ulValueLen = valueLen; - } - CATCH_ERROR; -} - -static Scoped v2c_ATTRIBUTE(Local v8Attribute) { - Nan::HandleScope scope; - - try { - if (!v8Attribute->IsObject()) { - THROW_ERROR("Parameter 1 MUST be Object", NULL); - } - - Local v8Object = Nan::To(v8Attribute).ToLocalChecked(); - - Local v8Type = Nan::Get(v8Object, Nan::New(STR_TYPE).ToLocalChecked()).ToLocalChecked(); - if (!v8Type->IsNumber()) { - THROW_ERROR("Member 'type' MUST be Number", NULL); - } - - Local v8Value = Nan::Get(v8Object, Nan::New(STR_VALUE).ToLocalChecked()).ToLocalChecked(); - if (!(v8Value->IsUndefined() || v8Value->IsNull() || - node::Buffer::HasInstance(v8Value) || - v8Value->IsBoolean() || - v8Value->IsString() || - v8Value->IsNumber())) { - THROW_ERROR("Member 'value' MUST has wrong type", NULL); - } - - Scoped attr(new CK_ATTRIBUTE()); - attr->pValue = NULL; - attr->ulValueLen = 0; - - attr->type = Nan::To(v8Type).FromJust(); - if (node::Buffer::HasInstance(v8Value)) { - // Buffer - GET_BUFFER_SMPL(data, v8Value); - attr_set_value(attr.get(), data, (uint32_t)dataLen); - } - else if (v8Value->IsBoolean()) { - // Boolean - char data[1]; - data[0] = (char)Nan::To(v8Value).FromJust(); - attr_set_value(attr.get(), data, 1); - } - else if (v8Value->IsNumber()) { - // Number - CK_ULONG num = (CK_ULONG)Nan::To(v8Value).FromJust(); - - uint32_t long_size = sizeof(CK_ULONG); - - attr->pValue = (char*)malloc(long_size); - *(CK_ULONG*)attr->pValue = num; - attr->ulValueLen = long_size; - } - else if (v8Value->IsString()) { - // String - Nan::Utf8String utf8Val(v8Value); - char* val = *utf8Val; - int valLen = utf8Val.length(); - attr_set_value(attr.get(), val, valLen); - } - - return attr; - } - CATCH_ERROR; -} - -static Local c2v_ATTRIBUTE(CK_ATTRIBUTE_PTR attr) { - Nan::EscapableHandleScope scope; - - try { - if (!attr) { - THROW_ERROR("Parameter 1 is EMPTY", NULL); - } - - Local v8Attribute = Nan::New(); - - // Type - Nan::Set(v8Attribute, Nan::New(STR_TYPE).ToLocalChecked(), Nan::New(attr->type)); - - // Value - Local v8Value = node::Buffer::Copy(Isolate::GetCurrent(), (char *)attr->pValue, attr->ulValueLen).ToLocalChecked(); - Nan::Set(v8Attribute, Nan::New(STR_VALUE).ToLocalChecked(), v8Value); - - return scope.Escape(v8Attribute); - } - CATCH_ERROR; -} - -static void TEMPLATE_free(TEMPLATE* tmpl) { - if (tmpl && tmpl->items) { - // Free attr values - for (CK_ULONG i = 0; i < tmpl->size; i++) { - if (&tmpl->items[i] && tmpl->items[i].pValue) { - free(tmpl->items[i].pValue); - } - } - free(tmpl->items); - } -} - -Attributes::Attributes() { - data = TEMPLATE(); - data.size = 0; - data.items = NULL; -} - -Attributes::~Attributes() { - TEMPLATE_free(Get()); -} - -TEMPLATE* Attributes::New() { - TEMPLATE_free(Get()); - data = TEMPLATE(); - data.size = 0; - data.items = NULL; - return Get(); -} - -void Attributes::Push(CK_ATTRIBUTE_PTR attr) { - try { - if (!attr) - THROW_ERROR("Parameter 1 is EMPTY", NULL); - if (Get()) { - data.items = (CK_ATTRIBUTE_PTR)realloc(data.items, ++data.size * sizeof(CK_ATTRIBUTE)); - data.items[data.size - 1] = *(attr); - } - } - CATCH_ERROR; -} - -void Attributes::FromV8(Local v8Value) { - Nan::HandleScope scope; - - try { - if (!v8Value->IsArray()) { - THROW_ERROR("Parameter 1 MUST be Array", NULL); - } - - Local v8Template = Nan::To(v8Value).ToLocalChecked(); - - Local v8TemplateLen = Nan::Get(v8Template, Nan::New("length").ToLocalChecked()).ToLocalChecked(); - uint32_t templateLen = Nan::To(v8TemplateLen).FromJust(); - - uint32_t i = 0; - New(); - for (i = 0; i < templateLen; i++) { - Local v8Attribute = Nan::Get(v8Template, i).ToLocalChecked(); - Scoped attr = v2c_ATTRIBUTE(v8Attribute); - this->Push(attr.get()); - } - } - CATCH_ERROR; -} - -Local Attributes::ToV8() { - Nan::EscapableHandleScope scope; - - try { - Local v8Res = Nan::New(); - for (uint32_t i = 0; i < data.size; i++) { - CK_ATTRIBUTE_PTR pItem = &data.items[i]; - Local v8Attribute = c2v_ATTRIBUTE(pItem); - - Nan::Set(v8Res, i, v8Attribute); - } - return scope.Escape(v8Res); - } - CATCH_ERROR; -} diff --git a/src/pkcs11/template.h b/src/pkcs11/template.h deleted file mode 100644 index 32e3066..0000000 --- a/src/pkcs11/template.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef INCLUDE_H_PKCS11_TEMPLATE -#define INCLUDE_H_PKCS11_TEMPLATE - -// #include "attr.h" -#include "core.h" -#include "v8_convert.h" - -struct TEMPLATE { - CK_ULONG size; - CK_ATTRIBUTE_PTR items; -}; - -class Attributes : public V8Converter