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; char message[1024]; int remainingTries = 0; CK_RV loginResult = CKR_FUNCTION_CANCELED; LOG_LOCATION; if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE; remainingTries = EstEID_getRemainingTries(slotID); EstEID_log("EstEID_getRemainingTries(slotID) = %i", remainingTries); if (remainingTries == -1) CLOSE_SESSION_AND_RETURN(FAILURE); if (!remainingTries) { sprintf_s(EstEID_error, ESTEID_ERROR_SIZE, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED); CLOSE_SESSION_AND_RETURN(FAILURE); } if (remainingTries < 3) { sprintf_s(message, 1024, "%s %i", l10n("Tries left:"), remainingTries); } else { message[0] = 0; } 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_s(EstEID_error, 1024, "C_Login error: %s (%li)", pkcs11_error_message(loginResult), loginResult); CLOSE_SESSION_AND_RETURN(loginResult); } return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, NULL); }
CK_RV pkcs11_login_session(CK_FUNCTION_LIST_PTR funcs, FILE *out, CK_SLOT_ID slot, CK_SESSION_HANDLE_PTR session, CK_BBOOL readwrite, CK_USER_TYPE user, CK_UTF8CHAR_PTR pin, CK_ULONG pinLen) { CK_SESSION_HANDLE h_session; CK_FLAGS flags = CKF_SERIAL_SESSION | (readwrite ? CKF_RW_SESSION : 0); CK_RV rc; rc = funcs->C_OpenSession(slot, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { if(out) { show_error(stdout, "C_OpenSession", rc); } return rc; } if(pin) { rc = funcs->C_Login(h_session, user, pin, pinLen); if (rc != CKR_OK) { if(out) { show_error(out, "C_Login", rc); } goto end; } } else if(readwrite || pinLen > 0) { CK_TOKEN_INFO info; rc = funcs->C_GetTokenInfo(slot, &info); if (rc != CKR_OK) { if(out) { show_error(out, "C_GetTokenInfo", rc); } goto end; } if(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) { rc = funcs->C_Login(h_session, user, NULL, 0); if (rc != CKR_OK) { if(out) { show_error(out, "C_Login", rc); } goto end; } } } end: if (rc != CKR_OK) { /* We want to keep the original error code */ CK_RV r = funcs->C_CloseSession(h_session); if ((r != CKR_OK) && out) { show_error(out, "C_CloseSession", r); } } else if(session) { *session = h_session; } return rc; }
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"); }
// 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; }
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 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); }
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; }
void processRequest(int client) { DataMarshalling *d = NULL; while (1) { d = new DataMarshalling(client); d->recvData(); if (!strcmp(d->getMsgType(), "C_Initialize")) { int p = 0; printf("Processing: C_Initialize\n"); p = d->unpackInt(); if (p == 0) pFunctionList->C_Initialize(NULL); else { printf("ERROR: C_Initialize shouldn't be called with not NULL\n"); } } else if (!strcmp(d->getMsgType(), "C_Finalize")) { int p = 0; CK_RV ret = 0; printf("Processing: C_Finalize\n"); p = d->unpackInt(); if (p == NULL) { ret = pFunctionList->C_Finalize(NULL); } else { printf("ERROR: C_Finalize shouldn't be called with not NULL\n"); ret = CKR_CANCEL; } { CK_ULONG count = 0; DataMarshalling *d2 = new DataMarshalling(client); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } break; } else if (!strcmp(d->getMsgType(), "C_GetSlotList")) { int p = 0; printf("Processing: C_GetSlotList\n"); p = d->unpackInt(); if (p == 0) { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ ret = pFunctionList->C_GetSlotList(TRUE, NULL, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); d2->sendData(); delete d2; } else { CK_ULONG count = 0; CK_SLOT_ID_PTR slot = NULL; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ pFunctionList->C_GetSlotList(TRUE, NULL, &count); slot = new(CK_SLOT_ID[count]); ret = pFunctionList->C_GetSlotList(TRUE, slot, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); for (int i = 0; i < count; i ++) d2->packInt((char *)&slot[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_OpenSession")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_OpenSession\n"); slotId = d->unpackInt(); flags = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_OpenSession(slotId, flags, NULL, NULL, &sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&sessionId); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_CloseSession")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_CloseSession\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_CloseSession(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; CK_INFO info; printf("Processing: C_GetInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_TOKEN_INFO token; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetInfo(&info); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packChar(info.cryptokiVersion.major); d2->packChar(info.cryptokiVersion.minor); d2->packMem((char *)info.manufacturerID, 32); d2->packInt((char *)&info.flags); d2->packMem((char *)info.libraryDescription, 32); d2->packChar(info.libraryVersion.major); d2->packChar(info.libraryVersion.minor); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetSlotInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetSlotInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_SLOT_INFO slot; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetSlotInfo(slotId, &slot); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packMem((char *)slot.slotDescription, 64); d2->packMem((char *)slot.manufacturerID, 32); d2->packInt((char *)&slot.flags); d2->packChar(slot.hardwareVersion.major); d2->packChar(slot.hardwareVersion.minor); d2->packChar(slot.firmwareVersion.major); d2->packChar(slot.firmwareVersion.minor); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetTokenInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetTokenInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_TOKEN_INFO token; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetTokenInfo(slotId, &token); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packMem((char *)token.label, 32); d2->packMem((char *)token.manufacturerID, 32); d2->packMem((char *)token.model, 16); d2->packMem((char *)token.serialNumber, 16); d2->packInt((char *)&token.flags); d2->packInt((char *)&token.ulMaxSessionCount); d2->packInt((char *)&token.ulSessionCount); d2->packInt((char *)&token.ulMaxRwSessionCount); d2->packInt((char *)&token.ulRwSessionCount); d2->packInt((char *)&token.ulMaxPinLen); d2->packInt((char *)&token.ulMinPinLen); d2->packInt((char *)&token.ulTotalPublicMemory); d2->packInt((char *)&token.ulFreePublicMemory); d2->packInt((char *)&token.ulTotalPrivateMemory); d2->packInt((char *)&token.ulFreePrivateMemory); d2->packChar(token.hardwareVersion.major); d2->packChar(token.hardwareVersion.minor); d2->packChar(token.firmwareVersion.major); d2->packChar(token.firmwareVersion.minor); d2->packMem((char *)token.utcTime, 16); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetMechanismList")) { unsigned int slotId = 0; CK_MECHANISM_TYPE_PTR pMechanismList = NULL; printf("Processing: C_GetMechanismList\n"); slotId = d->unpackInt(); pMechanismList = (CK_MECHANISM_TYPE_PTR)d->unpackInt(); if (pMechanismList == NULL) { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); printf("C_GetMechanismList count: %d\n", count); d2->sendData(); delete d2; } else { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ pFunctionList->C_GetMechanismList(TRUE, NULL, &count); pMechanismList = new(CK_MECHANISM_TYPE[count]); ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); printf("C_GetMechanismList count: %d\n", count); for (int i = 0; i < count; i ++) d2->packInt((char *)&pMechanismList[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetMechanismInfo")) { unsigned int slotId = 0, mechanismType = 0; printf("Processing: C_GetMechanismInfo\n"); slotId = d->unpackInt(); mechanismType = d->unpackInt(); { CK_RV ret = 0; CK_MECHANISM_INFO mechanism; DataMarshalling *d2 = new DataMarshalling(client); ret = pFunctionList->C_GetMechanismInfo(slotId, mechanismType, &mechanism); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&mechanism.ulMinKeySize); d2->packInt((char *)&mechanism.ulMaxKeySize); d2->packInt((char *)&mechanism.flags); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Login")) { CK_SESSION_HANDLE sessionId = 0; unsigned int user = 0, len = 0; CK_CHAR_PTR pin = NULL; printf("Processing: C_Login\n"); sessionId = d->unpackInt(); user = d->unpackInt(); len = d->unpackInt(); pin = (CK_CHAR_PTR) calloc(1, len + 1); if (!pin) { printf("ERROR: NO MEMORY\n"); break; } d->unpackMem((char *)pin, len); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Login(sessionId, user, pin, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Logout")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_Logout\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Logout(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjectsInit")) { CK_SESSION_HANDLE sessionId = 0; unsigned int len = 0; CK_ATTRIBUTE_PTR attr = NULL; printf("Processing: C_FindObjectsInit\n"); sessionId = d->unpackInt(); len = d->unpackInt(); attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE)); if (!attr) { printf("ERROR: NO MEMORY\n"); break; } for (int i = 0; i < len; i ++) { attr[i].type = d->unpackInt(); attr[i].ulValueLen = d->unpackInt(); attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen); d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjectsInit(sessionId, attr, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjects")) { CK_SESSION_HANDLE sessionId = 0; CK_OBJECT_HANDLE_PTR phObject = NULL; CK_ULONG len = 0, maxlen = 0; printf("Processing: C_FindObjects\n"); sessionId = d->unpackInt(); maxlen = d->unpackInt(); if (maxlen > 0) { phObject = new(CK_OBJECT_HANDLE[maxlen]); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjects(sessionId, phObject, maxlen, &len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&len); for (int i = 0; i < len && i < maxlen; i ++) d2->packInt((char *)&phObject[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetAttributeValue")) { CK_SESSION_HANDLE sessionId = 0; CK_OBJECT_HANDLE hObject = 0; CK_ULONG len = 0; CK_ATTRIBUTE_PTR attr = NULL; printf("Processing: C_GetAttributeValue\n"); sessionId = d->unpackInt(); hObject = d->unpackInt(); len = d->unpackInt(); attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE)); if (!attr) { printf("ERROR: NO MEM C_GetAttributeValue\n"); break; } for (int i = 0; i < len; i ++) { attr[i].type = d->unpackInt(); attr[i].ulValueLen = d->unpackInt(); attr[i].pValue = (char *)d->unpackInt(); if (attr[i].pValue != NULL) { attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen); if (!attr[i].pValue) { printf("ERROR: NO MEM\n"); exit(-1); } //d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen); } } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); ret = pFunctionList->C_GetAttributeValue(sessionId, hObject, attr, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); for (int i = 0; i < len; i ++) { d2->packInt((char *)&attr[i].type); d2->packInt((char *)&attr[i].ulValueLen); d2->packInt((char *)&attr[i].pValue); if (attr[i].pValue != NULL) { d2->packMem((char *)attr[i].pValue, attr[i].ulValueLen); #ifdef FUNC_DEBUG_ if (i == 2) { PCCERT_CONTEXT pCertContext; pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,((BYTE *)attr[i].pValue),attr[i].ulValueLen); printf("data len: %d\n", attr[i].ulValueLen); printf("issuer len: %d\n", pCertContext->pCertInfo->Issuer.cbData); std::wcout << byte2str(pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Issuer.cbData); CertFreeCertificateContext(pCertContext); } #endif } } d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjectsFinal")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_FindObjectsFinal\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjectsFinal(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_SignInit")) { CK_SESSION_HANDLE sessionId = 0; CK_MECHANISM mechanism; CK_OBJECT_HANDLE hKey; printf("Processing: C_SignInit\n"); sessionId = d->unpackInt(); hKey = d->unpackInt(); mechanism.mechanism = d->unpackInt(); mechanism.ulParameterLen = d->unpackInt(); mechanism.pParameter = NULL; { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_SignInit(sessionId, &mechanism, hKey); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Sign")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL, *signature = NULL; CK_ULONG dataLen = 0, signatureLen = 0; printf("Processing: C_Sign\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_Sign\n"); break; } d->unpackMem((char *)data, dataLen); } signatureLen = d->unpackInt(); signature = (char *)d->unpackInt(); if (signature != NULL) { signature = (char *)calloc(1, signatureLen); if (!signature) { printf("ERROR: NO MEM C_Sign\n"); break; } d->unpackMem((char *)signature, signatureLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Sign(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, &signatureLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&signatureLen); if (signature != NULL) d2->packMem((char *)signature, signatureLen); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_VerifyInit")) { CK_SESSION_HANDLE sessionId = 0; CK_MECHANISM mechanism; CK_OBJECT_HANDLE hKey; printf("Processing: C_VerifyInit\n"); sessionId = d->unpackInt(); hKey = d->unpackInt(); mechanism.mechanism = d->unpackInt(); mechanism.ulParameterLen = d->unpackInt(); mechanism.pParameter = NULL; { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_VerifyInit(sessionId, &mechanism, hKey); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Verify")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL, *signature = NULL; CK_ULONG dataLen = 0, signatureLen = 0; printf("Processing: C_Verify\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_Verify\n"); break; } d->unpackMem((char *)data, dataLen); } signatureLen = d->unpackInt(); signature = (char *)d->unpackInt(); if (signature != NULL) { signature = (char *)calloc(1, signatureLen); if (!signature) { printf("ERROR: NO MEM C_Verify\n"); break; } d->unpackMem((char *)signature, signatureLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Verify(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, signatureLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GenerateRandom")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL; CK_ULONG dataLen = 0; printf("Processing: C_GenerateRandom\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_GenerateRandom\n"); break; } //d->unpackMem((char *)data, dataLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GenerateRandom(sessionId, (CK_BYTE_PTR)data, dataLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); if (data != NULL) d2->packMem((char *)data, dataLen); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_SeedRandom")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL; CK_ULONG dataLen = 0; printf("Processing: C_SeedRandom\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_SeedRandom\n"); break; } d->unpackMem((char *)data, dataLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_SeedRandom(sessionId, (CK_BYTE_PTR)data, dataLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetSessionInfo")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetSessionInfo\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; CK_SESSION_INFO info; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetSessionInfo(sessionId, &info); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&info.slotID); d2->packInt((char *)&info.state); d2->packInt((char *)&info.flags); d2->packInt((char *)&info.ulDeviceError); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_CloseAllSessions")) { CK_SLOT_ID slotID = 0; printf("Processing: C_Logout\n"); slotID = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_CloseAllSessions(slotID); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else { pFunctionList->C_Finalize(NULL); } delete d; } }
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; if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE; const char *givenName = EstEID_mapGet(cert, "givenName"); if (!givenName) givenName = ""; const char *surname = EstEID_mapGet(cert, "surname"); if (!surname) surname = ""; const char *personalID = EstEID_mapGet(cert, "serialNumber"); if (!personalID) personalID = ""; char *name = (char *)malloc(strlen(givenName) + strlen(surname) + strlen(personalID) + 4); sprintf(name, "%s %s", givenName, surname); if(strlen(personalID)) { strcat(name, ", "); strcat(name, personalID); } for (int attempt = 0, blocked = FALSE;; attempt++) { char message[1024]; int remainingTries = EstEID_getRemainingTries(slotID); if (remainingTries == -1) CLOSE_SESSION_AND_FAIL; 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, cannot sign!")); CLOSE_SESSION_AND_FAIL; } 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_FAIL; } 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_FAIL; } } 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_FAIL; } break; // Login successful - correct PIN supplied } if (name){ free(name); name = NULL; } 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_FAIL; CK_OBJECT_HANDLE privateKeyHandle; CK_ULONG objectCount; if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &privateKeyHandle, 1, &objectCount))) CLOSE_SESSION_AND_FAIL; if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_FAIL; if (objectCount == 0) CLOSE_SESSION_AND_FAIL; // todo ?? set error message CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0}; if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle))) CLOSE_SESSION_AND_FAIL; unsigned int hashWithPaddingLength; char *hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength); 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_FAIL; } *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_FAIL; } *signatureLength = len; free(hashWithPadding); if (session) { if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) { return FAILURE; } } EstEID_log("successfully signed"); return SUCCESS; }
int testStability(CK_SLOT_ID slotID, CK_SESSION_HANDLE hSession, int rollovers, int batchjobs, int signatures, int sleepTime) { CK_RV rv; int retVal = 0; CK_OBJECT_HANDLE hPublicKey, hPrivateKey; CK_SESSION_HANDLE hSessionTmp; CK_BYTE_PTR pSignature = NULL; CK_ULONG ulSignatureLen = 0; CK_BYTE pData[] = {"Text"}; CK_ULONG ulDataLen = sizeof(pData)-1; printf("\n********************************************************\n"); printf("* Test for stability during key generation and signing *\n"); printf("********************************************************\n\n"); printf("This test will perform the following:\n\n"); printf("* Key rollovers = %i\n", rollovers); printf(" The number of times that the key pair will be replaced.\n"); printf("* Batchjobs = %i\n", batchjobs); printf(" The number of batchjobs for each key pair.\n"); printf("* signatures = %i\n", signatures); printf(" Each batchjob will create signatures and verify them.\n"); printf("* sleep time = %i\n", sleepTime); printf(" The process will sleep between the batchjobs.\n\n"); for (int i = 0; i <= rollovers; i++) { // Generate key pair if (testStability_generate(hSession, &hPublicKey, &hPrivateKey)) { retVal = 1; continue; } for (int j = 0; j < batchjobs; j++) { // Open Session rv = p11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionTmp); if (rv != CKR_OK) { printf("ERROR: Failed to open a session. rv=%s\n", rv2string(rv)); retVal = 1; continue; } printf("Creating signatures and verifying them...\n"); for (int k = 0; k < signatures; k++) { // Sign data if (testStability_sign( hSessionTmp, hPrivateKey, pData, ulDataLen, &pSignature, &ulSignatureLen)) { retVal = 1; continue; } // Verify signature if (testStability_verify( hSessionTmp, hPublicKey, pData, ulDataLen, pSignature, ulSignatureLen)) { retVal = 1; } // Clean up if (pSignature != NULL) { free(pSignature); pSignature = NULL; ulSignatureLen = 0; } } // Close session rv = p11->C_CloseSession(hSessionTmp); if (rv != CKR_OK) { printf("ERROR: Failed to close session. rv=%s\n", rv2string(rv)); retVal = 1; } // Sleep printf("Sleeping for %i seconds...\n", sleepTime); sleep(sleepTime); } // Delete key pair printf("Deleting the key pair...\n"); rv = p11->C_DestroyObject(hSession, hPublicKey); if (rv != CKR_OK) { printf("ERROR: Failed to delete the public key. rv=%s\n", rv2string(rv)); retVal = 1; } rv = p11->C_DestroyObject(hSession, hPrivateKey); if (rv != CKR_OK) { printf("ERROR: Failed to delete the private key. rv=%s\n", rv2string(rv)); retVal = 1; } } if (retVal == 0) { printf("\nThe test was performed successfully.\n"); } else { printf("\nThe test was not performed successfully.\n"); } return retVal; }
CK_SESSION_HANDLE sc_get_session(void *f, int try_write_syslog, CK_FUNCTION_LIST_PTR fl, const char *token_label) { #define SC_MAX_SLOT 16 CK_SESSION_HANDLE session = 0; unsigned long slot_count = SC_MAX_SLOT; CK_TOKEN_INFO token_info; CK_SLOT_ID slots[SC_MAX_SLOT]; CK_SLOT_ID c_slot = SC_MAX_SLOT; CK_SLOT_ID slot = SC_MAX_SLOT; CK_RV rv = 0; int i; char msg[SC_STR_MAX_LEN] = ""; if(fl == 0) { sprintf(msg, "sc: Invalid state, no function list"); goto err; } rv = fl->C_GetSlotList(TRUE, slots, &slot_count); if(CKR_OK != rv) { sprintf(msg, "sc: C_GetSlotList failed 0x%.4x", (int)rv); goto err; } if(slot_count < 1) { sprintf(msg, "sc: No token available"); goto err; } for(i=0; i<slot_count; i++) { slot = slots[i]; rv = fl->C_GetTokenInfo(slot,&token_info); if (CKR_OK != rv) { sprintf(msg, "sc: C_GetTokenInfo failed for token in slot %i", i); goto err; } { char buf[40]; memset(buf, 0, 40); int j; strncpy(buf, token_info.label, 30); for(j=29;j>0;j--) { if(buf[j] == ' ') { buf[j] = '\0'; } else { break; } } sprintf(msg, "sc: Found token in slot %i: %s", i, buf); if(f) { logevent(f, msg); if(try_write_syslog) sc_write_syslog(msg); } } if(strncmp(token_label, token_info.label, strlen(token_label)) == 0) { c_slot = i; break; } } if(c_slot == 64) { sprintf(msg, "sc: No token named: %s", token_label); goto err; } rv = fl->C_OpenSession(slots[c_slot],CKF_SERIAL_SESSION|CKF_RW_SESSION, 0, 0, &session); if (CKR_OK != rv) { sprintf(msg, "sc: C_OpenSession failed"); goto err; } else { if(f) logevent(f, "sc: Session opened"); } return session; err: if(f) { logevent(f, msg); if(try_write_syslog) sc_write_syslog(msg); } // m_fl->C_Finalize(0); // m_fl = 0; return 0; }
int EstEID_loadCertInfoEntries(EstEID_Certs *certs, int index) { EstEID_Map cert = certs->certs[index]; CK_SLOT_ID slotID = certs->slotIDs[index]; CK_SESSION_HANDLE session; FAIL_IF(EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))); CK_OBJECT_CLASS objectClass = CKO_CERTIFICATE; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) return FAILURE; CK_OBJECT_HANDLE objectHandle; CK_ULONG objectCount; if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &objectHandle, 1, &objectCount))) return FAILURE; if (objectCount == 0) return SUCCESS; CK_ATTRIBUTE attribute = {CKA_VALUE, NULL_PTR, 0}; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; CK_ULONG certificateLength = attribute.ulValueLen; CK_BYTE_PTR certificate = (CK_BYTE_PTR)malloc(certificateLength); attribute.pValue = certificate; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; EstEID_mapPutNoAlloc(cert, strdup("certificateAsHex"), EstEID_bin2hex((char *)certificate, certificateLength)); const unsigned char *p = certificate; X509 *x509 = d2i_X509(NULL, &p, certificateLength); char *certMD5; certMD5 = EstEID_getCertHash((char*)certificate); FAIL_IF(EstEID_md5_failure(certMD5)); EstEID_mapPutNoAlloc(cert, strdup("certHash"), certMD5); free(certificate); // todo: error handling of all openssl functions EstEID_mapPutNoAlloc(cert, strdup("validTo"), EstEID_ASN1_TIME_toString(X509_get_notAfter(x509))); EstEID_mapPutNoAlloc(cert, strdup("validFrom"), EstEID_ASN1_TIME_toString(X509_get_notBefore(x509))); unsigned long keyUsage; ASN1_BIT_STRING *usage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL); if (usage->length > 0) keyUsage = usage->data[0]; ASN1_BIT_STRING_free(usage); if (keyUsage & X509v3_KU_DIGITAL_SIGNATURE) EstEID_mapPut(cert, "usageDigitalSignature", "TRUE"); if (keyUsage & X509v3_KU_NON_REPUDIATION) { EstEID_mapPut(cert, "usageNonRepudiation", "TRUE"); EstEID_mapPut(cert, "keyUsage", "Non-Repudiation"); // for compatibility with older plugin } EstEID_loadCertEntries(cert, "", X509_get_subject_name(x509)); char *certSerialNumber = (char*)malloc(33); snprintf(certSerialNumber, 32, "%lX", ASN1_INTEGER_get(X509_get_serialNumber(x509))); EstEID_mapPutNoAlloc(cert, strdup("certSerialNumber"), certSerialNumber); EstEID_loadCertEntries(cert, "issuer.", X509_get_issuer_name(x509)); BIO *bio = BIO_new(BIO_s_mem()); if (!PEM_write_bio_X509(bio, x509)) printf("Cannot create PEM\n"); char *b; int len = BIO_get_mem_data(bio, &b); char *pem = (char *)malloc(len + 1); strncpy(pem, b, len); pem[len] = 0; BIO_free(bio); EstEID_mapPutNoAlloc(cert, strdup("certificateAsPEM"), pem); FAIL_IF(EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))); return SUCCESS; }
// Import a newly generated RSA1024 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10_RSA() { EVP_PKEY *evp; RSA *rsak; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_BYTE e[] = {0x01, 0x00, 0x01}; CK_BYTE p[64]; CK_BYTE q[64]; CK_BYTE dp[64]; CK_BYTE dq[64]; CK_BYTE qinv[64]; BIGNUM *e_bn; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_RSA; CK_BYTE id = 0; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *px; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_PUBLIC_EXPONENT, e, sizeof(e)}, {CKA_PRIME_1, p, sizeof(p)}, {CKA_PRIME_2, q, sizeof(q)}, {CKA_EXPONENT_1, dp, sizeof(dp)}, {CKA_EXPONENT_2, dq, sizeof(dq)}, {CKA_COEFFICIENT, qinv, sizeof(qinv)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_RSA_PKCS, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); rsak = RSA_new(); if (rsak == NULL) exit(EXIT_FAILURE); e_bn = BN_bin2bn(e, 3, NULL); if (e_bn == NULL) exit(EXIT_FAILURE); asrt(RSA_generate_key_ex(rsak, 1024, e_bn, NULL), 1, "GENERATE RSAK"); asrt(BN_bn2bin(rsak->p, p), 64, "GET P"); asrt(BN_bn2bin(rsak->q, q), 64, "GET Q"); asrt(BN_bn2bin(rsak->dmp1, dp), 64, "GET DP"); asrt(BN_bn2bin(rsak->dmq1, dp), 64, "GET DQ"); asrt(BN_bn2bin(rsak->iqmp, qinv), 64, "GET QINV"); if (EVP_PKEY_set1_RSA(evp, rsak) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); px = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; 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_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); /* r_len = 32; */ /* s_len = 32; */ /* der_ptr = der_encoded; */ /* *der_ptr++ = 0x30; */ /* *der_ptr++ = 0xff; // placeholder, fix below */ /* r_ptr = sig; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = r_len; */ /* if (*r_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { */ /* r_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* r_ptr++; */ /* } */ /* memcpy(der_ptr, r_ptr, r_len); */ /* der_ptr+= r_len; */ /* s_ptr = sig + 32; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = s_len; */ /* if (*s_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { */ /* s_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* s_ptr++; */ /* } */ /* memcpy(der_ptr, s_ptr, s_len); */ /* der_ptr+= s_len; */ /* der_encoded[1] = der_ptr - der_encoded - 2; */ /* dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); */ /* asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); */ } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
// Import a newly generated P256 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10() { EVP_PKEY *evp; EC_KEY *eck; const EC_POINT *ecp; const BIGNUM *bn; char pvt[32]; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_ECDSA; CK_BYTE id = 0; CK_BYTE params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *p; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_EC_PARAMS, ¶ms, sizeof(params)}, {CKA_VALUE, pvt, sizeof(pvt)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_ECDSA, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (eck == NULL) exit(EXIT_FAILURE); asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK"); bn = EC_KEY_get0_private_key(eck); asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT"); if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); p = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; 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_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); r_len = 32; s_len = 32; der_ptr = der_encoded; *der_ptr++ = 0x30; *der_ptr++ = 0xff; // placeholder, fix below r_ptr = sig; *der_ptr++ = 0x02; *der_ptr++ = r_len; if (*r_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { r_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; r_ptr++; } memcpy(der_ptr, r_ptr, r_len); der_ptr+= r_len; s_ptr = sig + 32; *der_ptr++ = 0x02; *der_ptr++ = s_len; if (*s_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { s_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; s_ptr++; } memcpy(der_ptr, s_ptr, s_len); der_ptr+= s_len; der_encoded[1] = der_ptr - der_encoded - 2; dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }