Problem with ENGINE_load_private_key and PKCS#11

Viewed 1920

Being stuck with signing (Authenticode) using PKCS#11 tokens, and given the amazingly poor driver support from the vendor (SafeNet), we're signing Windows code on Linux.

All of this is working fine using all of our tokens on several build servers. However, I have one token that fails, depending on the mechanism being used. From Java, using Jsign and the SunPKCS11 provider, everything works fine with this token.

However, from osslsigncode, signing fails with this token:

Unable to enumerate certificates
PKCS11_get_private_key returned NULL
Failed to load private key 9df65894eb084ba3140555614123992:error:26096080:engine routines:ENGINE_load_private_key:failed loading private key:eng_pkey.c:124:

Failed

The difference between the working token and the non-working token is that the non-working token includes not just the certificate, but also its trust chain:

# pkcs11-tool --module libeToken.so --list-objects
Using slot 0 with a present token (0x0)
Certificate Object, type = X.509 cert
  label:      te-69f298db-2f32-4a94-82ea-3e11829b26cd
  ID:         9df65894eb084ba3
Certificate Object, type = X.509 cert
  label:      
Certificate Object, type = X.509 cert
  label:      

Using p11tool, the two empty-looking certs above show as:

Type: X.509 Certificate
Label: 
Flags: CKA_CERTIFICATE_CATEGORY=CA; 
ID: 

My other tokens, all of which work fine, do not include these CA certs. This token was created recently, so it may be that either the token firmware is different from my others, or the token installation process has changed since I created the other, working tokens. The certificate is the same on all of them, working and non-working.

I've confirmed (via gdb) that the correct key ID is being passed into ENGINE_load_private_key.

I'm not sure who owns the ENGINE API in this case - is it a token driver issue? (SafeNet) Is it a problem with OpenSC? etc. It would be helpful to find some other tool that uses the API in the same way so I could confirm whether the problem somehow lies with osslsigncode (which isn't actively supported) or one of the lower layers in this tower of cards.

P.S. I used PKCS#11 Spy, and it shows enumeration of all of the certs in the chain, so it's finding the key pair (by ID), but then fails - no errors in PKCS#11 Spy - all CKR_OK.

P.P.S. To address the question of whether this token also has a private key...

Using slot 0 with a present token (0x0)
Logging in to "Code Signing Token 11".
Please enter User PIN: 
Private Key Object; RSA 
  label:      
  ID:         9df65894eb084ba3
  Usage:      decrypt, sign, unwrap
Certificate Object, type = X.509 cert
  label:      te-69f298db-2f32-4a94-82ea-3e11829b26cd
  ID:         9df65894eb084ba3
Certificate Object, type = X.509 cert
  label:      
Certificate Object, type = X.509 cert
  label:      
2 Answers

The solution, at least for now, seems to be just deleting the CA certs from the token (via SAC Tools on Windows). Once done, osslsigncode (via the PKCS#11 stack) has no problem finding the token. The CA certs aren't needed for signing, so deleting them presents no problem.

It seems that you did NOT login to the token. In pkcs11-tool, use --login --pin <your-pin-code> if you want to retrieve private objects.

It should be noted that the signing process needs an appropriate private key (not certificate).

Related