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

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

Issue 7530005: Add all NSS files to allow using a complete NSS in the future. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:executable
+ *
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the PKIX-C library.
15 *
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Sun Microsystems, Inc.
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37 /*
38 * pkix_validate.c
39 *
40 * Top level validateChain function
41 *
42 */
43
44 #include "pkix_validate.h"
45
46 /* --Private-Functions-------------------------------------------- */
47
48 /*
49 * FUNCTION: pkix_AddToVerifyLog
50 * DESCRIPTION:
51 *
52 * This function returns immediately if the address for the VerifyNode tree
53 * pointed to by "pVerifyTree" is NULL. Otherwise it creates a new VerifyNode
54 * from the Cert pointed to by "cert" and the Error pointed to by "error",
55 * and inserts it at the depth in the VerifyNode tree determined by "depth". A
56 * depth of zero means that this function creates the root node of a new tree.
57 *
58 * Note: this function does not include the means of choosing among branches
59 * of a tree. It is intended for non-branching trees, that is, where each
60 * parent node has only a single child node.
61 *
62 * PARAMETERS:
63 * "cert"
64 * The address of the Cert to be included in the new VerifyNode. Must be
65 * non-NULL.
66 * "depth"
67 * The UInt32 value of the depth.
68 * "error"
69 * The address of the Error to be included in the new VerifyNode.
70 * "pVerifyTree"
71 * The address of the VerifyNode tree into which the created VerifyNode
72 * is to be inserted. The node is not created if VerifyTree is NULL.
73 * "plContext"
74 * Platform-specific context pointer.
75 * THREAD SAFETY:
76 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
77 * RETURNS:
78 * Returns NULL if the function succeeds.
79 * Returns a Validate Error if the function fails in a non-fatal way.
80 * Returns a Fatal Error if the function fails in an unrecoverable way.
81 */
82 static PKIX_Error *
83 pkix_AddToVerifyLog(
84 PKIX_PL_Cert *cert,
85 PKIX_UInt32 depth,
86 PKIX_Error *error,
87 PKIX_VerifyNode **pVerifyTree,
88 void *plContext)
89 {
90
91 PKIX_VerifyNode *verifyNode = NULL;
92
93 PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog");
94 PKIX_NULLCHECK_ONE(cert);
95
96 if (pVerifyTree) { /* nothing to do if no address given for log */
97
98 PKIX_CHECK(pkix_VerifyNode_Create
99 (cert, depth, error, &verifyNode, plContext),
100 PKIX_VERIFYNODECREATEFAILED);
101
102 if (depth == 0) {
103 /* We just created the root node */
104 *pVerifyTree = verifyNode;
105 } else {
106 PKIX_CHECK(pkix_VerifyNode_AddToChain
107 (*pVerifyTree, verifyNode, plContext),
108 PKIX_VERIFYNODEADDTOCHAINFAILED);
109 }
110 }
111
112 cleanup:
113
114 PKIX_RETURN(VALIDATE);
115
116 }
117
118 /*
119 * FUNCTION: pkix_CheckCert
120 * DESCRIPTION:
121 *
122 * Checks whether the Cert pointed to by "cert" successfully validates
123 * using the List of CertChainCheckers pointed to by "checkers". If the
124 * certificate does not validate, an Error pointer is returned.
125 *
126 * This function should be called initially with the UInt32 pointed to by
127 * "pCheckerIndex" containing zero, and the pointer at "pNBIOContext"
128 * containing NULL. If a checker does non-blocking I/O, this function will
129 * return with the index of that checker stored at "pCheckerIndex" and a
130 * platform-dependent non-blocking I/O context stored at "pNBIOContext".
131 * A subsequent call to this function with those values intact will allow the
132 * checking to resume where it left off. This should be repeated until the
133 * function returns with NULL stored at "pNBIOContext".
134 *
135 * PARAMETERS:
136 * "cert"
137 * Address of Cert to validate. Must be non-NULL.
138 * "checkers"
139 * List of CertChainCheckers which must each validate the certificate.
140 * Must be non-NULL.
141 * "checkedExtOIDs"
142 * List of PKIX_PL_OID that has been processed. If called from building
143 * chain, it is the list of critical extension OIDs that has been
144 * processed prior to validation. May be NULL.
145 * "pCheckerIndex"
146 * Address at which is stored the the index, within the List "checkers",
147 * of a checker whose processing was interrupted by non-blocking I/O.
148 * Must be non-NULL.
149 * "pNBIOContext"
150 * Address at which is stored platform-specific non-blocking I/O context.
151 * Must be non-NULL.
152 * "plContext"
153 * Platform-specific context pointer.
154 * THREAD SAFETY:
155 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
156 * RETURNS:
157 * Returns NULL if the function succeeds.
158 * Returns a Validate Error if the function fails in a non-fatal way.
159 * Returns a Fatal Error if the function fails in an unrecoverable way.
160 */
161 static PKIX_Error *
162 pkix_CheckCert(
163 PKIX_PL_Cert *cert,
164 PKIX_List *checkers,
165 PKIX_List *checkedExtOIDsList,
166 PKIX_UInt32 *pCheckerIndex,
167 void **pNBIOContext,
168 void *plContext)
169 {
170 PKIX_CertChainChecker_CheckCallback checkerCheck = NULL;
171 PKIX_CertChainChecker *checker = NULL;
172 PKIX_List *unresCritExtOIDs = NULL;
173 PKIX_UInt32 numCheckers;
174 PKIX_UInt32 numUnresCritExtOIDs = 0;
175 PKIX_UInt32 checkerIndex = 0;
176 void *nbioContext = NULL;
177
178 PKIX_ENTER(VALIDATE, "pkix_CheckCert");
179 PKIX_NULLCHECK_FOUR(cert, checkers, pCheckerIndex, pNBIOContext);
180
181 nbioContext = *pNBIOContext;
182 *pNBIOContext = NULL; /* prepare for case of error exit */
183
184 PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
185 (cert, &unresCritExtOIDs, plContext),
186 PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
187
188 PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
189 PKIX_LISTGETLENGTHFAILED);
190
191 for (checkerIndex = *pCheckerIndex;
192 checkerIndex < numCheckers;
193 checkerIndex++) {
194
195 PKIX_CHECK(PKIX_List_GetItem
196 (checkers,
197 checkerIndex,
198 (PKIX_PL_Object **)&checker,
199 plContext),
200 PKIX_LISTGETITEMFAILED);
201
202 PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback
203 (checker, &checkerCheck, plContext),
204 PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED);
205
206 PKIX_CHECK(checkerCheck(checker, cert, unresCritExtOIDs,
207 &nbioContext, plContext),
208 PKIX_CERTCHAINCHECKERCHECKFAILED);
209
210 if (nbioContext != NULL) {
211 *pCheckerIndex = checkerIndex;
212 *pNBIOContext = nbioContext;
213 goto cleanup;
214 }
215
216 PKIX_DECREF(checker);
217 }
218
219 if (unresCritExtOIDs){
220
221 #ifdef PKIX_VALIDATEDEBUG
222 {
223 PKIX_PL_String *oidString = NULL;
224 PKIX_UInt32 length;
225 char *oidAscii = NULL;
226 PKIX_TOSTRING(unresCritExtOIDs, &oidString, plContext,
227 PKIX_LISTTOSTRINGFAILED);
228 PKIX_CHECK(PKIX_PL_String_GetEncoded
229 (oidString,
230 PKIX_ESCASCII,
231 (void **) &oidAscii,
232 &length,
233 plContext),
234 PKIX_STRINGGETENCODEDFAILED);
235 PKIX_VALIDATE_DEBUG_ARG
236 ("unrecognized critical extension OIDs:"
237 " %s\n", oidAscii);
238 PKIX_DECREF(oidString);
239 PKIX_PL_Free(oidAscii, plContext);
240 }
241 #endif
242
243 if (checkedExtOIDsList != NULL) {
244 /* Take out OID's that had been processed, if any */
245 PKIX_CHECK(pkix_List_RemoveItems
246 (unresCritExtOIDs,
247 checkedExtOIDsList,
248 plContext),
249 PKIX_LISTREMOVEITEMSFAILED);
250 }
251
252 PKIX_CHECK(PKIX_List_GetLength
253 (unresCritExtOIDs, &numUnresCritExtOIDs, plContext),
254 PKIX_LISTGETLENGTHFAILED);
255
256 if (numUnresCritExtOIDs != 0){
257 PKIX_ERROR(PKIX_UNRECOGNIZEDCRITICALEXTENSION);
258 }
259
260 }
261
262 cleanup:
263
264 PKIX_DECREF(checker);
265 PKIX_DECREF(unresCritExtOIDs);
266
267 PKIX_RETURN(VALIDATE);
268
269 }
270
271 /*
272 * FUNCTION: pkix_InitializeCheckers
273 * DESCRIPTION:
274 *
275 * Creates several checkers and initializes them with values derived from the
276 * TrustAnchor pointed to by "anchor", the ProcessingParams pointed to by
277 * "procParams", and the number of Certs in the Chain, represented by
278 * "numCerts". The List of checkers is stored at "pCheckers".
279 *
280 * PARAMETERS:
281 * "anchor"
282 * Address of TrustAnchor used to initialize the SignatureChecker and
283 * NameChainingChecker. Must be non-NULL.
284 * "procParams"
285 * Address of ProcessingParams used to initialize the ExpirationChecker
286 * and TargetCertChecker. Must be non-NULL.
287 * "numCerts"
288 * Number of certificates in the CertChain.
289 * "pCheckers"
290 * Address where object pointer will be stored. Must be non-NULL.
291 * "plContext"
292 * Platform-specific context pointer.
293 * THREAD SAFETY:
294 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
295 * RETURNS:
296 * Returns NULL if the function succeeds.
297 * Returns a Validate Error if the function fails in a non-fatal way.
298 * Returns a Fatal Error if the function fails in an unrecoverable way.
299 */
300 static PKIX_Error *
301 pkix_InitializeCheckers(
302 PKIX_TrustAnchor *anchor,
303 PKIX_ProcessingParams *procParams,
304 PKIX_UInt32 numCerts,
305 PKIX_List **pCheckers,
306 void *plContext)
307 {
308 PKIX_CertChainChecker *targetCertChecker = NULL;
309 PKIX_CertChainChecker *expirationChecker = NULL;
310 PKIX_CertChainChecker *nameChainingChecker = NULL;
311 PKIX_CertChainChecker *nameConstraintsChecker = NULL;
312 PKIX_CertChainChecker *basicConstraintsChecker = NULL;
313 PKIX_CertChainChecker *policyChecker = NULL;
314 PKIX_CertChainChecker *sigChecker = NULL;
315 PKIX_CertChainChecker *defaultCrlChecker = NULL;
316 PKIX_CertChainChecker *userChecker = NULL;
317 PKIX_PL_X500Name *trustedCAName = NULL;
318 PKIX_PL_PublicKey *trustedPubKey = NULL;
319 PKIX_List *checkers = NULL;
320 PKIX_PL_Date *testDate = NULL;
321 PKIX_CertSelector *certSelector = NULL;
322 PKIX_PL_Cert *trustedCert = NULL;
323 PKIX_PL_CertNameConstraints *trustedNC = NULL;
324 PKIX_List *initialPolicies = NULL;
325 PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
326 PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
327 PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
328 PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
329 PKIX_List *userCheckersList = NULL;
330 PKIX_List *certStores = NULL;
331 PKIX_UInt32 numCertCheckers = 0;
332 PKIX_UInt32 i;
333
334 PKIX_ENTER(VALIDATE, "pkix_InitializeCheckers");
335 PKIX_NULLCHECK_THREE(anchor, procParams, pCheckers);
336 PKIX_CHECK(PKIX_List_Create(&checkers, plContext),
337 PKIX_LISTCREATEFAILED);
338
339 /*
340 * The TrustAnchor may have been created using CreateWithCert
341 * (in which case GetCAPublicKey and GetCAName will return NULL)
342 * or may have been created using CreateWithNameKeyPair (in which
343 * case GetTrustedCert will return NULL. So we call GetTrustedCert
344 * and populate trustedPubKey and trustedCAName accordingly.
345 */
346
347 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
348 (anchor, &trustedCert, plContext),
349 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
350
351 if (trustedCert){
352 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
353 (trustedCert, &trustedPubKey, plContext),
354 PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
355
356 PKIX_CHECK(PKIX_PL_Cert_GetSubject
357 (trustedCert, &trustedCAName, plContext),
358 PKIX_CERTGETSUBJECTFAILED);
359 } else {
360 PKIX_CHECK(PKIX_TrustAnchor_GetCAPublicKey
361 (anchor, &trustedPubKey, plContext),
362 PKIX_TRUSTANCHORGETCAPUBLICKEYFAILED);
363
364 PKIX_CHECK(PKIX_TrustAnchor_GetCAName
365 (anchor, &trustedCAName, plContext),
366 PKIX_TRUSTANCHORGETCANAMEFAILED);
367 }
368
369 PKIX_NULLCHECK_TWO(trustedPubKey, trustedCAName);
370
371 PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints
372 (anchor, &trustedNC, plContext),
373 PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED);
374
375 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
376 (procParams, &certSelector, plContext),
377 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
378
379 PKIX_CHECK(PKIX_ProcessingParams_GetDate
380 (procParams, &testDate, plContext),
381 PKIX_PROCESSINGPARAMSGETDATEFAILED);
382
383 PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies
384 (procParams, &initialPolicies, plContext),
385 PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED);
386
387 PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected
388 (procParams, &policyQualifiersRejected, plContext),
389 PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED);
390
391 PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited
392 (procParams, &initialPolicyMappingInhibit, plContext),
393 PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED);
394
395 PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited
396 (procParams, &initialAnyPolicyInhibit, plContext),
397 PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED);
398
399 PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired
400 (procParams, &initialExplicitPolicy, plContext),
401 PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED);
402
403 PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
404 (procParams, &certStores, plContext),
405 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
406
407 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
408 (procParams, &userCheckersList, plContext),
409 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
410
411 /* now, initialize all the checkers */
412 PKIX_CHECK(pkix_TargetCertChecker_Initialize
413 (certSelector, numCerts, &targetCertChecker, plContext),
414 PKIX_TARGETCERTCHECKERINITIALIZEFAILED);
415
416 PKIX_CHECK(pkix_ExpirationChecker_Initialize
417 (testDate, &expirationChecker, plContext),
418 PKIX_EXPIRATIONCHECKERINITIALIZEFAILED);
419
420 PKIX_CHECK(pkix_NameChainingChecker_Initialize
421 (trustedCAName, &nameChainingChecker, plContext),
422 PKIX_NAMECHAININGCHECKERINITIALIZEFAILED);
423
424 PKIX_CHECK(pkix_NameConstraintsChecker_Initialize
425 (trustedNC, numCerts, &nameConstraintsChecker, plContext),
426 PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED);
427
428 PKIX_CHECK(pkix_BasicConstraintsChecker_Initialize
429 (numCerts, &basicConstraintsChecker, plContext),
430 PKIX_BASICCONSTRAINTSCHECKERINITIALIZEFAILED);
431
432 PKIX_CHECK(pkix_PolicyChecker_Initialize
433 (initialPolicies,
434 policyQualifiersRejected,
435 initialPolicyMappingInhibit,
436 initialExplicitPolicy,
437 initialAnyPolicyInhibit,
438 numCerts,
439 &policyChecker,
440 plContext),
441 PKIX_POLICYCHECKERINITIALIZEFAILED);
442
443 PKIX_CHECK(pkix_SignatureChecker_Initialize
444 (trustedPubKey, numCerts, &sigChecker, plContext),
445 PKIX_SIGNATURECHECKERINITIALIZEFAILED);
446
447 if (userCheckersList != NULL) {
448
449 PKIX_CHECK(PKIX_List_GetLength
450 (userCheckersList, &numCertCheckers, plContext),
451 PKIX_LISTGETLENGTHFAILED);
452
453 for (i = 0; i < numCertCheckers; i++) {
454
455 PKIX_CHECK(PKIX_List_GetItem
456 (userCheckersList,
457 i,
458 (PKIX_PL_Object **) &userChecker,
459 plContext),
460 PKIX_LISTGETITEMFAILED);
461
462 PKIX_CHECK(PKIX_List_AppendItem
463 (checkers,
464 (PKIX_PL_Object *)userChecker,
465 plContext),
466 PKIX_LISTAPPENDITEMFAILED);
467
468 PKIX_DECREF(userChecker);
469 }
470 }
471
472 PKIX_CHECK(PKIX_List_AppendItem
473 (checkers, (PKIX_PL_Object *)targetCertChecker, plContext),
474 PKIX_LISTAPPENDITEMFAILED);
475
476 PKIX_CHECK(PKIX_List_AppendItem
477 (checkers, (PKIX_PL_Object *)expirationChecker, plContext),
478 PKIX_LISTAPPENDITEMFAILED);
479
480 PKIX_CHECK(PKIX_List_AppendItem
481 (checkers, (PKIX_PL_Object *)nameChainingChecker, plContext),
482 PKIX_LISTAPPENDITEMFAILED);
483
484 PKIX_CHECK(PKIX_List_AppendItem
485 (checkers, (PKIX_PL_Object *)nameConstraintsChecker, plContext),
486 PKIX_LISTAPPENDITEMFAILED);
487
488 PKIX_CHECK(PKIX_List_AppendItem
489 (checkers, (PKIX_PL_Object *)basicConstraintsChecker, plContext),
490 PKIX_LISTAPPENDITEMFAILED);
491
492 PKIX_CHECK(PKIX_List_AppendItem
493 (checkers, (PKIX_PL_Object *)policyChecker, plContext),
494 PKIX_LISTAPPENDITEMFAILED);
495
496 PKIX_CHECK(PKIX_List_AppendItem
497 (checkers, (PKIX_PL_Object *)sigChecker, plContext),
498 PKIX_LISTAPPENDITEMFAILED);
499
500 *pCheckers = checkers;
501
502 cleanup:
503
504 if (PKIX_ERROR_RECEIVED){
505 PKIX_DECREF(checkers);
506 }
507
508 PKIX_DECREF(certSelector);
509 PKIX_DECREF(testDate);
510 PKIX_DECREF(initialPolicies);
511 PKIX_DECREF(targetCertChecker);
512 PKIX_DECREF(expirationChecker);
513 PKIX_DECREF(nameChainingChecker);
514 PKIX_DECREF(nameConstraintsChecker);
515 PKIX_DECREF(basicConstraintsChecker);
516 PKIX_DECREF(policyChecker);
517 PKIX_DECREF(sigChecker);
518 PKIX_DECREF(trustedCAName);
519 PKIX_DECREF(trustedPubKey);
520 PKIX_DECREF(trustedNC);
521 PKIX_DECREF(trustedCert);
522 PKIX_DECREF(defaultCrlChecker);
523 PKIX_DECREF(userCheckersList);
524 PKIX_DECREF(certStores);
525 PKIX_DECREF(userChecker);
526
527 PKIX_RETURN(VALIDATE);
528 }
529
530 /*
531 * FUNCTION: pkix_RetrieveOutputs
532 * DESCRIPTION:
533 *
534 * This function queries the respective states of the List of checkers in
535 * "checkers" to to obtain the final public key from the SignatureChecker
536 * and the policy tree from the PolicyChecker, storing those values at
537 * "pFinalSubjPubKey" and "pPolicyTree", respectively.
538 *
539 * PARAMETERS:
540 * "checkers"
541 * Address of List of checkers to be queried. Must be non-NULL.
542 * "pFinalSubjPubKey"
543 * Address where final public key will be stored. Must be non-NULL.
544 * "pPolicyTree"
545 * Address where policy tree will be stored. Must be non-NULL.
546 * "plContext"
547 * Platform-specific context pointer.
548 * THREAD SAFETY:
549 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
550 * RETURNS:
551 * Returns NULL if the function succeeds.
552 * Returns a Validate Error if the function fails in a non-fatal way.
553 * Returns a Fatal Error if the function fails in an unrecoverable way.
554 */
555 static PKIX_Error *
556 pkix_RetrieveOutputs(
557 PKIX_List *checkers,
558 PKIX_PL_PublicKey **pFinalSubjPubKey,
559 PKIX_PolicyNode **pPolicyTree,
560 void *plContext)
561 {
562 PKIX_PL_PublicKey *finalSubjPubKey = NULL;
563 PKIX_PolicyNode *validPolicyTree = NULL;
564 PKIX_CertChainChecker *checker = NULL;
565 PKIX_PL_Object *state = NULL;
566 PKIX_UInt32 numCheckers = 0;
567 PKIX_UInt32 type;
568 PKIX_Int32 j;
569
570 PKIX_ENTER(VALIDATE, "pkix_RetrieveOutputs");
571
572 PKIX_NULLCHECK_TWO(checkers, pPolicyTree);
573
574 /*
575 * To optimize the search, we guess that the sigChecker is
576 * last in the tree and is preceded by the policyChecker. We
577 * search toward the front of the chain. Remember that List
578 * items are indexed 0..(numItems - 1).
579 */
580
581 PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
582 PKIX_LISTGETLENGTHFAILED);
583
584 for (j = numCheckers - 1; j >= 0; j--){
585 PKIX_CHECK(PKIX_List_GetItem
586 (checkers, j, (PKIX_PL_Object **)&checker, plContext),
587 PKIX_LISTGETITEMFAILED);
588
589 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
590 (checker, &state, plContext),
591 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
592
593 /* user defined checker may have no state */
594 if (state != NULL) {
595
596 PKIX_CHECK(PKIX_PL_Object_GetType(state, &type, plContext),
597 PKIX_OBJECTGETTYPEFAILED);
598
599 if (type == PKIX_SIGNATURECHECKERSTATE_TYPE){
600 /* final pubKey will include any inherited DSA params */
601 finalSubjPubKey =
602 ((pkix_SignatureCheckerState *)state)->
603 prevPublicKey;
604 PKIX_INCREF(finalSubjPubKey);
605 *pFinalSubjPubKey = finalSubjPubKey;
606 }
607
608 if (type == PKIX_CERTPOLICYCHECKERSTATE_TYPE) {
609 validPolicyTree =
610 ((PKIX_PolicyCheckerState *)state)->validPolicyTree;
611 break;
612 }
613 }
614
615 PKIX_DECREF(checker);
616 PKIX_DECREF(state);
617 }
618
619 PKIX_INCREF(validPolicyTree);
620 *pPolicyTree = validPolicyTree;
621
622 cleanup:
623
624 PKIX_DECREF(checker);
625 PKIX_DECREF(state);
626
627 PKIX_RETURN(VALIDATE);
628
629 }
630
631 /*
632 * FUNCTION: pkix_CheckChain
633 * DESCRIPTION:
634 *
635 * Checks whether the List of Certs pointed to by "certs", containing
636 * "numCerts" entries, successfully validates using each CertChainChecker in
637 * the List pointed to by "checkers" and has not been revoked, according to any
638 * of the Revocation Checkers in the List pointed to by "revChecker". Checkers
639 * are expected to remove from "removeCheckedExtOIDs" and extensions that they
640 * process. Indices to the certChain and the checkerChain are obtained and
641 * returned in "pCertCheckedIndex" and "pCheckerIndex", respectively. These
642 * should be set to zero prior to the initial call, but may be changed (and
643 * must be supplied on subsequent calls) if processing is suspended for non-
644 * blocking I/O. Each time a Cert passes from being validated by one of the
645 * CertChainCheckers to being checked by a Revocation Checker, the Boolean
646 * stored at "pRevChecking" is changed from FALSE to TRUE. If the Cert is
647 * rejected by a Revocation Checker, its reason code is returned at
648 * "pReasonCode. If the List of Certs successfully validates, the public key i
649 * the final certificate is obtained and stored at "pFinalSubjPubKey" and the
650 * validPolicyTree, which could be NULL, is stored at pPolicyTree. If the List
651 * of Certs fails to validate, an Error pointer is returned.
652 *
653 * If "pVerifyTree" is non-NULL, a chain of VerifyNodes is created which
654 * tracks the results of the validation. That is, either each node in the
655 * chain has a NULL Error component, or the last node contains an Error
656 * which indicates why the validation failed.
657 *
658 * The number of Certs in the List, represented by "numCerts", is used to
659 * determine which Cert is the final Cert.
660 *
661 * PARAMETERS:
662 * "certs"
663 * Address of List of Certs to validate. Must be non-NULL.
664 * "numCerts"
665 * Number of certificates in the List of certificates.
666 * "checkers"
667 * List of CertChainCheckers which must each validate the List of
668 * certificates. Must be non-NULL.
669 * "revChecker"
670 * List of RevocationCheckers which must each not reject the List of
671 * certificates. May be empty, but must be non-NULL.
672 * "removeCheckedExtOIDs"
673 * List of PKIX_PL_OID that has been processed. If called from building
674 * chain, it is the list of critical extension OIDs that has been
675 * processed prior to validation. Extension OIDs that may be processed by
676 * user defined checker processes are also in the list. May be NULL.
677 * "procParams"
678 * Address of ProcessingParams used to initialize various checkers. Must
679 * be non-NULL.
680 * "pCertCheckedIndex"
681 * Address where Int32 index to the Cert chain is obtained and
682 * returned. Must be non-NULL.
683 * "pCheckerIndex"
684 * Address where Int32 index to the CheckerChain is obtained and
685 * returned. Must be non-NULL.
686 * "pRevChecking"
687 * Address where Boolean is obtained and returned, indicating, if FALSE,
688 * that CertChainCheckers are being called; or, if TRUE, that RevChecker
689 * are being called. Must be non-NULL.
690 * "pReasonCode"
691 * Address where UInt32 results of revocation checking are stored. Must be
692 * non-NULL.
693 * "pNBIOContext"
694 * Address where platform-dependent context is stored if checking is
695 * suspended for non-blocking I/O. Must be non-NULL.
696 * "pFinalSubjPubKey"
697 * Address where the final public key will be stored. Must be non-NULL.
698 * "pPolicyTree"
699 * Address where the final validPolicyTree is stored. Must be non-NULL.
700 * "pVerifyTree"
701 * Address where a VerifyTree is stored, if non-NULL.
702 * "plContext"
703 * Platform-specific context pointer.
704 * THREAD SAFETY:
705 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
706 * RETURNS:
707 * Returns NULL if the function succeeds.
708 * Returns a Validate Error if the function fails in a non-fatal way.
709 * Returns a Fatal Error if the function fails in an unrecoverable way.
710 */
711 PKIX_Error *
712 pkix_CheckChain(
713 PKIX_List *certs,
714 PKIX_UInt32 numCerts,
715 PKIX_TrustAnchor *anchor,
716 PKIX_List *checkers,
717 PKIX_RevocationChecker *revChecker,
718 PKIX_List *removeCheckedExtOIDs,
719 PKIX_ProcessingParams *procParams,
720 PKIX_UInt32 *pCertCheckedIndex,
721 PKIX_UInt32 *pCheckerIndex,
722 PKIX_Boolean *pRevChecking,
723 PKIX_UInt32 *pReasonCode,
724 void **pNBIOContext,
725 PKIX_PL_PublicKey **pFinalSubjPubKey,
726 PKIX_PolicyNode **pPolicyTree,
727 PKIX_VerifyNode **pVerifyTree,
728 void *plContext)
729 {
730 PKIX_UInt32 j = 0;
731 PKIX_Boolean revChecking = PKIX_FALSE;
732 PKIX_Error *checkCertError = NULL;
733 void *nbioContext = NULL;
734 PKIX_PL_Cert *cert = NULL;
735 PKIX_PL_Cert *issuer = NULL;
736
737 PKIX_ENTER(VALIDATE, "pkix_CheckChain");
738 PKIX_NULLCHECK_FOUR(certs, checkers, revChecker, pCertCheckedIndex);
739 PKIX_NULLCHECK_FOUR(pCheckerIndex, pRevChecking, pReasonCode, anchor);
740 PKIX_NULLCHECK_THREE(pNBIOContext, pFinalSubjPubKey, pPolicyTree);
741
742 nbioContext = *pNBIOContext;
743 *pNBIOContext = NULL;
744 revChecking = *pRevChecking;
745
746 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
747 (anchor, &cert, plContext),
748 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
749
750 for (j = *pCertCheckedIndex; j < numCerts; j++) {
751
752 PORT_Assert(cert);
753 PKIX_DECREF(issuer);
754 issuer = cert;
755 cert = NULL;
756
757 PKIX_CHECK(PKIX_List_GetItem(
758 certs, j, (PKIX_PL_Object **)&cert, plContext),
759 PKIX_LISTGETITEMFAILED);
760
761 /* check if cert pointer is valid */
762 PORT_Assert(cert);
763 if (cert == NULL) {
764 continue;
765 }
766
767 if (revChecking == PKIX_FALSE) {
768
769 PKIX_CHECK(pkix_CheckCert
770 (cert,
771 checkers,
772 removeCheckedExtOIDs,
773 pCheckerIndex,
774 &nbioContext,
775 plContext),
776 PKIX_CHECKCERTFAILED);
777
778 if (nbioContext != NULL) {
779 *pCertCheckedIndex = j;
780 *pRevChecking = revChecking;
781 *pNBIOContext = nbioContext;
782 goto cleanup;
783 }
784
785 revChecking = PKIX_TRUE;
786 *pCheckerIndex = 0;
787 }
788
789 if (revChecking == PKIX_TRUE) {
790 PKIX_RevocationStatus revStatus;
791 pkixErrorResult =
792 PKIX_RevocationChecker_Check(
793 cert, issuer, revChecker,
794 procParams, PKIX_TRUE,
795 (j == numCerts - 1) ? PKIX_TRUE : PKIX_FAL SE,
796 &revStatus, pReasonCode,
797 &nbioContext, plContext);
798 if (nbioContext != NULL) {
799 *pCertCheckedIndex = j;
800 *pRevChecking = revChecking;
801 *pNBIOContext = nbioContext;
802 goto cleanup;
803 }
804 if (revStatus == PKIX_RevStatus_Revoked ||
805 pkixErrorResult) {
806 if (!pkixErrorResult) {
807 /* if pkixErrorResult is returned then
808 * use it as it has a detailed revocation
809 * error code. Otherwise create a new error */
810 PKIX_ERROR_CREATE(VALIDATE,
811 PKIX_CERTIFICATEREVOKED,
812 pkixErrorResult);
813 }
814 goto cleanup;
815 }
816 revChecking = PKIX_FALSE;
817 *pCheckerIndex = 0;
818 }
819
820 PKIX_CHECK(pkix_AddToVerifyLog
821 (cert, j, NULL, pVerifyTree, plContext),
822 PKIX_ADDTOVERIFYLOGFAILED);
823 }
824
825 PKIX_CHECK(pkix_RetrieveOutputs
826 (checkers, pFinalSubjPubKey, pPolicyTree, plContext),
827 PKIX_RETRIEVEOUTPUTSFAILED);
828
829 *pNBIOContext = NULL;
830
831 cleanup:
832 if (PKIX_ERROR_RECEIVED && cert) {
833 checkCertError = pkixErrorResult;
834
835 PKIX_CHECK_FATAL(
836 pkix_AddToVerifyLog(cert, j, checkCertError, pVerifyTree,
837 plContext),
838 PKIX_ADDTOVERIFYLOGFAILED);
839 pkixErrorResult = checkCertError;
840 pkixErrorCode = pkixErrorResult->errCode;
841 checkCertError = NULL;
842 }
843
844 fatal:
845 PKIX_DECREF(checkCertError);
846 PKIX_DECREF(cert);
847 PKIX_DECREF(issuer);
848
849 PKIX_RETURN(VALIDATE);
850 }
851
852 /*
853 * FUNCTION: pkix_ExtractParameters
854 * DESCRIPTION:
855 *
856 * Extracts several parameters from the ValidateParams object pointed to by
857 * "valParams" and stores the CertChain at "pChain", the List of Certs at
858 * "pCerts", the number of Certs in the chain at "pNumCerts", the
859 * ProcessingParams object at "pProcParams", the List of TrustAnchors at
860 * "pAnchors", and the number of TrustAnchors at "pNumAnchors".
861 *
862 * PARAMETERS:
863 * "valParams"
864 * Address of ValidateParams from which the parameters are extracted.
865 * Must be non-NULL.
866 * "pCerts"
867 * Address where object pointer for List of Certs will be stored.
868 * Must be non-NULL.
869 * "pNumCerts"
870 * Address where number of Certs will be stored. Must be non-NULL.
871 * "pProcParams"
872 * Address where object pointer for ProcessingParams will be stored.
873 * Must be non-NULL.
874 * "pAnchors"
875 * Address where object pointer for List of Anchors will be stored.
876 * Must be non-NULL.
877 * "pNumAnchors"
878 * Address where number of Anchors will be stored. Must be non-NULL.
879 * "plContext"
880 * Platform-specific context pointer.
881 * THREAD SAFETY:
882 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
883 * RETURNS:
884 * Returns NULL if the function succeeds.
885 * Returns a Validate Error if the function fails in a non-fatal way.
886 * Returns a Fatal Error if the function fails in an unrecoverable way.
887 */
888 static PKIX_Error *
889 pkix_ExtractParameters(
890 PKIX_ValidateParams *valParams,
891 PKIX_List **pCerts,
892 PKIX_UInt32 *pNumCerts,
893 PKIX_ProcessingParams **pProcParams,
894 PKIX_List **pAnchors,
895 PKIX_UInt32 *pNumAnchors,
896 void *plContext)
897 {
898 PKIX_ENTER(VALIDATE, "pkix_ExtractParameters");
899 PKIX_NULLCHECK_THREE(valParams, pCerts, pNumCerts);
900 PKIX_NULLCHECK_THREE(pProcParams, pAnchors, pNumAnchors);
901
902 /* extract relevant parameters from chain */
903 PKIX_CHECK(PKIX_ValidateParams_GetCertChain
904 (valParams, pCerts, plContext),
905 PKIX_VALIDATEPARAMSGETCERTCHAINFAILED);
906
907 PKIX_CHECK(PKIX_List_GetLength(*pCerts, pNumCerts, plContext),
908 PKIX_LISTGETLENGTHFAILED);
909
910 /* extract relevant parameters from procParams */
911 PKIX_CHECK(PKIX_ValidateParams_GetProcessingParams
912 (valParams, pProcParams, plContext),
913 PKIX_VALIDATEPARAMSGETPROCESSINGPARAMSFAILED);
914
915 PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors
916 (*pProcParams, pAnchors, plContext),
917 PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED);
918
919 PKIX_CHECK(PKIX_List_GetLength(*pAnchors, pNumAnchors, plContext),
920 PKIX_LISTGETLENGTHFAILED);
921
922 cleanup:
923
924 PKIX_RETURN(VALIDATE);
925 }
926
927 /* --Public-Functions--------------------------------------------- */
928
929 /*
930 * FUNCTION: PKIX_ValidateChain (see comments in pkix.h)
931 */
932 PKIX_Error *
933 PKIX_ValidateChain(
934 PKIX_ValidateParams *valParams,
935 PKIX_ValidateResult **pResult,
936 PKIX_VerifyNode **pVerifyTree,
937 void *plContext)
938 {
939 PKIX_Error *chainFailed = NULL;
940
941 PKIX_ProcessingParams *procParams = NULL;
942 PKIX_CertChainChecker *userChecker = NULL;
943 PKIX_RevocationChecker *revChecker = NULL;
944 PKIX_List *certs = NULL;
945 PKIX_List *checkers = NULL;
946 PKIX_List *anchors = NULL;
947 PKIX_List *userCheckers = NULL;
948 PKIX_List *userCheckerExtOIDs = NULL;
949 PKIX_List *validateCheckedCritExtOIDsList = NULL;
950 PKIX_TrustAnchor *anchor = NULL;
951 PKIX_ValidateResult *valResult = NULL;
952 PKIX_PL_PublicKey *finalPubKey = NULL;
953 PKIX_PolicyNode *validPolicyTree = NULL;
954 PKIX_Boolean supportForwarding = PKIX_FALSE;
955 PKIX_Boolean revChecking = PKIX_FALSE;
956 PKIX_UInt32 i, numCerts, numAnchors;
957 PKIX_UInt32 numUserCheckers = 0;
958 PKIX_UInt32 certCheckedIndex = 0;
959 PKIX_UInt32 checkerIndex = 0;
960 PKIX_UInt32 reasonCode = 0;
961 void *nbioContext = NULL;
962
963 PKIX_ENTER(VALIDATE, "PKIX_ValidateChain");
964 PKIX_NULLCHECK_TWO(valParams, pResult);
965
966 /* extract various parameters from valParams */
967 PKIX_CHECK(pkix_ExtractParameters
968 (valParams,
969 &certs,
970 &numCerts,
971 &procParams,
972 &anchors,
973 &numAnchors,
974 plContext),
975 PKIX_EXTRACTPARAMETERSFAILED);
976
977 /*
978 * setup an extension OID list that user had defined for his checker
979 * processing. User checker is not responsible for taking out OIDs
980 * from unresolved critical extension list as the libpkix checker
981 * is doing. Here we add those user checkers' OIDs to the removal
982 * list to be taken out by CheckChain
983 */
984 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
985 (procParams, &userCheckers, plContext),
986 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
987
988 if (userCheckers != NULL) {
989
990 PKIX_CHECK(PKIX_List_Create
991 (&validateCheckedCritExtOIDsList,
992 plContext),
993 PKIX_LISTCREATEFAILED);
994
995 PKIX_CHECK(PKIX_List_GetLength
996 (userCheckers, &numUserCheckers, plContext),
997 PKIX_LISTGETLENGTHFAILED);
998
999 for (i = 0; i < numUserCheckers; i++) {
1000
1001 PKIX_CHECK(PKIX_List_GetItem
1002 (userCheckers,
1003 i,
1004 (PKIX_PL_Object **) &userChecker,
1005 plContext),
1006 PKIX_LISTGETITEMFAILED);
1007
1008 PKIX_CHECK
1009 (PKIX_CertChainChecker_IsForwardCheckingSupported
1010 (userChecker, &supportForwarding, plContext),
1011 PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
1012
1013 if (supportForwarding == PKIX_FALSE) {
1014
1015 PKIX_CHECK
1016 (PKIX_CertChainChecker_GetSupportedExtensions
1017 (userChecker, &userCheckerExtOIDs, plContext),
1018 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
1019
1020 if (userCheckerExtOIDs != NULL) {
1021 PKIX_CHECK(pkix_List_AppendList
1022 (validateCheckedCritExtOIDsList,
1023 userCheckerExtOIDs,
1024 plContext),
1025 PKIX_LISTAPPENDLISTFAILED);
1026 }
1027 }
1028
1029 PKIX_DECREF(userCheckerExtOIDs);
1030 PKIX_DECREF(userChecker);
1031 }
1032 }
1033
1034 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
1035 (procParams, &revChecker, plContext),
1036 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
1037
1038 /* try to validate the chain with each anchor */
1039 for (i = 0; i < numAnchors; i++){
1040
1041 /* get trust anchor */
1042 PKIX_CHECK(PKIX_List_GetItem
1043 (anchors, i, (PKIX_PL_Object **)&anchor, plContext),
1044 PKIX_LISTGETITEMFAILED);
1045
1046 /* initialize checkers using information from trust anchor */
1047 PKIX_CHECK(pkix_InitializeCheckers
1048 (anchor, procParams, numCerts, &checkers, plContext),
1049 PKIX_INITIALIZECHECKERSFAILED);
1050
1051 /*
1052 * Validate the chain using this trust anchor and these
1053 * checkers. (WARNING: checkers that use non-blocking I/O
1054 * are not currently supported.)
1055 */
1056 certCheckedIndex = 0;
1057 checkerIndex = 0;
1058 revChecking = PKIX_FALSE;
1059 chainFailed = pkix_CheckChain
1060 (certs,
1061 numCerts,
1062 anchor,
1063 checkers,
1064 revChecker,
1065 validateCheckedCritExtOIDsList,
1066 procParams,
1067 &certCheckedIndex,
1068 &checkerIndex,
1069 &revChecking,
1070 &reasonCode,
1071 &nbioContext,
1072 &finalPubKey,
1073 &validPolicyTree,
1074 pVerifyTree,
1075 plContext);
1076
1077 if (chainFailed || (reasonCode != 0)) {
1078
1079 /* cert chain failed to validate */
1080
1081 PKIX_DECREF(chainFailed);
1082 PKIX_DECREF(anchor);
1083 PKIX_DECREF(checkers);
1084 PKIX_DECREF(validPolicyTree);
1085
1086 /* if last anchor, we fail; else, we try next anchor */
1087 if (i == (numAnchors - 1)) { /* last anchor */
1088 PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
1089 }
1090
1091 } else {
1092
1093 /* cert chain successfully validated! */
1094 PKIX_CHECK(pkix_ValidateResult_Create
1095 (finalPubKey,
1096 anchor,
1097 validPolicyTree,
1098 &valResult,
1099 plContext),
1100 PKIX_VALIDATERESULTCREATEFAILED);
1101
1102 *pResult = valResult;
1103
1104 /* no need to try any more anchors in the loop */
1105 goto cleanup;
1106 }
1107 }
1108
1109 cleanup:
1110
1111 PKIX_DECREF(finalPubKey);
1112 PKIX_DECREF(certs);
1113 PKIX_DECREF(anchors);
1114 PKIX_DECREF(anchor);
1115 PKIX_DECREF(checkers);
1116 PKIX_DECREF(revChecker);
1117 PKIX_DECREF(validPolicyTree);
1118 PKIX_DECREF(chainFailed);
1119 PKIX_DECREF(procParams);
1120 PKIX_DECREF(userCheckers);
1121 PKIX_DECREF(validateCheckedCritExtOIDsList);
1122
1123 PKIX_RETURN(VALIDATE);
1124 }
1125
1126 /*
1127 * FUNCTION: pkix_Validate_BuildUserOIDs
1128 * DESCRIPTION:
1129 *
1130 * This function creates a List of the OIDs that are processed by the user
1131 * checkers in the List pointed to by "userCheckers", storing the resulting
1132 * List at "pUserCritOIDs". If the List of userCheckers is NULL, the output
1133 * List will be NULL. Otherwise the output List will be non-NULL, but may be
1134 * empty.
1135 *
1136 * PARAMETERS:
1137 * "userCheckers"
1138 * The address of the List of userCheckers.
1139 * "pUserCritOIDs"
1140 * The address at which the List is stored. Must be non-NULL.
1141 * "plContext"
1142 * Platform-specific context pointer.
1143 * THREAD SAFETY:
1144 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1145 * RETURNS:
1146 * Returns NULL if the function succeeds.
1147 * Returns a VALIDATE Error if the function fails in a non-fatal way.
1148 * Returns a Fatal Error if the function fails in an unrecoverable way.
1149 */
1150 static PKIX_Error *
1151 pkix_Validate_BuildUserOIDs(
1152 PKIX_List *userCheckers,
1153 PKIX_List **pUserCritOIDs,
1154 void *plContext)
1155 {
1156 PKIX_UInt32 numUserCheckers = 0;
1157 PKIX_UInt32 i = 0;
1158 PKIX_List *userCritOIDs = NULL;
1159 PKIX_List *userCheckerExtOIDs = NULL;
1160 PKIX_Boolean supportForwarding = PKIX_FALSE;
1161 PKIX_CertChainChecker *userChecker = NULL;
1162
1163 PKIX_ENTER(VALIDATE, "pkix_Validate_BuildUserOIDs");
1164 PKIX_NULLCHECK_ONE(pUserCritOIDs);
1165
1166 if (userCheckers != NULL) {
1167 PKIX_CHECK(PKIX_List_Create(&userCritOIDs, plContext),
1168 PKIX_LISTCREATEFAILED);
1169
1170 PKIX_CHECK(PKIX_List_GetLength
1171 (userCheckers, &numUserCheckers, plContext),
1172 PKIX_LISTGETLENGTHFAILED);
1173
1174 for (i = 0; i < numUserCheckers; i++) {
1175 PKIX_CHECK(PKIX_List_GetItem
1176 (userCheckers,
1177 i,
1178 (PKIX_PL_Object **) &userChecker,
1179 plContext),
1180 PKIX_LISTGETITEMFAILED);
1181
1182 PKIX_CHECK(PKIX_CertChainChecker_IsForwardCheckingSupported
1183 (userChecker, &supportForwarding, plContext),
1184 PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
1185
1186 if (supportForwarding == PKIX_FALSE) {
1187
1188 PKIX_CHECK(PKIX_CertChainChecker_GetSupportedExtensions
1189 (userChecker, &userCheckerExtOIDs, plContext),
1190 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
1191
1192 if (userCheckerExtOIDs != NULL) {
1193 PKIX_CHECK(pkix_List_AppendList
1194 (userCritOIDs, userCheckerExtOIDs, plContext),
1195 PKIX_LISTAPPENDLISTFAILED);
1196 }
1197 }
1198
1199 PKIX_DECREF(userCheckerExtOIDs);
1200 PKIX_DECREF(userChecker);
1201 }
1202 }
1203
1204 *pUserCritOIDs = userCritOIDs;
1205
1206 cleanup:
1207
1208 if (PKIX_ERROR_RECEIVED){
1209 PKIX_DECREF(userCritOIDs);
1210 }
1211
1212 PKIX_DECREF(userCheckerExtOIDs);
1213 PKIX_DECREF(userChecker);
1214
1215 PKIX_RETURN(VALIDATE);
1216 }
1217
1218 /*
1219 * FUNCTION: PKIX_ValidateChain_nb (see comments in pkix.h)
1220 */
1221 PKIX_Error *
1222 PKIX_ValidateChain_NB(
1223 PKIX_ValidateParams *valParams,
1224 PKIX_UInt32 *pCertIndex,
1225 PKIX_UInt32 *pAnchorIndex,
1226 PKIX_UInt32 *pCheckerIndex,
1227 PKIX_Boolean *pRevChecking,
1228 PKIX_List **pCheckers,
1229 void **pNBIOContext,
1230 PKIX_ValidateResult **pResult,
1231 PKIX_VerifyNode **pVerifyTree,
1232 void *plContext)
1233 {
1234 PKIX_UInt32 numCerts = 0;
1235 PKIX_UInt32 numAnchors = 0;
1236 PKIX_UInt32 i = 0;
1237 PKIX_UInt32 certIndex = 0;
1238 PKIX_UInt32 anchorIndex = 0;
1239 PKIX_UInt32 checkerIndex = 0;
1240 PKIX_UInt32 reasonCode = 0;
1241 PKIX_Boolean revChecking = PKIX_FALSE;
1242 PKIX_List *certs = NULL;
1243 PKIX_List *anchors = NULL;
1244 PKIX_List *checkers = NULL;
1245 PKIX_List *userCheckers = NULL;
1246 PKIX_List *validateCheckedCritExtOIDsList = NULL;
1247 PKIX_TrustAnchor *anchor = NULL;
1248 PKIX_ValidateResult *valResult = NULL;
1249 PKIX_PL_PublicKey *finalPubKey = NULL;
1250 PKIX_PolicyNode *validPolicyTree = NULL;
1251 PKIX_ProcessingParams *procParams = NULL;
1252 PKIX_RevocationChecker *revChecker = NULL;
1253 PKIX_Error *chainFailed = NULL;
1254 void *nbioContext = NULL;
1255
1256 PKIX_ENTER(VALIDATE, "PKIX_ValidateChain_NB");
1257 PKIX_NULLCHECK_FOUR
1258 (valParams, pCertIndex, pAnchorIndex, pCheckerIndex);
1259 PKIX_NULLCHECK_FOUR(pRevChecking, pCheckers, pNBIOContext, pResult);
1260
1261 nbioContext = *pNBIOContext;
1262 *pNBIOContext = NULL;
1263
1264 /* extract various parameters from valParams */
1265 PKIX_CHECK(pkix_ExtractParameters
1266 (valParams,
1267 &certs,
1268 &numCerts,
1269 &procParams,
1270 &anchors,
1271 &numAnchors,
1272 plContext),
1273 PKIX_EXTRACTPARAMETERSFAILED);
1274
1275 /*
1276 * Create a List of the OIDs that will be processed by the user
1277 * checkers. User checkers are not responsible for removing OIDs from
1278 * the List of unresolved critical extensions, as libpkix checkers are.
1279 * So we add those user checkers' OIDs to the removal list to be taken
1280 * out by CheckChain.
1281 */
1282 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
1283 (procParams, &userCheckers, plContext),
1284 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
1285
1286 PKIX_CHECK(pkix_Validate_BuildUserOIDs
1287 (userCheckers, &validateCheckedCritExtOIDsList, plContext),
1288 PKIX_VALIDATEBUILDUSEROIDSFAILED);
1289
1290 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
1291 (procParams, &revChecker, plContext),
1292 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
1293
1294 /* Are we resuming after a WOULDBLOCK return, or starting anew ? */
1295 if (nbioContext != NULL) {
1296 /* Resuming */
1297 certIndex = *pCertIndex;
1298 anchorIndex = *pAnchorIndex;
1299 checkerIndex = *pCheckerIndex;
1300 revChecking = *pRevChecking;
1301 checkers = *pCheckers;
1302 *pCheckers = NULL;
1303 }
1304
1305 /* try to validate the chain with each anchor */
1306 for (i = anchorIndex; i < numAnchors; i++) {
1307
1308 /* get trust anchor */
1309 PKIX_CHECK(PKIX_List_GetItem
1310 (anchors, i, (PKIX_PL_Object **)&anchor, plContext),
1311 PKIX_LISTGETITEMFAILED);
1312
1313 /* initialize checkers using information from trust anchor */
1314 if (nbioContext == NULL) {
1315 PKIX_CHECK(pkix_InitializeCheckers
1316 (anchor,
1317 procParams,
1318 numCerts,
1319 &checkers,
1320 plContext),
1321 PKIX_INITIALIZECHECKERSFAILED);
1322 }
1323
1324 /*
1325 * Validate the chain using this trust anchor and these
1326 * checkers.
1327 */
1328 chainFailed = pkix_CheckChain
1329 (certs,
1330 numCerts,
1331 anchor,
1332 checkers,
1333 revChecker,
1334 validateCheckedCritExtOIDsList,
1335 procParams,
1336 &certIndex,
1337 &checkerIndex,
1338 &revChecking,
1339 &reasonCode,
1340 &nbioContext,
1341 &finalPubKey,
1342 &validPolicyTree,
1343 pVerifyTree,
1344 plContext);
1345
1346 if (nbioContext != NULL) {
1347 *pCertIndex = certIndex;
1348 *pAnchorIndex = anchorIndex;
1349 *pCheckerIndex = checkerIndex;
1350 *pRevChecking = revChecking;
1351 PKIX_INCREF(checkers);
1352 *pCheckers = checkers;
1353 *pNBIOContext = nbioContext;
1354 goto cleanup;
1355 }
1356
1357 if (chainFailed || (reasonCode != 0)) {
1358
1359 /* cert chain failed to validate */
1360
1361 PKIX_DECREF(chainFailed);
1362 PKIX_DECREF(anchor);
1363 PKIX_DECREF(checkers);
1364 PKIX_DECREF(validPolicyTree);
1365
1366 /* if last anchor, we fail; else, we try next anchor */
1367 if (i == (numAnchors - 1)) { /* last anchor */
1368 PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
1369 }
1370
1371 } else {
1372
1373 /* cert chain successfully validated! */
1374 PKIX_CHECK(pkix_ValidateResult_Create
1375 (finalPubKey,
1376 anchor,
1377 validPolicyTree,
1378 &valResult,
1379 plContext),
1380 PKIX_VALIDATERESULTCREATEFAILED);
1381
1382 *pResult = valResult;
1383
1384 /* no need to try any more anchors in the loop */
1385 goto cleanup;
1386 }
1387 }
1388
1389 cleanup:
1390
1391 PKIX_DECREF(finalPubKey);
1392 PKIX_DECREF(certs);
1393 PKIX_DECREF(anchors);
1394 PKIX_DECREF(anchor);
1395 PKIX_DECREF(checkers);
1396 PKIX_DECREF(revChecker);
1397 PKIX_DECREF(validPolicyTree);
1398 PKIX_DECREF(chainFailed);
1399 PKIX_DECREF(procParams);
1400 PKIX_DECREF(userCheckers);
1401 PKIX_DECREF(validateCheckedCritExtOIDsList);
1402
1403 PKIX_RETURN(VALIDATE);
1404 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698