Giter Club home page Giter Club logo

pkcs11js's Introduction

PKCS11js

license test Coverage Status npm version

NPM

PKCS11js is a package for direct interaction with the PKCS#11 API, the standard interface for interacting with hardware crypto devices such as Smart Cards and Hardware Security Modules (HSMs). It was developed to the PKCS#11 2.40 specification and has been tested with a variety of devices.

Versioning Note:

  • Version 1.x was implemented using the nan module, which allowed the package to be built for older versions of Node.js.
  • Starting from version 2.x, the module has been rewritten to use napi. As a result, the minimum required Node.js version is now v18.

For most use cases, we recommend our package Graphene, which provides a simplistic Object Oriented interface for interacting with PKCS#11 devices.

This was developed to the PKCS#11 2.40 specification. It should be easy enough to extend it for any new versions at a later date.

It has been tested with :

NOTE: For testing purposes it may be easier to work with SoftHSM2 which is a software implementation of PKCS#11 based on OpenSSL or Botan.

Installation

$ npm install pkcs11js

Documentation

https://peculiarventures.github.io/pkcs11js/

Install SoftHSM2

Examples

Example #1

var pkcs11js = require("pkcs11js");

var pkcs11 = new pkcs11js.PKCS11();
pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so");

pkcs11.C_Initialize();

try {
    // Getting info about PKCS11 Module
    var module_info = pkcs11.C_GetInfo();

    // Getting list of slots
    var slots = pkcs11.C_GetSlotList(true);
    var slot = slots[0];

    // Getting info about slot
    var slot_info = pkcs11.C_GetSlotInfo(slot);
    // Getting info about token
    var token_info = pkcs11.C_GetTokenInfo(slot);

    // Getting info about Mechanism
    var mechs = pkcs11.C_GetMechanismList(slot);
    var mech_info = pkcs11.C_GetMechanismInfo(slot, mechs[0]);

    var session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION);

    // Getting info about Session
    var info = pkcs11.C_GetSessionInfo(session);
    pkcs11.C_Login(session, 1, "password");

    /**
     * Your app code here
     */
    
    pkcs11.C_Logout(session);
    pkcs11.C_CloseSession(session);
}
catch(e){
    console.error(e);
}
finally {
    pkcs11.C_Finalize();
}

Example #2

Generating secret key using AES mechanism

var template = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My AES Key" },
    { type: pkcs11js.CKA_VALUE_LEN, value: 256 / 8 },
    { type: pkcs11js.CKA_ENCRYPT, value: true },
    { type: pkcs11js.CKA_DECRYPT, value: true },
];
var key = pkcs11.C_GenerateKey(session, { mechanism: pkcs11js.CKM_AES_KEY_GEN }, template);

Example #3

Generating key pair using RSA-PKCS1 mechanism

var publicKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My RSA Public Key" },
    { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: new Buffer([1, 0, 1]) },
    { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 },
    { type: pkcs11js.CKA_VERIFY, value: true }
];
var privateKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My RSA Private Key" },
    { type: pkcs11js.CKA_SIGN, value: true },
];
var keys = pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, publicKeyTemplate, privateKeyTemplate);

Example #4

Generating key pair using ECDSA mechanism

var publicKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My EC Public Key" },
    { type: pkcs11js.CKA_EC_PARAMS, value: new Buffer("06082A8648CE3D030107", "hex") }, // secp256r1
];
var privateKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My EC Private Key" },
    { type: pkcs11js.CKA_DERIVE, value: true },
];
var keys = pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_EC_KEY_PAIR_GEN }, publicKeyTemplate, privateKeyTemplate);

Example #4

Working with Object

var nObject = pkcs11.C_CreateObject(session, [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_PRIVATE, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My custom data" },
]);

// Updating label of Object
pkcs11.C_SetAttributeValue(session, nObject, [{ type: pkcs11js.CKA_LABEL, value: "My custom data!!!" }]);

// Getting attribute value
var label = pkcs11.C_GetAttributeValue(session, nObject, [
    { type: pkcs11js.CKA_LABEL },
    { type: pkcs11js.CKA_TOKEN }
]);
console.log(label[0].value.toString()); // My custom data!!!
console.log(!!label[1].value[0]); // false

// Copying Object
var cObject = pkcs11.C_CopyObject(session, nObject, [
    { type: pkcs11js.CKA_CLASS},
    { type: pkcs11js.CKA_TOKEN},
    { type: pkcs11js.CKA_PRIVATE},
    { type: pkcs11js.CKA_LABEL},
]);

// Removing Object
pkcs11.C_DestroyObject(session, cObject);

Example #4

Searching objects

NOTE: If template is not set for C_FindObjectsInit, then C_FindObjects returns all objects from slot

pkcs11.C_FindObjectsInit(session, [{ type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA }]);
var hObject = pkcs11.C_FindObjects(session);
while (hObject) {
    var attrs = pkcs11.C_GetAttributeValue(session, hObject, [
        { type: pkcs11js.CKA_CLASS },
        { type: pkcs11js.CKA_TOKEN },
        { type: pkcs11js.CKA_LABEL }
    ]);
    // Output info for objects from token only
    if (attrs[1].value[0]){
        console.log(`Object #${hObject}: ${attrs[2].value.toString()}`);
    }
    hObject = pkcs11.C_FindObjects(session);
}
pkcs11.C_FindObjectsFinal(session);

Example #5

Generating random values

var random = pkcs11.C_GenerateRandom(session, new Buffer(20));
console.log(random.toString("hex"));

or

var random = new Buffer(20);
pkcs11.C_GenerateRandom(session, random);
console.log(random.toString("hex"));

Example #6

