NitroKey HSM CAPI not prompting for PIN

I’m working with a NitroKey HSM on Windows 7 x64. I’ve installed OpenSC and the OpenPGP card minidriver, per the suggestions on the Installation and Applications pages.

OpenSC’s sc-hsm-init and pkcs11-tool work as documented. PKCS#11 access works fine - I’ve used the card from Java programs through the Oracle pkcs11 CSP, and from OpenSSL using the OpenSC pkcs11 engine.

I’ve been less successful with the Windows Certificate Store and CAPI (CryptoAPI). The certificate on the card shows up in the certificate store and it knows there’s a non-exportable private key associated with it; that’s good. CAPI programs such as signtool.exe find the NitroKey HSM and locate the certificate:

$ signtool sign /n "NitroKey" /csp "Microsoft Base Smart Card Crypto Provider" /kc "Certificate" /fd SHA256 /v file.exe
The following certificate was selected:
    Issued to: NitroKey Code Signer
    Issued by: Code Signing CA
    Expires:   Thu Apr 19 15:01:47 2018
    SHA1 hash: 8FAE0CDB249EDA3BA21EF66CBC75575C9E7EDD0F

So far, so good. That’s the correct certificate, and the light on the NitroKey is blinking. If I run the command without the NitroKey connected, Windows prompts me to “insert smart card”; I plug in the NitroKey and Windows recognizes that it’s the correct device.

But then it fails. I don’t get prompted for the User PIN, and SignTool fails with Windows error 0x80070005, E_ACCESSDENIED.

I’m thinking either the OpenPGP minidriver or the OpenSC card-reader minidriver isn’t telling Windows to prompt for the User PIN. I’ve glanced at some Microsoft documentation and it seems like the minidriver needs to do that. But the NitroKey Applications page claims the NitroKey HSM can be used with CAPI applications through the OpenPGP minidriver, and it seems like this would always fail, unless the application sets the PIN programmatically before trying to perform a signing operation.

Has anyone actually used a NitroKey HSM successfully with a CAPI application? Am I missing some trick?

Update: I’ve been browsing through more of the OpenSC documentation, and discovered the certutil.exe -SCInfo command. It does cause Windows to prompt for the PIN (twice, as it tries out various operations), and appears to be able to sign data using the NitroKey HSM. So apparently the issue with SignTool only affects some CAPI programs. I’ll continue to investigate.

Further update. I notice that certutil is reporting “No AT_SIGNATURE key for reader”, even though the key pair has all usages (sign/verify, encrypt/decrypt, and wrap/unwrap). It appears the minidriver is reporting only AT_KEYEXCHANGE keys.

SignTool presumably wants an AT_SIGNATURE key.

I also see that when SignTool fails, I get an event 610 in the System event log, complaining ioctl 0x313520 (IOCTL_GET_FEATURE_REQUEST) failed. There are some discussions of similar issues in the OpenSC forums. It looks like a driver issue of some sort.

Ignore previous update. The lack of an AT_SIGNATURE key type is normal, and should not be a problem. It’s possible SignTool is insisting on an AT_SIGNATURE key, but if so that’s a bug in SignTool.

Looking at the source for the OpenSC minidriver, it appears it will return the key as AT_SIGNATURE if the private key usage is suitably constrained. I’ll experiment.

I’ve just confirmed that Microsoft’s VsixSignTool utility works correctly with the NitroKey HSM (via CAPI), prompting for the PIN. So the problem so far is limited to SignTool. If I figure out what’s going on there I’ll post a followup, but it doesn’t look like a NitroKey or OpenSC issue.

1 Like

Thank you for the details. Did you solve the SignTool issue eventually?