Pkcs11Interop / Pkcs11Interop.X509Store

Easy to use PKCS#11 based X.509 certificate store
Apache License 2.0
33 stars 18 forks source link

Can't get keys from HSM #1

Closed aaktash closed 5 years ago

aaktash commented 6 years ago

I need to get private key to use as SignedXml.SigningKey. We use HSM to store keys and I used Pkcs11Interop.X509Store to get certifates: var store = new Pkcs11X509Store(pkcs11LibraryPath, new ConstPinProvider("Pin")); Pkcs11X509Certificate cert = store.Slots[0].Token.Certificates[0]; RSA rsaPrivateKey = cert.GetRSAPrivateKey(); But GetRSAPrivateKey() returns null. When I use Pkcs11Interop to get private key,I am able to get the key and use it in signing. But I can't use ObjectHandle in SignedXml functions. Is there any way to use Private key as SignedXml.SigningKey?Do I have to implement custom class inherited from RSA as you adviced there?

jariq commented 6 years ago

What are the values of cert.HasPrivateKeyObject and cert.Info.KeyType ?

aaktash commented 6 years ago

The first value is false and there is no definition for KeyType in Info. When I checked HSMs content via Pkcs11Admin tool, I can see just 2 cer files there, both are public certificate. As the manufacturer said "you will see private key and certificate individually". I unterstood that from this sentence,public and private keys stored seperated.

jariq commented 6 years ago

Do you see any objects in Pkcs11Admin on Keys tab after you login into your HSM via menu Token > Login > User login... ?

aaktash commented 6 years ago

Yes, I can see all objects, private keys and public keys.

jariq commented 6 years ago

It is important to understand that Pkcs11Interop.X509Store uses the value of CKA_LABEL and CKA_ID attributes to pair certificate object with private key object. When you look at the private key object on Keys tab, are the values in Label column (CKA_LABEL attribute) and ID column (CKA_ID attribute) exactly the same as values on Certificates tab for corresponding certificate object?

aaktash commented 6 years ago

ID colum values are same but label column values are not same. Public certificate has 4 character more, "_CER". Bytheway how can we open session and login with Pkcs11Interop.X509Store? When I create an instance of Pkcs11Interop.X509Store, there is only pin parameter.

jariq commented 6 years ago

ID colum values are same but label column values are not same. Public certificate has 4 character more, "_CER".

Change label on certificate object to match private key object and that's it.

By the way how can we open session and login with Pkcs11Interop.X509Store? When I create an instance of Pkcs11Interop.X509Store, there is only pin parameter.

Pkcs11Interop.X509Store does not expose sessions to public API. It manages them for you.

aaktash commented 6 years ago

I think I am missing something. I want to take a picture of the situation:

  1. In Safenet HSM,We have Public and Private keys with same names,and corresponding public certificate with different name.
  2. I am able to sign data with using Pkcs11Interop. But we need to use SignedXml functions and it accept key paramater as RSA key. So I have to get key as RSA which cannot be provided by Pkcs11Interop.
  3. So I decided to use Pkcs11Interop.X509Store. But I couldn't find how can I access HSM. When I use var store = new Pkcs11X509Store(pkcs11LibraryPath, new ConstPinProvider("Pin")); I couldn't understand what should I use for pin and set it User password.
  4. This functions returns just public certificates as I said before.
  5. And as I unterstand from you, I can get private key with cert.GetRSAPrivateKey(); function if I make certificate label same with keys. But I can't change certifacte label but can change key labels. And if I change them store.Slots[0].Token.Certificates[0] throws attribute exception.
aaktash commented 6 years ago

I get able to change certificate label but now here is a different exception like: Net.Pkcs11Interop.Common.AttributeValueException

  HResult=0x80131500
  Message=Value of attribute CKA_ALWAYS_AUTHENTICATE could not be converted
  Exception: Unable to convert bytes to bool
  Source=Pkcs11Interop
  StackTrace:
   at Net.Pkcs11Interop.HighLevelAPI41.ObjectAttribute.GetValueAsBool()...
jariq commented 6 years ago

I get able to change certificate label but now here is a different exception

Thanks for the report. It's fixed in https://github.com/Pkcs11Interop/Pkcs11Interop.X509Store/commit/073fb412cb6496fe1e324f14775a2327d649d869. You can try with the code from current master branch.

aaktash commented 6 years ago

Thanks for update. But I couldn't get that how can I try. Should I get master branch and build it for myself?

jariq commented 6 years ago

Should I get master branch and build it for myself?

Yes. That would be the fastest way to try it out.

aaktash commented 6 years ago

Ok thanks, I will try. Bytheway do yo have any plan to to add XML sign functions into Pkcs11Interop project?

jariq commented 6 years ago
  1. In Safenet HSM,We have Public and Private keys with same names,and corresponding public certificate with different name.

IMO you can safely rename the certificate. PKCS#11 object label (CKA_LABEL attribute) can contain arbitrary string value and it is up to user/application what it will be. Pkcs11Interop.X509Store uses CKA_LABEL (and CKA_ID) to pair key objects with certificate objects. PKCS#11 standard does not define/enforce any pairing between them.

  1. I am able to sign data with using Pkcs11Interop. But we need to use SignedXml functions and it accept key paramater as RSA key. So I have to get key as RSA which cannot be provided by Pkcs11Interop.

System.Security.Cryptography.RSA is high-level .NET class. Pkcs11Interop is low-level PKCS#11 wrapper. You can use Pkcs11Interop to implement custom class inherited from System.Security.Cryptography.RSA class and then use instance of your custom class as a SigningKey. That's what Pkcs11RsaProvider class in Pkcs11Interop.X509Store library does. If you don't like it you can always write your own implementation.

  1. So I decided to use Pkcs11Interop.X509Store. But I couldn't find how can I access HSM. When I use var store = new Pkcs11X509Store(pkcs11LibraryPath, new ConstPinProvider("Pin")); I couldn't understand what should I use for pin and set it User password.

Third parameter of Pkcs11X509Store constructor takes implementation of IPinProvider interface. Pkcs11X509Store calls IPinProvider automatically when it needs PIN for login. You don't need to worry when. You can write your own implementation of IPinProvider interface or you can use ConstPinProvider which provides static string passed in its constructor.

  1. This functions returns just public certificates as I said before.

Label of your certificate object did not match label of your private key object. That's why the pairing was unsuccessful and you received only certificate without associated private key.

  1. And as I unterstand from you, I can get private key with cert.GetRSAPrivateKey(); function if I make certificate label same with keys. But I can't change certifacte label but can change key labels. And if I change them store.Slots[0].Token.Certificates[0] throws attribute exception.

Your understanding is correct and the exception should be fixed now.

jariq commented 6 years ago

Bytheway do yo have any plan to to add XML sign functions into Pkcs11Interop project?

Currently no. Pkcs11Interop is low-level PKCS#11 wrapper and I like it that way. XML signing is high-level operation and such operations will be implemented/supported only in Pkcs11Interop.X509Store project.

jariq commented 6 years ago

@aaktash any update on this? Have you managed to resolve the issues?