Digest

pkcs11.C_DigestInit(_session, { mechanism: pkcs11js.CKM_SHA256 });

pkcs11.C_DigestUpdate(session, new Buffer("Incoming message 1"));
pkcs11.C_DigestUpdate(session, new Buffer("Incoming message N"));

var digest = pkcs11.C_DigestFinal(_session, Buffer(256 / 8));

console.log(digest.toString("hex"));

Example #7

Signing data

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.privateKey);

pkcs11.C_SignUpdate(session, new Buffer("Incoming message 1"));
pkcs11.C_SignUpdate(session, new Buffer("Incoming message N"));

var signature = pkcs11.C_SignFinal(session, Buffer(256));

Verifying data

pkcs11.C_VerifyInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.publicKey);

pkcs11.C_VerifyUpdate(session, new Buffer("Incoming message 1"));
pkcs11.C_VerifyUpdate(session, new Buffer("Incoming message N"));

var verify = pkcs11.C_VerifyFinal(session, signature);

Example #8

Encrypting data with AES-CBC mechanism

var cbc_param = pkcs11.C_GenerateRandom(new Buffer(16));

pkcs11.C_EncryptInit(
    session,
    {
        mechanism: pkcs11js.CKM_AES_CBC,
        parameter: cbc_param
    },
    secretKey
);

var enc = new Buffer(0);
enc = Buffer.concat([enc, pkcs11.C_EncryptUpdate(session, new Buffer("Incoming data 1"), new Buffer(16))]);
enc = Buffer.concat([enc, pkcs11.C_EncryptUpdate(session, new Buffer("Incoming data N"), new Buffer(16))]);
enc = Buffer.concat([enc, pkcs11.C_EncryptFinal(session, new Buffer(16))]);

console.log(enc.toString("hex"));

Decrypting data with AES-CBC mechanism

pkcs11.C_DecryptInit(
    session,
    {
        mechanism: pkcs11js.CKM_AES_CBC,
        parameter: cbc_param
    },
    secretKey
);

var dec = new Buffer(0);
dec = Buffer.concat([dec, pkcs11.C_DecryptUpdate(session, enc, new Buffer(32))]);
dec = Buffer.concat([dec, pkcs11.C_DecryptFinal(session, new Buffer(16))]);

console.log(dec.toString());

Example #9

Deriving key with ECDH mechanism

// Receive public data from EC public key
var attrs = pkcs11.C_GetAttributeValue(session, publicKeyEC, [{ type: pkcs11js.CKA_EC_POINT }])
var ec = attrs[0].value;

var derivedKey = pkcs11.C_DeriveKey(
    session,
    {
        mechanism: pkcs11js.CKM_ECDH1_DERIVE,
        parameter: {
            type: pkcs11js.CK_PARAMS_EC_DH,
            kdf: 2,
            publicData: ec
        }
    },
    privateKeyEC,
    [
        { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_SECRET_KEY },
        { type: pkcs11js.CKA_TOKEN, value: false },
        { type: pkcs11js.CKA_KEY_TYPE, value: pkcs11js.CKK_AES },
        { type: pkcs11js.CKA_LABEL, value: "Derived AES key" },
        { type: pkcs11js.CKA_ENCRYPT, value: true },
        { type: pkcs11js.CKA_VALUE_LEN, value: 256 / 8 }
    ]
);

Example #10

Initializing NSS crypto library

Use options parameter for C_Initialize function.

Type

interface InitializationOptions {
    /**
     * NSS library parameters
     */
    libraryParameters?: string;
    /**
     * bit flags specifying options for `C_Initialize`
     * - CKF_LIBRARY_CANT_CREATE_OS_THREADS. True if application threads which are executing calls to the library
     *   may not use native operating system calls to spawn new threads; false if they may
     * - CKF_OS_LOCKING_OK. True if the library can use the native operation system threading model for locking;
     *   false otherwise
     */
    flags?: number;
}
/**
 * Initializes the Cryptoki library
 * @param options Initialization options
 * Supports implementation of standard `CK_C_INITIALIZE_ARGS` and extended NSS format.
 * - if `options` is null or empty, it calls native `C_Initialize` with `NULL`
 * - if `options` doesn't have `libraryParameters`, it uses `CK_C_INITIALIZE_ARGS` structure
 * - if `options` has `libraryParameters`, it uses extended NSS structure
 */
C_Initialize(options?: InitializationOptions): void;

Code

const mod = new pkcs11.PKCS11();
mod.load("/usr/local/opt/nss/lib/libsoftokn3.dylib");

mod.C_Initialize({
    libraryParameters: "configdir='' certPrefix='' keyPrefix='' secmod='' flags=readOnly,noCertDB,noModDB,forceOpen,optimizeSpace",
});

// Your code here

mod.C_Finalize();

More info about NSS params for C_Initialize

Example #11

Detect a slot event

var pkcs11js = require("pkcs11js");
var pkcs11 = new pkcs11js.PKCS11();
// Need a compliant Cryptoki Version 2.01 or later
pkcs11.load("/usr/local/lib/softhsm/libsofthsm2.so");

pkcs11.C_Initialize();

try {
    const slotId = pkcs11.C_WaitForSlotEvent(pkcs11js.CKF_DONT_BLOCK);
    if (slotId) {
        console.log(`Slot ${slotId} has been inserted`);
    } else {
        console.log(`No slot event`);
    }
} catch (e) {
    console.error(e);
} finally {
    pkcs11.C_Finalize();
}

Suitability

At this time this solution should be considered suitable for research and experimentation, further code and security review is needed before utilization in a production application.

Bug Reporting

