]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/certcrl/script.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / SecurityTests / clxutils / certcrl / script.cpp
1 /*
2 * script.cpp - run certcrl from script file
3 */
4
5 #include <security_cdsa_utils/cuFileIo.h>
6 #include <utilLib/common.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <Security/cssm.h>
12 #include <clAppUtils/BlobList.h>
13 #include <clAppUtils/certVerify.h>
14 #include "script.h"
15
16 /* Line type returned from parseLine */
17 typedef enum {
18 LT_Empty, // comments, whitespace
19 LT_TestName,
20 LT_DirName,
21 LT_Cert,
22 LT_Root,
23 LT_CRL,
24 LT_CertDb,
25 LT_CrlDb,
26 LT_ExpectError, // expected function return
27 LT_CertError, // per-cert error string
28 LT_CertStatus, // per-cert StatusBits
29 LT_SslHost,
30 LT_SslClient,
31 LT_SenderEmail,
32 LT_Policy,
33 LT_KeyUsage,
34 LT_RevokePolicy,
35 LT_RespURI,
36 LT_RespCert,
37 LT_EndOfSection,
38 LT_EndOfFile,
39 LT_BadLine,
40 LT_Globals,
41 LT_Echo,
42 LT_GenerateOcspNonce,
43 LT_RequireOcspNonce,
44 LT_AllowExpiredRoot,
45 LT_VerifyTime,
46 LT_ImplicitAnchors,
47
48 /* variables which can be in globals or per-test */
49 LT_AllowUnverified,
50 LT_CrlNetFetchEnable,
51 LT_CertNetFetchEnable,
52 LT_UseSystemAnchors,
53 LT_UseTrustSettings,
54 LT_LeafCertIsCA,
55 LT_CacheDisable,
56 LT_OcspNetFetchDisable,
57 LT_RequireOcspIfPresent,
58 LT_RequireCrlIfPresent,
59 LT_RequireCrlForAll,
60 LT_RequireOcspForAll
61 } LineType;
62
63 /* table to map key names to LineType */
64 typedef struct {
65 const char *keyName;
66 LineType lineType;
67 } KeyLineType;
68
69 KeyLineType keyLineTypes[] =
70 {
71 { "test", LT_TestName },
72 { "dir", LT_DirName },
73 { "cert", LT_Cert },
74 { "root", LT_Root },
75 { "crl", LT_CRL },
76 { "certDb", LT_CertDb },
77 { "crlDb", LT_CrlDb }, // no longer used
78 { "error", LT_ExpectError },
79 { "certerror", LT_CertError },
80 { "certstatus", LT_CertStatus },
81 { "sslHost", LT_SslHost },
82 { "sslClient", LT_SslClient },
83 { "senderEmail", LT_SenderEmail },
84 { "policy", LT_Policy },
85 { "keyUsage", LT_KeyUsage },
86 { "revokePolicy", LT_RevokePolicy },
87 { "responderURI", LT_RespURI },
88 { "responderCert", LT_RespCert },
89 { "cacheDisable", LT_CacheDisable },
90 { "echo", LT_Echo },
91 { "globals", LT_Globals },
92 { "end", LT_EndOfSection },
93 { "allowUnverified", LT_AllowUnverified },
94 { "requireCrlIfPresent",LT_RequireCrlIfPresent },
95 { "crlNetFetchEnable", LT_CrlNetFetchEnable },
96 { "certNetFetchEnable", LT_CertNetFetchEnable },
97 { "ocspNetFetchDisable",LT_OcspNetFetchDisable },
98 { "requireCrlForAll", LT_RequireCrlForAll },
99 { "requireOcspForAll", LT_RequireOcspForAll },
100 { "useSystemAnchors", LT_UseSystemAnchors },
101 { "useTrustSettings", LT_UseTrustSettings },
102 { "leafCertIsCA", LT_LeafCertIsCA },
103 { "requireOcspIfPresent",LT_RequireOcspIfPresent },
104 { "generateOcspNonce", LT_GenerateOcspNonce },
105 { "requireOcspNonce", LT_RequireOcspNonce },
106 { "allowExpiredRoot", LT_AllowExpiredRoot },
107 { "verifyTime", LT_VerifyTime },
108 { "implicitAnchors", LT_ImplicitAnchors },
109 };
110
111 #define NUM_KEYS (sizeof(keyLineTypes) / sizeof(KeyLineType))
112
113 /* map policy string to CertVerifyPolicy */
114 typedef struct {
115 const char *str;
116 CertVerifyPolicy policy;
117 } PolicyString;
118
119 static const PolicyString policyStrings[] =
120 {
121 { "basic", CVP_Basic },
122 { "ssl", CVP_SSL },
123 { "smime", CVP_SMIME },
124 { "swuSign", CVP_SWUpdateSign },
125 { "codeSign", CVP_AppleCodeSigning },
126 { "pkgSign", CVP_PackageSigning },
127 { "resourceSign", CVP_ResourceSigning },
128 { "iChat", CVP_iChat },
129 { "pkinitServer", CVP_PKINIT_Server },
130 { "pkinitClient", CVP_PKINIT_Client },
131 { "IPSec", CVP_IPSec },
132 { NULL, (CertVerifyPolicy)0 }
133 };
134
135 /* skip whitespace (but not line terminators) */
136 static void skipWhite(
137 const unsigned char *&cp,
138 unsigned &bytesLeft)
139 {
140 while(bytesLeft != 0) {
141 switch(*cp) {
142 case ' ':
143 case '\t':
144 cp++;
145 bytesLeft--;
146 break;
147 default:
148 return;
149 }
150 }
151 }
152
153 /* skip to next char after EOL */
154 static void skipLine(
155 const unsigned char *&cp,
156 unsigned &bytesLeft)
157 {
158 bool foundEol = false;
159 while(bytesLeft != 0) {
160 switch(*cp) {
161 case '\n':
162 case '\r':
163 foundEol = true;
164 cp++;
165 bytesLeft--;
166 break;
167 default:
168 if(foundEol) {
169 return;
170 }
171 cp++;
172 bytesLeft--;
173 break;
174 }
175 }
176 }
177
178 /* skip to end of current token (i.e., find next whitespace or '=') */
179 static void skipToken(
180 const unsigned char *&cp,
181 unsigned &bytesLeft,
182 bool isQuoted)
183 {
184 while(bytesLeft != 0) {
185 char c = *cp;
186 if(isQuoted) {
187 if(c == '"') {
188 /* end of quoted string, return still pointing to it */
189 return;
190 }
191 }
192 else {
193 if(isspace(c)) {
194 return;
195 }
196 if(c == '=') {
197 /* hopefully, end of key */
198 return;
199 }
200 }
201 cp++;
202 bytesLeft--;
203 }
204 }
205
206 /*
207 * Parse one line, return value (following "=" and whitespace) as
208 * mallocd C string. On return, scriptData points to next char after line
209 * terminator(s).
210 *
211 * The basic form of a line is
212 * [whitespace] key [whitespace] = [whitespace] value [whitespace] \n|\r...
213 *
214 * ...except for comments and blank lines. Comments contain '#' as the
215 * first non-whitespace char.
216 */
217 #define CHECK_EOF(bytesLeft) \
218 if(bytesLeft == 0) { \
219 return LT_BadLine; \
220 }
221
222 #define MAX_KEY_LEN 80
223
224 static LineType parseLine(
225 const unsigned char *&cp, // IN/OUT
226 unsigned &bytesLeft, // IN/OUT bytes left in script
227 char *&value, // mallocd and RETURNED
228 CSSM_BOOL verbose)
229 {
230 if(bytesLeft == 0) {
231 if(verbose) {
232 printf("...EOF reached\n");
233 }
234 return LT_EndOfFile;
235 }
236 skipWhite(cp, bytesLeft);
237 if(bytesLeft == 0) {
238 return LT_Empty;
239 }
240 switch(*cp) {
241 case '#':
242 case '\n':
243 case '\r':
244 skipLine(cp, bytesLeft);
245 return LT_Empty;
246 }
247
248 /*
249 * cp points to start of key
250 * get key value as NULL terminated C string
251 */
252 const unsigned char *tokenStart = cp;
253 skipToken(cp, bytesLeft, false);
254 CHECK_EOF(bytesLeft);
255 unsigned tokenLen = cp - tokenStart;
256 char key[MAX_KEY_LEN];
257 memmove(key, tokenStart, tokenLen);
258 key[tokenLen] = '\0';
259
260 /* parse key */
261 LineType rtnType = LT_BadLine;
262 for(unsigned i=0; i<NUM_KEYS; i++) {
263 KeyLineType *klt = &keyLineTypes[i];
264 if(!strcmp(klt->keyName, key)) {
265 rtnType = klt->lineType;
266 break;
267 }
268 }
269
270 /* these keys have no value */
271 bool noValue = false;
272 switch(rtnType) {
273 case LT_EndOfSection:
274 if(verbose) {
275 printf("...end of section\n");
276 }
277 noValue = true;
278 break;
279 case LT_Globals:
280 noValue = true;
281 break;
282 case LT_BadLine:
283 printf("***unknown key '%s'\n", key);
284 noValue = true;
285 break;
286 default:
287 break;
288 }
289 if(noValue) {
290 /* done with line */
291 skipLine(cp, bytesLeft);
292 return rtnType;
293 }
294
295 /* get to start of value */
296 skipWhite(cp, bytesLeft);
297 CHECK_EOF(bytesLeft);
298 if(rtnType == LT_Echo) {
299 /* echo: value is everything from this char to end of line */
300 tokenStart = cp;
301 for( ; bytesLeft != 0; cp++, bytesLeft--) {
302 if((*cp == '\n') || (*cp == '\r')) {
303 break;
304 }
305 }
306 if(cp != tokenStart) {
307 tokenLen = cp - tokenStart;
308 value = (char *)malloc(tokenLen + 1);
309 memmove(value, tokenStart, tokenLen);
310 value[tokenLen] = '\0';
311 }
312 else {
313 value = NULL;
314 }
315 skipLine(cp, bytesLeft);
316 return LT_Echo;
317 }
318
319 /* all other line types: value is first token after '=' */
320 if(*cp != '=') {
321 printf("===missing = after key\n");
322 return LT_BadLine;
323 }
324 cp++;
325 bytesLeft--;
326 skipWhite(cp, bytesLeft);
327 CHECK_EOF(bytesLeft);
328
329 /* cp points to start of value */
330 bool isQuoted = false;
331 if(*cp == '"') {
332 cp++;
333 bytesLeft--;
334 CHECK_EOF(bytesLeft)
335 isQuoted = true;
336 }
337 tokenStart = cp;
338 skipToken(cp, bytesLeft, isQuoted);
339 /* cp points to next char after end of value */
340 /* get value as mallocd C string */
341 tokenLen = cp - tokenStart;
342 if(tokenLen == 0) {
343 value = NULL;
344 }
345 else {
346 value = (char *)malloc(tokenLen + 1);
347 memmove(value, tokenStart, tokenLen);
348 value[tokenLen] = '\0';
349 }
350 skipLine(cp, bytesLeft);
351 if(verbose) {
352 printf("'%s' = '%s'\n", key, value);
353 }
354 return rtnType;
355 }
356
357 /* describe fate of one run of runOneTest() */
358 typedef enum {
359 OTR_Success,
360 OTR_Fail,
361 OTR_EndOfScript
362 } OneTestResult;
363
364 /* parse boolean variable, in globals or per-test */
365 OneTestResult parseVar(
366 LineType lineType,
367 const char *value,
368 ScriptVars &scriptVars)
369 {
370 /* parse value */
371 CSSM_BOOL cval;
372 if(!strcmp(value, "true")) {
373 cval = CSSM_TRUE;
374 }
375 else if(!strcmp(value, "false")) {
376 cval = CSSM_FALSE;
377 }
378 else {
379 printf("***boolean variables must be true or false, not '%s'\n", value);
380 return OTR_Fail;
381 }
382
383 switch(lineType) {
384 case LT_AllowUnverified:
385 scriptVars.allowUnverified = cval;
386 break;
387 case LT_CrlNetFetchEnable:
388 scriptVars.crlNetFetchEnable = cval;
389 break;
390 case LT_CertNetFetchEnable:
391 scriptVars.certNetFetchEnable = cval;
392 break;
393 case LT_UseSystemAnchors:
394 scriptVars.useSystemAnchors = cval;
395 break;
396 case LT_UseTrustSettings:
397 scriptVars.useTrustSettings = cval;
398 break;
399 case LT_LeafCertIsCA:
400 scriptVars.leafCertIsCA = cval;
401 break;
402 case LT_CacheDisable:
403 scriptVars.cacheDisable = cval;
404 break;
405 case LT_OcspNetFetchDisable:
406 scriptVars.ocspNetFetchDisable = cval;
407 break;
408 case LT_RequireOcspIfPresent:
409 scriptVars.requireOcspIfPresent = cval;
410 break;
411 case LT_RequireCrlIfPresent:
412 scriptVars.requireCrlIfPresent = cval;
413 break;
414 case LT_RequireCrlForAll:
415 scriptVars.requireCrlForAll = cval;
416 break;
417 case LT_RequireOcspForAll:
418 scriptVars.requireOcspForAll = cval;
419 break;
420 default:
421 return OTR_Fail;
422 }
423 return OTR_Success;
424 }
425
426 #if 0
427 /* sure wish X had strnstr */
428 static char *strnstr(
429 const char *big,
430 const char *little,
431 size_t len)
432 {
433 const char *cp;
434 unsigned littleLen = strlen(little);
435 const char *end = big + len - littleLen;
436 char first = little[0];
437
438 for(cp=big; cp<end; cp++) {
439 /* find first char of little in what's left of big */
440 if(*cp != first) {
441 continue;
442 }
443 if(memcmp(cp, little, littleLen) == 0) {
444 return (char *)cp;
445 }
446 } while(cp < end);
447 return NULL;
448 }
449 #endif
450
451 OneTestResult fetchGlobals(
452 const unsigned char *&scriptData, // IN/OUT
453 unsigned &bytesLeft, // IN/OUT
454 ScriptVars &scriptVars, // may be modified
455 CSSM_BOOL verbose)
456 {
457 char *value; // mallocd by parseLine
458 LineType lineType;
459 OneTestResult result;
460
461 if(verbose) {
462 printf("...processing global section\n");
463 }
464 /* parse globals section until end encountered */
465 do {
466 value = NULL;
467 lineType = parseLine(scriptData, bytesLeft, value, verbose);
468 switch(lineType) {
469 case LT_Empty:
470 case LT_Globals:
471 break; // nop
472 case LT_EndOfSection:
473 return OTR_Success;
474 case LT_EndOfFile:
475 printf("***Premature end of file in globals section.\n");
476 return OTR_EndOfScript;
477 case LT_BadLine:
478 return OTR_Fail;
479 default:
480 /* hopefully a variable */
481 result = parseVar(lineType, value, scriptVars);
482 if(result != OTR_Success) {
483 return OTR_Fail;
484 }
485 break;
486 }
487 if(value != NULL) {
488 free(value);
489 }
490 } while(1);
491 /* NOT REACHED */
492 return OTR_Success;
493 }
494
495 /* parse script fragment for one test, run it */
496 OneTestResult runOneTest(
497 const unsigned char *&scriptData, // IN/OUT
498 unsigned &bytesLeft, // IN/OUT bytes left in script
499 CSSM_TP_HANDLE tpHand,
500 CSSM_CL_HANDLE clHand,
501 CSSM_CSP_HANDLE cspHand,
502 CSSM_DL_HANDLE dlHand,
503 ScriptVars &scriptVars,
504 CSSM_BOOL quiet,
505 CSSM_BOOL verbose)
506 {
507 CertVerifyArgs vfyArgs;
508 memset(&vfyArgs, 0, sizeof(vfyArgs));
509
510 /* to be gathered from script */
511 char *testName = NULL;
512 char *dirName = NULL;
513 BlobList certs;
514 BlobList roots;
515 BlobList crls;
516
517 LineType lineType;
518 char *value; // mallocd by parseLine
519 int blobErr;
520 ScriptVars localVars = scriptVars;
521 OneTestResult result;
522 char pathName[300];
523 CSSM_RETURN crtn;
524 CSSM_DL_DB_HANDLE_PTR currDlDb = NULL;
525 CSSM_DL_DB_LIST dlDbList = {0, NULL};
526
527 vfyArgs.version = CERT_VFY_ARGS_VERS;
528 vfyArgs.certs = &certs;
529 vfyArgs.roots = &roots;
530 vfyArgs.crls = &crls;
531 vfyArgs.quiet = quiet;
532 vfyArgs.tpHand = tpHand;
533 vfyArgs.clHand = clHand;
534 vfyArgs.cspHand = cspHand;
535 vfyArgs.quiet = quiet;
536 vfyArgs.revokePolicy = CRP_None;
537 vfyArgs.vfyPolicy = CVP_Basic;
538 vfyArgs.dlDbList = &dlDbList;
539
540 /* parse script up to end of test */
541 do {
542 value = NULL;
543 blobErr = 0;
544 lineType = parseLine(scriptData, bytesLeft, value, verbose);
545 switch(lineType) {
546 case LT_Empty:
547 break; // nop
548 case LT_TestName:
549 if(testName != NULL) {
550 printf("***Duplicate test name ignored\n");
551 free(value);
552 }
553 else {
554 testName = value; // free after test
555 }
556 value = NULL;
557 break;
558 case LT_DirName:
559 if(dirName != NULL) {
560 printf("***Duplicate directory name ignored\n");
561 free(value);
562 }
563 else {
564 dirName = value; // free after test
565 }
566 value = NULL;
567 break;
568 case LT_Cert:
569 blobErr = certs.addFile(value, dirName);
570 break;
571 case LT_Root:
572 blobErr = roots.addFile(value, dirName);
573 break;
574 case LT_CRL:
575 blobErr = crls.addFile(value, dirName);
576 break;
577 case LT_CertDb:
578 case LT_CrlDb:
579 /* these can be called multiple times */
580 if(dirName) {
581 sprintf(pathName, "%s/%s", dirName, value);
582 }
583 else {
584 strcpy(pathName, value);
585 }
586 dlDbList.NumHandles++;
587 dlDbList.DLDBHandle = (CSSM_DL_DB_HANDLE_PTR)realloc(
588 dlDbList.DLDBHandle,
589 dlDbList.NumHandles * sizeof(CSSM_DL_DB_HANDLE));
590 currDlDb = &dlDbList.DLDBHandle[dlDbList.NumHandles-1];
591 currDlDb->DLHandle = dlHand;
592 crtn = CSSM_DL_DbOpen(dlHand,
593 pathName,
594 NULL, // DbLocation
595 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
596 NULL, // CSSM_ACCESS_CREDENTIALS *AccessCred
597 NULL, // void *OpenParameters
598 &currDlDb->DBHandle);
599 if(crtn) {
600 printError("CSSM_DL_DbOpen", crtn);
601 printf("***Error opening DB %s. Aborting.\n", value);
602 return OTR_Fail;
603 }
604 break;
605 case LT_ExpectError:
606 if(vfyArgs.expectedErrStr != NULL) {
607 printf("***Duplicate expected error ignored\n");
608 free(value);
609 }
610 else {
611 vfyArgs.expectedErrStr = value; // free after test
612 }
613 value = NULL;
614 break;
615 case LT_CertError:
616 vfyArgs.numCertErrors++;
617 vfyArgs.certErrors = (const char **)realloc(vfyArgs.certErrors,
618 vfyArgs.numCertErrors * sizeof(char *));
619 vfyArgs.certErrors[vfyArgs.numCertErrors - 1] = value;
620 value = NULL; // free after test
621 break;
622 case LT_CertStatus:
623 vfyArgs.numCertStatus++;
624 vfyArgs.certStatus = (const char **)realloc(vfyArgs.certStatus,
625 vfyArgs.numCertStatus * sizeof(char *));
626 vfyArgs.certStatus[vfyArgs.numCertStatus - 1] = value;
627 value = NULL; // // free after test
628 break;
629 case LT_SslHost:
630 vfyArgs.sslHost = value;
631 value = NULL; // free after test
632 vfyArgs.vfyPolicy = CVP_SSL;
633 break;
634 case LT_SenderEmail:
635 vfyArgs.senderEmail = value;
636 value = NULL; // free after test
637 if(vfyArgs.vfyPolicy == CVP_Basic) {
638 /* don't overwrite if it's already been set to e.g. iChat */
639 vfyArgs.vfyPolicy = CVP_SMIME;
640 }
641 break;
642 case LT_Policy:
643 if(parsePolicyString(value, &vfyArgs.vfyPolicy)) {
644 printf("Bogus policyValue (%s)\n", value);
645 printPolicyStrings();
646 return OTR_Fail;
647 }
648 break;
649 case LT_KeyUsage:
650 vfyArgs.intendedKeyUse = hexToBin(value);
651 break;
652 case LT_RevokePolicy:
653 if(!strcmp(value, "none")) {
654 vfyArgs.revokePolicy = CRP_None;
655 }
656 else if(!strcmp(value, "crl")) {
657 vfyArgs.revokePolicy = CRP_CRL;
658 }
659 else if(!strcmp(value, "ocsp")) {
660 vfyArgs.revokePolicy = CRP_OCSP;
661 }
662 else if(!strcmp(value, "both")) {
663 vfyArgs.revokePolicy = CRP_CRL_OCSP;
664 }
665 else {
666 printf("***Illegal revokePolicy (%s)\n.", value);
667 return OTR_Fail;
668 }
669 break;
670 case LT_RespURI:
671 vfyArgs.responderURI = value;
672 value = NULL; // free after test
673 break;
674 case LT_VerifyTime:
675 vfyArgs.vfyTime = value;
676 value = NULL; // free after test
677 break;
678 case LT_RespCert:
679 if(readFile(value, (unsigned char **)&vfyArgs.responderCert,
680 &vfyArgs.responderCertLen)) {
681 printf("***Error reading responderCert from %s\n", value);
682 return OTR_Fail;
683 }
684 break;
685 case LT_EndOfSection:
686 break;
687 case LT_EndOfFile:
688 /* only legal if we haven't gotten a test name */
689 if(testName == NULL) {
690 return OTR_EndOfScript;
691 }
692 printf("***Premature end of file.\n");
693 return OTR_Fail;
694 case LT_BadLine:
695 return OTR_Fail;
696 case LT_Globals:
697 result = fetchGlobals(scriptData, bytesLeft, scriptVars, verbose);
698 if(result != OTR_Success) {
699 printf("***Bad globals section\n");
700 return OTR_Fail;
701 }
702 /* and start over with these variables */
703 localVars = scriptVars;
704 break;
705 case LT_SslClient:
706 if(!strcmp(value, "true")) {
707 vfyArgs.sslClient = CSSM_TRUE;
708 }
709 else {
710 vfyArgs.sslClient = CSSM_FALSE;
711 }
712 vfyArgs.vfyPolicy = CVP_SSL;
713 break;
714 case LT_Echo:
715 if(!quiet) {
716 printf("%s\n", value);
717 }
718 break;
719 case LT_GenerateOcspNonce:
720 vfyArgs.generateOcspNonce = CSSM_TRUE;
721 break;
722 case LT_RequireOcspNonce:
723 vfyArgs.requireOcspRespNonce = CSSM_TRUE;
724 break;
725 case LT_AllowExpiredRoot:
726 if(!strcmp(value, "true")) {
727 vfyArgs.allowExpiredRoot = CSSM_TRUE;
728 }
729 else {
730 vfyArgs.allowExpiredRoot = CSSM_FALSE;
731 }
732 break;
733 case LT_ImplicitAnchors:
734 if(!strcmp(value, "true")) {
735 vfyArgs.implicitAnchors = CSSM_TRUE;
736 }
737 else {
738 vfyArgs.implicitAnchors = CSSM_FALSE;
739 }
740 break;
741 default:
742 /* hopefully a variable */
743 result = parseVar(lineType, value, localVars);
744 if(result != OTR_Success) {
745 printf("**Bogus line in script %u bytes from EOF\n",
746 bytesLeft);
747 return OTR_Fail;
748 }
749 break;
750
751 }
752 if(blobErr) {
753 return OTR_Fail;
754 }
755 if(value != NULL) {
756 free(value);
757 }
758 } while(lineType != LT_EndOfSection);
759
760 /* some args: copy from ScriptVars -> CertVerifyArgs */
761 vfyArgs.allowUnverified = localVars.allowUnverified;
762 vfyArgs.requireOcspIfPresent = localVars.requireOcspIfPresent;
763 vfyArgs.requireCrlIfPresent = localVars.requireCrlIfPresent;
764 vfyArgs.crlNetFetchEnable = localVars.crlNetFetchEnable;
765 vfyArgs.certNetFetchEnable = localVars.certNetFetchEnable;
766 vfyArgs.useSystemAnchors = localVars.useSystemAnchors;
767 vfyArgs.useTrustSettings = localVars.useTrustSettings;
768 vfyArgs.leafCertIsCA = localVars.leafCertIsCA;
769 vfyArgs.disableCache = localVars.cacheDisable;
770 vfyArgs.disableOcspNet = localVars.ocspNetFetchDisable;
771 vfyArgs.requireCrlForAll = localVars.requireCrlForAll;
772 vfyArgs.requireOcspForAll = localVars.requireOcspForAll;
773 vfyArgs.verbose = verbose;
774
775 /* here we go */
776 if(!quiet && (testName != NULL)) {
777 printf("%s\n", testName);
778 }
779 int rtn = certVerify(&vfyArgs);
780
781 OneTestResult ourRtn = OTR_Success;
782 if(rtn) {
783 printf("***Failure on %s\n", testName);
784 if(testError(quiet)) {
785 ourRtn = OTR_Fail;
786 }
787 }
788 /* free the stuff that didn't get freed and the end of the
789 * main per-line loop */
790 if(dirName != NULL) {
791 free(dirName);
792 }
793 if(vfyArgs.expectedErrStr != NULL) {
794 free((void *)vfyArgs.expectedErrStr);
795 }
796 if(vfyArgs.certErrors != NULL) {
797 for(unsigned i=0; i<vfyArgs.numCertErrors; i++) {
798 free((void *)vfyArgs.certErrors[i]); // mallocd by parseLine
799 }
800 free((void *)vfyArgs.certErrors); // reallocd by us
801 }
802 if(vfyArgs.certStatus != NULL) {
803 for(unsigned i=0; i<vfyArgs.numCertStatus; i++) {
804 free((void *)vfyArgs.certStatus[i]); // mallocd by parseLine
805 }
806 free((void *)vfyArgs.certStatus); // reallocd by us
807 }
808 if(testName != NULL) {
809 free(testName);
810 }
811 if(vfyArgs.sslHost) {
812 free((void *)vfyArgs.sslHost);
813 }
814 if(vfyArgs.senderEmail) {
815 free((void *)vfyArgs.senderEmail);
816 }
817 if(vfyArgs.responderURI) {
818 free((void *)vfyArgs.responderURI);
819 }
820 if(vfyArgs.responderCert) {
821 free((void *)vfyArgs.responderCert);
822 }
823 if(vfyArgs.vfyTime) {
824 free((void *)vfyArgs.vfyTime);
825 }
826 if(dlDbList.DLDBHandle) {
827 for(unsigned dex=0; dex<dlDbList.NumHandles; dex++) {
828 CSSM_DL_DbClose(dlDbList.DLDBHandle[dex]);
829 }
830 free(dlDbList.DLDBHandle);
831 }
832 return ourRtn;
833 }
834
835 int runScript(
836 const char *fileName,
837 CSSM_TP_HANDLE tpHand,
838 CSSM_CL_HANDLE clHand,
839 CSSM_CSP_HANDLE cspHand,
840 CSSM_DL_HANDLE dlHand,
841 ScriptVars *scriptVars,
842 CSSM_BOOL quiet,
843 CSSM_BOOL verbose,
844 CSSM_BOOL doPause)
845 {
846 const unsigned char *scriptData;
847 unsigned char *cp;
848 unsigned scriptDataLen;
849 int rtn;
850 ScriptVars localVars = *scriptVars;
851
852 rtn = readFile(fileName, &cp, &scriptDataLen);
853 if(rtn) {
854 printf("***Error reading script file; aborting.\n");
855 printf("***Are you sure you're running this from the proper directory?\n");
856 return rtn;
857 }
858 scriptData = (const unsigned char *)cp;
859 OneTestResult result;
860
861 do {
862 result = runOneTest(scriptData, scriptDataLen,
863 tpHand, clHand, cspHand, dlHand,
864 localVars, quiet, verbose);
865 if(result == OTR_Fail) {
866 rtn = 1;
867 break;
868 }
869 if(doPause) {
870 fpurge(stdin);
871 printf("CR to continue: ");
872 getchar();
873 }
874 } while(result == OTR_Success);
875 free(cp);
876 return rtn;
877 }
878
879 /* parse policy string; returns nonzero if not found */
880 int parsePolicyString(
881 const char *str,
882 CertVerifyPolicy *policy)
883 {
884 const PolicyString *ps;
885 for(ps=policyStrings; ps->str; ps++) {
886 if(!strcmp(ps->str, str)) {
887 *policy = ps->policy;
888 return 0;
889 }
890 }
891 return 1;
892 }
893
894 void printPolicyStrings()
895 {
896 printf("Valid policy strings are:\n ");
897 const PolicyString *ps;
898 unsigned i=0;
899 for(ps=policyStrings; ps->str; ps++, i++) {
900 printf("%s", ps->str);
901 if(ps[1].str == NULL) {
902 break;
903 }
904 if((i % 6) == 5) {
905 printf(",\n ");
906 }
907 else {
908 printf(", ");
909 }
910 }
911 printf("\n");
912 }
913
914 void printScriptVars()
915 {
916 printf("The list of script variables is as follows:\n");
917 for(unsigned dex=0; dex<NUM_KEYS; dex++) {
918 printf(" %s\n", keyLineTypes[dex].keyName);
919 }
920 printPolicyStrings();
921 printf("Valid revokePolicy strings are:\n none, crl, ocsp, both\n");
922 }
923