trivial.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:47k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is a trivial PKCS#11 test program.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #ifdef DEBUG
  34. static const char CVS_ID[] = "@(#) $RCSfile: trivial.c,v $ $Revision: 1.2 $ $Date: 2000/07/20 21:48:26 $ $Name: NSS_3_1_1_RTM $";
  35. #endif /* DEBUG */
  36. /*
  37.  * This is a very trivial program I wrote for testing out a 
  38.  * couple data-only Cryptoki modules for NSS.  It's not a "real"
  39.  * test program that prints out nice "PASS" or "FAIL" messages;
  40.  * it just makes calls and dumps data.
  41.  */
  42. #include "config.h"
  43. #ifdef HAVE_NSPR_H
  44. #include "nspr.h"
  45. #else
  46. #error "NSPR is required."
  47. #endif
  48. #ifdef WITH_NSS
  49. #define FGMR 1
  50. #include "ck.h"
  51. #else
  52. #include "pkcs11t.h"
  53. #include "pkcs11.h"
  54. #endif
  55. /* The RSA versions are sloppier with namespaces */
  56. #ifndef CK_TRUE
  57. #define CK_TRUE TRUE
  58. #endif
  59. #ifndef CK_FALSE
  60. #define CK_FALSE FALSE
  61. #endif
  62. int
  63. rmain
  64. (
  65.   int argc,
  66.   char *argv[]
  67. );
  68. int
  69. main
  70. (
  71.   int argc,
  72.   char *argv[]
  73. )
  74. {
  75.   int rv = 0;
  76.   PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 14);
  77.   rv = rmain(argc, argv);
  78.   PR_Cleanup();
  79.   return rv;
  80. }
  81. static CK_ATTRIBUTE_TYPE all_known_attribute_types[] = {
  82.   CKA_CLASS,
  83.   CKA_TOKEN,
  84.   CKA_PRIVATE,
  85.   CKA_LABEL,
  86.   CKA_APPLICATION,
  87.   CKA_VALUE,
  88.   CKA_CERTIFICATE_TYPE,
  89.   CKA_ISSUER,
  90.   CKA_SERIAL_NUMBER,
  91.   CKA_KEY_TYPE,
  92.   CKA_SUBJECT,
  93.   CKA_ID,
  94.   CKA_SENSITIVE,
  95.   CKA_ENCRYPT,
  96.   CKA_DECRYPT,
  97.   CKA_WRAP,
  98.   CKA_UNWRAP,
  99.   CKA_SIGN,
  100.   CKA_SIGN_RECOVER,
  101.   CKA_VERIFY,
  102.   CKA_VERIFY_RECOVER,
  103.   CKA_DERIVE,
  104.   CKA_START_DATE,
  105.   CKA_END_DATE,
  106.   CKA_MODULUS,
  107.   CKA_MODULUS_BITS,
  108.   CKA_PUBLIC_EXPONENT,
  109.   CKA_PRIVATE_EXPONENT,
  110.   CKA_PRIME_1,
  111.   CKA_PRIME_2,
  112.   CKA_EXPONENT_1,
  113.   CKA_EXPONENT_2,
  114.   CKA_COEFFICIENT,
  115.   CKA_PRIME,
  116.   CKA_SUBPRIME,
  117.   CKA_BASE,
  118.   CKA_VALUE_BITS,
  119.   CKA_VALUE_LEN,
  120.   CKA_EXTRACTABLE,
  121.   CKA_LOCAL,
  122.   CKA_NEVER_EXTRACTABLE,
  123.   CKA_ALWAYS_SENSITIVE,
  124.   CKA_MODIFIABLE,
  125. #ifdef CKA_NETSCAPE
  126.   CKA_NETSCAPE_URL,
  127.   CKA_NETSCAPE_EMAIL,
  128.   CKA_NETSCAPE_SMIME_INFO,
  129.   CKA_NETSCAPE_SMIME_TIMESTAMP,
  130.   CKA_NETSCAPE_PKCS8_SALT,
  131.   CKA_NETSCAPE_PASSWORD_CHECK,
  132.   CKA_NETSCAPE_EXPIRES,
  133. #endif /* CKA_NETSCAPE */
  134. #ifdef CKA_TRUST
  135.   CKA_TRUST_DIGITAL_SIGNATURE,
  136.   CKA_TRUST_NON_REPUDIATION,
  137.   CKA_TRUST_KEY_ENCIPHERMENT,
  138.   CKA_TRUST_DATA_ENCIPHERMENT,
  139.   CKA_TRUST_KEY_AGREEMENT,
  140.   CKA_TRUST_KEY_CERT_SIGN,
  141.   CKA_TRUST_CRL_SIGN,
  142.   CKA_TRUST_SERVER_AUTH,
  143.   CKA_TRUST_CLIENT_AUTH,
  144.   CKA_TRUST_CODE_SIGNING,
  145.   CKA_TRUST_EMAIL_PROTECTION,
  146.   CKA_TRUST_IPSEC_END_SYSTEM,
  147.   CKA_TRUST_IPSEC_TUNNEL,
  148.   CKA_TRUST_IPSEC_USER,
  149.   CKA_TRUST_TIME_STAMPING,
  150. #endif /* CKA_TRUST */
  151. };
  152. static number_of_all_known_attribute_types = 
  153.   (sizeof(all_known_attribute_types)/sizeof(all_known_attribute_types[0]));
  154. int
  155. usage
  156. (
  157.   char *argv0
  158. )
  159. {
  160.   PR_fprintf(PR_STDERR, "Usage: %s [-i {string|--}] <library>.son", argv0);
  161.   return 1;
  162. }
  163. int
  164. rmain
  165. (
  166.   int argc,
  167.   char *argv[]
  168. )
  169. {
  170.   char *argv0 = argv[0];
  171.   PRLibrary *lib;
  172.   CK_C_GetFunctionList gfl;
  173.   CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR)NULL;
  174.   CK_RV ck_rv;
  175.   CK_INFO info;
  176.   CK_ULONG nSlots;
  177.   CK_SLOT_ID *pSlots;
  178.   CK_ULONG i;
  179.   CK_C_INITIALIZE_ARGS ia, *iap;
  180.   (void)memset(&ia, 0, sizeof(CK_C_INITIALIZE_ARGS));
  181.   iap = (CK_C_INITIALIZE_ARGS *)NULL;
  182.   while( argv++, --argc ) {
  183.     if( '-' == argv[0][0] ) {
  184.       switch( argv[0][1] ) {
  185.       case 'i':
  186.         iap = &ia;
  187.         if( ((char *)NULL != argv[1]) && ('-' != argv[1][0]) ) {
  188. #ifdef WITH_NSS
  189.           ia.pConfig = argv[1];
  190.           ia.ulConfigLen = strlen(argv[1]);
  191.           argv++, --argc;
  192. #else
  193.           return usage(argv0);
  194. #endif /* WITH_NSS */
  195.         }
  196.         break;
  197.       case '-':
  198.         argv++, --argc;
  199.         goto endargs;
  200.       default:
  201.         return usage(argv0);
  202.       }
  203.     } else {
  204.       break;
  205.     }
  206.   }
  207.  endargs:;
  208.   if( 1 != argc ) {
  209.     return usage(argv0);
  210.   }
  211.   lib = PR_LoadLibrary(argv[0]);
  212.   if( (PRLibrary *)NULL == lib ) {
  213.     PR_fprintf(PR_STDERR, "Can't load %s: %ld, %ldn", argv[1], PR_GetError(), PR_GetOSError());
  214.     return 1;
  215.   }
  216.   gfl = (CK_C_GetFunctionList)PR_FindSymbol(lib, "C_GetFunctionList");
  217.   if( (CK_C_GetFunctionList)NULL == gfl ) {
  218.     PR_fprintf(PR_STDERR, "Can't find C_GetFunctionList in %s: %ld, %ldn", argv[1], 
  219.                PR_GetError(), PR_GetOSError());
  220.     return 1;
  221.   }
  222.   ck_rv = (*gfl)(&epv);
  223.   if( CKR_OK != ck_rv ) {
  224.     PR_fprintf(PR_STDERR, "CK_GetFunctionList returned 0x%08xn", ck_rv);
  225.     return 1;
  226.   }
  227.   PR_fprintf(PR_STDOUT, "Module %s loaded, epv = 0x%08x.nn", argv[1], (CK_ULONG)epv);
  228.   /* C_Initialize */
  229.   ck_rv = epv->C_Initialize(iap);
  230.   if( CKR_OK != ck_rv ) {
  231.     PR_fprintf(PR_STDERR, "C_Initialize returned 0x%08xn", ck_rv);
  232.     return 1;
  233.   }
  234.   /* C_GetInfo */
  235.   (void)memset(&info, 0, sizeof(CK_INFO));
  236.   ck_rv = epv->C_GetInfo(&info);
  237.   if( CKR_OK != ck_rv ) {
  238.     PR_fprintf(PR_STDERR, "C_GetInfo returned 0x%08xn", ck_rv);
  239.     return 1;
  240.   }
  241.   PR_fprintf(PR_STDOUT, "Module Info:n");
  242.   PR_fprintf(PR_STDOUT, "    cryptokiVersion = %lu.%02lun", 
  243.              (PRUint32)info.cryptokiVersion.major, (PRUint32)info.cryptokiVersion.minor);
  244.   PR_fprintf(PR_STDOUT, "    manufacturerID = "%.32s"n", info.manufacturerID);
  245.   PR_fprintf(PR_STDOUT, "    flags = 0x%08lxn", info.flags);
  246.   PR_fprintf(PR_STDOUT, "    libraryDescription = "%.32s"n", info.libraryDescription);
  247.   PR_fprintf(PR_STDOUT, "    libraryVersion = %lu.%02lun", 
  248.              (PRUint32)info.libraryVersion.major, (PRUint32)info.libraryVersion.minor);
  249.   PR_fprintf(PR_STDOUT, "n");
  250.   /* C_GetSlotList */
  251.   nSlots = 0;
  252.   ck_rv = epv->C_GetSlotList(CK_FALSE, (CK_SLOT_ID_PTR)CK_NULL_PTR, &nSlots);
  253.   switch( ck_rv ) {
  254.   case CKR_BUFFER_TOO_SMALL:
  255.   case CKR_OK:
  256.     break;
  257.   default:
  258.     PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, NULL, ) returned 0x%08xn", ck_rv);
  259.     return 1;
  260.   }
  261.   PR_fprintf(PR_STDOUT, "There are %lu slots.n", nSlots);
  262.   pSlots = (CK_SLOT_ID_PTR)PR_Calloc(nSlots, sizeof(CK_SLOT_ID));
  263.   if( (CK_SLOT_ID_PTR)NULL == pSlots ) {
  264.     PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]n", nSlots * sizeof(CK_SLOT_ID));
  265.     return 1;
  266.   }
  267.   ck_rv = epv->C_GetSlotList(CK_FALSE, pSlots, &nSlots);
  268.   if( CKR_OK != ck_rv ) {
  269.     PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, , ) returned 0x%08xn", ck_rv);
  270.     return 1;
  271.   }
  272.   for( i = 0; i < nSlots; i++ ) {
  273.     PR_fprintf(PR_STDOUT, "    [%lu]: CK_SLOT_ID = %lun", (i+1), pSlots[i]);
  274.   }
  275.   PR_fprintf(PR_STDOUT, "n");
  276.   /* C_GetSlotInfo */
  277.   for( i = 0; i < nSlots; i++ ) {
  278.     CK_SLOT_INFO sinfo;
  279.     PR_fprintf(PR_STDOUT, "[%lu]: CK_SLOT_ID = %lun", (i+1), pSlots[i]);
  280.     (void)memset(&sinfo, 0, sizeof(CK_SLOT_INFO));
  281.     ck_rv = epv->C_GetSlotInfo(pSlots[i], &sinfo);
  282.     if( CKR_OK != ck_rv ) {
  283.       PR_fprintf(PR_STDERR, "C_GetSlotInfo(%lu, ) returned 0x%08xn", pSlots[i], ck_rv);
  284.       return 1;
  285.     }
  286.     PR_fprintf(PR_STDOUT, "    Slot Info:n");
  287.     PR_fprintf(PR_STDOUT, "        slotDescription = "%.64s"n", sinfo.slotDescription);
  288.     PR_fprintf(PR_STDOUT, "        manufacturerID = "%.32s"n", sinfo.manufacturerID);
  289.     PR_fprintf(PR_STDOUT, "        flags = 0x%08lxn", sinfo.flags);
  290.     PR_fprintf(PR_STDOUT, "            -> TOKEN PRESENT = %sn", 
  291.                sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE");
  292.     PR_fprintf(PR_STDOUT, "            -> REMOVABLE DEVICE = %sn",
  293.                sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE");
  294.     PR_fprintf(PR_STDOUT, "            -> HW SLOT = %sn", 
  295.                sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE");
  296.     PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lun", 
  297.                (PRUint32)sinfo.hardwareVersion.major, (PRUint32)sinfo.hardwareVersion.minor);
  298.     PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lun",
  299.                (PRUint32)sinfo.firmwareVersion.major, (PRUint32)sinfo.firmwareVersion.minor);
  300.     if( sinfo.flags & CKF_TOKEN_PRESENT ) {
  301.       CK_TOKEN_INFO tinfo;
  302.       CK_MECHANISM_TYPE *pMechanismList;
  303.       CK_ULONG nMechanisms = 0;
  304.       CK_ULONG j;
  305.       (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
  306.       ck_rv = epv->C_GetTokenInfo(pSlots[i], &tinfo);
  307.       if( CKR_OK != ck_rv ) {
  308.         PR_fprintf(PR_STDERR, "C_GetTokenInfo(%lu, ) returned 0x%08xn", pSlots[i], ck_rv);
  309.         return 1;
  310.       }
  311.       PR_fprintf(PR_STDOUT, "    Token Info:n");
  312.       PR_fprintf(PR_STDOUT, "        label = "%.32s"n", tinfo.label);
  313.       PR_fprintf(PR_STDOUT, "        manufacturerID = "%.32s"n", tinfo.manufacturerID);
  314.       PR_fprintf(PR_STDOUT, "        model = "%.16s"n", tinfo.model);
  315.       PR_fprintf(PR_STDOUT, "        serialNumber = "%.16s"n", tinfo.serialNumber);
  316.       PR_fprintf(PR_STDOUT, "        flags = 0x%08lxn", tinfo.flags);
  317.       PR_fprintf(PR_STDOUT, "            -> RNG = %sn",
  318.                  tinfo.flags & CKF_RNG ? "TRUE" : "FALSE");
  319.       PR_fprintf(PR_STDOUT, "            -> WRITE PROTECTED = %sn",
  320.                  tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE");
  321.       PR_fprintf(PR_STDOUT, "            -> LOGIN REQUIRED = %sn",
  322.                  tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE");
  323.       PR_fprintf(PR_STDOUT, "            -> USER PIN INITIALIZED = %sn",
  324.                  tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE");
  325.       PR_fprintf(PR_STDOUT, "            -> RESTORE KEY NOT NEEDED = %sn",
  326.                  tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE");
  327.       PR_fprintf(PR_STDOUT, "            -> CLOCK ON TOKEN = %sn",
  328.                  tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE");
  329. #ifdef CKF_SUPPORTS_PARALLEL
  330.       PR_fprintf(PR_STDOUT, "            -> SUPPORTS PARALLEL = %sn",
  331.                  tinfo.flags & CKF_SUPPORTS_PARALLEL ? "TRUE" : "FALSE");
  332. #endif /* CKF_SUPPORTS_PARALLEL */
  333.       PR_fprintf(PR_STDOUT, "            -> PROTECTED AUTHENTICATION PATH = %sn",
  334.                  tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH ? "TRUE" : "FALSE");
  335.       PR_fprintf(PR_STDOUT, "            -> DUAL_CRYPTO_OPERATIONS = %sn", 
  336.                  tinfo.flags & CKF_DUAL_CRYPTO_OPERATIONS ? "TRUE" : "FALSE");
  337.       PR_fprintf(PR_STDOUT, "        ulMaxSessionCount = %lun", tinfo.ulMaxSessionCount);
  338.       PR_fprintf(PR_STDOUT, "        ulSessionCount = %lun", tinfo.ulSessionCount);
  339.       PR_fprintf(PR_STDOUT, "        ulMaxRwSessionCount = %lun", tinfo.ulMaxRwSessionCount);
  340.       PR_fprintf(PR_STDOUT, "        ulRwSessionCount = %lun", tinfo.ulRwSessionCount);
  341.       PR_fprintf(PR_STDOUT, "        ulMaxPinLen = %lun", tinfo.ulMaxPinLen);
  342.       PR_fprintf(PR_STDOUT, "        ulMinPinLen = %lun", tinfo.ulMinPinLen);
  343.       PR_fprintf(PR_STDOUT, "        ulTotalPublicMemory = %lun", tinfo.ulTotalPublicMemory);
  344.       PR_fprintf(PR_STDOUT, "        ulFreePublicMemory = %lun", tinfo.ulFreePublicMemory);
  345.       PR_fprintf(PR_STDOUT, "        ulTotalPrivateMemory = %lun", tinfo.ulTotalPrivateMemory);
  346.       PR_fprintf(PR_STDOUT, "        ulFreePrivateMemory = %lun", tinfo.ulFreePrivateMemory);
  347.       PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lun", 
  348.                  (PRUint32)tinfo.hardwareVersion.major, (PRUint32)tinfo.hardwareVersion.minor);
  349.       PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lun",
  350.                  (PRUint32)tinfo.firmwareVersion.major, (PRUint32)tinfo.firmwareVersion.minor);
  351.       PR_fprintf(PR_STDOUT, "        utcTime = "%.16s"n", tinfo.utcTime);
  352.       ck_rv = epv->C_GetMechanismList(pSlots[i], (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR, &nMechanisms);
  353.       switch( ck_rv ) {
  354.       case CKR_BUFFER_TOO_SMALL:
  355.       case CKR_OK:
  356.         break;
  357.       default:
  358.         PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, NULL, ) returned 0x%08xn", pSlots[i], ck_rv);
  359.         return 1;
  360.       }
  361.       PR_fprintf(PR_STDOUT, "    %lu mechanisms:n", nMechanisms);
  362.       pMechanismList = (CK_MECHANISM_TYPE_PTR)PR_Calloc(nMechanisms, sizeof(CK_MECHANISM_TYPE));
  363.       if( (CK_MECHANISM_TYPE_PTR)NULL == pMechanismList ) {
  364.         PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]n", 
  365.                    nMechanisms * sizeof(CK_MECHANISM_TYPE));
  366.         return 1;
  367.       }
  368.       ck_rv = epv->C_GetMechanismList(pSlots[i], pMechanismList, &nMechanisms);
  369.       if( CKR_OK != ck_rv ) {
  370.         PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, , ) returned 0x%08xn", pSlots[i], ck_rv);
  371.         return 1;
  372.       }
  373.       for( j = 0; j < nMechanisms; j++ ) {
  374.         PR_fprintf(PR_STDOUT, "        {%lu}: CK_MECHANISM_TYPE = %lun", (j+1), pMechanismList[j]);
  375.       }
  376.       PR_fprintf(PR_STDOUT, "n");
  377.       for( j = 0; j < nMechanisms; j++ ) {
  378.         CK_MECHANISM_INFO minfo;
  379.         (void)memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
  380.         ck_rv = epv->C_GetMechanismInfo(pSlots[i], pMechanismList[j], &minfo);
  381.         if( CKR_OK != ck_rv ) {
  382.           PR_fprintf(PR_STDERR, "C_GetMechanismInfo(%lu, %lu, ) returned 0x%08xn", pSlots[i], 
  383.                      pMechanismList[j]);
  384.           return 1;
  385.         }
  386.         PR_fprintf(PR_STDOUT, "    [%lu]: CK_MECHANISM_TYPE = %lun", (j+1), pMechanismList[j]);
  387.         PR_fprintf(PR_STDOUT, "    ulMinKeySize = %lun", minfo.ulMinKeySize);
  388.         PR_fprintf(PR_STDOUT, "    ulMaxKeySize = %lun", minfo.ulMaxKeySize);
  389.         PR_fprintf(PR_STDOUT, "    flags = 0x%08xn", minfo.flags);
  390.         PR_fprintf(PR_STDOUT, "        -> HW = %sn", minfo.flags & CKF_HW ? "TRUE" : "FALSE");
  391.         PR_fprintf(PR_STDOUT, "        -> ENCRYPT = %sn", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE");
  392.         PR_fprintf(PR_STDOUT, "        -> DECRYPT = %sn", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE");
  393.         PR_fprintf(PR_STDOUT, "        -> DIGEST = %sn", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE");
  394.         PR_fprintf(PR_STDOUT, "        -> SIGN = %sn", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE");
  395.         PR_fprintf(PR_STDOUT, "        -> SIGN_RECOVER = %sn", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
  396.         PR_fprintf(PR_STDOUT, "        -> VERIFY = %sn", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE");
  397.         PR_fprintf(PR_STDOUT, "        -> VERIFY_RECOVER = %sn", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
  398.         PR_fprintf(PR_STDOUT, "        -> GENERATE = %sn", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE");
  399.         PR_fprintf(PR_STDOUT, "        -> GENERATE_KEY_PAIR = %sn", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
  400.         PR_fprintf(PR_STDOUT, "        -> WRAP = %sn", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE");
  401.         PR_fprintf(PR_STDOUT, "        -> UNWRAP = %sn", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE");
  402.         PR_fprintf(PR_STDOUT, "        -> DERIVE = %sn", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE");
  403.         PR_fprintf(PR_STDOUT, "        -> EXTENSION = %sn", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE");
  404.         PR_fprintf(PR_STDOUT, "n");
  405.       }
  406.       if( tinfo.flags & CKF_LOGIN_REQUIRED ) {
  407.         PR_fprintf(PR_STDERR, "*** LOGIN REQUIRED but not yet implemented ***n");
  408.         /* all the stuff about logging in as SO and setting the user pin if needed, etc. */
  409.         return 2;
  410.       }
  411.       /* session to find objects */
  412.       {
  413.         CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
  414.         CK_SESSION_INFO sinfo;
  415.         CK_ATTRIBUTE_PTR pTemplate;
  416.         CK_ULONG tnObjects = 0;
  417.         ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
  418.         if( CKR_OK != ck_rv ) {
  419.           PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08xn", pSlots[i], ck_rv);
  420.           return 1;
  421.         }
  422.         PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08xn", h);
  423.         (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
  424.         ck_rv = epv->C_GetSessionInfo(h, &sinfo);
  425.         if( CKR_OK != ck_rv ) {
  426.           PR_fprintf(PR_STDOUT, "C_GetSessionInfo(%lu, ) returned 0x%08xn", h, ck_rv);
  427.           return 1;
  428.         }
  429.         PR_fprintf(PR_STDOUT, "    SESSION INFO:n");
  430.         PR_fprintf(PR_STDOUT, "        slotID = %lun", sinfo.slotID);
  431.         PR_fprintf(PR_STDOUT, "        state = %lun", sinfo.state);
  432.         PR_fprintf(PR_STDOUT, "        flags = 0x%08xn", sinfo.flags);
  433. #ifdef CKF_EXCLUSIVE_SESSION
  434.         PR_fprintf(PR_STDOUT, "            -> EXCLUSIVE SESSION = %sn", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
  435. #endif /* CKF_EXCLUSIVE_SESSION */
  436.         PR_fprintf(PR_STDOUT, "            -> RW SESSION = %sn", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE");
  437.         PR_fprintf(PR_STDOUT, "            -> SERIAL SESSION = %sn", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
  438. #ifdef CKF_INSERTION_CALLBACK
  439.         PR_fprintf(PR_STDOUT, "            -> INSERTION CALLBACK = %sn", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
  440. #endif /* CKF_INSERTION_CALLBACK */
  441.         PR_fprintf(PR_STDOUT, "        ulDeviceError = %lun", sinfo.ulDeviceError);
  442.         PR_fprintf(PR_STDOUT, "n");
  443.         ck_rv = epv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0);
  444.         if( CKR_OK != ck_rv ) {
  445.           PR_fprintf(PR_STDOUT, "C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08xn", h, ck_rv);
  446.           return 1;
  447.         }
  448.         pTemplate = (CK_ATTRIBUTE_PTR)PR_Calloc(number_of_all_known_attribute_types, sizeof(CK_ATTRIBUTE));
  449.         if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
  450.           PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]n", 
  451.                      number_of_all_known_attribute_types * sizeof(CK_ATTRIBUTE));
  452.           return 1;
  453.         }
  454.         PR_fprintf(PR_STDOUT, "    All objects:n");
  455.         while(1) {
  456.           CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
  457.           CK_ULONG nObjects = 0;
  458.           CK_ULONG k;
  459.           CK_ULONG nAttributes = 0;
  460.           CK_ATTRIBUTE_PTR pT2;
  461.           CK_ULONG l;
  462.           ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
  463.           if( CKR_OK != ck_rv ) {
  464.             PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08xn", h, ck_rv);
  465.             return 1;
  466.           }
  467.           if( 0 == nObjects ) {
  468.             PR_fprintf(PR_STDOUT, "n");
  469.             break;
  470.           }
  471.           tnObjects++;
  472.           PR_fprintf(PR_STDOUT, "        OBJECT HANDLE %lu:n", o);
  473.           for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
  474.             pTemplate[k].type = all_known_attribute_types[k];
  475.             pTemplate[k].pValue = (CK_VOID_PTR)CK_NULL_PTR;
  476.             pTemplate[k].ulValueLen = 0;
  477.           }
  478.           ck_rv = epv->C_GetAttributeValue(h, o, pTemplate, number_of_all_known_attribute_types);
  479.           switch( ck_rv ) {
  480.           case CKR_OK:
  481.           case CKR_ATTRIBUTE_SENSITIVE:
  482.           case CKR_ATTRIBUTE_TYPE_INVALID:
  483.           case CKR_BUFFER_TOO_SMALL:
  484.             break;
  485.           default:
  486.             PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {all attribute types}, %lu) returned 0x%08xn",
  487.                        h, o, number_of_all_known_attribute_types, ck_rv);
  488.             return 1;
  489.           }
  490.           for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
  491.             if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
  492.               nAttributes++;
  493.             }
  494.           }
  495.           if( 1 ) {
  496.             PR_fprintf(PR_STDOUT, "            %lu attributes:n", nAttributes);
  497.             for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
  498.               if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
  499.                 PR_fprintf(PR_STDOUT, "                0x%08x (len = %lu)n", pTemplate[k].type, 
  500.                            pTemplate[k].ulValueLen);
  501.               }
  502.             }
  503.             PR_fprintf(PR_STDOUT, "n");
  504.           }
  505.           pT2 = (CK_ATTRIBUTE_PTR)PR_Calloc(nAttributes, sizeof(CK_ATTRIBUTE));
  506.           if( (CK_ATTRIBUTE_PTR)NULL == pT2 ) {
  507.             PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]n", 
  508.                        nAttributes * sizeof(CK_ATTRIBUTE));
  509.             return 1;
  510.           }
  511.           for( l = 0, k = 0; k < number_of_all_known_attribute_types; k++ ) {
  512.             if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
  513.               pT2[l].type = pTemplate[k].type;
  514.               pT2[l].ulValueLen = pTemplate[k].ulValueLen;
  515.               pT2[l].pValue = (CK_VOID_PTR)PR_Malloc(pT2[l].ulValueLen);
  516.               if( (CK_VOID_PTR)NULL == pT2[l].pValue ) {
  517.                 PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]n", pT2[l].ulValueLen);
  518.                 return 1;
  519.               }
  520.               l++;
  521.             }
  522.           }
  523.           PR_ASSERT( l == nAttributes );
  524.           ck_rv = epv->C_GetAttributeValue(h, o, pT2, nAttributes);
  525.           switch( ck_rv ) {
  526.           case CKR_OK:
  527.           case CKR_ATTRIBUTE_SENSITIVE:
  528.           case CKR_ATTRIBUTE_TYPE_INVALID:
  529.           case CKR_BUFFER_TOO_SMALL:
  530.             break;
  531.           default:
  532.             PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {existant attribute types}, %lu) returned 0x%08xn",
  533.                        h, o, nAttributes, ck_rv);
  534.             return 1;
  535.           }
  536.           for( l = 0; l < nAttributes; l++ ) {
  537.             PR_fprintf(PR_STDOUT, "            type = 0x%08x, len = %ld", pT2[l].type, (CK_LONG)pT2[l].ulValueLen);
  538.             if( -1 == (CK_LONG)pT2[l].ulValueLen ) {
  539.               ;
  540.             } else {
  541.               CK_ULONG m;
  542.               if( pT2[l].ulValueLen <= 8 ) {
  543.                 PR_fprintf(PR_STDOUT, ", value = ");
  544.               } else {
  545.                 PR_fprintf(PR_STDOUT, ", value = n                ");
  546.               }
  547.               for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
  548.                 PR_fprintf(PR_STDOUT, "%02x", (CK_ULONG)(0xff & ((CK_CHAR_PTR)pT2[l].pValue)[m]));
  549.               }
  550.               PR_fprintf(PR_STDOUT, " ");
  551.               for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
  552.                 CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
  553.                 if( (c < 0x20) || (c >= 0x7f) ) {
  554.                   c = '.';
  555.                 }
  556.                 PR_fprintf(PR_STDOUT, "%c", c);
  557.               }
  558.             }
  559.             PR_fprintf(PR_STDOUT, "n");
  560.           }
  561.           
  562.           PR_fprintf(PR_STDOUT, "n");
  563.           for( l = 0; l < nAttributes; l++ ) {
  564.             PR_Free(pT2[l].pValue);
  565.           }
  566.           PR_Free(pT2);
  567.         } /* while(1) */
  568.         ck_rv = epv->C_FindObjectsFinal(h);
  569.         if( CKR_OK != ck_rv ) {
  570.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  571.           return 1;
  572.         }
  573.         PR_fprintf(PR_STDOUT, "    (%lu objects total)n", tnObjects);
  574.         ck_rv = epv->C_CloseSession(h);
  575.         if( CKR_OK != ck_rv ) {
  576.           PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08xn", h, ck_rv);
  577.           return 1;
  578.         }
  579.       } /* session to find objects */
  580.       /* session to create, find, and delete a couple session objects */
  581.       {
  582.         CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
  583.         CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
  584.         CK_OBJECT_CLASS cko_data = CKO_DATA;
  585.         CK_BBOOL false = CK_FALSE, true = CK_TRUE;
  586.         char *key = "TEST PROGRAM";
  587.         CK_ULONG key_len = strlen(key);
  588.         CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0, hTwoIn = (CK_OBJECT_HANDLE)0, 
  589.           hThreeIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
  590.         CK_OBJECT_HANDLE found[10];
  591.         CK_ULONG nFound;
  592.         ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
  593.         if( CKR_OK != ck_rv ) {
  594.           PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08xn", pSlots[i], ck_rv);
  595.           return 1;
  596.         }
  597.         PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08xn", h);
  598.         one[0].type = CKA_CLASS;
  599.         one[0].pValue = &cko_data;
  600.         one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  601.         one[1].type = CKA_TOKEN;
  602.         one[1].pValue = &false;
  603.         one[1].ulValueLen = sizeof(CK_BBOOL);
  604.         one[2].type = CKA_PRIVATE;
  605.         one[2].pValue = &false;
  606.         one[2].ulValueLen = sizeof(CK_BBOOL);
  607.         one[3].type = CKA_MODIFIABLE;
  608.         one[3].pValue = &true;
  609.         one[3].ulValueLen = sizeof(CK_BBOOL);
  610.         one[4].type = CKA_LABEL;
  611.         one[4].pValue = "Test data object one";
  612.         one[4].ulValueLen = strlen(one[4].pValue);
  613.         one[5].type = CKA_APPLICATION;
  614.         one[5].pValue = key;
  615.         one[5].ulValueLen = key_len;
  616.         one[6].type = CKA_VALUE;
  617.         one[6].pValue = "Object one";
  618.         one[6].ulValueLen = strlen(one[6].pValue);
  619.         two[0].type = CKA_CLASS;
  620.         two[0].pValue = &cko_data;
  621.         two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  622.         two[1].type = CKA_TOKEN;
  623.         two[1].pValue = &false;
  624.         two[1].ulValueLen = sizeof(CK_BBOOL);
  625.         two[2].type = CKA_PRIVATE;
  626.         two[2].pValue = &false;
  627.         two[2].ulValueLen = sizeof(CK_BBOOL);
  628.         two[3].type = CKA_MODIFIABLE;
  629.         two[3].pValue = &true;
  630.         two[3].ulValueLen = sizeof(CK_BBOOL);
  631.         two[4].type = CKA_LABEL;
  632.         two[4].pValue = "Test data object two";
  633.         two[4].ulValueLen = strlen(two[4].pValue);
  634.         two[5].type = CKA_APPLICATION;
  635.         two[5].pValue = key;
  636.         two[5].ulValueLen = key_len;
  637.         two[6].type = CKA_VALUE;
  638.         two[6].pValue = "Object two";
  639.         two[6].ulValueLen = strlen(two[6].pValue);
  640.         three[0].type = CKA_CLASS;
  641.         three[0].pValue = &cko_data;
  642.         three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  643.         three[1].type = CKA_TOKEN;
  644.         three[1].pValue = &false;
  645.         three[1].ulValueLen = sizeof(CK_BBOOL);
  646.         three[2].type = CKA_PRIVATE;
  647.         three[2].pValue = &false;
  648.         three[2].ulValueLen = sizeof(CK_BBOOL);
  649.         three[3].type = CKA_MODIFIABLE;
  650.         three[3].pValue = &true;
  651.         three[3].ulValueLen = sizeof(CK_BBOOL);
  652.         three[4].type = CKA_LABEL;
  653.         three[4].pValue = "Test data object three";
  654.         three[4].ulValueLen = strlen(three[4].pValue);
  655.         three[5].type = CKA_APPLICATION;
  656.         three[5].pValue = key;
  657.         three[5].ulValueLen = key_len;
  658.         three[6].type = CKA_VALUE;
  659.         three[6].pValue = "Object three";
  660.         three[6].ulValueLen = strlen(three[6].pValue);
  661.         ck_rv = epv->C_CreateObject(h, one, 7, &hOneIn);
  662.         if( CKR_OK != ck_rv ) {
  663.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, one, 7, ) returned 0x%08xn", h, ck_rv);
  664.           return 1;
  665.         }
  666.         PR_fprintf(PR_STDOUT, "    Created object one: handle = %lun", hOneIn);
  667.         ck_rv = epv->C_CreateObject(h, two, 7, &hTwoIn);
  668.         if( CKR_OK != ck_rv ) {
  669.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, two, 7, ) returned 0x%08xn", h, ck_rv);
  670.           return 1;
  671.         }
  672.         PR_fprintf(PR_STDOUT, "    Created object two: handle = %lun", hTwoIn);
  673.         ck_rv = epv->C_CreateObject(h, three, 7, &hThreeIn);
  674.         if( CKR_OK != ck_rv ) {
  675.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, three, 7, ) returned 0x%08xn", h, ck_rv);
  676.           return 1;
  677.         }
  678.         PR_fprintf(PR_STDOUT, "    Created object three: handle = %lun", hThreeIn);
  679.         delta[0].type = CKA_VALUE;
  680.         delta[0].pValue = "Copied object";
  681.         delta[0].ulValueLen = strlen(delta[0].pValue);
  682.         ck_rv = epv->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
  683.         if( CKR_OK != ck_rv ) {
  684.           PR_fprintf(PR_STDERR, "C_CopyObject(%lu, %lu, delta, 1, ) returned 0x%08xn", 
  685.                      h, hThreeIn, ck_rv);
  686.           return 1;
  687.         }
  688.         PR_fprintf(PR_STDOUT, "    Copied object three: new handle = %lun", hDeltaIn);
  689.         mask[0].type = CKA_APPLICATION;
  690.         mask[0].pValue = key;
  691.         mask[0].ulValueLen = key_len;
  692.         ck_rv = epv->C_FindObjectsInit(h, mask, 1);
  693.         if( CKR_OK != ck_rv ) {
  694.           PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08xn", 
  695.                      h, ck_rv);
  696.           return 1;
  697.         }
  698.         (void)memset(&found, 0, sizeof(found));
  699.         nFound = 0;
  700.         ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
  701.         if( CKR_OK != ck_rv ) {
  702.           PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08xn", 
  703.                      h, ck_rv);
  704.           return 1;
  705.         }
  706.         if( 4 != nFound ) {
  707.           PR_fprintf(PR_STDERR, "Found %lu objects, not 4.n", nFound);
  708.           return 1;
  709.         }
  710.         PR_fprintf(PR_STDOUT, "    Found 4 objects: %lu, %lu, %lu, %lun", 
  711.                    found[0], found[1], found[2], found[3]);
  712.         ck_rv = epv->C_FindObjectsFinal(h);
  713.         if( CKR_OK != ck_rv ) {
  714.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  715.           return 1;
  716.         }
  717.         ck_rv = epv->C_DestroyObject(h, hThreeIn);
  718.         if( CKR_OK != ck_rv ) {
  719.           PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08xn", h, hThreeIn, ck_rv);
  720.           return 1;
  721.         }
  722.         PR_fprintf(PR_STDOUT, "    Destroyed object three (handle = %lu)n", hThreeIn);
  723.         delta[0].type = CKA_APPLICATION;
  724.         delta[0].pValue = "Changed application";
  725.         delta[0].ulValueLen = strlen(delta[0].pValue);
  726.         ck_rv = epv->C_SetAttributeValue(h, hTwoIn, delta, 1);
  727.         if( CKR_OK != ck_rv ) {
  728.           PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08xn", 
  729.                      h, hTwoIn, ck_rv);
  730.           return 1;
  731.         }
  732.         PR_fprintf(PR_STDOUT, "    Changed object two (handle = %lu).n", hTwoIn);
  733.         /* Can another session find these session objects? */
  734.         {
  735.           CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;
  736.           ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h2);
  737.           if( CKR_OK != ck_rv ) {
  738.             PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08xn", pSlots[i], ck_rv);
  739.             return 1;
  740.           }
  741.           PR_fprintf(PR_STDOUT, "    Opened a second session: handle = 0x%08xn", h2);
  742.           /* mask is still the same */
  743.           ck_rv = epv->C_FindObjectsInit(h2, mask, 1);
  744.           if( CKR_OK != ck_rv ) {
  745.             PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08xn", 
  746.                        h2, ck_rv);
  747.             return 1;
  748.           }
  749.           (void)memset(&found, 0, sizeof(found));
  750.           nFound = 0;
  751.           ck_rv = epv->C_FindObjects(h2, found, 10, &nFound);
  752.           if( CKR_OK != ck_rv ) {
  753.             PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08xn", 
  754.                        h2, ck_rv);
  755.             return 1;
  756.           }
  757.           if( 2 != nFound ) {
  758.             PR_fprintf(PR_STDERR, "Found %lu objects, not 2.n", nFound);
  759.             return 1;
  760.           }
  761.           PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lun", 
  762.                      found[0], found[1]);
  763.           ck_rv = epv->C_FindObjectsFinal(h2);
  764.           if( CKR_OK != ck_rv ) {
  765.             PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h2, ck_rv);
  766.             return 1;
  767.           }
  768.           /* Leave the session hanging open, we'll CloseAllSessions later */
  769.         } /* Can another session find these session objects? */
  770.         ck_rv = epv->C_CloseAllSessions(pSlots[i]);
  771.         if( CKR_OK != ck_rv ) {
  772.           PR_fprintf(PR_STDERR, "C_CloseAllSessions(%lu) returned 0x%08xn", pSlots[i], ck_rv);
  773.           return 1;
  774.         }
  775.       } /* session to create, find, and delete a couple session objects */
  776.       /* Might be interesting to do a find here to verify that all session objects are gone. */
  777.       if( tinfo.flags & CKF_WRITE_PROTECTED ) {
  778.         PR_fprintf(PR_STDOUT, "Token is write protected, skipping token-object tests.n");
  779.       } else {
  780.         CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
  781.         CK_ATTRIBUTE tobj[7], tsobj[7], stobj[7], delta[1], mask[2];
  782.         CK_OBJECT_CLASS cko_data = CKO_DATA;
  783.         CK_BBOOL false = CK_FALSE, true = CK_TRUE;
  784.         char *key = "TEST PROGRAM";
  785.         CK_ULONG key_len = strlen(key);
  786.         CK_OBJECT_HANDLE hTIn = (CK_OBJECT_HANDLE)0, hTSIn = (CK_OBJECT_HANDLE)0, 
  787.           hSTIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
  788.         CK_OBJECT_HANDLE found[10];
  789.         CK_ULONG nFound;
  790.         ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
  791.         if( CKR_OK != ck_rv ) {
  792.           PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08xn", pSlots[i], ck_rv);
  793.           return 1;
  794.         }
  795.         PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08xn", h);
  796.         tobj[0].type = CKA_CLASS;
  797.         tobj[0].pValue = &cko_data;
  798.         tobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  799.         tobj[1].type = CKA_TOKEN;
  800.         tobj[1].pValue = &true;
  801.         tobj[1].ulValueLen = sizeof(CK_BBOOL);
  802.         tobj[2].type = CKA_PRIVATE;
  803.         tobj[2].pValue = &false;
  804.         tobj[2].ulValueLen = sizeof(CK_BBOOL);
  805.         tobj[3].type = CKA_MODIFIABLE;
  806.         tobj[3].pValue = &true;
  807.         tobj[3].ulValueLen = sizeof(CK_BBOOL);
  808.         tobj[4].type = CKA_LABEL;
  809.         tobj[4].pValue = "Test data object token";
  810.         tobj[4].ulValueLen = strlen(tobj[4].pValue);
  811.         tobj[5].type = CKA_APPLICATION;
  812.         tobj[5].pValue = key;
  813.         tobj[5].ulValueLen = key_len;
  814.         tobj[6].type = CKA_VALUE;
  815.         tobj[6].pValue = "Object token";
  816.         tobj[6].ulValueLen = strlen(tobj[6].pValue);
  817.         tsobj[0].type = CKA_CLASS;
  818.         tsobj[0].pValue = &cko_data;
  819.         tsobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  820.         tsobj[1].type = CKA_TOKEN;
  821.         tsobj[1].pValue = &true;
  822.         tsobj[1].ulValueLen = sizeof(CK_BBOOL);
  823.         tsobj[2].type = CKA_PRIVATE;
  824.         tsobj[2].pValue = &false;
  825.         tsobj[2].ulValueLen = sizeof(CK_BBOOL);
  826.         tsobj[3].type = CKA_MODIFIABLE;
  827.         tsobj[3].pValue = &true;
  828.         tsobj[3].ulValueLen = sizeof(CK_BBOOL);
  829.         tsobj[4].type = CKA_LABEL;
  830.         tsobj[4].pValue = "Test data object token->session";
  831.         tsobj[4].ulValueLen = strlen(tsobj[4].pValue);
  832.         tsobj[5].type = CKA_APPLICATION;
  833.         tsobj[5].pValue = key;
  834.         tsobj[5].ulValueLen = key_len;
  835.         tsobj[6].type = CKA_VALUE;
  836.         tsobj[6].pValue = "Object token->session";
  837.         tsobj[6].ulValueLen = strlen(tsobj[6].pValue);
  838.         stobj[0].type = CKA_CLASS;
  839.         stobj[0].pValue = &cko_data;
  840.         stobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  841.         stobj[1].type = CKA_TOKEN;
  842.         stobj[1].pValue = &false;
  843.         stobj[1].ulValueLen = sizeof(CK_BBOOL);
  844.         stobj[2].type = CKA_PRIVATE;
  845.         stobj[2].pValue = &false;
  846.         stobj[2].ulValueLen = sizeof(CK_BBOOL);
  847.         stobj[3].type = CKA_MODIFIABLE;
  848.         stobj[3].pValue = &true;
  849.         stobj[3].ulValueLen = sizeof(CK_BBOOL);
  850.         stobj[4].type = CKA_LABEL;
  851.         stobj[4].pValue = "Test data object session->token";
  852.         stobj[4].ulValueLen = strlen(stobj[4].pValue);
  853.         stobj[5].type = CKA_APPLICATION;
  854.         stobj[5].pValue = key;
  855.         stobj[5].ulValueLen = key_len;
  856.         stobj[6].type = CKA_VALUE;
  857.         stobj[6].pValue = "Object session->token";
  858.         stobj[6].ulValueLen = strlen(stobj[6].pValue);
  859.         ck_rv = epv->C_CreateObject(h, tobj, 7, &hTIn);
  860.         if( CKR_OK != ck_rv ) {
  861.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08xn", h, ck_rv);
  862.           return 1;
  863.         }
  864.         PR_fprintf(PR_STDOUT, "    Created object token: handle = %lun", hTIn);
  865.         ck_rv = epv->C_CreateObject(h, tsobj, 7, &hTSIn);
  866.         if( CKR_OK != ck_rv ) {
  867.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08xn", h, ck_rv);
  868.           return 1;
  869.         }
  870.         PR_fprintf(PR_STDOUT, "    Created object token->session: handle = %lun", hTSIn);
  871.         ck_rv = epv->C_CreateObject(h, stobj, 7, &hSTIn);
  872.         if( CKR_OK != ck_rv ) {
  873.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08xn", h, ck_rv);
  874.           return 1;
  875.         }
  876.         PR_fprintf(PR_STDOUT, "    Created object session->token: handle = %lun", hSTIn);
  877.         /* I've created two token objects and one session object; find the two */
  878.         mask[0].type = CKA_APPLICATION;
  879.         mask[0].pValue = key;
  880.         mask[0].ulValueLen = key_len;
  881.         mask[1].type = CKA_TOKEN;
  882.         mask[1].pValue = &true;
  883.         mask[1].ulValueLen = sizeof(CK_BBOOL);
  884.         ck_rv = epv->C_FindObjectsInit(h, mask, 2);
  885.         if( CKR_OK != ck_rv ) {
  886.           PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08xn", 
  887.                      h, ck_rv);
  888.           return 1;
  889.         }
  890.         (void)memset(&found, 0, sizeof(found));
  891.         nFound = 0;
  892.         ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
  893.         if( CKR_OK != ck_rv ) {
  894.           PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08xn", 
  895.                      h, ck_rv);
  896.           return 1;
  897.         }
  898.         if( 2 != nFound ) {
  899.           PR_fprintf(PR_STDERR, "Found %lu objects, not 2.n", nFound);
  900.           return 1;
  901.         }
  902.         PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lun", 
  903.                    found[0], found[1]);
  904.         ck_rv = epv->C_FindObjectsFinal(h);
  905.         if( CKR_OK != ck_rv ) {
  906.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  907.           return 1;
  908.         }
  909.         /* Convert a token to session object */
  910.         delta[0].type = CKA_TOKEN;
  911.         delta[0].pValue = &false;
  912.         delta[0].ulValueLen = sizeof(CK_BBOOL);
  913.         ck_rv = epv->C_SetAttributeValue(h, hTSIn, delta, 1);
  914.         if( CKR_OK != ck_rv ) {
  915.           PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08xn", 
  916.                      h, hTSIn, ck_rv);
  917.           return 1;
  918.         }
  919.         PR_fprintf(PR_STDOUT, "    Changed object from token to session (handle = %lu).n", hTSIn);
  920.         /* Now find again; there should be one */
  921.         mask[0].type = CKA_APPLICATION;
  922.         mask[0].pValue = key;
  923.         mask[0].ulValueLen = key_len;
  924.         mask[1].type = CKA_TOKEN;
  925.         mask[1].pValue = &true;
  926.         mask[1].ulValueLen = sizeof(CK_BBOOL);
  927.         ck_rv = epv->C_FindObjectsInit(h, mask, 2);
  928.         if( CKR_OK != ck_rv ) {
  929.           PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08xn", 
  930.                      h, ck_rv);
  931.           return 1;
  932.         }
  933.         (void)memset(&found, 0, sizeof(found));
  934.         nFound = 0;
  935.         ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
  936.         if( CKR_OK != ck_rv ) {
  937.           PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08xn", 
  938.                      h, ck_rv);
  939.           return 1;
  940.         }
  941.         if( 1 != nFound ) {
  942.           PR_fprintf(PR_STDERR, "Found %lu objects, not 1.n", nFound);
  943.           return 1;
  944.         }
  945.         PR_fprintf(PR_STDOUT, "    Found 1 objects: %lun", 
  946.                    found[0]);
  947.         ck_rv = epv->C_FindObjectsFinal(h);
  948.         if( CKR_OK != ck_rv ) {
  949.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  950.           return 1;
  951.         }
  952.         /* Convert a session to a token object */
  953.         delta[0].type = CKA_TOKEN;
  954.         delta[0].pValue = &true;
  955.         delta[0].ulValueLen = sizeof(CK_BBOOL);
  956.         ck_rv = epv->C_SetAttributeValue(h, hSTIn, delta, 1);
  957.         if( CKR_OK != ck_rv ) {
  958.           PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08xn", 
  959.                      h, hSTIn, ck_rv);
  960.           return 1;
  961.         }
  962.         PR_fprintf(PR_STDOUT, "    Changed object from session to token (handle = %lu).n", hSTIn);
  963.         /* Now find again; there should be two again */
  964.         mask[0].type = CKA_APPLICATION;
  965.         mask[0].pValue = key;
  966.         mask[0].ulValueLen = key_len;
  967.         mask[1].type = CKA_TOKEN;
  968.         mask[1].pValue = &true;
  969.         mask[1].ulValueLen = sizeof(CK_BBOOL);
  970.         ck_rv = epv->C_FindObjectsInit(h, mask, 2);
  971.         if( CKR_OK != ck_rv ) {
  972.           PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08xn", 
  973.                      h, ck_rv);
  974.           return 1;
  975.         }
  976.         (void)memset(&found, 0, sizeof(found));
  977.         nFound = 0;
  978.         ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
  979.         if( CKR_OK != ck_rv ) {
  980.           PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08xn", 
  981.                      h, ck_rv);
  982.           return 1;
  983.         }
  984.         if( 2 != nFound ) {
  985.           PR_fprintf(PR_STDERR, "Found %lu objects, not 2.n", nFound);
  986.           return 1;
  987.         }
  988.         PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lun", 
  989.                    found[0], found[1]);
  990.         ck_rv = epv->C_FindObjectsFinal(h);
  991.         if( CKR_OK != ck_rv ) {
  992.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  993.           return 1;
  994.         }
  995.         /* Delete the two (found) token objects to clean up */
  996.         ck_rv = epv->C_DestroyObject(h, found[0]);
  997.         if( CKR_OK != ck_rv ) {
  998.           PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08xn", h, found[0], ck_rv);
  999.           return 1;
  1000.         }
  1001.         PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)n", found[0]);
  1002.         ck_rv = epv->C_DestroyObject(h, found[1]);
  1003.         if( CKR_OK != ck_rv ) {
  1004.           PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08xn", h, found[1], ck_rv);
  1005.           return 1;
  1006.         }
  1007.         PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)n", found[1]);
  1008.         
  1009.         /* Close the session and all objects should be gone */
  1010.         ck_rv = epv->C_CloseSession(h);
  1011.         if( CKR_OK != ck_rv ) {
  1012.           PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08xn", h, ck_rv);
  1013.           return 1;
  1014.         }
  1015.       } /* if( tinfo.flags & CKF_WRITE_PROTECTED ) */
  1016.       if( tinfo.flags & CKF_WRITE_PROTECTED ) {
  1017.         PR_fprintf(PR_STDOUT, "Token is write protected, skipping leaving a record.n");
  1018.       } else {
  1019.         CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
  1020.         CK_ATTRIBUTE record[7], mask[2];
  1021.         CK_OBJECT_CLASS cko_data = CKO_DATA;
  1022.         CK_BBOOL false = CK_FALSE, true = CK_TRUE;
  1023.         char *key = "TEST RECORD";
  1024.         CK_ULONG key_len = strlen(key);
  1025.         CK_OBJECT_HANDLE hin = (CK_OBJECT_HANDLE)0;
  1026.         char timebuffer[256];
  1027.         ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
  1028.         if( CKR_OK != ck_rv ) {
  1029.           PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08xn", pSlots[i], ck_rv);
  1030.           return 1;
  1031.         }
  1032.         PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08xn", h);
  1033.         /* I can't believe how hard NSPR makes this operation */
  1034.         {
  1035.           time_t now = 0;
  1036.           struct tm *tm;
  1037.           time(&now);
  1038.           tm = localtime(&now);
  1039.           strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %T %Z", tm);
  1040.         }
  1041.         record[0].type = CKA_CLASS;
  1042.         record[0].pValue = &cko_data;
  1043.         record[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  1044.         record[1].type = CKA_TOKEN;
  1045.         record[1].pValue = &true;
  1046.         record[1].ulValueLen = sizeof(CK_BBOOL);
  1047.         record[2].type = CKA_PRIVATE;
  1048.         record[2].pValue = &false;
  1049.         record[2].ulValueLen = sizeof(CK_BBOOL);
  1050.         record[3].type = CKA_MODIFIABLE;
  1051.         record[3].pValue = &true;
  1052.         record[3].ulValueLen = sizeof(CK_BBOOL);
  1053.         record[4].type = CKA_LABEL;
  1054.         record[4].pValue = "Test record";
  1055.         record[4].ulValueLen = strlen(record[4].pValue);
  1056.         record[5].type = CKA_APPLICATION;
  1057.         record[5].pValue = key;
  1058.         record[5].ulValueLen = key_len;
  1059.         record[6].type = CKA_VALUE;
  1060.         record[6].pValue = timebuffer;
  1061.         record[6].ulValueLen = strlen(timebuffer)+1;
  1062.         PR_fprintf(PR_STDOUT, "    Timestamping with "%s"n", timebuffer);
  1063.         ck_rv = epv->C_CreateObject(h, record, 7, &hin);
  1064.         if( CKR_OK != ck_rv ) {
  1065.           PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08xn", h, ck_rv);
  1066.           return 1;
  1067.         }
  1068.         PR_fprintf(PR_STDOUT, "    Created record object: handle = %lun", hin);
  1069.         
  1070.         PR_fprintf(PR_STDOUT, "   == All test timestamps ==n");
  1071.         mask[0].type = CKA_CLASS;
  1072.         mask[0].pValue = &cko_data;
  1073.         mask[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
  1074.         mask[1].type = CKA_APPLICATION;
  1075.         mask[1].pValue = key;
  1076.         mask[1].ulValueLen = key_len;
  1077.         ck_rv = epv->C_FindObjectsInit(h, mask, 2);
  1078.         if( CKR_OK != ck_rv ) {
  1079.           PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08xn", 
  1080.                      h, ck_rv);
  1081.           return 1;
  1082.         }
  1083.         while( 1 ) {
  1084.           CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
  1085.           CK_ULONG nObjects = 0;
  1086.           CK_ATTRIBUTE value[1];
  1087.           char buffer[1024];
  1088.           ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
  1089.           if( CKR_OK != ck_rv ) {
  1090.             PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08xn", h, ck_rv);
  1091.             return 1;
  1092.           }
  1093.           if( 0 == nObjects ) {
  1094.             PR_fprintf(PR_STDOUT, "n");
  1095.             break;
  1096.           }
  1097.           value[0].type = CKA_VALUE;
  1098.           value[0].pValue = buffer;
  1099.           value[0].ulValueLen = sizeof(buffer);
  1100.           ck_rv = epv->C_GetAttributeValue(h, o, value, 1);
  1101.           switch( ck_rv ) {
  1102.           case CKR_OK:
  1103.             PR_fprintf(PR_STDOUT, "    %sn", value[0].pValue);
  1104.             break;
  1105.           case CKR_ATTRIBUTE_SENSITIVE:
  1106.             PR_fprintf(PR_STDOUT, "    [Sensitive???]n");
  1107.             break;
  1108.           case CKR_ATTRIBUTE_TYPE_INVALID:
  1109.             PR_fprintf(PR_STDOUT, "    [Invalid attribute???]n");
  1110.             break;
  1111.           case CKR_BUFFER_TOO_SMALL:
  1112.             PR_fprintf(PR_STDOUT, "    (result > 1k (%lu))n", value[0].ulValueLen);
  1113.             break;
  1114.           default:
  1115.             PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, CKA_VALUE, 1) returned 0x%08xn",
  1116.                        h, o);
  1117.             return 1;
  1118.           }
  1119.         } /* while */
  1120.         ck_rv = epv->C_FindObjectsFinal(h);
  1121.         if( CKR_OK != ck_rv ) {
  1122.           PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08xn", h, ck_rv);
  1123.           return 1;
  1124.         }
  1125.       } /* "leaving a record" else clause */
  1126.     }
  1127.     PR_fprintf(PR_STDOUT, "n");
  1128.   }
  1129.   return 0;
  1130. }