Please report bugs either as pull requests or as issues in the issue tracker. Graphene has a full disclosure vulnerability policy. Please do NOT attempt to report any security vulnerability in this code privately to anybody.

Related

pkcs11js's People

Contributors

dependabot[bot] avatar huxd-ibm avatar l-ko avatar maxker avatar microshine avatar nickrmc83 avatar rmhrisk avatar sfauvart avatar thpun avatar wkledxow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pkcs11js's Issues

Segmentation Fault

pkcs11js version: "1.0.17",

I have been testing node-webcrypto-p11 and graphene with a feitian epass2003 token on ubuntu18, and everything seems to work, I can login(auth) and sign some data..

now I'm trying to make it work on a raspberry (4.14.98-v7+ ARM7l debian/raspbian), most tools, works ok (I can login and list the private cert with pkcs11-tool --module /usr/lib/arm-linux-gnueabihf/opensc-pkcs11.so --login --list-objects)

but it gives me error on Node. I isolated up to pkcs11js if I try a pkcs11.C_Login it exists with a "Segmentation Fault" message and nothing more...

is there someway to get more information or debug logs? pcscd doesn't show anything unnatural BTW

Load method affects on the app performance.

As you guys can see on my issue title when I use the load method to load the library, It affects my app performance (Renderer process).
I'm using this module in my electron project. Let me show my problem details.
I have a screen to the user can insert their PIN.
After pressing the submit button, it redirects to the loading screen. In this screen, I have a loading animation. At the time the app calls the load method, the loading bar is hanged out for a while.

Could you guys help me to figure out this problem?

Unable to run - npm install pkcs11js

gyp ERR! build error
gyp ERR! stack Error: C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (C:\Users\shutripathy\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\build.js:258:23)
gyp ERR! stack at emitTwo (events.js:125:13)
gyp ERR! stack at ChildProcess.emit (events.js:213:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Windows_NT 10.0.14393
gyp ERR! command "C:\Program Files\nodejs\node.exe" "C:\Users\shutripathy\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\shutripathy\pkcs11js\node_modules\pkcs11js
gyp ERR! node -v v8.6.0
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: node-gyp rebuild
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Unable to run npm install

npm ERR! Failed at the [email protected] install script 'npm run build'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the pkcs11js package,

95 error argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "install"
696 error node v6.9.1
697 error npm v3.10.8
698 error code ELIFECYCLE
699 error [email protected] install: npm run build
npm-debug.zip

ECDSA error when calling update

Hello,

I Believe I found a bug in the C_SignUpdate and C_VerifyUpdate for the ECDSA mechanism.
And I thought I should report it here to be registered.

I'm trying to sign/verify messages, but get an exception "CKR_OPERATION_NOT_INITIALIZED".

Here's some code where it happens:

// Initialize all things: lib, session, keys, etc
...

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_ECDSA }, myPrivateKey);
pkcs11.C_SignUpdate(session, new Buffer("Tiago")); // Here, exception thrown
signature = pkcs11.C_SignFinal(session, new Buffer(64));
...

The same happens with C_VerifyUpdate.

I thought I was doing something wrong, but this following code, using C_Sign, works like a charm:

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_ECDSA }, myPrivateKey);
var signature = pkcs11.C_Sign(session, new Buffer('Tiago'), new Buffer(64));

I don't have a clue why this happens.
I tried with the CKM_SHA256_RSA_PKCS sign mechanism and it works normally.

Well, that's it. If anyone needs more information, please let me know.

Cheers!

How get publicKeyId fom token?


    const _pkcs11FindObjects = (pkcs11, pkcs11Session, pkcs11Template) => {
        pkcs11.C_FindObjectsInit(pkcs11Session, pkcs11Template);
        var objs = [];
        var obj = pkcs11.C_FindObjects(pkcs11Session);
        while (obj) {
            objs.push(obj);
            obj = pkcs11.C_FindObjects(pkcs11Session);
        }
        pkcs11.C_FindObjectsFinal(pkcs11Session);
        return objs;
    }    

    PrivKeysHandle = _pkcs11FindObjects(pkcs11, session, [
        { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
        { type: pkcs11js.CKA_TOKEN, value: true },
        { type: pkcs11js.CKA_LABEL, value: "mylabel" },
    ])         
    
    // Get public_key_id...
    publicKeyId = pkcs11.C_GetAttributeValue(session, PrivKeysHandle[0], [{ type: 0x129 }])
    console.log('publicKey', publicKeyId[0].value.toString())


This not working
how i can get public key and pubKeyId from token ?
I have only private key on token

RSA encryption/decryption support

I'd like to verify that this module supports RSA encryption with public key.
There is an example in the README.md for signing/verifying, but how could I encrypt/decrypt with some RSA mechanism?

Cannot generate 32 bytes AES Secret

I wanted to generate a 32 bytes AES Secret Key with the code below. However, when I printed the length of the key, it is showing 8 instead of 32.

var path = require('path');
var pkcs11js = require("pkcs11js");
var crypto = require('crypto');
process.env['SOFTHSM2_CONF'] = path.resolve(__dirname, '../softhsm2.conf');

var pkcs11 = new pkcs11js.PKCS11();
pkcs11.load("/usr/local/Cellar/softhsm/2.4.0/lib/softhsm/libsofthsm2.so");

pkcs11.C_Initialize();

const _pkcs11FindObjects = (pkcs11, pkcs11Session, pkcs11Template) => {
    pkcs11.C_FindObjectsInit(pkcs11Session, pkcs11Template);
    var objs = [];
    var obj = pkcs11.C_FindObjects(pkcs11Session);
    while (obj) {
        objs.push(obj);
        obj = pkcs11.C_FindObjects(pkcs11Session);
    }
    pkcs11.C_FindObjectsFinal(pkcs11Session);
    return objs;
}

const _pkcs11Login = (slotNumber, pin) => {

    let s = null;
    try {
        const slots = pkcs11.C_GetSlotList(true);
        const slot = slots[slotNumber];
        var token_info = pkcs11.C_GetTokenInfo(slot);
        s = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION);
        pkcs11.C_Login(s, 1, pin);
        return s;
    } catch (e) {
        if (s != null) {
            pkcs11.C_CloseSession(s);
        }
        pkcs11.C_Finalize();
    }

}

