OpenSC / libp11

PKCS#11 wrapper library
GNU Lesser General Public License v2.1
298 stars 183 forks source link

Issue with CKU_CONTEXT_SPECIFIC on Safenet HSM module #160

Closed mirozitnansky closed 7 years ago

mirozitnansky commented 7 years ago

First of all, you are doing great job guys, many thanks for time and energy you are putting into this project.

I am pretty noob with pkcs11 stuff, so please have patience with me. I spent quite some time trying to implement OpenSSL certification authority based on Sefenet HSM module which should store CA private keys. CA key is than used for singing client/server certificates. Using libp11 as OpenSSL engine, configured with pkcs11 lib supplied with HSM, I was able to make OpenSSL work correctly... on some conditions. Our HSM can work in few modes. Safenet's default (we are currently using this mode), FIPS-140 and others. We are planning to switch our device from current, default mode, into FIPS-140 mode. This means, among other things, device will be switched to No Public Crypto mode – user have to be always logged into token, if he is going to use key for crypto operation. In current mode, there no need to be logged in token to do the sign operation in OpenSSL. On the other hand, object in token can be public or private (I am not reffering to RSA pulic/private key). Private objects are only accessible after loggin in.

First problem I encountered lied on having private object while disabled No Public Crypto flag. Then even if I try to set pin for token, engine won’t log in and simply says there is no such object (because it was set private).

I have pkcs11 communication logged so pc_private_list.txt is list using safenet utility.

[root@mzcentos ~]# ctkmu l -s 0
ProtectToolkit C Key Management Utility 5.2.0
Copyright (c) Safenet, Inc. 2009-2016

logger: s_ctData->ft = 0x0x1dd5360
logger: s_ctData->ft->C_Initialize = 0x0x7f97d9acae20
Do you wish to view private (user) objects [y/N]: y

Please enter User's PIN for the token in slot 0: 

Manufacturer      = SafeNet Inc.
Label             = OPENSSL                         
Flags             = 0x649 (RNG USER-PIN-INIT CLOCK TOKEN-INIT DUAL-CRYPTO)

Public and Private Objects:
CA                               - PUBLIC_KEY      RSA         
CA                               - PRIVATE_KEY     RSA         

and pc_private_sign.txt is OpenSSL sign attempt which end up failed:

[root@mzcentos ca_ptk]# openssl req -config openssl.cnf -key "pkcs11:model=0000;manufacturer=SafeNet%20Inc.;serial=0000%3a84324;token=OPENSSL;id=%42%19%72%91%10%73%e4%b1%e0%7f%67%fe%2f%31%a8%6c%e6%5c%ca%66;object=CA;object-type=private?pin-value=1111" -keyform engine -engine pkcs11 -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
logger: s_ctData->ft = 0x0x21241a0
logger: s_ctData->ft->C_Initialize = 0x0x7f9fb5b44e20
engine "pkcs11" set.
No private keys found.
No private keys found.
PKCS11_get_private_key returned NULL
cannot load Private Key from engine
140323973031840:error:26096080:engine routines:ENGINE_load_private_key:failed loading private key:eng_pkey.c:126:
unable to load Private Key

In this case, I assume, if OpenSSL logged into token, sing operation would worked fine. So I set No public crypto flag to true, OpenSSL logs in correctly, finds private key and do the sing operation. Npc_private_sign.txt

Second thing, it seems to me, is some lack of implementation on side of Safenet. It looks like, they have not implemented CKU_CONTEXT_SPECIFIC user type in pkcs11 at all. When I have set No public crypto true, but my object is Public, OpenSSL finds it, then request pin (ignoring pin in URL), but then sing fails on

[root@mzcentos ca_ptk]# openssl req -config openssl.cnf -key "pkcs11:model=0000;manufacturer=SafeNet%20Inc.;serial=0000%3a84324;token=OPENSSL;id=%42%19%72%91%10%73%e4%b1%e0%7f%67%fe%2f%31%a8%6c%e6%5c%ca%66;object=CA;object-type=private?pin-value=1111" -keyform engine -engine pkcs11 -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
logger: s_ctData->ft = 0x0xd571a0
logger: s_ctData->ft->C_Initialize = 0x0x7f80d2c5be20
engine "pkcs11" set.
Missing CKA_ALWAYS_AUTHENTICATE attribute
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [SK]:
State or Province Name [Bratislavsky kraj]:
Locality Name [Bratislava]:
Organization Name [company]:
Organizational Unit Name [IKT]:
Common Name []:
Email Address [ikt@company.eu]:
Enter PKCS#11 key PIN for CA:
140191316727712:error:80009103:Vendor defined:PKCS11_rsa_encrypt:User type invalid:p11_rsa.c:120:
140191316727712:error:0D0DC006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:a_sign.c:314:

This seems to be a problem in pkcs11 log Npc_publicobj_sign.txt:

pid(14918) tid(139744935835712) time(16/05/2017,23:02:12.252)   > C_Login hSession=0x00000002 userType=2{?} pPin=0x0x7ffd53d62830 pinLen=4
    pin: (4Bytes)
    31 31 31 31 

pid(14918) tid(139744935835712) time(16/05/2017,23:02:12.252)   << C_Login rv=0x00000103{user type invalid}

As I mentioned before, we plan to switch mode of our device to FIPS (with No public crypto flag), and we have public objects in token, so after switch we won’t be able to use them, because sing will fail as in previous case. If I am able to force login into token as standard user, crypto operations shoud work correctly even after mode switch. I noticed _Missing CKA_ALWAYSAUTHENTICATE attribute message in OpenSSL operations, but I am not sure if this has something to do with my situation.

All tests I am doing, are done on software HSM emulation, but hardware HSM works the same. Do you think, if is there any way to overcome this user type invalid issue?

Thanks in advance. If there is any test/log I can provide, I'll be happy to.

mtrojnar commented 7 years ago

@mirozitnansky Can we close this issue now?

mirozitnansky commented 7 years ago

@mtrojnar, I am sorry I didn't have time to test it earlier. It is working now as expected in FIPS and default mode, always asking for pin. Once again, thank you very much for you support and all effort you are putting into this.