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 */ 17typedef 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 */ 64typedef struct { 65 const char *keyName; 66 LineType lineType; 67} KeyLineType; 68 69KeyLineType 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 */ 114typedef struct { 115 const char *str; 116 CertVerifyPolicy policy; 117} PolicyString; 118 119static 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) */ 136static 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 */ 154static 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 '=') */ 179static 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 224static 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() */ 358typedef enum { 359 OTR_Success, 360 OTR_Fail, 361 OTR_EndOfScript 362} OneTestResult; 363 364/* parse boolean variable, in globals or per-test */ 365OneTestResult 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 */ 428static 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 451OneTestResult 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 */ 496OneTestResult 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 835int 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 */ 880int 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 894void 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 914void 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 924