michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * This is a very trivial program I wrote for testing out a michael@0: * couple data-only Cryptoki modules for NSS. It's not a "real" michael@0: * test program that prints out nice "PASS" or "FAIL" messages; michael@0: * it just makes calls and dumps data. michael@0: */ michael@0: michael@0: #include "config.h" michael@0: michael@0: #ifdef HAVE_NSPR_H michael@0: #include "nspr.h" michael@0: #else michael@0: #error "NSPR is required." michael@0: #endif michael@0: michael@0: #ifdef WITH_NSS michael@0: #define FGMR 1 michael@0: #include "ck.h" michael@0: #else michael@0: #include "pkcs11t.h" michael@0: #include "pkcs11.h" michael@0: #endif michael@0: michael@0: /* The RSA versions are sloppier with namespaces */ michael@0: #ifndef CK_TRUE michael@0: #define CK_TRUE TRUE michael@0: #endif michael@0: michael@0: #ifndef CK_FALSE michael@0: #define CK_FALSE FALSE michael@0: #endif michael@0: michael@0: int michael@0: rmain michael@0: ( michael@0: int argc, michael@0: char *argv[] michael@0: ); michael@0: michael@0: int michael@0: main michael@0: ( michael@0: int argc, michael@0: char *argv[] michael@0: ) michael@0: { michael@0: int rv = 0; michael@0: michael@0: PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 14); michael@0: rv = rmain(argc, argv); michael@0: PR_Cleanup(); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: static CK_ATTRIBUTE_TYPE all_known_attribute_types[] = { michael@0: CKA_CLASS, michael@0: CKA_TOKEN, michael@0: CKA_PRIVATE, michael@0: CKA_LABEL, michael@0: CKA_APPLICATION, michael@0: CKA_VALUE, michael@0: CKA_CERTIFICATE_TYPE, michael@0: CKA_ISSUER, michael@0: CKA_SERIAL_NUMBER, michael@0: CKA_KEY_TYPE, michael@0: CKA_SUBJECT, michael@0: CKA_ID, michael@0: CKA_SENSITIVE, michael@0: CKA_ENCRYPT, michael@0: CKA_DECRYPT, michael@0: CKA_WRAP, michael@0: CKA_UNWRAP, michael@0: CKA_SIGN, michael@0: CKA_SIGN_RECOVER, michael@0: CKA_VERIFY, michael@0: CKA_VERIFY_RECOVER, michael@0: CKA_DERIVE, michael@0: CKA_START_DATE, michael@0: CKA_END_DATE, michael@0: CKA_MODULUS, michael@0: CKA_MODULUS_BITS, michael@0: CKA_PUBLIC_EXPONENT, michael@0: CKA_PRIVATE_EXPONENT, michael@0: CKA_PRIME_1, michael@0: CKA_PRIME_2, michael@0: CKA_EXPONENT_1, michael@0: CKA_EXPONENT_2, michael@0: CKA_COEFFICIENT, michael@0: CKA_PRIME, michael@0: CKA_SUBPRIME, michael@0: CKA_BASE, michael@0: CKA_VALUE_BITS, michael@0: CKA_VALUE_LEN, michael@0: CKA_EXTRACTABLE, michael@0: CKA_LOCAL, michael@0: CKA_NEVER_EXTRACTABLE, michael@0: CKA_ALWAYS_SENSITIVE, michael@0: CKA_MODIFIABLE, michael@0: #ifdef CKA_NETSCAPE michael@0: CKA_NETSCAPE_URL, michael@0: CKA_NETSCAPE_EMAIL, michael@0: CKA_NETSCAPE_SMIME_INFO, michael@0: CKA_NETSCAPE_SMIME_TIMESTAMP, michael@0: CKA_NETSCAPE_PKCS8_SALT, michael@0: CKA_NETSCAPE_PASSWORD_CHECK, michael@0: CKA_NETSCAPE_EXPIRES, michael@0: #endif /* CKA_NETSCAPE */ michael@0: #ifdef CKA_TRUST michael@0: CKA_TRUST_DIGITAL_SIGNATURE, michael@0: CKA_TRUST_NON_REPUDIATION, michael@0: CKA_TRUST_KEY_ENCIPHERMENT, michael@0: CKA_TRUST_DATA_ENCIPHERMENT, michael@0: CKA_TRUST_KEY_AGREEMENT, michael@0: CKA_TRUST_KEY_CERT_SIGN, michael@0: CKA_TRUST_CRL_SIGN, michael@0: CKA_TRUST_SERVER_AUTH, michael@0: CKA_TRUST_CLIENT_AUTH, michael@0: CKA_TRUST_CODE_SIGNING, michael@0: CKA_TRUST_EMAIL_PROTECTION, michael@0: CKA_TRUST_IPSEC_END_SYSTEM, michael@0: CKA_TRUST_IPSEC_TUNNEL, michael@0: CKA_TRUST_IPSEC_USER, michael@0: CKA_TRUST_TIME_STAMPING, michael@0: #endif /* CKA_TRUST */ michael@0: }; michael@0: michael@0: static number_of_all_known_attribute_types = michael@0: (sizeof(all_known_attribute_types)/sizeof(all_known_attribute_types[0])); michael@0: michael@0: int michael@0: usage michael@0: ( michael@0: char *argv0 michael@0: ) michael@0: { michael@0: PR_fprintf(PR_STDERR, "Usage: %s [-i {string|--}] .so\n", argv0); michael@0: return 1; michael@0: } michael@0: michael@0: int michael@0: rmain michael@0: ( michael@0: int argc, michael@0: char *argv[] michael@0: ) michael@0: { michael@0: char *argv0 = argv[0]; michael@0: PRLibrary *lib; michael@0: CK_C_GetFunctionList gfl; michael@0: CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR)NULL; michael@0: CK_RV ck_rv; michael@0: CK_INFO info; michael@0: CK_ULONG nSlots; michael@0: CK_SLOT_ID *pSlots; michael@0: CK_ULONG i; michael@0: CK_C_INITIALIZE_ARGS ia, *iap; michael@0: michael@0: (void)memset(&ia, 0, sizeof(CK_C_INITIALIZE_ARGS)); michael@0: iap = (CK_C_INITIALIZE_ARGS *)NULL; michael@0: while( argv++, --argc ) { michael@0: if( '-' == argv[0][0] ) { michael@0: switch( argv[0][1] ) { michael@0: case 'i': michael@0: iap = &ia; michael@0: if( ((char *)NULL != argv[1]) && ('-' != argv[1][0]) ) { michael@0: #ifdef WITH_NSS michael@0: ia.pConfig = argv[1]; michael@0: ia.ulConfigLen = strlen(argv[1]); michael@0: argv++, --argc; michael@0: #else michael@0: return usage(argv0); michael@0: #endif /* WITH_NSS */ michael@0: } michael@0: break; michael@0: case '-': michael@0: argv++, --argc; michael@0: goto endargs; michael@0: default: michael@0: return usage(argv0); michael@0: } michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: endargs:; michael@0: michael@0: if( 1 != argc ) { michael@0: return usage(argv0); michael@0: } michael@0: michael@0: lib = PR_LoadLibrary(argv[0]); michael@0: if( (PRLibrary *)NULL == lib ) { michael@0: PR_fprintf(PR_STDERR, "Can't load %s: %ld, %ld\n", argv[1], PR_GetError(), PR_GetOSError()); michael@0: return 1; michael@0: } michael@0: michael@0: gfl = (CK_C_GetFunctionList)PR_FindSymbol(lib, "C_GetFunctionList"); michael@0: if( (CK_C_GetFunctionList)NULL == gfl ) { michael@0: PR_fprintf(PR_STDERR, "Can't find C_GetFunctionList in %s: %ld, %ld\n", argv[1], michael@0: PR_GetError(), PR_GetOSError()); michael@0: return 1; michael@0: } michael@0: michael@0: ck_rv = (*gfl)(&epv); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "CK_GetFunctionList returned 0x%08x\n", ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "Module %s loaded, epv = 0x%08x.\n\n", argv[1], (CK_ULONG)epv); michael@0: michael@0: /* C_Initialize */ michael@0: ck_rv = epv->C_Initialize(iap); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_Initialize returned 0x%08x\n", ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: /* C_GetInfo */ michael@0: (void)memset(&info, 0, sizeof(CK_INFO)); michael@0: ck_rv = epv->C_GetInfo(&info); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetInfo returned 0x%08x\n", ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "Module Info:\n"); michael@0: PR_fprintf(PR_STDOUT, " cryptokiVersion = %lu.%02lu\n", michael@0: (PRUint32)info.cryptokiVersion.major, (PRUint32)info.cryptokiVersion.minor); michael@0: PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", info.manufacturerID); michael@0: PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", info.flags); michael@0: PR_fprintf(PR_STDOUT, " libraryDescription = \"%.32s\"\n", info.libraryDescription); michael@0: PR_fprintf(PR_STDOUT, " libraryVersion = %lu.%02lu\n", michael@0: (PRUint32)info.libraryVersion.major, (PRUint32)info.libraryVersion.minor); michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: michael@0: /* C_GetSlotList */ michael@0: nSlots = 0; michael@0: ck_rv = epv->C_GetSlotList(CK_FALSE, (CK_SLOT_ID_PTR)CK_NULL_PTR, &nSlots); michael@0: switch( ck_rv ) { michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: case CKR_OK: michael@0: break; michael@0: default: michael@0: PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, NULL, ) returned 0x%08x\n", ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "There are %lu slots.\n", nSlots); michael@0: michael@0: pSlots = (CK_SLOT_ID_PTR)PR_Calloc(nSlots, sizeof(CK_SLOT_ID)); michael@0: if( (CK_SLOT_ID_PTR)NULL == pSlots ) { michael@0: PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nSlots * sizeof(CK_SLOT_ID)); michael@0: return 1; michael@0: } michael@0: michael@0: ck_rv = epv->C_GetSlotList(CK_FALSE, pSlots, &nSlots); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, , ) returned 0x%08x\n", ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: for( i = 0; i < nSlots; i++ ) { michael@0: PR_fprintf(PR_STDOUT, " [%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]); michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: michael@0: /* C_GetSlotInfo */ michael@0: for( i = 0; i < nSlots; i++ ) { michael@0: CK_SLOT_INFO sinfo; michael@0: michael@0: PR_fprintf(PR_STDOUT, "[%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]); michael@0: michael@0: (void)memset(&sinfo, 0, sizeof(CK_SLOT_INFO)); michael@0: ck_rv = epv->C_GetSlotInfo(pSlots[i], &sinfo); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetSlotInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Slot Info:\n"); michael@0: PR_fprintf(PR_STDOUT, " slotDescription = \"%.64s\"\n", sinfo.slotDescription); michael@0: PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", sinfo.manufacturerID); michael@0: PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", sinfo.flags); michael@0: PR_fprintf(PR_STDOUT, " -> TOKEN PRESENT = %s\n", michael@0: sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> REMOVABLE DEVICE = %s\n", michael@0: sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> HW SLOT = %s\n", michael@0: sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " hardwareVersion = %lu.%02lu\n", michael@0: (PRUint32)sinfo.hardwareVersion.major, (PRUint32)sinfo.hardwareVersion.minor); michael@0: PR_fprintf(PR_STDOUT, " firmwareVersion = %lu.%02lu\n", michael@0: (PRUint32)sinfo.firmwareVersion.major, (PRUint32)sinfo.firmwareVersion.minor); michael@0: michael@0: if( sinfo.flags & CKF_TOKEN_PRESENT ) { michael@0: CK_TOKEN_INFO tinfo; michael@0: CK_MECHANISM_TYPE *pMechanismList; michael@0: CK_ULONG nMechanisms = 0; michael@0: CK_ULONG j; michael@0: michael@0: (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO)); michael@0: ck_rv = epv->C_GetTokenInfo(pSlots[i], &tinfo); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetTokenInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Token Info:\n"); michael@0: PR_fprintf(PR_STDOUT, " label = \"%.32s\"\n", tinfo.label); michael@0: PR_fprintf(PR_STDOUT, " manufacturerID = \"%.32s\"\n", tinfo.manufacturerID); michael@0: PR_fprintf(PR_STDOUT, " model = \"%.16s\"\n", tinfo.model); michael@0: PR_fprintf(PR_STDOUT, " serialNumber = \"%.16s\"\n", tinfo.serialNumber); michael@0: PR_fprintf(PR_STDOUT, " flags = 0x%08lx\n", tinfo.flags); michael@0: PR_fprintf(PR_STDOUT, " -> RNG = %s\n", michael@0: tinfo.flags & CKF_RNG ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> WRITE PROTECTED = %s\n", michael@0: tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> LOGIN REQUIRED = %s\n", michael@0: tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> USER PIN INITIALIZED = %s\n", michael@0: tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> RESTORE KEY NOT NEEDED = %s\n", michael@0: tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> CLOCK ON TOKEN = %s\n", michael@0: tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE"); michael@0: #ifdef CKF_SUPPORTS_PARALLEL michael@0: PR_fprintf(PR_STDOUT, " -> SUPPORTS PARALLEL = %s\n", michael@0: tinfo.flags & CKF_SUPPORTS_PARALLEL ? "TRUE" : "FALSE"); michael@0: #endif /* CKF_SUPPORTS_PARALLEL */ michael@0: PR_fprintf(PR_STDOUT, " -> PROTECTED AUTHENTICATION PATH = %s\n", michael@0: tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> DUAL_CRYPTO_OPERATIONS = %s\n", michael@0: tinfo.flags & CKF_DUAL_CRYPTO_OPERATIONS ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " ulMaxSessionCount = %lu\n", tinfo.ulMaxSessionCount); michael@0: PR_fprintf(PR_STDOUT, " ulSessionCount = %lu\n", tinfo.ulSessionCount); michael@0: PR_fprintf(PR_STDOUT, " ulMaxRwSessionCount = %lu\n", tinfo.ulMaxRwSessionCount); michael@0: PR_fprintf(PR_STDOUT, " ulRwSessionCount = %lu\n", tinfo.ulRwSessionCount); michael@0: PR_fprintf(PR_STDOUT, " ulMaxPinLen = %lu\n", tinfo.ulMaxPinLen); michael@0: PR_fprintf(PR_STDOUT, " ulMinPinLen = %lu\n", tinfo.ulMinPinLen); michael@0: PR_fprintf(PR_STDOUT, " ulTotalPublicMemory = %lu\n", tinfo.ulTotalPublicMemory); michael@0: PR_fprintf(PR_STDOUT, " ulFreePublicMemory = %lu\n", tinfo.ulFreePublicMemory); michael@0: PR_fprintf(PR_STDOUT, " ulTotalPrivateMemory = %lu\n", tinfo.ulTotalPrivateMemory); michael@0: PR_fprintf(PR_STDOUT, " ulFreePrivateMemory = %lu\n", tinfo.ulFreePrivateMemory); michael@0: PR_fprintf(PR_STDOUT, " hardwareVersion = %lu.%02lu\n", michael@0: (PRUint32)tinfo.hardwareVersion.major, (PRUint32)tinfo.hardwareVersion.minor); michael@0: PR_fprintf(PR_STDOUT, " firmwareVersion = %lu.%02lu\n", michael@0: (PRUint32)tinfo.firmwareVersion.major, (PRUint32)tinfo.firmwareVersion.minor); michael@0: PR_fprintf(PR_STDOUT, " utcTime = \"%.16s\"\n", tinfo.utcTime); michael@0: michael@0: michael@0: ck_rv = epv->C_GetMechanismList(pSlots[i], (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR, &nMechanisms); michael@0: switch( ck_rv ) { michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: case CKR_OK: michael@0: break; michael@0: default: michael@0: PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, NULL, ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " %lu mechanisms:\n", nMechanisms); michael@0: michael@0: pMechanismList = (CK_MECHANISM_TYPE_PTR)PR_Calloc(nMechanisms, sizeof(CK_MECHANISM_TYPE)); michael@0: if( (CK_MECHANISM_TYPE_PTR)NULL == pMechanismList ) { michael@0: PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", michael@0: nMechanisms * sizeof(CK_MECHANISM_TYPE)); michael@0: return 1; michael@0: } michael@0: michael@0: ck_rv = epv->C_GetMechanismList(pSlots[i], pMechanismList, &nMechanisms); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: for( j = 0; j < nMechanisms; j++ ) { michael@0: PR_fprintf(PR_STDOUT, " {%lu}: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]); michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: michael@0: for( j = 0; j < nMechanisms; j++ ) { michael@0: CK_MECHANISM_INFO minfo; michael@0: michael@0: (void)memset(&minfo, 0, sizeof(CK_MECHANISM_INFO)); michael@0: ck_rv = epv->C_GetMechanismInfo(pSlots[i], pMechanismList[j], &minfo); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_GetMechanismInfo(%lu, %lu, ) returned 0x%08x\n", pSlots[i], michael@0: pMechanismList[j]); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " [%lu]: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]); michael@0: PR_fprintf(PR_STDOUT, " ulMinKeySize = %lu\n", minfo.ulMinKeySize); michael@0: PR_fprintf(PR_STDOUT, " ulMaxKeySize = %lu\n", minfo.ulMaxKeySize); michael@0: PR_fprintf(PR_STDOUT, " flags = 0x%08x\n", minfo.flags); michael@0: PR_fprintf(PR_STDOUT, " -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE"); michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: } michael@0: michael@0: if( tinfo.flags & CKF_LOGIN_REQUIRED ) { michael@0: PR_fprintf(PR_STDERR, "*** LOGIN REQUIRED but not yet implemented ***\n"); michael@0: /* all the stuff about logging in as SO and setting the user pin if needed, etc. */ michael@0: return 2; michael@0: } michael@0: michael@0: /* session to find objects */ michael@0: { michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_SESSION_INFO sinfo; michael@0: CK_ATTRIBUTE_PTR pTemplate; michael@0: CK_ULONG tnObjects = 0; michael@0: michael@0: ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO)); michael@0: ck_rv = epv->C_GetSessionInfo(h, &sinfo); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDOUT, "C_GetSessionInfo(%lu, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " SESSION INFO:\n"); michael@0: PR_fprintf(PR_STDOUT, " slotID = %lu\n", sinfo.slotID); michael@0: PR_fprintf(PR_STDOUT, " state = %lu\n", sinfo.state); michael@0: PR_fprintf(PR_STDOUT, " flags = 0x%08x\n", sinfo.flags); michael@0: #ifdef CKF_EXCLUSIVE_SESSION michael@0: PR_fprintf(PR_STDOUT, " -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE"); michael@0: #endif /* CKF_EXCLUSIVE_SESSION */ michael@0: PR_fprintf(PR_STDOUT, " -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE"); michael@0: PR_fprintf(PR_STDOUT, " -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE"); michael@0: #ifdef CKF_INSERTION_CALLBACK michael@0: PR_fprintf(PR_STDOUT, " -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE"); michael@0: #endif /* CKF_INSERTION_CALLBACK */ michael@0: PR_fprintf(PR_STDOUT, " ulDeviceError = %lu\n", sinfo.ulDeviceError); michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDOUT, "C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: pTemplate = (CK_ATTRIBUTE_PTR)PR_Calloc(number_of_all_known_attribute_types, sizeof(CK_ATTRIBUTE)); michael@0: if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { michael@0: PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", michael@0: number_of_all_known_attribute_types * sizeof(CK_ATTRIBUTE)); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " All objects:\n"); michael@0: michael@0: while(1) { michael@0: CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0; michael@0: CK_ULONG nObjects = 0; michael@0: CK_ULONG k; michael@0: CK_ULONG nAttributes = 0; michael@0: CK_ATTRIBUTE_PTR pT2; michael@0: CK_ULONG l; michael@0: michael@0: ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 0 == nObjects ) { michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: break; michael@0: } michael@0: michael@0: tnObjects++; michael@0: michael@0: PR_fprintf(PR_STDOUT, " OBJECT HANDLE %lu:\n", o); michael@0: michael@0: for( k = 0; k < number_of_all_known_attribute_types; k++ ) { michael@0: pTemplate[k].type = all_known_attribute_types[k]; michael@0: pTemplate[k].pValue = (CK_VOID_PTR)CK_NULL_PTR; michael@0: pTemplate[k].ulValueLen = 0; michael@0: } michael@0: michael@0: ck_rv = epv->C_GetAttributeValue(h, o, pTemplate, number_of_all_known_attribute_types); michael@0: switch( ck_rv ) { michael@0: case CKR_OK: michael@0: case CKR_ATTRIBUTE_SENSITIVE: michael@0: case CKR_ATTRIBUTE_TYPE_INVALID: michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: break; michael@0: default: michael@0: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {all attribute types}, %lu) returned 0x%08x\n", michael@0: h, o, number_of_all_known_attribute_types, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: for( k = 0; k < number_of_all_known_attribute_types; k++ ) { michael@0: if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: nAttributes++; michael@0: } michael@0: } michael@0: michael@0: if( 1 ) { michael@0: PR_fprintf(PR_STDOUT, " %lu attributes:\n", nAttributes); michael@0: for( k = 0; k < number_of_all_known_attribute_types; k++ ) { michael@0: if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: PR_fprintf(PR_STDOUT, " 0x%08x (len = %lu)\n", pTemplate[k].type, michael@0: pTemplate[k].ulValueLen); michael@0: } michael@0: } michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: } michael@0: michael@0: pT2 = (CK_ATTRIBUTE_PTR)PR_Calloc(nAttributes, sizeof(CK_ATTRIBUTE)); michael@0: if( (CK_ATTRIBUTE_PTR)NULL == pT2 ) { michael@0: PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", michael@0: nAttributes * sizeof(CK_ATTRIBUTE)); michael@0: return 1; michael@0: } michael@0: michael@0: for( l = 0, k = 0; k < number_of_all_known_attribute_types; k++ ) { michael@0: if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) { michael@0: pT2[l].type = pTemplate[k].type; michael@0: pT2[l].ulValueLen = pTemplate[k].ulValueLen; michael@0: pT2[l].pValue = (CK_VOID_PTR)PR_Malloc(pT2[l].ulValueLen); michael@0: if( (CK_VOID_PTR)NULL == pT2[l].pValue ) { michael@0: PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", pT2[l].ulValueLen); michael@0: return 1; michael@0: } michael@0: l++; michael@0: } michael@0: } michael@0: michael@0: PR_ASSERT( l == nAttributes ); michael@0: michael@0: ck_rv = epv->C_GetAttributeValue(h, o, pT2, nAttributes); michael@0: switch( ck_rv ) { michael@0: case CKR_OK: michael@0: case CKR_ATTRIBUTE_SENSITIVE: michael@0: case CKR_ATTRIBUTE_TYPE_INVALID: michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: break; michael@0: default: michael@0: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {existent attribute types}, %lu) returned 0x%08x\n", michael@0: h, o, nAttributes, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: for( l = 0; l < nAttributes; l++ ) { michael@0: PR_fprintf(PR_STDOUT, " type = 0x%08x, len = %ld", pT2[l].type, (CK_LONG)pT2[l].ulValueLen); michael@0: if( -1 == (CK_LONG)pT2[l].ulValueLen ) { michael@0: ; michael@0: } else { michael@0: CK_ULONG m; michael@0: michael@0: if( pT2[l].ulValueLen <= 8 ) { michael@0: PR_fprintf(PR_STDOUT, ", value = "); michael@0: } else { michael@0: PR_fprintf(PR_STDOUT, ", value = \n "); michael@0: } michael@0: michael@0: for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { michael@0: PR_fprintf(PR_STDOUT, "%02x", (CK_ULONG)(0xff & ((CK_CHAR_PTR)pT2[l].pValue)[m])); michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " "); michael@0: michael@0: for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) { michael@0: CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m]; michael@0: if( (c < 0x20) || (c >= 0x7f) ) { michael@0: c = '.'; michael@0: } michael@0: PR_fprintf(PR_STDOUT, "%c", c); michael@0: } michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: michael@0: for( l = 0; l < nAttributes; l++ ) { michael@0: PR_Free(pT2[l].pValue); michael@0: } michael@0: PR_Free(pT2); michael@0: } /* while(1) */ michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " (%lu objects total)\n", tnObjects); michael@0: michael@0: ck_rv = epv->C_CloseSession(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: } /* session to find objects */ michael@0: michael@0: /* session to create, find, and delete a couple session objects */ michael@0: { michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1]; michael@0: CK_OBJECT_CLASS cko_data = CKO_DATA; michael@0: CK_BBOOL false = CK_FALSE, true = CK_TRUE; michael@0: char *key = "TEST PROGRAM"; michael@0: CK_ULONG key_len = strlen(key); michael@0: CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0, hTwoIn = (CK_OBJECT_HANDLE)0, michael@0: hThreeIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE found[10]; michael@0: CK_ULONG nFound; michael@0: michael@0: ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: one[0].type = CKA_CLASS; michael@0: one[0].pValue = &cko_data; michael@0: one[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: one[1].type = CKA_TOKEN; michael@0: one[1].pValue = &false; michael@0: one[1].ulValueLen = sizeof(CK_BBOOL); michael@0: one[2].type = CKA_PRIVATE; michael@0: one[2].pValue = &false; michael@0: one[2].ulValueLen = sizeof(CK_BBOOL); michael@0: one[3].type = CKA_MODIFIABLE; michael@0: one[3].pValue = &true; michael@0: one[3].ulValueLen = sizeof(CK_BBOOL); michael@0: one[4].type = CKA_LABEL; michael@0: one[4].pValue = "Test data object one"; michael@0: one[4].ulValueLen = strlen(one[4].pValue); michael@0: one[5].type = CKA_APPLICATION; michael@0: one[5].pValue = key; michael@0: one[5].ulValueLen = key_len; michael@0: one[6].type = CKA_VALUE; michael@0: one[6].pValue = "Object one"; michael@0: one[6].ulValueLen = strlen(one[6].pValue); michael@0: michael@0: two[0].type = CKA_CLASS; michael@0: two[0].pValue = &cko_data; michael@0: two[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: two[1].type = CKA_TOKEN; michael@0: two[1].pValue = &false; michael@0: two[1].ulValueLen = sizeof(CK_BBOOL); michael@0: two[2].type = CKA_PRIVATE; michael@0: two[2].pValue = &false; michael@0: two[2].ulValueLen = sizeof(CK_BBOOL); michael@0: two[3].type = CKA_MODIFIABLE; michael@0: two[3].pValue = &true; michael@0: two[3].ulValueLen = sizeof(CK_BBOOL); michael@0: two[4].type = CKA_LABEL; michael@0: two[4].pValue = "Test data object two"; michael@0: two[4].ulValueLen = strlen(two[4].pValue); michael@0: two[5].type = CKA_APPLICATION; michael@0: two[5].pValue = key; michael@0: two[5].ulValueLen = key_len; michael@0: two[6].type = CKA_VALUE; michael@0: two[6].pValue = "Object two"; michael@0: two[6].ulValueLen = strlen(two[6].pValue); michael@0: michael@0: three[0].type = CKA_CLASS; michael@0: three[0].pValue = &cko_data; michael@0: three[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: three[1].type = CKA_TOKEN; michael@0: three[1].pValue = &false; michael@0: three[1].ulValueLen = sizeof(CK_BBOOL); michael@0: three[2].type = CKA_PRIVATE; michael@0: three[2].pValue = &false; michael@0: three[2].ulValueLen = sizeof(CK_BBOOL); michael@0: three[3].type = CKA_MODIFIABLE; michael@0: three[3].pValue = &true; michael@0: three[3].ulValueLen = sizeof(CK_BBOOL); michael@0: three[4].type = CKA_LABEL; michael@0: three[4].pValue = "Test data object three"; michael@0: three[4].ulValueLen = strlen(three[4].pValue); michael@0: three[5].type = CKA_APPLICATION; michael@0: three[5].pValue = key; michael@0: three[5].ulValueLen = key_len; michael@0: three[6].type = CKA_VALUE; michael@0: three[6].pValue = "Object three"; michael@0: three[6].ulValueLen = strlen(three[6].pValue); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, one, 7, &hOneIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, one, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object one: handle = %lu\n", hOneIn); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, two, 7, &hTwoIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, two, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object two: handle = %lu\n", hTwoIn); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, three, 7, &hThreeIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object three: handle = %lu\n", hThreeIn); michael@0: michael@0: delta[0].type = CKA_VALUE; michael@0: delta[0].pValue = "Copied object"; michael@0: delta[0].ulValueLen = strlen(delta[0].pValue); michael@0: michael@0: ck_rv = epv->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CopyObject(%lu, %lu, delta, 1, ) returned 0x%08x\n", michael@0: h, hThreeIn, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Copied object three: new handle = %lu\n", hDeltaIn); michael@0: michael@0: mask[0].type = CKA_APPLICATION; michael@0: mask[0].pValue = key; michael@0: mask[0].ulValueLen = key_len; michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, mask, 1); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: ck_rv = epv->C_FindObjects(h, found, 10, &nFound); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 4 != nFound ) { michael@0: PR_fprintf(PR_STDERR, "Found %lu objects, not 4.\n", nFound); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Found 4 objects: %lu, %lu, %lu, %lu\n", michael@0: found[0], found[1], found[2], found[3]); michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: ck_rv = epv->C_DestroyObject(h, hThreeIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, hThreeIn, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Destroyed object three (handle = %lu)\n", hThreeIn); michael@0: michael@0: delta[0].type = CKA_APPLICATION; michael@0: delta[0].pValue = "Changed application"; michael@0: delta[0].ulValueLen = strlen(delta[0].pValue); michael@0: michael@0: ck_rv = epv->C_SetAttributeValue(h, hTwoIn, delta, 1); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", michael@0: h, hTwoIn, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Changed object two (handle = %lu).\n", hTwoIn); michael@0: michael@0: /* Can another session find these session objects? */ michael@0: { michael@0: CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0; michael@0: michael@0: ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Opened a second session: handle = 0x%08x\n", h2); michael@0: michael@0: /* mask is still the same */ michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h2, mask, 1); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", michael@0: h2, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: ck_rv = epv->C_FindObjects(h2, found, 10, &nFound); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", michael@0: h2, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 2 != nFound ) { michael@0: PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", michael@0: found[0], found[1]); michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h2, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: /* Leave the session hanging open, we'll CloseAllSessions later */ michael@0: } /* Can another session find these session objects? */ michael@0: michael@0: ck_rv = epv->C_CloseAllSessions(pSlots[i]); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CloseAllSessions(%lu) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: } /* session to create, find, and delete a couple session objects */ michael@0: michael@0: /* Might be interesting to do a find here to verify that all session objects are gone. */ michael@0: michael@0: if( tinfo.flags & CKF_WRITE_PROTECTED ) { michael@0: PR_fprintf(PR_STDOUT, "Token is write protected, skipping token-object tests.\n"); michael@0: } else { michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_ATTRIBUTE tobj[7], tsobj[7], stobj[7], delta[1], mask[2]; michael@0: CK_OBJECT_CLASS cko_data = CKO_DATA; michael@0: CK_BBOOL false = CK_FALSE, true = CK_TRUE; michael@0: char *key = "TEST PROGRAM"; michael@0: CK_ULONG key_len = strlen(key); michael@0: CK_OBJECT_HANDLE hTIn = (CK_OBJECT_HANDLE)0, hTSIn = (CK_OBJECT_HANDLE)0, michael@0: hSTIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0; michael@0: CK_OBJECT_HANDLE found[10]; michael@0: CK_ULONG nFound; michael@0: michael@0: ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: tobj[0].type = CKA_CLASS; michael@0: tobj[0].pValue = &cko_data; michael@0: tobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: tobj[1].type = CKA_TOKEN; michael@0: tobj[1].pValue = &true; michael@0: tobj[1].ulValueLen = sizeof(CK_BBOOL); michael@0: tobj[2].type = CKA_PRIVATE; michael@0: tobj[2].pValue = &false; michael@0: tobj[2].ulValueLen = sizeof(CK_BBOOL); michael@0: tobj[3].type = CKA_MODIFIABLE; michael@0: tobj[3].pValue = &true; michael@0: tobj[3].ulValueLen = sizeof(CK_BBOOL); michael@0: tobj[4].type = CKA_LABEL; michael@0: tobj[4].pValue = "Test data object token"; michael@0: tobj[4].ulValueLen = strlen(tobj[4].pValue); michael@0: tobj[5].type = CKA_APPLICATION; michael@0: tobj[5].pValue = key; michael@0: tobj[5].ulValueLen = key_len; michael@0: tobj[6].type = CKA_VALUE; michael@0: tobj[6].pValue = "Object token"; michael@0: tobj[6].ulValueLen = strlen(tobj[6].pValue); michael@0: michael@0: tsobj[0].type = CKA_CLASS; michael@0: tsobj[0].pValue = &cko_data; michael@0: tsobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: tsobj[1].type = CKA_TOKEN; michael@0: tsobj[1].pValue = &true; michael@0: tsobj[1].ulValueLen = sizeof(CK_BBOOL); michael@0: tsobj[2].type = CKA_PRIVATE; michael@0: tsobj[2].pValue = &false; michael@0: tsobj[2].ulValueLen = sizeof(CK_BBOOL); michael@0: tsobj[3].type = CKA_MODIFIABLE; michael@0: tsobj[3].pValue = &true; michael@0: tsobj[3].ulValueLen = sizeof(CK_BBOOL); michael@0: tsobj[4].type = CKA_LABEL; michael@0: tsobj[4].pValue = "Test data object token->session"; michael@0: tsobj[4].ulValueLen = strlen(tsobj[4].pValue); michael@0: tsobj[5].type = CKA_APPLICATION; michael@0: tsobj[5].pValue = key; michael@0: tsobj[5].ulValueLen = key_len; michael@0: tsobj[6].type = CKA_VALUE; michael@0: tsobj[6].pValue = "Object token->session"; michael@0: tsobj[6].ulValueLen = strlen(tsobj[6].pValue); michael@0: michael@0: stobj[0].type = CKA_CLASS; michael@0: stobj[0].pValue = &cko_data; michael@0: stobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: stobj[1].type = CKA_TOKEN; michael@0: stobj[1].pValue = &false; michael@0: stobj[1].ulValueLen = sizeof(CK_BBOOL); michael@0: stobj[2].type = CKA_PRIVATE; michael@0: stobj[2].pValue = &false; michael@0: stobj[2].ulValueLen = sizeof(CK_BBOOL); michael@0: stobj[3].type = CKA_MODIFIABLE; michael@0: stobj[3].pValue = &true; michael@0: stobj[3].ulValueLen = sizeof(CK_BBOOL); michael@0: stobj[4].type = CKA_LABEL; michael@0: stobj[4].pValue = "Test data object session->token"; michael@0: stobj[4].ulValueLen = strlen(stobj[4].pValue); michael@0: stobj[5].type = CKA_APPLICATION; michael@0: stobj[5].pValue = key; michael@0: stobj[5].ulValueLen = key_len; michael@0: stobj[6].type = CKA_VALUE; michael@0: stobj[6].pValue = "Object session->token"; michael@0: stobj[6].ulValueLen = strlen(stobj[6].pValue); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, tobj, 7, &hTIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object token: handle = %lu\n", hTIn); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, tsobj, 7, &hTSIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object token->session: handle = %lu\n", hTSIn); michael@0: ck_rv = epv->C_CreateObject(h, stobj, 7, &hSTIn); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created object session->token: handle = %lu\n", hSTIn); michael@0: michael@0: /* I've created two token objects and one session object; find the two */ michael@0: michael@0: mask[0].type = CKA_APPLICATION; michael@0: mask[0].pValue = key; michael@0: mask[0].ulValueLen = key_len; michael@0: mask[1].type = CKA_TOKEN; michael@0: mask[1].pValue = &true; michael@0: mask[1].ulValueLen = sizeof(CK_BBOOL); michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, mask, 2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: ck_rv = epv->C_FindObjects(h, found, 10, &nFound); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 2 != nFound ) { michael@0: PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", michael@0: found[0], found[1]); michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: /* Convert a token to session object */ michael@0: michael@0: delta[0].type = CKA_TOKEN; michael@0: delta[0].pValue = &false; michael@0: delta[0].ulValueLen = sizeof(CK_BBOOL); michael@0: michael@0: ck_rv = epv->C_SetAttributeValue(h, hTSIn, delta, 1); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", michael@0: h, hTSIn, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Changed object from token to session (handle = %lu).\n", hTSIn); michael@0: michael@0: /* Now find again; there should be one */ michael@0: michael@0: mask[0].type = CKA_APPLICATION; michael@0: mask[0].pValue = key; michael@0: mask[0].ulValueLen = key_len; michael@0: mask[1].type = CKA_TOKEN; michael@0: mask[1].pValue = &true; michael@0: mask[1].ulValueLen = sizeof(CK_BBOOL); michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, mask, 2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: ck_rv = epv->C_FindObjects(h, found, 10, &nFound); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 1 != nFound ) { michael@0: PR_fprintf(PR_STDERR, "Found %lu objects, not 1.\n", nFound); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Found 1 objects: %lu\n", michael@0: found[0]); michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: /* Convert a session to a token object */ michael@0: michael@0: delta[0].type = CKA_TOKEN; michael@0: delta[0].pValue = &true; michael@0: delta[0].ulValueLen = sizeof(CK_BBOOL); michael@0: michael@0: ck_rv = epv->C_SetAttributeValue(h, hSTIn, delta, 1); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", michael@0: h, hSTIn, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Changed object from session to token (handle = %lu).\n", hSTIn); michael@0: michael@0: /* Now find again; there should be two again */ michael@0: michael@0: mask[0].type = CKA_APPLICATION; michael@0: mask[0].pValue = key; michael@0: mask[0].ulValueLen = key_len; michael@0: mask[1].type = CKA_TOKEN; michael@0: mask[1].pValue = &true; michael@0: mask[1].ulValueLen = sizeof(CK_BBOOL); michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, mask, 2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: (void)memset(&found, 0, sizeof(found)); michael@0: nFound = 0; michael@0: ck_rv = epv->C_FindObjects(h, found, 10, &nFound); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 2 != nFound ) { michael@0: PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Found 2 objects: %lu, %lu\n", michael@0: found[0], found[1]); michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: /* Delete the two (found) token objects to clean up */ michael@0: michael@0: ck_rv = epv->C_DestroyObject(h, found[0]); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[0], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Destroyed token object (handle = %lu)\n", found[0]); michael@0: michael@0: ck_rv = epv->C_DestroyObject(h, found[1]); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[1], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Destroyed token object (handle = %lu)\n", found[1]); michael@0: michael@0: /* Close the session and all objects should be gone */ michael@0: michael@0: ck_rv = epv->C_CloseSession(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: } /* if( tinfo.flags & CKF_WRITE_PROTECTED ) */ michael@0: michael@0: if( tinfo.flags & CKF_WRITE_PROTECTED ) { michael@0: PR_fprintf(PR_STDOUT, "Token is write protected, skipping leaving a record.\n"); michael@0: } else { michael@0: CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0; michael@0: CK_ATTRIBUTE record[7], mask[2]; michael@0: CK_OBJECT_CLASS cko_data = CKO_DATA; michael@0: CK_BBOOL false = CK_FALSE, true = CK_TRUE; michael@0: char *key = "TEST RECORD"; michael@0: CK_ULONG key_len = strlen(key); michael@0: CK_OBJECT_HANDLE hin = (CK_OBJECT_HANDLE)0; michael@0: char timebuffer[256]; michael@0: michael@0: ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Opened a session: handle = 0x%08x\n", h); michael@0: michael@0: /* I can't believe how hard NSPR makes this operation */ michael@0: { michael@0: time_t now = 0; michael@0: struct tm *tm; michael@0: time(&now); michael@0: tm = localtime(&now); michael@0: strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %T %Z", tm); michael@0: } michael@0: michael@0: record[0].type = CKA_CLASS; michael@0: record[0].pValue = &cko_data; michael@0: record[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: record[1].type = CKA_TOKEN; michael@0: record[1].pValue = &true; michael@0: record[1].ulValueLen = sizeof(CK_BBOOL); michael@0: record[2].type = CKA_PRIVATE; michael@0: record[2].pValue = &false; michael@0: record[2].ulValueLen = sizeof(CK_BBOOL); michael@0: record[3].type = CKA_MODIFIABLE; michael@0: record[3].pValue = &true; michael@0: record[3].ulValueLen = sizeof(CK_BBOOL); michael@0: record[4].type = CKA_LABEL; michael@0: record[4].pValue = "Test record"; michael@0: record[4].ulValueLen = strlen(record[4].pValue); michael@0: record[5].type = CKA_APPLICATION; michael@0: record[5].pValue = key; michael@0: record[5].ulValueLen = key_len; michael@0: record[6].type = CKA_VALUE; michael@0: record[6].pValue = timebuffer; michael@0: record[6].ulValueLen = strlen(timebuffer)+1; michael@0: michael@0: PR_fprintf(PR_STDOUT, " Timestamping with \"%s\"\n", timebuffer); michael@0: michael@0: ck_rv = epv->C_CreateObject(h, record, 7, &hin); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, " Created record object: handle = %lu\n", hin); michael@0: michael@0: PR_fprintf(PR_STDOUT, " == All test timestamps ==\n"); michael@0: michael@0: mask[0].type = CKA_CLASS; michael@0: mask[0].pValue = &cko_data; michael@0: mask[0].ulValueLen = sizeof(CK_OBJECT_CLASS); michael@0: mask[1].type = CKA_APPLICATION; michael@0: mask[1].pValue = key; michael@0: mask[1].ulValueLen = key_len; michael@0: michael@0: ck_rv = epv->C_FindObjectsInit(h, mask, 2); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", michael@0: h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: while( 1 ) { michael@0: CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0; michael@0: CK_ULONG nObjects = 0; michael@0: CK_ATTRIBUTE value[1]; michael@0: char buffer[1024]; michael@0: michael@0: ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: michael@0: if( 0 == nObjects ) { michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: break; michael@0: } michael@0: michael@0: value[0].type = CKA_VALUE; michael@0: value[0].pValue = buffer; michael@0: value[0].ulValueLen = sizeof(buffer); michael@0: michael@0: ck_rv = epv->C_GetAttributeValue(h, o, value, 1); michael@0: switch( ck_rv ) { michael@0: case CKR_OK: michael@0: PR_fprintf(PR_STDOUT, " %s\n", value[0].pValue); michael@0: break; michael@0: case CKR_ATTRIBUTE_SENSITIVE: michael@0: PR_fprintf(PR_STDOUT, " [Sensitive???]\n"); michael@0: break; michael@0: case CKR_ATTRIBUTE_TYPE_INVALID: michael@0: PR_fprintf(PR_STDOUT, " [Invalid attribute???]\n"); michael@0: break; michael@0: case CKR_BUFFER_TOO_SMALL: michael@0: PR_fprintf(PR_STDOUT, " (result > 1k (%lu))\n", value[0].ulValueLen); michael@0: break; michael@0: default: michael@0: PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, CKA_VALUE, 1) returned 0x%08x\n", michael@0: h, o); michael@0: return 1; michael@0: } michael@0: } /* while */ michael@0: michael@0: ck_rv = epv->C_FindObjectsFinal(h); michael@0: if( CKR_OK != ck_rv ) { michael@0: PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv); michael@0: return 1; michael@0: } michael@0: } /* "leaving a record" else clause */ michael@0: michael@0: } michael@0: michael@0: PR_fprintf(PR_STDOUT, "\n"); michael@0: } michael@0: michael@0: return 0; michael@0: }