const _findAESKey = (session, ski) => {
    var secretKeyHandle = _pkcs11FindObjects(pkcs11, session, [{
            type: pkcs11js.CKA_ID,
            value: ski
        },
        {
            type: pkcs11js.CKA_CLASS,
            value: pkcs11js.CKO_SECRET_KEY
        }
    ]);

    if (secretKeyHandle.length == 1) {
        return secretKeyHandle[0];
    } else {
        return null;
    }
}

const _createAESKey = (session, ski) => {

    let key = _findAESKey(session, ski);
    if (key && key !== null) {
        console.log('Key already exists. No need to re-create');
        return;
    }

    var template = [{
            type: pkcs11js.CKA_ID,
            value: ski
        },
        {
            type: pkcs11js.CKA_CLASS,
            value: pkcs11js.CKO_SECRET_KEY
        },
        {
            type: pkcs11js.CKA_TOKEN,
            value: true
        },
        {
            type: pkcs11js.CKA_LABEL,
            value: "My AES Key"
        },
        {
            type: pkcs11js.CKA_VALUE_LEN,
            value: 32
        },
        {
            type: pkcs11js.CKA_ENCRYPT,
            value: true
        },
        {
            type: pkcs11js.CKA_DECRYPT,
            value: true
        },
        {
            type: pkcs11js.CKA_PRIVATE,
            value: true
        }
    ];
    pkcs11.C_GenerateKey(session, {
        mechanism: pkcs11js.CKM_AES_KEY_GEN
    }, template);
}

let session = _pkcs11Login(0, '98765432');
_createAESKey(session, `9Rf3uJ7CEdKIhUvQu/2KN8hK0Kce0zYfPXSc8xAK4Oc=`);
let key = _findAESKey(session, `9Rf3uJ7CEdKIhUvQu/2KN8hK0Kce0zYfPXSc8xAK4Oc=`);
console.log(`key length: ${key.length}`); //key length: 8

The reason is I want to encrypt data using the function below which requires a key length of 32.

const encryptString = (s, secret) => {
    const iv = crypto.randomBytes(16).toString('hex').slice(0, 16);
    const cipher = crypto.createCipheriv('aes-256-ctr', secret, iv);
    const encrypted = cipher.update(String(s), 'utf8', 'hex') + cipher.final('hex');
    return iv + encrypted;
}

let e = encryptString('shezhuan sauce', key);
console.log(`encrypted string: ${e}`);

The above code will generate Invalid key length error

Type inconsistent error when trying to initialize GOST signing

I get a private key handle from Rutoken 2.0 ECP using your example:

var keys1 = {privateKey: null, publicKey: null};

pkcs11.C_FindObjectsInit(session, [
	{ type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
	{ type: pkcs11js.CKA_LABEL, value: label }
]);
var hObject = pkcs11.C_FindObjects(session);
while (hObject) {
	var attrs = pkcs11.C_GetAttributeValue(session, hObject, [
		{ type: pkcs11js.CKA_CLASS },
		{ type: pkcs11js.CKA_TOKEN },
		{ type: pkcs11js.CKA_LABEL }
	]);

	keys1.privateKey = hObject;
	hObject = pkcs11.C_FindObjects(session);
}
pkcs11.C_FindObjectsFinal(session);

I check that keys1.privateKey has a non null value, then try to initialize signing algorithm:

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_GOSTR3410_WITH_GOSTR3411 }, keys1.privateKey);

But this returns an error:

Error: CKR_KEY_TYPE_INCONSISTENT:99
    at Error (native) crypto_init:563

How pkcs11js handle Vendor specific attributes?

Hello, I have a project that using attributes that are vendor attributes that start 0x40000000. I wonder how will it translate or convert values from JS layer to API. Like number to number/ string of number to number. Is there a way I can specific or understand how it works?

PKCS11JS: Error CKR_KEY_FUNCTION_NOT_PERMITTED:104 on pkcs11.C_GenerateKeyPair

Hi,

I'm using a certified usb device to sign documents.

This my code:


var pkcs11js = require("./node_modules/pkcs11js");

var pkcs11 = new pkcs11js.PKCS11();
pkcs11.load("C:/Program Files/Gemalto/Classic Client/BIN/gclib.dll");

pkcs11.C_Initialize();

try {
// Getting info about PKCS11 Module
var module_info = pkcs11.C_GetInfo();
console.log("Module: ");
console.log(module_info);

// Getting list of slots
var slots = pkcs11.C_GetSlotList(true);
var slot = slots[0];
console.log("Slots: ");
console.log(slots);

// Getting info about slot
var slot_info = pkcs11.C_GetSlotInfo(slot);
console.log("Slot info: ");
console.log(slot_info);
// Getting info about token
var token_info = pkcs11.C_GetTokenInfo(slot);

// Getting info about Mechanism
var mechs = pkcs11.C_GetMechanismList(slot);
var mech_info = pkcs11.C_GetMechanismInfo(slot, mechs[0]);
console.log("Mechanisme ");
console.log(mech_info);

var session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION);
console.log("Session ");
console.log(session);

