Question

I am using SafeNet's iKey usb token for my application.

My application is in C++ (win32 app) and I am accessing token's functionality through PKCS interface (pkcs11.h) from its SDK.

So far, I've been able to successfully do the following: generate public/private key pair, encrypt/decrypt, sign/verify, read attributes of objects stored inside the token.

But the main problem is: after importing X.509 certificate into the token (using iKey Token Utility), I can't read certificate details in my C++ application, as I need these to know which user is using my application, i.e user identity. However, with the "iKey Token Utility", which comes with the token driver, it is possible to view the certificate details. I couldn't find source code of that utility anywhere, also pkcs11.h library doesn't have any functions related to reading certificate details. For me, it would be just helpful to read public key value (not its handle) of the certificate.

I tried to read attributes of the certificate object inside the token using PKCS, but seems it gives me values encoded in some format.

I thoroughly looked through the SDK documentation, and over the Internet, but I couldn't find answer to my question:

  • How to read X509 certificate details from usb security token using PKCS in C++?

I would appreciate any hints to solve this problem, thanks...

Was it helpful?

Solution

According to the PKCS#11, X509 certificates are some kind of stored objects that their data class (CKA_CLASS attribute) equals to CKO_CERTIFICATE.
If you want to retrieve a certificate object from your token, all you need is to use C_GetAttributeValue function.
Before doing this you may want find all x.509 certificates stored on your token:

CK_BBOOL _true = CK_TRUE;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE certType = CKC_X_509_ATTR_CERT;
CK_ATTRIBUTE certificateSearchTemplate[] = {
    {CKA_CLASS, &certClass, sizeof(dataClass)},
    {CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},
    {CKA_TOKEN, &_true, sizeof(_true)}
};

CK_OBJECT_HANDLE hObject;
CK_ULONG ulObjectCount;
CK_RV rv = C_FindObjectsInit(hSession, certificateSearchTemplate, 3);
assert(rv == CKR_OK);
while (1) {
   rv = C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
   if (rv != CKR_OK || ulObjectCount == 0)
      break;
   //hObject is handle of a x.509 certificate, so you can fetch your desired attributes from it using C_GetAttributeValue
  getCertificateAttributes(hObject);
}
rv = C_FindObjectsFinal(hSession);
assert(rv == CKR_OK);

and in getCertificateAttributes function you can get desired certificate attributes:

void getCertificateAttributes(CK_OBJECT_HANDLE hCert)
{
   CK_ATTRIBUTE pTemplate[] = {
      //List your desired attributes here
   };
   ...
   CK_RV rv = C_GetAttributeValue(hSession, hCert, &pTemplate, pTemplateLen);
   if (rv == CKR_OK) {
      //here you have your desired certificate attributes
   }
}

OTHER TIPS

Apart from PKCS#11 library, Microsoft CryptoAPI(mscapi.dll) can also be used for retrieving certificate details. However, MSCAPI also uses PKCS internally to interact with the usb token. So, there should be some way to solve the problem using PKCS library alone and without MSCAPI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top