Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C_Login CKR_FUNCTION_NOT_SUPPORTED #57

Open
spanmatej opened this issue Dec 4, 2019 · 46 comments
Open

C_Login CKR_FUNCTION_NOT_SUPPORTED #57

spanmatej opened this issue Dec 4, 2019 · 46 comments

Comments

@spanmatej
Copy link

spanmatej commented Dec 4, 2019

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);
@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 4, 2019

Within fortify can you send us the log of whe you use the fortify app to generate a CSR on this card?

@spanmatej
Copy link
Author

I suppose I didn't provide enough context as to how I am using pkcs11js exactly..

This code lives inside an Electron Angular app. I am not directly using Fortify, only it's .dll to provide the layer for communication with smart cards.

I haven't found much information online on how exactly you get to these libraries, so that's why I used Fortify's dll, as it's the most relevant in my use case.

I would love to get some more insights in how exactly I should go about this.

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 4, 2019

The error you are having suggests there is something your smart card isn’t supporting related to login.

It is easier for us to troubleshoot this if you use Fortify, enable logging, perform the CSR generation, send us a log.

@spanmatej
Copy link
Author

Thank you for the suggestion. Will do that as soon as possible and report back to you.

@spanmatej
Copy link
Author

spanmatej commented Dec 4, 2019

While starting Fortify, I am presented with the notice that the smart card is not supported and if I'd like to request support.

Reader name: Gemalto USB Key Smart Card Reader 0
ATR: 3B7D96000080318065B0830201F383009000

{
   "cards": [{
   	"atr": "3B7D96000080318065B0830201F383009000",
   	"name": "Token name",
   	"driver": "B1B9E460251886FDB4207F3D1D243AB05A6AF3D6"
   }],
   "drivers": [{
   	"id": "B1B9E460251886FDB4207F3D1D243AB05A6AF3D6",
   	"name": "Driver name",
   	"file": {
   		"windows": "path/to/pkcs11.dll",
   		"osx": "path/to/pkcs11.dylib"
   	}
   }]
}

Smart card ATR parsing 3B7D96000080318065B0830201F383009000

It is the same token as in the following issue: PeculiarVentures/fortify#120

Nexus Personal is usually used with the smart card.
image

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 5, 2019

The card itself appears to be aGemalto IDClassic 340

Is that correct? Or is this some other card that’s been provisioned onto this card?

What PKCS11 library do you use with this card?

Where on your system do you find that PKCS11 library?

Does this card have a certificate on it already and read only (most National ID cards) or is it blank that you can arbitrary things to?

@spanmatej
Copy link
Author

spanmatej commented Dec 5, 2019

I do not know the exact name at this time but I would presume so. There is no information about it in the Nexus client nor the SafeNet Authorization client, which usually shows all the relevant card information. It's over 3 years old and searching through the internet I can see that it probably is the IDClassic one.

I am not using a specific library myself. What I am using is the Nexus Personal client which allows me to enter the PIN while signing data.

The card does have a certificate on it and is regularly used to access certificate-restricted government /bank sites and to manually sign PDF documents.

These are the .dll files of the program, also listed as "components" in the program itself.
image
image
image
image

@microshine
Copy link
Contributor

You can add your token to Fortify config file ~/.fortify/config.json. Please don't forget to restart your Fortify application.

Example

{
  "locale": "en",
  "logging": true,
  "cards": [
    {
      "atr": "3b8b015275746f6b656e20445320c1",
      "libraries": [
        "/usr/local/lib/librtpkcs11ecp1.dylib"
      ],
      "name": "Rutoken",
      "readOnly": true
    }
  ]
}

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 6, 2019

