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