Back to index

lightning-sunbird  0.9+nobinonly
pk11util.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 
00038 #include <stdio.h>
00039 #include <string.h>
00040 
00041 #if defined(WIN32)
00042 #undef __STDC__
00043 #include "fcntl.h"
00044 #include "io.h"
00045 #include <fcntl.h>
00046 #else
00047 #include <unistd.h>
00048 #include <sys/fcntl.h>
00049 #endif
00050 
00051 #include "secutil.h"
00052 
00053 
00054 #include "nspr.h"
00055 #include "prtypes.h"
00056 #include "prtime.h"
00057 #include "prlong.h"
00058 #include "prinrval.h"
00059 #include "prenv.h"
00060 
00061 #include "pkcs11.h"
00062 
00063 #include "pk11util.h"
00064 
00065 #ifndef O_BINARY
00066 #define O_BINARY 0
00067 #endif
00068 
00069 CK_ULONG systemFlags;
00070 #define FLAG_NEGATE 0x80000000
00071 #define FLAG_Verify 0x00000001
00072 #define FLAG_VerifyFile 0x00000002
00073 #define CKR_QUIT 0x80000000
00074 
00075 int ArgSize(ArgType type);
00076 const char *constLookup(const char *bp, CK_ULONG *value, ConstType *type);
00077 
00078 int
00079 isNum(char c)
00080 {
00081     return (c >= '0' && c <= '9');
00082 }
00083 
00084 int
00085 isConst(const char *c)
00086 {
00087     CK_ULONG value;
00088     ConstType type;
00089 
00090     constLookup(c, &value, &type);
00091     return type != ConstNone;
00092 }
00093 
00094 /*
00095  * see if the variable is really a 'size' function. This
00096  * function may modify var if it is a size function.
00097  */
00098 char *
00099 isSize(char *var, int *isArray)
00100 {
00101     char *ptr = NULL;
00102     char *end;
00103     int array = 0;
00104 
00105     if (PL_strncasecmp(var,"sizeof(",/*)*/ 7) == 0) {
00106        ptr = var + 7;
00107     } else if (PL_strncasecmp(var,"size(",/*)*/ 5) == 0) {
00108        ptr = var + 5;
00109     } else if (PL_strncasecmp(var,"sizeofarray(",/*)*/ 12) == 0) {
00110        ptr = var + 12;
00111        array = 1;
00112     } else if (PL_strncasecmp(var,"sizea(",/*)*/ 6) == 0) {
00113        ptr = var + 6;
00114        array = 1;
00115     } else {
00116        return NULL;
00117     }
00118     end = strchr(ptr,/*(*/ ')') ;
00119     if (end == NULL) {
00120        return NULL;
00121     }
00122     if (isArray) *isArray = array;
00123     *end = 0;
00124     return ptr;
00125 }
00126  
00127 void
00128 printConst(CK_ULONG value, ConstType type, int newLine)
00129 {
00130     int i;
00131 
00132     for (i=0; i < constCount; i++) {
00133        if (consts[i].type == type && consts[i].value == value) {
00134            printf("%s",consts[i].name);
00135            break;
00136        }
00137        if (type == ConstNone && consts[i].value == value) {
00138            printf("%s",consts[i].name);
00139            break;
00140        }
00141     }
00142     if (i == constCount) {
00143        if ((type == ConstAvailableSizes) || (type == ConstCurrentSize)) {
00144            printf("%lu",value);
00145        } else {
00146            printf("Unknown %s (%lu:0x%lx)",constTypeString[type],value,value);
00147        }
00148     }
00149     if (newLine) {
00150        printf("\n");
00151     }
00152 }
00153 
00154 ConstType
00155 getConstFromAttribute(CK_ATTRIBUTE_TYPE type)
00156 {
00157     int i;
00158 
00159     for (i=0; i < constCount; i++) {
00160        if (consts[i].type == ConstAttribute && consts[i].value == type) {
00161            return consts[i].attrType;
00162        }
00163     }
00164     return ConstNone;
00165 }
00166 
00167 void
00168 printChars(const char *name, CK_ULONG size)
00169 {
00170     CK_ULONG i;
00171     for (i=0; i < size; i++) {
00172        if (name[i] == 0) {
00173               break;
00174        }
00175        printf("%c",name[i]);
00176     }
00177     printf("\n");
00178 }
00179 
00180 #define DUMP_LEN 16
00181 void printDump(const unsigned char *buf, int size)
00182 {
00183     int i,j;
00184 
00185     for(i=0; i < size; i+= DUMP_LEN) {
00186        printf(" ");
00187        for (j=0; j< DUMP_LEN; j++) {
00188            if (i+j < size) {
00189               printf("%02x ",buf[i+j]);
00190            } else {
00191               printf("   ");
00192            }
00193        } 
00194        for (j=0; j< DUMP_LEN; j++) {
00195            if (i+j < size) {
00196               if (buf[i+j] < ' ' || buf[i+j] >= 0x7f) {
00197                   printf(".");
00198               } else {
00199                   printf("%c",buf[i+j]);
00200               }
00201            } else {
00202               printf(" ");
00203            }
00204        } 
00205        printf("\n");
00206     }
00207 }
00208 
00209 /*
00210  * free an argument structure
00211  */
00212 void
00213 argFreeData(Value *arg)
00214 {
00215     if (arg->data && ((arg->type & ArgStatic) == 0)) {
00216        if ((arg->type & ArgMask) == ArgAttribute) {
00217            int i;
00218            CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)arg->data;
00219 
00220            for (i=0; i < arg->arraySize; i++) {
00221               free(template[i].pValue);
00222            }
00223        }
00224        if ((arg->type & ArgMask) == ArgInitializeArgs) {
00225            CK_C_INITIALIZE_ARGS *init = (CK_C_INITIALIZE_ARGS *)arg->data;
00226             if (init->LibraryParameters) {
00227               free(init->LibraryParameters);
00228            }
00229        }
00230        free(arg->data);
00231     }
00232     arg->type &= ~ArgStatic;
00233     arg->data = NULL;
00234 }
00235 
00236 void
00237 argFree(Value *arg)
00238 {
00239     if (arg == NULL) return;
00240 
00241     arg->reference--;
00242     if (arg->reference == 0) {
00243        if (arg->type & ArgFile) {
00244            free(arg->filename);
00245        }
00246        argFreeData(arg);
00247        free (arg);
00248     }
00249 }
00250 
00251 /*
00252  * free and argument list
00253  */
00254 void
00255 parseFree(Value **ap)
00256 {
00257     int i;
00258     for (i=0 ; i < MAX_ARGS; i++) {
00259        argFree(ap[i]);
00260     }
00261 }
00262 
00263 /*
00264  * getEnd: how for to the end of this argmument list?
00265  */
00266 int
00267 getEnd(const char *bp)
00268 {
00269     int count = 0;
00270 
00271     while (*bp) {
00272         if (*bp == ' ' || *bp == '\t' || *bp == '\n') return count;
00273        count++;
00274        bp++;
00275     }
00276     return (count);
00277 }
00278 
00279 
00280 /*
00281  * strip: return the first none white space character
00282  */
00283 const char *
00284 strip(const char *bp)
00285 {
00286     while (*bp && (*bp == ' ' || *bp == '\t' || *bp == '\n')) bp++;
00287     return bp;
00288 }
00289 
00290 /*
00291  * read in the next argument into dp ... don't overflow
00292  */
00293 const char *
00294 readChars(const char *bp, char *dp, int max )
00295 {
00296     int count = 1;
00297     while (*bp) {
00298         if (*bp == ' ' || *bp == '\t' || *bp == '\n' ) {
00299            *dp = 0;
00300            return bp;
00301        }
00302        *dp++ = *bp++;
00303        if (++count == max) break;
00304     }
00305     while (*bp && (*bp != ' ' && *bp != '\t' && *bp != '\n')) bp++;
00306     *dp = 0;
00307     return (bp);
00308 }
00309 
00310 Value * varLookup(const char *bp, char *vname, int max, int *error);
00311 
00312 CK_ULONG
00313 getValue(const char *v, int *error)
00314 {
00315     Value * varVal = NULL;
00316     CK_ULONG retVal = 0;
00317     ConstType type;
00318     char tvar[512];
00319 
00320     *error = 0;
00321 
00322     varVal = varLookup( v, tvar, sizeof(tvar), error);
00323 
00324     if (varVal) {
00325        if ((varVal->type & ArgMask) == ArgULong) {
00326            retVal = *(CK_ULONG *)varVal->data;
00327        } else {
00328            fprintf(stderr,"%s: is not a ulong\n", v);
00329            *error = 1;
00330        }
00331        argFree(varVal);
00332        return retVal;
00333     }
00334     constLookup(v, &retVal, &type);
00335     return retVal;
00336 }
00337 
00338 Value *
00339 NewValue(ArgType type, CK_ULONG arraySize)
00340 {
00341     Value *value;
00342 
00343     value = (Value *)malloc(sizeof(Value));
00344     if (!value) return NULL;
00345     value->size = ArgSize(type)*arraySize;
00346     value->type = type;
00347     value->filename = NULL;
00348     value->constType = ConstNone;
00349     value->data = (void *)malloc(value->size);
00350     if (!value->data) {
00351        free(value);
00352        return NULL;
00353     }
00354     value->reference = 1;
00355     value->arraySize = (type == ArgChar) ? 1: arraySize;
00356 
00357     memset(value->data, 0, value->size);
00358     return value;
00359 }
00360 
00361 #define INVALID_INDEX 0xffffffff
00362 
00363 CK_ULONG
00364 handleArray(char *vname, int *error)
00365 {
00366     char *bracket;
00367     CK_ULONG index = INVALID_INDEX;
00368 
00369     if ((bracket = strchr(vname,'[')) != 0) {
00370        char *tmpv = bracket+1;
00371        *bracket = 0;
00372        bracket = strchr(tmpv,']');
00373 
00374        if (bracket == 0) {
00375            fprintf(stderr,"%s: missing closing brace\n", vname);
00376            return INVALID_INDEX;
00377        }
00378        *bracket = 0;
00379 
00380        index = getValue(tmpv, error);
00381        if (*error == 1) {
00382            return INVALID_INDEX;
00383        } else if (index == INVALID_INDEX) {
00384            fprintf(stderr, "%s: 0x%x is an invalid index\n",vname,index);
00385            *error = 1;
00386        }
00387     }
00388     return index;
00389 }
00390 
00391 void *
00392 makeArrayTarget(const char *vname, const Value *value, CK_ULONG index)
00393 {
00394     char * target;
00395     CK_ULONG elementSize;
00396 
00397     if (index >= (CK_ULONG)value->arraySize) {
00398        fprintf(stderr, "%s[%d]: index larger than array size (%d)\n",
00399               vname, index, value->arraySize);
00400        return NULL;
00401     }
00402 
00403     target = (char *)value->data;
00404     elementSize = value->size/value->arraySize;
00405     target += index * elementSize;
00406     return target;
00407 }
00408 
00409 /*
00410  * look up a variable from the variable chain
00411  */
00412 static Variable *varHead = NULL;
00413 Value *
00414 varLookup(const char *bp, char *vname, int max, int *error)
00415 {
00416     Variable *current;
00417     CK_ULONG index = INVALID_INDEX;
00418     int isArray = 0;
00419     char *ptr;
00420     *error = 0;
00421 
00422     if (bp != NULL) {
00423        readChars(bp, vname, max);
00424     } 
00425 
00426     /* don't make numbers into variables */
00427     if (isNum(vname[0])) {
00428        return NULL;
00429     }
00430     /* nor consts */
00431     if (isConst(vname)) {
00432        return NULL;
00433     }
00434     /* handle sizeof() */
00435     if ((ptr = isSize(vname, &isArray)) != NULL) {
00436        CK_ULONG size;
00437        Value  *targetValue = NULL;
00438        Value  *sourceValue = varLookup(NULL, ptr, 0, error);
00439        if (!sourceValue) {
00440           if (*error == 0) {
00441               /* just didn't find it */
00442               *error = 1;
00443               fprintf(stderr,"Couldn't find variable %s to take size of\n",
00444                      ptr);
00445               return NULL;
00446           }
00447        }
00448        size = isArray ? sourceValue->arraySize : sourceValue->size;
00449        targetValue = NewValue(ArgULong,1);
00450        memcpy(targetValue->data, &size, sizeof(size));
00451 
00452        return targetValue;
00453     }
00454 
00455     /* modifies vname */
00456     index = handleArray(vname, error);
00457     if (*error == 1) {
00458        return NULL;
00459     }
00460 
00461     for (current = varHead; current; current = current->next) {
00462        if (PL_strcasecmp(current->vname, vname) == 0) {
00463            char *target;
00464            if (index == INVALID_INDEX) {
00465               (current->value->reference)++;
00466               return current->value;
00467            }
00468            target = makeArrayTarget(vname, current->value, index);
00469            if (target) {
00470               Value *element = NewValue(current->value->type, 1);
00471               if (!element) {
00472                   fprintf(stderr, "MEMORY ERROR!\n");
00473                   *error = 1;
00474               }
00475               argFreeData(element);
00476               element->data = target;
00477               element->type |= ArgStatic;
00478               return element;
00479            }
00480            *error = 1;
00481            return NULL;
00482        }
00483     }
00484     return NULL;
00485 }
00486 
00487 static CK_RV 
00488 list(void)
00489 {
00490     Variable *current;
00491 
00492     if (varHead) {
00493        printf(" %10s\t%16s\t%8s\tSize\tElements\n","Name","Type","Const");
00494     } else {
00495        printf(" no variables set\n");
00496     }
00497 
00498     for (current = varHead; current; current = current->next) {
00499        printf(" %10s\t%16s\t%8s\t%d\t%d\n", current->vname,
00500            valueString[current->value->type&ArgMask],
00501            constTypeString[current->value->constType],
00502            current->value->size, current->value->arraySize);
00503     }
00504     return CKR_OK;
00505 }
00506 
00507 CK_RV
00508 printFlags(const char *s, CK_ULONG flags, ConstType type)
00509 {
00510     CK_ULONG i;
00511     int needComma = 0;
00512 
00513     printf("%s",s);
00514     for (i=1; i ; i=i << 1) {
00515        if (flags & i) {
00516           printf("%s",needComma?",":"");
00517           printConst(i, type, 0);
00518           needComma=1;
00519        }
00520     }
00521     if (!needComma) {
00522        printf("Empty");
00523     }
00524     printf("\n");
00525     return CKR_OK;
00526 }
00527 
00528 /*
00529  * add a new variable to the chain
00530  */
00531 const char *
00532 AddVariable(const char *bp, Value **ptr)
00533 {
00534     char vname[512];
00535     Variable *current;
00536     int index = INVALID_INDEX;
00537     int size;
00538     int error = 0;
00539 
00540     bp = readChars(bp,vname,sizeof(vname));
00541 
00542     /* don't make numbers into variables */
00543     if (isNum(vname[0])) {
00544        return bp;
00545     }
00546     /* or consts */
00547     if (isConst(vname)) {
00548        return bp;
00549     }
00550     /* or NULLs */
00551     if (vname[0] == 0) {
00552        return bp;
00553     }
00554     /* or sizeof */
00555     if (isSize(vname, NULL)) {
00556        return bp;
00557     }
00558     /* arrays values should be written back to the original */
00559     index = handleArray(vname, &error);
00560     if (error == 1) {
00561        return bp;
00562     }
00563 
00564 
00565     for (current = varHead; current; current = current->next) {
00566        if (PL_strcasecmp(current->vname,vname) == 0) {
00567            char *target;
00568            /* found a complete object, return the found one */
00569            if (index == INVALID_INDEX) {
00570               argFree(*ptr);
00571               *ptr = current->value;
00572               return bp;
00573            }
00574            /* found an array, update the array element */
00575            target = makeArrayTarget(vname, current->value, index);
00576            if (target) {
00577               memcpy(target, (*ptr)->data, (*ptr)->size);
00578               argFreeData(*ptr);
00579               (*ptr)->data = target;
00580               (*ptr)->type |= ArgStatic;
00581            }
00582            return bp;
00583        }
00584     }
00585 
00586     /* we are looking for an array and didn't find one */
00587     if (index != INVALID_INDEX) {
00588        return bp;
00589     }
00590 
00591 
00592     current = (Variable *)malloc(sizeof(Variable));
00593     size = strlen(vname);
00594     current->vname = (char *)malloc(size+1);
00595     strcpy(current->vname,vname);
00596     current->value = *ptr;
00597     (*ptr)->reference++;
00598 
00599     current->next = varHead;
00600     varHead = current;
00601     return bp;
00602 }
00603 
00604 ArgType
00605 FindTypeByName(const char *typeName)
00606 {
00607     int i;
00608 
00609     for (i=0; i < valueCount; i++) {
00610        if (PL_strcasecmp(typeName,valueString[i]) == 0) {
00611            return (ArgType) i;
00612        }
00613        if (valueString[i][0] == 'C' && valueString[i][1] == 'K' &&
00614           valueString[i][2] == '_' && 
00615                      (PL_strcasecmp(typeName,&valueString[i][3]) == 0)) {
00616            return (ArgType) i;
00617        }
00618     }
00619     return ArgNone;
00620 }
00621 
00622 CK_RV 
00623 ArrayVariable(const char *bp, const char *typeName, CK_ULONG count)
00624 {
00625     ArgType type;
00626     Value *value; /* new Value */
00627 
00628     type = FindTypeByName(typeName);
00629     if (type == ArgNone) {
00630        fprintf(stderr,"Invalid type (%s)\n", typeName);
00631        return CKR_FUNCTION_FAILED;
00632     }
00633     value = NewValue(type, count);
00634     (void) AddVariable(bp, &value);
00635     return CKR_OK;
00636 }
00637 
00638 #define MAX_TEMPLATE 25
00639 
00640 CK_RV 
00641 ArrayTemplate(const char *bp, char *attributes)
00642 {
00643     char aname[512];
00644     CK_ULONG attributeTypes[MAX_TEMPLATE];
00645     CK_ATTRIBUTE *template;
00646     Value *value; /* new Value */
00647     char *ap;
00648     int i, count = 0;
00649 
00650     memcpy(aname,attributes,strlen(attributes)+1);
00651 
00652     for (ap = aname, count = 0; ap && *ap && count < MAX_TEMPLATE; count++) {
00653        char *cur = ap;
00654        ConstType type;
00655 
00656        ap = strchr(ap,',');
00657        if (ap) {
00658            *ap++ = 0;
00659        }
00660 
00661        (void)constLookup(cur, &attributeTypes[count], &type);
00662        if ((type != ConstAttribute) && (type != ConstNone)) {
00663           fprintf(stderr, "Unknown Attribute %s\n", cur);
00664           return CKR_FUNCTION_FAILED;
00665        }
00666     }
00667 
00668     value = NewValue(ArgAttribute, count);
00669 
00670     template = (CK_ATTRIBUTE *)value->data;
00671     for (i=0; i < count ; i++) {
00672        template[i].type = attributeTypes[i];
00673     }
00674     (void) AddVariable(bp, &value);
00675     return CKR_OK;
00676 }
00677 
00678 CK_RV
00679 BuildTemplate(Value *vp)
00680 {
00681     CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
00682     int i;
00683 
00684     for (i=0; i < vp->arraySize; i++) {
00685        if (((signed long)template[i].ulValueLen) > 0) {
00686            if (template[i].pValue) free(template[i].pValue);
00687            template[i].pValue = malloc(template[i].ulValueLen);
00688        }
00689     }
00690     return CKR_OK;
00691 }
00692 
00693 CK_RV
00694 SetTemplate(Value *vp, CK_ULONG index, CK_ULONG value)
00695 {
00696     CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
00697     int isbool = 0;
00698     CK_ULONG len;
00699     ConstType attrType;
00700 
00701     if (index >= (CK_ULONG) vp->arraySize) {
00702        fprintf(stderr,"index (%lu) greater than array (%d)\n", 
00703                                           index, vp->arraySize);
00704        return CKR_ARGUMENTS_BAD;
00705     }
00706     attrType =  getConstFromAttribute(template[index].type);
00707 
00708     if (attrType == ConstNone) {
00709        fprintf(stderr,"can't set index (%lu) because ", index);
00710        printConst(template[index].type,ConstAttribute, 0);
00711        fprintf(stderr, " is not a CK_BBOOL or CK_ULONG\n");
00712        return CKR_ARGUMENTS_BAD;
00713     }
00714     isbool = (attrType == ConstBool);
00715     len = isbool ? sizeof (CK_BBOOL) : sizeof(CK_ULONG);
00716     if ((template[index].ulValueLen != len) || (template[index].pValue)) {
00717        free(template[index].pValue);
00718        template[index].pValue = malloc(len);
00719        template[index].ulValueLen = len;
00720     }
00721     if (isbool) {
00722        *(CK_BBOOL *)template[index].pValue = (CK_BBOOL) value;
00723     } else {
00724        *(CK_ULONG *)template[index].pValue = (CK_ULONG) value;
00725     }
00726     return CKR_OK;
00727 
00728 }
00729 
00730 CK_RV
00731 NewMechanism(const char *bp, CK_ULONG mechType)
00732 {
00733     Value *value; /* new Value */
00734     CK_MECHANISM *mechanism;
00735 
00736     value = NewValue(ArgMechanism, 1);
00737     mechanism = (CK_MECHANISM *)value->data;
00738     mechanism->mechanism = mechType;
00739     mechanism->pParameter = NULL;
00740     mechanism->ulParameterLen = 0;
00741     (void) AddVariable(bp, &value);
00742     return CKR_OK;
00743 }
00744 
00745 CK_RV
00746 NewInitializeArgs(const char *bp, CK_ULONG flags, const char *param)
00747 {
00748     Value *value; /* new Value */
00749     CK_C_INITIALIZE_ARGS *init;
00750 
00751     value = NewValue(ArgInitializeArgs, 1);
00752     init = (CK_C_INITIALIZE_ARGS *)value->data;
00753     init->flags = flags;
00754     if (strcmp(param, "null") != 0) {
00755         init->LibraryParameters = (CK_CHAR_PTR *)strdup(param);
00756     }
00757     (void) AddVariable(bp, &value);
00758     return CKR_OK;
00759 }
00760 
00761 /*
00762  * add a new variable to the chain
00763  */
00764 CK_RV
00765 DeleteVariable(const char *bp)
00766 {
00767     char vname[512];
00768     Variable **current;
00769 
00770     bp = readChars(bp,vname,sizeof(vname));
00771 
00772     for (current = &varHead; *current; current = &(*current)->next) {
00773        if (PL_strcasecmp((*current)->vname,vname) == 0) {
00774                argFree((*current)->value);
00775               *current = (*current)->next;
00776               break;
00777        }
00778     }
00779     return CKR_OK;
00780 }
00781 
00782 /*
00783  * convert an octal value to integer
00784  */   
00785 CK_ULONG
00786 otoi(const char *o)
00787 {
00788     CK_ULONG value = 0;
00789 
00790     while (*o) {
00791        if ((*o >= '0') && (*o <= '7')) {
00792            value = (value << 3) | (unsigned)(*o - '0');
00793        } else {
00794            break;
00795        }
00796     }
00797     return value;
00798 }
00799 
00800 /*
00801  * convert a hex value to integer
00802  */   
00803 CK_ULONG
00804 htoi(const char *x)
00805 {
00806     CK_ULONG value = 0;
00807 
00808     while (*x) {
00809        if ((*x >= '0') && (*x <= '9')) {
00810            value = (value << 4) | (unsigned)(*x - '0');
00811        } else if ((*x >= 'a') && (*x <= 'f')) {
00812            value = (value << 4) | (unsigned)(*x - 'a');
00813        } else if ((*x >= 'A') && (*x <= 'F')) {
00814            value = (value << 4) | (unsigned)(*x - 'A');
00815        } else {
00816            break;
00817        }
00818     }
00819     return value;
00820 }
00821 
00822 
00823 /*
00824  * look up or decode a constant value
00825  */
00826 const char *
00827 constLookup(const char *bp, CK_ULONG *value, ConstType *type)
00828 {
00829     char vname[512];
00830     int i;
00831 
00832     bp = readChars(bp,vname,sizeof(vname));
00833 
00834     for (i=0; i < constCount; i++) {
00835        if ((PL_strcasecmp(consts[i].name,vname) == 0) ||
00836               PL_strcasecmp(consts[i].name+5,vname) == 0) {
00837            *value = consts[i].value;
00838            *type = consts[i].type;
00839            return bp;
00840        }
00841     }
00842 
00843     *type = ConstNone;
00844     if (vname[0] == '0' && vname[1] == 'X') {
00845        *value = htoi(&vname[2]);
00846     } else if (vname[0] == '0') {
00847        *value = otoi(&vname[1]);
00848     } else {
00849        *value = atoi(vname);
00850     }
00851     return bp;
00852 }
00853 
00854 int
00855 ArgSize(ArgType type)
00856 {
00857        int size=0;
00858        type &= ArgMask;
00859 
00860        switch (type) {
00861        case ArgNone:
00862            size = 0;
00863            break;
00864        case ArgULong:
00865            size = sizeof(CK_ULONG);
00866            break;
00867        case ArgVar:
00868            size = 1; /* get's changed later */
00869            break;
00870        case ArgChar:
00871        case ArgUTF8:
00872            size = 1;
00873            break;
00874        case ArgInfo:
00875            size = sizeof(CK_INFO);
00876            break;
00877        case ArgSlotInfo:
00878            size = sizeof(CK_SLOT_INFO);
00879            break;
00880        case ArgTokenInfo:
00881            size = sizeof(CK_TOKEN_INFO);
00882            break;
00883        case ArgSessionInfo:
00884            size = sizeof(CK_SESSION_INFO);
00885            break;
00886        case ArgAttribute:
00887            size = sizeof(CK_ATTRIBUTE);
00888            break;
00889        case ArgMechanism:
00890            size = sizeof(CK_MECHANISM);
00891            break;
00892        case ArgMechanismInfo:
00893            size = sizeof(CK_MECHANISM_INFO);
00894            break;
00895        case ArgInitializeArgs:
00896            size = sizeof(CK_C_INITIALIZE_ARGS);
00897            break;
00898        case ArgFunctionList:
00899            size = sizeof(CK_FUNCTION_LIST);
00900            break;
00901        default:
00902            break;
00903        }
00904 
00905        return (size);
00906 }
00907 
00908 CK_RV
00909 restore(const char *filename,Value *ptr)
00910 {
00911     int fd,size;
00912 
00913     fd = open(filename,O_RDONLY|O_BINARY);
00914     if (fd < 0) {
00915        perror(filename);
00916        return CKR_FUNCTION_FAILED;
00917     }
00918 
00919     size = read(fd,ptr->data,ptr->size);
00920     if (systemFlags & FLAG_VerifyFile) {
00921        printDump(ptr->data,ptr->size);
00922     }
00923     if (size < 0) {
00924        perror(filename);
00925        return CKR_FUNCTION_FAILED;
00926     } else if (size != ptr->size) {
00927        fprintf(stderr,"%s: only read %d bytes, needed to read %d bytes\n",
00928                      filename,size,ptr->size);
00929        return CKR_FUNCTION_FAILED;
00930     }
00931     close(fd);
00932     return CKR_OK;
00933 }
00934 
00935 CK_RV
00936 save(const char *filename,Value *ptr)
00937 {
00938     int fd,size;
00939 
00940     fd = open(filename,O_WRONLY|O_BINARY|O_CREAT,0666);
00941     if (fd < 0) {
00942        perror(filename);
00943        return CKR_FUNCTION_FAILED;
00944     }
00945 
00946     size = write(fd,ptr->data,ptr->size);
00947     if (size < 0) {
00948        perror(filename);
00949        return CKR_FUNCTION_FAILED;
00950     } else if (size != ptr->size) {
00951        fprintf(stderr,"%s: only wrote %d bytes, need to write %d bytes\n",
00952                      filename,size,ptr->size);
00953        return CKR_FUNCTION_FAILED;
00954     }
00955     close(fd);
00956     return CKR_OK;
00957 }
00958 
00959 static CK_RV
00960 increment(Value *ptr, CK_ULONG value)
00961 {
00962     if ((ptr->type & ArgMask) != ArgULong) {
00963        return CKR_ARGUMENTS_BAD;
00964     }
00965     *(CK_ULONG *)ptr->data += value;
00966     return CKR_OK;
00967 }
00968 
00969 static CK_RV
00970 decrement(Value *ptr, CK_ULONG value)
00971 {
00972     if ((ptr->type & ArgMask) != ArgULong) {
00973        return CKR_ARGUMENTS_BAD;
00974     }
00975     *(CK_ULONG *)ptr->data -= value;
00976     return CKR_OK;
00977 }
00978 
00979 CK_RV
00980 printArg(Value *ptr,int arg_number)
00981 {
00982     ArgType type = ptr->type & ArgMask;
00983     CK_INFO *info;
00984     CK_SLOT_INFO    *slotInfo;
00985     CK_TOKEN_INFO   *tokenInfo;
00986     CK_SESSION_INFO *sessionInfo;
00987     CK_ATTRIBUTE    *attribute;
00988     CK_MECHANISM    *mechanism;
00989     CK_MECHANISM_INFO    *mechanismInfo;
00990     CK_C_INITIALIZE_ARGS *initArgs;
00991     CK_FUNCTION_LIST *functionList;
00992     CK_RV ckrv = CKR_OK;
00993     ConstType constType;
00994 
00995     if (arg_number) {
00996        printf("Arg %d: \n",arg_number);
00997     }
00998     if (ptr->arraySize > 1) {
00999        Value element;
01000        int i;
01001        int elementSize = ptr->size/ptr->arraySize;
01002        char *dp = (char *)ptr->data;
01003 
01004        /* build a temporary Value to hold a single element */
01005        element.type = type;
01006        element.constType = ptr->constType;
01007        element.size = elementSize;
01008        element.filename = ptr->filename;
01009        element.reference = 1;
01010        element.arraySize = 1;
01011        for (i=0; i < ptr->arraySize; i++) {
01012            printf(" -----[ %d ] -----\n", i);
01013            element.data = (void *) &dp[i*elementSize];
01014            (void) printArg(&element, 0);
01015        }
01016        return ckrv;
01017     }
01018     if (ptr->data == NULL) {
01019        printf(" NULL ptr to a %s\n", valueString[type]);
01020        return ckrv;
01021     }
01022     switch (type) {
01023     case ArgNone:
01024        printf(" None\n");
01025        break;
01026     case ArgULong:
01027        printf(" %lu (0x%lx)\n", *((CK_ULONG *)ptr->data),
01028                      *((CK_ULONG *)ptr->data));
01029        if (ptr->constType != ConstNone) {
01030            printf(" ");
01031            printConst(*(CK_ULONG *)ptr->data,ptr->constType,1);
01032        }
01033        break;
01034     case ArgVar:
01035        printf(" %s\n",(char *)ptr->data);
01036        break;
01037     case ArgUTF8:
01038        printf(" %s\n",(char *)ptr->data);
01039        break;
01040     case ArgChar:
01041        printDump(ptr->data,ptr->size);
01042        break;
01043     case ArgInfo:
01044 #define VERSION(x) (x).major, (x).minor
01045        info = (CK_INFO *)ptr->data;
01046        printf(" Cryptoki Version: %d.%02d\n",
01047               VERSION(info->cryptokiVersion));
01048        printf(" Manufacturer ID: ");
01049        printChars(info->manufacturerID,sizeof(info->manufacturerID));
01050        printFlags(" Flags: ", info->flags, ConstInfoFlags);
01051        printf(" Library Description: ");
01052        printChars(info->libraryDescription,sizeof(info->libraryDescription));
01053        printf(" Library Version: %d.%02d\n",
01054               VERSION(info->libraryVersion));
01055        break;
01056     case ArgSlotInfo:
01057        slotInfo = (CK_SLOT_INFO *)ptr->data;
01058        printf(" Slot Description: ");
01059        printChars(slotInfo->slotDescription,sizeof(slotInfo->slotDescription));
01060        printf(" Manufacturer ID: ");
01061        printChars(slotInfo->manufacturerID,sizeof(slotInfo->manufacturerID));
01062        printFlags(" Flags: ", slotInfo->flags, ConstSlotFlags);
01063        printf(" Hardware Version: %d.%02d\n",
01064               VERSION(slotInfo->hardwareVersion));
01065        printf(" Firmware Version: %d.%02d\n",
01066               VERSION(slotInfo->firmwareVersion));
01067        break;
01068     case ArgTokenInfo:
01069        tokenInfo = (CK_TOKEN_INFO *)ptr->data;
01070        printf(" Label: ");
01071        printChars(tokenInfo->label,sizeof(tokenInfo->label));
01072        printf(" Manufacturer ID: ");
01073        printChars(tokenInfo->manufacturerID,sizeof(tokenInfo->manufacturerID));
01074        printf(" Model: ");
01075        printChars(tokenInfo->model,sizeof(tokenInfo->model));
01076        printf(" Serial Number: ");
01077        printChars(tokenInfo->serialNumber,sizeof(tokenInfo->serialNumber));
01078        printFlags(" Flags: ", tokenInfo->flags, ConstTokenFlags);
01079        printf(" Max Session Count: ");
01080        printConst(tokenInfo->ulMaxSessionCount, ConstAvailableSizes, 1);
01081        printf(" Session Count: ");
01082        printConst(tokenInfo->ulSessionCount, ConstCurrentSize, 1);
01083        printf(" RW Session Count: ");
01084        printConst(tokenInfo->ulMaxRwSessionCount, ConstAvailableSizes, 1);
01085        printf(" Max Pin Length : ");
01086        printConst(tokenInfo->ulMaxPinLen, ConstCurrentSize, 1);
01087        printf(" Min Pin Length : ");
01088        printConst(tokenInfo->ulMinPinLen, ConstCurrentSize, 1);
01089        printf(" Total Public Memory: ");
01090        printConst(tokenInfo->ulTotalPublicMemory, ConstAvailableSizes, 1);
01091        printf(" Free Public Memory: ");
01092        printConst(tokenInfo->ulFreePublicMemory, ConstCurrentSize, 1);
01093        printf(" Total Private Memory: ");
01094        printConst(tokenInfo->ulTotalPrivateMemory, ConstAvailableSizes, 1);
01095        printf(" Free Private Memory: ");
01096        printConst(tokenInfo->ulFreePrivateMemory, ConstCurrentSize, 1);
01097        printf(" Hardware Version: %d.%02d\n",
01098               VERSION(tokenInfo->hardwareVersion));
01099        printf(" Firmware Version: %d.%02d\n",
01100               VERSION(tokenInfo->firmwareVersion));
01101        printf(" UTC Time: ");
01102        printChars(tokenInfo->utcTime,sizeof(tokenInfo->utcTime));
01103        break;
01104     case ArgSessionInfo:
01105        sessionInfo = (CK_SESSION_INFO *)ptr->data;
01106        printf(" SlotID: 0x%08lx\n", sessionInfo->slotID);
01107        printf(" State: ");
01108        printConst(sessionInfo->state, ConstSessionState, 1);
01109        printFlags(" Flags: ", sessionInfo->flags, ConstSessionFlags);
01110        printf(" Device error: %lu 0x%08lx\n",sessionInfo->ulDeviceError,
01111                      sessionInfo->ulDeviceError);
01112        break;
01113     case ArgAttribute:
01114        attribute = (CK_ATTRIBUTE *)ptr->data;
01115        printf(" Attribute Type: ");
01116        printConst(attribute->type, ConstAttribute, 1);
01117        printf(" Attribute Data: ");
01118        if (attribute->pValue == NULL) {
01119            printf("NULL\n");
01120            printf("Attribute Len: %lu\n",attribute->ulValueLen);
01121        } else {
01122            constType = getConstFromAttribute(attribute->type);
01123            if (constType != ConstNone) {
01124               CK_ULONG value = (constType == ConstBool) ?
01125                   *(CK_BBOOL *)attribute->pValue :
01126                   *(CK_ULONG *)attribute->pValue;
01127               printConst(value, constType, 1);
01128            } else {
01129               printf("\n");
01130               printDump(attribute->pValue, attribute->ulValueLen);
01131            }
01132        }
01133        break;
01134     case ArgMechanism:
01135        mechanism = (CK_MECHANISM *)ptr->data;
01136        printf(" Mechanism Type: ");
01137        printConst(mechanism->mechanism, ConstMechanism, 1);
01138        printf(" Mechanism Data:\n");
01139        printDump(mechanism->pParameter, mechanism->ulParameterLen);
01140        break;
01141     case ArgMechanismInfo:
01142        mechanismInfo = (CK_MECHANISM_INFO *)ptr->data;
01143        printf(" Minimum Key Size: %ld\n",mechanismInfo->ulMinKeySize);
01144        printf(" Maximum Key Size: %ld\n",mechanismInfo->ulMaxKeySize);
01145        printFlags(" Flags: ", mechanismInfo->flags, ConstMechanismFlags);
01146        break;
01147     case ArgInitializeArgs:
01148        initArgs = (CK_C_INITIALIZE_ARGS *)ptr->data;
01149        printFlags(" Flags: ", initArgs->flags, ConstInitializeFlags);
01150         if (initArgs->LibraryParameters) {
01151            printf("Params: %s\n",initArgs->LibraryParameters);
01152        }
01153     case ArgFunctionList:
01154        functionList = (CK_FUNCTION_LIST *)ptr->data;
01155        printf(" Version: %d.%02d\n", VERSION(functionList->version));
01156 #ifdef notdef
01157 #undef CK_NEED_ARG_LIST
01158 #define CK_PKCS11_FUNCTION_INFO(func) \
01159        printf(" %s: 0x%08lx\n", #func, (unsigned long) functionList->func );
01160 #include "pkcs11f.h"
01161 #undef CK_NEED_ARG_LIST
01162 #undef CK_PKCS11_FUNCTION_INFO
01163 #endif
01164     default:
01165        ckrv = CKR_ARGUMENTS_BAD;
01166        break;
01167     }
01168 
01169     return ckrv;
01170 }
01171 
01172 
01173 /*
01174  * Feeling ambitious? turn this whole thing into lexx yacc parser
01175  * with full expressions.
01176  */
01177 Value **
01178 parseArgs(int index, const char * bp)
01179 {
01180     const Commands *cp = &commands[index];
01181     int size = strlen(cp->fname);
01182     int i;
01183     CK_ULONG value;
01184     char vname[512];
01185     Value **argList,*possible;
01186     ConstType constType;
01187 
01188     /*
01189      * skip pass the command
01190      */
01191     if ((cp->fname[0] == 'C') && (cp->fname[1] == '_') && (bp[1] != '_')) {
01192        size -= 2;
01193     }
01194     bp += size;
01195 
01196     /*
01197      * Initialize our argument list
01198      */
01199     argList = (Value **)malloc(sizeof(Value*)*MAX_ARGS);
01200     for (i=0; i < MAX_ARGS; i++) { argList[i] = NULL; }
01201 
01202     /*
01203      * Walk the argument list parsing it...
01204      */
01205     for (i=0 ;i < MAX_ARGS; i++) {
01206        ArgType type = cp->args[i] & ArgMask;
01207        int error;
01208 
01209         /* strip blanks */
01210         bp = strip(bp);
01211 
01212        /* if we hit ArgNone, we've nabbed all the arguments we need */
01213        if (type == ArgNone) {
01214            break;
01215        }
01216 
01217        /* if we run out of space in the line, we weren't given enough
01218         * arguments... */
01219        if (*bp == '\0') {
01220            /* we're into optional arguments, ok to quit now */
01221            if (cp->args[i] & ArgOpt) {
01222               break;
01223            }
01224            fprintf(stderr,"%s: only %d args found,\n",cp->fname,i);
01225            parseFree(argList);
01226            return NULL;
01227        }
01228 
01229        /* collect all the rest of the command line and send
01230         * it as a single argument */
01231        if (cp->args[i] & ArgFull) {
01232            int size = strlen(bp)+1;
01233            argList[i] = NewValue(type, size);
01234            memcpy(argList[i]->data, bp, size);
01235            break;
01236        }
01237 
01238        /*
01239         * look up the argument in our variable list first... only 
01240         * exception is the new argument type for set...
01241         */
01242        error = 0;
01243        if ((cp->args[i] != (ArgVar|ArgNew)) && 
01244                      (possible = varLookup(bp,vname,sizeof(vname),&error))) {
01245           /* ints are only compatible with other ints... all other types
01246            * are interchangeable... */
01247           if (type != ArgVar) { /* ArgVar's match anyone */
01248               if ((type == ArgULong) ^ 
01249                             ((possible->type & ArgMask) == ArgULong)) {
01250                   fprintf(stderr,"%s: Arg %d incompatible type with <%s>\n",
01251                             cp->fname,i+1,vname);
01252                   argFree(possible);
01253                   parseFree(argList);
01254                   return NULL;
01255               }
01256               /*
01257                * ... that is as long as they are big enough...
01258                */
01259               if (ArgSize(type) > possible->size) {
01260                   fprintf(stderr,
01261                "%s: Arg %d %s is too small (%d bytes needs to be %d bytes)\n",
01262                      cp->fname,i+1,vname,possible->size,ArgSize(type));
01263                   argFree(possible);
01264                   parseFree(argList);
01265                   return NULL;
01266               }
01267           }
01268        
01269           /* everything looks kosher here, use it */    
01270           argList[i] = possible;
01271 
01272           bp = readChars(bp,vname,sizeof(vname));
01273           if (cp->args[i] & ArgOut) {
01274               possible->type |= ArgOut;
01275           }
01276           continue;
01277        }
01278 
01279        if (error == 1) {
01280            parseFree(argList);
01281            return NULL;
01282        }
01283 
01284        /* create space for our argument */
01285        argList[i] = NewValue(type, 1);
01286 
01287         if ((PL_strncasecmp(bp, "null", 4) == 0)  && ((bp[4] == 0) 
01288               || (bp[4] == ' ') || (bp[4] =='\t') || (bp[4] =='\n'))) {
01289            if (cp->args[i] == ArgULong) {
01290               fprintf(stderr, "%s: Arg %d CK_ULONG can't be NULL\n",
01291                                                         cp->fname,i+1);
01292               parseFree(argList);
01293               return NULL;
01294            }
01295            argFreeData(argList[i]);
01296            argList[i]->data = NULL;
01297            argList[i]->size = 0;
01298            bp += 4;
01299            if (*bp) bp++;
01300            continue;
01301         }
01302 
01303        /* if we're an output variable, we need to add it */
01304        if (cp->args[i] & ArgOut) {
01305             if (PL_strncasecmp(bp,"file(",5) == 0 /* ) */ ) {
01306                char filename[512];
01307               bp = readChars(bp+5,filename,sizeof(filename));
01308               size = PL_strlen(filename);
01309               if ((size > 0) && (/* ( */filename[size-1] == ')')) {
01310                   filename[size-1] = 0; 
01311               }
01312               filename[size] = 0; 
01313               argList[i]->filename = (char *)malloc(size+1);
01314 
01315               PL_strcpy(argList[i]->filename,filename);
01316 
01317               argList[i]->type |= ArgOut|ArgFile;
01318               break;
01319            }
01320            bp = AddVariable(bp,&argList[i]);
01321            argList[i]->type |= ArgOut;
01322            continue;
01323        } 
01324 
01325         if (PL_strncasecmp(bp, "file(", 5) == 0 /* ) */ ) {
01326            char filename[512];
01327 
01328            bp = readChars(bp+5,filename,sizeof(filename));
01329            size = PL_strlen(filename);
01330            if ((size > 0) && ( /* ( */ filename[size-1] == ')')) {
01331               filename[size-1] = 0; 
01332            }
01333 
01334            if (restore(filename,argList[i]) != CKR_OK) {
01335               parseFree(argList);
01336               return NULL;
01337            }
01338            continue;
01339        }
01340 
01341        switch (type) {
01342        case ArgULong:
01343             bp = constLookup(bp, &value, &constType);
01344             *(int *)argList[i]->data = value;
01345             argList[i]->constType = constType;
01346             break;
01347        case ArgVar:
01348             argFreeData(argList[i]);
01349             size = getEnd(bp)+1;
01350             argList[i]->data = (void *)malloc(size);
01351             argList[i]->size = size;
01352             /* fall through */
01353        case ArgInfo:
01354        case ArgSlotInfo:
01355        case ArgTokenInfo:
01356        case ArgSessionInfo:
01357        case ArgAttribute:
01358        case ArgMechanism:
01359        case ArgMechanismInfo:
01360        case ArgInitializeArgs:
01361        case ArgUTF8:
01362        case ArgChar:
01363             bp = readChars(bp,(char *)argList[i]->data,argList[i]->size);
01364        case ArgNone:
01365        default:
01366             break;
01367        }
01368     }
01369 
01370     return argList;
01371 }
01372 
01373 /* lookup the command in the array */
01374 int
01375 lookup(const char *buf)
01376 {
01377     int size,i;
01378     int buflen;
01379 
01380     buflen = PL_strlen(buf);
01381 
01382     for ( i = 0; i < commandCount; i++) {
01383        size = PL_strlen(commands[i].fname);
01384 
01385        if (size <= buflen) {
01386            if (PL_strncasecmp(buf,commands[i].fname,size) == 0) {
01387               return i;
01388            }
01389        }
01390        if (size-2 <= buflen) {
01391            if (commands[i].fname[0] == 'C' && commands[i].fname[1] == '_' &&
01392               (PL_strncasecmp(buf,&commands[i].fname[2],size-2) == 0)) {
01393               return i;
01394            }
01395        }
01396     }
01397     fprintf(stderr,"Can't find command %s\n",buf);
01398     return -1;
01399 }
01400 
01401 void
01402 putOutput(Value **ptr)
01403 {
01404     int i;
01405 
01406     for (i=0; i < MAX_ARGS; i++) {
01407        ArgType type;
01408 
01409        if (ptr[i] == NULL) break;
01410 
01411        type  = ptr[i]->type;
01412 
01413        ptr[i]->type &= ~ArgOut;
01414        if (type == ArgNone) {
01415            break;
01416        }
01417        if (type & ArgOut) {
01418            (void) printArg(ptr[i],i+1);
01419        }
01420        if (type & ArgFile) {
01421            save(ptr[i]->filename,ptr[i]);
01422            free(ptr[i]->filename);
01423            ptr[i]->filename= NULL; /* paranoia */
01424        }
01425     }
01426 }
01427           
01428 CK_RV
01429 unloadModule(Module *module)
01430 {
01431     char *disableUnload = NULL;
01432 
01433     disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
01434 
01435     if (module->library && !disableUnload) {
01436        PR_UnloadLibrary(module->library);
01437     }
01438 
01439     module->library = NULL;
01440     module->functionList = NULL;
01441 
01442     return CKR_OK;
01443 }
01444 
01445 CK_RV
01446 loadModule(Module *module, char *library)
01447 {
01448    PRLibrary *newLibrary;
01449    CK_C_GetFunctionList getFunctionList;
01450    CK_FUNCTION_LIST *functionList;
01451    CK_RV ckrv;
01452 
01453    newLibrary = PR_LoadLibrary(library);
01454    if (!newLibrary) {
01455        fprintf(stderr,"Couldn't load library %s\n",library);
01456        return CKR_FUNCTION_FAILED;
01457    }
01458    getFunctionList = (CK_C_GetFunctionList) 
01459                      PR_FindSymbol(newLibrary,"C_GetFunctionList");
01460    if (!getFunctionList) {
01461        fprintf(stderr,"Couldn't find \"C_GetFunctionList\" in %s\n",library);
01462        return CKR_FUNCTION_FAILED;
01463    }
01464 
01465    ckrv = (*getFunctionList)(&functionList);
01466    if (ckrv != CKR_OK) {
01467        return ckrv;
01468    }
01469    
01470    if (module->library) {
01471        PR_UnloadLibrary(module->library);
01472    }
01473 
01474    module->library = newLibrary;
01475    module->functionList = functionList;
01476 
01477    return CKR_OK;
01478 }
01479 
01480 static void
01481 printHelp(int index, int full)
01482 {
01483     int j;
01484     printf(" %s", commands[index].fname);
01485     for (j=0; j < MAX_ARGS; j++) {
01486        ArgType type = commands[index].args[j] & ArgMask;
01487        if (type == ArgNone) {
01488            break;
01489        }
01490        printf(" %s", valueString[type]);
01491     }
01492     printf("\n");
01493     printf(" %s\n",commands[index].helpString);
01494 }
01495 
01496 /* add Topical help here ! */
01497 static CK_RV
01498 printTopicHelp(char *topic)
01499 {
01500     int size,i;
01501     int topicLen;
01502 
01503     topicLen = PL_strlen(topic);
01504 
01505     for ( i = 0; i < topicCount; i++) {
01506        size = PL_strlen(topics[i].name);
01507 
01508        if (size <= topicLen) {
01509            if (PL_strncasecmp(topic,topics[i].name,size) == 0) {
01510               break;
01511            }
01512        }
01513     }
01514 
01515     if (i == topicCount) {
01516        fprintf(stderr,"Can't find topic '%s'\n", topic);
01517        return CKR_DATA_INVALID;
01518     }
01519 
01520     printf(" %s", topic);
01521     printf("\n");
01522     printf(" %s\n",topics[i].helpString);
01523     return CKR_OK;
01524 }
01525 
01526 static CK_RV
01527 printGeneralHelp(void)
01528 {
01529     int i;
01530     printf(" To get help on commands, select from the list below:");
01531     for ( i = 0; i < commandCount; i++) {
01532        if (i % 5 == 0) printf("\n");
01533        printf("%s,", commands[i].fname);
01534     }
01535     printf("\n");
01536     /* print help topics */
01537     printf(" To get help on a topic, select from the list below:");
01538     for ( i = 0; i < topicCount; i++) {
01539        if (i % 5 == 0) printf("\n");
01540        printf("%s,", topics[i].name);
01541     }
01542     printf("\n");
01543    return CKR_OK;
01544 }
01545 
01546 static CK_RV
01547 quitIf(CK_ULONG a, const char *cmp, CK_ULONG b)
01548 {
01549     if (strcmp(cmp, "<") == 0) {
01550        return (a < b) ? CKR_QUIT : CKR_OK;
01551     } else if (strcmp(cmp, ">") == 0) {
01552        return (a > b) ? CKR_QUIT : CKR_OK;
01553     } else if (strcmp(cmp, "<=") == 0) {
01554        return (a <= b) ? CKR_QUIT : CKR_OK;
01555     } else if (strcmp(cmp, ">=") == 0) {
01556        return (a >= b) ? CKR_QUIT : CKR_OK;
01557     } else if (strcmp(cmp, "=") == 0) {
01558        return (a == b) ? CKR_QUIT : CKR_OK;
01559     } else if (strcmp(cmp, "!=") == 0) {
01560        return (a != b) ? CKR_QUIT : CKR_OK;
01561     }
01562     printf("Unkown integer comparator: '%s'\n", cmp);
01563     return CKR_ARGUMENTS_BAD;
01564 }
01565 
01566 static CK_RV
01567 quitIfString(const char *a, const char *cmp, const char *b)
01568 {
01569 
01570     if (strcmp(cmp, "=") == 0) {
01571        return (strcmp(a,b) == 0) ? CKR_QUIT : CKR_OK;
01572     } else if (strcmp(cmp, "!=") == 0) {
01573        return (strcmp(a,b) != 0) ? CKR_QUIT : CKR_OK;
01574     }
01575     printf("Unkown string comparator: '%s'\n", cmp);
01576     return CKR_ARGUMENTS_BAD;
01577 }
01578 
01579 CK_RV run(const char *); 
01580 CK_RV timeCommand(const char *); 
01581 CK_RV loop(const char *filename, const char *var, 
01582             CK_ULONG start, CK_ULONG end, CK_ULONG step) ;
01583 
01584 /*
01585  * Actually dispatch the function... Bad things happen
01586  * if these don't match the commands array.
01587  */
01588 CK_RV
01589 do_func(int index, Value **a)
01590 {
01591     int value, helpIndex;
01592     static Module module = { NULL, NULL} ;
01593     CK_FUNCTION_LIST *func = module.functionList;
01594 
01595     switch (commands[index].fType) {
01596     case F_C_Initialize:
01597        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01598        return func->C_Initialize((void *)a[0]->data);
01599     case F_C_Finalize:
01600        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01601        return func->C_Finalize((void *)a[0]->data);
01602     case F_C_GetInfo:
01603        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01604        return func->C_GetInfo((CK_INFO *)a[0]->data);
01605     case F_C_GetFunctionList:
01606        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01607        return func->C_GetFunctionList((CK_FUNCTION_LIST **)a[0]->data);
01608     case F_C_GetSlotList:
01609        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01610        return func->C_GetSlotList((CK_BBOOL)*(CK_ULONG *)a[0]->data,
01611                                    (CK_SLOT_ID *)a[1]->data,
01612                                    (CK_LONG *)a[2]->data);
01613     case F_C_GetSlotInfo:
01614        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01615        return func->C_GetSlotInfo(*(CK_ULONG *)a[0]->data,
01616                                    (CK_SLOT_INFO *)a[1]->data);
01617     case F_C_GetTokenInfo:
01618        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01619        return func->C_GetTokenInfo(*(CK_ULONG *)a[0]->data,
01620                                    (CK_TOKEN_INFO *)a[1]->data);
01621     case F_C_GetMechanismList:
01622        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01623        if (a[1]->data) {
01624            a[1]->constType = ConstMechanism;
01625        }
01626        return func->C_GetMechanismList(*(CK_ULONG *)a[0]->data,
01627                                    (CK_MECHANISM_TYPE*)a[1]->data,
01628                                    (CK_ULONG *)a[2]->data);
01629     case F_C_GetMechanismInfo:
01630        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01631        return func->C_GetMechanismInfo(*(CK_ULONG *)a[0]->data,
01632                                    *(CK_ULONG *)a[1]->data,
01633                                    (CK_MECHANISM_INFO *)a[2]->data);
01634     case F_C_InitToken:
01635        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01636        return func->C_InitToken(*(CK_ULONG *)a[0]->data,
01637                                    (CK_CHAR *)a[1]->data,
01638                                    *(CK_ULONG *)a[2]->data,
01639                                    (CK_CHAR *)a[3]->data);
01640     case F_C_InitPIN:
01641        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01642        return func->C_InitPIN(*(CK_ULONG *)a[0]->data,
01643                                    (CK_CHAR *)a[1]->data,
01644                                    *(CK_ULONG *)a[2]->data);
01645     case F_C_SetPIN:
01646        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01647        return func->C_SetPIN(*(CK_ULONG *)a[0]->data,
01648                                    (CK_CHAR *)a[1]->data,
01649                                    *(CK_ULONG *)a[2]->data,
01650                                    (CK_CHAR *)a[3]->data,
01651                                    *(CK_ULONG *)a[4]->data);
01652     case F_C_OpenSession:
01653        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01654        return func->C_OpenSession(*(CK_ULONG *)a[0]->data,
01655                                    *(CK_ULONG *)a[1]->data,
01656                                    (void *)NULL,
01657                                    (CK_NOTIFY) NULL,
01658                                    (CK_ULONG *)a[2]->data);
01659     case F_C_CloseSession:
01660        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01661        return func->C_CloseSession(*(CK_ULONG *)a[0]->data);
01662     case F_C_CloseAllSessions:
01663        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01664        return func->C_CloseAllSessions(*(CK_ULONG *)a[0]->data);
01665     case F_C_GetSessionInfo:
01666        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01667        return func->C_GetSessionInfo(*(CK_ULONG *)a[0]->data,
01668                                    (CK_SESSION_INFO *)a[1]->data);
01669     case F_C_GetOperationState:
01670        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01671        return func->C_GetOperationState(*(CK_ULONG *)a[0]->data,
01672                                    (CK_BYTE *)a[1]->data,
01673                                    (CK_ULONG *)a[2]->data);
01674     case F_C_SetOperationState:
01675        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01676        return func->C_SetOperationState(*(CK_ULONG *)a[0]->data,
01677                                    (CK_CHAR *)a[1]->data,
01678                                    *(CK_ULONG *)a[2]->data,
01679                                    *(CK_ULONG *)a[3]->data,
01680                                    *(CK_ULONG *)a[4]->data);
01681     case F_C_Login:
01682        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01683        return func->C_Login(*(CK_ULONG *)a[0]->data,
01684                                    *(CK_ULONG *)a[1]->data,
01685                                    (CK_CHAR *)a[2]->data,
01686                                    *(CK_ULONG *)a[3]->data);
01687     case F_C_Logout:
01688        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01689        return func->C_Logout(*(CK_ULONG *)a[0]->data);
01690     case F_C_CreateObject:
01691        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01692        return func->C_CreateObject(*(CK_ULONG *)a[0]->data,
01693                                    (CK_ATTRIBUTE *)a[1]->data,
01694                                    *(CK_ULONG *)a[2]->data,
01695                                    (CK_ULONG *)a[3]->data);
01696     case F_C_CopyObject:
01697        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01698        return func->C_CopyObject(*(CK_ULONG *)a[0]->data,
01699                                    *(CK_ULONG *)a[0]->data,
01700                                    (CK_ATTRIBUTE *)a[1]->data,
01701                                    *(CK_ULONG *)a[2]->data,
01702                                    (CK_ULONG *)a[3]->data);
01703     case F_C_DestroyObject:
01704        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01705        return func->C_DestroyObject(*(CK_ULONG *)a[0]->data,
01706                                    *(CK_ULONG *)a[1]->data);
01707     case F_C_GetObjectSize:
01708        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01709        return func->C_GetObjectSize(*(CK_ULONG *)a[0]->data,
01710                                    *(CK_ULONG *)a[1]->data,
01711                                    (CK_ULONG *)a[2]->data);
01712     case F_C_GetAttributeValue:
01713        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01714        return func->C_GetAttributeValue(*(CK_ULONG *)a[0]->data,
01715                                    *(CK_ULONG *)a[1]->data,
01716                                    (CK_ATTRIBUTE *)a[2]->data,
01717                                    *(CK_ULONG *)a[3]->data);
01718     case F_C_SetAttributeValue:
01719        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01720        return func->C_SetAttributeValue(*(CK_ULONG *)a[0]->data,
01721                                    *(CK_ULONG *)a[1]->data,
01722                                    (CK_ATTRIBUTE *)a[2]->data,
01723                                    *(CK_ULONG *)a[3]->data);
01724     case F_C_FindObjectsInit:
01725        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01726        return func->C_FindObjectsInit(*(CK_ULONG *)a[0]->data,
01727                                    (CK_ATTRIBUTE *)a[1]->data,
01728                                    *(CK_ULONG *)a[2]->data);
01729     case F_C_FindObjects:
01730        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01731        return func->C_FindObjects(*(CK_ULONG *)a[0]->data,
01732                                    (CK_ULONG *)a[1]->data,
01733                                    *(CK_ULONG *)a[2]->data,
01734                                    (CK_ULONG *)a[3]->data);
01735     case F_C_FindObjectsFinal:
01736        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01737        return func->C_FindObjectsFinal(*(CK_ULONG *)a[0]->data);
01738     case F_C_EncryptInit:
01739        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01740        return func->C_EncryptInit(*(CK_ULONG *)a[0]->data,
01741                                    (CK_MECHANISM *)a[1]->data,
01742                                    *(CK_ULONG *)a[2]->data);
01743     case F_C_Encrypt:
01744        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01745        return func->C_Encrypt(*(CK_ULONG *)a[0]->data,
01746                                    (CK_CHAR *)a[1]->data,
01747                                    *(CK_ULONG *)a[2]->data,
01748                                    (CK_CHAR *)a[3]->data,
01749                                    (CK_ULONG *)a[4]->data);
01750     case F_C_EncryptUpdate:
01751        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01752        return func->C_EncryptUpdate(*(CK_ULONG *)a[0]->data,
01753                                    (CK_CHAR *)a[1]->data,
01754                                    *(CK_ULONG *)a[2]->data,
01755                                    (CK_CHAR *)a[3]->data,
01756                                    (CK_ULONG *)a[4]->data);
01757     case F_C_EncryptFinal:
01758        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01759        return func->C_EncryptFinal(*(CK_ULONG *)a[0]->data,
01760                                    (CK_CHAR *)a[1]->data,
01761                                    (CK_ULONG *)a[2]->data);
01762     case F_C_DecryptInit:
01763        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01764        return func->C_DecryptInit(*(CK_ULONG *)a[0]->data,
01765                                    (CK_MECHANISM *)a[1]->data,
01766                                    *(CK_ULONG *)a[2]->data);
01767     case F_C_Decrypt:
01768        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01769        return func->C_Decrypt(*(CK_ULONG *)a[0]->data,
01770                                    (CK_CHAR *)a[1]->data,
01771                                    *(CK_ULONG *)a[2]->data,
01772                                    (CK_CHAR *)a[3]->data,
01773                                    (CK_ULONG *)a[4]->data);
01774     case F_C_DecryptUpdate:
01775        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01776        return func->C_DecryptUpdate(*(CK_ULONG *)a[0]->data,
01777                                    (CK_CHAR *)a[1]->data,
01778                                    *(CK_ULONG *)a[2]->data,
01779                                    (CK_CHAR *)a[3]->data,
01780                                    (CK_ULONG *)a[4]->data);
01781     case F_C_DecryptFinal:
01782        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01783        return func->C_DecryptFinal(*(CK_ULONG *)a[0]->data,
01784                                    (CK_CHAR *)a[1]->data,
01785                                    (CK_ULONG *)a[2]->data);
01786     case F_C_DigestInit:
01787        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01788        return func->C_DigestInit(*(CK_ULONG *)a[0]->data,
01789                                    (CK_MECHANISM *)a[1]->data);
01790     case F_C_Digest:
01791        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01792        return func->C_Digest(*(CK_ULONG *)a[0]->data,
01793                                    (CK_CHAR *)a[1]->data,
01794                                    *(CK_ULONG *)a[2]->data,
01795                                    (CK_CHAR *)a[3]->data,
01796                                    (CK_ULONG *)a[4]->data);
01797     case F_C_DigestUpdate:
01798        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01799        return func->C_DigestUpdate(*(CK_ULONG *)a[0]->data,
01800                                    (CK_CHAR *)a[1]->data,
01801                                    *(CK_ULONG *)a[2]->data);
01802     case F_C_DigestKey:
01803        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01804        return func->C_DigestKey(*(CK_ULONG *)a[0]->data,
01805                                    *(CK_ULONG *)a[1]->data);
01806     case F_C_DigestFinal:
01807        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01808        return func->C_DigestFinal(*(CK_ULONG *)a[0]->data,
01809                                    (CK_CHAR *)a[1]->data,
01810                                    (CK_ULONG *)a[2]->data);
01811     case F_C_SignInit:
01812        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01813        return func->C_SignInit(*(CK_ULONG *)a[0]->data,
01814                                    (CK_MECHANISM *)a[1]->data,
01815                                    *(CK_ULONG *)a[2]->data);
01816     case F_C_Sign:
01817        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01818        return func->C_Sign(*(CK_ULONG *)a[0]->data,
01819                                    (CK_CHAR *)a[1]->data,
01820                                    *(CK_ULONG *)a[2]->data,
01821                                    (CK_CHAR *)a[3]->data,
01822                                    (CK_ULONG *)a[4]->data);
01823     case F_C_SignUpdate:
01824        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01825        return func->C_SignUpdate(*(CK_ULONG *)a[0]->data,
01826                                    (CK_CHAR *)a[1]->data,
01827                                    *(CK_ULONG *)a[2]->data);
01828     case F_C_SignFinal:
01829        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01830        return func->C_SignFinal(*(CK_ULONG *)a[0]->data,
01831                                    (CK_CHAR *)a[1]->data,
01832                                    (CK_ULONG *)a[2]->data);
01833 
01834     case F_C_SignRecoverInit:
01835        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01836        return func->C_SignRecoverInit(*(CK_ULONG *)a[0]->data,
01837                                    (CK_MECHANISM *)a[1]->data,
01838                                    *(CK_ULONG *)a[2]->data);
01839     case F_C_SignRecover:
01840        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01841        return func->C_SignRecover(*(CK_ULONG *)a[0]->data,
01842                                    (CK_CHAR *)a[1]->data,
01843                                    *(CK_ULONG *)a[2]->data,
01844                                    (CK_CHAR *)a[3]->data,
01845                                    (CK_ULONG *)a[4]->data);
01846     case F_C_VerifyInit:
01847        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01848        return func->C_VerifyInit(*(CK_ULONG *)a[0]->data,
01849                                    (CK_MECHANISM *)a[1]->data,
01850                                    *(CK_ULONG *)a[2]->data);
01851     case F_C_Verify:
01852        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01853        return func->C_Verify(*(CK_ULONG *)a[0]->data,
01854                                    (CK_CHAR *)a[1]->data,
01855                                    *(CK_ULONG *)a[2]->data,
01856                                    (CK_CHAR *)a[3]->data,
01857                                    *(CK_ULONG *)a[4]->data);
01858     case F_C_VerifyUpdate:
01859        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01860        return func->C_VerifyUpdate(*(CK_ULONG *)a[0]->data,
01861                                    (CK_CHAR *)a[1]->data,
01862                                    *(CK_ULONG *)a[2]->data);
01863     case F_C_VerifyFinal:
01864        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01865        return func->C_VerifyFinal(*(CK_ULONG *)a[0]->data,
01866                                    (CK_CHAR *)a[1]->data,
01867                                    *(CK_ULONG *)a[2]->data);
01868 
01869     case F_C_VerifyRecoverInit:
01870        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01871        return func->C_VerifyRecoverInit(*(CK_ULONG *)a[0]->data,
01872                                    (CK_MECHANISM *)a[1]->data,
01873                                    *(CK_ULONG *)a[2]->data);
01874     case F_C_VerifyRecover:
01875        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01876        return func->C_VerifyRecover(*(CK_ULONG *)a[0]->data,
01877                                    (CK_CHAR *)a[1]->data,
01878                                    *(CK_ULONG *)a[2]->data,
01879                                    (CK_CHAR *)a[3]->data,
01880                                    (CK_ULONG *)a[4]->data);
01881     case F_C_DigestEncryptUpdate:
01882        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01883        return func->C_DigestEncryptUpdate(*(CK_ULONG *)a[0]->data,
01884                                    (CK_CHAR *)a[1]->data,
01885                                    *(CK_ULONG *)a[2]->data,
01886                                    (CK_CHAR *)a[3]->data,
01887                                    (CK_ULONG *)a[4]->data);
01888     case F_C_DecryptDigestUpdate:
01889        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01890        return func->C_DecryptDigestUpdate(*(CK_ULONG *)a[0]->data,
01891                                    (CK_CHAR *)a[1]->data,
01892                                    *(CK_ULONG *)a[2]->data,
01893                                    (CK_CHAR *)a[3]->data,
01894                                    (CK_ULONG *)a[4]->data);
01895     case F_C_SignEncryptUpdate:
01896        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01897        return func->C_SignEncryptUpdate(*(CK_ULONG *)a[0]->data,
01898                                    (CK_CHAR *)a[1]->data,
01899                                    *(CK_ULONG *)a[2]->data,
01900                                    (CK_CHAR *)a[3]->data,
01901                                    (CK_ULONG *)a[4]->data);
01902     case F_C_DecryptVerifyUpdate:
01903        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01904        return func->C_DecryptVerifyUpdate(*(CK_ULONG *)a[0]->data,
01905                                    (CK_CHAR *)a[1]->data,
01906                                    *(CK_ULONG *)a[2]->data,
01907                                    (CK_CHAR *)a[3]->data,
01908                                    (CK_ULONG *)a[4]->data);
01909     case F_C_GenerateKey:
01910        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01911        return func->C_GenerateKey(*(CK_ULONG *)a[0]->data,
01912                                    (CK_MECHANISM *)a[1]->data,
01913                                    (CK_ATTRIBUTE *)a[2]->data,
01914                                    *(CK_ULONG *)a[3]->data,
01915                                    (CK_ULONG *)a[4]->data);
01916     case F_C_GenerateKeyPair:
01917        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01918        return func->C_GenerateKeyPair(*(CK_ULONG *)a[0]->data,
01919                                    (CK_MECHANISM *)a[1]->data,
01920                                    (CK_ATTRIBUTE *)a[2]->data,
01921                                    *(CK_ULONG *)a[3]->data,
01922                                    (CK_ATTRIBUTE *)a[4]->data,
01923                                    *(CK_ULONG *)a[5]->data,
01924                                    (CK_ULONG *)a[6]->data,
01925                                    (CK_ULONG *)a[7]->data);
01926     case F_C_WrapKey:
01927        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01928        return func->C_WrapKey(*(CK_ULONG *)a[0]->data,
01929                                    (CK_MECHANISM *)a[1]->data,
01930                                    *(CK_ULONG *)a[2]->data,
01931                                    *(CK_ULONG *)a[3]->data,
01932                                    (CK_CHAR *)a[5]->data,
01933                                    (CK_ULONG *)a[6]->data);
01934     case F_C_UnwrapKey:
01935        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01936        return func->C_UnwrapKey(*(CK_ULONG *)a[0]->data,
01937                                    (CK_MECHANISM *)a[1]->data,
01938                                    *(CK_ULONG *)a[2]->data,
01939                                    (CK_CHAR *)a[3]->data,
01940                                    *(CK_ULONG *)a[4]->data,
01941                                    (CK_ATTRIBUTE *)a[5]->data,
01942                                    *(CK_ULONG *)a[6]->data,
01943                                    (CK_ULONG *)a[7]->data);
01944     case F_C_DeriveKey:
01945        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01946        return func->C_DeriveKey (*(CK_ULONG *)a[0]->data,
01947                                    (CK_MECHANISM *)a[1]->data,
01948                                    *(CK_ULONG *)a[2]->data,
01949                                    (CK_ATTRIBUTE *)a[3]->data,
01950                                    *(CK_ULONG *)a[4]->data,
01951                                    (CK_ULONG *)a[5]->data);
01952     case F_C_SeedRandom:
01953        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01954        return func->C_SeedRandom(*(CK_ULONG *)a[0]->data,
01955                                    (CK_CHAR *)a[1]->data,
01956                                    *(CK_ULONG *)a[2]->data);
01957     case F_C_GenerateRandom:
01958        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01959        return func->C_GenerateRandom(*(CK_ULONG *)a[0]->data,
01960                                    (CK_CHAR *)a[1]->data,
01961                                    *(CK_ULONG *)a[2]->data);
01962     case F_C_GetFunctionStatus:
01963        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01964        return func->C_GetFunctionStatus(*(CK_ULONG *)a[0]->data);
01965     case F_C_CancelFunction:
01966        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01967        return func->C_CancelFunction(*(CK_ULONG *)a[0]->data);
01968     case F_C_WaitForSlotEvent:
01969        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01970        return func->C_WaitForSlotEvent(*(CK_ULONG *)a[0]->data,
01971                                    (CK_ULONG *)a[1]->data,
01972                                    (void *)a[2]->data);
01973     /* set a variable */
01974     case F_SetVar:   
01975     case F_SetStringVar:    
01976        (void) DeleteVariable(a[0]->data);
01977        (void) AddVariable(a[0]->data,&a[1]);
01978        return CKR_OK;
01979     /* print a value */
01980     case F_Print:
01981        return printArg(a[0],0);
01982     case F_SaveVar:
01983        return save(a[0]->data,a[1]);
01984     case F_RestoreVar:
01985        return restore(a[0]->data,a[1]);
01986     case F_Delete:
01987        return DeleteVariable(a[0]->data);
01988     case F_Increment:
01989        return increment(a[0], *(CK_ULONG *)a[1]->data);
01990     case F_Decrement:
01991        return decrement(a[0], *(CK_ULONG *)a[1]->data);
01992     case F_List:
01993        return list();
01994     case F_Run:
01995        return run(a[0]->data);
01996     case F_Time:
01997        return timeCommand(a[0]->data);
01998     case F_Load:
01999        return loadModule(&module,a[0]->data);
02000     case F_Unload:
02001        return unloadModule(&module);
02002     case F_NewArray:
02003        (void) DeleteVariable(a[0]->data);
02004        return ArrayVariable(a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data);
02005     case F_NewTemplate:
02006        (void) DeleteVariable(a[0]->data);
02007        return ArrayTemplate(a[0]->data,a[1]->data);
02008     case F_BuildTemplate:
02009        return BuildTemplate(a[0]);
02010     case F_SetTemplate:
02011        return SetTemplate(a[0],
02012               *(CK_ULONG *)a[1]->data,
02013               *(CK_ULONG *)a[2]->data);
02014     case F_NewMechanism:
02015        (void) DeleteVariable(a[0]->data);
02016        return NewMechanism(a[0]->data,*(CK_ULONG *)a[1]->data);
02017     case F_NewInitializeArgs:
02018        (void) DeleteVariable(a[0]->data);
02019        return NewInitializeArgs(a[0]->data,*(CK_ULONG *)a[1]->data,a[2]->data);
02020     case F_System:
02021         value = *(int *)a[0]->data;
02022        if (value & 0x80000000) {
02023            systemFlags &= ~value;
02024        } else {
02025            systemFlags |= value;
02026        }
02027        return CKR_OK;
02028     case F_Loop:
02029        return loop(a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data,
02030               *(CK_ULONG *)a[3]->data,*(CK_ULONG *)a[4]->data);
02031     case F_Help:
02032        if (a[0]) {
02033            helpIndex = lookup(a[0]->data);
02034            if (helpIndex < 0) {
02035               return printTopicHelp(a[0]->data);
02036            }
02037            printHelp(helpIndex, 1);
02038            return CKR_OK;
02039        }
02040        return printGeneralHelp();
02041     case F_QuitIfString:
02042        return quitIfString(a[0]->data,a[1]->data,a[2]->data);
02043     case F_QuitIf:
02044        return quitIf(*(CK_ULONG *)a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data);
02045     case F_Quit:
02046        return CKR_QUIT;
02047     default:
02048        fprintf(stderr,
02049               "Function %s not yet supported\n",commands[index].fname );
02050        return CKR_OK;
02051     }
02052     /* Not Reached */
02053     return CKR_OK;
02054 }
02055 
02056 CK_RV
02057 processCommand(const char * buf)
02058 {
02059     CK_RV error = CKR_OK;
02060     int index;
02061     const char *bp;
02062     Value **arglist;
02063 
02064     bp = strip(buf);
02065     /* allow comments and blank lines in scripts */
02066     if ((*bp == '#') || (*bp == 0) || (*bp == '\n')){
02067        return CKR_OK;
02068     }
02069 
02070     index = lookup(bp);
02071 
02072     if (index < 0) {
02073        return CKR_OK;
02074     }
02075 
02076     arglist = parseArgs(index,bp);
02077     if (arglist == NULL) {
02078        return CKR_OK;
02079     }
02080 
02081     error = do_func(index,arglist);
02082     if (error == CKR_OK) {
02083        putOutput(arglist);
02084     } else if (error != CKR_QUIT) {
02085        printf(">> Error : ");
02086        printConst(error, ConstResult, 1);
02087     }
02088 
02089     parseFree(arglist);
02090     return error;
02091 }
02092 
02093 CK_RV
02094 timeCommand(const char *command) 
02095 {
02096     CK_RV ckrv;
02097     PRIntervalTime startTime = PR_IntervalNow();
02098     PRIntervalTime endTime;
02099     PRIntervalTime elapsedTime;
02100 
02101     ckrv = processCommand(command);
02102 
02103     endTime = PR_IntervalNow();
02104     elapsedTime = endTime - startTime;
02105     printf("Time -- %d msec \n", 
02106        PR_IntervalToMilliseconds(elapsedTime));
02107     
02108     return ckrv;
02109 }
02110 
02111 
02112 
02113 CK_RV
02114 process(FILE *inFile,int user)
02115 {
02116     char buf[2048];
02117     CK_RV error;
02118     CK_RV ckrv = CKR_OK;
02119 
02120     if (user) { printf("pkcs11> "); fflush(stdout); }
02121 
02122     while (fgets(buf,2048,inFile) != NULL) {
02123 
02124        if (!user) printf("* %s",buf);
02125        error = processCommand(buf);
02126        if (error == CKR_QUIT) {
02127            break;
02128        } else if (error != CKR_OK) {
02129            ckrv = error;
02130        }
02131        if (user) { 
02132            printf("pkcs11> "); fflush(stdout); 
02133        }
02134     }
02135     return ckrv;
02136 }
02137 
02138 CK_RV
02139 run(const char *filename) 
02140 {
02141     FILE *infile;
02142     CK_RV ckrv;
02143 
02144     infile = fopen(filename,"r");
02145 
02146     if (infile == NULL) {
02147        perror(filename);
02148        return CKR_FUNCTION_FAILED;
02149     }
02150 
02151     ckrv = process(infile, 0);
02152 
02153     fclose(infile);
02154     return ckrv;
02155 }
02156 
02157 CK_RV
02158 loop(const char *filename, const char *var, 
02159      CK_ULONG start, CK_ULONG end, CK_ULONG step) 
02160 {
02161     CK_ULONG i = 0;
02162     Value *value = 0;
02163     CK_RV ckrv;
02164 
02165     for (i=start; i < end; i += step)
02166     {
02167         value = NewValue(ArgULong, 1);
02168        *(CK_ULONG *)value->data = i;
02169        DeleteVariable(var);
02170        AddVariable(var, &value);
02171        ckrv = run(filename);
02172        argFree(value);
02173        if (ckrv == CKR_QUIT) {
02174            break;
02175        }
02176     }
02177     return ckrv;
02178 }
02179 
02180 int
02181 main(int argc, char **argv)
02182 {
02183     /* I suppose that some day we could parse some arguments */
02184     (void) process(stdin, 1);
02185     return 0;
02186 }