pkix_build.c (153455B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * pkix_build.c 6 * 7 * Top level buildChain function 8 * 9 */ 10 11 /* #define PKIX_BUILDDEBUG 1 */ 12 /* #define PKIX_FORWARDBUILDERSTATEDEBUG 1 */ 13 14 #include "pkix_build.h" 15 16 extern PRLogModuleInfo *pkixLog; 17 18 /* 19 * List of critical extension OIDs associate with what build chain has 20 * checked. Those OIDs need to be removed from the unresolved critical 21 * extension OIDs list manually (instead of by checker automatically). 22 */ 23 static SECOidTag buildCheckedCritExtOIDs[] = { 24 PKIX_CERTKEYUSAGE_OID, 25 PKIX_CERTSUBJALTNAME_OID, 26 PKIX_BASICCONSTRAINTS_OID, 27 PKIX_NAMECONSTRAINTS_OID, 28 PKIX_EXTENDEDKEYUSAGE_OID, 29 PKIX_NSCERTTYPE_OID, 30 PKIX_UNKNOWN_OID 31 }; 32 33 /* --Private-ForwardBuilderState-Functions---------------------------------- */ 34 35 /* 36 * FUNCTION: pkix_ForwardBuilderState_Destroy 37 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 38 */ 39 static PKIX_Error * 40 pkix_ForwardBuilderState_Destroy( 41 PKIX_PL_Object *object, 42 void *plContext) 43 { 44 PKIX_ForwardBuilderState *state = NULL; 45 46 PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Destroy"); 47 PKIX_NULLCHECK_ONE(object); 48 49 PKIX_CHECK(pkix_CheckType 50 (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext), 51 PKIX_OBJECTNOTFORWARDBUILDERSTATE); 52 53 state = (PKIX_ForwardBuilderState *)object; 54 55 state->status = BUILD_INITIAL; 56 state->traversedCACerts = 0; 57 state->certStoreIndex = 0; 58 state->numCerts = 0; 59 state->numAias = 0; 60 state->certIndex = 0; 61 state->aiaIndex = 0; 62 state->certCheckedIndex = 0; 63 state->checkerIndex = 0; 64 state->hintCertIndex = 0; 65 state->numFanout = 0; 66 state->numDepth = 0; 67 state->reasonCode = 0; 68 state->canBeCached = PKIX_FALSE; 69 state->useOnlyLocal = PKIX_FALSE; 70 state->revChecking = PKIX_FALSE; 71 state->usingHintCerts = PKIX_FALSE; 72 state->certLoopingDetected = PKIX_FALSE; 73 PKIX_DECREF(state->validityDate); 74 PKIX_DECREF(state->prevCert); 75 PKIX_DECREF(state->candidateCert); 76 PKIX_DECREF(state->traversedSubjNames); 77 PKIX_DECREF(state->trustChain); 78 PKIX_DECREF(state->aia); 79 PKIX_DECREF(state->candidateCerts); 80 PKIX_DECREF(state->reversedCertChain); 81 PKIX_DECREF(state->checkedCritExtOIDs); 82 PKIX_DECREF(state->checkerChain); 83 PKIX_DECREF(state->certSel); 84 PKIX_DECREF(state->verifyNode); 85 PKIX_DECREF(state->client); 86 87 /* 88 * If we ever add a child link we have to be careful not to have loops 89 * in the Destroy process. But with one-way links we should be okay. 90 */ 91 if (state->parentState == NULL) { 92 state->buildConstants.numAnchors = 0; 93 state->buildConstants.numCertStores = 0; 94 state->buildConstants.numHintCerts = 0; 95 state->buildConstants.procParams = 0; 96 PKIX_DECREF(state->buildConstants.testDate); 97 PKIX_DECREF(state->buildConstants.timeLimit); 98 PKIX_DECREF(state->buildConstants.targetCert); 99 PKIX_DECREF(state->buildConstants.targetPubKey); 100 PKIX_DECREF(state->buildConstants.certStores); 101 PKIX_DECREF(state->buildConstants.anchors); 102 PKIX_DECREF(state->buildConstants.userCheckers); 103 PKIX_DECREF(state->buildConstants.hintCerts); 104 PKIX_DECREF(state->buildConstants.revChecker); 105 PKIX_DECREF(state->buildConstants.aiaMgr); 106 } else { 107 PKIX_DECREF(state->parentState); 108 } 109 110 cleanup: 111 112 PKIX_RETURN(FORWARDBUILDERSTATE); 113 } 114 115 /* 116 * FUNCTION: pkix_ForwardBuilderState_Create 117 * 118 * DESCRIPTION: 119 * Allocate and initialize a ForwardBuilderState. 120 * 121 * PARAMETERS 122 * "traversedCACerts" 123 * Number of CA certificates traversed. 124 * "numFanout" 125 * Number of Certs that can be considered at this level (0 = no limit) 126 * "numDepth" 127 * Number of additional levels that can be searched (0 = no limit) 128 * "canBeCached" 129 * Boolean value indicating whether all certs on the chain can be cached. 130 * "validityDate" 131 * Address of Date at which build chain Certs' most restricted validity 132 * time is kept. May be NULL. 133 * "prevCert" 134 * Address of Cert just traversed. Must be non-NULL. 135 * "traversedSubjNames" 136 * Address of List of GeneralNames that have been traversed. 137 * Must be non-NULL. 138 * "trustChain" 139 * Address of List of certificates traversed. Must be non-NULL. 140 * "parentState" 141 * Address of previous ForwardBuilderState 142 * "pState" 143 * Address where ForwardBuilderState will be stored. Must be non-NULL. 144 * "plContext" 145 * Platform-specific context pointer. 146 * THREAD SAFETY: 147 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 148 * RETURNS: 149 * Returns NULL if the function succeeds. 150 * Returns a Build Error if the function fails in a non-fatal way. 151 * Returns a Fatal Error if the function fails in an unrecoverable way. 152 */ 153 static PKIX_Error * 154 pkix_ForwardBuilderState_Create( 155 PKIX_Int32 traversedCACerts, 156 PKIX_UInt32 numFanout, 157 PKIX_UInt32 numDepth, 158 PKIX_Boolean canBeCached, 159 PKIX_PL_Date *validityDate, 160 PKIX_PL_Cert *prevCert, 161 PKIX_List *traversedSubjNames, 162 PKIX_List *trustChain, 163 PKIX_ForwardBuilderState *parentState, 164 PKIX_ForwardBuilderState **pState, 165 void *plContext) 166 { 167 PKIX_ForwardBuilderState *state = NULL; 168 169 PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Create"); 170 PKIX_NULLCHECK_FOUR(prevCert, traversedSubjNames, pState, trustChain); 171 172 PKIX_CHECK(PKIX_PL_Object_Alloc 173 (PKIX_FORWARDBUILDERSTATE_TYPE, 174 sizeof (PKIX_ForwardBuilderState), 175 (PKIX_PL_Object **)&state, 176 plContext), 177 PKIX_COULDNOTCREATEFORWARDBUILDERSTATEOBJECT); 178 179 state->status = BUILD_INITIAL; 180 state->traversedCACerts = traversedCACerts; 181 state->certStoreIndex = 0; 182 state->numCerts = 0; 183 state->numAias = 0; 184 state->certIndex = 0; 185 state->aiaIndex = 0; 186 state->certCheckedIndex = 0; 187 state->checkerIndex = 0; 188 state->hintCertIndex = 0; 189 state->numFanout = numFanout; 190 state->numDepth = numDepth; 191 state->reasonCode = 0; 192 state->revChecking = numDepth; 193 state->canBeCached = canBeCached; 194 state->useOnlyLocal = PKIX_TRUE; 195 state->revChecking = PKIX_FALSE; 196 state->usingHintCerts = PKIX_FALSE; 197 state->certLoopingDetected = PKIX_FALSE; 198 199 PKIX_INCREF(validityDate); 200 state->validityDate = validityDate; 201 202 PKIX_INCREF(prevCert); 203 state->prevCert = prevCert; 204 205 state->candidateCert = NULL; 206 207 PKIX_INCREF(traversedSubjNames); 208 state->traversedSubjNames = traversedSubjNames; 209 210 PKIX_INCREF(trustChain); 211 state->trustChain = trustChain; 212 213 state->aia = NULL; 214 state->candidateCerts = NULL; 215 state->reversedCertChain = NULL; 216 state->checkedCritExtOIDs = NULL; 217 state->checkerChain = NULL; 218 state->certSel = NULL; 219 state->verifyNode = NULL; 220 state->client = NULL; 221 222 PKIX_INCREF(parentState); 223 state->parentState = parentState; 224 225 if (parentState != NULL) { 226 state->buildConstants.numAnchors = 227 parentState->buildConstants.numAnchors; 228 state->buildConstants.numCertStores = 229 parentState->buildConstants.numCertStores; 230 state->buildConstants.numHintCerts = 231 parentState->buildConstants.numHintCerts; 232 state->buildConstants.maxFanout = 233 parentState->buildConstants.maxFanout; 234 state->buildConstants.maxDepth = 235 parentState->buildConstants.maxDepth; 236 state->buildConstants.maxTime = 237 parentState->buildConstants.maxTime; 238 state->buildConstants.procParams = 239 parentState->buildConstants.procParams; 240 state->buildConstants.testDate = 241 parentState->buildConstants.testDate; 242 state->buildConstants.timeLimit = 243 parentState->buildConstants.timeLimit; 244 state->buildConstants.targetCert = 245 parentState->buildConstants.targetCert; 246 state->buildConstants.targetPubKey = 247 parentState->buildConstants.targetPubKey; 248 state->buildConstants.certStores = 249 parentState->buildConstants.certStores; 250 state->buildConstants.anchors = 251 parentState->buildConstants.anchors; 252 state->buildConstants.userCheckers = 253 parentState->buildConstants.userCheckers; 254 state->buildConstants.hintCerts = 255 parentState->buildConstants.hintCerts; 256 state->buildConstants.revChecker = 257 parentState->buildConstants.revChecker; 258 state->buildConstants.aiaMgr = 259 parentState->buildConstants.aiaMgr; 260 state->buildConstants.trustOnlyUserAnchors = 261 parentState->buildConstants.trustOnlyUserAnchors; 262 } 263 264 *pState = state; 265 state = NULL; 266 cleanup: 267 268 PKIX_DECREF(state); 269 270 PKIX_RETURN(FORWARDBUILDERSTATE); 271 } 272 273 /* 274 * FUNCTION: pkix_Build_GetResourceLimits 275 * 276 * DESCRIPTION: 277 * Retrieve Resource Limits from ProcessingParams and initialize them in 278 * BuildConstants. 279 * 280 * PARAMETERS 281 * "buildConstants" 282 * Address of a BuildConstants structure containing objects and values 283 * that remain constant throughout the building of a chain. Must be 284 * non-NULL. 285 * "plContext" 286 * Platform-specific context pointer. 287 * THREAD SAFETY: 288 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 289 * RETURNS: 290 * Returns NULL if the function succeeds. 291 * Returns a Build Error if the function fails in a non-fatal way. 292 * Returns a Fatal Error if the function fails in an unrecoverable way. 293 */ 294 static PKIX_Error * 295 pkix_Build_GetResourceLimits( 296 BuildConstants *buildConstants, 297 void *plContext) 298 { 299 PKIX_ResourceLimits *resourceLimits = NULL; 300 301 PKIX_ENTER(BUILD, "pkix_Build_GetResourceLimits"); 302 PKIX_NULLCHECK_ONE(buildConstants); 303 304 PKIX_CHECK(PKIX_ProcessingParams_GetResourceLimits 305 (buildConstants->procParams, &resourceLimits, plContext), 306 PKIX_PROCESSINGPARAMSGETRESOURCELIMITSFAILED); 307 308 buildConstants->maxFanout = 0; 309 buildConstants->maxDepth = 0; 310 buildConstants->maxTime = 0; 311 312 if (resourceLimits) { 313 314 PKIX_CHECK(PKIX_ResourceLimits_GetMaxFanout 315 (resourceLimits, &buildConstants->maxFanout, plContext), 316 PKIX_RESOURCELIMITSGETMAXFANOUTFAILED); 317 318 PKIX_CHECK(PKIX_ResourceLimits_GetMaxDepth 319 (resourceLimits, &buildConstants->maxDepth, plContext), 320 PKIX_RESOURCELIMITSGETMAXDEPTHFAILED); 321 322 PKIX_CHECK(PKIX_ResourceLimits_GetMaxTime 323 (resourceLimits, &buildConstants->maxTime, plContext), 324 PKIX_RESOURCELIMITSGETMAXTIMEFAILED); 325 } 326 327 cleanup: 328 329 PKIX_DECREF(resourceLimits); 330 331 PKIX_RETURN(BUILD); 332 } 333 334 /* 335 * FUNCTION: pkix_ForwardBuilderState_ToString 336 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 337 */ 338 static PKIX_Error * 339 pkix_ForwardBuilderState_ToString 340 (PKIX_PL_Object *object, 341 PKIX_PL_String **pString, 342 void *plContext) 343 { 344 PKIX_ForwardBuilderState *state = NULL; 345 PKIX_PL_String *formatString = NULL; 346 PKIX_PL_String *resultString = NULL; 347 PKIX_PL_String *buildStatusString = NULL; 348 PKIX_PL_String *validityDateString = NULL; 349 PKIX_PL_String *prevCertString = NULL; 350 PKIX_PL_String *candidateCertString = NULL; 351 PKIX_PL_String *traversedSubjNamesString = NULL; 352 PKIX_PL_String *trustChainString = NULL; 353 PKIX_PL_String *candidateCertsString = NULL; 354 PKIX_PL_String *certSelString = NULL; 355 PKIX_PL_String *verifyNodeString = NULL; 356 PKIX_PL_String *parentStateString = NULL; 357 char *asciiFormat = "\n" 358 "\t{buildStatus: \t%s\n" 359 "\ttraversedCACerts: \t%d\n" 360 "\tcertStoreIndex: \t%d\n" 361 "\tnumCerts: \t%d\n" 362 "\tnumAias: \t%d\n" 363 "\tcertIndex: \t%d\n" 364 "\taiaIndex: \t%d\n" 365 "\tnumFanout: \t%d\n" 366 "\tnumDepth: \t%d\n" 367 "\treasonCode: \t%d\n" 368 "\tcanBeCached: \t%d\n" 369 "\tuseOnlyLocal: \t%d\n" 370 "\trevChecking: \t%d\n" 371 "\tvalidityDate: \t%s\n" 372 "\tprevCert: \t%s\n" 373 "\tcandidateCert: \t%s\n" 374 "\ttraversedSubjNames: \t%s\n" 375 "\ttrustChain: \t%s\n" 376 "\tcandidateCerts: \t%s\n" 377 "\tcertSel: \t%s\n" 378 "\tverifyNode: \t%s\n" 379 "\tparentState: \t%s}\n"; 380 char *asciiStatus = NULL; 381 382 PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_ToString"); 383 PKIX_NULLCHECK_TWO(object, pString); 384 385 PKIX_CHECK(pkix_CheckType 386 (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext), 387 PKIX_OBJECTNOTFORWARDBUILDERSTATE); 388 389 state = (PKIX_ForwardBuilderState *)object; 390 391 PKIX_CHECK(PKIX_PL_String_Create 392 (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), 393 PKIX_STRINGCREATEFAILED); 394 395 switch (state->status) { 396 case BUILD_SHORTCUTPENDING: asciiStatus = "BUILD_SHORTCUTPENDING"; 397 break; 398 case BUILD_INITIAL: asciiStatus = "BUILD_INITIAL"; 399 break; 400 case BUILD_TRYAIA: asciiStatus = "BUILD_TRYAIA"; 401 break; 402 case BUILD_AIAPENDING: asciiStatus = "BUILD_AIAPENDING"; 403 break; 404 case BUILD_COLLECTINGCERTS: asciiStatus = "BUILD_COLLECTINGCERTS"; 405 break; 406 case BUILD_GATHERPENDING: asciiStatus = "BUILD_GATHERPENDING"; 407 break; 408 case BUILD_CERTVALIDATING: asciiStatus = "BUILD_CERTVALIDATING"; 409 break; 410 case BUILD_ABANDONNODE: asciiStatus = "BUILD_ABANDONNODE"; 411 break; 412 case BUILD_DATEPREP: asciiStatus = "BUILD_DATEPREP"; 413 break; 414 case BUILD_CHECKTRUSTED: asciiStatus = "BUILD_CHECKTRUSTED"; 415 break; 416 case BUILD_CHECKTRUSTED2: asciiStatus = "BUILD_CHECKTRUSTED2"; 417 break; 418 case BUILD_ADDTOCHAIN: asciiStatus = "BUILD_ADDTOCHAIN"; 419 break; 420 case BUILD_VALCHAIN: asciiStatus = "BUILD_VALCHAIN"; 421 break; 422 case BUILD_VALCHAIN2: asciiStatus = "BUILD_VALCHAIN2"; 423 break; 424 case BUILD_EXTENDCHAIN: asciiStatus = "BUILD_EXTENDCHAIN"; 425 break; 426 case BUILD_GETNEXTCERT: asciiStatus = "BUILD_GETNEXTCERT"; 427 break; 428 default: asciiStatus = "INVALID STATUS"; 429 break; 430 } 431 432 PKIX_CHECK(PKIX_PL_String_Create 433 (PKIX_ESCASCII, asciiStatus, 0, &buildStatusString, plContext), 434 PKIX_STRINGCREATEFAILED); 435 436 PKIX_TOSTRING 437 (state->validityDate, &validityDateString, plContext, 438 PKIX_OBJECTTOSTRINGFAILED); 439 440 PKIX_TOSTRING 441 (state->prevCert, &prevCertString, plContext, 442 PKIX_OBJECTTOSTRINGFAILED); 443 444 PKIX_TOSTRING 445 (state->candidateCert, &candidateCertString, plContext, 446 PKIX_OBJECTTOSTRINGFAILED); 447 448 PKIX_TOSTRING 449 (state->traversedSubjNames, 450 &traversedSubjNamesString, 451 plContext, 452 PKIX_OBJECTTOSTRINGFAILED); 453 454 PKIX_TOSTRING 455 (state->trustChain, &trustChainString, plContext, 456 PKIX_OBJECTTOSTRINGFAILED); 457 458 PKIX_TOSTRING 459 (state->candidateCerts, &candidateCertsString, plContext, 460 PKIX_OBJECTTOSTRINGFAILED); 461 462 PKIX_TOSTRING 463 (state->certSel, &certSelString, plContext, 464 PKIX_OBJECTTOSTRINGFAILED); 465 466 PKIX_TOSTRING 467 (state->verifyNode, &verifyNodeString, plContext, 468 PKIX_OBJECTTOSTRINGFAILED); 469 470 PKIX_TOSTRING 471 (state->parentState, &parentStateString, plContext, 472 PKIX_OBJECTTOSTRINGFAILED); 473 474 PKIX_CHECK(PKIX_PL_Sprintf 475 (&resultString, 476 plContext, 477 formatString, 478 buildStatusString, 479 (PKIX_Int32)state->traversedCACerts, 480 (PKIX_UInt32)state->certStoreIndex, 481 (PKIX_UInt32)state->numCerts, 482 (PKIX_UInt32)state->numAias, 483 (PKIX_UInt32)state->certIndex, 484 (PKIX_UInt32)state->aiaIndex, 485 (PKIX_UInt32)state->numFanout, 486 (PKIX_UInt32)state->numDepth, 487 (PKIX_UInt32)state->reasonCode, 488 state->canBeCached, 489 state->useOnlyLocal, 490 state->revChecking, 491 validityDateString, 492 prevCertString, 493 candidateCertString, 494 traversedSubjNamesString, 495 trustChainString, 496 candidateCertsString, 497 certSelString, 498 verifyNodeString, 499 parentStateString), 500 PKIX_SPRINTFFAILED); 501 502 *pString = resultString; 503 504 cleanup: 505 PKIX_DECREF(formatString); 506 PKIX_DECREF(buildStatusString); 507 PKIX_DECREF(validityDateString); 508 PKIX_DECREF(prevCertString); 509 PKIX_DECREF(candidateCertString); 510 PKIX_DECREF(traversedSubjNamesString); 511 PKIX_DECREF(trustChainString); 512 PKIX_DECREF(candidateCertsString); 513 PKIX_DECREF(certSelString); 514 PKIX_DECREF(verifyNodeString); 515 PKIX_DECREF(parentStateString); 516 517 PKIX_RETURN(FORWARDBUILDERSTATE); 518 519 } 520 521 /* 522 * FUNCTION: pkix_ForwardBuilderState_RegisterSelf 523 * 524 * DESCRIPTION: 525 * Registers PKIX_FORWARDBUILDERSTATE_TYPE and its related functions 526 * with systemClasses[] 527 * 528 * THREAD SAFETY: 529 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 530 * 531 * Since this function is only called by PKIX_PL_Initialize, which should 532 * only be called once, it is acceptable that this function is not 533 * thread-safe. 534 */ 535 PKIX_Error * 536 pkix_ForwardBuilderState_RegisterSelf(void *plContext) 537 { 538 539 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 540 pkix_ClassTable_Entry entry; 541 542 PKIX_ENTER(FORWARDBUILDERSTATE, 543 "pkix_ForwardBuilderState_RegisterSelf"); 544 545 entry.description = "ForwardBuilderState"; 546 entry.objCounter = 0; 547 entry.typeObjectSize = sizeof(PKIX_ForwardBuilderState); 548 entry.destructor = pkix_ForwardBuilderState_Destroy; 549 entry.equalsFunction = NULL; 550 entry.hashcodeFunction = NULL; 551 entry.toStringFunction = pkix_ForwardBuilderState_ToString; 552 entry.comparator = NULL; 553 entry.duplicateFunction = NULL; 554 555 systemClasses[PKIX_FORWARDBUILDERSTATE_TYPE] = entry; 556 557 PKIX_RETURN(FORWARDBUILDERSTATE); 558 } 559 560 #if PKIX_FORWARDBUILDERSTATEDEBUG 561 /* 562 * FUNCTION: pkix_ForwardBuilderState_DumpState 563 * 564 * DESCRIPTION: 565 * This function invokes the ToString function on the argument pointed to 566 * by "state". 567 * PARAMETERS: 568 * "state" 569 * The address of the ForwardBuilderState object. Must be non-NULL. 570 * 571 * THREAD SAFETY: 572 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 573 */ 574 PKIX_Error * 575 pkix_ForwardBuilderState_DumpState( 576 PKIX_ForwardBuilderState *state, 577 void *plContext) 578 { 579 PKIX_PL_String *stateString = NULL; 580 char *stateAscii = NULL; 581 PKIX_UInt32 length; 582 583 PKIX_ENTER(FORWARDBUILDERSTATE,"pkix_ForwardBuilderState_DumpState"); 584 PKIX_NULLCHECK_ONE(state); 585 586 PKIX_CHECK(PKIX_PL_Object_InvalidateCache 587 ((PKIX_PL_Object *)state, plContext), 588 PKIX_OBJECTINVALIDATECACHEFAILED); 589 590 PKIX_CHECK(PKIX_PL_Object_ToString 591 ((PKIX_PL_Object*)state, &stateString, plContext), 592 PKIX_OBJECTTOSTRINGFAILED); 593 594 PKIX_CHECK(PKIX_PL_String_GetEncoded 595 (stateString, 596 PKIX_ESCASCII, 597 (void **)&stateAscii, 598 &length, 599 plContext), 600 PKIX_STRINGGETENCODEDFAILED); 601 602 PKIX_DEBUG_ARG("In Phase 1: state = %s\n", stateAscii); 603 604 PKIX_FREE(stateAscii); 605 PKIX_DECREF(stateString); 606 607 cleanup: 608 PKIX_RETURN(FORWARDBUILDERSTATE); 609 } 610 #endif 611 612 /* 613 * FUNCTION: pkix_ForwardBuilderState_IsIOPending 614 * DESCRIPTION: 615 * 616 * This function determines whether the state of the ForwardBuilderState 617 * pointed to by "state" indicates I/O is in progress, and stores the Boolean 618 * result at "pPending". 619 * 620 * PARAMETERS: 621 * "state" 622 * The address of the ForwardBuilderState object. Must be non-NULL. 623 * "pPending" 624 * The address at which the result is stored. Must be non-NULL. 625 * "plContext" 626 * Platform-specific context pointer. 627 * THREAD SAFETY: 628 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 629 * RETURNS: 630 * Returns NULL if the function succeeds. 631 * Returns a ForwardBuilderState Error if the function fails in a 632 * non-fatal way. 633 * Returns a Fatal Error if the function fails in an unrecoverable way. 634 */ 635 static PKIX_Error* 636 pkix_ForwardBuilderState_IsIOPending( 637 PKIX_ForwardBuilderState *state, 638 PKIX_Boolean *pPending, 639 void *plContext) 640 { 641 PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_IsIOPending"); 642 PKIX_NULLCHECK_TWO(state, pPending); 643 644 if ((state->status == BUILD_GATHERPENDING) || 645 (state->status == BUILD_CHECKTRUSTED2) || 646 (state->status == BUILD_VALCHAIN2) || 647 (state->status == BUILD_AIAPENDING)) { 648 *pPending = PKIX_TRUE; 649 } else { 650 *pPending = PKIX_FALSE; 651 } 652 653 PKIX_RETURN(FORWARDBUILDERSTATE); 654 } 655 656 /* --Private-BuildChain-Functions------------------------------------------- */ 657 658 /* 659 * FUNCTION: pkix_Build_SortCertComparator 660 * DESCRIPTION: 661 * 662 * This Function takes two Certificates cast in "obj1" and "obj2", 663 * compares them to determine which is a more preferable certificate 664 * for chain building. This Function is suitable for use as a 665 * comparator callback for pkix_List_BubbleSort, setting "*pResult" to 666 * > 0 if "obj1" is less desirable than "obj2" and < 0 if "obj1" 667 * is more desirable than "obj2". 668 * 669 * PARAMETERS: 670 * "obj1" 671 * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert. 672 * Must be non-NULL. 673 * "obj2" 674 * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert. 675 * Must be non-NULL. 676 * "pResult" 677 * Address where the comparison result is returned. Must be non-NULL. 678 * "plContext" 679 * Platform-specific context pointer. 680 * THREAD SAFETY: 681 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 682 * RETURNS: 683 * Returns NULL if the function succeeds. 684 * Returns a Build Error if the function fails in a non-fatal way 685 * Returns a Fatal Error if the function fails in an unrecoverable way. 686 */ 687 static PKIX_Error * 688 pkix_Build_SortCertComparator( 689 PKIX_PL_Object *obj1, 690 PKIX_PL_Object *obj2, 691 PKIX_Int32 *pResult, 692 void *plContext) 693 { 694 PKIX_PL_Date *date1 = NULL; 695 PKIX_PL_Date *date2 = NULL; 696 PKIX_Int32 result = 0; 697 698 PKIX_ENTER(BUILD, "pkix_Build_SortCertComparator"); 699 PKIX_NULLCHECK_THREE(obj1, obj2, pResult); 700 701 /* 702 * For sorting candidate certificates, we use NotAfter date as the 703 * comparison key for now (can be expanded if desired in the future). 704 * 705 * In PKIX_BuildChain, the List of CertStores was reordered so that 706 * trusted CertStores are ahead of untrusted CertStores. That sort, or 707 * this one, could be taken out if it is determined that it doesn't help 708 * performance, or in some way hinders the solution of choosing desired 709 * candidates. 710 */ 711 712 PKIX_CHECK(pkix_CheckType(obj1, PKIX_CERT_TYPE, plContext), 713 PKIX_OBJECTNOTCERT); 714 PKIX_CHECK(pkix_CheckType(obj2, PKIX_CERT_TYPE, plContext), 715 PKIX_OBJECTNOTCERT); 716 717 PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter 718 ((PKIX_PL_Cert *)obj1, &date1, plContext), 719 PKIX_CERTGETVALIDITYNOTAFTERFAILED); 720 721 PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter 722 ((PKIX_PL_Cert *)obj2, &date2, plContext), 723 PKIX_CERTGETVALIDITYNOTAFTERFAILED); 724 725 PKIX_CHECK(PKIX_PL_Object_Compare 726 ((PKIX_PL_Object *)date1, 727 (PKIX_PL_Object *)date2, 728 &result, 729 plContext), 730 PKIX_OBJECTCOMPARATORFAILED); 731 732 /* 733 * Invert the result, so that if date1 is greater than date2, 734 * obj1 is sorted before obj2. This is because pkix_List_BubbleSort 735 * sorts in ascending order. 736 */ 737 *pResult = -result; 738 739 cleanup: 740 741 PKIX_DECREF(date1); 742 PKIX_DECREF(date2); 743 744 PKIX_RETURN(BUILD); 745 } 746 747 /* This local error check macro */ 748 #define ERROR_CHECK(errCode) \ 749 if (pkixErrorResult) { \ 750 if (pkixLog) { \ 751 PR_LOG(pkixLog, PR_LOG_DEBUG, ("====> ERROR_CHECK code %s\n", #errCode)); \ 752 } \ 753 pkixTempErrorReceived = PKIX_TRUE; \ 754 pkixErrorClass = pkixErrorResult->errClass; \ 755 if (pkixErrorClass == PKIX_FATAL_ERROR) { \ 756 goto cleanup; \ 757 } \ 758 if (verifyNode) { \ 759 PKIX_DECREF(verifyNode->error); \ 760 PKIX_INCREF(pkixErrorResult); \ 761 verifyNode->error = pkixErrorResult; \ 762 } \ 763 pkixErrorCode = errCode; \ 764 goto cleanup; \ 765 } 766 767 /* 768 * FUNCTION: pkix_Build_VerifyCertificate 769 * DESCRIPTION: 770 * 771 * Checks whether the previous Cert stored in the ForwardBuilderState pointed 772 * to by "state" successfully chains, including signature verification, to the 773 * candidate Cert also stored in "state", using the Boolean value in "trusted" 774 * to determine whether "candidateCert" is trusted. 775 * 776 * First it checks whether "candidateCert" has already been traversed by 777 * determining whether it is contained in the List of traversed Certs. It then 778 * checks the candidate Cert with user checkers, if any, in the List pointed to 779 * by "userCheckers". Finally, it runs the signature validation. 780 * 781 * If this Certificate fails verification, and state->verifyNode is non-NULL, 782 * this function sets the Error code into the verifyNode. 783 * 784 * PARAMETERS: 785 * "state" 786 * Address of ForwardBuilderState to be used. Must be non-NULL. 787 * "userCheckers" 788 * Address of a List of CertChainCheckers to be used, if present, to 789 * validate the candidateCert. 790 * "trusted" 791 * Boolean value of trust for the candidate Cert 792 * "plContext" 793 * Platform-specific context pointer. 794 * THREAD SAFETY: 795 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 796 * RETURNS: 797 * Returns NULL if the function succeeds. 798 * Returns a Build Error if the function fails in a non-fatal way 799 * Returns a Fatal Error if the function fails in an unrecoverable way. 800 */ 801 static PKIX_Error * 802 pkix_Build_VerifyCertificate( 803 PKIX_ForwardBuilderState *state, 804 PKIX_List *userCheckers, 805 PKIX_Boolean *pTrusted, 806 PKIX_VerifyNode *verifyNode, 807 void *plContext) 808 { 809 PKIX_UInt32 numUserCheckers = 0; 810 PKIX_UInt32 i = 0; 811 PKIX_Boolean loopFound = PKIX_FALSE; 812 PKIX_Boolean supportForwardChecking = PKIX_FALSE; 813 PKIX_Boolean trusted = PKIX_FALSE; 814 PKIX_PL_Cert *candidateCert = NULL; 815 PKIX_PL_PublicKey *candidatePubKey = NULL; 816 PKIX_CertChainChecker *userChecker = NULL; 817 PKIX_CertChainChecker_CheckCallback checkerCheck = NULL; 818 PKIX_PL_TrustAnchorMode trustAnchorMode = 819 PKIX_PL_TrustAnchorMode_Ignore; 820 void *nbioContext = NULL; 821 822 PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate"); 823 PKIX_NULLCHECK_TWO(state, pTrusted); 824 PKIX_NULLCHECK_THREE 825 (state->candidateCerts, state->prevCert, state->trustChain); 826 827 PKIX_INCREF(state->candidateCert); 828 candidateCert = state->candidateCert; 829 830 if (state->buildConstants.numAnchors) { 831 if (state->buildConstants.trustOnlyUserAnchors) { 832 trustAnchorMode = PKIX_PL_TrustAnchorMode_Exclusive; 833 } else { 834 trustAnchorMode = PKIX_PL_TrustAnchorMode_Additive; 835 } 836 } else { 837 trustAnchorMode = PKIX_PL_TrustAnchorMode_Ignore; 838 } 839 840 PKIX_CHECK( 841 PKIX_PL_Cert_IsCertTrusted(candidateCert, trustAnchorMode, 842 &trusted, plContext), 843 PKIX_CERTISCERTTRUSTEDFAILED); 844 845 *pTrusted = trusted; 846 847 /* check for loops */ 848 PKIX_CHECK(pkix_List_Contains 849 (state->trustChain, 850 (PKIX_PL_Object *)candidateCert, 851 &loopFound, 852 plContext), 853 PKIX_LISTCONTAINSFAILED); 854 855 if (loopFound) { 856 if (verifyNode != NULL) { 857 PKIX_Error *verifyError = NULL; 858 PKIX_ERROR_CREATE 859 (BUILD, 860 PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED, 861 verifyError); 862 PKIX_DECREF(verifyNode->error); 863 verifyNode->error = verifyError; 864 } 865 /* Even if error logged, still need to abort 866 * if cert is not trusted. */ 867 if (!trusted) { 868 PKIX_ERROR(PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED); 869 } 870 state->certLoopingDetected = PKIX_TRUE; 871 } 872 873 if (userCheckers != NULL) { 874 875 PKIX_CHECK(PKIX_List_GetLength 876 (userCheckers, &numUserCheckers, plContext), 877 PKIX_LISTGETLENGTHFAILED); 878 879 for (i = 0; i < numUserCheckers; i++) { 880 881 PKIX_CHECK(PKIX_List_GetItem 882 (userCheckers, 883 i, 884 (PKIX_PL_Object **) &userChecker, 885 plContext), 886 PKIX_LISTGETITEMFAILED); 887 888 PKIX_CHECK 889 (PKIX_CertChainChecker_IsForwardCheckingSupported 890 (userChecker, &supportForwardChecking, plContext), 891 PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); 892 893 if (supportForwardChecking == PKIX_TRUE) { 894 895 PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback 896 (userChecker, &checkerCheck, plContext), 897 PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED); 898 899 pkixErrorResult = 900 checkerCheck(userChecker, candidateCert, NULL, 901 &nbioContext, plContext); 902 903 ERROR_CHECK(PKIX_USERCHECKERCHECKFAILED); 904 } 905 906 PKIX_DECREF(userChecker); 907 } 908 } 909 910 /* Check that public key of the trusted dsa cert has 911 * dsa parameters */ 912 if (trusted) { 913 PKIX_Boolean paramsNeeded = PKIX_FALSE; 914 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey 915 (candidateCert, &candidatePubKey, plContext), 916 PKIX_CERTGETSUBJECTPUBLICKEYFAILED); 917 PKIX_CHECK(PKIX_PL_PublicKey_NeedsDSAParameters 918 (candidatePubKey, ¶msNeeded, plContext), 919 PKIX_PUBLICKEYNEEDSDSAPARAMETERSFAILED); 920 if (paramsNeeded) { 921 PKIX_ERROR(PKIX_MISSINGDSAPARAMETERS); 922 } 923 } 924 925 cleanup: 926 PKIX_DECREF(candidateCert); 927 PKIX_DECREF(candidatePubKey); 928 PKIX_DECREF(userChecker); 929 930 PKIX_RETURN(BUILD); 931 } 932 933 /* 934 * FUNCTION: pkix_Build_ValidationCheckers 935 * DESCRIPTION: 936 * 937 * Creates a List of Objects to be used in determining whether the List of 938 * Certs pointed to by "certChain" successfully validates using the 939 * ForwardBuilderState pointed to by "state", and the TrustAnchor pointed to by 940 * "anchor". These objects are a reversed Cert Chain, consisting of the certs 941 * in "certChain" in reversed order, suitable for presenting to the 942 * CertChainCheckers; a List of critical extension OIDS that have already been 943 * processed in forward building; a List of CertChainCheckers to be called, and 944 * a List of RevocationCheckers to be called. These results are stored in 945 * fields of "state". 946 * 947 * PARAMETERS: 948 * "state" 949 * Address of ForwardBuilderState to be used. Must be non-NULL. 950 * "certChain" 951 * Address of List of Certs to be validated. Must be non-NULL. 952 * "anchor" 953 * Address of TrustAnchor to be used. Must be non-NULL. 954 * "addEkuChecker" 955 * Boolean flags that tells to add eku checker to the list 956 * of checkers. Only needs to be done for existing chain revalidation. 957 * "plContext" 958 * Platform-specific context pointer. 959 * THREAD SAFETY: 960 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 961 * RETURNS: 962 * Returns NULL if the function succeeds. 963 * Returns a Build Error if the function fails in a non-fatal way 964 * Returns a Fatal Error if the function fails in an unrecoverable way. 965 */ 966 static PKIX_Error * 967 pkix_Build_ValidationCheckers( 968 PKIX_ForwardBuilderState *state, 969 PKIX_List *certChain, 970 PKIX_TrustAnchor *anchor, 971 PKIX_Boolean chainRevalidationStage, 972 void *plContext) 973 { 974 PKIX_List *checkers = NULL; 975 PKIX_List *initialPolicies = NULL; 976 PKIX_List *reversedCertChain = NULL; 977 PKIX_List *buildCheckedCritExtOIDsList = NULL; 978 PKIX_ProcessingParams *procParams = NULL; 979 PKIX_PL_Cert *trustedCert = NULL; 980 PKIX_PL_PublicKey *trustedPubKey = NULL; 981 PKIX_PL_CertNameConstraints *trustedNC = NULL; 982 PKIX_CertChainChecker *sigChecker = NULL; 983 PKIX_CertChainChecker *policyChecker = NULL; 984 PKIX_CertChainChecker *userChecker = NULL; 985 PKIX_CertChainChecker *nameConstraintsChecker = NULL; 986 PKIX_CertChainChecker *checker = NULL; 987 PKIX_CertSelector *certSelector = NULL; 988 PKIX_List *userCheckerExtOIDs = NULL; 989 PKIX_PL_OID *oid = NULL; 990 PKIX_Boolean supportForwardChecking = PKIX_FALSE; 991 PKIX_Boolean policyQualifiersRejected = PKIX_FALSE; 992 PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; 993 PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; 994 PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; 995 PKIX_UInt32 numChainCerts; 996 PKIX_UInt32 numCertCheckers; 997 PKIX_UInt32 i; 998 999 PKIX_ENTER(BUILD, "pkix_Build_ValidationCheckers"); 1000 PKIX_NULLCHECK_THREE(state, certChain, anchor); 1001 1002 PKIX_CHECK(PKIX_List_Create(&checkers, plContext), 1003 PKIX_LISTCREATEFAILED); 1004 1005 PKIX_CHECK(PKIX_List_ReverseList 1006 (certChain, &reversedCertChain, plContext), 1007 PKIX_LISTREVERSELISTFAILED); 1008 1009 PKIX_CHECK(PKIX_List_GetLength 1010 (reversedCertChain, &numChainCerts, plContext), 1011 PKIX_LISTGETLENGTHFAILED); 1012 1013 procParams = state->buildConstants.procParams; 1014 1015 /* Do need to add a number of checker to revalidate 1016 * a built chain. KU, EKU, CertType and Validity Date 1017 * get checked by certificate selector during chain 1018 * construction, but needed to be checked for chain from 1019 * the cache.*/ 1020 if (chainRevalidationStage) { 1021 PKIX_CHECK(pkix_ExpirationChecker_Initialize 1022 (state->buildConstants.testDate, &checker, plContext), 1023 PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); 1024 PKIX_CHECK(PKIX_List_AppendItem 1025 (checkers, (PKIX_PL_Object *)checker, plContext), 1026 PKIX_LISTAPPENDITEMFAILED); 1027 PKIX_DECREF(checker); 1028 1029 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints 1030 (procParams, &certSelector, plContext), 1031 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); 1032 1033 PKIX_CHECK(pkix_TargetCertChecker_Initialize 1034 (certSelector, numChainCerts, &checker, plContext), 1035 PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); 1036 PKIX_CHECK(PKIX_List_AppendItem 1037 (checkers, (PKIX_PL_Object *)checker, plContext), 1038 PKIX_LISTAPPENDITEMFAILED); 1039 PKIX_DECREF(checker); 1040 } 1041 1042 PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies 1043 (procParams, &initialPolicies, plContext), 1044 PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED); 1045 1046 PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected 1047 (procParams, &policyQualifiersRejected, plContext), 1048 PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED); 1049 1050 PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited 1051 (procParams, &initialPolicyMappingInhibit, plContext), 1052 PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED); 1053 1054 PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited 1055 (procParams, &initialAnyPolicyInhibit, plContext), 1056 PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED); 1057 1058 PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired 1059 (procParams, &initialExplicitPolicy, plContext), 1060 PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED); 1061 1062 PKIX_CHECK(pkix_PolicyChecker_Initialize 1063 (initialPolicies, 1064 policyQualifiersRejected, 1065 initialPolicyMappingInhibit, 1066 initialExplicitPolicy, 1067 initialAnyPolicyInhibit, 1068 numChainCerts, 1069 &policyChecker, 1070 plContext), 1071 PKIX_POLICYCHECKERINITIALIZEFAILED); 1072 1073 PKIX_CHECK(PKIX_List_AppendItem 1074 (checkers, (PKIX_PL_Object *)policyChecker, plContext), 1075 PKIX_LISTAPPENDITEMFAILED); 1076 1077 /* 1078 * Create an OID list that contains critical extensions processed 1079 * by BuildChain. These are specified in a static const array. 1080 */ 1081 PKIX_CHECK(PKIX_List_Create(&buildCheckedCritExtOIDsList, plContext), 1082 PKIX_LISTCREATEFAILED); 1083 1084 for (i = 0; buildCheckedCritExtOIDs[i] != PKIX_UNKNOWN_OID; i++) { 1085 PKIX_CHECK(PKIX_PL_OID_Create 1086 (buildCheckedCritExtOIDs[i], &oid, plContext), 1087 PKIX_OIDCREATEFAILED); 1088 1089 PKIX_CHECK(PKIX_List_AppendItem 1090 (buildCheckedCritExtOIDsList, 1091 (PKIX_PL_Object *) oid, 1092 plContext), 1093 PKIX_LISTAPPENDITEMFAILED); 1094 1095 PKIX_DECREF(oid); 1096 } 1097 1098 if (state->buildConstants.userCheckers != NULL) { 1099 1100 PKIX_CHECK(PKIX_List_GetLength 1101 (state->buildConstants.userCheckers, 1102 &numCertCheckers, 1103 plContext), 1104 PKIX_LISTGETLENGTHFAILED); 1105 1106 for (i = 0; i < numCertCheckers; i++) { 1107 1108 PKIX_CHECK(PKIX_List_GetItem 1109 (state->buildConstants.userCheckers, 1110 i, 1111 (PKIX_PL_Object **) &userChecker, 1112 plContext), 1113 PKIX_LISTGETITEMFAILED); 1114 1115 PKIX_CHECK 1116 (PKIX_CertChainChecker_IsForwardCheckingSupported 1117 (userChecker, &supportForwardChecking, plContext), 1118 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); 1119 1120 /* 1121 * If this userChecker supports forwardChecking then it 1122 * should have been checked during build chain. Skip 1123 * checking but need to add checker's extension OIDs 1124 * to buildCheckedCritExtOIDsList. 1125 */ 1126 if (supportForwardChecking == PKIX_TRUE) { 1127 1128 PKIX_CHECK 1129 (PKIX_CertChainChecker_GetSupportedExtensions 1130 (userChecker, &userCheckerExtOIDs, plContext), 1131 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); 1132 1133 if (userCheckerExtOIDs != NULL) { 1134 PKIX_CHECK(pkix_List_AppendList 1135 (buildCheckedCritExtOIDsList, 1136 userCheckerExtOIDs, 1137 plContext), 1138 PKIX_LISTAPPENDLISTFAILED); 1139 } 1140 1141 } else { 1142 PKIX_CHECK(PKIX_List_AppendItem 1143 (checkers, 1144 (PKIX_PL_Object *)userChecker, 1145 plContext), 1146 PKIX_LISTAPPENDITEMFAILED); 1147 } 1148 1149 PKIX_DECREF(userCheckerExtOIDs); 1150 PKIX_DECREF(userChecker); 1151 } 1152 } 1153 1154 /* Enabling post chain building signature check on the certs. */ 1155 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert 1156 (anchor, &trustedCert, plContext), 1157 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); 1158 1159 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey 1160 (trustedCert, &trustedPubKey, plContext), 1161 PKIX_CERTGETSUBJECTPUBLICKEYFAILED); 1162 1163 PKIX_CHECK(pkix_SignatureChecker_Initialize 1164 (trustedPubKey, 1165 numChainCerts, 1166 &sigChecker, 1167 plContext), 1168 PKIX_SIGNATURECHECKERINITIALIZEFAILED); 1169 1170 PKIX_CHECK(PKIX_List_AppendItem 1171 (checkers, 1172 (PKIX_PL_Object *)sigChecker, 1173 plContext), 1174 PKIX_LISTAPPENDITEMFAILED); 1175 1176 /* Enabling post chain building name constraints check on the certs. */ 1177 PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints 1178 (anchor, &trustedNC, plContext), 1179 PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED); 1180 1181 PKIX_CHECK(pkix_NameConstraintsChecker_Initialize 1182 (trustedNC, numChainCerts, &nameConstraintsChecker, 1183 plContext), 1184 PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED); 1185 1186 PKIX_CHECK(PKIX_List_AppendItem 1187 (checkers, 1188 (PKIX_PL_Object *)nameConstraintsChecker, 1189 plContext), 1190 PKIX_LISTAPPENDITEMFAILED); 1191 1192 1193 PKIX_DECREF(state->reversedCertChain); 1194 PKIX_INCREF(reversedCertChain); 1195 state->reversedCertChain = reversedCertChain; 1196 PKIX_DECREF(state->checkedCritExtOIDs); 1197 PKIX_INCREF(buildCheckedCritExtOIDsList); 1198 state->checkedCritExtOIDs = buildCheckedCritExtOIDsList; 1199 PKIX_DECREF(state->checkerChain); 1200 state->checkerChain = checkers; 1201 checkers = NULL; 1202 state->certCheckedIndex = 0; 1203 state->checkerIndex = 0; 1204 state->revChecking = PKIX_FALSE; 1205 1206 1207 cleanup: 1208 1209 PKIX_DECREF(oid); 1210 PKIX_DECREF(reversedCertChain); 1211 PKIX_DECREF(buildCheckedCritExtOIDsList); 1212 PKIX_DECREF(checker); 1213 PKIX_DECREF(checkers); 1214 PKIX_DECREF(initialPolicies); 1215 PKIX_DECREF(trustedCert); 1216 PKIX_DECREF(trustedPubKey); 1217 PKIX_DECREF(certSelector); 1218 PKIX_DECREF(sigChecker); 1219 PKIX_DECREF(trustedNC); 1220 PKIX_DECREF(nameConstraintsChecker); 1221 PKIX_DECREF(policyChecker); 1222 PKIX_DECREF(userChecker); 1223 PKIX_DECREF(userCheckerExtOIDs); 1224 1225 PKIX_RETURN(BUILD); 1226 } 1227 1228 /* 1229 * FUNCTION: pkix_Build_ValidateEntireChain 1230 * DESCRIPTION: 1231 * 1232 * Checks whether the current List of Certs successfully validates using the 1233 * TrustAnchor pointed to by "anchor" and other parameters contained, as was 1234 * the Cert List, in "state". 1235 * 1236 * If a checker using non-blocking I/O returns with a non-NULL non-blocking I/O 1237 * context (NBIOContext), an indication that I/O is in progress and the 1238 * checking has not been completed, this function stores that context at 1239 * "pNBIOContext". Otherwise, it stores NULL at "pNBIOContext". 1240 * 1241 * If not awaiting I/O and if successful, a ValidateResult is created 1242 * containing the Public Key of the target certificate (including DSA parameter 1243 * inheritance, if any) and the PolicyNode representing the policy tree output 1244 * by the validation algorithm. If not successful, an Error pointer is 1245 * returned. 1246 * 1247 * PARAMETERS: 1248 * "state" 1249 * Address of ForwardBuilderState to be used. Must be non-NULL. 1250 * "anchor" 1251 * Address of TrustAnchor to be used. Must be non-NULL. 1252 * "pNBIOContext" 1253 * Address at which the NBIOContext is stored indicating whether the 1254 * validation is complete. Must be non-NULL. 1255 * "pValResult" 1256 * Address at which the ValidateResult is stored. Must be non-NULL. 1257 * "plContext" 1258 * Platform-specific context pointer. 1259 * THREAD SAFETY: 1260 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1261 * RETURNS: 1262 * Returns NULL if the function succeeds. 1263 * Returns a Build Error if the function fails in a non-fatal way 1264 * Returns a Fatal Error if the function fails in an unrecoverable way. 1265 */ 1266 static PKIX_Error * 1267 pkix_Build_ValidateEntireChain( 1268 PKIX_ForwardBuilderState *state, 1269 PKIX_TrustAnchor *anchor, 1270 void **pNBIOContext, 1271 PKIX_ValidateResult **pValResult, 1272 PKIX_VerifyNode *verifyNode, 1273 void *plContext) 1274 { 1275 PKIX_UInt32 numChainCerts = 0; 1276 PKIX_PL_PublicKey *subjPubKey = NULL; 1277 PKIX_PolicyNode *policyTree = NULL; 1278 PKIX_ValidateResult *valResult = NULL; 1279 void *nbioContext = NULL; 1280 1281 PKIX_ENTER(BUILD, "pkix_Build_ValidateEntireChain"); 1282 PKIX_NULLCHECK_FOUR(state, anchor, pNBIOContext, pValResult); 1283 1284 *pNBIOContext = NULL; /* prepare for case of error exit */ 1285 1286 PKIX_CHECK(PKIX_List_GetLength 1287 (state->reversedCertChain, &numChainCerts, plContext), 1288 PKIX_LISTGETLENGTHFAILED); 1289 1290 pkixErrorResult = 1291 pkix_CheckChain(state->reversedCertChain, numChainCerts, anchor, 1292 state->checkerChain, 1293 state->buildConstants.revChecker, 1294 state->checkedCritExtOIDs, 1295 state->buildConstants.procParams, 1296 &state->certCheckedIndex, &state->checkerIndex, 1297 &state->revChecking, &state->reasonCode, 1298 &nbioContext, &subjPubKey, &policyTree, NULL, 1299 plContext); 1300 1301 if (nbioContext != NULL) { 1302 *pNBIOContext = nbioContext; 1303 goto cleanup; 1304 } 1305 1306 ERROR_CHECK(PKIX_CHECKCHAINFAILED); 1307 1308 /* XXX Remove this assertion after 2014-12-31. See bug 946984. */ 1309 PORT_Assert(state->reasonCode == 0); 1310 1311 PKIX_CHECK(pkix_ValidateResult_Create 1312 (subjPubKey, anchor, policyTree, &valResult, plContext), 1313 PKIX_VALIDATERESULTCREATEFAILED); 1314 1315 *pValResult = valResult; 1316 valResult = NULL; 1317 1318 cleanup: 1319 PKIX_DECREF(subjPubKey); 1320 PKIX_DECREF(policyTree); 1321 PKIX_DECREF(valResult); 1322 1323 PKIX_RETURN(BUILD); 1324 } 1325 1326 /* 1327 * FUNCTION: pkix_Build_SortCandidateCerts 1328 * DESCRIPTION: 1329 * 1330 * This function sorts a List of candidate Certs pointed to by "candidates" 1331 * using an algorithm that places Certs most likely to produce a successful 1332 * chain at the front of the list, storing the resulting sorted List at 1333 * "pSortedCandidates". 1334 * 1335 * At present the only sort criterion is that trusted Certs go ahead of 1336 * untrusted Certs. 1337 * 1338 * PARAMETERS: 1339 * "candidates" 1340 * Address of List of Candidate Certs to be sorted. Must be non-NULL. 1341 * "pSortedCandidates" 1342 * Address at which sorted List is stored. Must be non-NULL. 1343 * "plContext" 1344 * Platform-specific context pointer. 1345 * THREAD SAFETY: 1346 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1347 * RETURNS: 1348 * Returns NULL if the function succeeds. 1349 * Returns a Build Error if the function fails in a non-fatal way 1350 * Returns a Fatal Error if the function fails in an unrecoverable way. 1351 */ 1352 static PKIX_Error * 1353 pkix_Build_SortCandidateCerts( 1354 PKIX_List *candidates, 1355 PKIX_List **pSortedCandidates, 1356 void *plContext) 1357 { 1358 PKIX_List *sortedList = NULL; 1359 1360 PKIX_ENTER(BUILD, "pkix_Build_SortCandidateCerts"); 1361 PKIX_NULLCHECK_TWO(candidates, pSortedCandidates); 1362 1363 /* 1364 * Both bubble and quick sort algorithms are available. 1365 * For a list of fewer than around 100 items, the bubble sort is more 1366 * efficient. (This number was determined by experimenting with both 1367 * algorithms on a Java List.) 1368 * If the candidate list is very small, using the sort can drag down 1369 * the performance a little bit. 1370 */ 1371 1372 PKIX_CHECK(pkix_List_BubbleSort 1373 (candidates, 1374 pkix_Build_SortCertComparator, 1375 &sortedList, 1376 plContext), 1377 PKIX_LISTBUBBLESORTFAILED); 1378 1379 *pSortedCandidates = sortedList; 1380 1381 cleanup: 1382 1383 PKIX_RETURN(BUILD); 1384 } 1385 1386 /* 1387 * FUNCTION: pkix_Build_BuildSelectorAndParams 1388 * DESCRIPTION: 1389 * 1390 * This function creates a CertSelector, initialized with an appropriate 1391 * ComCertSelParams, using the variables provided in the ForwardBuilderState 1392 * pointed to by "state". The CertSelector created is stored in the certsel 1393 * element of "state". 1394 * 1395 * PARAMETERS: 1396 * "state" 1397 * Address of ForwardBuilderState to be used. Must be non-NULL. 1398 * "plContext" 1399 * Platform-specific context pointer. 1400 * THREAD SAFETY: 1401 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1402 * RETURNS: 1403 * Returns NULL if the function succeeds. 1404 * Returns a Build Error if the function fails in a non-fatal way 1405 * Returns a Fatal Error if the function fails in an unrecoverable way. 1406 */ 1407 static PKIX_Error * 1408 pkix_Build_BuildSelectorAndParams( 1409 PKIX_ForwardBuilderState *state, 1410 void *plContext) 1411 { 1412 PKIX_ComCertSelParams *certSelParams = NULL; 1413 PKIX_CertSelector *certSel = NULL; 1414 PKIX_PL_X500Name *currentIssuer = NULL; 1415 PKIX_PL_ByteArray *authKeyId = NULL; 1416 PKIX_PL_Date *testDate = NULL; 1417 PKIX_CertSelector *callerCertSelector = NULL; 1418 PKIX_ComCertSelParams *callerComCertSelParams = NULL; 1419 PKIX_UInt32 reqKu = 0; 1420 PKIX_List *reqEkuOids = NULL; 1421 1422 PKIX_ENTER(BUILD, "pkix_Build_BuildSelectorAndParams"); 1423 PKIX_NULLCHECK_THREE(state, state->prevCert, state->traversedSubjNames); 1424 1425 PKIX_CHECK(PKIX_PL_Cert_GetIssuer 1426 (state->prevCert, ¤tIssuer, plContext), 1427 PKIX_CERTGETISSUERFAILED); 1428 1429 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier 1430 (state->prevCert, &authKeyId, plContext), 1431 PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED); 1432 1433 PKIX_CHECK(PKIX_ComCertSelParams_Create(&certSelParams, plContext), 1434 PKIX_COMCERTSELPARAMSCREATEFAILED); 1435 1436 PKIX_CHECK(PKIX_ComCertSelParams_SetSubject 1437 (certSelParams, currentIssuer, plContext), 1438 PKIX_COMCERTSELPARAMSSETSUBJECTFAILED); 1439 1440 if (authKeyId != NULL) { 1441 PKIX_CHECK(PKIX_ComCertSelParams_SetSubjKeyIdentifier 1442 (certSelParams, authKeyId, plContext), 1443 PKIX_COMCERTSELPARAMSSETSUBJKEYIDENTIFIERFAILED); 1444 } 1445 1446 PKIX_INCREF(state->buildConstants.testDate); 1447 testDate = state->buildConstants.testDate; 1448 1449 PKIX_CHECK(PKIX_ComCertSelParams_SetCertificateValid 1450 (certSelParams, testDate, plContext), 1451 PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED); 1452 1453 PKIX_CHECK(PKIX_ComCertSelParams_SetBasicConstraints 1454 (certSelParams, state->traversedCACerts, plContext), 1455 PKIX_COMCERTSELPARAMSSETBASICCONSTRAINTSFAILED); 1456 1457 PKIX_CHECK(PKIX_ComCertSelParams_SetPathToNames 1458 (certSelParams, state->traversedSubjNames, plContext), 1459 PKIX_COMCERTSELPARAMSSETPATHTONAMESFAILED); 1460 1461 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints 1462 (state->buildConstants.procParams, 1463 &callerCertSelector, plContext), 1464 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); 1465 1466 if (callerCertSelector != NULL) { 1467 1468 /* Get initial EKU OIDs from ComCertSelParams, if set */ 1469 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams 1470 (callerCertSelector, &callerComCertSelParams, plContext), 1471 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); 1472 1473 if (callerComCertSelParams != NULL) { 1474 PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage 1475 (callerComCertSelParams, &reqEkuOids, plContext), 1476 PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); 1477 1478 PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage 1479 (callerComCertSelParams, &reqKu, plContext), 1480 PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); 1481 } 1482 } 1483 1484 PKIX_CHECK( 1485 PKIX_ComCertSelParams_SetKeyUsage(certSelParams, reqKu, 1486 plContext), 1487 PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED); 1488 1489 PKIX_CHECK( 1490 PKIX_ComCertSelParams_SetExtendedKeyUsage(certSelParams, 1491 reqEkuOids, 1492 plContext), 1493 PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED); 1494 1495 PKIX_CHECK(PKIX_CertSelector_Create 1496 (NULL, NULL, &state->certSel, plContext), 1497 PKIX_CERTSELECTORCREATEFAILED); 1498 1499 PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams 1500 (state->certSel, certSelParams, plContext), 1501 PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED); 1502 1503 PKIX_CHECK(PKIX_List_Create(&state->candidateCerts, plContext), 1504 PKIX_LISTCREATEFAILED); 1505 1506 state->certStoreIndex = 0; 1507 1508 cleanup: 1509 PKIX_DECREF(certSelParams); 1510 PKIX_DECREF(certSel); 1511 PKIX_DECREF(currentIssuer); 1512 PKIX_DECREF(authKeyId); 1513 PKIX_DECREF(testDate); 1514 PKIX_DECREF(reqEkuOids); 1515 PKIX_DECREF(callerComCertSelParams); 1516 PKIX_DECREF(callerCertSelector); 1517 1518 PKIX_RETURN(BUILD); 1519 } 1520 1521 /* Match trust anchor to select params in order to find next cert. */ 1522 static PKIX_Error* 1523 pkix_Build_SelectCertsFromTrustAnchors( 1524 PKIX_List *trustAnchorsList, 1525 PKIX_ComCertSelParams *certSelParams, 1526 PKIX_List **pMatchList, 1527 void *plContext) 1528 { 1529 unsigned int anchorIndex = 0; 1530 PKIX_TrustAnchor *anchor = NULL; 1531 PKIX_PL_Cert *trustedCert = NULL; 1532 PKIX_List *matchList = NULL; 1533 PKIX_CertSelector *certSel = NULL; 1534 PKIX_CertSelector_MatchCallback selectorMatchCB = NULL; 1535 1536 PKIX_ENTER(BUILD, "pkix_Build_SelectCertsFromTrustAnchors"); 1537 1538 PKIX_CHECK(PKIX_CertSelector_Create 1539 (NULL, NULL, &certSel, plContext), 1540 PKIX_CERTSELECTORCREATEFAILED); 1541 PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams 1542 (certSel, certSelParams, plContext), 1543 PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED); 1544 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback 1545 (certSel, &selectorMatchCB, plContext), 1546 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); 1547 1548 for (anchorIndex = 0;anchorIndex < trustAnchorsList->length; anchorIndex++) { 1549 PKIX_CHECK( 1550 PKIX_List_GetItem(trustAnchorsList, 1551 anchorIndex, 1552 (PKIX_PL_Object **)&anchor, 1553 plContext), 1554 PKIX_LISTGETITEMFAILED); 1555 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert 1556 (anchor, &trustedCert, plContext), 1557 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); 1558 pkixErrorResult = 1559 (*selectorMatchCB)(certSel, trustedCert, plContext); 1560 if (!pkixErrorResult) { 1561 if (!matchList) { 1562 PKIX_CHECK(PKIX_List_Create(&matchList, 1563 plContext), 1564 PKIX_LISTCREATEFAILED); 1565 } 1566 PKIX_CHECK( 1567 PKIX_List_AppendItem(matchList, 1568 (PKIX_PL_Object*)trustedCert, 1569 plContext), 1570 PKIX_LISTAPPENDITEMFAILED); 1571 } else { 1572 PKIX_DECREF(pkixErrorResult); 1573 } 1574 PKIX_DECREF(trustedCert); 1575 PKIX_DECREF(anchor); 1576 } 1577 1578 *pMatchList = matchList; 1579 matchList = NULL; 1580 1581 cleanup: 1582 PKIX_DECREF(matchList); 1583 PKIX_DECREF(trustedCert); 1584 PKIX_DECREF(anchor); 1585 PKIX_DECREF(certSel); 1586 1587 PKIX_RETURN(BUILD); 1588 } 1589 1590 1591 static PKIX_Error* 1592 pkix_Build_RemoveDupUntrustedCerts( 1593 PKIX_List *trustedCertList, 1594 PKIX_List *certsFound, 1595 void *plContext) 1596 { 1597 PKIX_UInt32 trustIndex; 1598 PKIX_PL_Cert *trustCert = NULL, *cert = NULL; 1599 1600 PKIX_ENTER(BUILD, "pkix_Build_RemoveDupUntrustedCerts"); 1601 if (trustedCertList == NULL || certsFound == NULL) { 1602 goto cleanup; 1603 } 1604 for (trustIndex = 0;trustIndex < trustedCertList->length; 1605 trustIndex++) { 1606 PKIX_UInt32 certIndex = 0; 1607 PKIX_CHECK( 1608 PKIX_List_GetItem(trustedCertList, 1609 trustIndex, 1610 (PKIX_PL_Object **)&trustCert, 1611 plContext), 1612 PKIX_LISTGETITEMFAILED); 1613 1614 while (certIndex < certsFound->length) { 1615 PKIX_Boolean result = PKIX_FALSE; 1616 PKIX_DECREF(cert); 1617 PKIX_CHECK( 1618 PKIX_List_GetItem(certsFound, certIndex, 1619 (PKIX_PL_Object **)&cert, 1620 plContext), 1621 PKIX_LISTGETITEMFAILED); 1622 PKIX_CHECK( 1623 PKIX_PL_Object_Equals((PKIX_PL_Object *)trustCert, 1624 (PKIX_PL_Object *)cert, 1625 &result, 1626 plContext), 1627 PKIX_OBJECTEQUALSFAILED); 1628 if (!result) { 1629 certIndex += 1; 1630 continue; 1631 } 1632 PKIX_CHECK( 1633 PKIX_List_DeleteItem(certsFound, certIndex, 1634 plContext), 1635 PKIX_LISTDELETEITEMFAILED); 1636 } 1637 PKIX_DECREF(trustCert); 1638 } 1639 cleanup: 1640 PKIX_DECREF(cert); 1641 PKIX_DECREF(trustCert); 1642 1643 PKIX_RETURN(BUILD); 1644 } 1645 1646 1647 /* 1648 * FUNCTION: pkix_Build_GatherCerts 1649 * DESCRIPTION: 1650 * 1651 * This function traverses the CertStores in the List of CertStores contained 1652 * in "state", using the certSelector and other parameters contained in 1653 * "state", to obtain a List of all available Certs that satisfy the criteria. 1654 * If a CertStore has a cache, "certSelParams" is used both to query the cache 1655 * and, if an actual CertStore search occurred, to update the cache. (Behavior 1656 * is undefined if "certSelParams" is different from the parameters that were 1657 * used to initialize the certSelector in "state".) 1658 * 1659 * If a CertStore using non-blocking I/O returns with an indication that I/O is 1660 * in progress and the checking has not been completed, this function stores 1661 * platform-dependent information at "pNBIOContext". Otherwise it stores NULL 1662 * at "pNBIOContext", and state is updated with the results of the search. 1663 * 1664 * PARAMETERS: 1665 * "state" 1666 * Address of ForwardBuilderState to be used. Must be non-NULL. 1667 * "certSelParams" 1668 * Address of ComCertSelParams which were used in creating the current 1669 * CertSelector, and to be used in querying and updating any caches that 1670 * may be associated with with the CertStores. 1671 * "pNBIOContext" 1672 * Address at which platform-dependent information is returned if request 1673 * is suspended for non-blocking I/O. Must be non-NULL. 1674 * "plContext" 1675 * Platform-specific context pointer. 1676 * THREAD SAFETY: 1677 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1678 * RETURNS: 1679 * Returns NULL if the function succeeds. 1680 * Returns a Build Error if the function fails in a non-fatal way 1681 * Returns a Fatal Error if the function fails in an unrecoverable way. 1682 */ 1683 /* return NULL if wouldblock, empty list if none found, else list of found */ 1684 static PKIX_Error * 1685 pkix_Build_GatherCerts( 1686 PKIX_ForwardBuilderState *state, 1687 PKIX_ComCertSelParams *certSelParams, 1688 void **pNBIOContext, 1689 void *plContext) 1690 { 1691 PKIX_Boolean certStoreIsCached = PKIX_FALSE; 1692 PKIX_Boolean certStoreIsLocal = PKIX_FALSE; 1693 PKIX_Boolean foundInCache = PKIX_FALSE; 1694 PKIX_CertStore *certStore = NULL; 1695 PKIX_CertStore_CertCallback getCerts = NULL; 1696 PKIX_List *certsFound = NULL; 1697 PKIX_List *trustedCertList = NULL; 1698 void *nbioContext = NULL; 1699 1700 PKIX_ENTER(BUILD, "pkix_Build_GatherCerts"); 1701 PKIX_NULLCHECK_THREE(state, certSelParams, pNBIOContext); 1702 1703 nbioContext = *pNBIOContext; 1704 *pNBIOContext = NULL; 1705 1706 PKIX_DECREF(state->candidateCerts); 1707 1708 while (state->certStoreIndex < state->buildConstants.numCertStores) { 1709 1710 /* Get the current CertStore */ 1711 PKIX_CHECK(PKIX_List_GetItem 1712 (state->buildConstants.certStores, 1713 state->certStoreIndex, 1714 (PKIX_PL_Object **)&certStore, 1715 plContext), 1716 PKIX_LISTGETITEMFAILED); 1717 1718 PKIX_CHECK(PKIX_CertStore_GetLocalFlag 1719 (certStore, &certStoreIsLocal, plContext), 1720 PKIX_CERTSTOREGETLOCALFLAGFAILED); 1721 1722 if (state->useOnlyLocal == certStoreIsLocal) { 1723 /* If GATHERPENDING, we've already checked the cache */ 1724 if (state->status == BUILD_GATHERPENDING) { 1725 certStoreIsCached = PKIX_FALSE; 1726 foundInCache = PKIX_FALSE; 1727 } else { 1728 PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag 1729 (certStore, &certStoreIsCached, plContext), 1730 PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); 1731 1732 if (certStoreIsCached) { 1733 /* 1734 * Look for Certs in the cache, using the SubjectName as 1735 * the key. Then the ComCertSelParams are used to filter 1736 * for qualified certs. If none are found, then the 1737 * certStores are queried. When we eventually add items 1738 * to the cache, we will only add items that passed the 1739 * ComCertSelParams filter, rather than all Certs which 1740 * matched the SubjectName. 1741 */ 1742 1743 PKIX_CHECK(pkix_CacheCert_Lookup 1744 (certStore, 1745 certSelParams, 1746 state->buildConstants.testDate, 1747 &foundInCache, 1748 &certsFound, 1749 plContext), 1750 PKIX_CACHECERTCHAINLOOKUPFAILED); 1751 1752 } 1753 } 1754 1755 /* 1756 * XXX need to verify if Cert is trusted, hence may not 1757 * be worth it to have the Cert Cached or 1758 * If it is trusted, don't cache, but once there is cached 1759 * certs, we won't get certs from database any more. 1760 * can use flag to force not getting certs from cache 1761 */ 1762 if (!foundInCache) { 1763 1764 if (nbioContext == NULL) { 1765 PKIX_CHECK(PKIX_CertStore_GetCertCallback 1766 (certStore, &getCerts, plContext), 1767 PKIX_CERTSTOREGETCERTCALLBACKFAILED); 1768 1769 PKIX_CHECK(getCerts 1770 (certStore, 1771 state->certSel, 1772 state->verifyNode, 1773 &nbioContext, 1774 &certsFound, 1775 plContext), 1776 PKIX_GETCERTSFAILED); 1777 } else { 1778 PKIX_CHECK(PKIX_CertStore_CertContinue 1779 (certStore, 1780 state->certSel, 1781 state->verifyNode, 1782 &nbioContext, 1783 &certsFound, 1784 plContext), 1785 PKIX_CERTSTORECERTCONTINUEFAILED); 1786 } 1787 1788 if (certStoreIsCached && certsFound) { 1789 1790 PKIX_CHECK(pkix_CacheCert_Add 1791 (certStore, 1792 certSelParams, 1793 certsFound, 1794 plContext), 1795 PKIX_CACHECERTADDFAILED); 1796 } 1797 } 1798 1799 /* 1800 * getCerts returns an empty list for "NONE FOUND", 1801 * a NULL list for "would block" 1802 */ 1803 if (certsFound == NULL) { 1804 state->status = BUILD_GATHERPENDING; 1805 *pNBIOContext = nbioContext; 1806 goto cleanup; 1807 } 1808 } 1809 1810 /* Are there any more certStores to query? */ 1811 PKIX_DECREF(certStore); 1812 ++(state->certStoreIndex); 1813 } 1814 1815 if (certsFound && certsFound->length > 1) { 1816 PKIX_List *sorted = NULL; 1817 1818 /* sort Certs to try to optimize search */ 1819 PKIX_CHECK(pkix_Build_SortCandidateCerts 1820 (certsFound, &sorted, plContext), 1821 PKIX_BUILDSORTCANDIDATECERTSFAILED); 1822 PKIX_DECREF(certsFound); 1823 certsFound = sorted; 1824 } 1825 1826 PKIX_CHECK( 1827 pkix_Build_SelectCertsFromTrustAnchors( 1828 state->buildConstants.anchors, 1829 certSelParams, &trustedCertList, 1830 plContext), 1831 PKIX_FAILTOSELECTCERTSFROMANCHORS); 1832 PKIX_CHECK( 1833 pkix_Build_RemoveDupUntrustedCerts(trustedCertList, 1834 certsFound, 1835 plContext), 1836 PKIX_REMOVEDUPUNTRUSTEDCERTSFAILED); 1837 1838 PKIX_CHECK( 1839 pkix_List_MergeLists(trustedCertList, 1840 certsFound, 1841 &state->candidateCerts, 1842 plContext), 1843 PKIX_LISTMERGEFAILED); 1844 1845 /* No, return the list we have gathered */ 1846 PKIX_CHECK(PKIX_List_GetLength 1847 (state->candidateCerts, &state->numCerts, plContext), 1848 PKIX_LISTGETLENGTHFAILED); 1849 1850 state->certIndex = 0; 1851 1852 cleanup: 1853 PKIX_DECREF(trustedCertList); 1854 PKIX_DECREF(certStore); 1855 PKIX_DECREF(certsFound); 1856 1857 PKIX_RETURN(BUILD); 1858 } 1859 1860 /* 1861 * FUNCTION: pkix_Build_UpdateDate 1862 * DESCRIPTION: 1863 * 1864 * This function updates the validityDate contained in "state", for the current 1865 * CertChain contained in "state", to include the validityDate of the 1866 * candidateCert contained in "state". The validityDate of a chain is the 1867 * earliest of all the notAfter dates contained in the respective Certificates. 1868 * 1869 * PARAMETERS: 1870 * "state" 1871 * Address of ForwardBuilderState to be used. Must be non-NULL. 1872 * "plContext" 1873 * Platform-specific context pointer. 1874 * THREAD SAFETY: 1875 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1876 * RETURNS: 1877 * Returns NULL if the function succeeds. 1878 * Returns a Build Error if the function fails in a non-fatal way 1879 * Returns a Fatal Error if the function fails in an unrecoverable way. 1880 */ 1881 static PKIX_Error * 1882 pkix_Build_UpdateDate( 1883 PKIX_ForwardBuilderState *state, 1884 void *plContext) 1885 { 1886 PKIX_Boolean canBeCached = PKIX_FALSE; 1887 PKIX_Int32 comparison = 0; 1888 PKIX_PL_Date *notAfter = NULL; 1889 1890 PKIX_ENTER(BUILD, "pkix_Build_UpdateDate"); 1891 PKIX_NULLCHECK_ONE(state); 1892 1893 PKIX_CHECK(PKIX_PL_Cert_GetCacheFlag 1894 (state->candidateCert, &canBeCached, plContext), 1895 PKIX_CERTGETCACHEFLAGFAILED); 1896 1897 state->canBeCached = state->canBeCached && canBeCached; 1898 if (state->canBeCached == PKIX_TRUE) { 1899 1900 /* 1901 * So far, all certs can be cached. Update cert 1902 * chain validity time, which is the earliest of 1903 * all certs' notAfter times. 1904 */ 1905 PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter 1906 (state->candidateCert, ¬After, plContext), 1907 PKIX_CERTGETVALIDITYNOTAFTERFAILED); 1908 1909 if (state->validityDate == NULL) { 1910 state->validityDate = notAfter; 1911 notAfter = NULL; 1912 } else { 1913 PKIX_CHECK(PKIX_PL_Object_Compare 1914 ((PKIX_PL_Object *)state->validityDate, 1915 (PKIX_PL_Object *)notAfter, 1916 &comparison, 1917 plContext), 1918 PKIX_OBJECTCOMPARATORFAILED); 1919 if (comparison > 0) { 1920 PKIX_DECREF(state->validityDate); 1921 state->validityDate = notAfter; 1922 notAfter = NULL; 1923 } 1924 } 1925 } 1926 1927 cleanup: 1928 1929 PKIX_DECREF(notAfter); 1930 1931 PKIX_RETURN(BUILD); 1932 } 1933 1934 /* Prepare 'state' for the AIA round. */ 1935 static void 1936 pkix_PrepareForwardBuilderStateForAIA( 1937 PKIX_ForwardBuilderState *state) 1938 { 1939 PORT_Assert(state->useOnlyLocal == PKIX_TRUE); 1940 state->useOnlyLocal = PKIX_FALSE; 1941 state->certStoreIndex = 0; 1942 state->numFanout = state->buildConstants.maxFanout; 1943 state->status = BUILD_TRYAIA; 1944 } 1945 1946 extern SECStatus 1947 isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert, 1948 CERTCertificate *referenceCert); 1949 1950 /* 1951 * FUNCTION: pkix_BuildForwardDepthFirstSearch 1952 * DESCRIPTION: 1953 * 1954 * This function performs a depth first search in the "forward" direction (from 1955 * the target Cert to the trust anchor). A non-NULL targetCert must be stored 1956 * in the ForwardBuilderState before this function is called. It is not written 1957 * recursively since execution may be suspended in in any of several places 1958 * pending completion of non-blocking I/O. This iterative structure makes it 1959 * much easier to resume where it left off. 1960 * 1961 * Since the nature of the search is recursive, the recursion is handled by 1962 * chaining states. That is, each new step involves creating a new 1963 * ForwardBuilderState linked to its predecessor. If a step turns out to be 1964 * fruitless, the state of the predecessor is restored and the next alternative 1965 * is tried. When a search is successful, values needed from the last state 1966 * (canBeCached and validityDate) are copied to the state provided by the 1967 * caller, so that the caller can retrieve those values. 1968 * 1969 * There are three return arguments, the NBIOContext, the ValidateResult and 1970 * the ForwardBuilderState. If NBIOContext is non-NULL, it means the search is 1971 * suspended until the results of a non-blocking IO become available. The 1972 * caller may wait for the completion using platform-dependent methods and then 1973 * call this function again, allowing it to resume the search. If NBIOContext 1974 * is NULL and the ValidateResult is non-NULL, it means the search has 1975 * concluded successfully. If the NBIOContext is NULL but the ValidateResult is 1976 * NULL, it means the search was unsuccessful. 1977 * 1978 * This function performs several steps at each node in the constructed chain: 1979 * 1980 * 1) It retrieves Certs from the registered CertStores that match the 1981 * criteria established by the ForwardBuilderState pointed to by "state", such 1982 * as a subject name matching the issuer name of the previous Cert. If there 1983 * are no matching Certs, the function returns to the previous, or "parent", 1984 * state and tries to continue the chain building with another of the Certs 1985 * obtained from the CertStores as possible issuers for that parent Cert. 1986 * 1987 * 2) For each candidate Cert returned by the CertStores, this function checks 1988 * whether the Cert is valid. If it is trusted, this function checks whether 1989 * this Cert might serve as a TrustAnchor for a complete chain. 1990 * 1991 * 3) It determines whether this Cert, in conjunction with any of the 1992 * TrustAnchors, might complete a chain. A complete chain, from this or the 1993 * preceding step, is checked to see whether it is valid as a complete 1994 * chain, including the checks that cannot be done in the forward direction. 1995 * 1996 * 4) If this Cert chains successfully, but is not a complete chain, that is, 1997 * we have not reached a trusted Cert, a new ForwardBuilderState is created 1998 * with this Cert as the immediate predecessor, and we continue in step (1), 1999 * attempting to get Certs from the CertStores with this Certs "issuer" as 2000 * their subject. 2001 * 2002 * 5) If an entire chain validates successfully, then we are done. A 2003 * ValidateResult is created containing the Public Key of the target 2004 * certificate (including DSA parameter inheritance, if any) and the 2005 * PolicyNode representing the policy tree output by the validation algorithm, 2006 * and stored at pValResult, and the function exits returning NULL. 2007 * 2008 * 5) If the entire chain does not validate successfully, the algorithm 2009 * discards the latest Cert and continues in step 2 with the next candidate 2010 * Cert, backing up to a parent state when no more possibilities exist at a 2011 * given level, and returning failure when we try to back up but discover we 2012 * are at the top level. 2013 * 2014 * PARAMETERS: 2015 * "pNBIOContext" 2016 * Address at which platform-dependent information is returned if building 2017 * is suspended for non-blocking I/O. Must be non-NULL. 2018 * "pState" 2019 * Address at which input ForwardBuilderState is found, and at which output 2020 * ForwardBuilderState is stored. Must be non-NULL. 2021 * "pValResult" 2022 * Address at which the ValidateResult is stored. Must be non-NULL. 2023 * "plContext" 2024 * Platform-specific context pointer. 2025 * THREAD SAFETY: 2026 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 2027 * RETURNS: 2028 * Returns NULL if the function succeeds. 2029 * Returns a Build Error if the function fails in a non-fatal way. 2030 * Returns a Fatal Error if the function fails in an unrecoverable way. 2031 */ 2032 static PKIX_Error * 2033 pkix_BuildForwardDepthFirstSearch( 2034 void **pNBIOContext, 2035 PKIX_ForwardBuilderState *state, 2036 PKIX_ValidateResult **pValResult, 2037 void *plContext) 2038 { 2039 PKIX_Boolean outOfOptions = PKIX_FALSE; 2040 PKIX_Boolean trusted = PKIX_FALSE; 2041 PKIX_Boolean isSelfIssued = PKIX_FALSE; 2042 PKIX_Boolean canBeCached = PKIX_FALSE; 2043 PKIX_Boolean ioPending = PKIX_FALSE; 2044 PKIX_PL_Date *validityDate = NULL; 2045 PKIX_PL_Date *currTime = NULL; 2046 PKIX_Int32 childTraversedCACerts = 0; 2047 PKIX_UInt32 numSubjectNames = 0; 2048 PKIX_UInt32 numChained = 0; 2049 PKIX_Int32 cmpTimeResult = 0; 2050 PKIX_UInt32 i = 0; 2051 PKIX_UInt32 certsSoFar = 0; 2052 PKIX_List *childTraversedSubjNames = NULL; 2053 PKIX_List *subjectNames = NULL; 2054 PKIX_List *unfilteredCerts = NULL; 2055 PKIX_List *filteredCerts = NULL; 2056 PKIX_PL_Object *subjectName = NULL; 2057 PKIX_ValidateResult *valResult = NULL; 2058 PKIX_ForwardBuilderState *childState = NULL; 2059 PKIX_ForwardBuilderState *parentState = NULL; 2060 PKIX_PL_Object *revCheckerState = NULL; 2061 PKIX_ComCertSelParams *certSelParams = NULL; 2062 PKIX_TrustAnchor *trustAnchor = NULL; 2063 PKIX_PL_Cert *trustedCert = NULL; 2064 PKIX_PL_Cert *targetCert = NULL; 2065 PKIX_VerifyNode *verifyNode = NULL; 2066 PKIX_Error *verifyError = NULL; 2067 PKIX_Error *finalError = NULL; 2068 void *nbio = NULL; 2069 PKIX_UInt32 numIterations = 0; 2070 2071 PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch"); 2072 PKIX_NULLCHECK_THREE(pNBIOContext, state, pValResult); 2073 2074 nbio = *pNBIOContext; 2075 *pNBIOContext = NULL; 2076 PKIX_INCREF(state->validityDate); 2077 validityDate = state->validityDate; 2078 canBeCached = state->canBeCached; 2079 PKIX_DECREF(*pValResult); 2080 targetCert = state->buildConstants.targetCert; 2081 2082 /* 2083 * We return if successful; if we fall off the end 2084 * of this "while" clause our search has failed. 2085 */ 2086 while (outOfOptions == PKIX_FALSE) { 2087 /* 2088 * The maximum number of iterations works around a bug that 2089 * causes this while loop to never exit when AIA and cross 2090 * certificates are involved. See bug xxxxx. 2091 */ 2092 if (numIterations++ > 250) 2093 PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS); 2094 2095 if (state->buildConstants.maxTime != 0) { 2096 PKIX_DECREF(currTime); 2097 PKIX_CHECK(PKIX_PL_Date_Create_UTCTime 2098 (NULL, &currTime, plContext), 2099 PKIX_DATECREATEUTCTIMEFAILED); 2100 2101 PKIX_CHECK(PKIX_PL_Object_Compare 2102 ((PKIX_PL_Object *)state->buildConstants.timeLimit, 2103 (PKIX_PL_Object *)currTime, 2104 &cmpTimeResult, 2105 plContext), 2106 PKIX_OBJECTCOMPARATORFAILED); 2107 2108 if (cmpTimeResult < 0) { 2109 if (state->verifyNode != NULL) { 2110 PKIX_ERROR_CREATE 2111 (BUILD, 2112 PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS, 2113 verifyError); 2114 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError 2115 (state->verifyNode, 2116 verifyError, 2117 plContext), 2118 PKIX_VERIFYNODESETERRORFAILED); 2119 PKIX_DECREF(finalError); 2120 finalError = verifyError; 2121 verifyError = NULL; 2122 } 2123 /* Even if we logged error, we still have to abort */ 2124 PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS); 2125 } 2126 } 2127 2128 if (state->status == BUILD_INITIAL) { 2129 2130 PKIX_CHECK(pkix_Build_BuildSelectorAndParams(state, plContext), 2131 PKIX_BUILDBUILDSELECTORANDPARAMSFAILED); 2132 2133 /* 2134 * If the caller supplied a partial certChain (hintCerts) try 2135 * the next one from that List before we go to the certStores. 2136 */ 2137 if (state->buildConstants.numHintCerts > 0) { 2138 /* How many Certs does our trust chain have already? */ 2139 PKIX_CHECK(PKIX_List_GetLength 2140 (state->trustChain, &certsSoFar, plContext), 2141 PKIX_LISTGETLENGTHFAILED); 2142 2143 /* That includes the target Cert. Don't count it. */ 2144 certsSoFar--; 2145 2146 /* Are we still within range of the partial chain? */ 2147 if (certsSoFar >= state->buildConstants.numHintCerts) { 2148 state->status = BUILD_TRYAIA; 2149 } else { 2150 /* 2151 * If we already have n certs, we want the n+1th 2152 * (i.e., index = n) from the list of hints. 2153 */ 2154 PKIX_DECREF(state->candidateCert); 2155 PKIX_CHECK(PKIX_List_GetItem 2156 (state->buildConstants.hintCerts, 2157 certsSoFar, 2158 (PKIX_PL_Object **)&state->candidateCert, 2159 plContext), 2160 PKIX_LISTGETITEMFAILED); 2161 2162 PKIX_CHECK(PKIX_List_AppendItem 2163 (state->candidateCerts, 2164 (PKIX_PL_Object *)state->candidateCert, 2165 plContext), 2166 PKIX_LISTAPPENDITEMFAILED); 2167 2168 state->numCerts = 1; 2169 state->usingHintCerts = PKIX_TRUE; 2170 state->status = BUILD_CERTVALIDATING; 2171 } 2172 } else { 2173 state->status = BUILD_TRYAIA; 2174 } 2175 2176 } 2177 2178 if (state->status == BUILD_TRYAIA) { 2179 if (state->useOnlyLocal == PKIX_TRUE) { 2180 state->status = BUILD_COLLECTINGCERTS; 2181 } else { 2182 state->status = BUILD_AIAPENDING; 2183 } 2184 } 2185 2186 if (state->status == BUILD_AIAPENDING && 2187 state->buildConstants.aiaMgr) { 2188 pkixErrorResult = PKIX_PL_AIAMgr_GetAIACerts 2189 (state->buildConstants.aiaMgr, 2190 state->prevCert, 2191 &nbio, 2192 &unfilteredCerts, 2193 plContext); 2194 2195 if (nbio != NULL) { 2196 /* IO still pending, resume later */ 2197 *pNBIOContext = nbio; 2198 goto cleanup; 2199 } 2200 state->numCerts = 0; 2201 if (pkixErrorResult) { 2202 pkixErrorClass = pkixErrorResult->errClass; 2203 if (pkixErrorClass == PKIX_FATAL_ERROR) { 2204 goto fatal; 2205 } 2206 PKIX_DECREF(finalError); 2207 finalError = pkixErrorResult; 2208 pkixErrorResult = NULL; 2209 if (state->verifyNode != NULL) { 2210 /* state->verifyNode is the object that contains a list 2211 * of verifyNodes. verifyNodes contains cert chain 2212 * build failures that occurred on this level of chain 2213 * building. Here, creating new verify node 2214 * to log the failure and adding it to the list. */ 2215 PKIX_CHECK_FATAL(pkix_VerifyNode_Create 2216 (state->prevCert, 2217 0, NULL, 2218 &verifyNode, 2219 plContext), 2220 PKIX_VERIFYNODECREATEFAILED); 2221 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError 2222 (verifyNode, finalError, plContext), 2223 PKIX_VERIFYNODESETERRORFAILED); 2224 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2225 (state->verifyNode, 2226 verifyNode, 2227 plContext), 2228 PKIX_VERIFYNODEADDTOTREEFAILED); 2229 PKIX_DECREF(verifyNode); 2230 } 2231 } 2232 #ifdef PKIX_BUILDDEBUG 2233 /* Turn this on to trace the List of Certs, before CertSelect */ 2234 { 2235 PKIX_PL_String *unString; 2236 char *unAscii; 2237 PKIX_UInt32 length; 2238 PKIX_TOSTRING 2239 ((PKIX_PL_Object*)unfilteredCerts, 2240 &unString, 2241 plContext, 2242 PKIX_OBJECTTOSTRINGFAILED); 2243 2244 PKIX_CHECK(PKIX_PL_String_GetEncoded 2245 (unString, 2246 PKIX_ESCASCII, 2247 (void **)&unAscii, 2248 &length, 2249 plContext), 2250 PKIX_STRINGGETENCODEDFAILED); 2251 2252 PKIX_DEBUG_ARG 2253 ("unfilteredCerts = %s\n", unAscii); 2254 PKIX_DECREF(unString); 2255 PKIX_FREE(unAscii); 2256 } 2257 #endif 2258 2259 /* Note: Certs winnowed here don't get into VerifyTree. */ 2260 if (unfilteredCerts) { 2261 PKIX_CHECK(pkix_CertSelector_Select 2262 (state->certSel, 2263 unfilteredCerts, 2264 &filteredCerts, 2265 plContext), 2266 PKIX_CERTSELECTORSELECTFAILED); 2267 2268 PKIX_DECREF(unfilteredCerts); 2269 2270 PKIX_CHECK(PKIX_List_GetLength 2271 (filteredCerts, &(state->numCerts), plContext), 2272 PKIX_LISTGETLENGTHFAILED); 2273 2274 #ifdef PKIX_BUILDDEBUG 2275 /* Turn this on to trace the List of Certs, after CertSelect */ 2276 { 2277 PKIX_PL_String *unString; 2278 char *unAscii; 2279 PKIX_UInt32 length; 2280 PKIX_TOSTRING 2281 ((PKIX_PL_Object*)filteredCerts, 2282 &unString, 2283 plContext, 2284 PKIX_OBJECTTOSTRINGFAILED); 2285 2286 PKIX_CHECK(PKIX_PL_String_GetEncoded 2287 (unString, 2288 PKIX_ESCASCII, 2289 (void **)&unAscii, 2290 &length, 2291 plContext), 2292 PKIX_STRINGGETENCODEDFAILED); 2293 2294 PKIX_DEBUG_ARG("filteredCerts = %s\n", unAscii); 2295 PKIX_DECREF(unString); 2296 PKIX_FREE(unAscii); 2297 } 2298 #endif 2299 2300 PKIX_DECREF(state->candidateCerts); 2301 state->candidateCerts = filteredCerts; 2302 state->certIndex = 0; 2303 filteredCerts = NULL; 2304 } 2305 2306 /* Are there any Certs to try? */ 2307 if (state->numCerts > 0) { 2308 state->status = BUILD_CERTVALIDATING; 2309 } else { 2310 state->status = BUILD_COLLECTINGCERTS; 2311 } 2312 } 2313 2314 PKIX_DECREF(certSelParams); 2315 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams 2316 (state->certSel, &certSelParams, plContext), 2317 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); 2318 2319 /* **** Querying the CertStores ***** */ 2320 if ((state->status == BUILD_COLLECTINGCERTS) || 2321 (state->status == BUILD_GATHERPENDING)) { 2322 2323 #if PKIX_FORWARDBUILDERSTATEDEBUG 2324 PKIX_CHECK(pkix_ForwardBuilderState_DumpState 2325 (state, plContext), 2326 PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED); 2327 #endif 2328 2329 PKIX_CHECK(pkix_Build_GatherCerts 2330 (state, certSelParams, &nbio, plContext), 2331 PKIX_BUILDGATHERCERTSFAILED); 2332 2333 if (nbio != NULL) { 2334 /* IO still pending, resume later */ 2335 *pNBIOContext = nbio; 2336 goto cleanup; 2337 } 2338 2339 /* Are there any Certs to try? */ 2340 if (state->numCerts > 0) { 2341 state->status = BUILD_CERTVALIDATING; 2342 } else { 2343 state->status = BUILD_ABANDONNODE; 2344 } 2345 } 2346 2347 /* ****Phase 2 - Chain building***** */ 2348 2349 #if PKIX_FORWARDBUILDERSTATEDEBUG 2350 PKIX_CHECK(pkix_ForwardBuilderState_DumpState(state, plContext), 2351 PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED); 2352 #endif 2353 2354 if (state->status == BUILD_CERTVALIDATING) { 2355 PKIX_DECREF(state->candidateCert); 2356 PKIX_CHECK(PKIX_List_GetItem 2357 (state->candidateCerts, 2358 state->certIndex, 2359 (PKIX_PL_Object **)&(state->candidateCert), 2360 plContext), 2361 PKIX_LISTGETITEMFAILED); 2362 2363 if (isIssuerCertAllowedAtCertIssuanceTime( 2364 state->candidateCert->nssCert, targetCert->nssCert) 2365 != SECSuccess) { 2366 PKIX_ERROR(PKIX_CERTISBLOCKLISTEDATISSUANCETIME); 2367 } 2368 2369 if ((state->verifyNode) != NULL) { 2370 PKIX_CHECK_FATAL(pkix_VerifyNode_Create 2371 (state->candidateCert, 2372 0, 2373 NULL, 2374 &verifyNode, 2375 plContext), 2376 PKIX_VERIFYNODECREATEFAILED); 2377 } 2378 2379 /* If failure, this function sets Error in verifyNode */ 2380 verifyError = pkix_Build_VerifyCertificate 2381 (state, 2382 state->buildConstants.userCheckers, 2383 &trusted, 2384 verifyNode, 2385 plContext); 2386 2387 if (verifyError) { 2388 pkixTempErrorReceived = PKIX_TRUE; 2389 pkixErrorClass = verifyError->errClass; 2390 if (pkixErrorClass == PKIX_FATAL_ERROR) { 2391 pkixErrorResult = verifyError; 2392 verifyError = NULL; 2393 goto fatal; 2394 } 2395 } 2396 2397 if (PKIX_ERROR_RECEIVED) { 2398 if (state->verifyNode != NULL) { 2399 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError 2400 (verifyNode, verifyError, plContext), 2401 PKIX_VERIFYNODESETERRORFAILED); 2402 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2403 (state->verifyNode, 2404 verifyNode, 2405 plContext), 2406 PKIX_VERIFYNODEADDTOTREEFAILED); 2407 PKIX_DECREF(verifyNode); 2408 } 2409 pkixTempErrorReceived = PKIX_FALSE; 2410 PKIX_DECREF(finalError); 2411 finalError = verifyError; 2412 verifyError = NULL; 2413 if (state->certLoopingDetected) { 2414 PKIX_ERROR 2415 (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED); 2416 } 2417 state->status = BUILD_GETNEXTCERT; 2418 } else { 2419 state->status = BUILD_DATEPREP; 2420 } 2421 } 2422 2423 if (state->status == BUILD_DATEPREP) { 2424 /* Keep track of whether this chain can be cached */ 2425 PKIX_CHECK(pkix_Build_UpdateDate(state, plContext), 2426 PKIX_BUILDUPDATEDATEFAILED); 2427 2428 canBeCached = state->canBeCached; 2429 PKIX_DECREF(validityDate); 2430 PKIX_INCREF(state->validityDate); 2431 validityDate = state->validityDate; 2432 if (trusted == PKIX_TRUE) { 2433 state->status = BUILD_CHECKTRUSTED; 2434 } else { 2435 state->status = BUILD_ADDTOCHAIN; 2436 } 2437 } 2438 2439 if (state->status == BUILD_CHECKTRUSTED) { 2440 2441 /* 2442 * If this cert is trusted, try to validate the entire 2443 * chain using this certificate as trust anchor. 2444 */ 2445 PKIX_CHECK(PKIX_TrustAnchor_CreateWithCert 2446 (state->candidateCert, 2447 &trustAnchor, 2448 plContext), 2449 PKIX_TRUSTANCHORCREATEWITHCERTFAILED); 2450 2451 PKIX_CHECK(pkix_Build_ValidationCheckers 2452 (state, 2453 state->trustChain, 2454 trustAnchor, 2455 PKIX_FALSE, /* do not add eku checker 2456 * since eku was already 2457 * checked */ 2458 plContext), 2459 PKIX_BUILDVALIDATIONCHECKERSFAILED); 2460 2461 state->status = BUILD_CHECKTRUSTED2; 2462 } 2463 2464 if (state->status == BUILD_CHECKTRUSTED2) { 2465 verifyError = 2466 pkix_Build_ValidateEntireChain(state, 2467 trustAnchor, 2468 &nbio, &valResult, 2469 verifyNode, 2470 plContext); 2471 if (nbio != NULL) { 2472 /* IO still pending, resume later */ 2473 goto cleanup; 2474 } else { 2475 /* checking the error for fatal status */ 2476 if (verifyError) { 2477 pkixTempErrorReceived = PKIX_TRUE; 2478 pkixErrorClass = verifyError->errClass; 2479 if (pkixErrorClass == PKIX_FATAL_ERROR) { 2480 pkixErrorResult = verifyError; 2481 verifyError = NULL; 2482 goto fatal; 2483 } 2484 } 2485 if (state->verifyNode != NULL) { 2486 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2487 (state->verifyNode, 2488 verifyNode, 2489 plContext), 2490 PKIX_VERIFYNODEADDTOTREEFAILED); 2491 PKIX_DECREF(verifyNode); 2492 } 2493 if (!PKIX_ERROR_RECEIVED) { 2494 *pValResult = valResult; 2495 valResult = NULL; 2496 /* Change state so IsIOPending is FALSE */ 2497 state->status = BUILD_CHECKTRUSTED; 2498 goto cleanup; 2499 } 2500 PKIX_DECREF(finalError); 2501 finalError = verifyError; 2502 verifyError = NULL; 2503 /* Reset temp error that was set by 2504 * PKIX_CHECK_ONLY_FATAL and continue */ 2505 pkixTempErrorReceived = PKIX_FALSE; 2506 PKIX_DECREF(trustAnchor); 2507 } 2508 2509 /* 2510 * If chain doesn't validate with a trusted Cert, 2511 * adding more Certs to it can't help. 2512 */ 2513 if (state->certLoopingDetected) { 2514 PKIX_DECREF(verifyError); 2515 PKIX_ERROR_CREATE(BUILD, 2516 PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED, 2517 verifyError); 2518 PKIX_CHECK_FATAL( 2519 pkix_VerifyNode_SetError(state->verifyNode, 2520 verifyError, 2521 plContext), 2522 PKIX_VERIFYNODESETERRORFAILED); 2523 PKIX_DECREF(verifyError); 2524 } 2525 state->status = BUILD_GETNEXTCERT; 2526 } 2527 2528 /* 2529 * This Cert was not trusted. Add it to our chain, and 2530 * continue building. If we don't reach a trust anchor, 2531 * we'll take it off later and continue without it. 2532 */ 2533 if (state->status == BUILD_ADDTOCHAIN) { 2534 PKIX_CHECK(PKIX_List_AppendItem 2535 (state->trustChain, 2536 (PKIX_PL_Object *)state->candidateCert, 2537 plContext), 2538 PKIX_LISTAPPENDITEMFAILED); 2539 2540 state->status = BUILD_EXTENDCHAIN; 2541 } 2542 2543 if (state->status == BUILD_EXTENDCHAIN) { 2544 2545 /* Check whether we are allowed to extend the chain */ 2546 if ((state->buildConstants.maxDepth != 0) && 2547 (state->numDepth <= 1)) { 2548 2549 if (state->verifyNode != NULL) { 2550 PKIX_ERROR_CREATE 2551 (BUILD, 2552 PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS, 2553 verifyError); 2554 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError 2555 (verifyNode, verifyError, plContext), 2556 PKIX_VERIFYNODESETERRORFAILED); 2557 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2558 (state->verifyNode, verifyNode, plContext), 2559 PKIX_VERIFYNODEADDTOTREEFAILED); 2560 PKIX_DECREF(verifyNode); 2561 PKIX_DECREF(finalError); 2562 finalError = verifyError; 2563 verifyError = NULL; 2564 } 2565 /* Even if error logged, still need to abort */ 2566 PKIX_ERROR(PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS); 2567 } 2568 2569 PKIX_CHECK(pkix_IsCertSelfIssued 2570 (state->candidateCert, &isSelfIssued, plContext), 2571 PKIX_ISCERTSELFISSUEDFAILED); 2572 2573 PKIX_CHECK(PKIX_PL_Object_Duplicate 2574 ((PKIX_PL_Object *)state->traversedSubjNames, 2575 (PKIX_PL_Object **)&childTraversedSubjNames, 2576 plContext), 2577 PKIX_OBJECTDUPLICATEFAILED); 2578 2579 if (isSelfIssued) { 2580 childTraversedCACerts = state->traversedCACerts; 2581 } else { 2582 childTraversedCACerts = state->traversedCACerts + 1; 2583 2584 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames 2585 (state->candidateCert, 2586 &subjectNames, 2587 plContext), 2588 PKIX_CERTGETALLSUBJECTNAMESFAILED); 2589 2590 if (subjectNames) { 2591 PKIX_CHECK(PKIX_List_GetLength 2592 (subjectNames, 2593 &numSubjectNames, 2594 plContext), 2595 PKIX_LISTGETLENGTHFAILED); 2596 2597 } else { 2598 numSubjectNames = 0; 2599 } 2600 2601 for (i = 0; i < numSubjectNames; i++) { 2602 PKIX_CHECK(PKIX_List_GetItem 2603 (subjectNames, 2604 i, 2605 &subjectName, 2606 plContext), 2607 PKIX_LISTGETITEMFAILED); 2608 PKIX_NULLCHECK_ONE 2609 (state->traversedSubjNames); 2610 PKIX_CHECK(PKIX_List_AppendItem 2611 (state->traversedSubjNames, 2612 subjectName, 2613 plContext), 2614 PKIX_LISTAPPENDITEMFAILED); 2615 PKIX_DECREF(subjectName); 2616 } 2617 PKIX_DECREF(subjectNames); 2618 } 2619 2620 PKIX_CHECK(pkix_ForwardBuilderState_Create 2621 (childTraversedCACerts, 2622 state->buildConstants.maxFanout, 2623 state->numDepth - 1, 2624 canBeCached, 2625 validityDate, 2626 state->candidateCert, 2627 childTraversedSubjNames, 2628 state->trustChain, 2629 state, 2630 &childState, 2631 plContext), 2632 PKIX_FORWARDBUILDSTATECREATEFAILED); 2633 2634 PKIX_DECREF(childTraversedSubjNames); 2635 PKIX_DECREF(certSelParams); 2636 childState->verifyNode = verifyNode; 2637 verifyNode = NULL; 2638 PKIX_DECREF(state); 2639 state = childState; /* state->status == BUILD_INITIAL */ 2640 childState = NULL; 2641 continue; /* with while (!outOfOptions) */ 2642 } 2643 2644 if (state->status == BUILD_GETNEXTCERT) { 2645 pkixTempErrorReceived = PKIX_FALSE; 2646 PKIX_DECREF(state->candidateCert); 2647 2648 /* 2649 * If we were using a Cert from the callier-supplied partial 2650 * chain, delete it and go to the certStores. 2651 */ 2652 if (state->usingHintCerts == PKIX_TRUE) { 2653 PKIX_DECREF(state->candidateCerts); 2654 PKIX_CHECK(PKIX_List_Create 2655 (&state->candidateCerts, plContext), 2656 PKIX_LISTCREATEFAILED); 2657 2658 state->numCerts = 0; 2659 state->usingHintCerts = PKIX_FALSE; 2660 state->status = BUILD_TRYAIA; 2661 continue; 2662 } else if (++(state->certIndex) < (state->numCerts)) { 2663 if ((state->buildConstants.maxFanout != 0) && 2664 (--(state->numFanout) == 0)) { 2665 2666 if (state->verifyNode != NULL) { 2667 PKIX_ERROR_CREATE 2668 (BUILD, 2669 PKIX_FANOUTEXCEEDSRESOURCELIMITS, 2670 verifyError); 2671 PKIX_CHECK_FATAL 2672 (pkix_VerifyNode_SetError 2673 (state->verifyNode, 2674 verifyError, 2675 plContext), 2676 PKIX_VERIFYNODESETERRORFAILED); 2677 PKIX_DECREF(finalError); 2678 finalError = verifyError; 2679 verifyError = NULL; 2680 } 2681 /* Even if error logged, still need to abort */ 2682 PKIX_ERROR 2683 (PKIX_FANOUTEXCEEDSRESOURCELIMITS); 2684 } 2685 state->status = BUILD_CERTVALIDATING; 2686 continue; 2687 } 2688 } 2689 2690 /* 2691 * Adding the current cert to the chain didn't help. If our search 2692 * has been restricted to local certStores, try opening up the 2693 * search and see whether that helps. Otherwise, back up to the 2694 * parent cert, and see if there are any more to try. 2695 */ 2696 if (state->useOnlyLocal == PKIX_TRUE) { 2697 pkix_PrepareForwardBuilderStateForAIA(state); 2698 } else do { 2699 if (state->parentState == NULL) { 2700 /* We are at the top level, and can't back up! */ 2701 outOfOptions = PKIX_TRUE; 2702 } else { 2703 /* 2704 * Try the next cert, if any, for this parent. 2705 * Otherwise keep backing up until we reach a 2706 * parent with more certs to try. 2707 */ 2708 PKIX_CHECK(PKIX_List_GetLength 2709 (state->trustChain, &numChained, plContext), 2710 PKIX_LISTGETLENGTHFAILED); 2711 PKIX_CHECK(PKIX_List_DeleteItem 2712 (state->trustChain, numChained - 1, plContext), 2713 PKIX_LISTDELETEITEMFAILED); 2714 2715 /* local and aia fetching returned no good certs. 2716 * Creating a verify node in the parent that tells 2717 * us this. */ 2718 if (!state->verifyNode) { 2719 PKIX_CHECK_FATAL( 2720 pkix_VerifyNode_Create(state->prevCert, 2721 0, NULL, 2722 &state->verifyNode, 2723 plContext), 2724 PKIX_VERIFYNODECREATEFAILED); 2725 } 2726 /* Updating the log with the error. */ 2727 PKIX_DECREF(verifyError); 2728 PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER, 2729 verifyError); 2730 PKIX_CHECK_FATAL( 2731 pkix_VerifyNode_SetError(state->verifyNode, 2732 verifyError, 2733 plContext), 2734 PKIX_VERIFYNODESETERRORFAILED); 2735 PKIX_DECREF(verifyError); 2736 2737 PKIX_INCREF(state->parentState); 2738 parentState = state->parentState; 2739 PKIX_DECREF(verifyNode); 2740 verifyNode = state->verifyNode; 2741 state->verifyNode = NULL; 2742 PKIX_DECREF(state); 2743 state = parentState; 2744 parentState = NULL; 2745 if (state->verifyNode != NULL && verifyNode) { 2746 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2747 (state->verifyNode, 2748 verifyNode, 2749 plContext), 2750 PKIX_VERIFYNODEADDTOTREEFAILED); 2751 PKIX_DECREF(verifyNode); 2752 } 2753 PKIX_DECREF(validityDate); 2754 PKIX_INCREF(state->validityDate); 2755 validityDate = state->validityDate; 2756 canBeCached = state->canBeCached; 2757 2758 /* Are there any more Certs to try? */ 2759 if (++(state->certIndex) < (state->numCerts)) { 2760 state->status = BUILD_CERTVALIDATING; 2761 PKIX_DECREF(state->candidateCert); 2762 break; 2763 } 2764 if (state->useOnlyLocal == PKIX_TRUE) { 2765 /* Clean up and go for AIA round. */ 2766 pkix_PrepareForwardBuilderStateForAIA(state); 2767 break; 2768 } 2769 } 2770 PKIX_DECREF(state->candidateCert); 2771 } while (outOfOptions == PKIX_FALSE); 2772 2773 } /* while (outOfOptions == PKIX_FALSE) */ 2774 2775 cleanup: 2776 2777 if (pkixErrorClass == PKIX_FATAL_ERROR) { 2778 goto fatal; 2779 } 2780 2781 /* verifyNode should be equal to NULL at this point. Assert it. 2782 * Temporarelly use verifyError to store an error ref to which we 2783 * have in pkixErrorResult. This is done to prevent error cloberring 2784 * while using macros below. */ 2785 PORT_Assert(verifyError == NULL); 2786 verifyError = pkixErrorResult; 2787 2788 /* 2789 * We were called with an initialState that had no parent. If we are 2790 * returning with an error or with a result, we must destroy any state 2791 * that we created (any state with a parent). 2792 */ 2793 2794 PKIX_CHECK_FATAL(pkix_ForwardBuilderState_IsIOPending 2795 (state, &ioPending, plContext), 2796 PKIX_FORWARDBUILDERSTATEISIOPENDINGFAILED); 2797 2798 if (ioPending == PKIX_FALSE) { 2799 while (state->parentState) { 2800 PKIX_INCREF(state->parentState); 2801 parentState = state->parentState; 2802 PKIX_DECREF(verifyNode); 2803 verifyNode = state->verifyNode; 2804 state->verifyNode = NULL; 2805 PKIX_DECREF(state); 2806 state = parentState; 2807 parentState = NULL; 2808 if (state->verifyNode != NULL && verifyNode) { 2809 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree 2810 (state->verifyNode, 2811 verifyNode, 2812 plContext), 2813 PKIX_VERIFYNODEADDTOTREEFAILED); 2814 PKIX_DECREF(verifyNode); 2815 } 2816 } 2817 state->canBeCached = canBeCached; 2818 PKIX_DECREF(state->validityDate); 2819 state->validityDate = validityDate; 2820 validityDate = NULL; 2821 } 2822 if (!*pValResult && !verifyError) { 2823 if (!finalError) { 2824 PKIX_CHECK_FATAL( 2825 pkix_VerifyNode_FindError(state->verifyNode, 2826 &finalError, 2827 plContext), 2828 PKIX_VERIFYNODEFINDERRORFAILED); 2829 } 2830 if (finalError) { 2831 pkixErrorResult = finalError; 2832 pkixErrorCode = PKIX_BUILDFORWARDDEPTHFIRSTSEARCHFAILED; 2833 finalError = NULL; 2834 goto fatal; 2835 } 2836 pkixErrorCode = PKIX_SECERRORUNKNOWNISSUER; 2837 pkixErrorReceived = PKIX_TRUE; 2838 PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER, 2839 verifyError); 2840 PKIX_CHECK_FATAL( 2841 pkix_VerifyNode_SetError(state->verifyNode, verifyError, 2842 plContext), 2843 PKIX_VERIFYNODESETERRORFAILED); 2844 } else { 2845 pkixErrorResult = verifyError; 2846 verifyError = NULL; 2847 } 2848 2849 fatal: 2850 if (state->parentState) { 2851 /* parentState in "state" object should be NULL at this point. 2852 * If itn't, that means that we got fatal error(we have jumped to 2853 * "fatal" label) and we should destroy all state except the top one. */ 2854 while (state->parentState) { 2855 PKIX_Error *error = NULL; 2856 PKIX_ForwardBuilderState *prntState = state->parentState; 2857 /* Dumb: need to increment parentState to avoid destruction 2858 * of "build constants"(they get destroyed when parentState is 2859 * set to NULL. */ 2860 PKIX_INCREF(prntState); 2861 error = PKIX_PL_Object_DecRef((PKIX_PL_Object*)state, plContext); 2862 if (error) { 2863 PKIX_PL_Object_DecRef((PKIX_PL_Object*)error, plContext); 2864 } 2865 /* No need to decref the parent state. It was already done by 2866 * pkix_ForwardBuilderState_Destroy function. */ 2867 state = prntState; 2868 } 2869 } 2870 PKIX_DECREF(parentState); 2871 PKIX_DECREF(childState); 2872 PKIX_DECREF(valResult); 2873 PKIX_DECREF(verifyError); 2874 PKIX_DECREF(finalError); 2875 PKIX_DECREF(verifyNode); 2876 PKIX_DECREF(childTraversedSubjNames); 2877 PKIX_DECREF(certSelParams); 2878 PKIX_DECREF(subjectNames); 2879 PKIX_DECREF(subjectName); 2880 PKIX_DECREF(trustAnchor); 2881 PKIX_DECREF(validityDate); 2882 PKIX_DECREF(revCheckerState); 2883 PKIX_DECREF(currTime); 2884 PKIX_DECREF(filteredCerts); 2885 PKIX_DECREF(unfilteredCerts); 2886 PKIX_DECREF(trustedCert); 2887 2888 PKIX_RETURN(BUILD); 2889 } 2890 2891 /* 2892 * FUNCTION: pkix_Build_CheckInCache 2893 * DESCRIPTION: 2894 * 2895 * The function tries to locate a chain for a cert in the cert chain cache. 2896 * If found, the chain goes through revocation chacking and returned back to 2897 * caller. Chains that fail revocation check get removed from cache. 2898 * 2899 * PARAMETERS: 2900 * "state" 2901 * Address of ForwardBuilderState to be used. Must be non-NULL. 2902 * "pBuildResult" 2903 * Address at which the BuildResult is stored, after a successful build. 2904 * Must be non-NULL. 2905 * "pNBIOContext" 2906 * Address at which the NBIOContext is stored indicating whether the 2907 * validation is complete. Must be non-NULL. 2908 * "plContext" 2909 * Platform-specific context pointer. 2910 * THREAD SAFETY: 2911 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 2912 * RETURNS: 2913 * Returns NULL if the function succeeds. 2914 * Returns a Build Error if the function fails in a non-fatal way 2915 * Returns a Fatal Error if the function fails in an unrecoverable way. 2916 */ 2917 static PKIX_Error* 2918 pkix_Build_CheckInCache( 2919 PKIX_ForwardBuilderState *state, 2920 PKIX_BuildResult **pBuildResult, 2921 void **pNBIOContext, 2922 void *plContext) 2923 { 2924 PKIX_PL_Cert *targetCert = NULL; 2925 PKIX_List *anchors = NULL; 2926 PKIX_PL_Date *testDate = NULL; 2927 PKIX_BuildResult *buildResult = NULL; 2928 PKIX_ValidateResult *valResult = NULL; 2929 PKIX_Error *buildError = NULL; 2930 PKIX_TrustAnchor *matchingAnchor = NULL; 2931 PKIX_PL_Cert *trustedCert = NULL; 2932 PKIX_List *certList = NULL; 2933 PKIX_Boolean cacheHit = PKIX_FALSE; 2934 PKIX_Boolean trusted = PKIX_FALSE; 2935 PKIX_Boolean stillValid = PKIX_FALSE; 2936 void *nbioContext = NULL; 2937 2938 PKIX_ENTER(BUILD, "pkix_Build_CheckInCache"); 2939 2940 nbioContext = *pNBIOContext; 2941 *pNBIOContext = NULL; 2942 2943 targetCert = state->buildConstants.targetCert; 2944 anchors = state->buildConstants.anchors; 2945 testDate = state->buildConstants.testDate; 2946 2947 /* Check whether this cert verification has been cached. */ 2948 PKIX_CHECK(pkix_CacheCertChain_Lookup 2949 (targetCert, 2950 anchors, 2951 testDate, 2952 &cacheHit, 2953 &buildResult, 2954 plContext), 2955 PKIX_CACHECERTCHAINLOOKUPFAILED); 2956 2957 if (!cacheHit) { 2958 goto cleanup; 2959 } 2960 2961 /* 2962 * We found something in cache. Verify that the anchor 2963 * cert is still trusted, 2964 */ 2965 PKIX_CHECK(PKIX_BuildResult_GetValidateResult 2966 (buildResult, &valResult, plContext), 2967 PKIX_BUILDRESULTGETVALIDATERESULTFAILED); 2968 2969 PKIX_CHECK(PKIX_ValidateResult_GetTrustAnchor 2970 (valResult, &matchingAnchor, plContext), 2971 PKIX_VALIDATERESULTGETTRUSTANCHORFAILED); 2972 2973 PKIX_DECREF(valResult); 2974 2975 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert 2976 (matchingAnchor, &trustedCert, plContext), 2977 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); 2978 2979 if (anchors && state->buildConstants.numAnchors) { 2980 /* Check if it is one of the trust anchors */ 2981 PKIX_CHECK( 2982 pkix_List_Contains(anchors, 2983 (PKIX_PL_Object *)matchingAnchor, 2984 &trusted, 2985 plContext), 2986 PKIX_LISTCONTAINSFAILED); 2987 } 2988 2989 if ((!trusted && !state->buildConstants.trustOnlyUserAnchors) || 2990 !state->buildConstants.numAnchors) { 2991 /* If it is not one of the trust anchors and the trust anchors 2992 * are supplemental, or if there are no trust anchors, then check 2993 * if the cert is trusted directly. 2994 */ 2995 PKIX_CHECK( 2996 PKIX_PL_Cert_IsCertTrusted(trustedCert, 2997 PKIX_PL_TrustAnchorMode_Ignore, 2998 &trusted, plContext), 2999 PKIX_CERTISCERTTRUSTEDFAILED); 3000 } 3001 3002 if (!trusted) { 3003 goto cleanup; 3004 } 3005 /* 3006 * Since the key usage may vary for different 3007 * applications, we need to verify the chain again. 3008 * Reverification will be improved with a fix for 397805. 3009 */ 3010 PKIX_CHECK(PKIX_BuildResult_GetCertChain 3011 (buildResult, &certList, plContext), 3012 PKIX_BUILDRESULTGETCERTCHAINFAILED); 3013 3014 PKIX_CHECK(pkix_Build_ValidationCheckers 3015 (state, 3016 certList, 3017 matchingAnchor, 3018 PKIX_TRUE, /* Chain revalidation stage. */ 3019 plContext), 3020 PKIX_BUILDVALIDATIONCHECKERSFAILED); 3021 3022 PKIX_CHECK_ONLY_FATAL( 3023 pkix_Build_ValidateEntireChain(state, matchingAnchor, 3024 &nbioContext, &valResult, 3025 state->verifyNode, plContext), 3026 PKIX_BUILDVALIDATEENTIRECHAINFAILED); 3027 3028 if (nbioContext != NULL) { 3029 /* IO still pending, resume later */ 3030 *pNBIOContext = nbioContext; 3031 goto cleanup; 3032 } 3033 if (!PKIX_ERROR_RECEIVED) { 3034 /* The result from cache is still valid. But we replace an old*/ 3035 *pBuildResult = buildResult; 3036 buildResult = NULL; 3037 stillValid = PKIX_TRUE; 3038 } 3039 3040 cleanup: 3041 3042 if (!nbioContext && cacheHit && !(trusted && stillValid)) { 3043 /* The anchor of this chain is no longer trusted or 3044 * chain cert(s) has been revoked. 3045 * Invalidate this result in the cache */ 3046 buildError = pkixErrorResult; 3047 PKIX_CHECK_FATAL(pkix_CacheCertChain_Remove 3048 (targetCert, 3049 anchors, 3050 plContext), 3051 PKIX_CACHECERTCHAINREMOVEFAILED); 3052 pkixErrorResult = buildError; 3053 buildError = NULL; 3054 } 3055 3056 fatal: 3057 PKIX_DECREF(buildResult); 3058 PKIX_DECREF(valResult); 3059 PKIX_DECREF(buildError); 3060 PKIX_DECREF(certList); 3061 PKIX_DECREF(matchingAnchor); 3062 PKIX_DECREF(trustedCert); 3063 3064 3065 PKIX_RETURN(BUILD); 3066 } 3067 3068 /* 3069 * FUNCTION: pkix_Build_InitiateBuildChain 3070 * DESCRIPTION: 3071 * 3072 * This function initiates the search for a BuildChain, using the parameters 3073 * provided in "procParams" and, if continuing a search that was suspended 3074 * for I/O, using the ForwardBuilderState pointed to by "pState". 3075 * 3076 * If a successful chain is built, this function stores the BuildResult at 3077 * "pBuildResult". Alternatively, if an operation using non-blocking I/O 3078 * is in progress and the operation has not been completed, this function 3079 * stores the platform-dependent non-blocking I/O context (nbioContext) at 3080 * "pNBIOContext", the FowardBuilderState at "pState", and NULL at 3081 * "pBuildResult". Finally, if chain building was unsuccessful, this function 3082 * stores NULL at both "pState" and at "pBuildResult". 3083 * 3084 * Note: This function is re-entered only for the case of non-blocking I/O 3085 * in the "short-cut" attempt to build a chain using the target Certificate 3086 * directly with one of the trustAnchors. For all other cases, resumption 3087 * after non-blocking I/O is via pkix_Build_ResumeBuildChain. 3088 * 3089 * PARAMETERS: 3090 * "procParams" 3091 * Address of the ProcessingParams for the search. Must be non-NULL. 3092 * "pNBIOContext" 3093 * Address at which the NBIOContext is stored indicating whether the 3094 * validation is complete. Must be non-NULL. 3095 * "pState" 3096 * Address at which the ForwardBuilderState is stored, if the chain 3097 * building is suspended for waiting I/O; also, the address at which the 3098 * ForwardBuilderState is provided for resumption of the chain building 3099 * attempt. Must be non-NULL. 3100 * "pBuildResult" 3101 * Address at which the BuildResult is stored, after a successful build. 3102 * Must be non-NULL. 3103 * "pVerifyNode" 3104 * Address at which a VerifyNode chain is returned, if non-NULL. 3105 * "plContext" 3106 * Platform-specific context pointer. 3107 * THREAD SAFETY: 3108 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 3109 * RETURNS: 3110 * Returns NULL if the function succeeds. 3111 * Returns a Build Error if the function fails in a non-fatal way 3112 * Returns a Fatal Error if the function fails in an unrecoverable way. 3113 */ 3114 static PKIX_Error * 3115 pkix_Build_InitiateBuildChain( 3116 PKIX_ProcessingParams *procParams, 3117 void **pNBIOContext, 3118 PKIX_ForwardBuilderState **pState, 3119 PKIX_BuildResult **pBuildResult, 3120 PKIX_VerifyNode **pVerifyNode, 3121 void *plContext) 3122 { 3123 PKIX_UInt32 numAnchors = 0; 3124 PKIX_UInt32 numCertStores = 0; 3125 PKIX_UInt32 numHintCerts = 0; 3126 PKIX_UInt32 i = 0; 3127 PKIX_Boolean isDuplicate = PKIX_FALSE; 3128 PKIX_PL_Cert *trustedCert = NULL; 3129 PKIX_CertSelector *targetConstraints = NULL; 3130 PKIX_ComCertSelParams *targetParams = NULL; 3131 PKIX_List *anchors = NULL; 3132 PKIX_List *targetSubjNames = NULL; 3133 PKIX_PL_Cert *targetCert = NULL; 3134 PKIX_PL_Object *firstHintCert = NULL; 3135 PKIX_RevocationChecker *revChecker = NULL; 3136 PKIX_List *certStores = NULL; 3137 PKIX_CertStore *certStore = NULL; 3138 PKIX_List *userCheckers = NULL; 3139 PKIX_List *hintCerts = NULL; 3140 PKIX_PL_Date *testDate = NULL; 3141 PKIX_PL_PublicKey *targetPubKey = NULL; 3142 void *nbioContext = NULL; 3143 BuildConstants buildConstants; 3144 3145 PKIX_List *tentativeChain = NULL; 3146 PKIX_ValidateResult *valResult = NULL; 3147 PKIX_BuildResult *buildResult = NULL; 3148 PKIX_List *certList = NULL; 3149 PKIX_ForwardBuilderState *state = NULL; 3150 PKIX_CertStore_CheckTrustCallback trustCallback = NULL; 3151 PKIX_CertSelector_MatchCallback selectorCallback = NULL; 3152 PKIX_Boolean trusted = PKIX_FALSE; 3153 PKIX_PL_AIAMgr *aiaMgr = NULL; 3154 3155 PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain"); 3156 PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult); 3157 3158 nbioContext = *pNBIOContext; 3159 *pNBIOContext = NULL; 3160 3161 state = *pState; 3162 *pState = NULL; /* no net change in reference count */ 3163 3164 if (state == NULL) { 3165 PKIX_CHECK(PKIX_ProcessingParams_GetDate 3166 (procParams, &testDate, plContext), 3167 PKIX_PROCESSINGPARAMSGETDATEFAILED); 3168 3169 PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors 3170 (procParams, &anchors, plContext), 3171 PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED); 3172 3173 PKIX_CHECK(PKIX_List_GetLength(anchors, &numAnchors, plContext), 3174 PKIX_LISTGETLENGTHFAILED); 3175 3176 /* retrieve stuff from targetCertConstraints */ 3177 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints 3178 (procParams, &targetConstraints, plContext), 3179 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); 3180 3181 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams 3182 (targetConstraints, &targetParams, plContext), 3183 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); 3184 3185 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate 3186 (targetParams, &targetCert, plContext), 3187 PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED); 3188 3189 PKIX_CHECK( 3190 PKIX_ComCertSelParams_SetLeafCertFlag(targetParams, 3191 PKIX_TRUE, plContext), 3192 PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED); 3193 3194 PKIX_CHECK(PKIX_ProcessingParams_GetHintCerts 3195 (procParams, &hintCerts, plContext), 3196 PKIX_PROCESSINGPARAMSGETHINTCERTSFAILED); 3197 3198 if (hintCerts != NULL) { 3199 PKIX_CHECK(PKIX_List_GetLength 3200 (hintCerts, &numHintCerts, plContext), 3201 PKIX_LISTGETLENGTHFAILED); 3202 } 3203 3204 /* 3205 * Caller must provide either a target Cert 3206 * (in ComCertSelParams->Certificate) or a partial Cert 3207 * chain (in ProcParams->HintCerts). 3208 */ 3209 3210 if (targetCert == NULL) { 3211 3212 /* Use first cert of hintCerts as the targetCert */ 3213 if (numHintCerts == 0) { 3214 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED); 3215 } 3216 3217 PKIX_CHECK(PKIX_List_GetItem 3218 (hintCerts, 3219 0, 3220 (PKIX_PL_Object **)&targetCert, 3221 plContext), 3222 PKIX_LISTGETITEMFAILED); 3223 3224 PKIX_CHECK(PKIX_List_DeleteItem(hintCerts, 0, plContext), 3225 PKIX_LISTGETITEMFAILED); 3226 } else { 3227 3228 /* 3229 * If the first hintCert is the same as the targetCert, 3230 * delete it from hintCerts. 3231 */ 3232 if (numHintCerts != 0) { 3233 PKIX_CHECK(PKIX_List_GetItem 3234 (hintCerts, 0, &firstHintCert, plContext), 3235 PKIX_LISTGETITEMFAILED); 3236 3237 PKIX_CHECK(PKIX_PL_Object_Equals 3238 ((PKIX_PL_Object *)targetCert, 3239 firstHintCert, 3240 &isDuplicate, 3241 plContext), 3242 PKIX_OBJECTEQUALSFAILED); 3243 3244 if (isDuplicate) { 3245 PKIX_CHECK(PKIX_List_DeleteItem 3246 (hintCerts, 0, plContext), 3247 PKIX_LISTGETITEMFAILED); 3248 } 3249 PKIX_DECREF(firstHintCert); 3250 } 3251 3252 } 3253 3254 if (targetCert == NULL) { 3255 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED); 3256 } 3257 3258 PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted 3259 (targetCert, 3260 &trusted, 3261 plContext), 3262 PKIX_CERTISCERTTRUSTEDFAILED); 3263 3264 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames 3265 (targetCert, 3266 &targetSubjNames, 3267 plContext), 3268 PKIX_CERTGETALLSUBJECTNAMESFAILED); 3269 3270 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey 3271 (targetCert, &targetPubKey, plContext), 3272 PKIX_CERTGETSUBJECTPUBLICKEYFAILED); 3273 3274 PKIX_CHECK(PKIX_List_Create(&tentativeChain, plContext), 3275 PKIX_LISTCREATEFAILED); 3276 3277 PKIX_CHECK(PKIX_List_AppendItem 3278 (tentativeChain, (PKIX_PL_Object *)targetCert, plContext), 3279 PKIX_LISTAPPENDITEMFAILED); 3280 3281 if (procParams->qualifyTargetCert) { 3282 /* EE cert validation */ 3283 /* Sync up the time on the target selector parameter struct. */ 3284 PKIX_CHECK( 3285 PKIX_ComCertSelParams_SetCertificateValid(targetParams, 3286 testDate, 3287 plContext), 3288 PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED); 3289 3290 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback 3291 (targetConstraints, &selectorCallback, plContext), 3292 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); 3293 3294 pkixErrorResult = 3295 (*selectorCallback)(targetConstraints, targetCert, 3296 plContext); 3297 if (pkixErrorResult) { 3298 pkixErrorClass = pkixErrorResult->errClass; 3299 if (pkixErrorClass == PKIX_FATAL_ERROR) { 3300 goto cleanup; 3301 } 3302 if (pVerifyNode != NULL) { 3303 PKIX_Error *tempResult = 3304 pkix_VerifyNode_Create(targetCert, 0, 3305 pkixErrorResult, 3306 pVerifyNode, 3307 plContext); 3308 if (tempResult) { 3309 PKIX_DECREF(pkixErrorResult); 3310 pkixErrorResult = tempResult; 3311 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; 3312 pkixErrorClass = PKIX_FATAL_ERROR; 3313 goto cleanup; 3314 } 3315 } 3316 pkixErrorCode = PKIX_CERTCHECKVALIDITYFAILED; 3317 goto cleanup; 3318 } 3319 } 3320 3321 /* If the EE cert is trusted, force success. We only want to do 3322 * this if we aren't validating against a policy (like EV). */ 3323 if (trusted && procParams->initialPolicies == NULL) { 3324 if (pVerifyNode != NULL) { 3325 PKIX_Error *tempResult = 3326 pkix_VerifyNode_Create(targetCert, 0, NULL, 3327 pVerifyNode, 3328 plContext); 3329 if (tempResult) { 3330 pkixErrorResult = tempResult; 3331 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; 3332 pkixErrorClass = PKIX_FATAL_ERROR; 3333 goto cleanup; 3334 } 3335 } 3336 PKIX_CHECK(pkix_ValidateResult_Create 3337 (targetPubKey, NULL /* anchor */, 3338 NULL /* policyTree */, &valResult, plContext), 3339 PKIX_VALIDATERESULTCREATEFAILED); 3340 PKIX_CHECK( 3341 pkix_BuildResult_Create(valResult, tentativeChain, 3342 &buildResult, plContext), 3343 PKIX_BUILDRESULTCREATEFAILED); 3344 *pBuildResult = buildResult; 3345 /* Note that *pState is NULL. The only side effect is that 3346 * the cert chain won't be cached in PKIX_BuildChain, which 3347 * is fine. */ 3348 goto cleanup; 3349 } 3350 3351 PKIX_CHECK(PKIX_ProcessingParams_GetCertStores 3352 (procParams, &certStores, plContext), 3353 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED); 3354 3355 PKIX_CHECK(PKIX_List_GetLength 3356 (certStores, &numCertStores, plContext), 3357 PKIX_LISTGETLENGTHFAILED); 3358 3359 /* Reorder CertStores so trusted are at front of the List */ 3360 if (numCertStores > 1) { 3361 for (i = numCertStores - 1; i > 0; i--) { 3362 PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem 3363 (certStores, 3364 i, 3365 (PKIX_PL_Object **)&certStore, 3366 plContext), 3367 PKIX_LISTGETITEMFAILED); 3368 PKIX_CHECK_ONLY_FATAL(PKIX_CertStore_GetTrustCallback 3369 (certStore, &trustCallback, plContext), 3370 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED); 3371 3372 if (trustCallback != NULL) { 3373 /* Is a trusted Cert, move CertStore to front */ 3374 PKIX_CHECK(PKIX_List_DeleteItem 3375 (certStores, i, plContext), 3376 PKIX_LISTDELETEITEMFAILED); 3377 PKIX_CHECK(PKIX_List_InsertItem 3378 (certStores, 3379 0, 3380 (PKIX_PL_Object *)certStore, 3381 plContext), 3382 PKIX_LISTINSERTITEMFAILED); 3383 3384 } 3385 3386 PKIX_DECREF(certStore); 3387 } 3388 } 3389 3390 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers 3391 (procParams, &userCheckers, plContext), 3392 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); 3393 3394 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker 3395 (procParams, &revChecker, plContext), 3396 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); 3397 /* Do not initialize AIA manager if we are not going to fetch 3398 * cert using aia url. */ 3399 if (procParams->useAIAForCertFetching) { 3400 PKIX_CHECK(PKIX_PL_AIAMgr_Create(&aiaMgr, plContext), 3401 PKIX_AIAMGRCREATEFAILED); 3402 } 3403 3404 /* 3405 * We initialize all the fields of buildConstants here, in one place, 3406 * just to help keep track and ensure that we got everything. 3407 */ 3408 3409 buildConstants.numAnchors = numAnchors; 3410 buildConstants.numCertStores = numCertStores; 3411 buildConstants.numHintCerts = numHintCerts; 3412 buildConstants.procParams = procParams; 3413 buildConstants.testDate = testDate; 3414 buildConstants.timeLimit = NULL; 3415 buildConstants.targetCert = targetCert; 3416 buildConstants.targetPubKey = targetPubKey; 3417 buildConstants.certStores = certStores; 3418 buildConstants.anchors = anchors; 3419 buildConstants.userCheckers = userCheckers; 3420 buildConstants.hintCerts = hintCerts; 3421 buildConstants.revChecker = revChecker; 3422 buildConstants.aiaMgr = aiaMgr; 3423 buildConstants.trustOnlyUserAnchors = 3424 procParams->useOnlyTrustAnchors; 3425 3426 PKIX_CHECK(pkix_Build_GetResourceLimits(&buildConstants, plContext), 3427 PKIX_BUILDGETRESOURCELIMITSFAILED); 3428 3429 PKIX_CHECK(pkix_ForwardBuilderState_Create 3430 (0, /* PKIX_UInt32 traversedCACerts */ 3431 buildConstants.maxFanout, 3432 buildConstants.maxDepth, 3433 PKIX_TRUE, /* PKIX_Boolean canBeCached */ 3434 NULL, /* PKIX_Date *validityDate */ 3435 targetCert, /* PKIX_PL_Cert *prevCert */ 3436 targetSubjNames, /* PKIX_List *traversedSubjNames */ 3437 tentativeChain, /* PKIX_List *trustChain */ 3438 NULL, /* PKIX_ForwardBuilderState *parent */ 3439 &state, /* PKIX_ForwardBuilderState **pState */ 3440 plContext), 3441 PKIX_BUILDSTATECREATEFAILED); 3442 3443 state->buildConstants.numAnchors = buildConstants.numAnchors; 3444 state->buildConstants.numCertStores = buildConstants.numCertStores; 3445 state->buildConstants.numHintCerts = buildConstants.numHintCerts; 3446 state->buildConstants.maxFanout = buildConstants.maxFanout; 3447 state->buildConstants.maxDepth = buildConstants.maxDepth; 3448 state->buildConstants.maxTime = buildConstants.maxTime; 3449 state->buildConstants.procParams = buildConstants.procParams; 3450 PKIX_INCREF(buildConstants.testDate); 3451 state->buildConstants.testDate = buildConstants.testDate; 3452 state->buildConstants.timeLimit = buildConstants.timeLimit; 3453 PKIX_INCREF(buildConstants.targetCert); 3454 state->buildConstants.targetCert = buildConstants.targetCert; 3455 PKIX_INCREF(buildConstants.targetPubKey); 3456 state->buildConstants.targetPubKey = 3457 buildConstants.targetPubKey; 3458 PKIX_INCREF(buildConstants.certStores); 3459 state->buildConstants.certStores = buildConstants.certStores; 3460 PKIX_INCREF(buildConstants.anchors); 3461 state->buildConstants.anchors = buildConstants.anchors; 3462 PKIX_INCREF(buildConstants.userCheckers); 3463 state->buildConstants.userCheckers = 3464 buildConstants.userCheckers; 3465 PKIX_INCREF(buildConstants.hintCerts); 3466 state->buildConstants.hintCerts = buildConstants.hintCerts; 3467 PKIX_INCREF(buildConstants.revChecker); 3468 state->buildConstants.revChecker = buildConstants.revChecker; 3469 state->buildConstants.aiaMgr = buildConstants.aiaMgr; 3470 aiaMgr = NULL; 3471 state->buildConstants.trustOnlyUserAnchors = 3472 buildConstants.trustOnlyUserAnchors; 3473 3474 if (buildConstants.maxTime != 0) { 3475 PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds 3476 (buildConstants.maxTime, 3477 &state->buildConstants.timeLimit, 3478 plContext), 3479 PKIX_DATECREATECURRENTOFFBYSECONDSFAILED); 3480 } 3481 3482 if (pVerifyNode != NULL) { 3483 PKIX_Error *tempResult = 3484 pkix_VerifyNode_Create(targetCert, 0, NULL, 3485 &(state->verifyNode), 3486 plContext); 3487 if (tempResult) { 3488 pkixErrorResult = tempResult; 3489 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; 3490 pkixErrorClass = PKIX_FATAL_ERROR; 3491 goto cleanup; 3492 } 3493 } 3494 3495 PKIX_CHECK_ONLY_FATAL( 3496 pkix_Build_CheckInCache(state, &buildResult, 3497 &nbioContext, plContext), 3498 PKIX_UNABLETOBUILDCHAIN); 3499 if (nbioContext) { 3500 *pNBIOContext = nbioContext; 3501 *pState = state; 3502 state = NULL; 3503 goto cleanup; 3504 } 3505 if (buildResult) { 3506 *pBuildResult = buildResult; 3507 if (pVerifyNode != NULL) { 3508 *pVerifyNode = state->verifyNode; 3509 state->verifyNode = NULL; 3510 } 3511 goto cleanup; 3512 } 3513 } 3514 3515 /* If we're resuming after non-blocking I/O we need to get SubjNames */ 3516 if (targetSubjNames == NULL) { 3517 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames 3518 (state->buildConstants.targetCert, 3519 &targetSubjNames, 3520 plContext), 3521 PKIX_CERTGETALLSUBJECTNAMESFAILED); 3522 } 3523 3524 state->status = BUILD_INITIAL; 3525 3526 pkixErrorResult = 3527 pkix_BuildForwardDepthFirstSearch(&nbioContext, state, 3528 &valResult, plContext); 3529 3530 /* non-null nbioContext means the build would block */ 3531 if (pkixErrorResult == NULL && nbioContext != NULL) { 3532 3533 *pNBIOContext = nbioContext; 3534 *pBuildResult = NULL; 3535 3536 /* no valResult means the build has failed */ 3537 } else { 3538 if (pVerifyNode != NULL) { 3539 PKIX_INCREF(state->verifyNode); 3540 *pVerifyNode = state->verifyNode; 3541 } 3542 3543 if (valResult == NULL || pkixErrorResult) 3544 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); 3545 PKIX_CHECK( 3546 pkix_BuildResult_Create(valResult, state->trustChain, 3547 &buildResult, plContext), 3548 PKIX_BUILDRESULTCREATEFAILED); 3549 *pBuildResult = buildResult; 3550 } 3551 3552 *pState = state; 3553 state = NULL; 3554 3555 cleanup: 3556 3557 PKIX_DECREF(targetConstraints); 3558 PKIX_DECREF(targetParams); 3559 PKIX_DECREF(anchors); 3560 PKIX_DECREF(targetSubjNames); 3561 PKIX_DECREF(targetCert); 3562 PKIX_DECREF(revChecker); 3563 PKIX_DECREF(certStores); 3564 PKIX_DECREF(certStore); 3565 PKIX_DECREF(userCheckers); 3566 PKIX_DECREF(hintCerts); 3567 PKIX_DECREF(firstHintCert); 3568 PKIX_DECREF(testDate); 3569 PKIX_DECREF(targetPubKey); 3570 PKIX_DECREF(tentativeChain); 3571 PKIX_DECREF(valResult); 3572 PKIX_DECREF(certList); 3573 PKIX_DECREF(trustedCert); 3574 PKIX_DECREF(state); 3575 PKIX_DECREF(aiaMgr); 3576 3577 PKIX_RETURN(BUILD); 3578 } 3579 3580 /* 3581 * FUNCTION: pkix_Build_ResumeBuildChain 3582 * DESCRIPTION: 3583 * 3584 * This function continues the search for a BuildChain, using the parameters 3585 * provided in "procParams" and the ForwardBuilderState pointed to by "state". 3586 * 3587 * If a successful chain is built, this function stores the BuildResult at 3588 * "pBuildResult". Alternatively, if an operation using non-blocking I/O 3589 * is in progress and the operation has not been completed, this function 3590 * stores the FowardBuilderState at "pState" and NULL at "pBuildResult". 3591 * Finally, if chain building was unsuccessful, this function stores NULL 3592 * at both "pState" and at "pBuildResult". 3593 * 3594 * PARAMETERS: 3595 * "pNBIOContext" 3596 * Address at which the NBIOContext is stored indicating whether the 3597 * validation is complete. Must be non-NULL. 3598 * "pState" 3599 * Address at which the ForwardBuilderState is provided for resumption of 3600 * the chain building attempt; also, the address at which the 3601 * ForwardBuilderStateis stored, if the chain building is suspended for 3602 * waiting I/O. Must be non-NULL. 3603 * "pBuildResult" 3604 * Address at which the BuildResult is stored, after a successful build. 3605 * Must be non-NULL. 3606 * "plContext" 3607 * Platform-specific context pointer. 3608 * THREAD SAFETY: 3609 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 3610 * RETURNS: 3611 * Returns NULL if the function succeeds. 3612 * Returns a Build Error if the function fails in a non-fatal way 3613 * Returns a Fatal Error if the function fails in an unrecoverable way. 3614 */ 3615 static PKIX_Error * 3616 pkix_Build_ResumeBuildChain( 3617 void **pNBIOContext, 3618 PKIX_ForwardBuilderState *state, 3619 PKIX_BuildResult **pBuildResult, 3620 PKIX_VerifyNode **pVerifyNode, 3621 void *plContext) 3622 { 3623 PKIX_ValidateResult *valResult = NULL; 3624 PKIX_BuildResult *buildResult = NULL; 3625 void *nbioContext = NULL; 3626 3627 PKIX_ENTER(BUILD, "pkix_Build_ResumeBuildChain"); 3628 PKIX_NULLCHECK_TWO(state, pBuildResult); 3629 3630 nbioContext = *pNBIOContext; 3631 *pNBIOContext = NULL; 3632 3633 pkixErrorResult = 3634 pkix_BuildForwardDepthFirstSearch(&nbioContext, state, 3635 &valResult, plContext); 3636 3637 /* non-null nbioContext means the build would block */ 3638 if (pkixErrorResult == NULL && nbioContext != NULL) { 3639 3640 *pNBIOContext = nbioContext; 3641 *pBuildResult = NULL; 3642 3643 /* no valResult means the build has failed */ 3644 } else { 3645 if (pVerifyNode != NULL) { 3646 PKIX_INCREF(state->verifyNode); 3647 *pVerifyNode = state->verifyNode; 3648 } 3649 3650 if (valResult == NULL || pkixErrorResult) 3651 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); 3652 3653 PKIX_CHECK( 3654 pkix_BuildResult_Create(valResult, state->trustChain, 3655 &buildResult, plContext), 3656 PKIX_BUILDRESULTCREATEFAILED); 3657 *pBuildResult = buildResult; 3658 } 3659 3660 cleanup: 3661 3662 PKIX_DECREF(valResult); 3663 3664 PKIX_RETURN(BUILD); 3665 } 3666 3667 /* --Public-Functions--------------------------------------------- */ 3668 3669 /* 3670 * FUNCTION: PKIX_BuildChain (see comments in pkix.h) 3671 */ 3672 PKIX_Error * 3673 PKIX_BuildChain( 3674 PKIX_ProcessingParams *procParams, 3675 void **pNBIOContext, 3676 void **pState, 3677 PKIX_BuildResult **pBuildResult, 3678 PKIX_VerifyNode **pVerifyNode, 3679 void *plContext) 3680 { 3681 PKIX_ForwardBuilderState *state = NULL; 3682 PKIX_BuildResult *buildResult = NULL; 3683 void *nbioContext = NULL; 3684 3685 PKIX_ENTER(BUILD, "PKIX_BuildChain"); 3686 PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult); 3687 3688 nbioContext = *pNBIOContext; 3689 *pNBIOContext = NULL; 3690 3691 if (*pState == NULL) { 3692 PKIX_CHECK(pkix_Build_InitiateBuildChain 3693 (procParams, 3694 &nbioContext, 3695 &state, 3696 &buildResult, 3697 pVerifyNode, 3698 plContext), 3699 PKIX_BUILDINITIATEBUILDCHAINFAILED); 3700 } else { 3701 state = (PKIX_ForwardBuilderState *)(*pState); 3702 *pState = NULL; /* no net change in reference count */ 3703 if (state->status == BUILD_SHORTCUTPENDING) { 3704 PKIX_CHECK(pkix_Build_InitiateBuildChain 3705 (procParams, 3706 &nbioContext, 3707 &state, 3708 &buildResult, 3709 pVerifyNode, 3710 plContext), 3711 PKIX_BUILDINITIATEBUILDCHAINFAILED); 3712 } else { 3713 PKIX_CHECK(pkix_Build_ResumeBuildChain 3714 (&nbioContext, 3715 state, 3716 &buildResult, 3717 pVerifyNode, 3718 plContext), 3719 PKIX_BUILDINITIATEBUILDCHAINFAILED); 3720 } 3721 } 3722 3723 /* non-null nbioContext means the build would block */ 3724 if (nbioContext != NULL) { 3725 3726 *pNBIOContext = nbioContext; 3727 *pState = state; 3728 state = NULL; 3729 *pBuildResult = NULL; 3730 3731 /* no buildResult means the build has failed */ 3732 } else if (buildResult == NULL) { 3733 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); 3734 } else { 3735 /* 3736 * If we made a successful chain by combining the target Cert 3737 * with one of the Trust Anchors, we may have never created a 3738 * validityDate. We treat this situation as 3739 * canBeCached = PKIX_FALSE. 3740 */ 3741 if ((state != NULL) && 3742 ((state->validityDate) != NULL) && 3743 (state->canBeCached)) { 3744 PKIX_CHECK(pkix_CacheCertChain_Add 3745 (state->buildConstants.targetCert, 3746 state->buildConstants.anchors, 3747 state->validityDate, 3748 buildResult, 3749 plContext), 3750 PKIX_CACHECERTCHAINADDFAILED); 3751 } 3752 3753 *pState = NULL; 3754 *pBuildResult = buildResult; 3755 buildResult = NULL; 3756 } 3757 3758 cleanup: 3759 PKIX_DECREF(buildResult); 3760 PKIX_DECREF(state); 3761 3762 PKIX_RETURN(BUILD); 3763 }