I ran into some issues writing a small test programme using the cryptoki library. I want (have) to get hold of the RSA private key (all its parameters). I thought about either generate keys and then extract the parameters or use already generated parameters to set the keys manually. So far, I don't get any of this working. Code is at the end of the post.
Extraction
I know that there is the C_GetAttributeValue() with which I can extract attributes such as the public exponent or the modulus. That works for both public and private key objects but I get CKR_ATTRIBUTE_SENSITIVE error for when I try to extract private parameters from the private key object. Is there a way to extract these attributes? Can/Do I have to set certain parameters when logging into a session or during initialising?
Setting Keys manually
My second approach was to read key material (generated with OPENSSL) from a file and use that for generating key objects with C_CreateObject(). The file contains all RSA parameters (n,e,d,p,q,dmp1,dmq1,iqmp). After reading, I convert them from ASCII to hex representation and store them in a CK_BYTE[]. So far so good. Now, when I pass all this to the C_CreateObject() in order to create a private key I receive a CKR_ATTRIBUTE_VALUE_INVALID error message. Creating a public key object the same way with the public parameters works. I verified that using C_GetAttributeValue() on the created public key object. What am I missing for generating a private key object if this is even possible this way? I suppose that C_GenerateKeyPair() always generates new keys no matter whether key material is provided or not, right?
C Code
This is what I try to create the private key object with:
CK_OBJECT_HANDLE hPrivateKeys[NUMKEYS];
CK_KEY_TYPE kType= CKK_RSA;
CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY;
CK_BYTE id[] = {123};
CK_UTF8CHAR label[] = "An RSA private key object";
// sn,sd,se, etc contain the length of the respective parameter
CK_ATTRIBUTE privateKeyTemplate[] = {
{CKA_CLASS, &kClass, sizeof(kClass)},
{CKA_KEY_TYPE, &kType, sizeof(kType)},
{CKA_TOKEN, &false, sizeof(false)},
{CKA_PRIVATE, &false, sizeof(false)},
{CKA_SENSITIVE, &false, sizeof(false)},
{CKA_EXTRACTABLE, &true, sizeof(true)},
{CKA_ID, id, sizeof(id)},
{CKA_SUBJECT, NULL_PTR, 0},
{CKA_DECRYPT, &true, sizeof(true)},
{CKA_SIGN, &true, sizeof(true)},
{CKA_LABEL, label, sizeof(label)-1},
{CKA_ID, id, sizeof(id)},
{CKA_MODULUS, modulus, sn},
{CKA_PUBLIC_EXPONENT, publicExponent, se},
{CKA_PRIVATE_EXPONENT, privateExponent, sd},
{CKA_PRIME_1, prime1, sp},
{CKA_PRIME_2, prime2, sq},
{CKA_EXPONENT_1, exponent1, sdmp1},
{CKA_EXPONENT_2, exponent2, sdmq1},
{CKA_COEFFICIENT, coefficient, siqmp}
};
CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_ENCRYPT, &true, sizeof(true)},
{CKA_VERIFY, &true, sizeof(true)},
{CKA_WRAP, &true, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, se},
{CKA_MODULUS, modulus, sn}
};
rv = pFunctionList->C_CreateObject(hSession, privateKeyTemplate, NUM_ELEM(privateKeyTemplate), &hPrivateKeys[j]);