// Getting info about Session
var info = pkcs11.C_GetSessionInfo(session);
console.log("Session Info");
console.log(info);

pkcs11.C_Login(session, 1, "856489");

console.log("Info");    
console.log(pkcs11js.CKM_SHA256_RSA_PKCS);
console.log("Info 2"); 
console.log(pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN);

var publicKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My RSA Public Key" },
    { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: Buffer.from([1, 0, 1]) },
    { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 },
    { type: pkcs11js.CKA_VERIFY, value: true }
];

console.log("Public Key");
console.log(publicKeyTemplate);
console.log(pkcs11js.CKO_PUBLIC_KEY);

var privateKeyTemplate = [
    { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
    { type: pkcs11js.CKA_TOKEN, value: false },
    { type: pkcs11js.CKA_LABEL, value: "My RSA Private Key" },
    { type: pkcs11js.CKA_SIGN, value: true },
];

console.log("Private Key");
console.log(privateKeyTemplate);
console.log(pkcs11js.CKO_PRIVATE_KEY);

var keys = pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, publicKeyTemplate, privateKeyTemplate);

console.log("Keys");
console.log(keys);

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS },
    keys.privateKey); 

pkcs11.C_SignUpdate(session, new Buffer("Incomming message 1"));
pkcs11.C_SignUpdate(session, new Buffer("Incomming message N"));

var signature = pkcs11.C_SignFinal(session, Buffer(256));

pkcs11.C_Logout(session);
pkcs11.C_CloseSession(session);

}
catch(e){
console.error(e);
}
finally {
pkcs11.C_Finalize();
}


When the program try to generate the keys "pkcs11.C_GenerateKeyPair", i get : " Error CKR_KEY_FUNCTION_NOT_PERMITTED:104".

Can you help me to resolve the problem ??

load error

WARNING in ./node_modules/node-gyp-build/index.js 20:15-54
Critical dependency: the request of a dependency is an expression
@ ./node_modules/utf-8-validate/index.js
@ ./node_modules/ws/lib/Validation.js
@ ./node_modules/ws/lib/Receiver.js
@ ./node_modules/ws/index.js
@ ./app/platform/electron/socket.js
@ ./app/platform/electron/index.js
@ ./app/core/ui.js
@ ./app/index.js
@ multi webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr babel-polyfill ./app/index

ERROR in ./node_modules/pkcs11js/build/Release/pkcs11.node 1:2
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./node_modules/pkcs11js/index.js 2:0-44 2:0-44 8:21-59
@ ./node_modules/graphene-pk11/build/module.js
@ ./node_modules/graphene-pk11/build/index.js
@ ./app/views/login/form.js
@ ./app/views/login/index.js
@ ./app/views/index/app-view.js
@ ./app/views/index/index.js
@ ./app/index.js
@ multi webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr babel-polyfill ./app/index

Unable to Install pkcs11js

Node Version: 12.16.3
NPM Version: 6.14.4

I am getting this error when running npm install in my project directory. Is this an issue with my node version?

verbose stack Error: [email protected] install: `node-gyp rebuild`
8341 verbose stack Exit status 1
8341 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
8341 verbose stack     at EventEmitter.emit (events.js:310:20)
8341 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
8341 verbose stack     at ChildProcess.emit (events.js:310:20)
8341 verbose stack     at maybeClose (internal/child_process.js:1021:16)
8341 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
8342 verbose pkgid [email protected]
8343 verbose cwd /PATH/PATH/PATH
8344 verbose Darwin 19.3.0
8345 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "i"
8346 verbose node v12.16.3
8347 verbose npm  v6.14.4
8348 error code ELIFECYCLE
8349 error errno 1
8350 error [email protected] install: `node-gyp rebuild`
8350 error Exit status 1
8351 error Failed at the [email protected] install script.

key labels and key deletions

Thanks a lot for the pkcs11 interface for node.

One thing I would like to understand is that we are giving a key label during the key creation as well and then still we are passing an actual key during encryption and decryption methods.
Isn't there any way where in we can just pass the key label and the cleartext to encrypt and same key label and ciphertext to decrypt.
Furthermore, since this is a softhsm implementation. Are the keys stored permanently in the hsm. I was doing some tests on AES by generating the key and then by fetching the key as per the below 2 scenarios.

  1. Generate the AES key and print it in the same session. It is working.

Mechanism Info: {"minKeySize":16,"maxKeySize":32,"flags":131840}
Key generated: {"type":"Buffer","data":[2,0,0,0]}
Var hObject is: {"type":"Buffer","data":[2,0,0,0]}
Crypto HSM server listener is active on 2099

  1. Generate the AES key in one session. In the next session call only the print method. It is returning null.

Mechanism Info: {"minKeySize":16,"maxKeySize":32,"flags":131840}
Var hObject is: null
Crypto HSM server listener is active on 2099

Therefore, it seems keys are not persistent. Could you please help. I am new to hsm implementation.

CKR_GENERAL_ERROR:5

I am developing in windows environment. I am getting such an error.

PS C:\Users\thzbr\Desktop\test> node .\app.js
C:\Users\thzbr\Desktop\test\app.js:7
pkcs11.C_Initialize();
       ^

Error: CKR_GENERAL_ERROR:5
    at Error (native) PKCS11::C_Initialize:170
    at Object.<anonymous> (C:\Users\thzbr\Desktop\test\app.js:7:8)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

centos error

[root@localhost nodeTest]# npm install pkcs11js
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data
\

[email protected] install /root/nodeTest/node_modules/pkcs11js
node-gyp rebuild

