Sample openCryptoki program
View a completely coded example of an openCryptoki application that performs an RSA key generation operation.
Note: This sample program does not include the operation to encrypt data with the previously
generated RSA private key as described in step 7 of Structure of an openCryptoki application.
/*
* Build:
* cc -o pkcs11 pkcs11.c -ldl
*
* Usage:
* pkcs11 <so_name> <slot_id> <user_pin>
*
* Description:
* Loads the PKCS11 shared library <so_name>,
* opens a session with slot <slot_id>,
* logs the user in using the PIN <user_pin>,
* and performs an RSA key generation operation.
*/
/* Step 1 */
#include <opencryptoki/pkcs11.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>
#define NELEM(array) (sizeof(array) / sizeof((array)[0]))
int main(int argc, char *argv[])
{
CK_C_GetFunctionList get_functionlist = {NULL};
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
CK_FUNCTION_LIST *fn = NULL;
void *pkcs11so = NULL;
CK_SLOT_ID slot_id;
CK_FLAGS flags;
int rc = -1;
char *ptr;
CK_RV rv;
if (argc != 4) goto err;
pkcs11so = dlopen(argv[1], RTLD_NOW);
if (pkcs11so == NULL) goto err;
slot_id = strtoul(argv[2], &ptr, 0);
if (*(argv[2]) == '\0' || *ptr != '\0') goto err;
*(void **)(&get_functionlist) = dlsym(pkcs11so, "C_GetFunctionList");
if (get_functionlist == NULL) goto err;
rv = get_functionlist(&fn);
if (rv != CKR_OK || fn == NULL) goto err;
/* Step 2 */
rv = fn->C_Initialize(NULL);
if (rv != CKR_OK) goto err;
flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
/* Step 4 (Step 3 assumed to be done by pkcsconf) */
rv = fn->C_OpenSession(slot_id, flags, NULL, NULL, &session);
if (rv != CKR_OK || session == CK_INVALID_HANDLE) goto err;
/* Step 5 */
rv = fn->C_Login(session, CKU_USER, (CK_UTF8CHAR *)argv[3], strlen(argv[3]));
if (rv != CKR_OK) goto err;
/* Step 6 (Step 7 not coded in this example */
{
CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
CK_BYTE e[] = {0x01, 0x00, 0x01};
CK_ULONG modbits = 4096;
CK_BYTE subject[] = "RSA4096 Test";
CK_BYTE id[] = {1};
CK_BBOOL true_ = CK_TRUE;
CK_ATTRIBUTE template_publ[] = {
{CKA_ENCRYPT, &true_, sizeof(true_)},
{CKA_VERIFY, &true_, sizeof(true_)},
{CKA_WRAP, &true_, sizeof(true_)},
{CKA_MODULUS_BITS, &modbits, sizeof(modbits)},
{CKA_PUBLIC_EXPONENT, e, sizeof(e)}
};
CK_ATTRIBUTE template_priv[] = {
{CKA_SUBJECT, subject, sizeof(subject)},
{CKA_ID, id, sizeof(id)},
{CKA_TOKEN, &true_, sizeof(true_)},
{CKA_PRIVATE, &true_, sizeof(true_)},
{CKA_SENSITIVE, &true_, sizeof(true_)},
{CKA_DECRYPT, &true_, sizeof(true_)},
{CKA_SIGN, &true_, sizeof(true_)},
{CKA_UNWRAP, &true_, sizeof(true_)}
};
CK_OBJECT_HANDLE publ, priv;
rv = fn->C_GenerateKeyPair(session, &mechanism,
template_publ, NELEM(template_publ),
template_priv, NELEM(template_priv),
&publ, &priv);
if (rv != CKR_OK) goto err;
}
/* Step 8 */
rv = fn->C_Logout(session);
if (rv != CKR_OK) goto err;
rv = fn->C_CloseSession(session);
if (rv != CKR_OK) goto err;
/* Step 9 */
rv = fn->C_Finalize(NULL);
if (rv != CKR_OK) goto err;
rc = 0;
err:
if (pkcs11so != NULL)
dlclose(pkcs11so);
return rc;
}