1

I am trying to use the Pkcs11Interop library to get my own certificate from HSM(Safenet inc) when i have generated public/private key i got error "Method C_GenerateKeyPair returned CKR_FUNCTION_FAILED"

My code

if (Net.Pkcs11Interop.Common.Platform.Uses64BitRuntime)
{
    loggerLibraryPath = @"C:\inetpub\wwwroot\ETPkcs11\ETPkcsII\libs\pkcs11-logger-x64.dll";
}
else
{
    loggerLibraryPath = @"C:\inetpub\wwwroot\ETPkcs11\ETPkcsII\libs\pkcs11-logger-x86.dll";
}
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_LIBRARY_PATH", pkcs11LibraryPath);
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_LOG_FILE_PATH", loogerLogFilePath);
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_FLAGS", "64");

if (System.IO.File.Exists(loogerLogFilePath))
{
    System.IO.File.Delete(loogerLogFilePath);
}

using (Pkcs11 pkcs11 = new Pkcs11(loggerLibraryPath, AppType.SingleThreaded))
{
    LibraryInfo libraryInfo = pkcs11.GetInfo();
    var aviSlot = pkcs11.GetSlotList(SlotsType.WithTokenPresent).Where(slot => slot.GetSlotInfo().SlotFlags.TokenPresent).FirstOrDefault();

    using (Session session = aviSlot.OpenSession(SessionType.ReadWrite))
    {
        // Login as normal user
        session.Login(CKU.CKU_USER, "xxxxxxxx");
        byte[] ckaId = session.GenerateRandom(20);

        // Prepare attribute template of new public key
        List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>();
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, Settings.ApplicationName));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS_BITS, 1024));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));

        // Prepare attribute template of new private key
        List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>();
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, Settings.ApplicationName));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SENSITIVE, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN_RECOVER, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));

        // Specify key generation mechanism
        Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);

        // Generate key pair
        ObjectHandle publicKeyHandle = null;
        ObjectHandle privateKeyHandle = null;
        session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);

        // Do something interesting with generated key pair
        // Destroy keys
        session.DestroyObject(privateKeyHandle);
        session.DestroyObject(publicKeyHandle);

        session.Logout();
    }
}

Here are some of the log

0x00002478 : 0x00001af8 : Attribute 7
0x00002478 : 0x00001af8 : Attribute: 265 (CKA_SIGN_RECOVER)
0x00002478 : 0x00001af8 : pValue: 0597E850
0x00002478 : 0x00001af8 : ulValueLen: 1
0x00002478 : 0x00001af8 : *pValue: HEX(01)
0x00002478 : 0x00001af8 : Attribute 8
0x00002478 : 0x00001af8 : Attribute: 263 (CKA_UNWRAP)
0x00002478 : 0x00001af8 : pValue: 0597E830
0x00002478 : 0x00001af8 : ulValueLen: 1
0x00002478 : 0x00001af8 : pValue: HEX(01)
0x00002478 : 0x00001af8 :
End attribute template *
0x00002478 : 0x00001af8 : phPublicKey: 0643EA74
0x00002478 : 0x00001af8 : *phPublicKey: 0
0x00002478 : 0x00001af8 : phPrivateKey: 0643EA70
0x00002478 : 0x00001af8 : *phPrivateKey: 0
0x00002478 : 0x00001af8 : Returning 6 (CKR_FUNCTION_FAILED)
0x00002478 : 0x00001af8 : ****************************** 2019-03-22 16:37:32 *
0x00002478 : 0x00001af8 : Calling C_CloseSession
0x00002478 : 0x00001af8 : Input
0x00002478 : 0x00001af8 : hSession: 2490369
0x00002478 : 0x00001af8 : Returning 0 (CKR_OK)
0x00002478 : 0x00001af8 : ****************************** 2019-03-22 16:37:32 *

0x00002478 : 0x00001af8 : Calling C_Finalize
0x00002478 : 0x00001af8 : Input
0x00002478 : 0x00001af8 : pReserved: 00000000
0x00002478 : 0x00001af8 : Returning 0 (CKR_OK)

Miracu
  • 11
  • 1
  • 2
  • Please use proper formatting. if you want people to use their free time to solve YOUR problems, then you should at least take some time to put the problem into a presentable form. Proper indentation and line breaks are key to understanding code. you just dumping it in here is rude towards the people you expect to help you. I have done the work you should've done to begin with. – FalcoGer Mar 24 '19 at 20:16
  • 2
    Try creating the `Public Key` and `Private Key` objects with a very minimal template configuration. To begin with, just set the `token`, `label` and `id` attributes in both the templates, and see if you are able to create the key pair objects. If you are successfully able to create them, try setting the other attributes you might need. And FYI, the public and private key objects might be related by the `id`, so try to use the same id in both the templates. – always_a_rookie Mar 25 '19 at 00:46
  • FalcoGer,Thank you for your suggestions and corrections. – Miracu Mar 25 '19 at 04:21
  • always_a_rookie_to_learn , Thank you for your advice I've tried But still not successful. – Miracu Mar 25 '19 at 04:26
  • Consider examining attributes of an existing key pair (generated by official client) and using similar values. An alternative way is to use pkcs11-logger (you seem to be already familiar with) to log templates used by the official client during key pair generation...Good luck! – vlp Apr 15 '19 at 20:40

2 Answers2

0

If facing CKR_FUNCTION_FAILED, check the alias used. If there are multiple aliases, check one by one and pass the same to keystore.

Ruli
  • 2,592
  • 12
  • 30
  • 40
-1

Unfortunately PKCS#11 API does not provide any details on why C_GenerateKeyPair function failed but many PKCS#11 libraries support some kind of internal logging mechanism which may reveal the real cause of error. Exact steps needed to enable logging should be present in the documentation provided by the PKCS#11 library vendor.

jariq
  • 11,681
  • 3
  • 33
  • 52