This suggests (https://doc.nexusgroup.com/display/PUB/Personal+Desktop+Client+overview) that the nexus client includes a mini driver and a PKCS#11.

As per @microshine's comment if you can specify which one to use in the fortify config file it should work. Once you confirm we can add it to the global config.

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 6, 2019

It seems maybe this smart card is related to Swedish BankID (www.bankid.com)?

According to this The software client includes both a CSP and a PKCS11 module that is, however, not used nor formally supported.

I've asked a knowlegable friend for more information here : https://twitter.com/rmhrisk/status/1202905241177542656?s=20

@spanmatej
Copy link
Author

The smart card is issued by Halcom (http://www.halcom.si/en/) a Slovenian provider of digital certification software/products. I am not aware of any connection between them and the Swedish BankID.

As suggested, I found the library which Nexus Personal is using (personal64.dll) and am trying it out at the moment. I will shorty report if there is any more information available through it.

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 6, 2019

Actually I may have found it; according to this it is personal.dll.

If so I think the configuration you need to test would be:

{
	"cards": [{
		"atr": "3B7D96000080318065B0830201F383009000",
		"name": "Gemalto IDClassic 340",
		"driver": "0da8b1af9bd641a8955316eebf393b4d",
		"readOnly": true
	}],
	"drivers": [{
		"id": "71789068c5ff4891aeeaf7fb9608a22f",
		"name": "Nexus Personal,
		"file": {
			"windows": {
				"x86": "%PROGRAMFILES(X86)/Personal/bin/personal.dll"
				"x64": "%PROGRAMFILES/Personal/bin/personal64.dll"
			}
		}
	}]
}

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 6, 2019

Please try the above configuration and see if it works.

@spanmatej
Copy link
Author

spanmatej commented Dec 6, 2019

I have tested the library with pkcs11js and I have successfully logged in with the correct PIN. The token info is now populated and shows the correct manufacturer and serial number, which means this is the correct one to be used.

I am now presented with the error CKR_GENERAL_ERROR at crypto_final:637 on line:
const signature = pkcs11.C_SignFinal(session, new Buffer(256));

Any ideas as to how to check what causes this?

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 6, 2019

We will need the fortify log associated with that transaction.

@spanmatej
Copy link
Author

Do you mean generating a CSR?

I don't know how I would do the signing process with Fortify or how it is connected with it in any way, as I am using pkcs11js inside an Angular Electron application.

Please advise on how to get some more information out of the error, as that is all I get:
Error: CKR_GENERAL_ERROR:5 at Error (:4200/native) crypto_final:637

Do you know of any tool I could use to check if the signing process works manually (Windows)?

@microshine
Copy link
Contributor

image
You can enable logging and get a detailed exception message

@spanmatej
Copy link
Author

spanmatej commented Dec 6, 2019

I am aware of the process for enabling and checking the log and I have checked it after the signing process but nothing is logged inside it.

And how would Fortify know of any signing process outside the app itself? I need some more explanation on that.

Note: I am using pkcs11js by itself, stand-alone inside an Electron app, not connected to Fortify in any way.

@microshine
Copy link
Contributor

I am using pkcs11js inside an Angular Electron application

Can you share a part of your source code where you are using pkcs11js

It's interesting to see which mechanisms you are using for signing

@spanmatej
Copy link
Author

Here is the updated code from my initial issue comment:

const lib = 'personal64.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');

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, Buffer.from(pdfBinary));

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

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

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

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

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

@microshine
Copy link
Contributor

try to increase buffer for a signature object to 1024

@spanmatej
Copy link
Author

spanmatej commented Dec 6, 2019

try to increase buffer for a signature object to 1024

Did so, no effect, the same error persists..

@microshine
Copy link
Contributor

this is strange

  1. PKCS#11 libraries support own loggers. You can try to enable it and get additional information about that error

  2. You can try to use another mechanism CKM_RSA_PKCS1 (if your token supports it)
    2.1 Compute hash from data you want to sign
    2.2 Compute signature from hash value

@microshine
Copy link
Contributor

@spanmatej Please try node-webcrypto-p11 module.

const { Crypto } = require("node-webcrypto-p11");

async function main() {
  const crypto = new Crypto({
    library: "personal64.dll",
    slot: 1,
    pin: "1234",
  });

  const alg = {
    name: "RSASSA-PKCS1-v1_5",
    hash: "SHA-256",
    publicExponent: new Uint8Array([1, 0, 1]),
    modulusLength: 2048,
  }

  const keys = await crypto.subtle.generateKey(alg, false, ["sign", "verify"])
  
  const data = Buffer.from("some message to be signed");
  const signature = await crypto.subtle.sign(alg, keys.privateKey, data);
  const ok = await crypto.subtle.verify(alg, keys.publicKey, signature, data);

  console.log("Signature:", ok);
}

main().catch((e) => console.error(e));

