The other day I was looking for a C
code example of illustrating how to leverage the softtoken key store
when directly interacting with the Solaris crypto framework. There's
substantial documentation available but I couldn't find a basic
example. So here's what I concocted:
1. Configure my softtoken keystore via
the command line:
pktool setpin keystore=pkcs11
pktool genkey label=test_key keytype=aes keylen=128
pktool list objtype=key
where the first operation updates the
passphrase required to access the keystore. If the keystore doesn't
exist, the keystore is first created. The default passphrase is
“changeme”. The second operation creates a 128-bit AES
key and installs it in the keystore – the label associated with
the key is “test_key”. The third operation displays the
contents of the keystore, so it is possible to confirm that the key
has been created correctly.
2. Use the AES key in the keystore from
a application that is directly using the Solaris crytpto framework:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <security/cryptoki.h>
#include <security/pkcs11.h>
int
main()
{
CK_RV rv;
CK_ULONG found_keys;
CK_MECHANISM mechanism;
CK_OBJECT_HANDLE hKey, key_list[1];
CK_SESSION_HANDLE hSession;
CK_UTF8CHAR label[] = {"test_key"};
unsigned char ivec[16];
unsigned char userPIN[] = {"mykeystore"};
mechanism.mechanism = CKM_AES_CBC;
mechanism.pParameter = ivec;
mechanism.ulParameterLen = 16;
rv = C_Initialize(NULL);
if (rv != CKR_OK) {
fprintf(stdout, "C_Init: rv = 0x%.8X\n", rv);
exit(1);
}
/*Use metaslot i.e. slot 0*/
rv = C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, NULL, &hSession);
if (rv != CKR_OK) {
fprintf(stdout, "C_openSess: rv = 0x%.8X\n", rv);
exit(1);
}
/*Log in using the correct passphrase*/
rv = C_Login(hSession, CKU_USER, userPIN, sizeof(userPIN));
if (rv != CKR_OK) {
fprintf(stdout, "C_Login: rv = 0x%.8X\n", rv);
exit(1);
}
/* Get the key object, where lable is the label of the
* key we which to leverage
*/
CK_ATTRIBUTE template[] = {
{CKA_LABEL, label, sizeof(label)-1}
};
rv = C_FindObjectsInit(hSession, template,
sizeof (template) / sizeof (CK_ATTRIBUTE));
if (rv != CKR_OK) {
fprintf(stdout, "C_FindObjectsInit: rv = 0x%.8X\n", rv);
exit(1);
}
rv = C_FindObjects(hSession, key_list, 1, &found_keys);
hKey = key_list[0];
if (rv != CKR_OK) {
fprintf(stdout, "C_FindObjects: rv = 0x%.8X\n", rv);
exit(1);
}
if (found_keys != 1)
{
fprintf(stdout, "C_FindObjects found %d objects\n", found_keys);
exit(1);
}
/* Initialize the encryption operation in the session */
rv = C_EncryptInit(hSession, &mechanism, hKey);
if (rv != CKR_OK) {
fprintf(stdout, "C_EncryptInit: rv = 0x%.8X\n", rv);
exit(1);
}
.
.
.
in the above example it is assumed that
the phasephrase is set to “mykeystore”.
The keys stored in the Solaris
softtoken keystore are encrypted and they are also checked for
integrity. The PBKDF2 function defined in PKCS#5 is used for
generating the keys from the passphrase.