CardContact / sc-hsm-embedded

PKCS#11 and CSP-Minidriver library for the SmartCard-HSM and STARCOS based signature cards
BSD 3-Clause "New" or "Revised" License
95 stars 31 forks source link

Key Usage Limit missing #30

Open stoprocent opened 3 years ago

stoprocent commented 3 years ago

Hi

I bought just recently Nitrokey HSM2 and I wanted to validate a few things on it. I wanted to create a keypair with Key usage limit over pcks11 but that didnt work. I have looked up attributes to use from here: https://github.com/CardContact/sc-hsm-embedded/blob/master/src/sc-hsm/sc-hsm-pkcs11.h. I was able to create a key but couldn't set the key use limit. I then tried using scsh3 and modified keymanager.js to input key limit and it worked. I was able to see it in scsh3 and also after performing more signing operations than specified limit I was getting errors. scsh3

I then wrote a script to dump every attribute from objects using pkcs11js library and this is what im getting:

##################################### [ C.DevAut ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 01 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 00>
Attribute: 3 <Buffer 43 2e 44 65 76 41 75 74>
Attribute: 11 <Buffer 7f 21 81 e4 7f 4e 81 9d 5f 29 01 00 42 0d 44 45 44 49 4e 4b 30 31 30 30 30 30 31 7f 49 4f 06 0a 04 00 7f 00 07 02 02 02 02 03 86 41 04 65 f1 29 f5 b7 ... 182 more bytes>
Attribute: 80 <Buffer 01 00 00 80 00 00 00 00>
Attribute: 86 <Buffer 00>
Attribute: 87 <Buffer 01 00 00 00 00 00 00 00>
Attribute: 102 <Buffer >
Attribute: 170 <Buffer 00>
Attribute: 80000100 <Buffer 44 45 44 49 4e 4b 30 31 30 30 30 30 31>
Attribute: 80000102 <Buffer 44 45 4e 4b 30 31 30 34 34 34 39 30 30 30 30 30>
Attribute: 80000103 <Buffer 02 00 00 07 00 06>
Attribute: 80000104 <Buffer 02 03 01 00 02 05>
Attribute: 80000105 <Buffer 06 0b 2b 06 01 04 01 81 c3 1f 03 01 01 53 01 00>

##################################### [ C.DICA ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 01 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 00>
Attribute: 3 <Buffer 43 2e 44 49 43 41>
Attribute: 11 <Buffer 7f 21 81 e2 7f 4e 81 9b 5f 29 01 00 42 0e 44 45 53 52 43 41 43 43 31 30 30 30 30 31 7f 49 4f 06 0a 04 00 7f 00 07 02 02 02 02 03 86 41 04 9d 49 cd 08 ... 180 more bytes>
Attribute: 80 <Buffer 01 00 00 80 00 00 00 00>
Attribute: 86 <Buffer 01>
Attribute: 87 <Buffer 02 00 00 00 00 00 00 00>
Attribute: 102 <Buffer >
Attribute: 170 <Buffer 00>
Attribute: 80000100 <Buffer 44 45 53 52 43 41 43 43 31 30 30 30 30 31>
Attribute: 80000102 <Buffer 44 45 44 49 4e 4b 30 31 30 30 30 30 31>
Attribute: 80000103 <Buffer 01 05 01 00 02 06>
Attribute: 80000104 <Buffer 02 03 01 00 02 05>
Attribute: 80000105 <Buffer 06 0b 2b 06 01 04 01 81 c3 1f 03 01 01 53 01 80>

##################################### [ miot ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 02 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 00>
Attribute: 3 <Buffer 6d 69 6f 74>
Attribute: 86 <Buffer 00>
Attribute: 100 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 101 <Buffer >
Attribute: 102 <Buffer 9a bb ae d4 39 5a 6e d9 ee c1 23 3a 42 50 84 33 12 2c bc 3b>
Attribute: 104 <Buffer 01>
Attribute: 106 <Buffer 00>
Attribute: 10a <Buffer 01>
Attribute: 10b <Buffer 01>
Attribute: 10c <Buffer 00>
Attribute: 110 <Buffer >
Attribute: 111 <Buffer >
Attribute: 163 <Buffer 01>
Attribute: 166 <Buffer ff ff ff ff ff ff ff ff>
Attribute: 170 <Buffer 01>
Attribute: 180 <Buffer 06 08 2a 86 48 ce 3d 03 01 07>
Attribute: 181 <Buffer 04 41 04 5e 68 7d d8 5c 7d 2a ec cc a6 15 a7 d3 14 38 fd 2a 6a a4 19 a9 d0 0d 54 e2 c8 18 d3 a2 88 dd 90 fb a0 ba 00 12 ed dd 8d 8f 1e c3 3e 3b 51 46 ... 17 more bytes>
Attribute: 80000110 <Buffer 67 82 01 ed 7f 21 82 01 93 7f 4e 82 01 4b 5f 29 01 00 42 10 44 45 4e 4b 30 31 30 34 34 34 39 30 30 30 30 30 7f 49 82 01 1d 06 0a 04 00 7f 00 07 02 02 ... 447 more bytes>