@spanmatej
Copy link
Author

@microshine I'm sorry for the late response.

Error still persists, even though now instead of pointing to crypto_final, it points to crypto_update.

const signature = await crypto.subtle.sign(alg, keys.privateKey, data);

Error: Uncaught (in promise): Error: CKR_GENERAL_ERROR:5
    at Error (native) crypto_update:592

@rmhrisk
Copy link
Contributor

rmhrisk commented Dec 7, 2019

I am aware of the process for enabling and checking the log and I have checked it after the signing process but nothing is logged inside it.

And how would Fortify know of any signing process outside the app itself? I need some more explanation on that.

Note: I am using pkcs11js by itself, stand-alone inside an Electron app, not connected to Fortify in any way.

Can you, as requested earlier, add support for your smart card to fortify with the above details, use fortify to create a CSR, and send the log.

It is easier for us to troubleshoot this if
you use Fortify, enable logging, perform > the CSR generation, send us a log.

This may tell us something new.

Alternatively maybe you can contact your middleware provider for examples of how to perform a working transaction with their middleware.

Each P11 unfortunately behaves a little different, some more than others. This is made worse by the middleware returning awesome errors like GENERAL ERROR. Some offer additional logging that can be enabled to see what it was doing when the error was encountered which can help tease out why the middleware is not happy.

@microshine
Copy link
Contributor

@spanmatej What about node-webcrypto-p11 application. Does it throw the same exception?

@microshine
Copy link
Contributor

microshine commented Dec 7, 2019

I found some information about personal64.dll logging

https://blog.goranrakic.com/uploads/pkcs11_putanje.pdf

Name Windows 32bit Windows 64bit
Nexus Personal C:\Program Files (x86)\Personal\bin\personal.dll C:\Program Files (x86)\Personal\bin64\personal64.dll

https://doc.nexusgroup.com/display/PUB/Personal+Desktop+Client+user%27s+guide

Nexus desktop client

Logging is enabled by default.

To disable logging:

  1. Edit personal.cfg.
  2. Set Enabled to 0 under section Diagnostics.


The files are located at:

On Windows: %APPDATA%\Personal\log

@spanmatej
Copy link
Author

@microshine My previous comment is from using the node-webcrypto-p11 module. It also produces that error.

Thank you for finding that! I will try enabling the logging and get back to you with more info.

@rmhrisk I added the suggested data inside the config file, done the CSR generation and this is the log.