make: Entering directory `/root/nodeTest/node_modules/pkcs11js/build'
CXX(target) Release/obj.target/pkcs11/src/main.o
In file included from ../src/pkcs11/error.h:6:0,
from ../src/pkcs11/v8_convert.h:13,
from ../src/pkcs11/param.h:5,
from ../src/const.h:17,
from ../src/main.cpp:4:
../src/pkcs11/scope.h:7:1: error: expected unqualified-id before ‘using’
using Scoped = std::shared_ptr;
^
In file included from ../src/pkcs11/v8_convert.h:13:0,
from ../src/pkcs11/param.h:5,
from ../src/const.h:17,
from ../src/main.cpp:4:
../src/pkcs11/error.h:12:2: error: ‘Scoped’ does not name a type
Scoped stack;
[root@localhost nodeTest]# npm install pkcs11js
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data
\

[email protected] install /root/nodeTest/node_modules/pkcs11js
node-gyp rebuild

make: Entering directory `/root/nodeTest/node_modules/pkcs11js/build'
CXX(target) Release/obj.target/pkcs11/src/main.o
In file included from ../src/pkcs11/error.h:6:0,
from ../src/pkcs11/v8_convert.h:13,
from ../src/pkcs11/param.h:5,
from ../src/const.h:17,
from ../src/main.cpp:4:
../src/pkcs11/scope.h:7:1: error: expected unqualified-id before ‘using’
using Scoped = std::shared_ptr;
^
In file included from ../src/pkcs11/v8_convert.h:13:0,
from ../src/pkcs11/param.h:5,
from ../src/const.h:17,
from ../src/main.cpp:4:
../src/pkcs11/error.h:12:2: error: ‘Scoped’ does not name a type
Scoped stack;

How to read and generate X.509 certificate stored on usb token in js

Hi Experts,
I am using Gemalto usb token for my Javascript application. I am accessing token's functionality through PKCS11 Javascript library.

I've been able to: Generate public and private key, encrypt/decrypt, sign/verify.

But the main problem is:
How can i read attributes of certificate stored inside the token using Javascript code?, so that I can move on to the next step, which will be the signature of the pdf document via this certificate (always using javascript).

I thoroughly looked through the PKCS#11 documentation, and over the Internet, but I couldn't find answer to my question.

I would appreciate any hints to solve this problem.
Thanks for help.

pkijs vs pkcs11js use cases

Sorry, this question may not be posted in the correct channel. but I am trying to figure out when to use which library. It feels like to me pkcs11js is a subset of the pkijs. If I just want to work with softhsm, then pkcs11js is enough for me. thanks,

Error: Win32 error 126 at Error (native) PKCS11::Load:129

when running the tests this error occurred which can be
D:\ProjetoJs\Desktop\pocDesktop\Certificado\graphene\graphene>npm run test

[email protected] test D:\ProjetoJs\Desktop\pocDesktop\Certificado\graphene\graphene
mocha

AES
1) "before all" hook
2) "after all" hook

Digest
3) "before all" hook
4) "after all" hook

ECDSA
5) "before all" hook
6) "after all" hook

Module
7) load
8) initialize/finalize
9) getSlots
10) props

Object
11) "before all" hook
12) "after all" hook

RSA
13) "before all" hook
14) "after all" hook

Session
15) "before all" hook
16) "after all" hook

Slot
17) "before all" hook
18) "after all" hook

0 passing (20ms)
18 failing

  1. AES "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\aes.js:30:16)

  2. AES "after all" hook:
    TypeError: Cannot read property 'finalize' of undefined
    at Context. (test\aes.js:43:13)

  3. Digest "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\digest.js:13:22)

  4. Digest "after all" hook:
    TypeError: Cannot read property 'closeAll' of undefined
    at Context. (test\digest.js:19:14)

  5. ECDSA "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\ec.js:30:22)

  6. ECDSA "after all" hook:
    TypeError: Cannot read property 'finalize' of undefined
    at Context. (test\ec.js:43:13)

  7. Module load:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\module.js:16:23)

  8. Module initialize/finalize:
    AssertionError [ERR_ASSERTION]: Got unwanted exception.
    at innerThrows (assert.js:653:7)
    at Function.doesNotThrow (assert.js:665:3)
    at Context. (test\module.js:20:16)

  9. Module getSlots:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\module.js:29:26)

  10. Module props:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\module.js:39:26)

  11. Object "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\object.js:14:22)

  12. Object "after all" hook:
    TypeError: Cannot read property 'logout' of undefined
    at Context. (test\object.js:25:17)

  13. RSA "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\rsa.js:30:22)

  14. RSA "after all" hook:
    TypeError: Cannot read property 'finalize' of undefined
    at Context. (test\rsa.js:40:13)

  15. Session "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\session.js:13:22)

  16. Session "after all" hook:
    TypeError: Cannot read property 'finalize' of undefined
    at Context. (test\session.js:21:13)

  17. Slot "before all" hook:
    Error: Win32 error 126
    at Error (native) PKCS11::Load:129
    at Function.Module.load (build\module.js:44:13)
    at Context. (test\slot.js:12:22)

  18. Slot "after all" hook:
    TypeError: Cannot read property 'finalize' of undefined
    at Context. (test\slot.js:17:13)

npm ERR! code ELIFECYCLE
npm ERR! errno 18
npm ERR! [email protected] test: mocha
npm ERR! Exit status 18
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Anizair\AppData\Roaming\npm-cache_logs\2017-10-19T13_06_27_398Z-debug.log

I'm using Windows 7 64bit with SoftHSM2

Update cases for C_GetAttributeValue

