comparison nss/lib/libpkix/pkix/top/pkix_build.c @ 0:1e5118fa0cb1

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