int EstEID_isPinPad(CK_SLOT_ID slotID) { CK_TOKEN_INFO tokenInfo; if (EstEID_CK_failure("C_GetTokenInfo", fl->C_GetTokenInfo(slotID, &tokenInfo))) return 0; EstEID_log("flags: %li (%lx)", tokenInfo.flags, tokenInfo.flags); if (tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) return 1; else return 0; }
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; }
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; }
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; }
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"); }
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; } }
CK_RV WaitForCardEvent(HWND hTextEdit, CK_FUNCTION_LIST_PTR functions, DWORD *pAutoFlags) { CK_RV retVal = CKR_OK; CK_FLAGS flags = 0; CK_SLOT_ID slotID; CK_SLOT_INFO slotInfo; CK_TOKEN_INFO tokenInfo; CK_ULONG ulPreviousCount = 0; CK_ULONG ulCount = 0; CK_ULONG ulCounter = 0; CK_SLOT_ID_PTR pSlotList; CK_ULONG_PTR pCardPresentList; //CK_BYTE_PTR pserialNumberList; //CK_ULONG_PTR pserialNumberLenList; //CK_ULONG certContextLen = 5; PCCERT_CONTEXT** pCertContextArray; retVal = functions->C_GetSlotList(FALSE, NULL_PTR, &ulCount); ulPreviousCount = ulCount; pSlotList = (CK_SLOT_ID_PTR) malloc(ulCount*sizeof(CK_SLOT_ID)); pCardPresentList = (CK_ULONG_PTR)malloc(ulCount*sizeof(CK_SLOT_ID)); //pserialNumberList = (CK_BYTE*)malloc(ulCount*sizeof(CK_BYTE)); //memset(pserialNumberList,0,ulCount*sizeof(CK_BYTE)); //pserialNumberLenList = (CK_ULONG*)malloc(ulCount*sizeof(CK_ULONG)); //allocate space for the array of certificate pointers per slot pCertContextArray = malloc(ulCount*sizeof(PCCERT_CONTEXT*)); //initialize with zero's memset(pCertContextArray,0,ulCount*sizeof(PCCERT_CONTEXT*)); if((pSlotList != NULL) &&(pCardPresentList != NULL) &&(pCertContextArray != NULL)) { //retVal = functions->C_GetSlotList(FALSE, NULL_PTR, &ulCount); //if(retVal != CKR_OK){} if ((retVal == CKR_OK) && (ulCount > 0)) { SendMessage(hTextEdit, EM_REPLACESEL, 0, (LPARAM)"Readers found: \r\n"); retVal = functions->C_GetSlotList(FALSE, pSlotList, &ulCount); if(retVal != CKR_OK){} //ulCount readers found, now fill in the certificate context array, //and register all certificates found while(ulCounter < ulCount) { /* Get slot information*/ retVal = functions->C_GetSlotInfo(pSlotList[ulCounter], &slotInfo); if(retVal != CKR_OK){} else { slotInfo.slotDescription[63] = 0; //do not display the PnP slot if(strncmp(slotInfo.slotDescription,"\\\\?PnP?\\Notification",20) != 0) { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"- "); SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)slotInfo.slotDescription); //SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"\r\n"); /* Get token information*/ retVal = functions->C_GetTokenInfo(pSlotList[ulCounter], &tokenInfo); if (retVal == CKR_TOKEN_NOT_PRESENT) { pCardPresentList[ulCounter] = 0; SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)" No Card Found \r\n"); } else if (retVal==CKR_OK) { pCardPresentList[ulCounter] = 1; tokenInfo.label[31]=0; SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)" Card Found: "); SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)tokenInfo.label); SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"\r\n"); //allocate space for 5 certificate context pointers pCertContextArray[ulCounter] = malloc (5*sizeof(PCCERT_CONTEXT)); memset(pCertContextArray[ulCounter],0,5*sizeof(PCCERT_CONTEXT)); if(pCertContextArray[ulCounter] != NULL) { memset(pCertContextArray[ulCounter],0,5*sizeof(PCCERT_CONTEXT)); if(*pAutoFlags & AUTO_REGISTER) retVal = HandleNewCardFound(hTextEdit, functions, ulCounter, pSlotList,pCertContextArray[ulCounter], 5); } else { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"ERROR: Out of memory\r\n"); } } } } ulCounter++; }//end of while } //as long as the readercount didn't change; keep the current slotlist //TODO: match the entire slotList, not just checking its size while(ulCount == ulPreviousCount) { /* Block and wait for a slot event */ retVal = functions->C_WaitForSlotEvent(flags, &slotID, NULL_PTR); if(retVal != CKR_OK) { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"WARNING: C_WaitForSlotEvent returned an error \r\n"); return retVal; // printError() // char errormessage[100]; // _snprintf(errormessage,100,"C_GetAttributeValue returned 0x%0.8x\r\n",retval); // SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"\r\n"); } /* Check if we already know that slot */ retVal = functions->C_GetSlotInfo(slotID, &slotInfo); if(retVal != CKR_OK){} ulCounter = 0; while(ulCounter < ulCount) { if(pSlotList[ulCounter] == slotID) { // Get token information retVal = functions->C_GetTokenInfo(slotID, &tokenInfo); if( (retVal == CKR_TOKEN_NOT_PRESENT) && (pCardPresentList[ulCounter] == 1) ) { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"Card removed\r\n"); pCardPresentList[ulCounter] = 0; //token removed, so remove its certificates if(*pAutoFlags & AUTO_REMOVE) retVal = HandleCardRemoved(hTextEdit, functions, pCertContextArray[ulCounter], 5); //free the allocated space of the certificate context pointers if(pCertContextArray[ulCounter] != NULL) free (pCertContextArray[ulCounter]); } else { if(pCardPresentList[ulCounter] == 0) { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"Card inserted\r\n"); pCardPresentList[ulCounter] = 1; //allocate space for 5 certificate context pointers pCertContextArray[ulCounter] = malloc (5*sizeof(PCCERT_CONTEXT)); if(pCertContextArray[ulCounter] != NULL) { memset(pCertContextArray[ulCounter],0,5*sizeof(PCCERT_CONTEXT)); //token added, so add its certificates if(*pAutoFlags & AUTO_REGISTER) retVal = HandleNewCardFound(hTextEdit, functions, ulCounter, pSlotList, pCertContextArray[ulCounter], 5); } else { SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"ERROR: Out of memory\r\n"); } } } break; } ulCounter++; } if(ulCounter == ulCount) { //a new reader is detected SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"New reader detected \r\n"); // Get token information // retVal = functions->C_GetTokenInfo(slotID, &tokenInfo); // if (retVal == CKR_TOKEN_NOT_PRESENT) // { // SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)" No Card Found \r\n"); // } // else // { // SendMessage(hTextEdit, EM_REPLACESEL,0, (LPARAM)"Card Found: \r\n"); // } } retVal = functions->C_GetSlotList(FALSE, NULL_PTR, &ulCount); }// end of while if(pSlotList != NULL) free(pSlotList); if(pCardPresentList != NULL) free(pCardPresentList); if(pCertContextArray != NULL) { for(ulCounter = 0;ulCounter < ulPreviousCount;ulCounter++ ) { if(pCertContextArray[ulCounter] != NULL) { free(pCertContextArray[ulCounter]); pCertContextArray[ulCounter] = NULL; } } free(pCertContextArray); } } return retVal; }
/* * While our keystore is always the one used by the pubkey slot (which is * usually the Metaslot) we must make sure that those URI attributes that * specify the keystore match the real attributes of our slot keystore. Note * that one can use the METASLOT_OBJECTSTORE_TOKEN environment variable to * change the Metaslot's keystore from the softtoken to something else (see * libpkcs11(3LIB)). The user might want to use such attributes in the PKCS#11 * URI to make sure that the intended keystore is used. * * Returns: * 1 on success * 0 on failure */ int pk11_check_token_attrs(pkcs11_uri *uri_struct) { CK_RV rv; static CK_TOKEN_INFO_PTR token_info = NULL; (void) pthread_mutex_lock(uri_lock); if (token_info == NULL) { token_info = OPENSSL_malloc(sizeof (CK_TOKEN_INFO)); if (token_info == NULL) { PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_MALLOC_FAILURE); goto err; } rv = pFuncList->C_GetTokenInfo(pubkey_SLOTID, token_info); if (rv != CKR_OK) { PK11err_add_data(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_GETTOKENINFO, rv); goto err; } } if (uri_struct->token != NULL) if (strncmp(uri_struct->token, (char *)token_info->label, strlen(uri_struct->token) > 32 ? 32 : strlen(uri_struct->token)) != 0) { goto urierr; } if (uri_struct->manuf != NULL) if (strncmp(uri_struct->manuf, (char *)token_info->manufacturerID, strlen(uri_struct->manuf) > 32 ? 32 : strlen(uri_struct->manuf)) != 0) goto urierr; if (uri_struct->model != NULL) if (strncmp(uri_struct->model, (char *)token_info->model, strlen(uri_struct->model) > 16 ? 16 : strlen(uri_struct->model)) != 0) goto urierr; if (uri_struct->serial != NULL) if (strncmp(uri_struct->serial, (char *)token_info->serialNumber, strlen(uri_struct->serial) > 16 ? 16 : strlen(uri_struct->serial)) != 0) goto urierr; (void) pthread_mutex_unlock(uri_lock); return (1); urierr: PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_TOKEN_ATTRS_DO_NOT_MATCH); /* Correct error already set above for the "err" label. */ err: (void) pthread_mutex_unlock(uri_lock); return (0); }
int list_metaslot_info(boolean_t show_mechs, boolean_t verbose, mechlist_t *mechlist) { int rc = SUCCESS; CK_RV rv; CK_SLOT_INFO slot_info; CK_TOKEN_INFO token_info; CK_MECHANISM_TYPE_PTR pmech_list = NULL; CK_ULONG mech_count; int i; CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR); CK_FUNCTION_LIST_PTR funcs; void *dldesc = NULL; boolean_t lib_initialized = B_FALSE; uentry_t *puent; char buf[128]; /* * Display the system-wide metaslot settings as specified * in pkcs11.conf file. */ if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) { cryptoerror(LOG_STDERR, gettext("metaslot entry doesn't exist.")); return (FAILURE); } (void) printf(gettext("System-wide Meta Slot Configuration:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as long as * the length of the translated text above. */ (void) printf(gettext("------------------------------------\n")); (void) printf(gettext("Status: %s\n"), puent->flag_metaslot_enabled ? gettext("enabled") : gettext("disabled")); (void) printf(gettext("Sensitive Token Object Automatic Migrate: %s\n"), puent->flag_metaslot_auto_key_migrate ? gettext("enabled") : gettext("disabled")); bzero(buf, sizeof (buf)); if (memcmp(puent->metaslot_ks_slot, buf, SLOT_DESCRIPTION_SIZE) != 0) { (void) printf(gettext("Persistent object store slot: %s\n"), puent->metaslot_ks_slot); } if (memcmp(puent->metaslot_ks_token, buf, TOKEN_LABEL_SIZE) != 0) { (void) printf(gettext("Persistent object store token: %s\n"), puent->metaslot_ks_token); } if ((!verbose) && (!show_mechs)) { return (SUCCESS); } if (verbose) { (void) printf(gettext("\nDetailed Meta Slot Information:\n")); /* * TRANSLATION_NOTE * Strictly for appearance's sake, this line should be as * long as the length of the translated text above. */ (void) printf(gettext("-------------------------------\n")); } /* * Need to actually make calls to libpkcs11.so to get * information about metaslot. */ dldesc = dlopen(UEF_FRAME_LIB, RTLD_NOW); if (dldesc == NULL) { char *dl_error; dl_error = dlerror(); cryptodebug("Cannot load PKCS#11 framework library. " "dlerror:%s", dl_error); return (FAILURE); } /* Get the pointer to library's C_GetFunctionList() */ Tmp_C_GetFunctionList = (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList"); if (Tmp_C_GetFunctionList == NULL) { cryptodebug("Cannot get the address of the C_GetFunctionList " "from framework"); rc = FAILURE; goto finish; } /* Get the provider's function list */ rv = Tmp_C_GetFunctionList(&funcs); if (rv != CKR_OK) { cryptodebug("failed to call C_GetFunctionList in " "framework library"); rc = FAILURE; goto finish; } /* Initialize this provider */ rv = funcs->C_Initialize(NULL_PTR); if (rv != CKR_OK) { cryptodebug("C_Initialize failed with error code 0x%x\n", rv); rc = FAILURE; goto finish; } else { lib_initialized = B_TRUE; } /* * We know for sure that metaslot is slot 0 in the framework, * so, we will do a C_GetSlotInfo() trying to see if it works. * If it fails with CKR_SLOT_ID_INVALID, we know that metaslot * is not really enabled. */ rv = funcs->C_GetSlotInfo(METASLOT_ID, &slot_info); if (rv == CKR_SLOT_ID_INVALID) { (void) printf(gettext("actual status: disabled.\n")); /* * Even if the -m and -v flag is supplied, there's nothing * interesting to display about metaslot since it is disabled, * so, just stop right here. */ goto finish; } if (rv != CKR_OK) { cryptodebug("C_GetSlotInfo failed with error " "code 0x%x\n", rv); rc = FAILURE; goto finish; } if (!verbose) { goto display_mechs; } (void) printf(gettext("actual status: enabled.\n")); (void) printf(gettext("Description: %.64s\n"), slot_info.slotDescription); (void) printf(gettext("Token Present: %s\n"), (slot_info.flags & CKF_TOKEN_PRESENT ? gettext("True") : gettext("False"))); rv = funcs->C_GetTokenInfo(METASLOT_ID, &token_info); if (rv != CKR_OK) { cryptodebug("C_GetTokenInfo failed with error " "code 0x%x\n", rv); rc = FAILURE; goto finish; } (void) printf(gettext("Token Label: %.32s\n" "Manufacturer ID: %.32s\n" "Model: %.16s\n" "Serial Number: %.16s\n" "Hardware Version: %d.%d\n" "Firmware Version: %d.%d\n" "UTC Time: %.16s\n" "PIN Min Length: %d\n" "PIN Max Length: %d\n"), token_info.label, token_info.manufacturerID, token_info.model, token_info.serialNumber, token_info.hardwareVersion.major, token_info.hardwareVersion.minor, token_info.firmwareVersion.major, token_info.firmwareVersion.minor, token_info.utcTime, token_info.ulMinPinLen, token_info.ulMaxPinLen); display_token_flags(token_info.flags); if (!show_mechs) { goto finish; } display_mechs: if (mechlist == NULL) { rv = funcs->C_GetMechanismList(METASLOT_ID, NULL_PTR, &mech_count); if (rv != CKR_OK) { cryptodebug("C_GetMechanismList failed with error " "code 0x%x\n", rv); rc = FAILURE; goto finish; } if (mech_count > 0) { pmech_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE)); if (pmech_list == NULL) { cryptodebug("out of memory"); rc = FAILURE; goto finish; } rv = funcs->C_GetMechanismList(METASLOT_ID, pmech_list, &mech_count); if (rv != CKR_OK) { cryptodebug("C_GetMechanismList failed with " "error code 0x%x\n", rv); rc = FAILURE; goto finish; } } } else { rc = convert_mechlist(&pmech_list, &mech_count, mechlist); if (rc != SUCCESS) { goto finish; } } (void) printf(gettext("Mechanisms:\n")); if (mech_count == 0) { /* should never be this case */ (void) printf(gettext("No mechanisms\n")); goto finish; } if (verbose) { display_verbose_mech_header(); } for (i = 0; i < mech_count; i++) { CK_MECHANISM_TYPE mech = pmech_list[i]; if (mech >= CKM_VENDOR_DEFINED) { (void) printf("%#lx", mech); } else { (void) printf("%-29s", pkcs11_mech2str(mech)); } if (verbose) { CK_MECHANISM_INFO mech_info; rv = funcs->C_GetMechanismInfo(METASLOT_ID, mech, &mech_info); if (rv != CKR_OK) { cryptodebug("C_GetMechanismInfo failed with " "error code 0x%x\n", rv); rc = FAILURE; goto finish; } display_mech_info(&mech_info); } (void) printf("\n"); } finish: if ((rc == FAILURE) && (show_mechs)) { (void) printf(gettext( "metaslot: failed to retrieve the mechanism list.\n")); } if (lib_initialized) { (void) funcs->C_Finalize(NULL_PTR); } if (dldesc != NULL) { (void) dlclose(dldesc); } if (pmech_list != NULL) { (void) free(pmech_list); } return (rc); }
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; }