Skip to content

Instantly share code, notes, and snippets.

@alfredgamulo
Last active January 25, 2019 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alfredgamulo/b6f605d00f148a5d739086dd972e2ecf to your computer and use it in GitHub Desktop.
Save alfredgamulo/b6f605d00f148a5d739086dd972e2ecf to your computer and use it in GitHub Desktop.
//$ test_unwrap_templat --pin <PIN> --library </usr/local/Cellar/softhsm/2.5.0/lib/softhsm/libsofthsm2.so>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cryptoki.h"
#include "dlfcn.h"
#define SLOT 1054660623
char pPin[256] = "1234";
void *module = NULL;
CK_FUNCTION_LIST_PTR func_list = NULL;
unsigned long int Private = 0;
unsigned long int Public = 0;
int do_wrap_unwrap(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE aeskey)
{
CK_RV rv = 0;
CK_OBJECT_HANDLE unwrapped_handle = CK_INVALID_HANDLE;
CK_ATTRIBUTE attr = { };
CK_BBOOL val = CK_TRUE;
CK_BBOOL f_val = CK_FALSE;
// CK_ULONG aes_key_bits = 256;
// CK_RSA_PKCS_OAEP_PARAMS oaep_params = { CKM_SHA256, CKG_MGF1_SHA256 };
// CK_RSA_AES_KEY_WRAP_PARAMS params = { aes_key_bits, &oaep_params };
// CK_MECHANISM mech = { CKM_RSA_AES_KEY_WRAP, &params, sizeof(params) };
CK_RSA_PKCS_OAEP_PARAMS params = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL_PTR, 0 };
CK_MECHANISM mech = {CKM_RSA_PKCS_OAEP, &params, sizeof(params)};
// First determine space needed for wrapped key
CK_ULONG n_buffer = 0;
rv = func_list->C_WrapKey(session, &mech, Public, aeskey, NULL, &n_buffer);
if(rv != CKR_OK) {
printf("\nCould not determine size of wrapped key: %lu \n",rv);
goto end_doWrapUnwrapKey;
}
CK_BYTE_PTR buffer = malloc(n_buffer);
if (NULL == buffer) {
printf("Could not allocate memory to hold wrapped key\n");
goto end_doWrapUnwrapKey;
}
// Wrap the key
rv = func_list->C_WrapKey(session, &mech, Public, aeskey, buffer, &n_buffer);
if(rv != CKR_OK) {
printf("\nWrap key failed: %lu \n",rv);
goto end_doWrapUnwrapKey;
}
// Unwrap the key
CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
CK_KEY_TYPE key_type = CKK_AES;
CK_ATTRIBUTE key_template[] = {
{CKA_TOKEN, &val, sizeof(val)}
,
{CKA_CLASS, &key_class, sizeof(key_class)}
,
{CKA_KEY_TYPE, &key_type, sizeof(key_type)}
,
{CKA_EXTRACTABLE, &f_val, sizeof(CK_BBOOL)}
};
CK_ULONG n_attr = 4;
rv = (func_list->C_UnwrapKey) (session, &mech,
Private, buffer,
n_buffer, key_template, n_attr,
&unwrapped_handle);
if(rv != CKR_OK) {
printf("\nUnwrapKey failed with error %lu \n",rv);
goto end_doWrapUnwrapKey;
}
printf("\nUnwrap Successful \n");
attr.type = CKA_EXTRACTABLE;
attr.ulValueLen = sizeof(val);
attr.pValue = &(val);
rv = (func_list->C_GetAttributeValue) (session, unwrapped_handle, &attr, 1);
if(rv!= CKR_OK)
printf("C_GetAttributeValue failed \n");
else
printf("CKA_EXTRACTABLE value [%d] \n", val);
end_doWrapUnwrapKey:
return rv;
}
int generate_rsa_key_pair(CK_SESSION_HANDLE session)
{
CK_RV rv = CKR_OK;
CK_OBJECT_CLASS public = CKO_PUBLIC_KEY, private = CKO_PRIVATE_KEY;
CK_KEY_TYPE rsa = CKK_RSA;
CK_BBOOL t_val = 1, f_val = 0;
CK_ULONG modulus_bits = 2048;
CK_BYTE public_exponent[] = { 0x01, 0x00, 0x01 };
CK_BYTE id_bytes[16] = { 0 };
unsigned int rand = 0;
CK_ATTRIBUTE unwrap_attr[] = {{CKA_EXTRACTABLE, &f_val, sizeof(CK_BBOOL)}};
CK_MECHANISM pMechanism = {
CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0
};
CK_ATTRIBUTE pubAttr[] = {
{CKA_CLASS, &public, sizeof(CK_OBJECT_CLASS)}
,
{CKA_LABEL, "RSA_public_key", strlen("RSA_public_key")}
,
{CKA_KEY_TYPE, &rsa, sizeof(CK_KEY_TYPE)}
,
{CKA_TOKEN, &t_val, sizeof(CK_BBOOL)}
,
{CKA_PRIVATE, &t_val, sizeof(CK_BBOOL)}
,
{CKA_VERIFY, &t_val, sizeof(CK_BBOOL)}
,
{CKA_MODULUS_BITS, &modulus_bits, sizeof(CK_ULONG)}
,
{CKA_PUBLIC_EXPONENT, &public_exponent, sizeof(public_exponent)}
,
{CKA_ID, &id_bytes, sizeof(id_bytes)}
,
{CKA_WRAP, &t_val, sizeof(CK_BBOOL)}
,
};
CK_ATTRIBUTE privAttr[] = {
{CKA_CLASS, &private, sizeof(CK_OBJECT_CLASS)}
,
{CKA_LABEL, "RSA_private_key", strlen("RSA_private_key")}
,
{CKA_KEY_TYPE, &rsa, sizeof(CK_KEY_TYPE)}
,
{CKA_TOKEN, &t_val, sizeof(CK_BBOOL)}
,
{CKA_PRIVATE, &t_val, sizeof(CK_BBOOL)}
,
{CKA_SIGN, &t_val, sizeof(CK_BBOOL)}
,
{CKA_ID, &id_bytes, sizeof(id_bytes)}
,
{CKA_UNWRAP, &t_val, sizeof(CK_BBOOL)}
,
{CKA_UNWRAP_TEMPLATE, &unwrap_attr, sizeof(unwrap_attr)} /* STEP 2:CKA_UNWRAP_TEMPLATE sets exportble to be false*/
,
};
CK_ULONG pubAttrCnt = 10;
CK_ULONG privAttrCnt = 9;
CK_OBJECT_HANDLE pubKey, privKey;
rv = (func_list->C_GenerateKeyPair) (session,
&pMechanism,
(CK_ATTRIBUTE_PTR) & pubAttr,
pubAttrCnt,
(CK_ATTRIBUTE_PTR) & privAttr,
privAttrCnt, &pubKey, &privKey);
if (CKR_OK != rv) {
printf("\nCall C_GenerateKeyPair failed with error %08lx\n", rv);
return -1;
}
Private = privKey;
Public = pubKey;
return rv;
}
int generate_aes_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE * aeskey)
{
CK_RV rv = CKR_OK;
CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY;
CK_BBOOL t_val = 1;
CK_BYTE id_bytes[16] = { 0 };
CK_KEY_TYPE key_type = CKK_AES;
CK_ULONG key_length = 32;
CK_MECHANISM pMechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0};
CK_ATTRIBUTE keyTemplateAES[] = {
{CKA_CLASS, &secret_key_class, sizeof(CK_OBJECT_CLASS)}
,
{CKA_LABEL, "AES_key", strlen("AES_key")}
,
{CKA_TOKEN, &t_val, sizeof(CK_BBOOL)}
,
{CKA_ENCRYPT, &t_val, sizeof(CK_BBOOL)}
,
{CKA_DECRYPT, &t_val, sizeof(CK_BBOOL)}
,
{CKA_ID, &id_bytes, sizeof(id_bytes)}
,
{CKA_KEY_TYPE, &key_type, sizeof(key_type)}
,
{CKA_VALUE_LEN, &key_length, sizeof(key_length)}
,
{CKA_SIGN, &t_val, sizeof(CK_BBOOL)}
,
{CKA_VERIFY, &t_val, sizeof(CK_BBOOL)}
,
{CKA_EXTRACTABLE, &t_val, sizeof(CK_BBOOL)}
,
{CKA_WRAP, &t_val, sizeof(CK_BBOOL)}
,
{CKA_UNWRAP, &t_val, sizeof(CK_BBOOL)}
,
};
CK_ULONG n_attr = 13;
rv = (func_list->C_GenerateKey) (session, &pMechanism,
(CK_ATTRIBUTE_PTR) keyTemplateAES,
n_attr, aeskey);
if (CKR_OK != rv) {
printf("\nCall C_GenerateKey failed with error %08lx\n", rv);
return -1;
}
return rv;
}
int do_operation()
{
CK_INFO info;
CK_RV rv;
CK_SESSION_HANDLE session_rw;
CK_SLOT_ID slot = SLOT;
CK_TOKEN_INFO token_info = { };
CK_OBJECT_HANDLE aeskey;
int n_pin = strlen(pPin);
int retval = 0;
int session_open = 0;
printf("\nC_Initialize\n");
rv = (func_list->C_Initialize) (NULL);
if (CKR_OK != rv) {
printf("\nC_Initialize() failed with %08lx\n", rv);
retval = -1;
goto clean_up;
}
rv = (func_list->C_OpenSession) (slot,
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, NULL, &session_rw);
if (CKR_OK != rv) {
printf("\nC_OpenSession() failed with %08lx\n", rv);
retval = -1;
goto clean_up;
}
session_open = 1;
rv = (func_list->C_Login) (session_rw, CKU_USER,
(CK_UTF8CHAR_PTR) pPin, n_pin);
if (CKR_OK != rv) {
retval = -1;
goto clean_up;
}
/* 1. Generate RSA key pair with unwrap template */
rv = generate_rsa_key_pair(session_rw);
if (CKR_OK == rv && Private) {
printf("\nGOT RSA Private Key handle [%lu] and Public Key handle [%lu] \n", Private, Public);
} else {
printf("Could not generate key pair \n");
retval = -1;
goto clean_up;
}
/* 2. Generate AES key */
rv = generate_aes_key(session_rw, &aeskey);
if (CKR_OK == rv && aeskey) {
printf("\nGOT AES Key handle [%lu]\n", aeskey);
} else {
printf("Could not generate AES key\n");
retval = -1;
goto clean_up;
}
printf("\nPublic handle [%lu] || Private handle [%lu] || AES handle [%lu] \n", Public, Private, aeskey);
/* 3. Perform wrap/unwrap */
rv = do_wrap_unwrap(session_rw, aeskey);
if (CKR_OK == rv) {
printf("\nPassed.\n");
} else {
printf("Error: failed.\n");
retval = -1;
goto clean_up;
}
clean_up:
if (session_open) {
/* Do logout */
rv = func_list->C_Logout(session_rw);
if (CKR_OK != rv) {
printf("\nC_Logout() failed with %08lx\n", rv);
retval = -1;
}
/* Do close session */
rv = func_list->C_CloseSession(session_rw);
if (CKR_OK != rv) {
printf("\nC_CloseSession() failed with %08lx\n", rv);
retval = -1;
}
}
/* Do app shutdown */
rv = func_list->C_Finalize(NULL);
if (CKR_OK != rv) {
printf("\nC_Finalize() failed with %08lx\n", rv);
retval = -1;
}
return retval;
}
int load_lib(const char *libpath)
{
CK_RV rv = -1;
CK_C_GetFunctionList get_function_list;
module = dlopen(libpath, RTLD_NOW);
if (!module) {
printf("couldn't open library: %s: %s", libpath, dlerror());
return -1;
}
/* Lookup the appropriate function in library */
get_function_list =
(CK_C_GetFunctionList) dlsym(module, "C_GetFunctionList");
if (!get_function_list) {
printf
("couldn't find function 'C_GetFunctionList' in library: %s: %s",
libpath, dlerror());
return -1;
}
/* Get the function list */
rv = (get_function_list) (&func_list);
if (rv != CKR_OK || !func_list) {
printf("couldn't get function list: %d", (int) rv);
return -1;
}
return rv;
}
int lib_close()
{
if (module)
dlclose(module);
return 0;
}
int main(int argc, char *argv[])
{
int err = 0;
int i = 0;
char *pin = NULL;
char *password = NULL;
char *libname = NULL;
char bPin = FALSE;
char bPassword = FALSE;
char bLibray = FALSE;
if (argc < 5) {
printf
("\nMissing arguments: The format is ./test_unwrap_template -p <PIN> -l <pkcs-lib> \n\n");
return -1;
}
if (argc > 5) {
printf
("\nToo many arguments: The format is ./test_unwrap_template -p <PIN> -l <pkcs-lib> \n\n");
return -1;
}
for (i = 1; i < argc; i++) {
if ((strcmp(argv[i], "-p") == 0) && (argc > i + 1)
&& (bPin == FALSE)) {
pin = argv[++i];
bPin = TRUE;
} else if ((strcmp(argv[i], "-l") == 0) && (argc > i + 1)
&& (bLibray == FALSE)) {
libname = argv[++i];
bLibray = TRUE;
} else {
printf
("\nWrong arguments: The format is ./test_unwrap_template -p <PIN> -l <pkcs-lib>\n\n");
return -1;
}
}
if (!bPin || !bLibray) {
printf
("\nThe format is ./test_unwrap_template -p <PIN> -l <pkcs-lib>\n\n");
return -1;
}
if (load_lib(libname)) {
printf("\n Error: loading library %s\n ", libname);
goto end;
}
if (!module) {
printf("\n Error: module loading failure %s\n ", libname);
goto end;
}
/* prepare the pPin with given username and password */
snprintf(pPin, sizeof(pPin), "%s", pin);
err = do_operation();
if (err) {
printf("Error while running the tests\n");
}
end:
lib_close();
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment