]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/keyStore/keyStore.c
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / cspxutils / keyStore / keyStore.c
1 /* Copyright (c) 2001,2003-2006,2008 Apple Inc.
2 *
3 * keyStore.c - basic key pair store/lookup routines.
4 *
5 * create key pair, varying pub is permanent, priv is permanent;
6 * sign some data with priv;
7 * lookUpPub = lookup pub by label;
8 * vfy with lookUpPub;
9 * lookUpPriv = lookup priv by label;
10 * if(privIsPerm) {
11 * ensure lookUpPriv == priv;
12 * freeKey(lookUpPriv);
13 * obtainedPriv = obtainPubFromPriv(lookUpPub);
14 * ensure obtainedPriv == priv;
15 * freeKey(obtainedPriv);
16 * delete priv; // cspwrap does implicit freeKey here...
17 * }
18 * else {
19 * free priv;
20 * }
21 * lookUpPriv = lookup priv by label; verify fail;
22 * lookUpPriv = obtainPubFromPriv(pub); verify fail;
23 * freeKey(lookUpPub);
24 * if pub is permament {
25 * lookUpPub = lookup pub by label; verify OK;
26 * deleteKey(lookUpPub);
27 * lookUpPub = lookup pub by label; verify fail;
28 * }
29 * lookUpPub = lookup pub by label; verify fail;
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <time.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <Security/cssm.h>
38 #include "cspwrap.h"
39 #include "common.h"
40 #include "cspdlTesting.h"
41
42 #define LOOPS_DEF 10
43 #define MAX_DATA_SIZE 100
44 #define DB_NAME "keyStore.db"
45
46 /* can't lookup non-permanent keys! */
47 #define FORCE_PUB_PERMANENT 0
48
49 static void usage(char **argv)
50 {
51 printf("usage: %s [options]\n", argv[0]);
52 printf(" Options:\n");
53 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
54 printf(" r(RSA; default = FEE)\n");
55 printf(" p(ermanent keys, implies l=1)\n");
56 printf(" k=keyChainFile\n");
57 printf(" n(o sign/verify)\n");
58 printf(" N(o lookup of nonexistent keys)\n");
59 printf(" x (privKey always extractable)\n");
60 printf(" P(ause for MallocDebug)\n");
61 printf(" v(erbose)\n");
62 printf(" q(uiet)\n");
63 printf(" h(elp)\n");
64 exit(1);
65 }
66
67 #define FEE_PRIV_DATA_SIZE 20
68
69 /*
70 * NULL wrap, error tolerant.
71 */
72 CSSM_RETURN cspNullWrapKey(
73 CSSM_CSP_HANDLE cspHand,
74 const CSSM_KEY *refKey,
75 CSSM_KEY_PTR rawKey) // RETURNED on success, caller must FreeKey
76 {
77 CSSM_CC_HANDLE ccHand;
78 CSSM_RETURN crtn;
79 CSSM_ACCESS_CREDENTIALS creds;
80 CSSM_DATA descData = {0, 0};
81
82 memset(rawKey, 0, sizeof(CSSM_KEY));
83 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
84 crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
85 CSSM_ALGID_NONE,
86 CSSM_ALGMODE_NONE,
87 &creds, // passPhrase,
88 NULL, // wrappingKey,
89 NULL, // initVector,
90 CSSM_PADDING_NONE,
91 0, // Params
92 &ccHand);
93 if(crtn) {
94 printError("cspNullWrapKey/CreateContext", crtn);
95 return crtn;
96 }
97 crtn = CSSM_WrapKey(ccHand,
98 &creds,
99 refKey,
100 &descData, // DescriptiveData
101 rawKey);
102 if(CSSM_DeleteContext(ccHand)) {
103 printf("CSSM_DeleteContext failure\n");
104 }
105 return crtn;
106 }
107
108
109 /*
110 * Generate key pair, default size. This is like cspGenKeyPair in cspwrap.c,
111 * tweaked for this test To allow varying permanent attribute.
112 */
113 static CSSM_RETURN genKeyPair(CSSM_CSP_HANDLE cspHand,
114 CSSM_DL_HANDLE dlHand,
115 CSSM_DB_HANDLE dbHand,
116 const CSSM_DATA_PTR keyLabel,
117 CSSM_KEY_PTR pubKey, // mallocd by caller
118 uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
119 uint32 pubKeyAttr,
120 CSSM_KEY_PTR privKey, // mallocd by caller
121 uint32 privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc.
122 uint32 privKeyAttr,
123 uint32 keyGenAlg)
124 {
125 CSSM_RETURN crtn;
126 CSSM_CC_HANDLE ccHand;
127 CSSM_RETURN ocrtn = CSSM_OK;
128 uint32 keySize;
129
130 if(keyGenAlg == CSSM_ALGID_FEE) {
131 keySize = CSP_FEE_KEY_SIZE_DEFAULT;
132 }
133 else {
134 keySize = CSP_RSA_KEY_SIZE_DEFAULT;
135 }
136 memset(pubKey, 0, sizeof(CSSM_KEY));
137 memset(privKey, 0, sizeof(CSSM_KEY));
138
139 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
140 keyGenAlg,
141 keySize,
142 NULL, // Seed
143 NULL, // Salt
144 NULL, // StartDate
145 NULL, // EndDate
146 NULL, // Params
147 &ccHand);
148 if(crtn) {
149 printError("CSSM_CSP_CreateKeyGenContext", crtn);
150 ocrtn = crtn;
151 goto abort;
152 }
153
154 /* add in DL/DB to context */
155 crtn = cspAddDlDbToContext(ccHand, dlHand, dbHand);
156 if(crtn) {
157 ocrtn = crtn;
158 goto abort;
159 }
160 crtn = CSSM_GenerateKeyPair(ccHand,
161 pubKeyUsage,
162 pubKeyAttr,
163 keyLabel,
164 pubKey,
165 privKeyUsage,
166 privKeyAttr,
167 keyLabel, // same labels
168 NULL, // cred/acl
169 privKey);
170 if(crtn) {
171 printError("CSSM_GenerateKeyPair", crtn);
172 ocrtn = crtn;
173 goto abort;
174 }
175
176 /* basic checks...*/
177 if(privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
178 printf("privKey blob type: exp %u got %u\n",
179 CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType);
180 }
181 if(pubKeyAttr & CSSM_KEYATTR_RETURN_REF) {
182 if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
183 printf("pubKey blob type: exp %u got %u\n",
184 CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType);
185 ocrtn = -1;
186 goto abort;
187 }
188 }
189 else {
190 if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_RAW) {
191 printf("pubKey blob type: exp %u got %u\n",
192 CSSM_KEYBLOB_RAW, (unsigned)privKey->KeyHeader.BlobType);
193 ocrtn = -1;
194 goto abort;
195 }
196 }
197
198 abort:
199 if(ccHand != 0) {
200 crtn = CSSM_DeleteContext(ccHand);
201 if(crtn) {
202 printError("CSSM_DeleteContext", crtn);
203 ocrtn = crtn;
204 }
205 }
206 return ocrtn;
207 }
208
209 #define KEY_LABEL "testKey"
210
211 /*
212 * when true, keyref in key obtained from DL differs from
213 * keyref in key from CSP
214 */
215 #define DL_REF_KEYS_DIFFER 1
216
217 /*
218 * ObtainPrivateKeyFromPublicKey doesn't work yet
219 */
220 #define DO_OBTAIN_FROM_PUB CSPDL_OBTAIN_PRIV_FROM_PUB
221
222 /* we're assumed to be logged in for access to private objects */
223 static int doTest(CSSM_CSP_HANDLE cspHand,
224 CSSM_DL_HANDLE dlHand,
225 CSSM_DB_HANDLE dbHand,
226 CSSM_BOOL pubIsPerm, // pub is permanent
227 CSSM_BOOL privIsPerm, // priv is permanent
228 CSSM_BOOL privIsExtractable,
229 CSSM_BOOL permKeys, // leave them in the KC
230 CSSM_BOOL doSignVerify,
231 CSSM_BOOL doFailedLookup,
232 CSSM_DATA_PTR ptext,
233 CSSM_BOOL verbose,
234 CSSM_BOOL quiet,
235 uint32 keyGenAlg,
236 uint32 sigAlg)
237 {
238 CSSM_KEY pubKey; // from GenerateKeyPair
239 CSSM_KEY privKey;
240 CSSM_KEY_PTR lookUpPub; // from cspLookUpKeyByLabel, etc.
241 CSSM_KEY_PTR lookUpPriv;
242 CSSM_RETURN crtn;
243 CSSM_DATA sig;
244 CSSM_DATA labelData;
245 CSSM_KEY obtainedPriv;
246 uint32 pubAttr;
247 uint32 privAttr;
248 CSSM_KEY rawPrivKey;
249 labelData.Data = (uint8 *)KEY_LABEL;
250 labelData.Length = strlen(KEY_LABEL);
251 CSSM_BOOL doLookup;
252
253 /* create key pair */
254 if(verbose) {
255 printf(" ...generating key pair (pubIsPerm %d privIsPerm %d privIsExtract"
256 " %d)\n", (int)pubIsPerm, (int)privIsPerm, (int)privIsExtractable);
257 }
258 pubAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF;
259 if(pubIsPerm) {
260 pubAttr |= CSSM_KEYATTR_PERMANENT;
261 }
262
263 /*
264 * To use a NULL wrap to test detection of !EXTRACTABLE, we're relying on
265 * being able to create !SENSITIVE private keys. We'll make 'em sensitive
266 * if we're not trying to null wrap them.
267 */
268 privAttr = CSSM_KEYATTR_RETURN_REF;
269 if(privIsPerm) {
270 privAttr |= CSSM_KEYATTR_PERMANENT;
271 }
272 if(privIsExtractable) {
273 privAttr |= CSSM_KEYATTR_EXTRACTABLE;
274 }
275 else {
276 privAttr |= CSSM_KEYATTR_SENSITIVE;
277 }
278 #if CSPDL_KEYATTR_PRIVATE
279 privAttr |= CSSM_KEYATTR_PRIVATE;
280 #endif
281 crtn = genKeyPair(cspHand,
282 dlHand,
283 dbHand,
284 &labelData,
285 &pubKey,
286 CSSM_KEYUSE_VERIFY, // pubKeyUsage
287 pubAttr,
288 &privKey,
289 CSSM_KEYUSE_SIGN,
290 privAttr,
291 keyGenAlg);
292 if(crtn) {
293 return testError(quiet);
294 }
295
296 /* lookUpPub = lookup pub by label; */
297 doLookup = CSSM_TRUE;
298 if(verbose) {
299 if(pubIsPerm) {
300 printf(" ...lookup pub by label\n");
301 }
302 else {
303 if(doFailedLookup) {
304 printf(" ...lookup (nonexistent) pub by label\n");
305 }
306 else {
307 doLookup = CSSM_FALSE;
308 lookUpPub = NULL;
309 }
310 }
311 }
312 if(doLookup) {
313 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public);
314 }
315 if(pubIsPerm) {
316 if(lookUpPub == NULL) {
317 printf("lookup pub by label failed\n");
318 return testError(quiet);
319 }
320
321 /* sign some data with priv; */
322 sig.Data = NULL;
323 sig.Length = 0;
324 if(doSignVerify) {
325 if(cspSign(cspHand,
326 sigAlg,
327 &privKey,
328 ptext,
329 &sig)) {
330 return testError(quiet);
331 }
332 }
333 /* verify header compare */
334 if(memcmp(&lookUpPub->KeyHeader, &pubKey.KeyHeader,
335 sizeof(CSSM_KEYHEADER))) {
336 printf("**pubKey header miscompare\n");
337 return testError(quiet);
338 }
339
340 /* vfy with lookUpPub; */
341 if(doSignVerify) {
342 if(cspSigVerify(cspHand,
343 sigAlg,
344 lookUpPub,
345 ptext,
346 &sig,
347 CSSM_OK)) {
348 return testError(quiet);
349 }
350
351 CSSM_FREE(sig.Data);
352 sig.Data = NULL;
353 sig.Data = 0;
354 }
355 }
356 else {
357 if(doLookup && (lookUpPub != NULL)) {
358 printf("***Unexpected success on cspLookUpKeyByLabel(pub, not perm)\n");
359 return testError(quiet);
360 }
361 }
362
363 /*
364 * Ensure proper behavior of extractable bit
365 */
366 if(verbose) {
367 printf(" ...null wrap %s private key\n",
368 privIsExtractable ? "EXTRACTABLE" : "!EXTRACTABLE");
369 }
370 crtn = cspNullWrapKey(cspHand, &privKey, &rawPrivKey);
371 if(privIsExtractable) {
372 if(crtn) {
373 printError("Null Wrap(extractable private key)", crtn);
374 return testError(quiet);
375 }
376 if(verbose) {
377 printf(" ...free rawPrivKey\n");
378 }
379 cspFreeKey(cspHand, &rawPrivKey);
380 }
381 else {
382 if(crtn != CSSMERR_CSP_INVALID_KEYATTR_MASK) {
383 printError("Null Wrap of !extractable private key: expected "
384 "INVALID_KEYATTR_MASK, got", crtn);
385 if(crtn == CSSM_OK) {
386 cspFreeKey(cspHand, &rawPrivKey);
387 }
388 return testError(quiet);
389 }
390 }
391 /* lookUpPriv = lookup priv by label; ensure == privKey; */
392 doLookup = CSSM_TRUE;
393 if(verbose) {
394 if(privIsPerm) {
395 printf(" ...lookup priv by label\n");
396 }
397 else {
398 if(doFailedLookup) {
399 printf(" ...lookup (nonexistent) priv by label\n");
400 }
401 else {
402 doLookup = CSSM_FALSE;
403 lookUpPriv = NULL;
404 }
405 }
406 }
407 if(doLookup) {
408 lookUpPriv = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Private);
409 }
410 if(privIsPerm) {
411 if(lookUpPriv == NULL) {
412 printf("lookup priv by label failed\n");
413 return testError(quiet);
414 }
415
416 /* note we "know" that both keys are ref keys...*/
417 if(lookUpPriv->KeyData.Length != privKey.KeyData.Length) {
418 printf("priv key data length mismatch\n");
419 return testError(quiet);
420 }
421 #if DL_REF_KEYS_DIFFER
422 if(!memcmp(lookUpPriv->KeyData.Data, privKey.KeyData.Data,
423 privKey.KeyData.Length)) {
424 printf("priv key ref data mismatch\n");
425 return testError(quiet);
426 }
427 #else /* DL_REF_KEYS_DIFFER */
428 if(memcmp(lookUpPriv->KeyData.Data, privKey.KeyData.Data,
429 privKey.KeyData.Length)) {
430 printf("unexpected priv key ref data match\n");
431 return testError(quiet);
432 }
433 #endif /* DL_REF_KEYS_DIFFER */
434
435 /* verify header compare in any case */
436 if(memcmp(&lookUpPriv->KeyHeader, &privKey.KeyHeader,
437 sizeof(CSSM_KEYHEADER))) {
438 printf("**privKey header miscompare\n");
439 return testError(quiet);
440 }
441
442 /* sign with lookUpPriv, verify with pubKey */
443 sig.Data = NULL;
444 sig.Length = 0;
445 if(doSignVerify) {
446 if(verbose) {
447 printf(" ...sign with lookup priv\n");
448 }
449 if(cspSign(cspHand,
450 sigAlg,
451 lookUpPriv,
452 ptext,
453 &sig)) {
454 return testError(quiet);
455 }
456 if(verbose) {
457 printf(" ...verify with pub\n");
458 }
459 if(cspSigVerify(cspHand,
460 sigAlg,
461 &pubKey,
462 ptext,
463 &sig,
464 CSSM_OK)) {
465 printf("***sign with lookUpPriv, vfy with pub FAILED\n");
466 return testError(quiet);
467 }
468 CSSM_FREE(sig.Data);
469 sig.Data = NULL;
470 sig.Data = 0;
471 }
472
473 /* free lookUpPriv from cache, but it's permanent */
474 if(verbose) {
475 printf(" ...free lookupPriv\n");
476 }
477 if(cspFreeKey(cspHand, lookUpPriv)) {
478 printf("Error on cspFreeKey(lookUpPriv)\n");
479 return testError(quiet);
480 }
481 CSSM_FREE(lookUpPriv); // mallocd during lookup
482 lookUpPriv = NULL;
483
484 #if DO_OBTAIN_FROM_PUB
485 /* obtainedPriv = obtainPubFromPriv(pub); ensure == priv; */
486 if(verbose) {
487 printf(" ...ObtainPrivateKeyFromPublicKey\n");
488 }
489 obtainedPriv.KeyData.Data = NULL;
490 obtainedPriv.KeyData.Length = 0;
491 crtn = CSSM_CSP_ObtainPrivateKeyFromPublicKey(cspHand,
492 lookUpPub,
493 &obtainedPriv);
494 if(crtn) {
495 printError("ObtainPrivateKeyFromPublicKey", crtn);
496 return testError(quiet);
497 }
498
499 /* free obtainedPriv from cache, but it's permanent */
500 if(verbose) {
501 printf(" ...free obtainedPriv\n");
502 }
503 if(cspFreeKey(cspHand, &obtainedPriv)) {
504 printf("Error on cspFreeKey(obtainedPriv)\n");
505 return testError(quiet);
506 }
507
508 #endif /* DO_OBTAIN_FROM_PUB */
509
510 if(!permKeys) {
511 /* delete priv - implies freeKey as well */
512 if(verbose) {
513 printf(" ...delete privKey\n");
514 }
515 crtn = cspDeleteKey(cspHand, dlHand, dbHand, &labelData, &privKey);
516 if(crtn) {
517 printf("Error deleting priv\n");
518 return testError(quiet);
519 }
520
521 /* lookUpPriv = lookup priv by label; verify fail; */
522 if(doFailedLookup) {
523 if(verbose) {
524 printf(" ...lookup (nonexistent) priv by label\n");
525 }
526 lookUpPriv = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Private);
527 if(lookUpPriv != NULL) {
528 printf("Unexpected success on cspLookUpKeyByLabel(priv)\n");
529 return testError(quiet);
530 }
531 }
532 else {
533 lookUpPriv = NULL;
534 }
535 }
536 }
537 else if(doLookup) {
538 /* !privIsPerm - just free it and it's all gone */
539 if(lookUpPriv != NULL) {
540 printf("***Unexpected success on cspLookUpKeyByLabel(priv, not perm)\n");
541 return testError(quiet);
542 }
543 if(verbose) {
544 printf(" ...free privKey\n");
545 }
546 if(cspFreeKey(cspHand, &privKey)) {
547 printf("Error on cspFreeKey(privKey)\n");
548 return testError(quiet);
549 }
550 }
551 /* CSP, DL have no knowledge of privKey or its variations */
552
553 /* obtainedPriv = obtainPubFromPriv(pub); verify fail;*/
554 /* Note this should be safe even if DO_OBTAIN_FROM_PUB == 0 */
555 obtainedPriv.KeyData.Data = NULL;
556 obtainedPriv.KeyData.Length = 0;
557 if(verbose) {
558 printf(" ...obtain (nonexistent) priv by public\n");
559 }
560 crtn = CSSM_CSP_ObtainPrivateKeyFromPublicKey(cspHand,
561 &pubKey,
562 &obtainedPriv);
563 switch(crtn) {
564 case CSSM_OK:
565 printf("Unexpected success on ObtainPrivateKeyFromPublicKey\n");
566 return testError(quiet);
567 case CSSMERR_CSP_PRIVATE_KEY_NOT_FOUND:
568 break;
569 #if !CSPDL_OBTAIN_PRIV_FROM_PUB
570 case CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED:
571 /* OK */
572 break;
573 #endif
574 default:
575 printf("Unexpected err ObtainPrivateKeyFromPublicKey\n");
576 printError("got this", crtn);
577 return testError(quiet);
578 }
579
580 /* free one or both copies of pub as appropriate */
581 if(verbose) {
582 printf(" ...free pubKey\n");
583 }
584 crtn = cspFreeKey(cspHand, &pubKey);
585 if(crtn) {
586 printf("Error freeing pubKey\n");
587 return testError(quiet);
588 }
589 if(pubIsPerm) {
590 if(verbose) {
591 printf(" ...free lookUpPub\n");
592 }
593 crtn = cspFreeKey(cspHand, lookUpPub);
594 if(crtn) {
595 printf("Error freeing lookUpPub\n");
596 return testError(quiet);
597 }
598 }
599 if(lookUpPub) {
600 CSSM_FREE(lookUpPub); // mallocd by lookup in any case
601 }
602
603 if(pubIsPerm) {
604 /* pub should still be there in DL */
605 /* lookUpPub = lookup pub by label; verify OK; */
606 if(verbose) {
607 printf(" ...lookup pub by label (2)\n");
608 }
609 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public);
610 if(lookUpPub == NULL) {
611 printf("lookup pub by label (2) failed\n");
612 return testError(quiet);
613 }
614
615 if(!permKeys) {
616 /* now really delete it */
617 if(verbose) {
618 printf(" ...delete lookUpPub\n");
619 }
620 crtn = cspDeleteKey(cspHand, dlHand, dbHand, &labelData, lookUpPub);
621 if(crtn) {
622 printf("Error deleting lookUpPub\n");
623 return testError(quiet);
624 }
625 CSSM_FREE(lookUpPub); // mallocd by lookup
626 }
627 }
628 /* else freeKey should have removed all trace */
629
630 if(!permKeys && doFailedLookup) {
631 /* lookUpPub = lookup pub by label; verify fail; */
632 if(verbose) {
633 printf(" ...lookup (nonexistent) pub by label\n");
634 }
635 lookUpPub = cspLookUpKeyByLabel(dlHand, dbHand, &labelData, CKT_Public);
636 if(lookUpPub != NULL) {
637 printf("Unexpected success on cspLookUpKeyByLabel(pub) (2)\n");
638 return testError(quiet);
639 }
640 }
641 return 0;
642 }
643
644 int main(int argc, char **argv)
645 {
646 int arg;
647 char *argp;
648 unsigned loop;
649 CSSM_DATA ptext;
650 CSSM_CSP_HANDLE cspHand;
651 CSSM_DB_HANDLE dbHand;
652 CSSM_DL_HANDLE dlHand;
653 CSSM_BOOL pubIsPerm;
654 CSSM_BOOL privIsPerm;
655 CSSM_BOOL privIsExtractable;
656 uint32 keyGenAlg = CSSM_ALGID_FEE;
657 uint32 sigAlg = CSSM_ALGID_FEE_MD5;
658 int rtn = 0;
659 CSSM_RETURN crtn;
660
661 /*
662 * User-spec'd params
663 */
664 unsigned loops = LOOPS_DEF;
665 CSSM_BOOL verbose = CSSM_FALSE;
666 CSSM_BOOL quiet = CSSM_FALSE;
667 CSSM_BOOL permKeys = CSSM_FALSE;
668 char dbName[100]; /* DB_NAME_pid */
669 CSSM_BOOL useExistDb = CSSM_FALSE;
670 CSSM_BOOL doPause = CSSM_FALSE;
671 CSSM_BOOL doSignVerify = CSSM_TRUE;
672 CSSM_BOOL doFailedLookup = CSSM_TRUE;
673 CSSM_BOOL privAlwaysExtractable = CSSM_FALSE;
674
675 dbName[0] = '\0';
676
677 for(arg=1; arg<argc; arg++) {
678 argp = argv[arg];
679 switch(argp[0]) {
680 case 'l':
681 loops = atoi(&argp[2]);
682 break;
683 case 'v':
684 verbose = CSSM_TRUE;
685 break;
686 case 'q':
687 quiet = CSSM_TRUE;
688 break;
689 case 'p':
690 permKeys = CSSM_TRUE;
691 loops = 1;
692 break;
693 case 'r':
694 keyGenAlg = CSSM_ALGID_RSA;
695 sigAlg = CSSM_ALGID_MD5WithRSA;
696 break;
697 case 'k':
698 memmove(dbName, &argp[2], strlen(&argp[2]) + 1);
699 useExistDb = CSSM_TRUE;
700 break;
701 case 'P':
702 doPause = CSSM_TRUE;
703 break;
704 case 'n':
705 doSignVerify = CSSM_FALSE;
706 break;
707 case 'N':
708 doFailedLookup = CSSM_FALSE;
709 break;
710 case 'x':
711 privAlwaysExtractable = CSSM_TRUE;
712 break;
713 case 'h':
714 default:
715 usage(argv);
716 }
717 }
718
719 if(dbName[0] == '\0') {
720 sprintf(dbName, "%s_%d", DB_NAME, (int)getpid());
721 }
722
723 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_DATA_SIZE);
724 ptext.Length = MAX_DATA_SIZE;
725 /* data generated in test loop */
726 if(ptext.Data == NULL) {
727 printf("Insufficient heap\n");
728 exit(1);
729 }
730
731 testStartBanner("keyStore", argc, argv);
732
733 /* attach to CSP/DL */
734 cspHand = cspDlDbStartup(CSSM_FALSE, NULL);
735 if(cspHand == 0) {
736 exit(1);
737 }
738 dlHand = dlStartup();
739 if(dlHand == 0) {
740 exit(1);
741 }
742 if(useExistDb) {
743 /* this one may well require SecurityAgent UI */
744 crtn = dbCreateOpen(dlHand, dbName, CSSM_FALSE, CSSM_FALSE, NULL,
745 &dbHand);
746 }
747 else {
748 /* hands-free test */
749 crtn = dbCreateOpen(dlHand, dbName, CSSM_TRUE, CSSM_TRUE, dbName,
750 &dbHand);
751 }
752 if(crtn) {
753 exit(1);
754 }
755 for(loop=1; ; loop++) {
756
757 if(!quiet) {
758 printf("...loop %d\n", loop);
759 }
760 appGetRandomBytes(ptext.Data, ptext.Length);
761
762 if(permKeys) {
763 pubIsPerm = privIsPerm = CSSM_TRUE;
764 }
765 else {
766 #if CSPDL_ALL_KEYS_ARE_PERMANENT
767 pubIsPerm = CSSM_TRUE;
768 privIsPerm = CSSM_TRUE;
769 #else
770
771 /* mix up pubIsPerm, privIsPerm */
772 pubIsPerm = (loop & 1) ? CSSM_TRUE : CSSM_FALSE;
773 privIsPerm = (loop & 2) ? CSSM_TRUE : CSSM_FALSE;
774 #if FORCE_PUB_PERMANENT
775 pubIsPerm = CSSM_TRUE;
776 #endif
777 #endif /* CSPDL_ALL_KEYS_ARE_PERMANENT */
778 }
779 privIsExtractable = ((loop & 4) || privAlwaysExtractable) ? CSSM_TRUE : CSSM_FALSE;
780 if(doTest(cspHand,
781 dlHand,
782 dbHand,
783 pubIsPerm,
784 privIsPerm,
785 privIsExtractable,
786 permKeys,
787 doSignVerify, doFailedLookup,
788 &ptext,
789 verbose,
790 quiet,
791 keyGenAlg,
792 sigAlg)) {
793 rtn = 1;
794 break;
795 }
796 if(loops && (loop == loops)) {
797 break;
798 }
799 if(doPause) {
800 fpurge(stdin);
801 printf("CR to continue: ");
802 getchar();
803 }
804 }
805
806 cspShutdown(cspHand, CSSM_FALSE);
807 /* FIXME - DB close? DL shutdown? */
808 if((rtn == 0) && !quiet) {
809 printf("%s test complete\n", argv[0]);
810 }
811 if((rtn == 0) & !permKeys) {
812 /* be nice: if we ran OK delete the cruft DB we created */
813 unlink(dbName);
814 }
815 return rtn;
816 }