Last active
January 25, 2019 16:46
-
-
Save alfredgamulo/b6f605d00f148a5d739086dd972e2ecf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//$ 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, ¶ms, 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, ¶ms, 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