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

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

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

Powered by Google App Engine
This is Rietveld 408576698