]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/cgVerify/cgVerify.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / cgVerify / cgVerify.cpp
1 /*
2 * cgVerify.cpp - basic test of TP's CertGroupVerify
3 *
4 * cook up array of n key pairs;
5 * cook up cert chain to go with them;
6 * main test loop {
7 * numCerts = total # of incoming certs;
8 * test one of four or five "expected result" cases {
9 * case root in certGroup but not found in AnchorCerts:
10 * certGroup = tpMakeRandCertGroup(certs[0..numCerts-1];
11 * anchorCerts = tpMakeRandCertGroup[certs[0...numCerts-2];
12 * expErr = CSSMERR_TP_INVALID_ANCHOR_CERT;
13 * expEvidenceSize = numCerts;
14 * case root in certGroup, found a copy in AnchorCerts:
15 * certGroup = tpMakeRandCertGroup(certs[0..numCerts-1];
16 * anchorCerts = tpMakeRandCertGroup[certs[0...numCerts-1];
17 * expErr = CSSM_OK;
18 * expEvidenceSize = numCerts;
19 * case verified by an AnchorCert:
20 * n = rand(1, numCerts-2);
21 * certGroup = tpMakeRandCertGroup(certs[0..n]);
22 * anchorCerts = tpMakeRandCertGroup[certs[0...numCerts-2];
23 * expErr = CSSM_OK;
24 * expEvidenceSize = n+2;
25 * case no root found:
26 * n = rand(1, numCerts-3);
27 * certGroup = tpMakeRandCertGroup(certs[0..n]);
28 * anchorCerts = tpMakeRandCertGroup[certs[n+2...numCerts-2];
29 * anchorCerts may be empty....
30 * expErr = CSSMERR_TP_NOT_TRUSTED;
31 * expEvidenceSize = n+1;
32 * case incomplete public key (DSA only):
33 * root public keys is incomplete;
34 * certGroup = tpMakeRandCertGroup(certs[0..numCerts-1];
35 * anchorCerts = tpMakeRandCertGroup[certs[0...numCerts-1];
36 * expErr = CSSM_OK;
37 * expEvidenceSize = numCerts;
38 * }
39 * result = certGroupVerify();
40 * verify expected result and getError();
41 * delete certs from DB;
42 * }
43 */
44
45 #include <Security/cssm.h>
46 #include <utilLib/common.h>
47 #include <utilLib/cspwrap.h>
48 #include <clAppUtils/clutils.h>
49 #include <clAppUtils/tpUtils.h>
50 #include <clAppUtils/timeStr.h>
51 #include <utilLib/nssAppUtils.h>
52 #include <security_cdsa_utils/cuFileIo.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <time.h>
56 #include <string.h>
57 #include <sys/types.h>
58 #include <unistd.h>
59 #include <Security/oidsalg.h>
60
61 #define NUM_CERTS_DEF 10
62 #define KEYGEN_ALG_DEF CSSM_ALGID_RSA
63 #define SIG_ALG_DEF CSSM_ALGID_SHA1WithRSA
64 #define LOOPS_DEF 10
65 #define SECONDS_TO_LIVE (60 * 60 * 24) /* certs are valid for this long */
66 //#define SECONDS_TO_LIVE 5
67
68 #define CERT_IN_DB 1
69 #define DB_NAME "cgVerify.db"
70 #define DSA_PARAM_FILE "dsaParam512.der"
71
72 /*
73 * How we define the "expected result".
74 */
75 typedef enum {
76 ER_InvalidAnchor, // root in certGroup, not found in AnchorCerts
77 ER_RootInCertGroup, // root in certGroup, copy in AnchorCerts
78 ER_AnchorVerify, // end of chain verified by an anchor
79 ER_NoRoot, // no root, no anchor verify
80 ER_IncompleteKey // un-completable public key (all keys are partial), DSA
81 // ONLY
82 } ExpectResult;
83
84 static void usage(char **argv)
85 {
86 printf("Usage: %s [options]\n", argv[0]);
87 printf(" Options:\n");
88 printf(" n=numCerts; default = %d\n", NUM_CERTS_DEF);
89 printf(" l=loops; default=%d; 0=forever\n", LOOPS_DEF);
90 printf(" a=alg (f=FEE/MD5, F=FEE/SHA1, e=FEE/ECDSA, s=RSA/SHA1, m=RSA/MD5,\n");
91 printf(" d=DSA, 4=RSA/SHA224, 6=RSA/SHA256, 3=RSA/SHA384, 5=RSA/SHA512,\n");
92 printf(" E=ANSI/ECDSA, 7=ECDSA/SHA256; default = RSA/SHA1\n");
93 printf(" k=keySizeInBits\n");
94 printf(" d(isable DB)\n");
95 printf(" P(ause on each loop)\n");
96 printf(" N (no partial pub keys)\n");
97 printf(" v(erbose)\n");
98 printf(" q(uiet)\n");
99 printf(" h(elp)\n");
100 exit(1);
101 }
102
103 static int doTest(
104 CSSM_TP_HANDLE tpHand,
105 CSSM_CL_HANDLE clHand,
106 CSSM_CSP_HANDLE cspHand,
107 CSSM_DL_DB_HANDLE dlDb,
108 CSSM_DATA_PTR certs,
109 unsigned numCerts,
110 CSSM_KEY_PTR pubKeys, // for partial key detect
111 CSSM_BOOL useDb,
112 ExpectResult expectResult,
113 CSSM_BOOL verbose,
114 CSSM_BOOL quiet)
115 {
116 unsigned cgEnd; // last cert in certGroupFrag
117 unsigned anchorStart; // first cert in anchorGroup
118 unsigned anchorEnd; // last cert in anchorGroup
119 CSSM_CERTGROUP certGroupFrag; // INPUT to CertGroupVerify
120 CSSM_CERTGROUP anchorCerts; // ditto
121 unsigned die; // random number
122 CSSM_DL_DB_LIST dbList;
123 CSSM_DL_DB_LIST_PTR dbListPtr;
124 CSSM_RETURN expErr; // expected rtn from GroupVfy()
125 int rtn = 0;
126 const char *expResStr;
127 uint32 expEvidenceSize; // expected evidenceSize
128 unsigned evidenceSize; // actual evidence size
129 CSSM_TP_VERIFY_CONTEXT_RESULT vfyResult;
130 CSSM_CERTGROUP_PTR outGrp = NULL;
131 CSSM_RETURN crtn;
132 CSSM_DL_DB_HANDLE_PTR dlDbPtr;
133 unsigned numAnchors;
134
135 memset(&vfyResult, 0, sizeof(CSSM_TP_VERIFY_CONTEXT_RESULT));
136
137 if(useDb) {
138 dlDbPtr = &dlDb;
139 dbList.NumHandles = 1;
140 dbList.DLDBHandle = &dlDb;
141 dbListPtr = &dbList;
142 }
143 else {
144 /* not yet */
145 dlDbPtr = NULL;
146 dbListPtr = NULL;
147 }
148
149 /* the four test cases */
150 switch(expectResult) {
151 case ER_InvalidAnchor:
152 /* root in certGroup, not found in AnchorCerts */
153 cgEnd = numCerts - 1; // certGroupFrag is the whole pile
154 anchorStart = 0; // anchors = all except root
155 anchorEnd = numCerts - 2;
156 expErr = CSSMERR_TP_INVALID_ANCHOR_CERT;
157 expEvidenceSize = numCerts;
158 expResStr = "InvalidAnchor (root in certGroup but not in anchors)";
159 break;
160
161 case ER_RootInCertGroup:
162 /* root in certGroup, copy in AnchorCerts */
163 cgEnd = numCerts - 1; // certGroupFrag = the whole pile
164 anchorStart = 0; // anchors = the whole pile
165 anchorEnd = numCerts - 1;
166 expErr = CSSM_OK;
167 expEvidenceSize = numCerts;
168 expResStr = "Good (root in certGroup AND in anchors)";
169 break;
170
171 case ER_AnchorVerify:
172 /* non-root end of chain verified by an anchor */
173 /* break chain at random place other than end */
174 /* die is the last cert in certGroupFrag */
175 die = genRand(0, numCerts-2);
176 cgEnd = die; // certGroupFrag up to break point
177 anchorStart = 0; // anchors = all
178 anchorEnd = numCerts - 1;
179 if(pubKeys[die+1].KeyHeader.KeyAttr & CSSM_KEYATTR_PARTIAL) {
180 /* this will fail due to an unusable anchor */
181 expErr = CSSMERR_TP_CERTIFICATE_CANT_OPERATE;
182 expResStr = "Root ONLY in anchors but has partial pub key";
183 }
184 else {
185 expErr = CSSM_OK;
186 expResStr = "Good (root ONLY in anchors)";
187 }
188 /* size = # certs in certGroupFrag, plus one anchor */
189 expEvidenceSize = die + 2;
190 break;
191
192 case ER_NoRoot:
193 /* no root, no anchor verify */
194 /* break chain at random place other than end */
195 /* die is the last cert in certGroupFrag */
196 /* skip a cert, then anchors start at die + 2 */
197 die = genRand(0, numCerts-2);
198 cgEnd = die; // certGroupFrag up to break point
199 anchorStart = die + 2; // anchors = n+1...numCerts-2
200 // may be empty if n == numCerts-2
201 anchorEnd = numCerts - 2;
202 if((die != 0) && // partial leaf not reported as partial!
203 (pubKeys[die].KeyHeader.KeyAttr & CSSM_KEYATTR_PARTIAL)) {
204 /* this will fail due to an unusable cert (this one) */
205 expErr = CSSMERR_TP_CERTIFICATE_CANT_OPERATE;
206 expResStr = "Not Trusted (no root, no anchor verify), partial";
207 }
208 else {
209 expErr = CSSMERR_TP_NOT_TRUSTED;
210 expResStr = "Not Trusted (no root, no anchor verify)";
211 }
212 expEvidenceSize = die + 1;
213 break;
214
215 case ER_IncompleteKey:
216 /*
217 * Anchor has incomplete pub key
218 * Root in certGroup, copy in AnchorCerts
219 * Avoid putting anchor in certGroupFrag because the TP will think
220 * it's NOT a root and it'll show up twice in the evidence - once
221 * from certGroupFrag (at which point the search for a root
222 * keeps going), and once from Anchors.
223 */
224 cgEnd = numCerts - 2; // certGroupFrag = the whole pile less the anchor
225 anchorStart = 0; // anchors = the whole pile
226 anchorEnd = numCerts - 1;
227 expErr = CSSMERR_TP_CERTIFICATE_CANT_OPERATE;
228 expEvidenceSize = numCerts;
229 expResStr = "Partial public key in anchor";
230 break;
231 }
232
233 if(verbose) {
234 printf(" ...expectResult = %s\n", expResStr);
235 }
236
237 /* cook up two cert groups */
238 if(verbose) {
239 printf(" ...building certGroupFrag from certs[0..%d]\n",
240 cgEnd);
241 }
242 if(tpMakeRandCertGroup(clHand,
243 dbListPtr,
244 certs, // certGroupFrag always starts at 0
245 cgEnd+1, // # of certs
246 &certGroupFrag,
247 CSSM_TRUE, // firstCertIsSubject
248 verbose,
249 CSSM_FALSE, // allInDbs
250 CSSM_FALSE)) { // skipFirstDb
251 printf("Error in tpMakeRandCertGroup\n");
252 return 1;
253 }
254
255 if(verbose) {
256 printf(" ...building anchorCerts from certs[%d..%d]\n",
257 anchorStart, anchorEnd);
258 }
259 if(anchorEnd > (numCerts - 1)) {
260 printf("anchorEnd overflow\n");
261 exit(1);
262 }
263 if(anchorStart >= anchorEnd) {
264 /* legal in some corner cases, ==> empty enchors */
265 numAnchors = 0;
266 }
267 else {
268 numAnchors = anchorEnd - anchorStart + 1;
269 }
270 /* anchors do not go in DB */
271 if(tpMakeRandCertGroup(clHand,
272 NULL,
273 certs + anchorStart,
274 numAnchors, // # of certs
275 &anchorCerts,
276 CSSM_FALSE, // firstCertIsSubject
277 verbose,
278 CSSM_FALSE, // allInDbs
279 CSSM_FALSE)) { // skipFirstDb
280 printf("Error in tpMakeRandCertGroup\n");
281 return 1;
282 }
283
284 crtn = tpCertGroupVerify(
285 tpHand,
286 clHand,
287 cspHand,
288 dbListPtr,
289 &CSSMOID_APPLE_X509_BASIC, // policy
290 NULL, // fieldOpts
291 NULL, // actionData
292 NULL, // policyOpts
293 &certGroupFrag,
294 anchorCerts.GroupList.CertList, // passed as CSSM_DATA_PTR, not CERTGROUP....
295 anchorCerts.NumCerts,
296 CSSM_TP_STOP_ON_POLICY,
297 NULL, // cssmTimeStr
298 &vfyResult);
299
300 /* first verify format of result */
301 if( (vfyResult.NumberOfEvidences != 3) ||
302 (vfyResult.Evidence == NULL) ||
303 (vfyResult.Evidence[0].EvidenceForm != CSSM_EVIDENCE_FORM_APPLE_HEADER) ||
304 (vfyResult.Evidence[1].EvidenceForm != CSSM_EVIDENCE_FORM_APPLE_CERTGROUP) ||
305 (vfyResult.Evidence[2].EvidenceForm != CSSM_EVIDENCE_FORM_APPLE_CERT_INFO) ||
306 (vfyResult.Evidence[0].Evidence == NULL) ||
307 (vfyResult.Evidence[1].Evidence == NULL) ||
308 (vfyResult.Evidence[2].Evidence == NULL)) {
309 printf("***Malformed VerifyContextResult\n");
310 rtn = testError(quiet);
311 if(rtn) {
312 return rtn;
313 }
314 }
315 if((vfyResult.Evidence != NULL) && (vfyResult.Evidence[1].Evidence != NULL)) {
316 outGrp = (CSSM_CERTGROUP_PTR)vfyResult.Evidence[1].Evidence;
317 evidenceSize = outGrp->NumCerts;
318 }
319 else {
320 /* in case no evidence returned */
321 evidenceSize = 0;
322 }
323
324 /* %%% since non-root anchors are permitted as of <rdar://5685316>,
325 * the test assumptions have become invalid: these tests generate
326 * an anchors list which always includes the full chain, so by
327 * definition, the evidence chain will never be longer than 2,
328 * since the leaf's issuer is always an anchor.
329 * %%% need to revisit and rewrite these tests. -kcm
330 */
331 if ((evidenceSize > 1) && (evidenceSize < expEvidenceSize) &&
332 (crtn == CSSM_OK || crtn == CSSMERR_TP_CERTIFICATE_CANT_OPERATE)) {
333 /* ignore, for now */
334 expErr = crtn;
335 expEvidenceSize = evidenceSize;
336 }
337
338 if((crtn != expErr) ||
339 (evidenceSize != expEvidenceSize)) {
340 printf("***Error on expectResult %s\n", expResStr);
341 printf(" err %s expErr %s\n",
342 cssmErrToStr(crtn), cssmErrToStr(expErr));
343 printf(" evidenceSize %d expEvidenceSize %u\n",
344 evidenceSize, (unsigned)expEvidenceSize);
345 rtn = testError(quiet);
346 }
347 else {
348 rtn = 0;
349 }
350
351 /* free resources */
352 tpFreeCertGroup(&certGroupFrag,
353 CSSM_FALSE, // caller malloc'd the actual certs
354 CSSM_FALSE); // struct is on stack
355 tpFreeCertGroup(&anchorCerts,
356 CSSM_FALSE, // caller malloc'd the actual certs
357 CSSM_FALSE); // struct is on stack
358 freeVfyResult(&vfyResult);
359 if(useDb) {
360 clDeleteAllCerts(dlDb);
361 }
362 return rtn;
363 }
364
365 int main(int argc, char **argv)
366 {
367 int arg;
368 char *argp;
369 unsigned loop;
370 CSSM_TP_HANDLE tpHand = 0;
371 CSSM_CL_HANDLE clHand = 0;
372 CSSM_CSP_HANDLE cspHand = 0;
373 CSSM_DL_DB_HANDLE dlDbHand = {0, 0};
374 ExpectResult expectResult;
375 char *notAfterStr;
376 char *notBeforeStr;
377 unsigned i;
378 CSSM_DATA paramData;
379 CSSM_DATA_PTR paramDataP = NULL;
380 unsigned numTests = 4;
381 unsigned len;
382
383 /* all three of these are arrays with numCert elements */
384 CSSM_KEY_PTR pubKeys = NULL;
385 CSSM_KEY_PTR privKeys = NULL;
386 CSSM_DATA_PTR certs = NULL;
387
388 /* Keys do NOT go in the cert DB */
389 CSSM_DL_DB_HANDLE keyDb = {0, 0};
390 CSSM_KEY savedRoot; // for ER_IncompleteKey
391
392 /*
393 * User-spec'd params
394 */
395 unsigned loops = LOOPS_DEF;
396 CSSM_BOOL verbose = CSSM_FALSE;
397 CSSM_BOOL quiet = CSSM_FALSE;
398 unsigned numCerts = NUM_CERTS_DEF;
399 uint32 keyGenAlg = KEYGEN_ALG_DEF;
400 uint32 sigAlg = SIG_ALG_DEF;
401 #if CERT_IN_DB
402 CSSM_BOOL useDb = CSSM_TRUE;
403 #else
404 CSSM_BOOL useDb = CSSM_FALSE;
405 #endif
406 CSSM_BOOL doPause = CSSM_FALSE;
407 uint32 keySizeInBits = CSP_KEY_SIZE_DEFAULT;
408 CSSM_BOOL noPartialKeys = CSSM_FALSE;
409 char dbName[100]; /* DB_NAME_pid */
410
411 for(arg=1; arg<argc; arg++) {
412 argp = argv[arg];
413 switch(argp[0]) {
414 case 'l':
415 loops = atoi(&argp[2]);
416 break;
417 case 'k':
418 keySizeInBits = atoi(&argp[2]);
419 break;
420 case 'n':
421 numCerts = atoi(&argp[2]);
422 break;
423 case 'v':
424 verbose = CSSM_TRUE;
425 break;
426 case 'q':
427 quiet = CSSM_TRUE;
428 break;
429 case 'a':
430 switch(argp[2]) {
431 case 'f':
432 keyGenAlg = CSSM_ALGID_FEE;
433 sigAlg = CSSM_ALGID_FEE_MD5;
434 break;
435 case 'F':
436 keyGenAlg = CSSM_ALGID_FEE;
437 sigAlg = CSSM_ALGID_FEE_SHA1;
438 break;
439 case 'e':
440 keyGenAlg = CSSM_ALGID_FEE;
441 sigAlg = CSSM_ALGID_SHA1WithECDSA;
442 break;
443 case 's':
444 keyGenAlg = CSSM_ALGID_RSA;
445 sigAlg = CSSM_ALGID_SHA1WithRSA;
446 break;
447 case 'm':
448 keyGenAlg = CSSM_ALGID_RSA;
449 sigAlg = CSSM_ALGID_MD5WithRSA;
450 break;
451 case 'd':
452 keyGenAlg = CSSM_ALGID_DSA;
453 sigAlg = CSSM_ALGID_SHA1WithDSA;
454 break;
455 case '4':
456 keyGenAlg = CSSM_ALGID_RSA;
457 sigAlg = CSSM_ALGID_SHA224WithRSA;
458 break;
459 case '6':
460 keyGenAlg = CSSM_ALGID_RSA;
461 sigAlg = CSSM_ALGID_SHA256WithRSA;
462 break;
463 case '3':
464 keyGenAlg = CSSM_ALGID_RSA;
465 sigAlg = CSSM_ALGID_SHA512WithRSA;
466 break;
467 case '5':
468 keyGenAlg = CSSM_ALGID_RSA;
469 sigAlg = CSSM_ALGID_SHA512WithRSA;
470 break;
471 case 'E':
472 keyGenAlg = CSSM_ALGID_ECDSA;
473 sigAlg = CSSM_ALGID_SHA1WithECDSA;
474 break;
475 case '7':
476 keyGenAlg = CSSM_ALGID_ECDSA;
477 sigAlg = CSSM_ALGID_SHA512WithECDSA;
478 break;
479 default:
480 usage(argv);
481 }
482 break;
483 case 'N':
484 noPartialKeys = CSSM_TRUE;
485 break;
486 case 'd':
487 useDb = CSSM_FALSE;
488 break;
489 case 'P':
490 doPause = CSSM_TRUE;
491 break;
492 case 'h':
493 default:
494 usage(argv);
495 }
496 }
497
498 sprintf(dbName, "%s_%d", DB_NAME, (int)getpid());
499
500 if(numCerts < 2) {
501 printf("Can't run with cert chain smaller than 2\n");
502 exit(1);
503 }
504
505 /* attach to all the modules we need */
506 cspHand = cspStartup();
507 if(cspHand == 0) {
508 exit(1);
509 }
510 #if CERT_IN_DB
511 if(useDb) {
512 dlDbHand.DLHandle = dlStartup();
513 if(dlDbHand.DLHandle == 0) {
514 exit(1);
515 }
516 CSSM_RETURN crtn = tpKcOpen(dlDbHand.DLHandle, dbName, dbName,
517 CSSM_TRUE, &dlDbHand.DBHandle);
518 if(crtn) {
519 printf("Error opening keychain %s; aborting.\n", dbName);
520 exit(1);
521 }
522 }
523 #endif
524 clHand = clStartup();
525 if(clHand == 0) {
526 goto abort;
527 }
528 tpHand = tpStartup();
529 if(tpHand == 0) {
530 goto abort;
531 }
532
533 /* malloc empty keys and certs */
534 pubKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numCerts, sizeof(CSSM_KEY));
535 privKeys = (CSSM_KEY_PTR)CSSM_CALLOC(numCerts, sizeof(CSSM_KEY));
536 certs = (CSSM_DATA_PTR)CSSM_CALLOC(numCerts, sizeof(CSSM_DATA));
537 if((pubKeys == NULL) || (privKeys == NULL) || (certs == NULL)) {
538 printf("not enough memory for %u keys pairs and certs.\n",
539 numCerts);
540 goto abort;
541 }
542
543 printf("Starting cgVerify; args: ");
544 for(i=1; i<(unsigned)argc; i++) {
545 printf("%s ", argv[i]);
546 }
547 printf("\n");
548
549 /* generate key pairs */
550 if(!quiet) {
551 printf("generating keys...\n");
552 }
553 if(keyGenAlg == CSSM_ALGID_DSA) {
554 if(!readFile(DSA_PARAM_FILE, (unsigned char **)&paramData.Data, &len)) {
555 if(!quiet) {
556 printf("...using DSA params from %s\n", DSA_PARAM_FILE);
557 }
558 paramData.Length = len;
559 paramDataP = &paramData;
560 }
561 else {
562 printf("***warning: no param file. KeyGen is going to be slow!\n");
563 printf("***You might consider running this from the clxutils/cgVerify "
564 "directory.\n");
565 }
566 }
567 if(tpGenKeys(cspHand,
568 keyDb,
569 numCerts,
570 keyGenAlg,
571 keySizeInBits,
572 "cgVerify", // keyLabelBase
573 pubKeys,
574 privKeys,
575 paramDataP)) {
576 goto abort;
577 }
578 notBeforeStr = genTimeAtNowPlus(0);
579 notAfterStr = genTimeAtNowPlus(SECONDS_TO_LIVE);
580
581 /*
582 * If DSA, insert some random partial public keys which are not
583 * fatal (i.e., root can not be partial). We include the leaf in this
584 * loop - the TP is *supposed* to ignore that situation, ane we make
585 * sure it does.
586 */
587 if((keyGenAlg == CSSM_ALGID_DSA) && !noPartialKeys) {
588 for(unsigned dex=0; dex<(numCerts-1); dex++) {
589 int die = genRand(0,1);
590 if(die) {
591 /* this one gets partialized */
592 CSSM_KEY newKey;
593 if(verbose) {
594 printf("...making partial DSA pub key at index %u\n", dex);
595 }
596 CSSM_RETURN crtn = extractDsaPartial(cspHand, &pubKeys[dex], &newKey);
597 if(crtn) {
598 printf("***Error converting to partial key. Aborting.\n");
599 exit(1);
600 }
601 CSSM_FREE(pubKeys[dex].KeyData.Data);
602 pubKeys[dex] = newKey;
603 }
604 }
605 }
606 if(!quiet) {
607 printf("starting %s test\n", argv[0]);
608
609 }
610 if(keyGenAlg == CSSM_ALGID_DSA) {
611 numTests = 5;
612 }
613 for(loop=1; ; loop++) {
614 if(!quiet) {
615 printf("...loop %d\n", loop);
616 }
617
618 /* cycle thru test scenarios */
619 switch(loop % numTests) {
620 case 0:
621 expectResult = ER_InvalidAnchor;
622 break;
623 case 1:
624 expectResult = ER_RootInCertGroup;
625 break;
626 case 2:
627 expectResult = ER_AnchorVerify;
628 break;
629 case 3:
630 expectResult = ER_NoRoot;
631 break;
632 case 4:
633 /* DSA only */
634 expectResult = ER_IncompleteKey;
635 savedRoot = pubKeys[numCerts-1];
636 /* make anchor unusable */
637 if(extractDsaPartial(cspHand, &savedRoot, &pubKeys[numCerts-1])) {
638 printf("...error partializing anchor key; aborting\n");
639 exit(1);
640 }
641 break;
642 }
643 if(tpGenCerts(cspHand,
644 clHand,
645 numCerts,
646 sigAlg,
647 "cgConstruct", // nameBase
648 pubKeys,
649 privKeys,
650 certs,
651 notBeforeStr,
652 notAfterStr)) {
653 break;
654 }
655
656 if(doTest(tpHand,
657 clHand,
658 cspHand,
659 dlDbHand,
660 certs,
661 numCerts,
662 pubKeys,
663 useDb,
664 expectResult,
665 verbose,
666 quiet)) {
667 break;
668 }
669 for(i=0; i<numCerts; i++) {
670 appFreeCssmData(&certs[i], CSSM_FALSE);
671 }
672 if(expectResult == ER_IncompleteKey) {
673 CSSM_FREE(pubKeys[numCerts-1].KeyData.Data);
674 pubKeys[numCerts-1] = savedRoot;
675 }
676
677 memset(certs, 0, numCerts * sizeof(CSSM_DATA));
678 if(loops && (loop == loops)) {
679 break;
680 }
681 if(doPause) {
682 printf("Hit CR to continue: ");
683 fpurge(stdin);
684 getchar();
685 }
686 }
687 abort:
688 if(privKeys != NULL) {
689 for(i=0; i<numCerts; i++) {
690 if(privKeys[i].KeyData.Data != NULL) {
691 cspFreeKey(cspHand, &privKeys[i]);
692 }
693 }
694 CSSM_FREE(privKeys);
695 }
696 if(pubKeys != NULL) {
697 for(i=0; i<numCerts; i++) {
698 if(pubKeys[i].KeyData.Data != NULL) {
699 cspFreeKey(cspHand, &pubKeys[i]);
700 }
701 }
702 CSSM_FREE(pubKeys);
703 }
704 if(certs != NULL) {
705 for(i=0; i<numCerts; i++) {
706 appFreeCssmData(&certs[i], CSSM_FALSE);
707 }
708 CSSM_FREE(certs);
709 }
710 if(cspHand != 0) {
711 CSSM_ModuleDetach(cspHand);
712 }
713 if(clHand != 0) {
714 CSSM_ModuleDetach(clHand);
715 }
716 if(tpHand != 0) {
717 CSSM_ModuleDetach(tpHand);
718 }
719
720 if(!quiet) {
721 printf("%s test complete\n", argv[0]);
722 }
723 return 0;
724 }