{"message":"Application started at Sat Dec 07 2019 15:49:14 GMT+0100 (Central European Standard Time)","level":"info"}
{"message":"OS win32 x64 ","level":"info"}
{"message":"Fortify v1.0.20","level":"info"}
{"message":"System locale is 'en-US'","level":"info"}
{"message":"Locale: Set language to 'en'","level":"info"}
{"message":"Fortify: Create window index","level":"info"}
{"message":"Update: Check for new update","level":"info"}
{"message":"Update: New version wasn't found","level":"info"}
{"message":"SSL certificate is loaded","level":"info"}
{"message":"Comparing current version of card.json file with remote","level":"info"}
{"message":"card.json has the latest version","level":"info"}
{"message":"Server: Started at 127.0.0.1:31337","level":"info"}
{"message":"Provider: Add crypto 'Windows CryptoAPI' 9f7dab1bb0d6c10da015c3dd4aa20393548bac2b","level":"info"}
{"message":"Provider:AddCrypto: PKCS#11 'C:\\Program Files\\Fortify\\pvpkcs11.dll' 'C:\\Program Files\\Fortify\\pvpkcs11.dll'","level":"info"}
{"message":"Provider:Opened","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS ifdh 0","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS ifdh 1","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS VR 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Gemalto USB Key Smart Card Reader 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Rainbow Technologies iKeyVirtualReader 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Rainbow Technologies iKeyVirtualReader 1","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS ifdh 0","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS ifdh 1","level":"info"}
{"message":"PCSCWatcher: New reader detected AKS VR 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Gemalto USB Key Smart Card Reader 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Rainbow Technologies iKeyVirtualReader 0","level":"info"}
{"message":"PCSCWatcher: New reader detected Rainbow Technologies iKeyVirtualReader 1","level":"info"}
{"message":"PCSCWatcher:Insert reader:'Gemalto USB Key Smart Card Reader 0' ATR:3b7d96000080318065b0830201f383009000","level":"info"}
{"message":"PCSCWatcher:Insert reader:'Gemalto USB Key Smart Card Reader 0' ATR:3b7d96000080318065b0830201f383009000","level":"info"}
{"message":"TypeError: customCard.libraries is not iterable\n    at CardWatcher.getCard (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:938:43)\n    at PCSCWatcher.<anonymous> (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:854:41)\n    at PCSCWatcher.emit (events.js:194:13)\n    at Timeout._onTimeout (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:798:38)\n    at listOnTimeout (internal/timers.js:535:17)\n    at processTimers (internal/timers.js:479:7)","level":"error"}
{"message":"TypeError: customCard.libraries is not iterable\n    at CardWatcher.getCard (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:938:43)\n    at PCSCWatcher.<anonymous> (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:854:41)\n    at PCSCWatcher.emit (events.js:194:13)\n    at Timeout._onTimeout (C:\\Program Files\\Fortify\\resources\\app.asar\\node_modules\\@webcrypto-local\\server\\build\\index.js:798:38)\n    at listOnTimeout (internal/timers.js:535:17)\n    at processTimers (internal/timers.js:479:7)","level":"error"}
{"message":"Server: New session connect https://tools.fortifyapp.com","level":"info"}
{"message":"Server: Push session to stack","level":"info"}
{"message":"Server: Cannot parse MessageSignedProtocol","level":"info"}
{"message":"Server: Initialize secure session origin:https://tools.fortifyapp.com id:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 authorized:true","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 server/isLoggedIn","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider/action/info","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider/action/getCrypto","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/isLoggedIn","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider/action/getCrypto","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/isLoggedIn","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/keyStorage/keys","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/keys","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider/action/getCrypto","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/subtle/generateKey","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/subtle/exportKey","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/subtle/sign","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/import","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/setItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/keyStorage/setItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/keyStorage/setItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/getItem","level":"info"}
{"message":"Server: session:94ce20c1f25f17967fead981d90d745a6e826cf0a9a14d7b9b3e327708196927 provider:9f7dab1bb0d6c10da015c3dd4aa20393548bac2b crypto/certificateStorage/export","level":"info"}

@spanmatej
Copy link
Author

spanmatej commented Dec 7, 2019

@microshine The logging/diagnostics was actually already enabled and the log file was present.

As there is no functional difference between node-webcrypto-p11 and pkcs11js, except for it adding an additional layer, I'm going forward with pkcs11js at this moment, so all logging is relevant to that code.

I've checked the log and I can't find anything relevant myself, except for this message (logged after SignFinal starts):
2019-12-07 16:11:29 [9584:5680] CEnginePSCBaseNoHash<64>::CreateSignature - No pin object found.

Would this mean that I would need to provide the PIN again for the signing process, even though the login was a success? Is there any case with such a procedure?

pkcs11.log

@microshine
Copy link
Contributor

Have you tried to use another hash mechanism?

Try SHA-1

@spanmatej
Copy link
Author

Have you tried to use another hash mechanism?

Try SHA-1

@microshine Unfortunately, the same thing happens.
pkcs11.log

@microshine
Copy link
Contributor

microshine commented Dec 7, 2019

Would this mean that I would need to provide the PIN again for the signing process, even though the login was a success? Is there any case with such a procedure?

@spanmatej Please try to get CKA_ALWAYS_AUTHENTICATE attribute from your private key

If CK_TRUE, the user has to supply the PIN for each use (sign or decrypt) with the key. Default is CK_FALSE.

@microshine
Copy link
Contributor

Re-authentication occurs by calling C_Login with userType set to CKU_CONTEXT_SPECIFIC
immediately after a cryptographic operation using the key has been initiated (e.g. after C_SignInit).

@spanmatej
Copy link
Author

@microshine I am not sure how to get the CKA_ALWAYS_AUTHENTICATE attribute exactly. I got it once before but I switched between graphene, node-webcrypto, pkcs11js so many times that I forgot and I'm lost..

pkcs11js.CKA_ALWAYS_AUTHENTICATE returns value 514 which doesn't seem right as that is probably just it's assigned value.