For each (type, pValue, ulValueLen) triple in the template, C_GetAttributeValue performs the following algorithm:

  • If the specified attribute (i.e., the attribute specified by the type field) for the object cannot be revealed because the object is sensitive or unextractable, then the ulValueLen field in that triple is modified to hold the value -1 (i.e., when it is cast to a CK_LONG, it holds -1).
  • Otherwise, if the specified attribute for the object is invalid (the object does not possess such an attribute), then the ulValueLen field in that triple is modified to hold the value -1.
  • Otherwise, if the pValue field has the value NULL_PTR, then the ulValueLen field is modified to hold the exact length of the specified attribute for the object.
  • Otherwise, if the length specified in ulValueLen is large enough to hold the value of the specified attribute for the object, then that attribute is copied into the buffer located at pValue, and the ulValueLen field is modified to hold the exact length of the attribute.
  • Otherwise, the ulValueLen field is modified to hold the value -1.

C_Login CKR_FUNCTION_NOT_SUPPORTED

I am trying to sign a PDF signature using a Gemalto USB Key Smart Card. I am able to find the slot, open session and generally access it, but I am not able to Login with PIN.

Usually you have to enter the PIN during the signing process, for example you select the certificate from the list in Adobe Reader, then choose to sign with it after which you are shown the window to enter the PIN.

C_Login & C_Logout both return CKR_FUNCTION_NOT_SUPPORTED.

Here is some info and the code.

Using pvpkcs11.dll as library (from Fortify app).
C_GetInfo
image

C_GetSlotInfo
image

C_GetTokenInfo (seems to be lacking data)
image

While trying to login, I receive the following error:
**pkcs11.C_Login(session, 1, 1234);**
image

HOWEVER if I comment out the login, the rest of the signing process successfully completes and the verfication of the signature returns as true. Afterwards I attach this signature to an actual PDF document on the server side (C# .NET Core), where it shows as invalid.

const lib = 'pvpkcs11_fortify.dll';
const pkcs11 = new pkcs11js.PKCS11();
pkcs11.load(lib);
pkcs11.C_Initialize();

const slots = pkcs11.C_GetSlotList(true);
const slot = slots[1];

const session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_SERIAL_SESSION);
// pkcs11.C_Login(session, 1, 1234); // GEMALTO UNSUPPORTED?

const publicKeyTemplate = [
  { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PUBLIC_KEY },
  { type: pkcs11js.CKA_TOKEN, value: false },
  { type: pkcs11js.CKA_LABEL, value: 'My RSA Public Key' },
  { type: pkcs11js.CKA_PUBLIC_EXPONENT, value: Buffer.from([1, 0, 1]) },
  { type: pkcs11js.CKA_MODULUS_BITS, value: 2048 },
  { type: pkcs11js.CKA_VERIFY, value: true }
];

const privateKeyTemplate = [
  { type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_PRIVATE_KEY },
  { type: pkcs11js.CKA_TOKEN, value: false },
  { type: pkcs11js.CKA_LABEL, value: 'My RSA Private Key' },
  { type: pkcs11js.CKA_SIGN, value: true },
];

const keys = pkcs11.C_GenerateKeyPair(session, { mechanism: pkcs11js.CKM_RSA_PKCS_KEY_PAIR_GEN }, publicKeyTemplate, privateKeyTemplate);

pkcs11.C_SignInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.privateKey);

const pdfBinary = decodeFromBase64(bytesToSign); // data to sign

pkcs11.C_SignUpdate(session, new Buffer(pdfBinary));

const signature = pkcs11.C_SignFinal(session, new Buffer(256));

pkcs11.C_VerifyInit(session, { mechanism: pkcs11js.CKM_SHA256_RSA_PKCS }, keys.publicKey);

pkcs11.C_VerifyUpdate(session, new Buffer(pdfBinary));

const verify = pkcs11.C_VerifyFinal(session, signature);

// pkcs11.C_Logout(session); // GEMALTO UNSUPPORTED?
pkcs11.C_CloseSession(session);

Cannot do npm install on Mac

Hi, having trouble doing npm install.

Please can you help? Thanks!

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'build' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle [email protected]prebuild: [email protected]
6 info lifecycle [email protected]
build: [email protected]
7 verbose lifecycle [email protected]build: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]
build: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/projectpath/node_modules/pkcs11js/node_modules/.bin:/Users/projectpath$
9 verbose lifecycle [email protected]build: CWD: /Users/projectpath/node_modules/pkcs11js
10 silly lifecycle [email protected]
build: Args: [ '-c', 'node-gyp configure build' ]
11 silly lifecycle [email protected]build: Returned: code: 1 signal: null
12 info lifecycle [email protected]
build: Failed to exec build script
13 verbose stack Error: [email protected] build: node-gyp configure build
13 verbose stack Exit status 1
13 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:289:16)
13 verbose stack at emitTwo (events.js:125:13)
13 verbose stack at EventEmitter.emit (events.js:213:7)
13 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)
13 verbose stack at emitTwo (events.js:125:13)
13 verbose stack at ChildProcess.emit (events.js:213:7)
13 verbose stack at maybeClose (internal/child_process.js:927:16)
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
14 verbose pkgid [email protected]
15 verbose cwd /Users/projectpath/node_modules/pkcs11js
16 verbose Darwin 16.7.0
17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build"
18 verbose node v8.4.0
19 verbose npm v5.3.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] build: node-gyp configure build
22 error Exit status 1
23 error Failed at the [email protected] build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

version reference issue

"This was developed to the PKCS#11 2.3 specification, the 2.4 headers were not availible at the time we created this, it should be easy enough to extend it for the new version at a later date."