##################################### [ miot ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 01>
Attribute: 3 <Buffer 6d 69 6f 74>
Attribute: 100 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 101 <Buffer >
Attribute: 102 <Buffer 9a bb ae d4 39 5a 6e d9 ee c1 23 3a 42 50 84 33 12 2c bc 3b>
Attribute: 103 <Buffer 01>
Attribute: 105 <Buffer 00>
Attribute: 107 <Buffer 00>
Attribute: 108 <Buffer 01>
Attribute: 109 <Buffer 00>
Attribute: 10c <Buffer 00>
Attribute: 110 <Buffer >
Attribute: 111 <Buffer >
Attribute: 162 <Buffer 00>
Attribute: 163 <Buffer 01>
Attribute: 164 <Buffer 01>
Attribute: 165 <Buffer 01>
Attribute: 166 <Buffer 00 00 00 00 00 00 00 00>
Attribute: 170 <Buffer 01>
Attribute: 180 <Buffer 06 08 2a 86 48 ce 3d 03 01 07>
Attribute: 202 <Buffer 00>
Attribute: 210 <Buffer 00>

According to your spec Key Use Limit should be at 0x80000108. But I cannot see this at any object. Am I doing something wrong?

Edit: Also CKA_SC_HSM_ALGORITHM_LIST which I have specified and is visible in scsh3 is missing from pcks11 attributes.

stoprocent commented 3 years ago

Also when switching module to opensc (opensc-pkcs11.so) output is totaly different. Missing Certificates and no Vendor attributes.

I guess I'm using correct one from this repository (libsc-hsm-pkcs11.so)

##################################### [ miot ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 01>
Attribute: 3 <Buffer 6d 69 6f 74>
Attribute: 100 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 101 <Buffer >
Attribute: 102 <Buffer 9a bb ae d4 39 5a 6e d9 ee c1 23 3a 42 50 84 33 12 2c bc 3b>
Attribute: 103 <Buffer 01>
Attribute: 105 <Buffer 00>
Attribute: 107 <Buffer 00>
Attribute: 108 <Buffer 01>
Attribute: 109 <Buffer 00>
Attribute: 10c <Buffer 01>
Attribute: 110 <Buffer >
Attribute: 111 <Buffer >
Attribute: 121 <Buffer 00 01 00 00 00 00 00 00>
Attribute: 162 <Buffer 00>
Attribute: 163 <Buffer 01>
Attribute: 164 <Buffer 01>
Attribute: 165 <Buffer 01>
Attribute: 166 <Buffer ff ff ff ff ff ff ff ff>
Attribute: 170 <Buffer 00>
Attribute: 180 <Buffer 06 08 2a 86 48 ce 3d 03 01 07>
Attribute: 202 <Buffer 00>

##################################### [ miot ] #####################################

Listing Attributes: 

Attribute: 0 <Buffer 02 00 00 00 00 00 00 00>
Attribute: 1 <Buffer 01>
Attribute: 2 <Buffer 00>
Attribute: 3 <Buffer 6d 69 6f 74>
Attribute: 11 <Buffer 04 41 04 5e 68 7d d8 5c 7d 2a ec cc a6 15 a7 d3 14 38 fd 2a 6a a4 19 a9 d0 0d 54 e2 c8 18 d3 a2 88 dd 90 fb a0 ba 00 12 ed dd 8d 8f 1e c3 3e 3b 51 46 ... 17 more bytes>
Attribute: 100 <Buffer 03 00 00 00 00 00 00 00>
Attribute: 102 <Buffer 9a bb ae d4 39 5a 6e d9 ee c1 23 3a 42 50 84 33 12 2c bc 3b>
Attribute: 103 <Buffer 00>
Attribute: 104 <Buffer 00>
Attribute: 106 <Buffer 00>
Attribute: 10a <Buffer 01>
Attribute: 10b <Buffer 00>
Attribute: 10c <Buffer 00>
Attribute: 162 <Buffer 00>
Attribute: 163 <Buffer 00>
Attribute: 166 <Buffer ff ff ff ff ff ff ff ff>
Attribute: 170 <Buffer 00>
Attribute: 180 <Buffer 06 08 2a 86 48 ce 3d 03 01 07>
Attribute: 181 <Buffer 04 41 04 5e 68 7d d8 5c 7d 2a ec cc a6 15 a7 d3 14 38 fd 2a 6a a4 19 a9 d0 0d 54 e2 c8 18 d3 a2 88 dd 90 fb a0 ba 00 12 ed dd 8d 8f 1e c3 3e 3b 51 46 ... 17 more bytes>
CardContact commented 3 years ago

There is currently no mechanism to query CKA_SC_HSM_KEY_USE_COUNTER.

CKA_SC_HSM_KEY_USE_COUNTER can only be used to set the key use counter in C_GenerateKey() or C_GenerateKeyPair().

Unfortunately that code had a bug when used on non-32 bit systems. I've posted a fix a couple of minutes ago.

stoprocent commented 3 years ago

@CardContact Nice! Thanks for that! I have compiled master on Mac OS and I was able to create keypair with key use limit from pkcs11!