I'd like to note that I messed up in my code at opening the session, instead of (suggested in documentation):
pkcs11.C_OpenSession(slot, pkcs11js.CKF_RW_SESSION | pkcs11js.CKF_SERIAL_SESSION);
I had the following for whatever reason:
pkcs11.C_OpenSession(slot, pkcs11js.CKF_SERIAL_SESSION);

Without knowing the value of CKA_ALWAYS_AUTHENTICATE, I went ahead and did as suggested, calling login immediately after SignInit with CKU_CONTEXT_SPECIFIC user:
pkcs11.C_Login(session, pkcs11js.CKU_CONTEXT_SPECIFIC, '1234');

That causes:
CKR_USER_ANOTHER_ALREADY_LOGGED_IN

I'm sorry for the dumb questions at times.. I'm doing my best to get a deeper understanding of all this and it's a lot to take in. I really do appreciate all the help.

@microshine
Copy link
Contributor

I'll create a script. ~10 minutes

@microshine
Copy link
Contributor

microshine commented Dec 7, 2019

You need update lib, pin and slotIndex values

const pkcs11js = require("pkcs11js");

const lib = '/usr/local/Cellar/softhsm/2.5.0/lib/softhsm/libsofthsm2.so';
const pin = '12345';
const slotIndex = 0;

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

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

const session = pkcs11.C_OpenSession(slot, pkcs11js.CKF_SERIAL_SESSION);
pkcs11.C_Login(session, pkcs11js.CKU_USER, pin); // 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);

// Check private key attribute
const alwaysAuthenticate = pkcs11.C_GetAttributeValue(session, keys.privateKey, [{ type: pkcs11js.CKA_ALWAYS_AUTHENTICATE }])[0].value;
if (alwaysAuthenticate.length && alwaysAuthenticate[0]) {
  pkcs11.C_Login(session, pkcs11js.CKU_CONTEXT_SPECIFIC, pin);
}

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);

@spanmatej
Copy link
Author

CKR_ATTRIBUTE_TYPE_INVALID PKCS11::C_GetAttributeValue:447
at
pkcs11.C_GetAttributeValue(session, keys.privateKey, [{ type: pkcs11js.CKA_ALWAYS_AUTHENTICATE }])[0].value;

logged:

2019-12-07 17:43:20 [11008:9564] C_SignInit: hSession = 0x1, Mechanism = 0x40, hKey = 0x2
2019-12-07 17:43:20 [11008:9564] Return 0x0
2019-12-07 17:43:20 [11008:9564] C_GetAttributeValue: hSession = 0x1, hObject = 0x2
2019-12-07 17:43:20 [11008:9564] CProfile::GetAttributeValues() failed, rv = 0x12
2019-12-07 17:43:20 [11008:9564] C_GetAttributeValue: Session get attribute value failed
2019-12-07 17:43:20 [11008:9564] Template[0] type : CKA_ALWAYS_AUTHENTICATE
2019-12-07 17:43:20 [11008:9564]             value: NULL
2019-12-07 17:43:20 [11008:9564] Return 0x12

@microshine
Copy link
Contributor

Please comment this attr getting and call your app again. It must login to session with CKU_CONTEXT_SPECIFIC after C_SignInit

@microshine
Copy link
Contributor

I mean to call pkcs11.C_Login(session, pkcs11js.CKU_CONTEXT_SPECIFIC, pin) without CKA_ALWAYS_AUTHENTICATE getting

@spanmatej
Copy link
Author

Yes of course, done just that, commented out the attribute getting lines and left the login immediately after SignInit.
image

CKR_SESSION_READ_ONLY_EXISTS:183
    at Error (native) PKCS11::C_Login:372

I previously got that error and figured the session must be opened as read-only..

@microshine
Copy link
Contributor

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

@spanmatej
Copy link
Author

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

Changing to that gives

CKR_USER_ANOTHER_ALREADY_LOGGED_IN:260
    at Error (native) PKCS11::C_Login:372

@microshine
Copy link
Contributor

Can we move our chat to Skype? Please contact me via email [email protected]

@spanmatej
Copy link
Author

The issue has been resolved. I will update this comment shortly and describe the solution.

@ferikeem
Copy link

@spanmatej Can you elaborate on what solved your issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants