~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/cmd/pk11util/pk11util.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

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