If you don't mind I have another question. Can you edit this value by using C_SetAttributeValue? I'm getting an error which in fact is the behavior I'm looking for but when I'm reading the description from nitrokey website about key limit I'm confused about what is possible and what is not. In my case, I want to send a client Nitrokey with a limited singing cap which they cannot change just by knowing the user pin.

The Key Use Counter is displayed in the Key Manager of the Smart Card Shell. At the moment you can only set it with a script (SmartCardHSMKeySpecGenerator.prototype.setKeyUseCounter in the class scsh/sc-hsm/SmartCardHSM.js).

In our PKCS#11 module there is a proprietary attribute CKA_SC_HSM_KEY_USE_COUNTER with the key use of the C_GenerateKeyPair counter can be set. The attribute can then also be set for a key can be queried.

In OCF and the JCE Provider, the Key Use Counter can be queried with SmartCardHSMKey.getUseCounter() and confirm with SmartCardHSMKeySpec.setKeyUseCounter() can be set.

CardContact commented 3 years ago

No, you can't change the key use counter. It's initial value is set during key creation and decremented with each crypto operation performed with that key. If the use counter is expired, the key can no longer be used.

You could probably use C_SetAttributeValue() and read back with C_GetAttributeValue(), but that has only an effect on the attribute stored in the PKCS#11 module, not on the device. The key use counter is a mechanism inside the device.

You can also not export a key with a key use counter, as otherwise you could reset the counter by importing the key with the initial value.

The key use counter serves two purposes: You can limit the number of times the key can be used or you can use the key use counter as auditing measure.

stoprocent commented 3 years ago

@CardContact Thank you very much! That is a perfect explanation! One last question :) ...

I want to sign and verify data using C_Sign and C_Verify. I'm getting the correct signature from pkcs11 but cannot get verification. I'm getting CKR_FUNCTION_NOT_SUPPORTED. I have specified CKA_SC_HSM_ALGORITHM_LIST and I have included CKM_ECDSA. Any Ideas?

stoprocent commented 3 years ago

I guess it's coming from here: https://github.com/CardContact/sc-hsm-embedded/blob/e83057370a10d4d5f7e6e92a7950317ab8c439c7/src/pkcs11/p11mechanisms.c#L1124 But not sure why ...

stoprocent commented 3 years ago

I have found that my compiled version didn't have support for libcrypto. I've fixed it and recompiled with libcrypto support but still getting CKR_FUNCTION_NOT_SUPPORTED

stoprocent commented 3 years ago

Forgot to make clean :) Now verify is working. Thanks!

nmoskopp commented 2 years ago

@stoprocent could you maybe share some example C code for creating a keypair with a key use counter? My use case is the same as yours, giving someone else a HSM with a keypair that only allows a limited amount of signings.

nmoskopp commented 2 years ago

@CardContact could you point me to documentation on how to set this up for RSA or EC encryption/signing?

CardContact commented 2 years ago

Currently the only way to generate a key with a key use counter is by using a Smart Card Shell script:

var SmartCardHSM = require('scsh/sc-hsm/SmartCardHSM').SmartCardHSM;
var SmartCardHSMKeySpecGenerator = require("scsh/sc-hsm/SmartCardHSM").SmartCardHSMKeySpecGenerator;
var HSMKeyStore = require("scsh/sc-hsm/HSMKeyStore").HSMKeyStore;

// Create card access object
var card = new Card(_scsh3.reader);

// Create SmartCard-HSM card service
var sc = new SmartCardHSM(card);

// Attach key store
var ks = new HSMKeyStore(sc);

// Login
sc.verifyUserPIN(new ByteString("648219", ASCII));

var label = "AESKey";

if (ks.hasKey(label)) {
    ks.deleteKey(label);
}

var spec = new SmartCardHSMKeySpecGenerator(Crypto.AES, 128);
spec.setAlgorithms(new ByteString("101118929499", HEX));
spec.setKeyUseCounter(100000000);

ks.generateKey(label, spec);

label = "ECKey";

if (ks.hasKey(label)) {
    ks.deleteKey(label);
}

var dp = new Key();
dp.setComponent(Key.ECC_CURVE_OID, new ByteString("brainpoolP256r1", OID));
var spec = new SmartCardHSMKeySpecGenerator(Crypto.EC, dp);
spec.setKeyUseCounter(100);

ks.generateKeyPair(label, spec);

label = "RSAKey";

if (ks.hasKey(label)) {
    ks.deleteKey(label);
}

var spec = new SmartCardHSMKeySpecGenerator(Crypto.RSA, 2048);
spec.setKeyUseCounter(100);

ks.generateKeyPair(label, spec);
jowilkes commented 2 years ago

Is there a documented way how this setKeyUseCounter() is represented in an APDU?

CardContact commented 2 years ago

Yes, you can find that information in chapter 5.5.2 of the SmartCard-HSM User Manual.

It is basically DO '90' in C-Data of the GENERATE ASYMMETRIC KEY PAIR / GENERATE SYMMETRIC KEY command.

All manuals can be found in the CDN (Registration required).