1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include <stdio.h>
6 #include <string.h>
7
8 #if defined(WIN32)
9 #undef __STDC__
10 #include "fcntl.h"
11 #include "io.h"
12 #include <fcntl.h>
13 #else
14 #include <unistd.h>
15 #include <fcntl.h>
16 #endif
17
18 #include "secutil.h"
19
20 #include <nspr.h>
21 #include "prtypes.h"
22 #include "prtime.h"
23 #include "prlong.h"
24 #include "prinrval.h"
25 #include "prenv.h"
26
27 #include "pkcs11.h"
28
29 #include "pk11table.h"
30
31 #ifndef O_BINARY
32 #define O_BINARY 0
33 #endif
34
35 CK_ULONG systemFlags;
36 #define FLAG_NEGATE 0x80000000
37 #define FLAG_Verify 0x00000001
38 #define FLAG_VerifyFile 0x00000002
39 #define CKR_QUIT 0x80000000
40
41 int ArgSize(ArgType type);
42 const char *constLookup(const char *bp, CK_ULONG *value, ConstType *type);
43
44 int
isNum(char c)45 isNum(char c)
46 {
47 return (c >= '0' && c <= '9');
48 }
49
50 int
isConst(const char * c)51 isConst(const char *c)
52 {
53 CK_ULONG value;
54 ConstType type;
55
56 constLookup(c, &value, &type);
57 return type != ConstNone;
58 }
59
60 /*
61 * see if the variable is really a 'size' function. This
62 * function may modify var if it is a size function.
63 */
64 char *
isSize(char * var,int * isArray)65 isSize(char *var, int *isArray)
66 {
67 char *ptr = NULL;
68 char *end;
69 int array = 0;
70
71 if (PL_strncasecmp(var, "sizeof(", /*)*/ 7) == 0) {
72 ptr = var + 7;
73 } else if (PL_strncasecmp(var, "size(", /*)*/ 5) == 0) {
74 ptr = var + 5;
75 } else if (PL_strncasecmp(var, "sizeofarray(", /*)*/ 12) == 0) {
76 ptr = var + 12;
77 array = 1;
78 } else if (PL_strncasecmp(var, "sizea(", /*)*/ 6) == 0) {
79 ptr = var + 6;
80 array = 1;
81 } else {
82 return NULL;
83 }
84 end = strchr(ptr, /*(*/ ')');
85 if (end == NULL) {
86 return NULL;
87 }
88 if (isArray)
89 *isArray = array;
90 *end = 0;
91 return ptr;
92 }
93
94 void
printConst(CK_ULONG value,ConstType type,int newLine)95 printConst(CK_ULONG value, ConstType type, int newLine)
96 {
97 int i;
98
99 for (i = 0; i < constCount; i++) {
100 if (consts[i].type == type && consts[i].value == value) {
101 printf("%s", consts[i].name);
102 break;
103 }
104 if (type == ConstNone && consts[i].value == value) {
105 printf("%s", consts[i].name);
106 break;
107 }
108 }
109 if (i == constCount) {
110 if ((type == ConstAvailableSizes) || (type == ConstCurrentSize)) {
111 printf("%lu", value);
112 } else {
113 printf("Unknown %s (%lu:0x%lx)", constTypeString[type], value, value);
114 }
115 }
116 if (newLine) {
117 printf("\n");
118 }
119 }
120
121 ConstType
getConstFromAttribute(CK_ATTRIBUTE_TYPE type)122 getConstFromAttribute(CK_ATTRIBUTE_TYPE type)
123 {
124 int i;
125
126 for (i = 0; i < constCount; i++) {
127 if (consts[i].type == ConstAttribute && consts[i].value == type) {
128 return consts[i].attrType;
129 }
130 }
131 return ConstNone;
132 }
133
134 void
printChars(const char * name,CK_ULONG size)135 printChars(const char *name, CK_ULONG size)
136 {
137 CK_ULONG i;
138 for (i = 0; i < size; i++) {
139 if (name[i] == 0) {
140 break;
141 }
142 printf("%c", name[i]);
143 }
144 printf("\n");
145 }
146
147 #define DUMP_LEN 16
148 void
printDump(const unsigned char * buf,int size)149 printDump(const unsigned char *buf, int size)
150 {
151 int i, j;
152
153 for (i = 0; i < size; i += DUMP_LEN) {
154 printf(" ");
155 for (j = 0; j < DUMP_LEN; j++) {
156 if (i + j < size) {
157 printf("%02x ", buf[i + j]);
158 } else {
159 printf(" ");
160 }
161 }
162 for (j = 0; j < DUMP_LEN; j++) {
163 if (i + j < size) {
164 if (buf[i + j] < ' ' || buf[i + j] >= 0x7f) {
165 printf(".");
166 } else {
167 printf("%c", buf[i + j]);
168 }
169 } else {
170 printf(" ");
171 }
172 }
173 printf("\n");
174 }
175 }
176
177 /*
178 * free an argument structure
179 */
180 void
argFreeData(Value * arg)181 argFreeData(Value *arg)
182 {
183 if (arg->data && ((arg->type & ArgStatic) == 0)) {
184 if ((arg->type & ArgMask) == ArgAttribute) {
185 int i;
186 CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)arg->data;
187
188 for (i = 0; i < arg->arraySize; i++) {
189 free(template[i].pValue);
190 }
191 }
192 if ((arg->type & ArgMask) == ArgInitializeArgs) {
193 CK_C_INITIALIZE_ARGS *init = (CK_C_INITIALIZE_ARGS *)arg->data;
194 if (init->LibraryParameters) {
195 free(init->LibraryParameters);
196 }
197 }
198 free(arg->data);
199 }
200 arg->type &= ~ArgStatic;
201 arg->data = NULL;
202 }
203
204 void
argFree(Value * arg)205 argFree(Value *arg)
206 {
207 if (arg == NULL)
208 return;
209
210 arg->reference--;
211 if (arg->reference == 0) {
212 if (arg->type & ArgFile) {
213 free(arg->filename);
214 }
215 argFreeData(arg);
216 free(arg);
217 }
218 }
219
220 /*
221 * free and argument list
222 */
223 void
parseFree(Value ** ap)224 parseFree(Value **ap)
225 {
226 int i;
227 for (i = 0; i < MAX_ARGS; i++) {
228 argFree(ap[i]);
229 }
230 }
231
232 /*
233 * getEnd: how for to the end of this argmument list?
234 */
235 int
getEnd(const char * bp)236 getEnd(const char *bp)
237 {
238 int count = 0;
239
240 while (*bp) {
241 if (*bp == ' ' || *bp == '\t' || *bp == '\n')
242 return count;
243 count++;
244 bp++;
245 }
246 return (count);
247 }
248
249 /*
250 * strip: return the first none white space character
251 */
252 const char *
strip(const char * bp)253 strip(const char *bp)
254 {
255 while (*bp && (*bp == ' ' || *bp == '\t' || *bp == '\n'))
256 bp++;
257 return bp;
258 }
259
260 /*
261 * read in the next argument into dp ... don't overflow
262 */
263 const char *
readChars(const char * bp,char * dp,int max)264 readChars(const char *bp, char *dp, int max)
265 {
266 int count = 1;
267 while (*bp) {
268 if (*bp == ' ' || *bp == '\t' || *bp == '\n') {
269 *dp = 0;
270 return bp;
271 }
272 *dp++ = *bp++;
273 if (++count == max)
274 break;
275 }
276 while (*bp && (*bp != ' ' && *bp != '\t' && *bp != '\n'))
277 bp++;
278 *dp = 0;
279 return (bp);
280 }
281
282 Value *varLookup(const char *bp, char *vname, int max, int *error);
283
284 CK_ULONG
getValue(const char * v,int * error)285 getValue(const char *v, int *error)
286 {
287 Value *varVal = NULL;
288 CK_ULONG retVal = 0;
289 ConstType type;
290 char tvar[512];
291
292 *error = 0;
293
294 varVal = varLookup(v, tvar, sizeof(tvar), error);
295
296 if (varVal) {
297 if ((varVal->type & ArgMask) == ArgULong) {
298 retVal = *(CK_ULONG *)varVal->data;
299 } else {
300 fprintf(stderr, "%s: is not a ulong\n", v);
301 *error = 1;
302 }
303 argFree(varVal);
304 return retVal;
305 }
306 constLookup(v, &retVal, &type);
307 return retVal;
308 }
309
310 Value *
NewValue(ArgType type,CK_ULONG arraySize)311 NewValue(ArgType type, CK_ULONG arraySize)
312 {
313 Value *value;
314
315 value = (Value *)malloc(sizeof(Value));
316 if (!value)
317 return NULL;
318 value->size = ArgSize(type) * arraySize;
319 value->type = type;
320 value->filename = NULL;
321 value->constType = ConstNone;
322 value->data = (void *)malloc(value->size);
323 if (!value->data) {
324 free(value);
325 return NULL;
326 }
327 value->reference = 1;
328 value->arraySize = (type == ArgChar) ? 1 : arraySize;
329
330 memset(value->data, 0, value->size);
331 return value;
332 }
333
334 #define INVALID_INDEX 0xffffffff
335
336 CK_ULONG
handleArray(char * vname,int * error)337 handleArray(char *vname, int *error)
338 {
339 char *bracket;
340 CK_ULONG index = INVALID_INDEX;
341
342 if ((bracket = strchr(vname, '[')) != 0) {
343 char *tmpv = bracket + 1;
344 *bracket = 0;
345 bracket = strchr(tmpv, ']');
346
347 if (bracket == 0) {
348 fprintf(stderr, "%s: missing closing brace\n", vname);
349 return INVALID_INDEX;
350 }
351 *bracket = 0;
352
353 index = getValue(tmpv, error);
354 if (*error == 1) {
355 return INVALID_INDEX;
356 } else if (index == INVALID_INDEX) {
357 fprintf(stderr, "%s: 0x%lx is an invalid index\n", vname, index);
358 *error = 1;
359 }
360 }
361 return index;
362 }
363
364 void *
makeArrayTarget(const char * vname,const Value * value,CK_ULONG index)365 makeArrayTarget(const char *vname, const Value *value, CK_ULONG index)
366 {
367 char *target;
368 CK_ULONG elementSize;
369
370 if (index >= (CK_ULONG)value->arraySize) {
371 fprintf(stderr, "%s[%lu]: index larger than array size (%d)\n",
372 vname, index, value->arraySize);
373 return NULL;
374 }
375
376 target = (char *)value->data;
377 elementSize = value->size / value->arraySize;
378 target += index * elementSize;
379 return target;
380 }
381
382 /*
383 * look up a variable from the variable chain
384 */
385 static Variable *varHead = NULL;
386 Value *
varLookup(const char * bp,char * vname,int max,int * error)387 varLookup(const char *bp, char *vname, int max, int *error)
388 {
389 Variable *current;
390 CK_ULONG index = INVALID_INDEX;
391 int isArray = 0;
392 char *ptr;
393 *error = 0;
394
395 if (bp != NULL) {
396 readChars(bp, vname, max);
397 }
398
399 /* don't make numbers into variables */
400 if (isNum(vname[0])) {
401 return NULL;
402 }
403 /* nor consts */
404 if (isConst(vname)) {
405 return NULL;
406 }
407 /* handle sizeof() */
408 if ((ptr = isSize(vname, &isArray)) != NULL) {
409 CK_ULONG size;
410 Value *targetValue = NULL;
411 Value *sourceValue = varLookup(NULL, ptr, 0, error);
412 if (!sourceValue) {
413 if (*error == 0) {
414 /* just didn't find it */
415 *error = 1;
416 fprintf(stderr, "Couldn't find variable %s to take size of\n",
417 ptr);
418 return NULL;
419 }
420 }
421 size = isArray ? sourceValue->arraySize : sourceValue->size;
422 targetValue = NewValue(ArgULong, 1);
423 memcpy(targetValue->data, &size, sizeof(size));
424
425 return targetValue;
426 }
427
428 /* modifies vname */
429 index = handleArray(vname, error);
430 if (*error == 1) {
431 return NULL;
432 }
433
434 for (current = varHead; current; current = current->next) {
435 if (PL_strcasecmp(current->vname, vname) == 0) {
436 char *target;
437 if (index == INVALID_INDEX) {
438 (current->value->reference)++;
439 return current->value;
440 }
441 target = makeArrayTarget(vname, current->value, index);
442 if (target) {
443 Value *element = NewValue(current->value->type, 1);
444 if (!element) {
445 fprintf(stderr, "MEMORY ERROR!\n");
446 *error = 1;
447 }
448 argFreeData(element);
449 element->data = target;
450 element->type |= ArgStatic;
451 return element;
452 }
453 *error = 1;
454 return NULL;
455 }
456 }
457 return NULL;
458 }
459
460 static CK_RV
list(void)461 list(void)
462 {
463 Variable *current;
464
465 if (varHead) {
466 printf(" %10s\t%16s\t%8s\tSize\tElements\n", "Name", "Type", "Const");
467 } else {
468 printf(" no variables set\n");
469 }
470
471 for (current = varHead; current; current = current->next) {
472 printf(" %10s\t%16s\t%8s\t%d\t%d\n", current->vname,
473 valueString[current->value->type & ArgMask],
474 constTypeString[current->value->constType],
475 current->value->size, current->value->arraySize);
476 }
477 return CKR_OK;
478 }
479
480 CK_RV
printFlags(const char * s,CK_ULONG flags,ConstType type)481 printFlags(const char *s, CK_ULONG flags, ConstType type)
482 {
483 CK_ULONG i;
484 int needComma = 0;
485
486 printf("%s", s);
487 for (i = 1; i; i = i << 1) {
488 if (flags & i) {
489 printf("%s", needComma ? "," : "");
490 printConst(i, type, 0);
491 needComma = 1;
492 }
493 }
494 if (!needComma) {
495 printf("Empty");
496 }
497 printf("\n");
498 return CKR_OK;
499 }
500
501 /*
502 * add a new variable to the chain
503 */
504 const char *
AddVariable(const char * bp,Value ** ptr)505 AddVariable(const char *bp, Value **ptr)
506 {
507 char vname[512];
508 Variable *current;
509 int index = INVALID_INDEX;
510 int size;
511 int error = 0;
512
513 bp = readChars(bp, vname, sizeof(vname));
514
515 /* don't make numbers into variables */
516 if (isNum(vname[0])) {
517 return bp;
518 }
519 /* or consts */
520 if (isConst(vname)) {
521 return bp;
522 }
523 /* or NULLs */
524 if (vname[0] == 0) {
525 return bp;
526 }
527 /* or sizeof */
528 if (isSize(vname, NULL)) {
529 return bp;
530 }
531 /* arrays values should be written back to the original */
532 index = handleArray(vname, &error);
533 if (error == 1) {
534 return bp;
535 }
536
537 for (current = varHead; current; current = current->next) {
538 if (PL_strcasecmp(current->vname, vname) == 0) {
539 char *target;
540 /* found a complete object, return the found one */
541 if (index == INVALID_INDEX) {
542 argFree(*ptr);
543 *ptr = current->value;
544 return bp;
545 }
546 /* found an array, update the array element */
547 target = makeArrayTarget(vname, current->value, index);
548 if (target) {
549 memcpy(target, (*ptr)->data, (*ptr)->size);
550 argFreeData(*ptr);
551 (*ptr)->data = target;
552 (*ptr)->type |= ArgStatic;
553 }
554 return bp;
555 }
556 }
557
558 /* we are looking for an array and didn't find one */
559 if (index != INVALID_INDEX) {
560 return bp;
561 }
562
563 current = (Variable *)malloc(sizeof(Variable));
564 size = strlen(vname);
565 current->vname = (char *)malloc(size + 1);
566 strcpy(current->vname, vname);
567 current->value = *ptr;
568 (*ptr)->reference++;
569
570 current->next = varHead;
571 varHead = current;
572 return bp;
573 }
574
575 ArgType
FindTypeByName(const char * typeName)576 FindTypeByName(const char *typeName)
577 {
578 int i;
579
580 for (i = 0; i < valueCount; i++) {
581 if (PL_strcasecmp(typeName, valueString[i]) == 0) {
582 return (ArgType)i;
583 }
584 if (valueString[i][0] == 'C' && valueString[i][1] == 'K' &&
585 valueString[i][2] == '_' &&
586 (PL_strcasecmp(typeName, &valueString[i][3]) == 0)) {
587 return (ArgType)i;
588 }
589 }
590 return ArgNone;
591 }
592
593 CK_RV
ArrayVariable(const char * bp,const char * typeName,CK_ULONG count)594 ArrayVariable(const char *bp, const char *typeName, CK_ULONG count)
595 {
596 ArgType type;
597 Value *value; /* new Value */
598
599 type = FindTypeByName(typeName);
600 if (type == ArgNone) {
601 fprintf(stderr, "Invalid type (%s)\n", typeName);
602 return CKR_FUNCTION_FAILED;
603 }
604 value = NewValue(type, count);
605 (void)AddVariable(bp, &value);
606 return CKR_OK;
607 }
608
609 #define MAX_TEMPLATE 25
610
611 CK_RV
ArrayTemplate(const char * bp,char * attributes)612 ArrayTemplate(const char *bp, char *attributes)
613 {
614 char aname[512];
615 CK_ULONG attributeTypes[MAX_TEMPLATE];
616 CK_ATTRIBUTE *template;
617 Value *value; /* new Value */
618 char *ap;
619 int i, count = 0;
620
621 memcpy(aname, attributes, strlen(attributes) + 1);
622
623 for (ap = aname, count = 0; ap && *ap && count < MAX_TEMPLATE; count++) {
624 char *cur = ap;
625 ConstType type;
626
627 ap = strchr(ap, ',');
628 if (ap) {
629 *ap++ = 0;
630 }
631
632 (void)constLookup(cur, &attributeTypes[count], &type);
633 if ((type != ConstAttribute) && (type != ConstNone)) {
634 fprintf(stderr, "Unknown Attribute %s\n", cur);
635 return CKR_FUNCTION_FAILED;
636 }
637 }
638
639 value = NewValue(ArgAttribute, count);
640
641 template = (CK_ATTRIBUTE *)value->data;
642 for (i = 0; i < count; i++) {
643 template[i].type = attributeTypes[i];
644 }
645 (void)AddVariable(bp, &value);
646 return CKR_OK;
647 }
648
649 CK_RV
BuildTemplate(Value * vp)650 BuildTemplate(Value *vp)
651 {
652 CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
653 int i;
654
655 for (i = 0; i < vp->arraySize; i++) {
656 if (((signed long)template[i].ulValueLen) > 0) {
657 if (template[i].pValue)
658 free(template[i].pValue);
659 template[i].pValue = malloc(template[i].ulValueLen);
660 }
661 }
662 return CKR_OK;
663 }
664
665 CK_RV
SetTemplate(Value * vp,CK_ULONG index,CK_ULONG value)666 SetTemplate(Value *vp, CK_ULONG index, CK_ULONG value)
667 {
668 CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
669 int isbool = 0;
670 CK_ULONG len;
671 ConstType attrType;
672
673 if (index >= (CK_ULONG)vp->arraySize) {
674 fprintf(stderr, "index (%lu) greater than array (%d)\n",
675 index, vp->arraySize);
676 return CKR_ARGUMENTS_BAD;
677 }
678 attrType = getConstFromAttribute(template[index].type);
679
680 if (attrType == ConstNone) {
681 fprintf(stderr, "can't set index (%lu) because ", index);
682 printConst(template[index].type, ConstAttribute, 0);
683 fprintf(stderr, " is not a CK_BBOOL or CK_ULONG\n");
684 return CKR_ARGUMENTS_BAD;
685 }
686 isbool = (attrType == ConstBool);
687 len = isbool ? sizeof(CK_BBOOL) : sizeof(CK_ULONG);
688 if ((template[index].ulValueLen != len) || (template[index].pValue)) {
689 free(template[index].pValue);
690 template[index].pValue = malloc(len);
691 template[index].ulValueLen = len;
692 }
693 if (isbool) {
694 *(CK_BBOOL *)template[index].pValue = (CK_BBOOL)value;
695 } else {
696 *(CK_ULONG *)template[index].pValue = (CK_ULONG)value;
697 }
698 return CKR_OK;
699 }
700
701 CK_RV
NewMechanism(const char * bp,CK_ULONG mechType)702 NewMechanism(const char *bp, CK_ULONG mechType)
703 {
704 Value *value; /* new Value */
705 CK_MECHANISM *mechanism;
706
707 value = NewValue(ArgMechanism, 1);
708 mechanism = (CK_MECHANISM *)value->data;
709 mechanism->mechanism = mechType;
710 mechanism->pParameter = NULL;
711 mechanism->ulParameterLen = 0;
712 (void)AddVariable(bp, &value);
713 return CKR_OK;
714 }
715
716 CK_RV
NewInitializeArgs(const char * bp,CK_ULONG flags,const char * param)717 NewInitializeArgs(const char *bp, CK_ULONG flags, const char *param)
718 {
719 Value *value; /* new Value */
720 CK_C_INITIALIZE_ARGS *init;
721
722 value = NewValue(ArgInitializeArgs, 1);
723 init = (CK_C_INITIALIZE_ARGS *)value->data;
724 init->flags = flags;
725 if (strcmp(param, "null") != 0) {
726 init->LibraryParameters = (CK_CHAR_PTR *)strdup(param);
727 }
728 (void)AddVariable(bp, &value);
729 return CKR_OK;
730 }
731
732 /*
733 * add a new variable to the chain
734 */
735 CK_RV
DeleteVariable(const char * bp)736 DeleteVariable(const char *bp)
737 {
738 char vname[512];
739 Variable **current;
740
741 bp = readChars(bp, vname, sizeof(vname));
742
743 for (current = &varHead; *current; current = &(*current)->next) {
744 if (PL_strcasecmp((*current)->vname, vname) == 0) {
745 argFree((*current)->value);
746 *current = (*current)->next;
747 break;
748 }
749 }
750 return CKR_OK;
751 }
752
753 /*
754 * convert an octal value to integer
755 */
756 CK_ULONG
otoi(const char * o)757 otoi(const char *o)
758 {
759 CK_ULONG value = 0;
760
761 while (*o) {
762 if ((*o >= '0') && (*o <= '7')) {
763 value = (value << 3) | (unsigned)(*o - '0');
764 } else {
765 break;
766 }
767 }
768 return value;
769 }
770
771 /*
772 * convert a hex value to integer
773 */
774 CK_ULONG
htoi(const char * x)775 htoi(const char *x)
776 {
777 CK_ULONG value = 0;
778
779 while (*x) {
780 if ((*x >= '0') && (*x <= '9')) {
781 value = (value << 4) | (unsigned)(*x - '0');
782 } else if ((*x >= 'a') && (*x <= 'f')) {
783 value = (value << 4) | (unsigned)(*x - 'a');
784 } else if ((*x >= 'A') && (*x <= 'F')) {
785 value = (value << 4) | (unsigned)(*x - 'A');
786 } else {
787 break;
788 }
789 }
790 return value;
791 }
792
793 /*
794 * look up or decode a constant value
795 */
796 const char *
constLookup(const char * bp,CK_ULONG * value,ConstType * type)797 constLookup(const char *bp, CK_ULONG *value, ConstType *type)
798 {
799 char vname[512];
800 int i;
801
802 bp = readChars(bp, vname, sizeof(vname));
803
804 for (i = 0; i < constCount; i++) {
805 if ((PL_strcasecmp(consts[i].name, vname) == 0) ||
806 PL_strcasecmp(consts[i].name + 5, vname) == 0) {
807 *value = consts[i].value;
808 *type = consts[i].type;
809 return bp;
810 }
811 }
812
813 *type = ConstNone;
814 if (vname[0] == '0' && vname[1] == 'X') {
815 *value = htoi(&vname[2]);
816 } else if (vname[0] == '0') {
817 *value = otoi(&vname[1]);
818 } else {
819 *value = atoi(vname);
820 }
821 return bp;
822 }
823
824 int
ArgSize(ArgType type)825 ArgSize(ArgType type)
826 {
827 int size = 0;
828 type &= ArgMask;
829
830 switch (type) {
831 case ArgNone:
832 size = 0;
833 break;
834 case ArgULong:
835 size = sizeof(CK_ULONG);
836 break;
837 case ArgVar:
838 size = 1; /* get's changed later */
839 break;
840 case ArgChar:
841 case ArgUTF8:
842 size = 1;
843 break;
844 case ArgInfo:
845 size = sizeof(CK_INFO);
846 break;
847 case ArgSlotInfo:
848 size = sizeof(CK_SLOT_INFO);
849 break;
850 case ArgTokenInfo:
851 size = sizeof(CK_TOKEN_INFO);
852 break;
853 case ArgSessionInfo:
854 size = sizeof(CK_SESSION_INFO);
855 break;
856 case ArgAttribute:
857 size = sizeof(CK_ATTRIBUTE);
858 break;
859 case ArgMechanism:
860 size = sizeof(CK_MECHANISM);
861 break;
862 case ArgMechanismInfo:
863 size = sizeof(CK_MECHANISM_INFO);
864 break;
865 case ArgInitializeArgs:
866 size = sizeof(CK_C_INITIALIZE_ARGS);
867 break;
868 case ArgFunctionList:
869 size = sizeof(CK_FUNCTION_LIST);
870 break;
871 default:
872 break;
873 }
874
875 return (size);
876 }
877
878 CK_RV
restore(const char * filename,Value * ptr)879 restore(const char *filename, Value *ptr)
880 {
881 int fd, size;
882
883 fd = open(filename, O_RDONLY | O_BINARY);
884 if (fd < 0) {
885 perror(filename);
886 return CKR_FUNCTION_FAILED;
887 }
888
889 size = read(fd, ptr->data, ptr->size);
890 if (systemFlags & FLAG_VerifyFile) {
891 printDump(ptr->data, ptr->size);
892 }
893 if (size < 0) {
894 perror(filename);
895 return CKR_FUNCTION_FAILED;
896 } else if (size != ptr->size) {
897 fprintf(stderr, "%s: only read %d bytes, needed to read %d bytes\n",
898 filename, size, ptr->size);
899 return CKR_FUNCTION_FAILED;
900 }
901 close(fd);
902 return CKR_OK;
903 }
904
905 CK_RV
save(const char * filename,Value * ptr)906 save(const char *filename, Value *ptr)
907 {
908 int fd, size;
909
910 fd = open(filename, O_WRONLY | O_BINARY | O_CREAT, 0666);
911 if (fd < 0) {
912 perror(filename);
913 return CKR_FUNCTION_FAILED;
914 }
915
916 size = write(fd, ptr->data, ptr->size);
917 if (size < 0) {
918 perror(filename);
919 return CKR_FUNCTION_FAILED;
920 } else if (size != ptr->size) {
921 fprintf(stderr, "%s: only wrote %d bytes, need to write %d bytes\n",
922 filename, size, ptr->size);
923 return CKR_FUNCTION_FAILED;
924 }
925 close(fd);
926 return CKR_OK;
927 }
928
929 static CK_RV
increment(Value * ptr,CK_ULONG value)930 increment(Value *ptr, CK_ULONG value)
931 {
932 if ((ptr->type & ArgMask) != ArgULong) {
933 return CKR_ARGUMENTS_BAD;
934 }
935 *(CK_ULONG *)ptr->data += value;
936 return CKR_OK;
937 }
938
939 static CK_RV
decrement(Value * ptr,CK_ULONG value)940 decrement(Value *ptr, CK_ULONG value)
941 {
942 if ((ptr->type & ArgMask) != ArgULong) {
943 return CKR_ARGUMENTS_BAD;
944 }
945 *(CK_ULONG *)ptr->data -= value;
946 return CKR_OK;
947 }
948
949 CK_RV
printArg(Value * ptr,int arg_number)950 printArg(Value *ptr, int arg_number)
951 {
952 ArgType type = ptr->type & ArgMask;
953 CK_INFO *info;
954 CK_SLOT_INFO *slotInfo;
955 CK_TOKEN_INFO *tokenInfo;
956 CK_SESSION_INFO *sessionInfo;
957 CK_ATTRIBUTE *attribute;
958 CK_MECHANISM *mechanism;
959 CK_MECHANISM_INFO *mechanismInfo;
960 CK_C_INITIALIZE_ARGS *initArgs;
961 CK_FUNCTION_LIST *functionList;
962 CK_RV ckrv = CKR_OK;
963 ConstType constType;
964
965 if (arg_number) {
966 printf("Arg %d: \n", arg_number);
967 }
968 if (ptr->arraySize > 1) {
969 Value element;
970 int i;
971 int elementSize = ptr->size / ptr->arraySize;
972 char *dp = (char *)ptr->data;
973
974 /* build a temporary Value to hold a single element */
975 element.type = type;
976 element.constType = ptr->constType;
977 element.size = elementSize;
978 element.filename = ptr->filename;
979 element.reference = 1;
980 element.arraySize = 1;
981 for (i = 0; i < ptr->arraySize; i++) {
982 printf(" -----[ %d ] -----\n", i);
983 element.data = (void *)&dp[i * elementSize];
984 (void)printArg(&element, 0);
985 }
986 return ckrv;
987 }
988 if (ptr->data == NULL) {
989 printf(" NULL ptr to a %s\n", valueString[type]);
990 return ckrv;
991 }
992 switch (type) {
993 case ArgNone:
994 printf(" None\n");
995 break;
996 case ArgULong:
997 printf(" %lu (0x%lx)\n", *((CK_ULONG *)ptr->data),
998 *((CK_ULONG *)ptr->data));
999 if (ptr->constType != ConstNone) {
1000 printf(" ");
1001 printConst(*(CK_ULONG *)ptr->data, ptr->constType, 1);
1002 }
1003 break;
1004 case ArgVar:
1005 printf(" %s\n", (char *)ptr->data);
1006 break;
1007 case ArgUTF8:
1008 printf(" %s\n", (char *)ptr->data);
1009 break;
1010 case ArgChar:
1011 printDump(ptr->data, ptr->size);
1012 break;
1013 case ArgInfo:
1014 #define VERSION(x) (x).major, (x).minor
1015 info = (CK_INFO *)ptr->data;
1016 printf(" Cryptoki Version: %d.%02d\n",
1017 VERSION(info->cryptokiVersion));
1018 printf(" Manufacturer ID: ");
1019 printChars((char *)info->manufacturerID,
1020 sizeof(info->manufacturerID));
1021 printFlags(" Flags: ", info->flags, ConstInfoFlags);
1022 printf(" Library Description: ");
1023 printChars((char *)info->libraryDescription,
1024 sizeof(info->libraryDescription));
1025 printf(" Library Version: %d.%02d\n",
1026 VERSION(info->libraryVersion));
1027 break;
1028 case ArgSlotInfo:
1029 slotInfo = (CK_SLOT_INFO *)ptr->data;
1030 printf(" Slot Description: ");
1031 printChars((char *)slotInfo->slotDescription,
1032 sizeof(slotInfo->slotDescription));
1033 printf(" Manufacturer ID: ");
1034 printChars((char *)slotInfo->manufacturerID,
1035 sizeof(slotInfo->manufacturerID));
1036 printFlags(" Flags: ", slotInfo->flags, ConstSlotFlags);
1037 printf(" Hardware Version: %d.%02d\n",
1038 VERSION(slotInfo->hardwareVersion));
1039 printf(" Firmware Version: %d.%02d\n",
1040 VERSION(slotInfo->firmwareVersion));
1041 break;
1042 case ArgTokenInfo:
1043 tokenInfo = (CK_TOKEN_INFO *)ptr->data;
1044 printf(" Label: ");
1045 printChars((char *)tokenInfo->label, sizeof(tokenInfo->label));
1046 printf(" Manufacturer ID: ");
1047 printChars((char *)tokenInfo->manufacturerID,
1048 sizeof(tokenInfo->manufacturerID));
1049 printf(" Model: ");
1050 printChars((char *)tokenInfo->model, sizeof(tokenInfo->model));
1051 printf(" Serial Number: ");
1052 printChars((char *)tokenInfo->serialNumber,
1053 sizeof(tokenInfo->serialNumber));
1054 printFlags(" Flags: ", tokenInfo->flags, ConstTokenFlags);
1055 printf(" Max Session Count: ");
1056 printConst(tokenInfo->ulMaxSessionCount, ConstAvailableSizes, 1);
1057 printf(" Session Count: ");
1058 printConst(tokenInfo->ulSessionCount, ConstCurrentSize, 1);
1059 printf(" RW Session Count: ");
1060 printConst(tokenInfo->ulMaxRwSessionCount, ConstAvailableSizes, 1);
1061 printf(" Max Pin Length : ");
1062 printConst(tokenInfo->ulMaxPinLen, ConstCurrentSize, 1);
1063 printf(" Min Pin Length : ");
1064 printConst(tokenInfo->ulMinPinLen, ConstCurrentSize, 1);
1065 printf(" Total Public Memory: ");
1066 printConst(tokenInfo->ulTotalPublicMemory, ConstAvailableSizes, 1);
1067 printf(" Free Public Memory: ");
1068 printConst(tokenInfo->ulFreePublicMemory, ConstCurrentSize, 1);
1069 printf(" Total Private Memory: ");
1070 printConst(tokenInfo->ulTotalPrivateMemory, ConstAvailableSizes, 1);
1071 printf(" Free Private Memory: ");
1072 printConst(tokenInfo->ulFreePrivateMemory, ConstCurrentSize, 1);
1073 printf(" Hardware Version: %d.%02d\n",
1074 VERSION(tokenInfo->hardwareVersion));
1075 printf(" Firmware Version: %d.%02d\n",
1076 VERSION(tokenInfo->firmwareVersion));
1077 printf(" UTC Time: ");
1078 printChars((char *)tokenInfo->utcTime, sizeof(tokenInfo->utcTime));
1079 break;
1080 case ArgSessionInfo:
1081 sessionInfo = (CK_SESSION_INFO *)ptr->data;
1082 printf(" SlotID: 0x%08lx\n", sessionInfo->slotID);
1083 printf(" State: ");
1084 printConst(sessionInfo->state, ConstSessionState, 1);
1085 printFlags(" Flags: ", sessionInfo->flags, ConstSessionFlags);
1086 printf(" Device error: %lu 0x%08lx\n", sessionInfo->ulDeviceError,
1087 sessionInfo->ulDeviceError);
1088 break;
1089 case ArgAttribute:
1090 attribute = (CK_ATTRIBUTE *)ptr->data;
1091 printf(" Attribute Type: ");
1092 printConst(attribute->type, ConstAttribute, 1);
1093 printf(" Attribute Data: ");
1094 if (attribute->pValue == NULL) {
1095 printf("NULL\n");
1096 printf("Attribute Len: %lu\n", attribute->ulValueLen);
1097 } else {
1098 constType = getConstFromAttribute(attribute->type);
1099 if (constType != ConstNone) {
1100 CK_ULONG value = (constType == ConstBool) ? *(CK_BBOOL *)attribute->pValue
1101 : *(CK_ULONG *)attribute->pValue;
1102 printConst(value, constType, 1);
1103 } else {
1104 printf("\n");
1105 printDump(attribute->pValue, attribute->ulValueLen);
1106 }
1107 }
1108 break;
1109 case ArgMechanism:
1110 mechanism = (CK_MECHANISM *)ptr->data;
1111 printf(" Mechanism Type: ");
1112 printConst(mechanism->mechanism, ConstMechanism, 1);
1113 printf(" Mechanism Data:\n");
1114 printDump(mechanism->pParameter, mechanism->ulParameterLen);
1115 break;
1116 case ArgMechanismInfo:
1117 mechanismInfo = (CK_MECHANISM_INFO *)ptr->data;
1118 printf(" Minimum Key Size: %ld\n", mechanismInfo->ulMinKeySize);
1119 printf(" Maximum Key Size: %ld\n", mechanismInfo->ulMaxKeySize);
1120 printFlags(" Flags: ", mechanismInfo->flags, ConstMechanismFlags);
1121 break;
1122 case ArgInitializeArgs:
1123 initArgs = (CK_C_INITIALIZE_ARGS *)ptr->data;
1124 printFlags(" Flags: ", initArgs->flags, ConstInitializeFlags);
1125 if (initArgs->LibraryParameters) {
1126 printf("Params: %s\n", (char *)initArgs->LibraryParameters);
1127 }
1128 case ArgFunctionList:
1129 functionList = (CK_FUNCTION_LIST *)ptr->data;
1130 printf(" Version: %d.%02d\n", VERSION(functionList->version));
1131 #ifdef notdef
1132 #undef CK_NEED_ARG_LIST
1133 #define CK_PKCS11_FUNCTION_INFO(func) \
1134 printf(" %s: 0x%08lx\n", #func, (unsigned long)functionList->func);
1135 #include "pkcs11f.h"
1136 #undef CK_NEED_ARG_LIST
1137 #undef CK_PKCS11_FUNCTION_INFO
1138 #endif
1139 default:
1140 ckrv = CKR_ARGUMENTS_BAD;
1141 break;
1142 }
1143
1144 return ckrv;
1145 }
1146
1147 /*
1148 * Feeling ambitious? turn this whole thing into lexx yacc parser
1149 * with full expressions.
1150 */
1151 Value **
parseArgs(int index,const char * bp)1152 parseArgs(int index, const char *bp)
1153 {
1154 const Commands *cp = &commands[index];
1155 int size = strlen(cp->fname);
1156 int i;
1157 CK_ULONG value;
1158 char vname[512];
1159 Value **argList, *possible;
1160 ConstType constType;
1161
1162 /*
1163 * skip pass the command
1164 */
1165 if ((cp->fname[0] == 'C') && (cp->fname[1] == '_') && (bp[1] != '_')) {
1166 size -= 2;
1167 }
1168 bp += size;
1169
1170 /*
1171 * Initialize our argument list
1172 */
1173 argList = (Value **)malloc(sizeof(Value *) * MAX_ARGS);
1174 for (i = 0; i < MAX_ARGS; i++) {
1175 argList[i] = NULL;
1176 }
1177
1178 /*
1179 * Walk the argument list parsing it...
1180 */
1181 for (i = 0; i < MAX_ARGS; i++) {
1182 ArgType type = cp->args[i] & ArgMask;
1183 int error;
1184
1185 /* strip blanks */
1186 bp = strip(bp);
1187
1188 /* if we hit ArgNone, we've nabbed all the arguments we need */
1189 if (type == ArgNone) {
1190 break;
1191 }
1192
1193 /* if we run out of space in the line, we weren't given enough
1194 * arguments... */
1195 if (*bp == '\0') {
1196 /* we're into optional arguments, ok to quit now */
1197 if (cp->args[i] & ArgOpt) {
1198 break;
1199 }
1200 fprintf(stderr, "%s: only %d args found,\n", cp->fname, i);
1201 parseFree(argList);
1202 return NULL;
1203 }
1204
1205 /* collect all the rest of the command line and send
1206 * it as a single argument */
1207 if (cp->args[i] & ArgFull) {
1208 int size = strlen(bp) + 1;
1209 argList[i] = NewValue(type, size);
1210 memcpy(argList[i]->data, bp, size);
1211 break;
1212 }
1213
1214 /*
1215 * look up the argument in our variable list first... only
1216 * exception is the new argument type for set...
1217 */
1218 error = 0;
1219 if ((cp->args[i] != (ArgVar | ArgNew)) &&
1220 (possible = varLookup(bp, vname, sizeof(vname), &error))) {
1221 /* ints are only compatible with other ints... all other types
1222 * are interchangeable... */
1223 if (type != ArgVar) { /* ArgVar's match anyone */
1224 if ((type == ArgULong) ^
1225 ((possible->type & ArgMask) == ArgULong)) {
1226 fprintf(stderr, "%s: Arg %d incompatible type with <%s>\n",
1227 cp->fname, i + 1, vname);
1228 argFree(possible);
1229 parseFree(argList);
1230 return NULL;
1231 }
1232 /*
1233 * ... that is as long as they are big enough...
1234 */
1235 if (ArgSize(type) > possible->size) {
1236 fprintf(stderr,
1237 "%s: Arg %d %s is too small (%d bytes needs to be %d bytes)\n",
1238 cp->fname, i + 1, vname, possible->size, ArgSize(type));
1239 argFree(possible);
1240 parseFree(argList);
1241 return NULL;
1242 }
1243 }
1244
1245 /* everything looks kosher here, use it */
1246 argList[i] = possible;
1247
1248 bp = readChars(bp, vname, sizeof(vname));
1249 if (cp->args[i] & ArgOut) {
1250 possible->type |= ArgOut;
1251 }
1252 continue;
1253 }
1254
1255 if (error == 1) {
1256 parseFree(argList);
1257 return NULL;
1258 }
1259
1260 /* create space for our argument */
1261 argList[i] = NewValue(type, 1);
1262
1263 if ((PL_strncasecmp(bp, "null", 4) == 0) && ((bp[4] == 0) ||
1264 (bp[4] ==
1265 ' ') ||
1266 (bp[4] ==
1267 '\t') ||
1268 (bp[4] == '\n'))) {
1269 if (cp->args[i] == ArgULong) {
1270 fprintf(stderr, "%s: Arg %d CK_ULONG can't be NULL\n",
1271 cp->fname, i + 1);
1272 parseFree(argList);
1273 return NULL;
1274 }
1275 argFreeData(argList[i]);
1276 argList[i]->data = NULL;
1277 argList[i]->size = 0;
1278 bp += 4;
1279 if (*bp)
1280 bp++;
1281 continue;
1282 }
1283
1284 /* if we're an output variable, we need to add it */
1285 if (cp->args[i] & ArgOut) {
1286 if (PL_strncasecmp(bp, "file(", 5) == 0 /* ) */) {
1287 char filename[512];
1288 bp = readChars(bp + 5, filename, sizeof(filename));
1289 size = PL_strlen(filename);
1290 if ((size > 0) && (/* ( */ filename[size - 1] == ')')) {
1291 filename[size - 1] = 0;
1292 }
1293 filename[size] = 0;
1294 argList[i]->filename = (char *)malloc(size + 1);
1295
1296 PL_strcpy(argList[i]->filename, filename);
1297
1298 argList[i]->type |= ArgOut | ArgFile;
1299 break;
1300 }
1301 bp = AddVariable(bp, &argList[i]);
1302 argList[i]->type |= ArgOut;
1303 continue;
1304 }
1305
1306 if (PL_strncasecmp(bp, "file(", 5) == 0 /* ) */) {
1307 char filename[512];
1308
1309 bp = readChars(bp + 5, filename, sizeof(filename));
1310 size = PL_strlen(filename);
1311 if ((size > 0) && (/* ( */ filename[size - 1] == ')')) {
1312 filename[size - 1] = 0;
1313 }
1314
1315 if (restore(filename, argList[i]) != CKR_OK) {
1316 parseFree(argList);
1317 return NULL;
1318 }
1319 continue;
1320 }
1321
1322 switch (type) {
1323 case ArgULong:
1324 bp = constLookup(bp, &value, &constType);
1325 *(int *)argList[i]->data = value;
1326 argList[i]->constType = constType;
1327 break;
1328 case ArgVar:
1329 argFreeData(argList[i]);
1330 size = getEnd(bp) + 1;
1331 argList[i]->data = (void *)malloc(size);
1332 argList[i]->size = size;
1333 /* fall through */
1334 case ArgInfo:
1335 case ArgSlotInfo:
1336 case ArgTokenInfo:
1337 case ArgSessionInfo:
1338 case ArgAttribute:
1339 case ArgMechanism:
1340 case ArgMechanismInfo:
1341 case ArgInitializeArgs:
1342 case ArgUTF8:
1343 case ArgChar:
1344 bp = readChars(bp, (char *)argList[i]->data, argList[i]->size);
1345 case ArgNone:
1346 default:
1347 break;
1348 }
1349 }
1350
1351 return argList;
1352 }
1353
1354 /* lookup the command in the array */
1355 int
lookup(const char * buf)1356 lookup(const char *buf)
1357 {
1358 int size, i;
1359 int buflen;
1360
1361 buflen = PL_strlen(buf);
1362
1363 for (i = 0; i < commandCount; i++) {
1364 size = PL_strlen(commands[i].fname);
1365
1366 if (size <= buflen) {
1367 if (PL_strncasecmp(buf, commands[i].fname, size) == 0) {
1368 return i;
1369 }
1370 }
1371 if (size - 2 <= buflen) {
1372 if (commands[i].fname[0] == 'C' && commands[i].fname[1] == '_' &&
1373 (PL_strncasecmp(buf, &commands[i].fname[2], size - 2) == 0)) {
1374 return i;
1375 }
1376 }
1377 }
1378 fprintf(stderr, "Can't find command %s\n", buf);
1379 return -1;
1380 }
1381
1382 void
putOutput(Value ** ptr)1383 putOutput(Value **ptr)
1384 {
1385 int i;
1386
1387 for (i = 0; i < MAX_ARGS; i++) {
1388 ArgType type;
1389
1390 if (ptr[i] == NULL)
1391 break;
1392
1393 type = ptr[i]->type;
1394
1395 ptr[i]->type &= ~ArgOut;
1396 if (type == ArgNone) {
1397 break;
1398 }
1399 if (type & ArgOut) {
1400 (void)printArg(ptr[i], i + 1);
1401 }
1402 if (type & ArgFile) {
1403 save(ptr[i]->filename, ptr[i]);
1404 free(ptr[i]->filename);
1405 ptr[i]->filename = NULL; /* paranoia */
1406 }
1407 }
1408 }
1409
1410 CK_RV
unloadModule(Module * module)1411 unloadModule(Module *module)
1412 {
1413 char *disableUnload = NULL;
1414
1415 disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
1416
1417 if (module->library && !disableUnload) {
1418 PR_UnloadLibrary(module->library);
1419 }
1420
1421 module->library = NULL;
1422 module->functionList = NULL;
1423
1424 return CKR_OK;
1425 }
1426
1427 CK_RV
loadModule(Module * module,char * library)1428 loadModule(Module *module, char *library)
1429 {
1430 PRLibrary *newLibrary;
1431 CK_C_GetFunctionList getFunctionList;
1432 CK_FUNCTION_LIST *functionList;
1433 CK_RV ckrv;
1434
1435 newLibrary = PR_LoadLibrary(library);
1436 if (!newLibrary) {
1437 fprintf(stderr, "Couldn't load library %s\n", library);
1438 return CKR_FUNCTION_FAILED;
1439 }
1440 getFunctionList = (CK_C_GetFunctionList)
1441 PR_FindSymbol(newLibrary, "C_GetFunctionList");
1442 if (!getFunctionList) {
1443 fprintf(stderr, "Couldn't find \"C_GetFunctionList\" in %s\n", library);
1444 return CKR_FUNCTION_FAILED;
1445 }
1446
1447 ckrv = (*getFunctionList)(&functionList);
1448 if (ckrv != CKR_OK) {
1449 return ckrv;
1450 }
1451
1452 if (module->library) {
1453 PR_UnloadLibrary(module->library);
1454 }
1455
1456 module->library = newLibrary;
1457 module->functionList = functionList;
1458
1459 return CKR_OK;
1460 }
1461
1462 static void
printHelp(int index,int full)1463 printHelp(int index, int full)
1464 {
1465 int j;
1466 printf(" %s", commands[index].fname);
1467 for (j = 0; j < MAX_ARGS; j++) {
1468 ArgType type = commands[index].args[j] & ArgMask;
1469 if (type == ArgNone) {
1470 break;
1471 }
1472 printf(" %s", valueString[type]);
1473 }
1474 printf("\n");
1475 printf(" %s\n", commands[index].helpString);
1476 }
1477
1478 /* add Topical help here ! */
1479 static CK_RV
printTopicHelp(char * topic)1480 printTopicHelp(char *topic)
1481 {
1482 int size, i;
1483 int topicLen;
1484
1485 topicLen = PL_strlen(topic);
1486
1487 for (i = 0; i < topicCount; i++) {
1488 size = PL_strlen(topics[i].name);
1489
1490 if (size <= topicLen) {
1491 if (PL_strncasecmp(topic, topics[i].name, size) == 0) {
1492 break;
1493 }
1494 }
1495 }
1496
1497 if (i == topicCount) {
1498 fprintf(stderr, "Can't find topic '%s'\n", topic);
1499 return CKR_DATA_INVALID;
1500 }
1501
1502 printf(" %s", topic);
1503 printf("\n");
1504 printf(" %s\n", topics[i].helpString);
1505 return CKR_OK;
1506 }
1507
1508 static CK_RV
printGeneralHelp(void)1509 printGeneralHelp(void)
1510 {
1511 int i;
1512 printf(" To get help on commands, select from the list below:");
1513 for (i = 0; i < commandCount; i++) {
1514 if (i % 5 == 0)
1515 printf("\n");
1516 printf("%s,", commands[i].fname);
1517 }
1518 printf("\n");
1519 /* print help topics */
1520 printf(" To get help on a topic, select from the list below:");
1521 for (i = 0; i < topicCount; i++) {
1522 if (i % 5 == 0)
1523 printf("\n");
1524 printf("%s,", topics[i].name);
1525 }
1526 printf("\n");
1527 return CKR_OK;
1528 }
1529
1530 static CK_RV
quitIf(CK_ULONG a,const char * cmp,CK_ULONG b)1531 quitIf(CK_ULONG a, const char *cmp, CK_ULONG b)
1532 {
1533 if (strcmp(cmp, "<") == 0) {
1534 return (a < b) ? CKR_QUIT : CKR_OK;
1535 } else if (strcmp(cmp, ">") == 0) {
1536 return (a > b) ? CKR_QUIT : CKR_OK;
1537 } else if (strcmp(cmp, "<=") == 0) {
1538 return (a <= b) ? CKR_QUIT : CKR_OK;
1539 } else if (strcmp(cmp, ">=") == 0) {
1540 return (a >= b) ? CKR_QUIT : CKR_OK;
1541 } else if (strcmp(cmp, "=") == 0) {
1542 return (a == b) ? CKR_QUIT : CKR_OK;
1543 } else if (strcmp(cmp, "!=") == 0) {
1544 return (a != b) ? CKR_QUIT : CKR_OK;
1545 }
1546 printf("Unkown integer comparator: '%s'\n", cmp);
1547 return CKR_ARGUMENTS_BAD;
1548 }
1549
1550 static CK_RV
quitIfString(const char * a,const char * cmp,const char * b)1551 quitIfString(const char *a, const char *cmp, const char *b)
1552 {
1553
1554 if (strcmp(cmp, "=") == 0) {
1555 return (strcmp(a, b) == 0) ? CKR_QUIT : CKR_OK;
1556 } else if (strcmp(cmp, "!=") == 0) {
1557 return (strcmp(a, b) != 0) ? CKR_QUIT : CKR_OK;
1558 }
1559 printf("Unkown string comparator: '%s'\n", cmp);
1560 return CKR_ARGUMENTS_BAD;
1561 }
1562
1563 CK_RV run(const char *);
1564 CK_RV timeCommand(const char *);
1565 CK_RV loop(const char *filename, const char *var,
1566 CK_ULONG start, CK_ULONG end, CK_ULONG step);
1567
1568 /*
1569 * Actually dispatch the function... Bad things happen
1570 * if these don't match the commands array.
1571 */
1572 CK_RV
do_func(int index,Value ** a)1573 do_func(int index, Value **a)
1574 {
1575 int value, helpIndex;
1576 static Module module = { NULL, NULL };
1577 CK_FUNCTION_LIST *func = module.functionList;
1578
1579 switch (commands[index].fType) {
1580 case F_C_Initialize:
1581 if (!func)
1582 return CKR_CRYPTOKI_NOT_INITIALIZED;
1583 return func->C_Initialize((void *)a[0]->data);
1584 case F_C_Finalize:
1585 if (!func)
1586 return CKR_CRYPTOKI_NOT_INITIALIZED;
1587 return func->C_Finalize((void *)a[0]->data);
1588 case F_C_GetInfo:
1589 if (!func)
1590 return CKR_CRYPTOKI_NOT_INITIALIZED;
1591 return func->C_GetInfo((CK_INFO *)a[0]->data);
1592 case F_C_GetFunctionList:
1593 if (!func)
1594 return CKR_CRYPTOKI_NOT_INITIALIZED;
1595 return func->C_GetFunctionList((CK_FUNCTION_LIST **)a[0]->data);
1596 case F_C_GetSlotList:
1597 if (!func)
1598 return CKR_CRYPTOKI_NOT_INITIALIZED;
1599 return func->C_GetSlotList((CK_BBOOL) * (CK_ULONG *)a[0]->data,
1600 (CK_SLOT_ID *)a[1]->data,
1601 (CK_ULONG *)a[2]->data);
1602 case F_C_GetSlotInfo:
1603 if (!func)
1604 return CKR_CRYPTOKI_NOT_INITIALIZED;
1605 return func->C_GetSlotInfo(*(CK_ULONG *)a[0]->data,
1606 (CK_SLOT_INFO *)a[1]->data);
1607 case F_C_GetTokenInfo:
1608 if (!func)
1609 return CKR_CRYPTOKI_NOT_INITIALIZED;
1610 return func->C_GetTokenInfo(*(CK_ULONG *)a[0]->data,
1611 (CK_TOKEN_INFO *)a[1]->data);
1612 case F_C_GetMechanismList:
1613 if (!func)
1614 return CKR_CRYPTOKI_NOT_INITIALIZED;
1615 if (a[1]->data) {
1616 a[1]->constType = ConstMechanism;
1617 }
1618 return func->C_GetMechanismList(*(CK_ULONG *)a[0]->data,
1619 (CK_MECHANISM_TYPE *)a[1]->data,
1620 (CK_ULONG *)a[2]->data);
1621 case F_C_GetMechanismInfo:
1622 if (!func)
1623 return CKR_CRYPTOKI_NOT_INITIALIZED;
1624 return func->C_GetMechanismInfo(*(CK_ULONG *)a[0]->data,
1625 *(CK_ULONG *)a[1]->data,
1626 (CK_MECHANISM_INFO *)a[2]->data);
1627 case F_C_InitToken:
1628 if (!func)
1629 return CKR_CRYPTOKI_NOT_INITIALIZED;
1630 return func->C_InitToken(*(CK_ULONG *)a[0]->data,
1631 (CK_CHAR *)a[1]->data,
1632 *(CK_ULONG *)a[2]->data,
1633 (CK_CHAR *)a[3]->data);
1634 case F_C_InitPIN:
1635 if (!func)
1636 return CKR_CRYPTOKI_NOT_INITIALIZED;
1637 return func->C_InitPIN(*(CK_ULONG *)a[0]->data,
1638 (CK_CHAR *)a[1]->data,
1639 *(CK_ULONG *)a[2]->data);
1640 case F_C_SetPIN:
1641 if (!func)
1642 return CKR_CRYPTOKI_NOT_INITIALIZED;
1643 return func->C_SetPIN(*(CK_ULONG *)a[0]->data,
1644 (CK_CHAR *)a[1]->data,
1645 *(CK_ULONG *)a[2]->data,
1646 (CK_CHAR *)a[3]->data,
1647 *(CK_ULONG *)a[4]->data);
1648 case F_C_OpenSession:
1649 if (!func)
1650 return CKR_CRYPTOKI_NOT_INITIALIZED;
1651 return func->C_OpenSession(*(CK_ULONG *)a[0]->data,
1652 *(CK_ULONG *)a[1]->data,
1653 (void *)NULL,
1654 (CK_NOTIFY)NULL,
1655 (CK_ULONG *)a[2]->data);
1656 case F_C_CloseSession:
1657 if (!func)
1658 return CKR_CRYPTOKI_NOT_INITIALIZED;
1659 return func->C_CloseSession(*(CK_ULONG *)a[0]->data);
1660 case F_C_CloseAllSessions:
1661 if (!func)
1662 return CKR_CRYPTOKI_NOT_INITIALIZED;
1663 return func->C_CloseAllSessions(*(CK_ULONG *)a[0]->data);
1664 case F_C_GetSessionInfo:
1665 if (!func)
1666 return CKR_CRYPTOKI_NOT_INITIALIZED;
1667 return func->C_GetSessionInfo(*(CK_ULONG *)a[0]->data,
1668 (CK_SESSION_INFO *)a[1]->data);
1669 case F_C_GetOperationState:
1670 if (!func)
1671 return CKR_CRYPTOKI_NOT_INITIALIZED;
1672 return func->C_GetOperationState(*(CK_ULONG *)a[0]->data,
1673 (CK_BYTE *)a[1]->data,
1674 (CK_ULONG *)a[2]->data);
1675 case F_C_SetOperationState:
1676 if (!func)
1677 return CKR_CRYPTOKI_NOT_INITIALIZED;
1678 return func->C_SetOperationState(*(CK_ULONG *)a[0]->data,
1679 (CK_CHAR *)a[1]->data,
1680 *(CK_ULONG *)a[2]->data,
1681 *(CK_ULONG *)a[3]->data,
1682 *(CK_ULONG *)a[4]->data);
1683 case F_C_Login:
1684 if (!func)
1685 return CKR_CRYPTOKI_NOT_INITIALIZED;
1686 return func->C_Login(*(CK_ULONG *)a[0]->data,
1687 *(CK_ULONG *)a[1]->data,
1688 (CK_CHAR *)a[2]->data,
1689 *(CK_ULONG *)a[3]->data);
1690 case F_C_Logout:
1691 if (!func)
1692 return CKR_CRYPTOKI_NOT_INITIALIZED;
1693 return func->C_Logout(*(CK_ULONG *)a[0]->data);
1694 case F_C_CreateObject:
1695 if (!func)
1696 return CKR_CRYPTOKI_NOT_INITIALIZED;
1697 return func->C_CreateObject(*(CK_ULONG *)a[0]->data,
1698 (CK_ATTRIBUTE *)a[1]->data,
1699 *(CK_ULONG *)a[2]->data,
1700 (CK_ULONG *)a[3]->data);
1701 case F_C_CopyObject:
1702 if (!func)
1703 return CKR_CRYPTOKI_NOT_INITIALIZED;
1704 return func->C_CopyObject(*(CK_ULONG *)a[0]->data,
1705 *(CK_ULONG *)a[0]->data,
1706 (CK_ATTRIBUTE *)a[1]->data,
1707 *(CK_ULONG *)a[2]->data,
1708 (CK_ULONG *)a[3]->data);
1709 case F_C_DestroyObject:
1710 if (!func)
1711 return CKR_CRYPTOKI_NOT_INITIALIZED;
1712 return func->C_DestroyObject(*(CK_ULONG *)a[0]->data,
1713 *(CK_ULONG *)a[1]->data);
1714 case F_C_GetObjectSize:
1715 if (!func)
1716 return CKR_CRYPTOKI_NOT_INITIALIZED;
1717 return func->C_GetObjectSize(*(CK_ULONG *)a[0]->data,
1718 *(CK_ULONG *)a[1]->data,
1719 (CK_ULONG *)a[2]->data);
1720 case F_C_GetAttributeValue:
1721 if (!func)
1722 return CKR_CRYPTOKI_NOT_INITIALIZED;
1723 return func->C_GetAttributeValue(*(CK_ULONG *)a[0]->data,
1724 *(CK_ULONG *)a[1]->data,
1725 (CK_ATTRIBUTE *)a[2]->data,
1726 *(CK_ULONG *)a[3]->data);
1727 case F_C_SetAttributeValue:
1728 if (!func)
1729 return CKR_CRYPTOKI_NOT_INITIALIZED;
1730 return func->C_SetAttributeValue(*(CK_ULONG *)a[0]->data,
1731 *(CK_ULONG *)a[1]->data,
1732 (CK_ATTRIBUTE *)a[2]->data,
1733 *(CK_ULONG *)a[3]->data);
1734 case F_C_FindObjectsInit:
1735 if (!func)
1736 return CKR_CRYPTOKI_NOT_INITIALIZED;
1737 return func->C_FindObjectsInit(*(CK_ULONG *)a[0]->data,
1738 (CK_ATTRIBUTE *)a[1]->data,
1739 *(CK_ULONG *)a[2]->data);
1740 case F_C_FindObjects:
1741 if (!func)
1742 return CKR_CRYPTOKI_NOT_INITIALIZED;
1743 return func->C_FindObjects(*(CK_ULONG *)a[0]->data,
1744 (CK_ULONG *)a[1]->data,
1745 *(CK_ULONG *)a[2]->data,
1746 (CK_ULONG *)a[3]->data);
1747 case F_C_FindObjectsFinal:
1748 if (!func)
1749 return CKR_CRYPTOKI_NOT_INITIALIZED;
1750 return func->C_FindObjectsFinal(*(CK_ULONG *)a[0]->data);
1751 case F_C_EncryptInit:
1752 if (!func)
1753 return CKR_CRYPTOKI_NOT_INITIALIZED;
1754 return func->C_EncryptInit(*(CK_ULONG *)a[0]->data,
1755 (CK_MECHANISM *)a[1]->data,
1756 *(CK_ULONG *)a[2]->data);
1757 case F_C_Encrypt:
1758 if (!func)
1759 return CKR_CRYPTOKI_NOT_INITIALIZED;
1760 return func->C_Encrypt(*(CK_ULONG *)a[0]->data,
1761 (CK_CHAR *)a[1]->data,
1762 *(CK_ULONG *)a[2]->data,
1763 (CK_CHAR *)a[3]->data,
1764 (CK_ULONG *)a[4]->data);
1765 case F_C_EncryptUpdate:
1766 if (!func)
1767 return CKR_CRYPTOKI_NOT_INITIALIZED;
1768 return func->C_EncryptUpdate(*(CK_ULONG *)a[0]->data,
1769 (CK_CHAR *)a[1]->data,
1770 *(CK_ULONG *)a[2]->data,
1771 (CK_CHAR *)a[3]->data,
1772 (CK_ULONG *)a[4]->data);
1773 case F_C_EncryptFinal:
1774 if (!func)
1775 return CKR_CRYPTOKI_NOT_INITIALIZED;
1776 return func->C_EncryptFinal(*(CK_ULONG *)a[0]->data,
1777 (CK_CHAR *)a[1]->data,
1778 (CK_ULONG *)a[2]->data);
1779 case F_C_DecryptInit:
1780 if (!func)
1781 return CKR_CRYPTOKI_NOT_INITIALIZED;
1782 return func->C_DecryptInit(*(CK_ULONG *)a[0]->data,
1783 (CK_MECHANISM *)a[1]->data,
1784 *(CK_ULONG *)a[2]->data);
1785 case F_C_Decrypt:
1786 if (!func)
1787 return CKR_CRYPTOKI_NOT_INITIALIZED;
1788 return func->C_Decrypt(*(CK_ULONG *)a[0]->data,
1789 (CK_CHAR *)a[1]->data,
1790 *(CK_ULONG *)a[2]->data,
1791 (CK_CHAR *)a[3]->data,
1792 (CK_ULONG *)a[4]->data);
1793 case F_C_DecryptUpdate:
1794 if (!func)
1795 return CKR_CRYPTOKI_NOT_INITIALIZED;
1796 return func->C_DecryptUpdate(*(CK_ULONG *)a[0]->data,
1797 (CK_CHAR *)a[1]->data,
1798 *(CK_ULONG *)a[2]->data,
1799 (CK_CHAR *)a[3]->data,
1800 (CK_ULONG *)a[4]->data);
1801 case F_C_DecryptFinal:
1802 if (!func)
1803 return CKR_CRYPTOKI_NOT_INITIALIZED;
1804 return func->C_DecryptFinal(*(CK_ULONG *)a[0]->data,
1805 (CK_CHAR *)a[1]->data,
1806 (CK_ULONG *)a[2]->data);
1807 case F_C_DigestInit:
1808 if (!func)
1809 return CKR_CRYPTOKI_NOT_INITIALIZED;
1810 return func->C_DigestInit(*(CK_ULONG *)a[0]->data,
1811 (CK_MECHANISM *)a[1]->data);
1812 case F_C_Digest:
1813 if (!func)
1814 return CKR_CRYPTOKI_NOT_INITIALIZED;
1815 return func->C_Digest(*(CK_ULONG *)a[0]->data,
1816 (CK_CHAR *)a[1]->data,
1817 *(CK_ULONG *)a[2]->data,
1818 (CK_CHAR *)a[3]->data,
1819 (CK_ULONG *)a[4]->data);
1820 case F_C_DigestUpdate:
1821 if (!func)
1822 return CKR_CRYPTOKI_NOT_INITIALIZED;
1823 return func->C_DigestUpdate(*(CK_ULONG *)a[0]->data,
1824 (CK_CHAR *)a[1]->data,
1825 *(CK_ULONG *)a[2]->data);
1826 case F_C_DigestKey:
1827 if (!func)
1828 return CKR_CRYPTOKI_NOT_INITIALIZED;
1829 return func->C_DigestKey(*(CK_ULONG *)a[0]->data,
1830 *(CK_ULONG *)a[1]->data);
1831 case F_C_DigestFinal:
1832 if (!func)
1833 return CKR_CRYPTOKI_NOT_INITIALIZED;
1834 return func->C_DigestFinal(*(CK_ULONG *)a[0]->data,
1835 (CK_CHAR *)a[1]->data,
1836 (CK_ULONG *)a[2]->data);
1837 case F_C_SignInit:
1838 if (!func)
1839 return CKR_CRYPTOKI_NOT_INITIALIZED;
1840 return func->C_SignInit(*(CK_ULONG *)a[0]->data,
1841 (CK_MECHANISM *)a[1]->data,
1842 *(CK_ULONG *)a[2]->data);
1843 case F_C_Sign:
1844 if (!func)
1845 return CKR_CRYPTOKI_NOT_INITIALIZED;
1846 return func->C_Sign(*(CK_ULONG *)a[0]->data,
1847 (CK_CHAR *)a[1]->data,
1848 *(CK_ULONG *)a[2]->data,
1849 (CK_CHAR *)a[3]->data,
1850 (CK_ULONG *)a[4]->data);
1851 case F_C_SignUpdate:
1852 if (!func)
1853 return CKR_CRYPTOKI_NOT_INITIALIZED;
1854 return func->C_SignUpdate(*(CK_ULONG *)a[0]->data,
1855 (CK_CHAR *)a[1]->data,
1856 *(CK_ULONG *)a[2]->data);
1857 case F_C_SignFinal:
1858 if (!func)
1859 return CKR_CRYPTOKI_NOT_INITIALIZED;
1860 return func->C_SignFinal(*(CK_ULONG *)a[0]->data,
1861 (CK_CHAR *)a[1]->data,
1862 (CK_ULONG *)a[2]->data);
1863
1864 case F_C_SignRecoverInit:
1865 if (!func)
1866 return CKR_CRYPTOKI_NOT_INITIALIZED;
1867 return func->C_SignRecoverInit(*(CK_ULONG *)a[0]->data,
1868 (CK_MECHANISM *)a[1]->data,
1869 *(CK_ULONG *)a[2]->data);
1870 case F_C_SignRecover:
1871 if (!func)
1872 return CKR_CRYPTOKI_NOT_INITIALIZED;
1873 return func->C_SignRecover(*(CK_ULONG *)a[0]->data,
1874 (CK_CHAR *)a[1]->data,
1875 *(CK_ULONG *)a[2]->data,
1876 (CK_CHAR *)a[3]->data,
1877 (CK_ULONG *)a[4]->data);
1878 case F_C_VerifyInit:
1879 if (!func)
1880 return CKR_CRYPTOKI_NOT_INITIALIZED;
1881 return func->C_VerifyInit(*(CK_ULONG *)a[0]->data,
1882 (CK_MECHANISM *)a[1]->data,
1883 *(CK_ULONG *)a[2]->data);
1884 case F_C_Verify:
1885 if (!func)
1886 return CKR_CRYPTOKI_NOT_INITIALIZED;
1887 return func->C_Verify(*(CK_ULONG *)a[0]->data,
1888 (CK_CHAR *)a[1]->data,
1889 *(CK_ULONG *)a[2]->data,
1890 (CK_CHAR *)a[3]->data,
1891 *(CK_ULONG *)a[4]->data);
1892 case F_C_VerifyUpdate:
1893 if (!func)
1894 return CKR_CRYPTOKI_NOT_INITIALIZED;
1895 return func->C_VerifyUpdate(*(CK_ULONG *)a[0]->data,
1896 (CK_CHAR *)a[1]->data,
1897 *(CK_ULONG *)a[2]->data);
1898 case F_C_VerifyFinal:
1899 if (!func)
1900 return CKR_CRYPTOKI_NOT_INITIALIZED;
1901 return func->C_VerifyFinal(*(CK_ULONG *)a[0]->data,
1902 (CK_CHAR *)a[1]->data,
1903 *(CK_ULONG *)a[2]->data);
1904
1905 case F_C_VerifyRecoverInit:
1906 if (!func)
1907 return CKR_CRYPTOKI_NOT_INITIALIZED;
1908 return func->C_VerifyRecoverInit(*(CK_ULONG *)a[0]->data,
1909 (CK_MECHANISM *)a[1]->data,
1910 *(CK_ULONG *)a[2]->data);
1911 case F_C_VerifyRecover:
1912 if (!func)
1913 return CKR_CRYPTOKI_NOT_INITIALIZED;
1914 return func->C_VerifyRecover(*(CK_ULONG *)a[0]->data,
1915 (CK_CHAR *)a[1]->data,
1916 *(CK_ULONG *)a[2]->data,
1917 (CK_CHAR *)a[3]->data,
1918 (CK_ULONG *)a[4]->data);
1919 case F_C_DigestEncryptUpdate:
1920 if (!func)
1921 return CKR_CRYPTOKI_NOT_INITIALIZED;
1922 return func->C_DigestEncryptUpdate(*(CK_ULONG *)a[0]->data,
1923 (CK_CHAR *)a[1]->data,
1924 *(CK_ULONG *)a[2]->data,
1925 (CK_CHAR *)a[3]->data,
1926 (CK_ULONG *)a[4]->data);
1927 case F_C_DecryptDigestUpdate:
1928 if (!func)
1929 return CKR_CRYPTOKI_NOT_INITIALIZED;
1930 return func->C_DecryptDigestUpdate(*(CK_ULONG *)a[0]->data,
1931 (CK_CHAR *)a[1]->data,
1932 *(CK_ULONG *)a[2]->data,
1933 (CK_CHAR *)a[3]->data,
1934 (CK_ULONG *)a[4]->data);
1935 case F_C_SignEncryptUpdate:
1936 if (!func)
1937 return CKR_CRYPTOKI_NOT_INITIALIZED;
1938 return func->C_SignEncryptUpdate(*(CK_ULONG *)a[0]->data,
1939 (CK_CHAR *)a[1]->data,
1940 *(CK_ULONG *)a[2]->data,
1941 (CK_CHAR *)a[3]->data,
1942 (CK_ULONG *)a[4]->data);
1943 case F_C_DecryptVerifyUpdate:
1944 if (!func)
1945 return CKR_CRYPTOKI_NOT_INITIALIZED;
1946 return func->C_DecryptVerifyUpdate(*(CK_ULONG *)a[0]->data,
1947 (CK_CHAR *)a[1]->data,
1948 *(CK_ULONG *)a[2]->data,
1949 (CK_CHAR *)a[3]->data,
1950 (CK_ULONG *)a[4]->data);
1951 case F_C_GenerateKey:
1952 if (!func)
1953 return CKR_CRYPTOKI_NOT_INITIALIZED;
1954 return func->C_GenerateKey(*(CK_ULONG *)a[0]->data,
1955 (CK_MECHANISM *)a[1]->data,
1956 (CK_ATTRIBUTE *)a[2]->data,
1957 *(CK_ULONG *)a[3]->data,
1958 (CK_ULONG *)a[4]->data);
1959 case F_C_GenerateKeyPair:
1960 if (!func)
1961 return CKR_CRYPTOKI_NOT_INITIALIZED;
1962 return func->C_GenerateKeyPair(*(CK_ULONG *)a[0]->data,
1963 (CK_MECHANISM *)a[1]->data,
1964 (CK_ATTRIBUTE *)a[2]->data,
1965 *(CK_ULONG *)a[3]->data,
1966 (CK_ATTRIBUTE *)a[4]->data,
1967 *(CK_ULONG *)a[5]->data,
1968 (CK_ULONG *)a[6]->data,
1969 (CK_ULONG *)a[7]->data);
1970 case F_C_WrapKey:
1971 if (!func)
1972 return CKR_CRYPTOKI_NOT_INITIALIZED;
1973 return func->C_WrapKey(*(CK_ULONG *)a[0]->data,
1974 (CK_MECHANISM *)a[1]->data,
1975 *(CK_ULONG *)a[2]->data,
1976 *(CK_ULONG *)a[3]->data,
1977 (CK_CHAR *)a[5]->data,
1978 (CK_ULONG *)a[6]->data);
1979 case F_C_UnwrapKey:
1980 if (!func)
1981 return CKR_CRYPTOKI_NOT_INITIALIZED;
1982 return func->C_UnwrapKey(*(CK_ULONG *)a[0]->data,
1983 (CK_MECHANISM *)a[1]->data,
1984 *(CK_ULONG *)a[2]->data,
1985 (CK_CHAR *)a[3]->data,
1986 *(CK_ULONG *)a[4]->data,
1987 (CK_ATTRIBUTE *)a[5]->data,
1988 *(CK_ULONG *)a[6]->data,
1989 (CK_ULONG *)a[7]->data);
1990 case F_C_DeriveKey:
1991 if (!func)
1992 return CKR_CRYPTOKI_NOT_INITIALIZED;
1993 return func->C_DeriveKey(*(CK_ULONG *)a[0]->data,
1994 (CK_MECHANISM *)a[1]->data,
1995 *(CK_ULONG *)a[2]->data,
1996 (CK_ATTRIBUTE *)a[3]->data,
1997 *(CK_ULONG *)a[4]->data,
1998 (CK_ULONG *)a[5]->data);
1999 case F_C_SeedRandom:
2000 if (!func)
2001 return CKR_CRYPTOKI_NOT_INITIALIZED;
2002 return func->C_SeedRandom(*(CK_ULONG *)a[0]->data,
2003 (CK_CHAR *)a[1]->data,
2004 *(CK_ULONG *)a[2]->data);
2005 case F_C_GenerateRandom:
2006 if (!func)
2007 return CKR_CRYPTOKI_NOT_INITIALIZED;
2008 return func->C_GenerateRandom(*(CK_ULONG *)a[0]->data,
2009 (CK_CHAR *)a[1]->data,
2010 *(CK_ULONG *)a[2]->data);
2011 case F_C_GetFunctionStatus:
2012 if (!func)
2013 return CKR_CRYPTOKI_NOT_INITIALIZED;
2014 return func->C_GetFunctionStatus(*(CK_ULONG *)a[0]->data);
2015 case F_C_CancelFunction:
2016 if (!func)
2017 return CKR_CRYPTOKI_NOT_INITIALIZED;
2018 return func->C_CancelFunction(*(CK_ULONG *)a[0]->data);
2019 case F_C_WaitForSlotEvent:
2020 if (!func)
2021 return CKR_CRYPTOKI_NOT_INITIALIZED;
2022 return func->C_WaitForSlotEvent(*(CK_ULONG *)a[0]->data,
2023 (CK_ULONG *)a[1]->data,
2024 (void *)a[2]->data);
2025 /* set a variable */
2026 case F_SetVar:
2027 case F_SetStringVar:
2028 (void)DeleteVariable(a[0]->data);
2029 (void)AddVariable(a[0]->data, &a[1]);
2030 return CKR_OK;
2031 /* print a value */
2032 case F_Print:
2033 return printArg(a[0], 0);
2034 case F_SaveVar:
2035 return save(a[0]->data, a[1]);
2036 case F_RestoreVar:
2037 return restore(a[0]->data, a[1]);
2038 case F_Delete:
2039 return DeleteVariable(a[0]->data);
2040 case F_Increment:
2041 return increment(a[0], *(CK_ULONG *)a[1]->data);
2042 case F_Decrement:
2043 return decrement(a[0], *(CK_ULONG *)a[1]->data);
2044 case F_List:
2045 return list();
2046 case F_Run:
2047 return run(a[0]->data);
2048 case F_Time:
2049 return timeCommand(a[0]->data);
2050 case F_Load:
2051 return loadModule(&module, a[0]->data);
2052 case F_Unload:
2053 return unloadModule(&module);
2054 case F_NewArray:
2055 (void)DeleteVariable(a[0]->data);
2056 return ArrayVariable(a[0]->data, a[1]->data, *(CK_ULONG *)a[2]->data);
2057 case F_NewTemplate:
2058 (void)DeleteVariable(a[0]->data);
2059 return ArrayTemplate(a[0]->data, a[1]->data);
2060 case F_BuildTemplate:
2061 return BuildTemplate(a[0]);
2062 case F_SetTemplate:
2063 return SetTemplate(a[0],
2064 *(CK_ULONG *)a[1]->data,
2065 *(CK_ULONG *)a[2]->data);
2066 case F_NewMechanism:
2067 (void)DeleteVariable(a[0]->data);
2068 return NewMechanism(a[0]->data, *(CK_ULONG *)a[1]->data);
2069 case F_NewInitializeArgs:
2070 (void)DeleteVariable(a[0]->data);
2071 return NewInitializeArgs(a[0]->data, *(CK_ULONG *)a[1]->data, a[2]->data);
2072 case F_System:
2073 value = *(int *)a[0]->data;
2074 if (value & 0x80000000) {
2075 systemFlags &= ~value;
2076 } else {
2077 systemFlags |= value;
2078 }
2079 return CKR_OK;
2080 case F_Loop:
2081 return loop(a[0]->data, a[1]->data, *(CK_ULONG *)a[2]->data,
2082 *(CK_ULONG *)a[3]->data, *(CK_ULONG *)a[4]->data);
2083 case F_Help:
2084 if (a[0]) {
2085 helpIndex = lookup(a[0]->data);
2086 if (helpIndex < 0) {
2087 return printTopicHelp(a[0]->data);
2088 }
2089 printHelp(helpIndex, 1);
2090 return CKR_OK;
2091 }
2092 return printGeneralHelp();
2093 case F_QuitIfString:
2094 return quitIfString(a[0]->data, a[1]->data, a[2]->data);
2095 case F_QuitIf:
2096 return quitIf(*(CK_ULONG *)a[0]->data, a[1]->data, *(CK_ULONG *)a[2]->data);
2097 case F_Quit:
2098 return CKR_QUIT;
2099 default:
2100 fprintf(stderr,
2101 "Function %s not yet supported\n", commands[index].fname);
2102 return CKR_OK;
2103 }
2104 /* Not Reached */
2105 return CKR_OK;
2106 }
2107
2108 CK_RV
processCommand(const char * buf)2109 processCommand(const char *buf)
2110 {
2111 CK_RV error = CKR_OK;
2112 int index;
2113 const char *bp;
2114 Value **arglist;
2115
2116 bp = strip(buf);
2117 /* allow comments and blank lines in scripts */
2118 if ((*bp == '#') || (*bp == 0) || (*bp == '\n')) {
2119 return CKR_OK;
2120 }
2121
2122 index = lookup(bp);
2123
2124 if (index < 0) {
2125 return CKR_OK;
2126 }
2127
2128 arglist = parseArgs(index, bp);
2129 if (arglist == NULL) {
2130 return CKR_OK;
2131 }
2132
2133 error = do_func(index, arglist);
2134 if (error == CKR_OK) {
2135 putOutput(arglist);
2136 } else if (error != CKR_QUIT) {
2137 printf(">> Error : ");
2138 printConst(error, ConstResult, 1);
2139 }
2140
2141 parseFree(arglist);
2142 return error;
2143 }
2144
2145 CK_RV
timeCommand(const char * command)2146 timeCommand(const char *command)
2147 {
2148 CK_RV ckrv;
2149 PRIntervalTime startTime = PR_IntervalNow();
2150 PRIntervalTime endTime;
2151 PRIntervalTime elapsedTime;
2152
2153 ckrv = processCommand(command);
2154
2155 endTime = PR_IntervalNow();
2156 elapsedTime = endTime - startTime;
2157 printf("Time -- %d msec \n",
2158 PR_IntervalToMilliseconds(elapsedTime));
2159
2160 return ckrv;
2161 }
2162
2163 CK_RV
process(FILE * inFile,int user)2164 process(FILE *inFile, int user)
2165 {
2166 char buf[2048];
2167 CK_RV error;
2168 CK_RV ckrv = CKR_OK;
2169
2170 if (user) {
2171 printf("pkcs11> ");
2172 fflush(stdout);
2173 }
2174
2175 while (fgets(buf, 2048, inFile) != NULL) {
2176
2177 if (!user)
2178 printf("* %s", buf);
2179 error = processCommand(buf);
2180 if (error == CKR_QUIT) {
2181 break;
2182 } else if (error != CKR_OK) {
2183 ckrv = error;
2184 }
2185 if (user) {
2186 printf("pkcs11> ");
2187 fflush(stdout);
2188 }
2189 }
2190 return ckrv;
2191 }
2192
2193 CK_RV
run(const char * filename)2194 run(const char *filename)
2195 {
2196 FILE *infile;
2197 CK_RV ckrv;
2198
2199 infile = fopen(filename, "r");
2200
2201 if (infile == NULL) {
2202 perror(filename);
2203 return CKR_FUNCTION_FAILED;
2204 }
2205
2206 ckrv = process(infile, 0);
2207
2208 fclose(infile);
2209 return ckrv;
2210 }
2211
2212 CK_RV
loop(const char * filename,const char * var,CK_ULONG start,CK_ULONG end,CK_ULONG step)2213 loop(const char *filename, const char *var,
2214 CK_ULONG start, CK_ULONG end, CK_ULONG step)
2215 {
2216 CK_ULONG i = 0;
2217 Value *value = 0;
2218 CK_RV ckrv;
2219
2220 for (i = start; i < end; i += step) {
2221 value = NewValue(ArgULong, 1);
2222 *(CK_ULONG *)value->data = i;
2223 DeleteVariable(var);
2224 AddVariable(var, &value);
2225 ckrv = run(filename);
2226 argFree(value);
2227 if (ckrv == CKR_QUIT) {
2228 break;
2229 }
2230 }
2231 return ckrv;
2232 }
2233
2234 int
main(int argc,char ** argv)2235 main(int argc, char **argv)
2236 {
2237 /* I suppose that some day we could parse some arguments */
2238 (void)process(stdin, 1);
2239 return 0;
2240 }
2241