This needs to be corrected - there is no such version as 2.3 or 2.4 - there is 2.30 and 2.40
The official current version is 2.40
The OASIS PKCS#11 technical committee are working on 3.0

AES_KEY_WRAP reporting CKR_MECHANISM_INVALID

I'm using graphene to try to wrap an AES key stored in SoftHSM2. Here is the code:

mech = { name: 'AES_KEY_WRAP', params: new Buffer([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) }; 
wKey = _session.wrapKey(mech, wrappingKeyObj, keyObj); 

I get the following error:
CKR_MECHANISM_INVALID:112\n at Error (native) C_WrapKey:949

I noticed the values for AES_KEY_WRAP are different in pkcs11js and SoftHSM2 as follows:

Pkcs11js:
#define CKM_AES_KEY_WRAP 0x00001090

SoftHSM2:
#define CKM_AES_KEY_WRAP (0x2109UL)

Is there a workaround for this?

Thanks,
Jas

Is it possible to access pkcs11 interface from webapp?

Hi.
I'm currently making a webapp with React, and I would like users to be able to use their smartcard to authenticate their id.

Using pkcs11-tool on command line worked perfect with my smartcard. Now how can I integrate it with my webapp? Is this the right package? I'm kind of lost...

CK_ULONG type attribute value in template can't be passed correctly on s390x

when invoking function that requires template, for example C_GenerateKeyPair, if we want to pass in some CK_ULONG type attribute in the template, for example CKA_KEY_TYPE, the value could not be passed correctly on s390x.

if we look at function v2c_ATTRIBUTE in file src/pkcs11/template.cpp, when v8Value->IsNumber() is true, if we try to print both value of "num" and value of *(CK_ULONG*)attr->pValue using format %lu, we will see they actually have different value.
change the way to copy value of num to attr-pValue can fix the problem:
*(CK_ULONG*)attr->pValue = num;

Templete Incomplete when when creating data object

I trying example in the read me to Create Object with Yubikey 4.

I get Error: CKR_TEMPLATE_INCOMPLETE:208

when calling:

var nObject = pkcs11.C_CreateObject(session, [
{ type: pkcs11js.CKA_CLASS, value: pkcs11js.CKO_DATA },
{ type: pkcs11js.CKA_TOKEN, value: false },
{ type: pkcs11js.CKA_PRIVATE, value: false },
{ type: pkcs11js.CKA_LABEL, value: "My Label" },
]);

Any suggestions please?

Using `pkcs11js` and native `crypto` within one runtime causes errors

Hi,

We are using the pkcs11js library, version 1.0.9 in combination with SoftHSMv2.

Everything worked fine until recently we added a module that relies on the native crypto module for signing purposes. Once the pkcs11js lib is loaded the signing fails, complaining about a shared library that could not be loaded. In the demo snippet below, sign try 1 works and sign try 2 fails.

Any hints on what the root cause might be, an maybe some hints for a solution? It looks that both libraries are accessing the same (libcrypto?) shared library, causing issues.

Node Version: 8.4.0

Demo Snippet

const crypto = require('crypto');
const pkcs11js = require('pkcs11js');
const fs = require('fs');

const privKey = fs.readFileSync('./test');
const privKeyString = privKey.toString('ascii'); 


function mainTest() {


  const thing = 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlRGVTNDUTNYNTgifQ.eyJpYXQiOjE1MDcyNzU5NTAsImlzcyI6IjcySzhRV1ZSRVQifQ';
  console.log('CREATE SIGN');
  
  // SIGN TRY 1
  const signer = crypto.createSign('RSA-SHA256');
  console.log('SIGNING')
  const res = (signer.update(thing), signer.sign(privKey));
  console.log(res);
  
  // LOAD PKCS11 With SoftHSM
  console.log('LOAD PKCS11');
  const pkcs11 = new pkcs11js.PKCS11();
  pkcs11.load('/usr/local/lib/softhsm/libsofthsm2.so');
  pkcs11.C_Initialize();
  const slots = pkcs11.C_GetSlotList(true);
  const slot = slots[0];
  const session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION);
  pkcs11.C_Login(session, 1, "1234");

  // SIGN TRY 2
  const signer2 = crypto.createSign('RSA-SHA256');
  console.log('SIGNING 2')
  const res2 = (signer2.update(thing), signer2.sign(privKey));
  console.log(res2);
}

try {
  mainTest();
} catch(e) {
  console.log("ERROR");
  console.log(e);
}

Resulting Error

Error: error:25066067:DSO support routines:DLFCN_LOAD:could not load the shared library
    at Sign.sign (crypto.js:329:26)
    at mainTest (/usr/src/test/app.js:38:48)
    at Object.<anonymous> (/usr/src/test/app.js:47:3)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)

Passing CK_ATTRIBUTE_PTR to vendor specific mechanism

Hi,
First i would like to thanks you for develloping such project.

I would like to use a vendor derivation mechanism that expect such structure:

typedef struct CK_VENDOR_DERIVE_PARAMS {
    CK_ATTRIBUTE_PTR pPublicKeyTemplate;
    CK_ULONG ulPublicKeyAttributeCount;
    CK_ATTRIBUTE_PTR pPrivateKeyTemplate;
    CK_ULONG ulPrivateKeyAttributeCount;
    CK_OBJECT_HANDLE hPublicKey; // output parameter
    CK_OBJECT_HANDLE hPrivateKey; // output parameter
} CK_VENDOR_DERIVE_PARAMS;


to be passed as deriveMech.pParameter = &vendor_Params;
i try to get inspiration from param_ecdh
Yet, i'm not expert in node binding, and before commiting to much time in finding a nasty way to do this :) maybe you can point me the right way to pass template definition from v8 to c++
Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.