2

I have a task to sign and decrypt data, but the private keys are located at a HSM ( Luna SA, / Safenet ). I installed all the client software and connected the Luna SA CSP to the test servers.

Using the PKCS#11 functions provided, I am able to list and export the public keys on the HSM as PCCERT_CONTEXT (CertCreateCertificateContext). When I try to acquire the private key (using CryptoAPI function CryptAcquireCertificatePrivateKey), I receive an error code CRYPT_E_NO_KEY_PROPERTY.

I am probably missing the link between the certificate data and the CSP/HSM. Has anybody done something similar and can give any hints?

EDIT


I sucessfully created CER files from all the keys located on the HSM. When i know use signtool.exe (the one that ships with Microsoft Plattform SDK) i am able to sign a dll with a key on the HSM (the tool wizard lets me choose key container, key spec, ...). I tried to use the information the tool shows me and set the private key

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = CRYPT_MACHINE_KEYSET; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.cProvParam = 0;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}

but CryptAcquirePrivateKey still gives me the same error. I believe I am missing only a small bit here, since the signtool is able to access the private key

enter image description here

Edit2


The screnshot shows KEYEXCHANGE but I chose SIGNATURE

Edit3


I changed the LinkPrivateKeyfunction a little bit, now it works

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = 1; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}
esskar
  • 10,638
  • 3
  • 36
  • 57
  • You've described the steps you took, but what your goal is? How do you imagine the end result? – Eugene Mayevski 'Callback Sep 08 '14 at 14:49
  • i need to be able to sign/decrypt something using the private key located on the HSM. I do not want to export the key, i just want to be able to use it – esskar Sep 08 '14 at 15:01
  • Does your keys have label's or ids? Are you generating your keys within the HSM? Are you importing the keys from a pfx container? – Raj Sep 08 '14 at 15:03
  • the keys are already there. i am supposed to not create new keys, just use the keys that have been already at the HSM. they have ids and labels, yes! – esskar Sep 08 '14 at 15:05

2 Answers2

1

I don't have any experience with Luna but this worked well for nCiper HSM:

certutil -repairstore -csp "nCipher Enhanced Cryptographic Provider" My <serial number of certificate>

where "nCipher Enhanced Cryptographic Provider" is the name of CSP that comes with HSM.

Serial number of certificate can be obtained using this command:

certutil -store My

It will print all certificates in Local_Machine\My store. The serial number will be between bunch of ====== like ================ Certificate 5 ================. It will also parse information about the certificates like serial number, subject etc. and it will run encrypt/decrypt test to verify usability of the certificate.

After you repair the binding you can use this (second) command to verify that it went well. Don't be fooled by output of the first command, I have never seen it put out anything other than success.

You can find more information about usage of certutil here.

pepo
  • 8,644
  • 2
  • 27
  • 42
1

As stated in my post, I can link the private key using

I changed the LinkPrivateKeyfunction a little bit, now it works

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = 1; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}

YOu have to replace L"MSS"with the key container defined on you server. LunSA provides the tool keymap.exe that is insatlled along with the LunaCSP to get the container names.

esskar
  • 10,638
  • 3
  • 36
  • 57