Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: nss/lib/libpkix/pkix/top/pkix_build.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/libpkix/pkix/top/pkix_build.h ('k') | nss/lib/libpkix/pkix/top/pkix_lifecycle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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", #errCo de)); \
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, &paramsNeeded, 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, &currentIssuer, 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, &notAfter, 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 /*
1947 * FUNCTION: pkix_BuildForwardDepthFirstSearch
1948 * DESCRIPTION:
1949 *
1950 * This function performs a depth first search in the "forward" direction (from
1951 * the target Cert to the trust anchor). A non-NULL targetCert must be stored
1952 * in the ForwardBuilderState before this function is called. It is not written
1953 * recursively since execution may be suspended in in any of several places
1954 * pending completion of non-blocking I/O. This iterative structure makes it
1955 * much easier to resume where it left off.
1956 *
1957 * Since the nature of the search is recursive, the recursion is handled by
1958 * chaining states. That is, each new step involves creating a new
1959 * ForwardBuilderState linked to its predecessor. If a step turns out to be
1960 * fruitless, the state of the predecessor is restored and the next alternative
1961 * is tried. When a search is successful, values needed from the last state
1962 * (canBeCached and validityDate) are copied to the state provided by the
1963 * caller, so that the caller can retrieve those values.
1964 *
1965 * There are three return arguments, the NBIOContext, the ValidateResult and
1966 * the ForwardBuilderState. If NBIOContext is non-NULL, it means the search is
1967 * suspended until the results of a non-blocking IO become available. The
1968 * caller may wait for the completion using platform-dependent methods and then
1969 * call this function again, allowing it to resume the search. If NBIOContext
1970 * is NULL and the ValidateResult is non-NULL, it means the search has
1971 * concluded successfully. If the NBIOContext is NULL but the ValidateResult is
1972 * NULL, it means the search was unsuccessful.
1973 *
1974 * This function performs several steps at each node in the constructed chain:
1975 *
1976 * 1) It retrieves Certs from the registered CertStores that match the
1977 * criteria established by the ForwardBuilderState pointed to by "state", such
1978 * as a subject name matching the issuer name of the previous Cert. If there
1979 * are no matching Certs, the function returns to the previous, or "parent",
1980 * state and tries to continue the chain building with another of the Certs
1981 * obtained from the CertStores as possible issuers for that parent Cert.
1982 *
1983 * 2) For each candidate Cert returned by the CertStores, this function checks
1984 * whether the Cert is valid. If it is trusted, this function checks whether
1985 * this Cert might serve as a TrustAnchor for a complete chain.
1986 *
1987 * 3) It determines whether this Cert, in conjunction with any of the
1988 * TrustAnchors, might complete a chain. A complete chain, from this or the
1989 * preceding step, is checked to see whether it is valid as a complete
1990 * chain, including the checks that cannot be done in the forward direction.
1991 *
1992 * 4) If this Cert chains successfully, but is not a complete chain, that is,
1993 * we have not reached a trusted Cert, a new ForwardBuilderState is created
1994 * with this Cert as the immediate predecessor, and we continue in step (1),
1995 * attempting to get Certs from the CertStores with this Certs "issuer" as
1996 * their subject.
1997 *
1998 * 5) If an entire chain validates successfully, then we are done. A
1999 * ValidateResult is created containing the Public Key of the target
2000 * certificate (including DSA parameter inheritance, if any) and the
2001 * PolicyNode representing the policy tree output by the validation algorithm,
2002 * and stored at pValResult, and the function exits returning NULL.
2003 *
2004 * 5) If the entire chain does not validate successfully, the algorithm
2005 * discards the latest Cert and continues in step 2 with the next candidate
2006 * Cert, backing up to a parent state when no more possibilities exist at a
2007 * given level, and returning failure when we try to back up but discover we
2008 * are at the top level.
2009 *
2010 * PARAMETERS:
2011 * "pNBIOContext"
2012 * Address at which platform-dependent information is returned if building
2013 * is suspended for non-blocking I/O. Must be non-NULL.
2014 * "pState"
2015 * Address at which input ForwardBuilderState is found, and at which output
2016 * ForwardBuilderState is stored. Must be non-NULL.
2017 * "pValResult"
2018 * Address at which the ValidateResult is stored. Must be non-NULL.
2019 * "plContext"
2020 * Platform-specific context pointer.
2021 * THREAD SAFETY:
2022 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2023 * RETURNS:
2024 * Returns NULL if the function succeeds.
2025 * Returns a Build Error if the function fails in a non-fatal way.
2026 * Returns a Fatal Error if the function fails in an unrecoverable way.
2027 */
2028 static PKIX_Error *
2029 pkix_BuildForwardDepthFirstSearch(
2030 void **pNBIOContext,
2031 PKIX_ForwardBuilderState *state,
2032 PKIX_ValidateResult **pValResult,
2033 void *plContext)
2034 {
2035 PKIX_Boolean outOfOptions = PKIX_FALSE;
2036 PKIX_Boolean trusted = PKIX_FALSE;
2037 PKIX_Boolean isSelfIssued = PKIX_FALSE;
2038 PKIX_Boolean canBeCached = PKIX_FALSE;
2039 PKIX_Boolean ioPending = PKIX_FALSE;
2040 PKIX_PL_Date *validityDate = NULL;
2041 PKIX_PL_Date *currTime = NULL;
2042 PKIX_Int32 childTraversedCACerts = 0;
2043 PKIX_UInt32 numSubjectNames = 0;
2044 PKIX_UInt32 numChained = 0;
2045 PKIX_Int32 cmpTimeResult = 0;
2046 PKIX_UInt32 i = 0;
2047 PKIX_UInt32 certsSoFar = 0;
2048 PKIX_List *childTraversedSubjNames = NULL;
2049 PKIX_List *subjectNames = NULL;
2050 PKIX_List *unfilteredCerts = NULL;
2051 PKIX_List *filteredCerts = NULL;
2052 PKIX_PL_Object *subjectName = NULL;
2053 PKIX_ValidateResult *valResult = NULL;
2054 PKIX_ForwardBuilderState *childState = NULL;
2055 PKIX_ForwardBuilderState *parentState = NULL;
2056 PKIX_PL_Object *revCheckerState = NULL;
2057 PKIX_ComCertSelParams *certSelParams = NULL;
2058 PKIX_TrustAnchor *trustAnchor = NULL;
2059 PKIX_PL_Cert *trustedCert = NULL;
2060 PKIX_VerifyNode *verifyNode = NULL;
2061 PKIX_Error *verifyError = NULL;
2062 PKIX_Error *finalError = NULL;
2063 void *nbio = NULL;
2064 PKIX_UInt32 numIterations = 0;
2065
2066 PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch");
2067 PKIX_NULLCHECK_THREE(pNBIOContext, state, pValResult);
2068
2069 nbio = *pNBIOContext;
2070 *pNBIOContext = NULL;
2071 PKIX_INCREF(state->validityDate);
2072 validityDate = state->validityDate;
2073 canBeCached = state->canBeCached;
2074 PKIX_DECREF(*pValResult);
2075
2076 /*
2077 * We return if successful; if we fall off the end
2078 * of this "while" clause our search has failed.
2079 */
2080 while (outOfOptions == PKIX_FALSE) {
2081 /*
2082 * The maximum number of iterations works around a bug that
2083 * causes this while loop to never exit when AIA and cross
2084 * certificates are involved. See bug xxxxx.
2085 */
2086 if (numIterations++ > 250)
2087 PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS);
2088
2089 if (state->buildConstants.maxTime != 0) {
2090 PKIX_DECREF(currTime);
2091 PKIX_CHECK(PKIX_PL_Date_Create_UTCTime
2092 (NULL, &currTime, plContext),
2093 PKIX_DATECREATEUTCTIMEFAILED);
2094
2095 PKIX_CHECK(PKIX_PL_Object_Compare
2096 ((PKIX_PL_Object *)state->buildConstants.timeLimit,
2097 (PKIX_PL_Object *)currTime,
2098 &cmpTimeResult,
2099 plContext),
2100 PKIX_OBJECTCOMPARATORFAILED);
2101
2102 if (cmpTimeResult < 0) {
2103 if (state->verifyNode != NULL) {
2104 PKIX_ERROR_CREATE
2105 (BUILD,
2106 PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS,
2107 verifyError);
2108 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
2109 (state->verifyNode,
2110 verifyError,
2111 plContext),
2112 PKIX_VERIFYNODESETERRORFAILED);
2113 PKIX_DECREF(finalError);
2114 finalError = verifyError;
2115 verifyError = NULL;
2116 }
2117 /* Even if we logged error, we still have to abort */
2118 PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS);
2119 }
2120 }
2121
2122 if (state->status == BUILD_INITIAL) {
2123
2124 PKIX_CHECK(pkix_Build_BuildSelectorAndParams(state, plContext),
2125 PKIX_BUILDBUILDSELECTORANDPARAMSFAILED);
2126
2127 /*
2128 * If the caller supplied a partial certChain (hintCerts) try
2129 * the next one from that List before we go to the certStores.
2130 */
2131 if (state->buildConstants.numHintCerts > 0) {
2132 /* How many Certs does our trust chain have already? */
2133 PKIX_CHECK(PKIX_List_GetLength
2134 (state->trustChain, &certsSoFar, plContext),
2135 PKIX_LISTGETLENGTHFAILED);
2136
2137 /* That includes the target Cert. Don't count it. */
2138 certsSoFar--;
2139
2140 /* Are we still within range of the partial chain? */
2141 if (certsSoFar >= state->buildConstants.numHintCerts) {
2142 state->status = BUILD_TRYAIA;
2143 } else {
2144 /*
2145 * If we already have n certs, we want the n+1th
2146 * (i.e., index = n) from the list of hints.
2147 */
2148 PKIX_DECREF(state->candidateCert);
2149 PKIX_CHECK(PKIX_List_GetItem
2150 (state->buildConstants.hintCerts,
2151 certsSoFar,
2152 (PKIX_PL_Object **)&state->candidateCert,
2153 plContext),
2154 PKIX_LISTGETITEMFAILED);
2155
2156 PKIX_CHECK(PKIX_List_AppendItem
2157 (state->candidateCerts,
2158 (PKIX_PL_Object *)state->candidateCert,
2159 plContext),
2160 PKIX_LISTAPPENDITEMFAILED);
2161
2162 state->numCerts = 1;
2163 state->usingHintCerts = PKIX_TRUE;
2164 state->status = BUILD_CERTVALIDATING;
2165 }
2166 } else {
2167 state->status = BUILD_TRYAIA;
2168 }
2169
2170 }
2171
2172 if (state->status == BUILD_TRYAIA) {
2173 if (state->useOnlyLocal == PKIX_TRUE) {
2174 state->status = BUILD_COLLECTINGCERTS;
2175 } else {
2176 state->status = BUILD_AIAPENDING;
2177 }
2178 }
2179
2180 if (state->status == BUILD_AIAPENDING &&
2181 state->buildConstants.aiaMgr) {
2182 pkixErrorResult = PKIX_PL_AIAMgr_GetAIACerts
2183 (state->buildConstants.aiaMgr,
2184 state->prevCert,
2185 &nbio,
2186 &unfilteredCerts,
2187 plContext);
2188
2189 if (nbio != NULL) {
2190 /* IO still pending, resume later */
2191 *pNBIOContext = nbio;
2192 goto cleanup;
2193 }
2194 state->numCerts = 0;
2195 if (pkixErrorResult) {
2196 pkixErrorClass = pkixErrorResult->errClass;
2197 if (pkixErrorClass == PKIX_FATAL_ERROR) {
2198 goto fatal;
2199 }
2200 PKIX_DECREF(finalError);
2201 finalError = pkixErrorResult;
2202 pkixErrorResult = NULL;
2203 if (state->verifyNode != NULL) {
2204 /* state->verifyNode is the object that contains a list
2205 * of verifyNodes. verifyNodes contains cert chain
2206 * build failures that occurred on this level of chain
2207 * building. Here, creating new verify node
2208 * to log the failure and adding it to the list. */
2209 PKIX_CHECK_FATAL(pkix_VerifyNode_Create
2210 (state->prevCert,
2211 0, NULL,
2212 &verifyNode,
2213 plContext),
2214 PKIX_VERIFYNODECREATEFAILED);
2215 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
2216 (verifyNode, finalError, plContext),
2217 PKIX_VERIFYNODESETERRORFAILED);
2218 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2219 (state->verifyNode,
2220 verifyNode,
2221 plContext),
2222 PKIX_VERIFYNODEADDTOTREEFAILED);
2223 PKIX_DECREF(verifyNode);
2224 }
2225 }
2226 #ifdef PKIX_BUILDDEBUG
2227 /* Turn this on to trace the List of Certs, before CertSelect */
2228 {
2229 PKIX_PL_String *unString;
2230 char *unAscii;
2231 PKIX_UInt32 length;
2232 PKIX_TOSTRING
2233 ((PKIX_PL_Object*)unfilteredCerts,
2234 &unString,
2235 plContext,
2236 PKIX_OBJECTTOSTRINGFAILED);
2237
2238 PKIX_CHECK(PKIX_PL_String_GetEncoded
2239 (unString,
2240 PKIX_ESCASCII,
2241 (void **)&unAscii,
2242 &length,
2243 plContext),
2244 PKIX_STRINGGETENCODEDFAILED);
2245
2246 PKIX_DEBUG_ARG
2247 ("unfilteredCerts = %s\n", unAscii);
2248 PKIX_DECREF(unString);
2249 PKIX_FREE(unAscii);
2250 }
2251 #endif
2252
2253 /* Note: Certs winnowed here don't get into VerifyTree. */
2254 if (unfilteredCerts) {
2255 PKIX_CHECK(pkix_CertSelector_Select
2256 (state->certSel,
2257 unfilteredCerts,
2258 &filteredCerts,
2259 plContext),
2260 PKIX_CERTSELECTORSELECTFAILED);
2261
2262 PKIX_DECREF(unfilteredCerts);
2263
2264 PKIX_CHECK(PKIX_List_GetLength
2265 (filteredCerts, &(state->numCerts), plContext),
2266 PKIX_LISTGETLENGTHFAILED);
2267
2268 #ifdef PKIX_BUILDDEBUG
2269 /* Turn this on to trace the List of Certs, after CertSelect */
2270 {
2271 PKIX_PL_String *unString;
2272 char *unAscii;
2273 PKIX_UInt32 length;
2274 PKIX_TOSTRING
2275 ((PKIX_PL_Object*)filteredCerts,
2276 &unString,
2277 plContext,
2278 PKIX_OBJECTTOSTRINGFAILED);
2279
2280 PKIX_CHECK(PKIX_PL_String_GetEncoded
2281 (unString,
2282 PKIX_ESCASCII,
2283 (void **)&unAscii,
2284 &length,
2285 plContext),
2286 PKIX_STRINGGETENCODEDFAILED);
2287
2288 PKIX_DEBUG_ARG("filteredCerts = %s\n", unAscii);
2289 PKIX_DECREF(unString);
2290 PKIX_FREE(unAscii);
2291 }
2292 #endif
2293
2294 PKIX_DECREF(state->candidateCerts);
2295 state->candidateCerts = filteredCerts;
2296 state->certIndex = 0;
2297 filteredCerts = NULL;
2298 }
2299
2300 /* Are there any Certs to try? */
2301 if (state->numCerts > 0) {
2302 state->status = BUILD_CERTVALIDATING;
2303 } else {
2304 state->status = BUILD_COLLECTINGCERTS;
2305 }
2306 }
2307
2308 PKIX_DECREF(certSelParams);
2309 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
2310 (state->certSel, &certSelParams, plContext),
2311 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
2312
2313 /* **** Querying the CertStores ***** */
2314 if ((state->status == BUILD_COLLECTINGCERTS) ||
2315 (state->status == BUILD_GATHERPENDING)) {
2316
2317 #if PKIX_FORWARDBUILDERSTATEDEBUG
2318 PKIX_CHECK(pkix_ForwardBuilderState_DumpState
2319 (state, plContext),
2320 PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED);
2321 #endif
2322
2323 PKIX_CHECK(pkix_Build_GatherCerts
2324 (state, certSelParams, &nbio, plContext),
2325 PKIX_BUILDGATHERCERTSFAILED);
2326
2327 if (nbio != NULL) {
2328 /* IO still pending, resume later */
2329 *pNBIOContext = nbio;
2330 goto cleanup;
2331 }
2332
2333 /* Are there any Certs to try? */
2334 if (state->numCerts > 0) {
2335 state->status = BUILD_CERTVALIDATING;
2336 } else {
2337 state->status = BUILD_ABANDONNODE;
2338 }
2339 }
2340
2341 /* ****Phase 2 - Chain building***** */
2342
2343 #if PKIX_FORWARDBUILDERSTATEDEBUG
2344 PKIX_CHECK(pkix_ForwardBuilderState_DumpState(state, plContext),
2345 PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED);
2346 #endif
2347
2348 if (state->status == BUILD_CERTVALIDATING) {
2349 PKIX_DECREF(state->candidateCert);
2350 PKIX_CHECK(PKIX_List_GetItem
2351 (state->candidateCerts,
2352 state->certIndex,
2353 (PKIX_PL_Object **)&(state->candidateCert),
2354 plContext),
2355 PKIX_LISTGETITEMFAILED);
2356
2357 if ((state->verifyNode) != NULL) {
2358 PKIX_CHECK_FATAL(pkix_VerifyNode_Create
2359 (state->candidateCert,
2360 0,
2361 NULL,
2362 &verifyNode,
2363 plContext),
2364 PKIX_VERIFYNODECREATEFAILED);
2365 }
2366
2367 /* If failure, this function sets Error in verifyNode */
2368 verifyError = pkix_Build_VerifyCertificate
2369 (state,
2370 state->buildConstants.userCheckers,
2371 &trusted,
2372 verifyNode,
2373 plContext);
2374
2375 if (verifyError) {
2376 pkixTempErrorReceived = PKIX_TRUE;
2377 pkixErrorClass = verifyError->errClass;
2378 if (pkixErrorClass == PKIX_FATAL_ERROR) {
2379 pkixErrorResult = verifyError;
2380 verifyError = NULL;
2381 goto fatal;
2382 }
2383 }
2384
2385 if (PKIX_ERROR_RECEIVED) {
2386 if (state->verifyNode != NULL) {
2387 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
2388 (verifyNode, verifyError, plContext),
2389 PKIX_VERIFYNODESETERRORFAILED);
2390 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2391 (state->verifyNode,
2392 verifyNode,
2393 plContext),
2394 PKIX_VERIFYNODEADDTOTREEFAILED);
2395 PKIX_DECREF(verifyNode);
2396 }
2397 pkixTempErrorReceived = PKIX_FALSE;
2398 PKIX_DECREF(finalError);
2399 finalError = verifyError;
2400 verifyError = NULL;
2401 if (state->certLoopingDetected) {
2402 PKIX_ERROR
2403 (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED);
2404 }
2405 state->status = BUILD_GETNEXTCERT;
2406 } else {
2407 state->status = BUILD_DATEPREP;
2408 }
2409 }
2410
2411 if (state->status == BUILD_DATEPREP) {
2412 /* Keep track of whether this chain can be cached */
2413 PKIX_CHECK(pkix_Build_UpdateDate(state, plContext),
2414 PKIX_BUILDUPDATEDATEFAILED);
2415
2416 canBeCached = state->canBeCached;
2417 PKIX_DECREF(validityDate);
2418 PKIX_INCREF(state->validityDate);
2419 validityDate = state->validityDate;
2420 if (trusted == PKIX_TRUE) {
2421 state->status = BUILD_CHECKTRUSTED;
2422 } else {
2423 state->status = BUILD_ADDTOCHAIN;
2424 }
2425 }
2426
2427 if (state->status == BUILD_CHECKTRUSTED) {
2428
2429 /*
2430 * If this cert is trusted, try to validate the entire
2431 * chain using this certificate as trust anchor.
2432 */
2433 PKIX_CHECK(PKIX_TrustAnchor_CreateWithCert
2434 (state->candidateCert,
2435 &trustAnchor,
2436 plContext),
2437 PKIX_TRUSTANCHORCREATEWITHCERTFAILED);
2438
2439 PKIX_CHECK(pkix_Build_ValidationCheckers
2440 (state,
2441 state->trustChain,
2442 trustAnchor,
2443 PKIX_FALSE, /* do not add eku checker
2444 * since eku was already
2445 * checked */
2446 plContext),
2447 PKIX_BUILDVALIDATIONCHECKERSFAILED);
2448
2449 state->status = BUILD_CHECKTRUSTED2;
2450 }
2451
2452 if (state->status == BUILD_CHECKTRUSTED2) {
2453 verifyError =
2454 pkix_Build_ValidateEntireChain(state,
2455 trustAnchor,
2456 &nbio, &valResult,
2457 verifyNode,
2458 plContext);
2459 if (nbio != NULL) {
2460 /* IO still pending, resume later */
2461 goto cleanup;
2462 } else {
2463 /* checking the error for fatal status */
2464 if (verifyError) {
2465 pkixTempErrorReceived = PKIX_TRUE;
2466 pkixErrorClass = verifyError->errClass;
2467 if (pkixErrorClass == PKIX_FATAL_ERROR) {
2468 pkixErrorResult = verifyError;
2469 verifyError = NULL;
2470 goto fatal;
2471 }
2472 }
2473 if (state->verifyNode != NULL) {
2474 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2475 (state->verifyNode,
2476 verifyNode,
2477 plContext),
2478 PKIX_VERIFYNODEADDTOTREEFAILED);
2479 PKIX_DECREF(verifyNode);
2480 }
2481 if (!PKIX_ERROR_RECEIVED) {
2482 *pValResult = valResult;
2483 valResult = NULL;
2484 /* Change state so IsIOPending is FALSE */
2485 state->status = BUILD_CHECKTRUSTED;
2486 goto cleanup;
2487 }
2488 PKIX_DECREF(finalError);
2489 finalError = verifyError;
2490 verifyError = NULL;
2491 /* Reset temp error that was set by
2492 * PKIX_CHECK_ONLY_FATAL and continue */
2493 pkixTempErrorReceived = PKIX_FALSE;
2494 PKIX_DECREF(trustAnchor);
2495 }
2496
2497 /*
2498 * If chain doesn't validate with a trusted Cert,
2499 * adding more Certs to it can't help.
2500 */
2501 if (state->certLoopingDetected) {
2502 PKIX_DECREF(verifyError);
2503 PKIX_ERROR_CREATE(BUILD,
2504 PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED,
2505 verifyError);
2506 PKIX_CHECK_FATAL(
2507 pkix_VerifyNode_SetError(state->verifyNode,
2508 verifyError,
2509 plContext),
2510 PKIX_VERIFYNODESETERRORFAILED);
2511 PKIX_DECREF(verifyError);
2512 }
2513 state->status = BUILD_GETNEXTCERT;
2514 }
2515
2516 /*
2517 * This Cert was not trusted. Add it to our chain, and
2518 * continue building. If we don't reach a trust anchor,
2519 * we'll take it off later and continue without it.
2520 */
2521 if (state->status == BUILD_ADDTOCHAIN) {
2522 PKIX_CHECK(PKIX_List_AppendItem
2523 (state->trustChain,
2524 (PKIX_PL_Object *)state->candidateCert,
2525 plContext),
2526 PKIX_LISTAPPENDITEMFAILED);
2527
2528 state->status = BUILD_EXTENDCHAIN;
2529 }
2530
2531 if (state->status == BUILD_EXTENDCHAIN) {
2532
2533 /* Check whether we are allowed to extend the chain */
2534 if ((state->buildConstants.maxDepth != 0) &&
2535 (state->numDepth <= 1)) {
2536
2537 if (state->verifyNode != NULL) {
2538 PKIX_ERROR_CREATE
2539 (BUILD,
2540 PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS,
2541 verifyError);
2542 PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
2543 (verifyNode, verifyError, plContext),
2544 PKIX_VERIFYNODESETERRORFAILED);
2545 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2546 (state->verifyNode, verifyNode, plContext),
2547 PKIX_VERIFYNODEADDTOTREEFAILED);
2548 PKIX_DECREF(verifyNode);
2549 PKIX_DECREF(finalError);
2550 finalError = verifyError;
2551 verifyError = NULL;
2552 }
2553 /* Even if error logged, still need to abort */
2554 PKIX_ERROR(PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS);
2555 }
2556
2557 PKIX_CHECK(pkix_IsCertSelfIssued
2558 (state->candidateCert, &isSelfIssued, plContext),
2559 PKIX_ISCERTSELFISSUEDFAILED);
2560
2561 PKIX_CHECK(PKIX_PL_Object_Duplicate
2562 ((PKIX_PL_Object *)state->traversedSubjNames,
2563 (PKIX_PL_Object **)&childTraversedSubjNames,
2564 plContext),
2565 PKIX_OBJECTDUPLICATEFAILED);
2566
2567 if (isSelfIssued) {
2568 childTraversedCACerts = state->traversedCACerts;
2569 } else {
2570 childTraversedCACerts = state->traversedCACerts + 1;
2571
2572 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
2573 (state->candidateCert,
2574 &subjectNames,
2575 plContext),
2576 PKIX_CERTGETALLSUBJECTNAMESFAILED);
2577
2578 if (subjectNames) {
2579 PKIX_CHECK(PKIX_List_GetLength
2580 (subjectNames,
2581 &numSubjectNames,
2582 plContext),
2583 PKIX_LISTGETLENGTHFAILED);
2584
2585 } else {
2586 numSubjectNames = 0;
2587 }
2588
2589 for (i = 0; i < numSubjectNames; i++) {
2590 PKIX_CHECK(PKIX_List_GetItem
2591 (subjectNames,
2592 i,
2593 &subjectName,
2594 plContext),
2595 PKIX_LISTGETITEMFAILED);
2596 PKIX_NULLCHECK_ONE
2597 (state->traversedSubjNames);
2598 PKIX_CHECK(PKIX_List_AppendItem
2599 (state->traversedSubjNames,
2600 subjectName,
2601 plContext),
2602 PKIX_LISTAPPENDITEMFAILED);
2603 PKIX_DECREF(subjectName);
2604 }
2605 PKIX_DECREF(subjectNames);
2606 }
2607
2608 PKIX_CHECK(pkix_ForwardBuilderState_Create
2609 (childTraversedCACerts,
2610 state->buildConstants.maxFanout,
2611 state->numDepth - 1,
2612 canBeCached,
2613 validityDate,
2614 state->candidateCert,
2615 childTraversedSubjNames,
2616 state->trustChain,
2617 state,
2618 &childState,
2619 plContext),
2620 PKIX_FORWARDBUILDSTATECREATEFAILED);
2621
2622 PKIX_DECREF(childTraversedSubjNames);
2623 PKIX_DECREF(certSelParams);
2624 childState->verifyNode = verifyNode;
2625 verifyNode = NULL;
2626 PKIX_DECREF(state);
2627 state = childState; /* state->status == BUILD_INITIAL */
2628 childState = NULL;
2629 continue; /* with while (!outOfOptions) */
2630 }
2631
2632 if (state->status == BUILD_GETNEXTCERT) {
2633 pkixTempErrorReceived = PKIX_FALSE;
2634 PKIX_DECREF(state->candidateCert);
2635
2636 /*
2637 * If we were using a Cert from the callier-supplied partial
2638 * chain, delete it and go to the certStores.
2639 */
2640 if (state->usingHintCerts == PKIX_TRUE) {
2641 PKIX_DECREF(state->candidateCerts);
2642 PKIX_CHECK(PKIX_List_Create
2643 (&state->candidateCerts, plContext),
2644 PKIX_LISTCREATEFAILED);
2645
2646 state->numCerts = 0;
2647 state->usingHintCerts = PKIX_FALSE;
2648 state->status = BUILD_TRYAIA;
2649 continue;
2650 } else if (++(state->certIndex) < (state->numCerts)) {
2651 if ((state->buildConstants.maxFanout != 0) &&
2652 (--(state->numFanout) == 0)) {
2653
2654 if (state->verifyNode != NULL) {
2655 PKIX_ERROR_CREATE
2656 (BUILD,
2657 PKIX_FANOUTEXCEEDSRESOURCELIMITS,
2658 verifyError);
2659 PKIX_CHECK_FATAL
2660 (pkix_VerifyNode_SetError
2661 (state->verifyNode,
2662 verifyError,
2663 plContext),
2664 PKIX_VERIFYNODESETERRORFAILED);
2665 PKIX_DECREF(finalError);
2666 finalError = verifyError;
2667 verifyError = NULL;
2668 }
2669 /* Even if error logged, still need to abort */
2670 PKIX_ERROR
2671 (PKIX_FANOUTEXCEEDSRESOURCELIMITS);
2672 }
2673 state->status = BUILD_CERTVALIDATING;
2674 continue;
2675 }
2676 }
2677
2678 /*
2679 * Adding the current cert to the chain didn't help. If our search
2680 * has been restricted to local certStores, try opening up the
2681 * search and see whether that helps. Otherwise, back up to the
2682 * parent cert, and see if there are any more to try.
2683 */
2684 if (state->useOnlyLocal == PKIX_TRUE) {
2685 pkix_PrepareForwardBuilderStateForAIA(state);
2686 } else do {
2687 if (state->parentState == NULL) {
2688 /* We are at the top level, and can't back up! */
2689 outOfOptions = PKIX_TRUE;
2690 } else {
2691 /*
2692 * Try the next cert, if any, for this parent.
2693 * Otherwise keep backing up until we reach a
2694 * parent with more certs to try.
2695 */
2696 PKIX_CHECK(PKIX_List_GetLength
2697 (state->trustChain, &numChained, plContext),
2698 PKIX_LISTGETLENGTHFAILED);
2699 PKIX_CHECK(PKIX_List_DeleteItem
2700 (state->trustChain, numChained - 1, plContext),
2701 PKIX_LISTDELETEITEMFAILED);
2702
2703 /* local and aia fetching returned no good certs.
2704 * Creating a verify node in the parent that tells
2705 * us this. */
2706 if (!state->verifyNode) {
2707 PKIX_CHECK_FATAL(
2708 pkix_VerifyNode_Create(state->prevCert,
2709 0, NULL,
2710 &state->verifyNode,
2711 plContext),
2712 PKIX_VERIFYNODECREATEFAILED);
2713 }
2714 /* Updating the log with the error. */
2715 PKIX_DECREF(verifyError);
2716 PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER,
2717 verifyError);
2718 PKIX_CHECK_FATAL(
2719 pkix_VerifyNode_SetError(state->verifyNode,
2720 verifyError,
2721 plContext),
2722 PKIX_VERIFYNODESETERRORFAILED);
2723 PKIX_DECREF(verifyError);
2724
2725 PKIX_INCREF(state->parentState);
2726 parentState = state->parentState;
2727 PKIX_DECREF(verifyNode);
2728 verifyNode = state->verifyNode;
2729 state->verifyNode = NULL;
2730 PKIX_DECREF(state);
2731 state = parentState;
2732 parentState = NULL;
2733 if (state->verifyNode != NULL && verifyNode) {
2734 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2735 (state->verifyNode,
2736 verifyNode,
2737 plContext),
2738 PKIX_VERIFYNODEADDTOTREEFAILED);
2739 PKIX_DECREF(verifyNode);
2740 }
2741 PKIX_DECREF(validityDate);
2742 PKIX_INCREF(state->validityDate);
2743 validityDate = state->validityDate;
2744 canBeCached = state->canBeCached;
2745
2746 /* Are there any more Certs to try? */
2747 if (++(state->certIndex) < (state->numCerts)) {
2748 state->status = BUILD_CERTVALIDATING;
2749 PKIX_DECREF(state->candidateCert);
2750 break;
2751 }
2752 if (state->useOnlyLocal == PKIX_TRUE) {
2753 /* Clean up and go for AIA round. */
2754 pkix_PrepareForwardBuilderStateForAIA(state);
2755 break;
2756 }
2757 }
2758 PKIX_DECREF(state->candidateCert);
2759 } while (outOfOptions == PKIX_FALSE);
2760
2761 } /* while (outOfOptions == PKIX_FALSE) */
2762
2763 cleanup:
2764
2765 if (pkixErrorClass == PKIX_FATAL_ERROR) {
2766 goto fatal;
2767 }
2768
2769 /* verifyNode should be equal to NULL at this point. Assert it.
2770 * Temporarelly use verifyError to store an error ref to which we
2771 * have in pkixErrorResult. This is done to prevent error cloberring
2772 * while using macros below. */
2773 PORT_Assert(verifyError == NULL);
2774 verifyError = pkixErrorResult;
2775
2776 /*
2777 * We were called with an initialState that had no parent. If we are
2778 * returning with an error or with a result, we must destroy any state
2779 * that we created (any state with a parent).
2780 */
2781
2782 PKIX_CHECK_FATAL(pkix_ForwardBuilderState_IsIOPending
2783 (state, &ioPending, plContext),
2784 PKIX_FORWARDBUILDERSTATEISIOPENDINGFAILED);
2785
2786 if (ioPending == PKIX_FALSE) {
2787 while (state->parentState) {
2788 PKIX_INCREF(state->parentState);
2789 parentState = state->parentState;
2790 PKIX_DECREF(verifyNode);
2791 verifyNode = state->verifyNode;
2792 state->verifyNode = NULL;
2793 PKIX_DECREF(state);
2794 state = parentState;
2795 parentState = NULL;
2796 if (state->verifyNode != NULL && verifyNode) {
2797 PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
2798 (state->verifyNode,
2799 verifyNode,
2800 plContext),
2801 PKIX_VERIFYNODEADDTOTREEFAILED);
2802 PKIX_DECREF(verifyNode);
2803 }
2804 }
2805 state->canBeCached = canBeCached;
2806 PKIX_DECREF(state->validityDate);
2807 state->validityDate = validityDate;
2808 validityDate = NULL;
2809 }
2810 if (!*pValResult && !verifyError) {
2811 if (!finalError) {
2812 PKIX_CHECK_FATAL(
2813 pkix_VerifyNode_FindError(state->verifyNode,
2814 &finalError,
2815 plContext),
2816 PKIX_VERIFYNODEFINDERRORFAILED);
2817 }
2818 if (finalError) {
2819 pkixErrorResult = finalError;
2820 pkixErrorCode = PKIX_BUILDFORWARDDEPTHFIRSTSEARCHFAILED;
2821 finalError = NULL;
2822 goto fatal;
2823 }
2824 pkixErrorCode = PKIX_SECERRORUNKNOWNISSUER;
2825 pkixErrorReceived = PKIX_TRUE;
2826 PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER,
2827 verifyError);
2828 PKIX_CHECK_FATAL(
2829 pkix_VerifyNode_SetError(state->verifyNode, verifyError,
2830 plContext),
2831 PKIX_VERIFYNODESETERRORFAILED);
2832 } else {
2833 pkixErrorResult = verifyError;
2834 verifyError = NULL;
2835 }
2836
2837 fatal:
2838 if (state->parentState) {
2839 /* parentState in "state" object should be NULL at this point.
2840 * If itn't, that means that we got fatal error(we have jumped to
2841 * "fatal" label) and we should destroy all state except the top one . */
2842 while (state->parentState) {
2843 PKIX_Error *error = NULL;
2844 PKIX_ForwardBuilderState *prntState = state->parentState;
2845 /* Dumb: need to increment parentState to avoid destruction
2846 * of "build constants"(they get destroyed when parentState is
2847 * set to NULL. */
2848 PKIX_INCREF(prntState);
2849 error = PKIX_PL_Object_DecRef((PKIX_PL_Object*)state, plContext) ;
2850 if (error) {
2851 PKIX_PL_Object_DecRef((PKIX_PL_Object*)error, plContext);
2852 }
2853 /* No need to decref the parent state. It was already done by
2854 * pkix_ForwardBuilderState_Destroy function. */
2855 state = prntState;
2856 }
2857 }
2858 PKIX_DECREF(parentState);
2859 PKIX_DECREF(childState);
2860 PKIX_DECREF(valResult);
2861 PKIX_DECREF(verifyError);
2862 PKIX_DECREF(finalError);
2863 PKIX_DECREF(verifyNode);
2864 PKIX_DECREF(childTraversedSubjNames);
2865 PKIX_DECREF(certSelParams);
2866 PKIX_DECREF(subjectNames);
2867 PKIX_DECREF(subjectName);
2868 PKIX_DECREF(trustAnchor);
2869 PKIX_DECREF(validityDate);
2870 PKIX_DECREF(revCheckerState);
2871 PKIX_DECREF(currTime);
2872 PKIX_DECREF(filteredCerts);
2873 PKIX_DECREF(unfilteredCerts);
2874 PKIX_DECREF(trustedCert);
2875
2876 PKIX_RETURN(BUILD);
2877 }
2878
2879 /*
2880 * FUNCTION: pkix_Build_CheckInCache
2881 * DESCRIPTION:
2882 *
2883 * The function tries to locate a chain for a cert in the cert chain cache.
2884 * If found, the chain goes through revocation chacking and returned back to
2885 * caller. Chains that fail revocation check get removed from cache.
2886 *
2887 * PARAMETERS:
2888 * "state"
2889 * Address of ForwardBuilderState to be used. Must be non-NULL.
2890 * "pBuildResult"
2891 * Address at which the BuildResult is stored, after a successful build.
2892 * Must be non-NULL.
2893 * "pNBIOContext"
2894 * Address at which the NBIOContext is stored indicating whether the
2895 * validation is complete. Must be non-NULL.
2896 * "plContext"
2897 * Platform-specific context pointer.
2898 * THREAD SAFETY:
2899 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2900 * RETURNS:
2901 * Returns NULL if the function succeeds.
2902 * Returns a Build Error if the function fails in a non-fatal way
2903 * Returns a Fatal Error if the function fails in an unrecoverable way.
2904 */
2905 static PKIX_Error*
2906 pkix_Build_CheckInCache(
2907 PKIX_ForwardBuilderState *state,
2908 PKIX_BuildResult **pBuildResult,
2909 void **pNBIOContext,
2910 void *plContext)
2911 {
2912 PKIX_PL_Cert *targetCert = NULL;
2913 PKIX_List *anchors = NULL;
2914 PKIX_PL_Date *testDate = NULL;
2915 PKIX_BuildResult *buildResult = NULL;
2916 PKIX_ValidateResult *valResult = NULL;
2917 PKIX_Error *buildError = NULL;
2918 PKIX_TrustAnchor *matchingAnchor = NULL;
2919 PKIX_PL_Cert *trustedCert = NULL;
2920 PKIX_List *certList = NULL;
2921 PKIX_Boolean cacheHit = PKIX_FALSE;
2922 PKIX_Boolean trusted = PKIX_FALSE;
2923 PKIX_Boolean stillValid = PKIX_FALSE;
2924 void *nbioContext = NULL;
2925
2926 PKIX_ENTER(BUILD, "pkix_Build_CheckInCache");
2927
2928 nbioContext = *pNBIOContext;
2929 *pNBIOContext = NULL;
2930
2931 targetCert = state->buildConstants.targetCert;
2932 anchors = state->buildConstants.anchors;
2933 testDate = state->buildConstants.testDate;
2934
2935 /* Check whether this cert verification has been cached. */
2936 PKIX_CHECK(pkix_CacheCertChain_Lookup
2937 (targetCert,
2938 anchors,
2939 testDate,
2940 &cacheHit,
2941 &buildResult,
2942 plContext),
2943 PKIX_CACHECERTCHAINLOOKUPFAILED);
2944
2945 if (!cacheHit) {
2946 goto cleanup;
2947 }
2948
2949 /*
2950 * We found something in cache. Verify that the anchor
2951 * cert is still trusted,
2952 */
2953 PKIX_CHECK(PKIX_BuildResult_GetValidateResult
2954 (buildResult, &valResult, plContext),
2955 PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
2956
2957 PKIX_CHECK(PKIX_ValidateResult_GetTrustAnchor
2958 (valResult, &matchingAnchor, plContext),
2959 PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
2960
2961 PKIX_DECREF(valResult);
2962
2963 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
2964 (matchingAnchor, &trustedCert, plContext),
2965 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
2966
2967 if (anchors && state->buildConstants.numAnchors) {
2968 /* Check if it is one of the trust anchors */
2969 PKIX_CHECK(
2970 pkix_List_Contains(anchors,
2971 (PKIX_PL_Object *)matchingAnchor,
2972 &trusted,
2973 plContext),
2974 PKIX_LISTCONTAINSFAILED);
2975 }
2976
2977 if ((!trusted && !state->buildConstants.trustOnlyUserAnchors) ||
2978 !state->buildConstants.numAnchors) {
2979 /* If it is not one of the trust anchors and the trust anchors
2980 * are supplemental, or if there are no trust anchors, then check
2981 * if the cert is trusted directly.
2982 */
2983 PKIX_CHECK(
2984 PKIX_PL_Cert_IsCertTrusted(trustedCert,
2985 PKIX_PL_TrustAnchorMode_Ignore,
2986 &trusted, plContext),
2987 PKIX_CERTISCERTTRUSTEDFAILED);
2988 }
2989
2990 if (!trusted) {
2991 goto cleanup;
2992 }
2993 /*
2994 * Since the key usage may vary for different
2995 * applications, we need to verify the chain again.
2996 * Reverification will be improved with a fix for 397805.
2997 */
2998 PKIX_CHECK(PKIX_BuildResult_GetCertChain
2999 (buildResult, &certList, plContext),
3000 PKIX_BUILDRESULTGETCERTCHAINFAILED);
3001
3002 PKIX_CHECK(pkix_Build_ValidationCheckers
3003 (state,
3004 certList,
3005 matchingAnchor,
3006 PKIX_TRUE, /* Chain revalidation stage. */
3007 plContext),
3008 PKIX_BUILDVALIDATIONCHECKERSFAILED);
3009
3010 PKIX_CHECK_ONLY_FATAL(
3011 pkix_Build_ValidateEntireChain(state, matchingAnchor,
3012 &nbioContext, &valResult,
3013 state->verifyNode, plContext),
3014 PKIX_BUILDVALIDATEENTIRECHAINFAILED);
3015
3016 if (nbioContext != NULL) {
3017 /* IO still pending, resume later */
3018 *pNBIOContext = nbioContext;
3019 goto cleanup;
3020 }
3021 if (!PKIX_ERROR_RECEIVED) {
3022 /* The result from cache is still valid. But we replace an old*/
3023 *pBuildResult = buildResult;
3024 buildResult = NULL;
3025 stillValid = PKIX_TRUE;
3026 }
3027
3028 cleanup:
3029
3030 if (!nbioContext && cacheHit && !(trusted && stillValid)) {
3031 /* The anchor of this chain is no longer trusted or
3032 * chain cert(s) has been revoked.
3033 * Invalidate this result in the cache */
3034 buildError = pkixErrorResult;
3035 PKIX_CHECK_FATAL(pkix_CacheCertChain_Remove
3036 (targetCert,
3037 anchors,
3038 plContext),
3039 PKIX_CACHECERTCHAINREMOVEFAILED);
3040 pkixErrorResult = buildError;
3041 buildError = NULL;
3042 }
3043
3044 fatal:
3045 PKIX_DECREF(buildResult);
3046 PKIX_DECREF(valResult);
3047 PKIX_DECREF(buildError);
3048 PKIX_DECREF(certList);
3049 PKIX_DECREF(matchingAnchor);
3050 PKIX_DECREF(trustedCert);
3051
3052
3053 PKIX_RETURN(BUILD);
3054 }
3055
3056 /*
3057 * FUNCTION: pkix_Build_InitiateBuildChain
3058 * DESCRIPTION:
3059 *
3060 * This function initiates the search for a BuildChain, using the parameters
3061 * provided in "procParams" and, if continuing a search that was suspended
3062 * for I/O, using the ForwardBuilderState pointed to by "pState".
3063 *
3064 * If a successful chain is built, this function stores the BuildResult at
3065 * "pBuildResult". Alternatively, if an operation using non-blocking I/O
3066 * is in progress and the operation has not been completed, this function
3067 * stores the platform-dependent non-blocking I/O context (nbioContext) at
3068 * "pNBIOContext", the FowardBuilderState at "pState", and NULL at
3069 * "pBuildResult". Finally, if chain building was unsuccessful, this function
3070 * stores NULL at both "pState" and at "pBuildResult".
3071 *
3072 * Note: This function is re-entered only for the case of non-blocking I/O
3073 * in the "short-cut" attempt to build a chain using the target Certificate
3074 * directly with one of the trustAnchors. For all other cases, resumption
3075 * after non-blocking I/O is via pkix_Build_ResumeBuildChain.
3076 *
3077 * PARAMETERS:
3078 * "procParams"
3079 * Address of the ProcessingParams for the search. Must be non-NULL.
3080 * "pNBIOContext"
3081 * Address at which the NBIOContext is stored indicating whether the
3082 * validation is complete. Must be non-NULL.
3083 * "pState"
3084 * Address at which the ForwardBuilderState is stored, if the chain
3085 * building is suspended for waiting I/O; also, the address at which the
3086 * ForwardBuilderState is provided for resumption of the chain building
3087 * attempt. Must be non-NULL.
3088 * "pBuildResult"
3089 * Address at which the BuildResult is stored, after a successful build.
3090 * Must be non-NULL.
3091 * "pVerifyNode"
3092 * Address at which a VerifyNode chain is returned, if non-NULL.
3093 * "plContext"
3094 * Platform-specific context pointer.
3095 * THREAD SAFETY:
3096 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
3097 * RETURNS:
3098 * Returns NULL if the function succeeds.
3099 * Returns a Build Error if the function fails in a non-fatal way
3100 * Returns a Fatal Error if the function fails in an unrecoverable way.
3101 */
3102 static PKIX_Error *
3103 pkix_Build_InitiateBuildChain(
3104 PKIX_ProcessingParams *procParams,
3105 void **pNBIOContext,
3106 PKIX_ForwardBuilderState **pState,
3107 PKIX_BuildResult **pBuildResult,
3108 PKIX_VerifyNode **pVerifyNode,
3109 void *plContext)
3110 {
3111 PKIX_UInt32 numAnchors = 0;
3112 PKIX_UInt32 numCertStores = 0;
3113 PKIX_UInt32 numHintCerts = 0;
3114 PKIX_UInt32 i = 0;
3115 PKIX_Boolean isDuplicate = PKIX_FALSE;
3116 PKIX_PL_Cert *trustedCert = NULL;
3117 PKIX_CertSelector *targetConstraints = NULL;
3118 PKIX_ComCertSelParams *targetParams = NULL;
3119 PKIX_List *anchors = NULL;
3120 PKIX_List *targetSubjNames = NULL;
3121 PKIX_PL_Cert *targetCert = NULL;
3122 PKIX_PL_Object *firstHintCert = NULL;
3123 PKIX_RevocationChecker *revChecker = NULL;
3124 PKIX_List *certStores = NULL;
3125 PKIX_CertStore *certStore = NULL;
3126 PKIX_List *userCheckers = NULL;
3127 PKIX_List *hintCerts = NULL;
3128 PKIX_PL_Date *testDate = NULL;
3129 PKIX_PL_PublicKey *targetPubKey = NULL;
3130 void *nbioContext = NULL;
3131 BuildConstants buildConstants;
3132
3133 PKIX_List *tentativeChain = NULL;
3134 PKIX_ValidateResult *valResult = NULL;
3135 PKIX_BuildResult *buildResult = NULL;
3136 PKIX_List *certList = NULL;
3137 PKIX_ForwardBuilderState *state = NULL;
3138 PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
3139 PKIX_CertSelector_MatchCallback selectorCallback = NULL;
3140 PKIX_Boolean trusted = PKIX_FALSE;
3141 PKIX_PL_AIAMgr *aiaMgr = NULL;
3142
3143 PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain");
3144 PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
3145
3146 nbioContext = *pNBIOContext;
3147 *pNBIOContext = NULL;
3148
3149 state = *pState;
3150 *pState = NULL; /* no net change in reference count */
3151
3152 if (state == NULL) {
3153 PKIX_CHECK(PKIX_ProcessingParams_GetDate
3154 (procParams, &testDate, plContext),
3155 PKIX_PROCESSINGPARAMSGETDATEFAILED);
3156
3157 PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors
3158 (procParams, &anchors, plContext),
3159 PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED);
3160
3161 PKIX_CHECK(PKIX_List_GetLength(anchors, &numAnchors, plContext),
3162 PKIX_LISTGETLENGTHFAILED);
3163
3164 /* retrieve stuff from targetCertConstraints */
3165 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
3166 (procParams, &targetConstraints, plContext),
3167 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
3168
3169 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
3170 (targetConstraints, &targetParams, plContext),
3171 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
3172
3173 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
3174 (targetParams, &targetCert, plContext),
3175 PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
3176
3177 PKIX_CHECK(
3178 PKIX_ComCertSelParams_SetLeafCertFlag(targetParams,
3179 PKIX_TRUE, plContext),
3180 PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED);
3181
3182 PKIX_CHECK(PKIX_ProcessingParams_GetHintCerts
3183 (procParams, &hintCerts, plContext),
3184 PKIX_PROCESSINGPARAMSGETHINTCERTSFAILED);
3185
3186 if (hintCerts != NULL) {
3187 PKIX_CHECK(PKIX_List_GetLength
3188 (hintCerts, &numHintCerts, plContext),
3189 PKIX_LISTGETLENGTHFAILED);
3190 }
3191
3192 /*
3193 * Caller must provide either a target Cert
3194 * (in ComCertSelParams->Certificate) or a partial Cert
3195 * chain (in ProcParams->HintCerts).
3196 */
3197
3198 if (targetCert == NULL) {
3199
3200 /* Use first cert of hintCerts as the targetCert */
3201 if (numHintCerts == 0) {
3202 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
3203 }
3204
3205 PKIX_CHECK(PKIX_List_GetItem
3206 (hintCerts,
3207 0,
3208 (PKIX_PL_Object **)&targetCert,
3209 plContext),
3210 PKIX_LISTGETITEMFAILED);
3211
3212 PKIX_CHECK(PKIX_List_DeleteItem(hintCerts, 0, plContext),
3213 PKIX_LISTGETITEMFAILED);
3214 } else {
3215
3216 /*
3217 * If the first hintCert is the same as the targetCert,
3218 * delete it from hintCerts.
3219 */
3220 if (numHintCerts != 0) {
3221 PKIX_CHECK(PKIX_List_GetItem
3222 (hintCerts, 0, &firstHintCert, plContext),
3223 PKIX_LISTGETITEMFAILED);
3224
3225 PKIX_CHECK(PKIX_PL_Object_Equals
3226 ((PKIX_PL_Object *)targetCert,
3227 firstHintCert,
3228 &isDuplicate,
3229 plContext),
3230 PKIX_OBJECTEQUALSFAILED);
3231
3232 if (isDuplicate) {
3233 PKIX_CHECK(PKIX_List_DeleteItem
3234 (hintCerts, 0, plContext),
3235 PKIX_LISTGETITEMFAILED);
3236 }
3237 PKIX_DECREF(firstHintCert);
3238 }
3239
3240 }
3241
3242 if (targetCert == NULL) {
3243 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
3244 }
3245
3246 PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted
3247 (targetCert,
3248 &trusted,
3249 plContext),
3250 PKIX_CERTISCERTTRUSTEDFAILED);
3251
3252 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
3253 (targetCert,
3254 &targetSubjNames,
3255 plContext),
3256 PKIX_CERTGETALLSUBJECTNAMESFAILED);
3257
3258 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
3259 (targetCert, &targetPubKey, plContext),
3260 PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
3261
3262 PKIX_CHECK(PKIX_List_Create(&tentativeChain, plContext),
3263 PKIX_LISTCREATEFAILED);
3264
3265 PKIX_CHECK(PKIX_List_AppendItem
3266 (tentativeChain, (PKIX_PL_Object *)targetCert, plContext),
3267 PKIX_LISTAPPENDITEMFAILED);
3268
3269 if (procParams->qualifyTargetCert) {
3270 /* EE cert validation */
3271 /* Sync up the time on the target selector parameter struct. */
3272 PKIX_CHECK(
3273 PKIX_ComCertSelParams_SetCertificateValid(targetParams,
3274 testDate,
3275 plContext),
3276 PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED);
3277
3278 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
3279 (targetConstraints, &selectorCallback, plContext),
3280 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
3281
3282 pkixErrorResult =
3283 (*selectorCallback)(targetConstraints, targetCert,
3284 plContext);
3285 if (pkixErrorResult) {
3286 pkixErrorClass = pkixErrorResult->errClass;
3287 if (pkixErrorClass == PKIX_FATAL_ERROR) {
3288 goto cleanup;
3289 }
3290 if (pVerifyNode != NULL) {
3291 PKIX_Error *tempResult =
3292 pkix_VerifyNode_Create(targetCert, 0,
3293 pkixErrorResult,
3294 pVerifyNode,
3295 plContext);
3296 if (tempResult) {
3297 PKIX_DECREF(pkixErrorResult);
3298 pkixErrorResult = tempResult;
3299 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
3300 pkixErrorClass = PKIX_FATAL_ERROR;
3301 goto cleanup;
3302 }
3303 }
3304 pkixErrorCode = PKIX_CERTCHECKVALIDITYFAILED;
3305 goto cleanup;
3306 }
3307 }
3308
3309 /* If the EE cert is trusted, force success. We only want to do
3310 * this if we aren't validating against a policy (like EV). */
3311 if (trusted && procParams->initialPolicies == NULL) {
3312 if (pVerifyNode != NULL) {
3313 PKIX_Error *tempResult =
3314 pkix_VerifyNode_Create(targetCert, 0, NULL,
3315 pVerifyNode,
3316 plContext);
3317 if (tempResult) {
3318 pkixErrorResult = tempResult;
3319 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
3320 pkixErrorClass = PKIX_FATAL_ERROR;
3321 goto cleanup;
3322 }
3323 }
3324 PKIX_CHECK(pkix_ValidateResult_Create
3325 (targetPubKey, NULL /* anchor */,
3326 NULL /* policyTree */, &valResult, plContext),
3327 PKIX_VALIDATERESULTCREATEFAILED);
3328 PKIX_CHECK(
3329 pkix_BuildResult_Create(valResult, tentativeChain,
3330 &buildResult, plContext),
3331 PKIX_BUILDRESULTCREATEFAILED);
3332 *pBuildResult = buildResult;
3333 /* Note that *pState is NULL. The only side effect is that
3334 * the cert chain won't be cached in PKIX_BuildChain, which
3335 * is fine. */
3336 goto cleanup;
3337 }
3338
3339 PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
3340 (procParams, &certStores, plContext),
3341 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
3342
3343 PKIX_CHECK(PKIX_List_GetLength
3344 (certStores, &numCertStores, plContext),
3345 PKIX_LISTGETLENGTHFAILED);
3346
3347 /* Reorder CertStores so trusted are at front of the List */
3348 if (numCertStores > 1) {
3349 for (i = numCertStores - 1; i > 0; i--) {
3350 PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem
3351 (certStores,
3352 i,
3353 (PKIX_PL_Object **)&certStore,
3354 plContext),
3355 PKIX_LISTGETITEMFAILED);
3356 PKIX_CHECK_ONLY_FATAL(PKIX_CertStore_GetTrustCallback
3357 (certStore, &trustCallback, plContext),
3358 PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
3359
3360 if (trustCallback != NULL) {
3361 /* Is a trusted Cert, move CertStore to front */
3362 PKIX_CHECK(PKIX_List_DeleteItem
3363 (certStores, i, plContext),
3364 PKIX_LISTDELETEITEMFAILED);
3365 PKIX_CHECK(PKIX_List_InsertItem
3366 (certStores,
3367 0,
3368 (PKIX_PL_Object *)certStore,
3369 plContext),
3370 PKIX_LISTINSERTITEMFAILED);
3371
3372 }
3373
3374 PKIX_DECREF(certStore);
3375 }
3376 }
3377
3378 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
3379 (procParams, &userCheckers, plContext),
3380 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
3381
3382 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
3383 (procParams, &revChecker, plContext),
3384 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
3385 /* Do not initialize AIA manager if we are not going to fetch
3386 * cert using aia url. */
3387 if (procParams->useAIAForCertFetching) {
3388 PKIX_CHECK(PKIX_PL_AIAMgr_Create(&aiaMgr, plContext),
3389 PKIX_AIAMGRCREATEFAILED);
3390 }
3391
3392 /*
3393 * We initialize all the fields of buildConstants here, in one place ,
3394 * just to help keep track and ensure that we got everything.
3395 */
3396
3397 buildConstants.numAnchors = numAnchors;
3398 buildConstants.numCertStores = numCertStores;
3399 buildConstants.numHintCerts = numHintCerts;
3400 buildConstants.procParams = procParams;
3401 buildConstants.testDate = testDate;
3402 buildConstants.timeLimit = NULL;
3403 buildConstants.targetCert = targetCert;
3404 buildConstants.targetPubKey = targetPubKey;
3405 buildConstants.certStores = certStores;
3406 buildConstants.anchors = anchors;
3407 buildConstants.userCheckers = userCheckers;
3408 buildConstants.hintCerts = hintCerts;
3409 buildConstants.revChecker = revChecker;
3410 buildConstants.aiaMgr = aiaMgr;
3411 buildConstants.trustOnlyUserAnchors =
3412 procParams->useOnlyTrustAnchors;
3413
3414 PKIX_CHECK(pkix_Build_GetResourceLimits(&buildConstants, plContext),
3415 PKIX_BUILDGETRESOURCELIMITSFAILED);
3416
3417 PKIX_CHECK(pkix_ForwardBuilderState_Create
3418 (0, /* PKIX_UInt32 traversedCACerts */
3419 buildConstants.maxFanout,
3420 buildConstants.maxDepth,
3421 PKIX_TRUE, /* PKIX_Boolean canBeCached */
3422 NULL, /* PKIX_Date *validityDate */
3423 targetCert, /* PKIX_PL_Cert *prevCert */
3424 targetSubjNames, /* PKIX_List *traversedSubjNames */
3425 tentativeChain, /* PKIX_List *trustChain */
3426 NULL, /* PKIX_ForwardBuilderState *parent */
3427 &state, /* PKIX_ForwardBuilderState **pState */
3428 plContext),
3429 PKIX_BUILDSTATECREATEFAILED);
3430
3431 state->buildConstants.numAnchors = buildConstants.numAnchors;
3432 state->buildConstants.numCertStores = buildConstants.numCertStores;
3433 state->buildConstants.numHintCerts = buildConstants.numHintCerts;
3434 state->buildConstants.maxFanout = buildConstants.maxFanout;
3435 state->buildConstants.maxDepth = buildConstants.maxDepth;
3436 state->buildConstants.maxTime = buildConstants.maxTime;
3437 state->buildConstants.procParams = buildConstants.procParams;
3438 PKIX_INCREF(buildConstants.testDate);
3439 state->buildConstants.testDate = buildConstants.testDate;
3440 state->buildConstants.timeLimit = buildConstants.timeLimit;
3441 PKIX_INCREF(buildConstants.targetCert);
3442 state->buildConstants.targetCert = buildConstants.targetCert;
3443 PKIX_INCREF(buildConstants.targetPubKey);
3444 state->buildConstants.targetPubKey =
3445 buildConstants.targetPubKey;
3446 PKIX_INCREF(buildConstants.certStores);
3447 state->buildConstants.certStores = buildConstants.certStores;
3448 PKIX_INCREF(buildConstants.anchors);
3449 state->buildConstants.anchors = buildConstants.anchors;
3450 PKIX_INCREF(buildConstants.userCheckers);
3451 state->buildConstants.userCheckers =
3452 buildConstants.userCheckers;
3453 PKIX_INCREF(buildConstants.hintCerts);
3454 state->buildConstants.hintCerts = buildConstants.hintCerts;
3455 PKIX_INCREF(buildConstants.revChecker);
3456 state->buildConstants.revChecker = buildConstants.revChecker;
3457 state->buildConstants.aiaMgr = buildConstants.aiaMgr;
3458 aiaMgr = NULL;
3459 state->buildConstants.trustOnlyUserAnchors =
3460 buildConstants.trustOnlyUserAnchors;
3461
3462 if (buildConstants.maxTime != 0) {
3463 PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
3464 (buildConstants.maxTime,
3465 &state->buildConstants.timeLimit,
3466 plContext),
3467 PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
3468 }
3469
3470 if (pVerifyNode != NULL) {
3471 PKIX_Error *tempResult =
3472 pkix_VerifyNode_Create(targetCert, 0, NULL,
3473 &(state->verifyNode),
3474 plContext);
3475 if (tempResult) {
3476 pkixErrorResult = tempResult;
3477 pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
3478 pkixErrorClass = PKIX_FATAL_ERROR;
3479 goto cleanup;
3480 }
3481 }
3482
3483 PKIX_CHECK_ONLY_FATAL(
3484 pkix_Build_CheckInCache(state, &buildResult,
3485 &nbioContext, plContext),
3486 PKIX_UNABLETOBUILDCHAIN);
3487 if (nbioContext) {
3488 *pNBIOContext = nbioContext;
3489 *pState = state;
3490 state = NULL;
3491 goto cleanup;
3492 }
3493 if (buildResult) {
3494 *pBuildResult = buildResult;
3495 if (pVerifyNode != NULL) {
3496 *pVerifyNode = state->verifyNode;
3497 state->verifyNode = NULL;
3498 }
3499 goto cleanup;
3500 }
3501 }
3502
3503 /* If we're resuming after non-blocking I/O we need to get SubjNames */
3504 if (targetSubjNames == NULL) {
3505 PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
3506 (state->buildConstants.targetCert,
3507 &targetSubjNames,
3508 plContext),
3509 PKIX_CERTGETALLSUBJECTNAMESFAILED);
3510 }
3511
3512 state->status = BUILD_INITIAL;
3513
3514 pkixErrorResult =
3515 pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
3516 &valResult, plContext);
3517
3518 /* non-null nbioContext means the build would block */
3519 if (pkixErrorResult == NULL && nbioContext != NULL) {
3520
3521 *pNBIOContext = nbioContext;
3522 *pBuildResult = NULL;
3523
3524 /* no valResult means the build has failed */
3525 } else {
3526 if (pVerifyNode != NULL) {
3527 PKIX_INCREF(state->verifyNode);
3528 *pVerifyNode = state->verifyNode;
3529 }
3530
3531 if (valResult == NULL || pkixErrorResult)
3532 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
3533 PKIX_CHECK(
3534 pkix_BuildResult_Create(valResult, state->trustChain,
3535 &buildResult, plContext),
3536 PKIX_BUILDRESULTCREATEFAILED);
3537 *pBuildResult = buildResult;
3538 }
3539
3540 *pState = state;
3541 state = NULL;
3542
3543 cleanup:
3544
3545 PKIX_DECREF(targetConstraints);
3546 PKIX_DECREF(targetParams);
3547 PKIX_DECREF(anchors);
3548 PKIX_DECREF(targetSubjNames);
3549 PKIX_DECREF(targetCert);
3550 PKIX_DECREF(revChecker);
3551 PKIX_DECREF(certStores);
3552 PKIX_DECREF(certStore);
3553 PKIX_DECREF(userCheckers);
3554 PKIX_DECREF(hintCerts);
3555 PKIX_DECREF(firstHintCert);
3556 PKIX_DECREF(testDate);
3557 PKIX_DECREF(targetPubKey);
3558 PKIX_DECREF(tentativeChain);
3559 PKIX_DECREF(valResult);
3560 PKIX_DECREF(certList);
3561 PKIX_DECREF(trustedCert);
3562 PKIX_DECREF(state);
3563 PKIX_DECREF(aiaMgr);
3564
3565 PKIX_RETURN(BUILD);
3566 }
3567
3568 /*
3569 * FUNCTION: pkix_Build_ResumeBuildChain
3570 * DESCRIPTION:
3571 *
3572 * This function continues the search for a BuildChain, using the parameters
3573 * provided in "procParams" and the ForwardBuilderState pointed to by "state".
3574 *
3575 * If a successful chain is built, this function stores the BuildResult at
3576 * "pBuildResult". Alternatively, if an operation using non-blocking I/O
3577 * is in progress and the operation has not been completed, this function
3578 * stores the FowardBuilderState at "pState" and NULL at "pBuildResult".
3579 * Finally, if chain building was unsuccessful, this function stores NULL
3580 * at both "pState" and at "pBuildResult".
3581 *
3582 * PARAMETERS:
3583 * "pNBIOContext"
3584 * Address at which the NBIOContext is stored indicating whether the
3585 * validation is complete. Must be non-NULL.
3586 * "pState"
3587 * Address at which the ForwardBuilderState is provided for resumption of
3588 * the chain building attempt; also, the address at which the
3589 * ForwardBuilderStateis stored, if the chain building is suspended for
3590 * waiting I/O. Must be non-NULL.
3591 * "pBuildResult"
3592 * Address at which the BuildResult is stored, after a successful build.
3593 * Must be non-NULL.
3594 * "plContext"
3595 * Platform-specific context pointer.
3596 * THREAD SAFETY:
3597 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
3598 * RETURNS:
3599 * Returns NULL if the function succeeds.
3600 * Returns a Build Error if the function fails in a non-fatal way
3601 * Returns a Fatal Error if the function fails in an unrecoverable way.
3602 */
3603 static PKIX_Error *
3604 pkix_Build_ResumeBuildChain(
3605 void **pNBIOContext,
3606 PKIX_ForwardBuilderState *state,
3607 PKIX_BuildResult **pBuildResult,
3608 PKIX_VerifyNode **pVerifyNode,
3609 void *plContext)
3610 {
3611 PKIX_ValidateResult *valResult = NULL;
3612 PKIX_BuildResult *buildResult = NULL;
3613 void *nbioContext = NULL;
3614
3615 PKIX_ENTER(BUILD, "pkix_Build_ResumeBuildChain");
3616 PKIX_NULLCHECK_TWO(state, pBuildResult);
3617
3618 nbioContext = *pNBIOContext;
3619 *pNBIOContext = NULL;
3620
3621 pkixErrorResult =
3622 pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
3623 &valResult, plContext);
3624
3625 /* non-null nbioContext means the build would block */
3626 if (pkixErrorResult == NULL && nbioContext != NULL) {
3627
3628 *pNBIOContext = nbioContext;
3629 *pBuildResult = NULL;
3630
3631 /* no valResult means the build has failed */
3632 } else {
3633 if (pVerifyNode != NULL) {
3634 PKIX_INCREF(state->verifyNode);
3635 *pVerifyNode = state->verifyNode;
3636 }
3637
3638 if (valResult == NULL || pkixErrorResult)
3639 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
3640
3641 PKIX_CHECK(
3642 pkix_BuildResult_Create(valResult, state->trustChain,
3643 &buildResult, plContext),
3644 PKIX_BUILDRESULTCREATEFAILED);
3645 *pBuildResult = buildResult;
3646 }
3647
3648 cleanup:
3649
3650 PKIX_DECREF(valResult);
3651
3652 PKIX_RETURN(BUILD);
3653 }
3654
3655 /* --Public-Functions--------------------------------------------- */
3656
3657 /*
3658 * FUNCTION: PKIX_BuildChain (see comments in pkix.h)
3659 */
3660 PKIX_Error *
3661 PKIX_BuildChain(
3662 PKIX_ProcessingParams *procParams,
3663 void **pNBIOContext,
3664 void **pState,
3665 PKIX_BuildResult **pBuildResult,
3666 PKIX_VerifyNode **pVerifyNode,
3667 void *plContext)
3668 {
3669 PKIX_ForwardBuilderState *state = NULL;
3670 PKIX_BuildResult *buildResult = NULL;
3671 void *nbioContext = NULL;
3672
3673 PKIX_ENTER(BUILD, "PKIX_BuildChain");
3674 PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
3675
3676 nbioContext = *pNBIOContext;
3677 *pNBIOContext = NULL;
3678
3679 if (*pState == NULL) {
3680 PKIX_CHECK(pkix_Build_InitiateBuildChain
3681 (procParams,
3682 &nbioContext,
3683 &state,
3684 &buildResult,
3685 pVerifyNode,
3686 plContext),
3687 PKIX_BUILDINITIATEBUILDCHAINFAILED);
3688 } else {
3689 state = (PKIX_ForwardBuilderState *)(*pState);
3690 *pState = NULL; /* no net change in reference count */
3691 if (state->status == BUILD_SHORTCUTPENDING) {
3692 PKIX_CHECK(pkix_Build_InitiateBuildChain
3693 (procParams,
3694 &nbioContext,
3695 &state,
3696 &buildResult,
3697 pVerifyNode,
3698 plContext),
3699 PKIX_BUILDINITIATEBUILDCHAINFAILED);
3700 } else {
3701 PKIX_CHECK(pkix_Build_ResumeBuildChain
3702 (&nbioContext,
3703 state,
3704 &buildResult,
3705 pVerifyNode,
3706 plContext),
3707 PKIX_BUILDINITIATEBUILDCHAINFAILED);
3708 }
3709 }
3710
3711 /* non-null nbioContext means the build would block */
3712 if (nbioContext != NULL) {
3713
3714 *pNBIOContext = nbioContext;
3715 *pState = state;
3716 state = NULL;
3717 *pBuildResult = NULL;
3718
3719 /* no buildResult means the build has failed */
3720 } else if (buildResult == NULL) {
3721 PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
3722 } else {
3723 /*
3724 * If we made a successful chain by combining the target Cert
3725 * with one of the Trust Anchors, we may have never created a
3726 * validityDate. We treat this situation as
3727 * canBeCached = PKIX_FALSE.
3728 */
3729 if ((state != NULL) &&
3730 ((state->validityDate) != NULL) &&
3731 (state->canBeCached)) {
3732 PKIX_CHECK(pkix_CacheCertChain_Add
3733 (state->buildConstants.targetCert,
3734 state->buildConstants.anchors,
3735 state->validityDate,
3736 buildResult,
3737 plContext),
3738 PKIX_CACHECERTCHAINADDFAILED);
3739 }
3740
3741 *pState = NULL;
3742 *pBuildResult = buildResult;
3743 buildResult = NULL;
3744 }
3745
3746 cleanup:
3747 PKIX_DECREF(buildResult);
3748 PKIX_DECREF(state);
3749
3750 PKIX_RETURN(BUILD);
3751 }
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix/top/pkix_build.h ('k') | nss/lib/libpkix/pkix/top/pkix_lifecycle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698