CreateObject PKCS#11 fail

1.6k Views Asked by At

I tried to comment on this link https://stackoverflow.com/a/39798597/448266, but could not due to the reputation #.

I have tried the sample and run well, but when I changed to arbitrary value it returns exception Message: Net.Pkcs11Interop.Common.Pkcs11Exception : Method C_CreateObject returned 2147483968

I am using safenet HSM SW.

plainKeyValue = Common.HelperFunctions.StringToByteArray("112233445566778899001122334455665566998844335511");

Below is the snapshot of the code, I changed slightly on the key value (as above).

 public static string generateAndCreateKeyObj()
    {
        using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Configurations.Pkcs11LibraryPath, Settings.AppType))
        {
            // Find first slot with token present
            ISlot slot = Helpers.GetUsableSlot(pkcs11, Configurations.default_slot);

            // Open RW session
            using (Net.Pkcs11Interop.HighLevelAPI.ISession session = slot.OpenSession(SessionType.ReadWrite))
            {
                // Login as normal user
                session.Login(Configurations.user_type, "1234");

                // Prepare attribute template of new key
                List<IObjectAttribute> objectAttributes = new List<IObjectAttribute>();
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_TOKEN, false)); //not stored in token
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_ENCRYPT, true));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_DECRYPT, true));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_WRAP, true));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_UNWRAP, true));
                objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_EXTRACTABLE, true));

                // Specify key generation mechanism
                IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_DES3_KEY_GEN);

                // Generate key
                IObjectHandle secret_key = session.GenerateKey(mechanism, objectAttributes);


                ////////////////////////////////////////////////////////////////////////////////////////

                // Export the key
                byte[] plainKeyValue = null;
                List<IObjectAttribute> readAttrs = session.GetAttributeValue(secret_key, new List<CKA>() { CKA.CKA_VALUE });
                if (readAttrs[0].CannotBeRead)
                    throw new Exception("Key cannot be exported");
                else
                    plainKeyValue = readAttrs[0].GetValueAsByteArray();

                plainKeyValue = Common.HelperFunctions.StringToByteArray("112233445566778899001122334455665566998844335511");

                // Prepare attribute template of new key
                List<IObjectAttribute> oa = new List<IObjectAttribute>();
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_LABEL, "Imported key"));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_TOKEN, true));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_ENCRYPT, true));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_DECRYPT, true));
                oa.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_VALUE, plainKeyValue));


                IObjectHandle importedKey = session.CreateObject(oa);


                // Test encryption with generated key and decryption with imported key
                using (IMechanism mechanismx = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_DES3_CBC, session.GenerateRandom(8)))
                {
                    byte[] sourceData = ConvertUtils.Utf8StringToBytes("Our new password");
                    byte[] encryptedData = session.Encrypt(mechanismx, secret_key, sourceData);
                    byte[] decryptedData = session.Decrypt(mechanismx, importedKey, encryptedData);
                    if (Convert.ToBase64String(sourceData) != Convert.ToBase64String(decryptedData))
                        throw new Exception("Encryption test failed");
                }
                // Destroy object
                session.DestroyObject(importedKey);
                session.DestroyObject(secret_key);
                session.Logout();

                return HelperFunctions.ByteArrayToString(plainKeyValue);
            }
        }
    }

 // convert from string to array
    public static byte[] StringToByteArray(string hex)
    {
        byte[] result;
        try
        {
            result = Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();

            return result;
        }
        catch (Exception e)
        {
            throw new Exception(e.Message); ;
        }
    }
2

There are 2 best solutions below

1
On BEST ANSWER

Thanks @jariq for your response.

I found out that in safenet hsm when creating a key object, the key plain value must be with odd parity bit, if not then the error mentioned above will occur.

Hope this will help anyone who stumbled the same error.

0
On

Exception you are getting says that low level PKCS#11 function C_CreateObject returned vendor specific error 0x80000140. You will need to discuss documentation provided by the device vendor or contact vendor support to get better understanding how to handle or avoid this specific error.