int sc_init_library(void *f, int try_write_syslog, sc_lib *sclib, Filename *pkcs11_libfile) { CK_FUNCTION_LIST_PTR fl = 0; CK_C_GetFunctionList pGFL = 0; unsigned long slot_count = 16; CK_SLOT_ID slots[16]; CK_RV rv = 0; char *msg = ""; sclib->hLib = LoadLibrary((char *)pkcs11_libfile); if (sclib->hLib == NULL) { msg = "sc: Cannot load PKCS 11 DLL."; goto err; } pGFL= (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))GetProcAddress(sclib->hLib, "C_GetFunctionList"); if (pGFL == NULL) { msg = "sc: Cannot find GetFunctionList()"; goto err; } rv = pGFL(&fl); if(rv != CKR_OK) { msg = "sc: Can't get function list"; goto err; } rv = fl->C_Initialize (0); if (CKR_OK != rv ) { msg = "sc: C_Initialize failed"; goto err; } rv = fl->C_GetSlotList (TRUE, slots, &slot_count); if (CKR_OK != rv) { msg = "sc: C_GetSlotList failed"; goto err; } if (slot_count < 1) { msg = "sc: No token available"; goto err; } sclib->m_fl = fl; return TRUE; err: logevent(f, msg); if(try_write_syslog) sc_write_syslog(msg); FreeLibrary(sclib->hLib); return FALSE; }
static void teardown_mock_module (CK_FUNCTION_LIST_PTR module) { CK_RV rv; rv = module->C_Finalize (NULL); assert (rv == CKR_OK); }
int EstEID_tokensChanged() { LOG_LOCATION; CK_SLOT_ID slotID; int changed = FALSE; while (fl->C_WaitForSlotEvent(CKF_DONT_BLOCK, &slotID, NULL_PTR) == CKR_OK) { EstEID_log("C_WaitForSlotEvent() pass cycle 1"); changed = TRUE; } if (!changed) { while (fl->C_WaitForSlotEvent(CKF_DONT_BLOCK, &slotID, NULL_PTR) == CKR_OK) { EstEID_log("C_WaitForSlotEvent() pass cycle 2"); changed = TRUE; } } EstEID_log("tokens change %sdetected", changed ? "" : "not "); return changed; }
int EstEID_loadCertInfo(EstEID_Certs *certs, int index) { CK_SLOT_ID slotID = certs->slotIDs[index]; CK_SLOT_INFO slotInfo; FAIL_IF(EstEID_CK_failure("C_GetSlotInfo", fl->C_GetSlotInfo(slotID, &slotInfo))); if (!(slotInfo.flags & CKF_TOKEN_PRESENT)) return SUCCESS; CK_TOKEN_INFO tokenInfo; FAIL_IF(EstEID_CK_failure("C_GetTokenInfo", fl->C_GetTokenInfo(slotID, &tokenInfo))); certs->certs[index] = EstEID_createCertMap(tokenInfo); FAIL_UNLESS(EstEID_loadCertInfoEntries(certs, index)); return SUCCESS; }
int EstEID_getRemainingTries(CK_SLOT_ID slotID) { CK_TOKEN_INFO tokenInfo; if (EstEID_CK_failure("C_GetTokenInfo", fl->C_GetTokenInfo(slotID, &tokenInfo))) return -1; EstEID_log("flags: %li (%lx)", tokenInfo.flags, tokenInfo.flags); if (tokenInfo.flags & CKF_USER_PIN_LOCKED) return 0; else if (tokenInfo.flags & CKF_USER_PIN_FINAL_TRY) return 1; else if (tokenInfo.flags & CKF_USER_PIN_COUNT_LOW) return 2; else return 3; }
static void test_initialize_finalize (void) { CK_FUNCTION_LIST_PTR proxy; CK_RV rv; rv = C_GetFunctionList (&proxy); assert (rv == CKR_OK); assert (p11_proxy_module_check (proxy)); rv = proxy->C_Initialize (NULL); assert (rv == CKR_OK); rv = proxy->C_Finalize (NULL); assert_num_eq (rv, CKR_OK); p11_proxy_module_cleanup (); }
int testStability_sign ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivateKey, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR *ppSignature, CK_ULONG_PTR pulSignatureLen ) { CK_RV rv; CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 }; rv = p11->C_SignInit(hSession, &mechanism, hPrivateKey); if (rv != CKR_OK) { printf("ERROR: Failed to initialize signing. rv=%s\n", rv2string(rv)); return 1; } *pulSignatureLen = 0; rv = p11->C_Sign(hSession, pData, ulDataLen, NULL_PTR, pulSignatureLen); if (rv != CKR_OK) { printf("ERROR: Failed to check the size of the signature. rv=%s\n", rv2string(rv)); return 1; } *ppSignature = (CK_BYTE_PTR)malloc(*pulSignatureLen); rv = p11->C_Sign(hSession, pData, ulDataLen, *ppSignature, pulSignatureLen); if (rv != CKR_OK) { printf("ERROR: Failed to sign the data. rv=%s\n", rv2string(rv)); free(*ppSignature); *ppSignature = NULL; *pulSignatureLen = 0; return 1; } return 0; }
// Connect and login to the token int openP11(CK_SLOT_ID slotID, char* userPIN, CK_SESSION_HANDLE* hSession) { char user_pin_copy[MAX_PIN_LEN+1]; CK_RV rv; rv = p11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, hSession); if (rv != CKR_OK) { if (rv == CKR_SLOT_ID_INVALID) { fprintf(stderr, "ERROR: The given slot does not exist.\n"); } else { fprintf(stderr, "ERROR: Could not open a session on the given slot.\n"); } return 1; } // Get the password if (getPW(userPIN, user_pin_copy, CKU_USER) != 0) { fprintf(stderr, "ERROR: Could not get user PIN\n"); return 1; } rv = p11->C_Login(*hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen(user_pin_copy)); if (rv != CKR_OK) { if (rv == CKR_PIN_INCORRECT) { fprintf(stderr, "ERROR: The given user PIN does not match the one in the token.\n"); } else { fprintf(stderr, "ERROR: Could not log in on the token.\n"); } return 1; } return 0; }
// Extract the information about the public RSA key and save it in the token int dbRSAPub2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession) { int result = 0; int i; CK_OBJECT_HANDLE hKey; CK_RV rv; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, NULL, 0 }, { CKA_KEY_TYPE, NULL, 0 }, { CKA_TOKEN, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, { CKA_MODIFIABLE, NULL, 0 }, { CKA_LABEL, NULL, 0 }, { CKA_ID, NULL, 0 }, { CKA_START_DATE, NULL, 0 }, { CKA_END_DATE, NULL, 0 }, { CKA_DERIVE, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, { CKA_ENCRYPT, NULL, 0 }, { CKA_VERIFY, NULL, 0 }, { CKA_VERIFY_RECOVER, NULL, 0 }, { CKA_WRAP, NULL, 0 }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 } }; for (i = 0; i < 17; i++) { result = getAttribute(objectID, &pubTemplate[i]); if (result) { freeTemplate(pubTemplate, 17); return 1; } } rv = p11->C_CreateObject(hSession, pubTemplate, 17, &hKey); if (rv != CKR_OK) { fprintf(stderr, "ERROR %X: Could not save the public key in the token. " "Skipping object %lu\n", (unsigned int)rv, objectID); result = 1; } else { printf("Object %lu has been migrated\n", objectID); } freeTemplate(pubTemplate, 17); return result; }
static void test_initialize_multiple (void) { CK_FUNCTION_LIST_PTR proxy; CK_RV rv; rv = C_GetFunctionList (&proxy); assert (rv == CKR_OK); assert (p11_proxy_module_check (proxy)); rv = proxy->C_Initialize (NULL); assert (rv == CKR_OK); rv = proxy->C_Initialize (NULL); assert (rv == CKR_OK); rv = proxy->C_Finalize (NULL); assert (rv == CKR_OK); rv = proxy->C_Finalize (NULL); assert (rv == CKR_OK); rv = proxy->C_Finalize (NULL); assert (rv == CKR_CRYPTOKI_NOT_INITIALIZED); p11_proxy_module_cleanup (); }
CK_RV pkcs11_find_object(CK_FUNCTION_LIST_PTR funcs, FILE *out, CK_SESSION_HANDLE h_session, CK_ATTRIBUTE_PTR search, CK_ULONG length, CK_OBJECT_HANDLE_PTR objects, CK_ULONG count, CK_ULONG_PTR found) { CK_ULONG f; CK_RV rc; rc = funcs->C_FindObjectsInit(h_session, search, length); if (rc != CKR_OK) { if(out) { show_error(out, "C_FindObjectsInit", rc); } return rc; } rc = funcs->C_FindObjects(h_session, objects, count, &f); if (rc != CKR_OK) { if(out) { show_error(out, "C_FindObjects", rc); } return rc; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { if(out) { show_error(out, "C_FindObjectsFinal", rc); } return rc; } if(found) { *found = f; } return rc; }
CK_RV pkcs11_close(FILE *err, CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE h_session) { CK_RV rc = funcs->C_Logout(h_session); if (rc != CKR_OK) { show_error(err, "C_Logout", rc); return rc; } rc = funcs->C_CloseSession(h_session); if (rc != CKR_OK) { show_error(err, "C_CloseSession", rc); return rc; } rc = funcs->C_Finalize(NULL); if (rc != CKR_OK) { show_error(err, "C_Finalize", rc); return rc; } return rc; }
static void test_token_info() { const CK_CHAR_PTR TOKEN_LABEL = "YubiKey PIV"; const CK_CHAR_PTR TOKEN_MODEL = "YubiKey "; // Skip last 3 characters (version dependent) const CK_CHAR_PTR TOKEN_SERIAL = "1234"; const CK_FLAGS TOKEN_FLAGS = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED; const CK_VERSION HW = {0, 0}; const CK_CHAR_PTR TOKEN_TIME = " "; CK_TOKEN_INFO info; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_GetTokenInfo(0, &info), CKR_OK, "GetTokeninfo"); asrt(strncmp(info.label, TOKEN_LABEL, strlen(TOKEN_LABEL)), 0, "TOKEN_LABEL"); // Skip manufacturer id (not used) asrt(strncmp(info.model, TOKEN_MODEL, strlen(TOKEN_MODEL)), 0, "TOKEN_MODEL"); asrt(strncmp(info.serialNumber, TOKEN_SERIAL, strlen(TOKEN_SERIAL)), 0, "SERIAL_NUMBER"); asrt(info.flags, TOKEN_FLAGS, "TOKEN_FLAGS"); asrt(info.ulMaxSessionCount, CK_UNAVAILABLE_INFORMATION, "MAX_SESSION_COUNT"); asrt(info.ulSessionCount, CK_UNAVAILABLE_INFORMATION, "SESSION_COUNT"); asrt(info.ulMaxRwSessionCount, CK_UNAVAILABLE_INFORMATION, "MAX_RW_SESSION_COUNT"); asrt(info.ulRwSessionCount, CK_UNAVAILABLE_INFORMATION, "RW_SESSION_COUNT"); asrt(info.ulMaxPinLen, 8, "MAX_PIN_LEN"); asrt(info.ulMinPinLen, 6, "MIN_PIN_LEN"); asrt(info.ulTotalPublicMemory, CK_UNAVAILABLE_INFORMATION, "TOTAL_PUB_MEM"); asrt(info.ulFreePublicMemory, CK_UNAVAILABLE_INFORMATION, "FREE_PUB_MEM"); asrt(info.ulTotalPrivateMemory, CK_UNAVAILABLE_INFORMATION, "TOTAL_PVT_MEM"); asrt(info.ulFreePrivateMemory, CK_UNAVAILABLE_INFORMATION, "FREE_PVT_MEM"); asrt(info.hardwareVersion.major, HW.major, "HW_MAJ"); asrt(info.hardwareVersion.minor, HW.minor, "HW_MIN"); if (info.firmwareVersion.major != 4 && info.firmwareVersion.major != 0) asrt(info.firmwareVersion.major, 4, "FW_MAJ"); asrt(strcmp(info.utcTime, TOKEN_TIME), 0, "TOKEN_TIME"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
static void lib_info() { CK_INFO info; CK_FUNCTION_LIST_PTR funcs; if (C_GetFunctionList(&funcs) != CKR_OK) { fprintf(stderr, "Get function list failed\n"); exit(EXIT_FAILURE); } if (funcs->C_GetInfo(&info) != CKR_OK) { fprintf(stderr, "GetInfo failed\n"); exit(EXIT_FAILURE); } if (strcmp(info.manufacturerID, MANUFACTURER_ID) != 0) { fprintf(stderr, "unexpected manufacturer ID %s\n", info.manufacturerID); exit(EXIT_FAILURE); } if (info.cryptokiVersion.major != CRYPTOKI_VERSION_MAJ || info.cryptokiVersion.minor != CRYPTOKI_VERSION_MIN ) { fprintf(stderr, "unexpected Cryptoki version %d.%d\n", info.cryptokiVersion.major, info.cryptokiVersion.minor); exit(EXIT_FAILURE); } if (info.libraryVersion.major != YKCS11_VERSION_MAJOR || info.libraryVersion.minor != ((YKCS11_VERSION_MINOR * 100) + YKCS11_VERSION_PATCH )) { fprintf(stderr, "unexpected YKCS11 version %d.%d\n", info.libraryVersion.major, info.libraryVersion.minor); exit(EXIT_FAILURE); } if (strcmp(info.libraryDescription, YKCS11_DESCRIPTION) != 0) { fprintf(stderr, "unexpected description %s\n", info.libraryDescription); exit(EXIT_FAILURE); } }
CK_RV login(CK_FUNCTION_LIST_PTR p11p, CK_SESSION_HANDLE hSession, int admin, CK_UTF8CHAR *password, CK_ULONG passwordLen) { CK_UTF8CHAR pin[64]; CK_ULONG pinLen = sizeof(pin) - 1; CK_RV rv; if (passwordLen > 0 && password != NULL && passwordLen <= pinLen) { memcpy(pin, password, passwordLen); pinLen = passwordLen; } else { printf("Enter %sPIN: ", (admin == 1) ? "admin " : ""); rv = getPassword(pin, &pinLen); if (rv!= 0) return(-1); } if (admin == 1) rv = p11p->C_Login(hSession, CKU_SO, pin, pinLen); else rv = p11p->C_Login(hSession, CKU_USER, pin, pinLen); memset(pin, 0, sizeof(pin)); return(rv); }
THREAD_RETURN_TYPE EstEID_initializeCryptokiThread(void *v) { LOG_LOCATION; #ifdef _WIN32 WaitForSingleObject(initialization_mutex, INFINITE); #else pthread_mutex_lock(&initialization_mutex); #endif CK_C_INITIALIZE_ARGS init_args; memset( &init_args, 0x0, sizeof(init_args) ); init_args.flags = CKF_OS_LOCKING_OK; struct timeval start = EstEID_startTimer(); initialization_result = fl->C_Initialize(&init_args); EstEID_log("C_Initialize: %s (%li)", pkcs11_error_message(initialization_result), initialization_result); EstEID_stopTimerAndLog(start, "C_Initialize:"); if (initialization_result == CKR_CRYPTOKI_ALREADY_INITIALIZED) { EstEID_log("initialization_result == CKR_CRYPTOKI_ALREADY_INITIALIZED"); } if (initialization_result == CKR_OK) { CK_INFO info; EstEID_log("initialization_result == CKR_OK"); if (!EstEID_CK_failure("C_GetInfo", fl->C_GetInfo(&info))) { EstEID_logInitInfo(info); }; } initialization_completed = TRUE; #ifdef _WIN32 ReleaseMutex(initialization_mutex); return TRUE; #else pthread_cond_broadcast(&initialization_condition); pthread_mutex_unlock(&initialization_mutex); pthread_exit(NULL); #endif }
static CK_FUNCTION_LIST_PTR setup_mock_module (CK_SESSION_HANDLE *session) { CK_FUNCTION_LIST_PTR proxy; CK_SLOT_ID slots[32]; CK_RV rv; rv = C_GetFunctionList (&proxy); assert (rv == CKR_OK); assert (p11_proxy_module_check (proxy)); rv = proxy->C_Initialize (NULL); assert (rv == CKR_OK); mock_slots_all = 32; rv = proxy->C_GetSlotList (CK_FALSE, slots, &mock_slots_all); assert (rv == CKR_OK); assert (mock_slots_all >= 2); /* Assume this is the slot we want to deal with */ mock_slot_one_id = slots[0]; mock_slot_two_id = slots[1]; rv = proxy->C_GetSlotList (CK_TRUE, NULL, &mock_slots_present); assert (rv == CKR_OK); assert (mock_slots_present > 1); if (session) { rv = (proxy->C_OpenSession) (mock_slot_one_id, CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, session); assert (rv == CKR_OK); } return proxy; }
int EstEID_sighHashWindows(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) { CK_SESSION_HANDLE session = 0L; LOG_LOCATION; if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE; char message[1024]; int remainingTries = EstEID_getRemainingTries(slotID); EstEID_log("EstEID_getRemainingTries(slotID) = %i", remainingTries); if (remainingTries == -1) CLOSE_SESSION_AND_RETURN(FAILURE); if (!remainingTries) { sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED); CLOSE_SESSION_AND_RETURN(FAILURE); } if (remainingTries < 3) { sprintf(message, "%s %i", l10n("Tries left:"), remainingTries); } else { message[0] = 0; } CK_RV loginResult = CKR_FUNCTION_CANCELED; LOG_LOCATION; EstEID_log("(unsigned char *)pinPromptData.pin2 = %s", (unsigned char *)pinPromptData.pin2); loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pinPromptData.pin2, strlen(pinPromptData.pin2)); if(loginResult != CKR_OK) { EstEID_log("loginResult = %s", pkcs11_error_message(loginResult)); sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(loginResult), loginResult); CLOSE_SESSION_AND_RETURN(loginResult); } return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, NULL); }
int EstEID_RealSign(CK_SESSION_HANDLE session, char **signature, unsigned int *signatureLength, const char *hash, unsigned int hashLength, char* name) { CK_OBJECT_HANDLE privateKeyHandle; CK_ULONG objectCount; unsigned int hashWithPaddingLength = 0; char *hashWithPadding; CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0}; CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_RETURN(FAILURE); if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &privateKeyHandle, 1, &objectCount))) CLOSE_SESSION_AND_RETURN(FAILURE); if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_RETURN(FAILURE); if (objectCount == 0) CLOSE_SESSION_AND_RETURN(FAILURE); // todo ?? set error message if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle))) CLOSE_SESSION_AND_RETURN(FAILURE); hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength); if (hashWithPadding) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding() CK_ULONG len; if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_RETURN(FAILURE); } *signature = (char *)malloc(len); if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_RETURN(FAILURE); } *signatureLength = len; free(hashWithPadding); } if (session) { if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) { return FAILURE; } } if(name) { free(name); } if (!hashWithPaddingLength) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding() EstEID_log("will not sign due to incorrect incoming message digest length"); return FAILURE; } EstEID_log("successfully signed"); return SUCCESS; }
static void test_session() { CK_SESSION_HANDLE session; CK_SESSION_INFO info; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession2"); asrt(funcs->C_GetSessionInfo(session, &info), CKR_OK, "GetSessionInfo"); asrt(info.state, CKS_RW_PUBLIC_SESSION, "CHECK STATE"); asrt(info.flags, CKF_SERIAL_SESSION | CKF_RW_SESSION, "CHECK FLAGS"); asrt(info.ulDeviceError, 0, "CHECK DEVICE ERROR"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession3"); asrt(funcs->C_CloseAllSessions(0), CKR_OK, "CloseAllSessions"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
/* * Log in to the keystore in the child if we were logged in in the parent. There * are similarities in the code with pk11_token_login() but still it is quite * different so we need a separate function for this. * * Note that this function is called under the locked session mutex when fork is * detected. That means that C_Login() will be called from the child just once. * * Returns: * 1 on success * 0 on failure */ int pk11_token_relogin(CK_SESSION_HANDLE session) { CK_RV rv; /* * We are in the child so check if we should login to the token again. * Note that it is enough to log in to the token through one session * only, all already open and all future sessions can access the token * then. */ if (passphrasedialog != NULL) { char *pin = NULL; /* If we cached the PIN then use it. */ if (token_pin != NULL) pin = token_pin; else if (pk11_get_pin(passphrasedialog, &pin) == 0) goto err; (void) pthread_mutex_lock(uri_lock); if ((rv = pFuncList->C_Login(session, CKU_USER, (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK) { PK11err_add_data(PK11_F_TOKEN_RELOGIN, PK11_R_TOKEN_LOGIN_FAILED, rv); (void) pthread_mutex_unlock(uri_lock); goto err; } (void) pthread_mutex_unlock(uri_lock); /* Forget the PIN now if we did not cache it before. */ if (pin != token_pin) { memset(pin, 0, strlen(pin)); OPENSSL_free(pin); } } return (1); err: return (0); }
static void test_login() { CK_SESSION_HANDLE session; CK_SESSION_INFO info; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
static void test_lib_info() { const CK_CHAR_PTR MANUFACTURER_ID = "Yubico (www.yubico.com)"; const CK_CHAR_PTR YKCS11_DESCRIPTION = "PKCS#11 PIV Library (SP-800-73)"; const CK_ULONG CRYPTOKI_VERSION_MAJ = 2; const CK_ULONG CRYPTOKI_VERSION_MIN = 40; CK_INFO info; asrt(funcs->C_GetInfo(&info), CKR_OK, "GET_INFO"); asrt(strcmp(info.manufacturerID, MANUFACTURER_ID), 0, "MANUFACTURER"); asrt(info.cryptokiVersion.major, CRYPTOKI_VERSION_MAJ, "CK_MAJ"); asrt(info.cryptokiVersion.minor, CRYPTOKI_VERSION_MIN, "CK_MIN"); asrt(info.libraryVersion.major, YKCS11_VERSION_MAJOR, "LIB_MAJ"); asrt(info.libraryVersion.minor, ((YKCS11_VERSION_MINOR * 10) + YKCS11_VERSION_PATCH ), "LIB_MIN"); asrt(strcmp(info.libraryDescription, YKCS11_DESCRIPTION), 0, "LIB_DESC"); }
int testStability_generate(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hPublicKey, CK_OBJECT_HANDLE *hPrivateKey) { CK_RV rv; CK_BBOOL ckTrue = CK_TRUE; CK_MECHANISM keyGenMechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0}; CK_BYTE publicExponent[] = { 1, 0, 1 }; CK_ULONG modulusBits = 1024; CK_MECHANISM mechanism = { CKM_VENDOR_DEFINED, NULL_PTR, 0 }; CK_ATTRIBUTE publicKeyTemplate[] = { { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) }, { CKA_VERIFY, &ckTrue, sizeof(ckTrue) }, { CKA_WRAP, &ckTrue, sizeof(ckTrue) }, { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, { CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits) }, { CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent) } }; CK_ATTRIBUTE privateKeyTemplate[] = { { CKA_PRIVATE, &ckTrue, sizeof(ckTrue) }, { CKA_SENSITIVE, &ckTrue, sizeof(ckTrue) }, { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) }, { CKA_SIGN, &ckTrue, sizeof(ckTrue) }, { CKA_UNWRAP, &ckTrue, sizeof(ckTrue) }, { CKA_TOKEN, &ckTrue, sizeof(ckTrue) } }; printf("Generating a key pair...\n"); rv = p11->C_GenerateKeyPair(hSession, &keyGenMechanism, publicKeyTemplate, 6, privateKeyTemplate, 6, hPublicKey, hPrivateKey); if (rv != CKR_OK) { printf("ERROR: Failed to generate a keypair. rv=%s\n", rv2string(rv)); return 1; } return 0; }
THREAD_RETURN_TYPE EstEID_pinPadLogin(void* threadData) { LOG_LOCATION; #ifndef _WIN32 pthread_mutex_lock(&pinpad_thread_mutex); CK_SESSION_HANDLE session = ((EstEID_PINPadThreadData*)threadData)->session; CK_RV loginResult = fl->C_Login(session, CKU_USER, NULL, 0); ((EstEID_PINPadThreadData*)threadData)->result = loginResult; closePinPadModalSheet(); EstEID_log("modal sheet/dialog destroyed"); pinpad_thread_completed = TRUE; pthread_cond_broadcast(&pinpad_thread_condition); pthread_mutex_unlock(&pinpad_thread_mutex); pthread_exit(NULL); #else WaitForSingleObject(pinpad_thread_mutex, INFINITE); EstEID_PINPromptDataEx* pinPromptDataEx = (EstEID_PINPromptDataEx*)threadData; pinPromptDataEx->pinPromptData.promptFunction(NULL, pinPromptDataEx->name, pinPromptDataEx->message, 0, true); ReleaseMutex(pinpad_thread_mutex); return TRUE; #endif }
static CK_RV hacky_perform_initialize_pin (GP11Slot *slot) { CK_FUNCTION_LIST_PTR funcs; CK_SESSION_HANDLE session; CK_SLOT_ID slot_id; CK_RV rv; /* * This hack only works when: * * - Module is protected authentication path * - No other sessions are open. * * Thankfully this is the case with mate-keyring-daemon and * the mate-keyring tool. */ funcs = gp11_module_get_functions (gp11_slot_get_module (slot)); g_return_val_if_fail (funcs, CKR_GENERAL_ERROR); slot_id = gp11_slot_get_handle (slot); rv = funcs->C_OpenSession (slot_id, CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session); if (rv != CKR_OK) return rv; rv = funcs->C_Login (session, CKU_SO, NULL, 0); if (rv == CKR_OK) { rv = funcs->C_InitPIN (session, NULL, 0); funcs->C_Logout (session); } funcs->C_CloseSession (session); return rv; }
int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) { CK_SESSION_HANDLE session = 0L; LOG_LOCATION; if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE; char *name = EstEID_getFullNameWithPersonalCode(cert); for (int attempt = 0, blocked = FALSE;; attempt++) { char message[1024]; int remainingTries = EstEID_getRemainingTries(slotID); if (remainingTries == -1) CLOSE_SESSION_AND_RETURN(FAILURE); if (!remainingTries || blocked) { sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED); pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, can not sign!")); CLOSE_SESSION_AND_RETURN(FAILURE); } if (remainingTries < 3 || attempt) { sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries); } else { message[0] = 0; } int isPinPad = EstEID_isPinPad(slotID); CK_RV loginResult = CKR_FUNCTION_CANCELED; if(!isPinPad) { // Simple card reader char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad); if (!pin || strlen(pin) == 0) { if (pin) free(pin); setUserCancelErrorCodeAndMessage(); CLOSE_SESSION_AND_RETURN(FAILURE); } loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin)); free(pin); } else { // PIN pad #ifdef _WIN32 EstEID_log("creating pinpad dialog UI thread"); pinpad_thread_result = -1; FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL))); #else EstEID_log("creating pinpad worker thread"); pinpad_thread_result = -1; FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL)); FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL)); pthread_t pinpad_thread; EstEID_PINPadThreadData threadData; threadData.session = session; threadData.result = CKR_OK; #endif EstEID_log("thread launched"); #ifdef _WIN32 /* NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread and UI code is running in separate thread if running on Windows. */ EstEID_PINPromptDataEx pinPromptDataEx; pinPromptDataEx.pinPromptData = pinPromptData; pinPromptDataEx.message = message; pinPromptDataEx.name = name; CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL); loginResult = fl->C_Login(session, CKU_USER, NULL, 0); closePinPadModalSheet(); #else FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData)); pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad); loginResult = threadData.result; #endif EstEID_log("pinpad sheet/dialog closed"); if (loginResult == CKR_FUNCTION_CANCELED) { setUserCancelErrorCodeAndMessage(); CLOSE_SESSION_AND_RETURN(FAILURE); } } EstEID_log("loginResult = %s", pkcs11_error_message(loginResult)); switch (loginResult) { case CKR_PIN_LOCKED: blocked = TRUE; case CKR_PIN_INCORRECT: case CKR_PIN_INVALID: case CKR_PIN_LEN_RANGE: EstEID_log("this was attempt %i, loginResult causes to run next round", attempt); continue; default: if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_RETURN(FAILURE); } break; // Login successful - correct PIN supplied } return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, name); }
// Extract the information about the private RSA key and save it in the token int dbRSAPriv2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession) { int result = 0; int i; CK_OBJECT_HANDLE hKey; CK_RV rv; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, NULL, 0 }, { CKA_TOKEN, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, { CKA_MODIFIABLE, NULL, 0 }, { CKA_LABEL, NULL, 0 }, { CKA_KEY_TYPE, NULL, 0 }, { CKA_ID, NULL, 0 }, { CKA_START_DATE, NULL, 0 }, { CKA_END_DATE, NULL, 0 }, { CKA_DERIVE, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, { CKA_SENSITIVE, NULL, 0 }, { CKA_DECRYPT, NULL, 0 }, { CKA_SIGN, NULL, 0 }, { CKA_SIGN_RECOVER, NULL, 0 }, { CKA_UNWRAP, NULL, 0 }, { CKA_EXTRACTABLE, NULL, 0 }, { CKA_WRAP_WITH_TRUSTED, NULL, 0 }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, { CKA_PRIME_1, NULL, 0 }, { CKA_PRIME_2, NULL, 0 } // SoftHSM v1 did not store these values // { CKA_EXPONENT_1, NULL, 0 }, // { CKA_EXPONENT_2, NULL, 0 }, // { CKA_COEFFICIENT, NULL, 0 } }; for (i = 0; i < 23; i++) { result = getAttribute(objectID, &privTemplate[i]); if (result) { freeTemplate(privTemplate, 23); return 1; } } rv = p11->C_CreateObject(hSession, privTemplate, 23, &hKey); if (rv != CKR_OK) { fprintf(stderr, "ERROR %X: Could not save the private key in the token. " "Skipping object %lu\n", (unsigned int)rv, objectID); result = 1; } else { printf("Object %lu has been migrated\n", objectID); } freeTemplate(privTemplate, 23); return result; }
// The main function int main(int argc, char* argv[]) { int option_index = 0; int opt; char* dbPath = NULL; char* userPIN = NULL; char* module = NULL; char* slot = NULL; char* serial = NULL; char* token = NULL; char *errMsg = NULL; int noPublicKey = 0; int result = 0; CK_RV rv; moduleHandle = NULL; p11 = NULL; CK_SLOT_ID slotID = 0; if (argc == 1) { usage(); exit(0); } while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) { switch (opt) { case OPT_DB: dbPath = optarg; break; case OPT_SLOT: slot = optarg; break; case OPT_SERIAL: serial = optarg; break; case OPT_TOKEN: token = optarg; break; case OPT_MODULE: module = optarg; break; case OPT_NO_PUBLIC_KEY: noPublicKey = 1; break; case OPT_PIN: userPIN = optarg; break; case OPT_VERSION: case 'v': printf("%s\n", PACKAGE_VERSION); exit(0); break; case OPT_HELP: case 'h': default: usage(); exit(0); break; } } // Get a pointer to the function list for PKCS#11 library CK_C_GetFunctionList pGetFunctionList = loadLibrary(module, &moduleHandle, &errMsg); if (pGetFunctionList == NULL) { fprintf(stderr, "ERROR: Could not load the library: %s\n", errMsg); exit(1); } // Load the function list (*pGetFunctionList)(&p11); // Initialize the library rv = p11->C_Initialize(NULL_PTR); if (rv != CKR_OK) { fprintf(stderr, "ERROR: Could not initialize the library.\n"); exit(1); } // Get the slotID result = findSlot(slot, serial, token, slotID); if (!result) { // Migrate the database result = migrate(dbPath, slotID, userPIN, noPublicKey); } // Finalize the library p11->C_Finalize(NULL_PTR); unloadLibrary(moduleHandle); return result; }
int rmain ( int argc, char *argv[] ) { char *argv0 = argv[0]; PRLibrary *lib; CK_C_GetFunctionList gfl; CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR)NULL; CK_RV ck_rv; CK_INFO info; CK_ULONG nSlots; CK_SLOT_ID *pSlots; CK_ULONG i; CK_C_INITIALIZE_ARGS ia, *iap; (void)memset(&ia, 0, sizeof(CK_C_INITIALIZE_ARGS)); iap = (CK_C_INITIALIZE_ARGS *)NULL; while( argv++, --argc ) { if( '-' == argv[0][0] ) { switch( argv[0][1] ) { case 'i': iap = &ia; if( ((char *)NULL != argv[1]) && ('-' != argv[1][0]) ) { #ifdef WITH_NSS ia.pConfig = argv[1]; ia.ulConfigLen = strlen(argv[1]); argv++, --argc; #else return usage(argv0); #endif /* WITH_NSS */ } break; case '-': argv++, --argc; goto endargs; default: return usage(argv0); } } else { break; } } endargs:; if( 1 != argc ) { return usage(argv0); } lib = PR_LoadLibrary(argv[0]); if( (PRLibrary *)NULL == lib ) { PR_fprintf(PR_STDERR, "Can't load %s: %ld, %ld\n", argv[1], PR_GetError(), PR_GetOSError()); return 1; } gfl = (CK_C_GetFunctionList)PR_FindSymbol(lib, "C_GetFunctionList"); if( (CK_C_GetFunctionList)NULL == gfl ) { PR_fprintf(PR_STDERR, "Can't find C_GetFunctionList in %s: %ld, %ld\n", argv[1], PR_GetError(), PR_GetOSError()); return 1; } ck_rv = (*gfl)(&epv); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "CK_GetFunctionList returned 0x%08x\n", ck_rv); return 1; } PR_fprintf(PR_STDOUT, "Module %s loaded, epv = 0x%08x.\n\n", argv[1], (CK_ULONG)epv); /* C_Initialize */ ck_rv = epv->C_Initialize(iap); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_Initialize returned 0x%08x\n", ck_rv); return 1; } /* C_GetInfo */ (void)memset(&info, 0, sizeof(CK_INFO)); ck_rv = epv->C_GetInfo(&info); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetInfo returned 0x%08x\n", ck_rv); return 1; } PR_fprintf(PR_STDOUT, "Module Info:\n"); PR_fprintf(PR_STDOUT, " cryptokiVersion = %lu.%02lu\n", (PRUint32)info.cryptokiVersion.major, (PRUint32)info.cryptokiVersion.minor); PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", info.manufacturerID); PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", info.flags); PR_fprintf(PR_STDOUT, " libraryDescription = \"%.32s\"\n", info.libraryDescription); PR_fprintf(PR_STDOUT, " libraryVersion = %lu.%02lu\n", (PRUint32)info.libraryVersion.major, (PRUint32)info.libraryVersion.minor); PR_fprintf(PR_STDOUT, "\n"); /* C_GetSlotList */ nSlots = 0; ck_rv = epv->C_GetSlotList(CK_FALSE, (CK_SLOT_ID_PTR)CK_NULL_PTR, &nSlots); switch( ck_rv ) { case CKR_BUFFER_TOO_SMALL: case CKR_OK: break; default: PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, NULL, ) returned 0x%08x\n", ck_rv); return 1; } PR_fprintf(PR_STDOUT, "There are %lu slots.\n", nSlots); pSlots = (CK_SLOT_ID_PTR)PR_Calloc(nSlots, sizeof(CK_SLOT_ID)); if( (CK_SLOT_ID_PTR)NULL == pSlots ) { PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nSlots * sizeof(CK_SLOT_ID)); return 1; } ck_rv = epv->C_GetSlotList(CK_FALSE, pSlots, &nSlots); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, , ) returned 0x%08x\n", ck_rv); return 1; } for( i = 0; i < nSlots; i++ ) { PR_fprintf(PR_STDOUT, " [%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]); } PR_fprintf(PR_STDOUT, "\n"); /* C_GetSlotInfo */ for( i = 0; i < nSlots; i++ ) { CK_SLOT_INFO sinfo; PR_fprintf(PR_STDOUT, "[%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]); (void)memset(&sinfo, 0, sizeof(CK_SLOT_INFO)); ck_rv = epv->C_GetSlotInfo(pSlots[i], &sinfo); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetSlotInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Slot Info:\n"); PR_fprintf(PR_STDOUT, " slotDescription = \"%.64s\"\n", sinfo.slotDescription); PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", sinfo.manufacturerID); PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", sinfo.flags); PR_fprintf(PR_STDOUT, " -> TOKEN PRESENT = %s\n", sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> REMOVABLE DEVICE = %s\n", sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> HW SLOT = %s\n", sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " hardwareVersion = %lu.%02lu\n", (PRUint32)sinfo.hardwareVersion.major, (PRUint32)sinfo.hardwareVersion.minor); PR_fprintf(PR_STDOUT, " firmwareVersion = %lu.%02lu\n", (PRUint32)sinfo.firmwareVersion.major, (PRUint32)sinfo.firmwareVersion.minor); if( sinfo.flags & CKF_TOKEN_PRESENT ) { CK_TOKEN_INFO tinfo; CK_MECHANISM_TYPE *pMechanismList; CK_ULONG nMechanisms = 0; CK_ULONG j; (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO)); ck_rv = epv->C_GetTokenInfo(pSlots[i], &tinfo); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetTokenInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Token Info:\n"); PR_fprintf(PR_STDOUT, " label = \"%.32s\"\n", tinfo.label); PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", tinfo.manufacturerID); PR_fprintf(PR_STDOUT, " model = \"%.16s\"\n", tinfo.model); PR_fprintf(PR_STDOUT, " serialNumber = \"%.16s\"\n", tinfo.serialNumber); PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", tinfo.flags); PR_fprintf(PR_STDOUT, " -> RNG = %s\n", tinfo.flags & CKF_RNG ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> WRITE PROTECTED = %s\n", tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> LOGIN REQUIRED = %s\n", tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> USER PIN INITIALIZED = %s\n", tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> RESTORE KEY NOT NEEDED = %s\n", tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> CLOCK ON TOKEN = %s\n", tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE"); #ifdef CKF_SUPPORTS_PARALLEL PR_fprintf(PR_STDOUT, " -> SUPPORTS PARALLEL = %s\n", tinfo.flags & CKF_SUPPORTS_PARALLEL ? "TRUE" : "FALSE"); #endif /* CKF_SUPPORTS_PARALLEL */ PR_fprintf(PR_STDOUT, " -> PROTECTED AUTHENTICATION PATH = %s\n", tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> DUAL_CRYPTO_OPERATIONS = %s\n", tinfo.flags & CKF_DUAL_CRYPTO_OPERATIONS ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " ulMaxSessionCount = %lu\n", tinfo.ulMaxSessionCount); PR_fprintf(PR_STDOUT, " ulSessionCount = %lu\n", tinfo.ulSessionCount); PR_fprintf(PR_STDOUT, " ulMaxRwSessionCount = %lu\n", tinfo.ulMaxRwSessionCount); PR_fprintf(PR_STDOUT, " ulRwSessionCount = %lu\n", tinfo.ulRwSessionCount); PR_fprintf(PR_STDOUT, " ulMaxPinLen = %lu\n", tinfo.ulMaxPinLen); PR_fprintf(PR_STDOUT, " ulMinPinLen = %lu\n", tinfo.ulMinPinLen); PR_fprintf(PR_STDOUT, " ulTotalPublicMemory = %lu\n", tinfo.ulTotalPublicMemory); PR_fprintf(PR_STDOUT, " ulFreePublicMemory = %lu\n", tinfo.ulFreePublicMemory); PR_fprintf(PR_STDOUT, " ulTotalPrivateMemory = %lu\n", tinfo.ulTotalPrivateMemory); PR_fprintf(PR_STDOUT, " ulFreePrivateMemory = %lu\n", tinfo.ulFreePrivateMemory); PR_fprintf(PR_STDOUT, " hardwareVersion = %lu.%02lu\n", (PRUint32)tinfo.hardwareVersion.major, (PRUint32)tinfo.hardwareVersion.minor); PR_fprintf(PR_STDOUT, " firmwareVersion = %lu.%02lu\n", (PRUint32)tinfo.firmwareVersion.major, (PRUint32)tinfo.firmwareVersion.minor); PR_fprintf(PR_STDOUT, " utcTime = \"%.16s\"\n", tinfo.utcTime); ck_rv = epv->C_GetMechanismList(pSlots[i], (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR, &nMechanisms); switch( ck_rv ) { case CKR_BUFFER_TOO_SMALL: case CKR_OK: break; default: PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, NULL, ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " %lu mechanisms:\n", nMechanisms); pMechanismList = (CK_MECHANISM_TYPE_PTR)PR_Calloc(nMechanisms, sizeof(CK_MECHANISM_TYPE)); if( (CK_MECHANISM_TYPE_PTR)NULL == pMechanismList ) { PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nMechanisms * sizeof(CK_MECHANISM_TYPE)); return 1; } ck_rv = epv->C_GetMechanismList(pSlots[i], pMechanismList, &nMechanisms); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } for( j = 0; j < nMechanisms; j++ ) { PR_fprintf(PR_STDOUT, " {%lu}: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]); } PR_fprintf(PR_STDOUT, "\n"); for( j = 0; j < nMechanisms; j++ ) { CK_MECHANISM_INFO minfo; (void)memset(&minfo, 0, sizeof(CK_MECHANISM_INFO)); ck_rv = epv->C_GetMechanismInfo(pSlots[i], pMechanismList[j], &minfo); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_GetMechanismInfo(%lu, %lu, ) returned 0x%08x\n", pSlots[i], pMechanismList[j]); return 1; } PR_fprintf(PR_STDOUT, " [%lu]: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]); PR_fprintf(PR_STDOUT, " ulMinKeySize = %lu\n", minfo.ulMinKeySize); PR_fprintf(PR_STDOUT, " ulMaxKeySize = %lu\n", minfo.ulMaxKeySize); PR_fprintf(PR_STDOUT, " flags = 0x%08x\n", minfo.flags); PR_fprintf(PR_STDOUT, " -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, "\n"); } if( tinfo.flags & CKF_LOGIN_REQUIRED ) { PR_fprintf(PR_STDERR, "*** LOGIN REQUIRED but not yet implemented ***\n"); /* all the stuff about logging in as SO and setting the user pin if needed, etc. */ return 2; } /* session to find objects */ { CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; CK_SESSION_INFO sinfo; CK_ATTRIBUTE_PTR pTemplate; CK_ULONG tnObjects = 0; ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO)); ck_rv = epv->C_GetSessionInfo(h, &sinfo); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDOUT, "C_GetSessionInfo(%lu, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " SESSION INFO:\n"); PR_fprintf(PR_STDOUT, " slotID = %lu\n", sinfo.slotID); PR_fprintf(PR_STDOUT, " state = %lu\n", sinfo.state); PR_fprintf(PR_STDOUT, " flags = 0x%08x\n", sinfo.flags); #ifdef CKF_EXCLUSIVE_SESSION PR_fprintf(PR_STDOUT, " -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE"); #endif /* CKF_EXCLUSIVE_SESSION */ PR_fprintf(PR_STDOUT, " -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE"); PR_fprintf(PR_STDOUT, " -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE"); #ifdef CKF_INSERTION_CALLBACK PR_fprintf(PR_STDOUT, " -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE"); #endif /* CKF_INSERTION_CALLBACK */ PR_fprintf(PR_STDOUT, " ulDeviceError = %lu\n", sinfo.ulDeviceError); PR_fprintf(PR_STDOUT, "\n"); ck_rv = epv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDOUT, "C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x\n", h, ck_rv); return 1; } pTemplate = (CK_ATTRIBUTE_PTR)PR_Calloc(number_of_all_known_attribute_types, sizeof(CK_ATTRIBUTE)); if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", number_of_all_known_attribute_types * sizeof(CK_ATTRIBUTE)); return 1; } PR_fprintf(PR_STDOUT, " All objects:\n"); while(1) { CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0; CK_ULONG nObjects = 0; CK_ULONG k; CK_ULONG nAttributes = 0; CK_ATTRIBUTE_PTR pT2; CK_ULONG l; ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 0 == nObjects ) { PR_fprintf(PR_STDOUT, "\n"); break; } tnObjects++; PR_fprintf(PR_STDOUT, " OBJECT HANDLE %lu:\n", o); for( k = 0; k < number_of_all_known_attribute_types; k++ ) { pTemplate[k].type = all_known_attribute_types[k]; pTemplate[k].pValue = (CK_VOID_PTR)CK_NULL_PTR; pTemplate[k].ulValueLen = 0; } ck_rv = epv->C_GetAttributeValue(h, o, pTemplate, number_of_all_known_attribute_types); switch( ck_rv ) { case CKR_OK: case CKR_ATTRIBUTE_SENSITIVE: case CKR_ATTRIBUTE_TYPE_INVALID: case CKR_BUFFER_TOO_SMALL: break; default: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {all attribute types}, %lu) returned 0x%08x\n", h, o, number_of_all_known_attribute_types, ck_rv); return 1; } for( k = 0; k < number_of_all_known_attribute_types; k++ ) { if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { nAttributes++; } } if( 1 ) { PR_fprintf(PR_STDOUT, " %lu attributes:\n", nAttributes); for( k = 0; k < number_of_all_known_attribute_types; k++ ) { if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { PR_fprintf(PR_STDOUT, " 0x%08x (len = %lu)\n", pTemplate[k].type, pTemplate[k].ulValueLen); } } PR_fprintf(PR_STDOUT, "\n"); } pT2 = (CK_ATTRIBUTE_PTR)PR_Calloc(nAttributes, sizeof(CK_ATTRIBUTE)); if( (CK_ATTRIBUTE_PTR)NULL == pT2 ) { PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nAttributes * sizeof(CK_ATTRIBUTE)); return 1; } for( l = 0, k = 0; k < number_of_all_known_attribute_types; k++ ) { if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { pT2[l].type = pTemplate[k].type; pT2[l].ulValueLen = pTemplate[k].ulValueLen; pT2[l].pValue = (CK_VOID_PTR)PR_Malloc(pT2[l].ulValueLen); if( (CK_VOID_PTR)NULL == pT2[l].pValue ) { PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", pT2[l].ulValueLen); return 1; } l++; } } PR_ASSERT( l == nAttributes ); ck_rv = epv->C_GetAttributeValue(h, o, pT2, nAttributes); switch( ck_rv ) { case CKR_OK: case CKR_ATTRIBUTE_SENSITIVE: case CKR_ATTRIBUTE_TYPE_INVALID: case CKR_BUFFER_TOO_SMALL: break; default: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {existent attribute types}, %lu) returned 0x%08x\n", h, o, nAttributes, ck_rv); return 1; } for( l = 0; l < nAttributes; l++ ) { PR_fprintf(PR_STDOUT, " type = 0x%08x, len = %ld", pT2[l].type, (CK_LONG)pT2[l].ulValueLen); if( -1 == (CK_LONG)pT2[l].ulValueLen ) { ; } else { CK_ULONG m; if( pT2[l].ulValueLen <= 8 ) { PR_fprintf(PR_STDOUT, ", value = "); } else { PR_fprintf(PR_STDOUT, ", value = \n "); } for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { PR_fprintf(PR_STDOUT, "%02x", (CK_ULONG)(0xff & ((CK_CHAR_PTR)pT2[l].pValue)[m])); } PR_fprintf(PR_STDOUT, " "); for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m]; if( (c < 0x20) || (c >= 0x7f) ) { c = '.'; } PR_fprintf(PR_STDOUT, "%c", c); } } PR_fprintf(PR_STDOUT, "\n"); } PR_fprintf(PR_STDOUT, "\n"); for( l = 0; l < nAttributes; l++ ) { PR_Free(pT2[l].pValue); } PR_Free(pT2); } /* while(1) */ ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " (%lu objects total)\n", tnObjects); ck_rv = epv->C_CloseSession(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv); return 1; } } /* session to find objects */ /* session to create, find, and delete a couple session objects */ { CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1]; CK_OBJECT_CLASS cko_data = CKO_DATA; CK_BBOOL false = CK_FALSE, true = CK_TRUE; char *key = "TEST PROGRAM"; CK_ULONG key_len = strlen(key); CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0, hTwoIn = (CK_OBJECT_HANDLE)0, hThreeIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0; CK_OBJECT_HANDLE found[10]; CK_ULONG nFound; ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); one[0].type = CKA_CLASS; one[0].pValue = &cko_data; one[0].ulValueLen = sizeof(CK_OBJECT_CLASS); one[1].type = CKA_TOKEN; one[1].pValue = &false; one[1].ulValueLen = sizeof(CK_BBOOL); one[2].type = CKA_PRIVATE; one[2].pValue = &false; one[2].ulValueLen = sizeof(CK_BBOOL); one[3].type = CKA_MODIFIABLE; one[3].pValue = &true; one[3].ulValueLen = sizeof(CK_BBOOL); one[4].type = CKA_LABEL; one[4].pValue = "Test data object one"; one[4].ulValueLen = strlen(one[4].pValue); one[5].type = CKA_APPLICATION; one[5].pValue = key; one[5].ulValueLen = key_len; one[6].type = CKA_VALUE; one[6].pValue = "Object one"; one[6].ulValueLen = strlen(one[6].pValue); two[0].type = CKA_CLASS; two[0].pValue = &cko_data; two[0].ulValueLen = sizeof(CK_OBJECT_CLASS); two[1].type = CKA_TOKEN; two[1].pValue = &false; two[1].ulValueLen = sizeof(CK_BBOOL); two[2].type = CKA_PRIVATE; two[2].pValue = &false; two[2].ulValueLen = sizeof(CK_BBOOL); two[3].type = CKA_MODIFIABLE; two[3].pValue = &true; two[3].ulValueLen = sizeof(CK_BBOOL); two[4].type = CKA_LABEL; two[4].pValue = "Test data object two"; two[4].ulValueLen = strlen(two[4].pValue); two[5].type = CKA_APPLICATION; two[5].pValue = key; two[5].ulValueLen = key_len; two[6].type = CKA_VALUE; two[6].pValue = "Object two"; two[6].ulValueLen = strlen(two[6].pValue); three[0].type = CKA_CLASS; three[0].pValue = &cko_data; three[0].ulValueLen = sizeof(CK_OBJECT_CLASS); three[1].type = CKA_TOKEN; three[1].pValue = &false; three[1].ulValueLen = sizeof(CK_BBOOL); three[2].type = CKA_PRIVATE; three[2].pValue = &false; three[2].ulValueLen = sizeof(CK_BBOOL); three[3].type = CKA_MODIFIABLE; three[3].pValue = &true; three[3].ulValueLen = sizeof(CK_BBOOL); three[4].type = CKA_LABEL; three[4].pValue = "Test data object three"; three[4].ulValueLen = strlen(three[4].pValue); three[5].type = CKA_APPLICATION; three[5].pValue = key; three[5].ulValueLen = key_len; three[6].type = CKA_VALUE; three[6].pValue = "Object three"; three[6].ulValueLen = strlen(three[6].pValue); ck_rv = epv->C_CreateObject(h, one, 7, &hOneIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, one, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object one: handle = %lu\n", hOneIn); ck_rv = epv->C_CreateObject(h, two, 7, &hTwoIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, two, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object two: handle = %lu\n", hTwoIn); ck_rv = epv->C_CreateObject(h, three, 7, &hThreeIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object three: handle = %lu\n", hThreeIn); delta[0].type = CKA_VALUE; delta[0].pValue = "Copied object"; delta[0].ulValueLen = strlen(delta[0].pValue); ck_rv = epv->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CopyObject(%lu, %lu, delta, 1, ) returned 0x%08x\n", h, hThreeIn, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Copied object three: new handle = %lu\n", hDeltaIn); mask[0].type = CKA_APPLICATION; mask[0].pValue = key; mask[0].ulValueLen = key_len; ck_rv = epv->C_FindObjectsInit(h, mask, 1); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", h, ck_rv); return 1; } (void)memset(&found, 0, sizeof(found)); nFound = 0; ck_rv = epv->C_FindObjects(h, found, 10, &nFound); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 4 != nFound ) { PR_fprintf(PR_STDERR, "Found %lu objects, not 4.\n", nFound); return 1; } PR_fprintf(PR_STDOUT, " Found 4 objects: %lu, %lu, %lu, %lu\n", found[0], found[1], found[2], found[3]); ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } ck_rv = epv->C_DestroyObject(h, hThreeIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, hThreeIn, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Destroyed object three (handle = %lu)\n", hThreeIn); delta[0].type = CKA_APPLICATION; delta[0].pValue = "Changed application"; delta[0].ulValueLen = strlen(delta[0].pValue); ck_rv = epv->C_SetAttributeValue(h, hTwoIn, delta, 1); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", h, hTwoIn, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Changed object two (handle = %lu).\n", hTwoIn); /* Can another session find these session objects? */ { CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0; ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Opened a second session: handle = 0x%08x\n", h2); /* mask is still the same */ ck_rv = epv->C_FindObjectsInit(h2, mask, 1); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", h2, ck_rv); return 1; } (void)memset(&found, 0, sizeof(found)); nFound = 0; ck_rv = epv->C_FindObjects(h2, found, 10, &nFound); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", h2, ck_rv); return 1; } if( 2 != nFound ) { PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); return 1; } PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", found[0], found[1]); ck_rv = epv->C_FindObjectsFinal(h2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h2, ck_rv); return 1; } /* Leave the session hanging open, we'll CloseAllSessions later */ } /* Can another session find these session objects? */ ck_rv = epv->C_CloseAllSessions(pSlots[i]); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CloseAllSessions(%lu) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } } /* session to create, find, and delete a couple session objects */ /* Might be interesting to do a find here to verify that all session objects are gone. */ if( tinfo.flags & CKF_WRITE_PROTECTED ) { PR_fprintf(PR_STDOUT, "Token is write protected, skipping token-object tests.\n"); } else { CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; CK_ATTRIBUTE tobj[7], tsobj[7], stobj[7], delta[1], mask[2]; CK_OBJECT_CLASS cko_data = CKO_DATA; CK_BBOOL false = CK_FALSE, true = CK_TRUE; char *key = "TEST PROGRAM"; CK_ULONG key_len = strlen(key); CK_OBJECT_HANDLE hTIn = (CK_OBJECT_HANDLE)0, hTSIn = (CK_OBJECT_HANDLE)0, hSTIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0; CK_OBJECT_HANDLE found[10]; CK_ULONG nFound; ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); tobj[0].type = CKA_CLASS; tobj[0].pValue = &cko_data; tobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); tobj[1].type = CKA_TOKEN; tobj[1].pValue = &true; tobj[1].ulValueLen = sizeof(CK_BBOOL); tobj[2].type = CKA_PRIVATE; tobj[2].pValue = &false; tobj[2].ulValueLen = sizeof(CK_BBOOL); tobj[3].type = CKA_MODIFIABLE; tobj[3].pValue = &true; tobj[3].ulValueLen = sizeof(CK_BBOOL); tobj[4].type = CKA_LABEL; tobj[4].pValue = "Test data object token"; tobj[4].ulValueLen = strlen(tobj[4].pValue); tobj[5].type = CKA_APPLICATION; tobj[5].pValue = key; tobj[5].ulValueLen = key_len; tobj[6].type = CKA_VALUE; tobj[6].pValue = "Object token"; tobj[6].ulValueLen = strlen(tobj[6].pValue); tsobj[0].type = CKA_CLASS; tsobj[0].pValue = &cko_data; tsobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); tsobj[1].type = CKA_TOKEN; tsobj[1].pValue = &true; tsobj[1].ulValueLen = sizeof(CK_BBOOL); tsobj[2].type = CKA_PRIVATE; tsobj[2].pValue = &false; tsobj[2].ulValueLen = sizeof(CK_BBOOL); tsobj[3].type = CKA_MODIFIABLE; tsobj[3].pValue = &true; tsobj[3].ulValueLen = sizeof(CK_BBOOL); tsobj[4].type = CKA_LABEL; tsobj[4].pValue = "Test data object token->session"; tsobj[4].ulValueLen = strlen(tsobj[4].pValue); tsobj[5].type = CKA_APPLICATION; tsobj[5].pValue = key; tsobj[5].ulValueLen = key_len; tsobj[6].type = CKA_VALUE; tsobj[6].pValue = "Object token->session"; tsobj[6].ulValueLen = strlen(tsobj[6].pValue); stobj[0].type = CKA_CLASS; stobj[0].pValue = &cko_data; stobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); stobj[1].type = CKA_TOKEN; stobj[1].pValue = &false; stobj[1].ulValueLen = sizeof(CK_BBOOL); stobj[2].type = CKA_PRIVATE; stobj[2].pValue = &false; stobj[2].ulValueLen = sizeof(CK_BBOOL); stobj[3].type = CKA_MODIFIABLE; stobj[3].pValue = &true; stobj[3].ulValueLen = sizeof(CK_BBOOL); stobj[4].type = CKA_LABEL; stobj[4].pValue = "Test data object session->token"; stobj[4].ulValueLen = strlen(stobj[4].pValue); stobj[5].type = CKA_APPLICATION; stobj[5].pValue = key; stobj[5].ulValueLen = key_len; stobj[6].type = CKA_VALUE; stobj[6].pValue = "Object session->token"; stobj[6].ulValueLen = strlen(stobj[6].pValue); ck_rv = epv->C_CreateObject(h, tobj, 7, &hTIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object token: handle = %lu\n", hTIn); ck_rv = epv->C_CreateObject(h, tsobj, 7, &hTSIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object token->session: handle = %lu\n", hTSIn); ck_rv = epv->C_CreateObject(h, stobj, 7, &hSTIn); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created object session->token: handle = %lu\n", hSTIn); /* I've created two token objects and one session object; find the two */ mask[0].type = CKA_APPLICATION; mask[0].pValue = key; mask[0].ulValueLen = key_len; mask[1].type = CKA_TOKEN; mask[1].pValue = &true; mask[1].ulValueLen = sizeof(CK_BBOOL); ck_rv = epv->C_FindObjectsInit(h, mask, 2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", h, ck_rv); return 1; } (void)memset(&found, 0, sizeof(found)); nFound = 0; ck_rv = epv->C_FindObjects(h, found, 10, &nFound); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 2 != nFound ) { PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); return 1; } PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", found[0], found[1]); ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } /* Convert a token to session object */ delta[0].type = CKA_TOKEN; delta[0].pValue = &false; delta[0].ulValueLen = sizeof(CK_BBOOL); ck_rv = epv->C_SetAttributeValue(h, hTSIn, delta, 1); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", h, hTSIn, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Changed object from token to session (handle = %lu).\n", hTSIn); /* Now find again; there should be one */ mask[0].type = CKA_APPLICATION; mask[0].pValue = key; mask[0].ulValueLen = key_len; mask[1].type = CKA_TOKEN; mask[1].pValue = &true; mask[1].ulValueLen = sizeof(CK_BBOOL); ck_rv = epv->C_FindObjectsInit(h, mask, 2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", h, ck_rv); return 1; } (void)memset(&found, 0, sizeof(found)); nFound = 0; ck_rv = epv->C_FindObjects(h, found, 10, &nFound); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 1 != nFound ) { PR_fprintf(PR_STDERR, "Found %lu objects, not 1.\n", nFound); return 1; } PR_fprintf(PR_STDOUT, " Found 1 objects: %lu\n", found[0]); ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } /* Convert a session to a token object */ delta[0].type = CKA_TOKEN; delta[0].pValue = &true; delta[0].ulValueLen = sizeof(CK_BBOOL); ck_rv = epv->C_SetAttributeValue(h, hSTIn, delta, 1); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", h, hSTIn, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Changed object from session to token (handle = %lu).\n", hSTIn); /* Now find again; there should be two again */ mask[0].type = CKA_APPLICATION; mask[0].pValue = key; mask[0].ulValueLen = key_len; mask[1].type = CKA_TOKEN; mask[1].pValue = &true; mask[1].ulValueLen = sizeof(CK_BBOOL); ck_rv = epv->C_FindObjectsInit(h, mask, 2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", h, ck_rv); return 1; } (void)memset(&found, 0, sizeof(found)); nFound = 0; ck_rv = epv->C_FindObjects(h, found, 10, &nFound); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 2 != nFound ) { PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); return 1; } PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", found[0], found[1]); ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } /* Delete the two (found) token objects to clean up */ ck_rv = epv->C_DestroyObject(h, found[0]); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[0], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Destroyed token object (handle = %lu)\n", found[0]); ck_rv = epv->C_DestroyObject(h, found[1]); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[1], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Destroyed token object (handle = %lu)\n", found[1]); /* Close the session and all objects should be gone */ ck_rv = epv->C_CloseSession(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv); return 1; } } /* if( tinfo.flags & CKF_WRITE_PROTECTED ) */ if( tinfo.flags & CKF_WRITE_PROTECTED ) { PR_fprintf(PR_STDOUT, "Token is write protected, skipping leaving a record.\n"); } else { CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; CK_ATTRIBUTE record[7], mask[2]; CK_OBJECT_CLASS cko_data = CKO_DATA; CK_BBOOL false = CK_FALSE, true = CK_TRUE; char *key = "TEST RECORD"; CK_ULONG key_len = strlen(key); CK_OBJECT_HANDLE hin = (CK_OBJECT_HANDLE)0; char timebuffer[256]; ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); /* I can't believe how hard NSPR makes this operation */ { time_t now = 0; struct tm *tm; time(&now); tm = localtime(&now); strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %T %Z", tm); } record[0].type = CKA_CLASS; record[0].pValue = &cko_data; record[0].ulValueLen = sizeof(CK_OBJECT_CLASS); record[1].type = CKA_TOKEN; record[1].pValue = &true; record[1].ulValueLen = sizeof(CK_BBOOL); record[2].type = CKA_PRIVATE; record[2].pValue = &false; record[2].ulValueLen = sizeof(CK_BBOOL); record[3].type = CKA_MODIFIABLE; record[3].pValue = &true; record[3].ulValueLen = sizeof(CK_BBOOL); record[4].type = CKA_LABEL; record[4].pValue = "Test record"; record[4].ulValueLen = strlen(record[4].pValue); record[5].type = CKA_APPLICATION; record[5].pValue = key; record[5].ulValueLen = key_len; record[6].type = CKA_VALUE; record[6].pValue = timebuffer; record[6].ulValueLen = strlen(timebuffer)+1; PR_fprintf(PR_STDOUT, " Timestamping with \"%s\"\n", timebuffer); ck_rv = epv->C_CreateObject(h, record, 7, &hin); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); return 1; } PR_fprintf(PR_STDOUT, " Created record object: handle = %lu\n", hin); PR_fprintf(PR_STDOUT, " == All test timestamps ==\n"); mask[0].type = CKA_CLASS; mask[0].pValue = &cko_data; mask[0].ulValueLen = sizeof(CK_OBJECT_CLASS); mask[1].type = CKA_APPLICATION; mask[1].pValue = key; mask[1].ulValueLen = key_len; ck_rv = epv->C_FindObjectsInit(h, mask, 2); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", h, ck_rv); return 1; } while( 1 ) { CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0; CK_ULONG nObjects = 0; CK_ATTRIBUTE value[1]; char buffer[1024]; ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv); return 1; } if( 0 == nObjects ) { PR_fprintf(PR_STDOUT, "\n"); break; } value[0].type = CKA_VALUE; value[0].pValue = buffer; value[0].ulValueLen = sizeof(buffer); ck_rv = epv->C_GetAttributeValue(h, o, value, 1); switch( ck_rv ) { case CKR_OK: PR_fprintf(PR_STDOUT, " %s\n", value[0].pValue); break; case CKR_ATTRIBUTE_SENSITIVE: PR_fprintf(PR_STDOUT, " [Sensitive???]\n"); break; case CKR_ATTRIBUTE_TYPE_INVALID: PR_fprintf(PR_STDOUT, " [Invalid attribute???]\n"); break; case CKR_BUFFER_TOO_SMALL: PR_fprintf(PR_STDOUT, " (result > 1k (%lu))\n", value[0].ulValueLen); break; default: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, CKA_VALUE, 1) returned 0x%08x\n", h, o); return 1; } } /* while */ ck_rv = epv->C_FindObjectsFinal(h); if( CKR_OK != ck_rv ) { PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); return 1; } } /* "leaving a record" else clause */ } PR_fprintf(PR_STDOUT, "\n"); } return 0; }