In my C++ program I created a public/private key pair using CryptoAPI.
CryptGenKey(eTokenProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE,&k1)
Keys are stored in a eToken. Is it possible to get the public key using PKCS#11? The private key previously created is found after a search using the following search-template:
CK_ATTRIBUTE private_search[] = {
{CKA_PRIVATE, CK_TRUE, sizeof(CK_BBOOL)}
};
If I set CKA_PRIVATE
to CK_FALSE, I can't get the public key. I also tried with other attributes.
Is there a way to do it?
EDIT
As owlstead suggests, I tried to create a public key starting from the modulus and public exponent of a key created in a previous session (in CAPI or, just for this test, in PKCS11). I got the modulus and public exponent from a private key in these buffers:
CK_BYTE modulus[128]; //if 1024bit
CK_BYTE publicExponent[4]; //4 Byte, according to public key blob
But when I try to create a new public with key with the following instructions:
CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_TOKEN, &yes, sizeof(true)},
{CKA_WRAP, &yes, sizeof(true)},
{CKA_ENCRYPT, &yes, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_MODULUS, &modulus, sizeof(modulus)},
{CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)}
CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
rv = (*functions->C_GenerateKeyPair) (session, &mechanism, publicKeyTemplate, 6, privateKeyTemplate, 6, &hPublicKey, &hPrivateKey);
I get the error "Invalid template". The probles is the modulus, because, without it, I can create a key pair. I use the function C_GenerateKeyPair
, but I'm only interested in the public key. I omitted the private template.
What is the wrong here?
CKA_PRIVATE
does not indicate a private key at all.
When the CKA_PRIVATE attribute is TRUE, a user may not access the object until the user has been authenticated to the token
Instead you should look for an attribute such as CKA_CLASS
with a value CKO_PUBLIC_KEY
or CKO_PRIVATE_KEY
, possibly using other attributes to filter your results further.
If you cannot find any CKO_PUBLIC_KEY
then I presume it was either not generated in the token (key was imported, check if CKA_LOCAL
is set). Alternatively, it may have only been created as a session object. Finally it may have been removed.
Note that RSA private keys commonly do contain the public exponent, so you can still construct a public key from just the private key object (using the modulus and public exponent, of course).