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/. */
7
* Top level validateChain function
11
#include "pkix_validate.h"
12
#include "pkix_pl_common.h"
14
/* --Private-Functions-------------------------------------------- */
17
* FUNCTION: pkix_AddToVerifyLog
20
* This function returns immediately if the address for the VerifyNode tree
21
* pointed to by "pVerifyTree" is NULL. Otherwise it creates a new VerifyNode
22
* from the Cert pointed to by "cert" and the Error pointed to by "error",
23
* and inserts it at the depth in the VerifyNode tree determined by "depth". A
24
* depth of zero means that this function creates the root node of a new tree.
26
* Note: this function does not include the means of choosing among branches
27
* of a tree. It is intended for non-branching trees, that is, where each
28
* parent node has only a single child node.
32
* The address of the Cert to be included in the new VerifyNode. Must be
35
* The UInt32 value of the depth.
37
* The address of the Error to be included in the new VerifyNode.
39
* The address of the VerifyNode tree into which the created VerifyNode
40
* is to be inserted. The node is not created if VerifyTree is NULL.
42
* Platform-specific context pointer.
44
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
46
* Returns NULL if the function succeeds.
47
* Returns a Validate Error if the function fails in a non-fatal way.
48
* Returns a Fatal Error if the function fails in an unrecoverable way.
55
PKIX_VerifyNode **pVerifyTree,
59
PKIX_VerifyNode *verifyNode = NULL;
61
PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog");
62
PKIX_NULLCHECK_ONE(cert);
64
if (pVerifyTree) { /* nothing to do if no address given for log */
66
PKIX_CHECK(pkix_VerifyNode_Create
67
(cert, depth, error, &verifyNode, plContext),
68
PKIX_VERIFYNODECREATEFAILED);
71
/* We just created the root node */
72
*pVerifyTree = verifyNode;
74
PKIX_CHECK(pkix_VerifyNode_AddToChain
75
(*pVerifyTree, verifyNode, plContext),
76
PKIX_VERIFYNODEADDTOCHAINFAILED);
82
PKIX_RETURN(VALIDATE);
87
* FUNCTION: pkix_CheckCert
90
* Checks whether the Cert pointed to by "cert" successfully validates
91
* using the List of CertChainCheckers pointed to by "checkers". If the
92
* certificate does not validate, an Error pointer is returned.
94
* This function should be called initially with the UInt32 pointed to by
95
* "pCheckerIndex" containing zero, and the pointer at "pNBIOContext"
96
* containing NULL. If a checker does non-blocking I/O, this function will
97
* return with the index of that checker stored at "pCheckerIndex" and a
98
* platform-dependent non-blocking I/O context stored at "pNBIOContext".
99
* A subsequent call to this function with those values intact will allow the
100
* checking to resume where it left off. This should be repeated until the
101
* function returns with NULL stored at "pNBIOContext".
105
* Address of Cert to validate. Must be non-NULL.
107
* List of CertChainCheckers which must each validate the certificate.
110
* List of PKIX_PL_OID that has been processed. If called from building
111
* chain, it is the list of critical extension OIDs that has been
112
* processed prior to validation. May be NULL.
114
* Address at which is stored the the index, within the List "checkers",
115
* of a checker whose processing was interrupted by non-blocking I/O.
118
* Address at which is stored platform-specific non-blocking I/O context.
121
* Platform-specific context pointer.
123
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
125
* Returns NULL if the function succeeds.
126
* Returns a Validate Error if the function fails in a non-fatal way.
127
* Returns a Fatal Error if the function fails in an unrecoverable way.
133
PKIX_List *checkedExtOIDsList,
134
PKIX_UInt32 *pCheckerIndex,
138
PKIX_CertChainChecker_CheckCallback checkerCheck = NULL;
139
PKIX_CertChainChecker *checker = NULL;
140
PKIX_List *unresCritExtOIDs = NULL;
141
PKIX_UInt32 numCheckers;
142
PKIX_UInt32 numUnresCritExtOIDs = 0;
143
PKIX_UInt32 checkerIndex = 0;
144
void *nbioContext = NULL;
146
PKIX_ENTER(VALIDATE, "pkix_CheckCert");
147
PKIX_NULLCHECK_FOUR(cert, checkers, pCheckerIndex, pNBIOContext);
149
nbioContext = *pNBIOContext;
150
*pNBIOContext = NULL; /* prepare for case of error exit */
152
PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
153
(cert, &unresCritExtOIDs, plContext),
154
PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
156
PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
157
PKIX_LISTGETLENGTHFAILED);
159
for (checkerIndex = *pCheckerIndex;
160
checkerIndex < numCheckers;
163
PKIX_CHECK(PKIX_List_GetItem
166
(PKIX_PL_Object **)&checker,
168
PKIX_LISTGETITEMFAILED);
170
PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback
171
(checker, &checkerCheck, plContext),
172
PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED);
174
PKIX_CHECK(checkerCheck(checker, cert, unresCritExtOIDs,
175
&nbioContext, plContext),
176
PKIX_CERTCHAINCHECKERCHECKFAILED);
178
if (nbioContext != NULL) {
179
*pCheckerIndex = checkerIndex;
180
*pNBIOContext = nbioContext;
184
PKIX_DECREF(checker);
187
if (unresCritExtOIDs){
189
#ifdef PKIX_VALIDATEDEBUG
191
PKIX_PL_String *oidString = NULL;
193
char *oidAscii = NULL;
194
PKIX_TOSTRING(unresCritExtOIDs, &oidString, plContext,
195
PKIX_LISTTOSTRINGFAILED);
196
PKIX_CHECK(PKIX_PL_String_GetEncoded
202
PKIX_STRINGGETENCODEDFAILED);
203
PKIX_VALIDATE_DEBUG_ARG
204
("unrecognized critical extension OIDs:"
206
PKIX_DECREF(oidString);
207
PKIX_PL_Free(oidAscii, plContext);
211
if (checkedExtOIDsList != NULL) {
212
/* Take out OID's that had been processed, if any */
213
PKIX_CHECK(pkix_List_RemoveItems
217
PKIX_LISTREMOVEITEMSFAILED);
220
PKIX_CHECK(PKIX_List_GetLength
221
(unresCritExtOIDs, &numUnresCritExtOIDs, plContext),
222
PKIX_LISTGETLENGTHFAILED);
224
if (numUnresCritExtOIDs != 0){
225
PKIX_ERROR(PKIX_UNRECOGNIZEDCRITICALEXTENSION);
232
PKIX_DECREF(checker);
233
PKIX_DECREF(unresCritExtOIDs);
235
PKIX_RETURN(VALIDATE);
240
* FUNCTION: pkix_InitializeCheckers
243
* Creates several checkers and initializes them with values derived from the
244
* TrustAnchor pointed to by "anchor", the ProcessingParams pointed to by
245
* "procParams", and the number of Certs in the Chain, represented by
246
* "numCerts". The List of checkers is stored at "pCheckers".
250
* Address of TrustAnchor used to initialize the SignatureChecker and
251
* NameChainingChecker. Must be non-NULL.
253
* Address of ProcessingParams used to initialize the ExpirationChecker
254
* and TargetCertChecker. Must be non-NULL.
256
* Number of certificates in the CertChain.
258
* Address where object pointer will be stored. Must be non-NULL.
260
* Platform-specific context pointer.
262
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
264
* Returns NULL if the function succeeds.
265
* Returns a Validate Error if the function fails in a non-fatal way.
266
* Returns a Fatal Error if the function fails in an unrecoverable way.
269
pkix_InitializeCheckers(
270
PKIX_TrustAnchor *anchor,
271
PKIX_ProcessingParams *procParams,
272
PKIX_UInt32 numCerts,
273
PKIX_List **pCheckers,
276
PKIX_CertChainChecker *targetCertChecker = NULL;
277
PKIX_CertChainChecker *expirationChecker = NULL;
278
PKIX_CertChainChecker *nameChainingChecker = NULL;
279
PKIX_CertChainChecker *nameConstraintsChecker = NULL;
280
PKIX_CertChainChecker *basicConstraintsChecker = NULL;
281
PKIX_CertChainChecker *policyChecker = NULL;
282
PKIX_CertChainChecker *sigChecker = NULL;
283
PKIX_CertChainChecker *defaultCrlChecker = NULL;
284
PKIX_CertChainChecker *userChecker = NULL;
285
PKIX_PL_X500Name *trustedCAName = NULL;
286
PKIX_PL_PublicKey *trustedPubKey = NULL;
287
PKIX_List *checkers = NULL;
288
PKIX_PL_Date *testDate = NULL;
289
PKIX_CertSelector *certSelector = NULL;
290
PKIX_PL_Cert *trustedCert = NULL;
291
PKIX_PL_CertNameConstraints *trustedNC = NULL;
292
PKIX_List *initialPolicies = NULL;
293
PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
294
PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
295
PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
296
PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
297
PKIX_List *userCheckersList = NULL;
298
PKIX_List *certStores = NULL;
299
PKIX_UInt32 numCertCheckers = 0;
302
PKIX_ENTER(VALIDATE, "pkix_InitializeCheckers");
303
PKIX_NULLCHECK_THREE(anchor, procParams, pCheckers);
304
PKIX_CHECK(PKIX_List_Create(&checkers, plContext),
305
PKIX_LISTCREATEFAILED);
308
* The TrustAnchor may have been created using CreateWithCert
309
* (in which case GetCAPublicKey and GetCAName will return NULL)
310
* or may have been created using CreateWithNameKeyPair (in which
311
* case GetTrustedCert will return NULL. So we call GetTrustedCert
312
* and populate trustedPubKey and trustedCAName accordingly.
315
PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
316
(anchor, &trustedCert, plContext),
317
PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
320
PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
321
(trustedCert, &trustedPubKey, plContext),
322
PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
324
PKIX_CHECK(PKIX_PL_Cert_GetSubject
325
(trustedCert, &trustedCAName, plContext),
326
PKIX_CERTGETSUBJECTFAILED);
328
PKIX_CHECK(PKIX_TrustAnchor_GetCAPublicKey
329
(anchor, &trustedPubKey, plContext),
330
PKIX_TRUSTANCHORGETCAPUBLICKEYFAILED);
332
PKIX_CHECK(PKIX_TrustAnchor_GetCAName
333
(anchor, &trustedCAName, plContext),
334
PKIX_TRUSTANCHORGETCANAMEFAILED);
337
PKIX_NULLCHECK_TWO(trustedPubKey, trustedCAName);
339
PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints
340
(anchor, &trustedNC, plContext),
341
PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED);
343
PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
344
(procParams, &certSelector, plContext),
345
PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
347
PKIX_CHECK(PKIX_ProcessingParams_GetDate
348
(procParams, &testDate, plContext),
349
PKIX_PROCESSINGPARAMSGETDATEFAILED);
351
PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies
352
(procParams, &initialPolicies, plContext),
353
PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED);
355
PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected
356
(procParams, &policyQualifiersRejected, plContext),
357
PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED);
359
PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited
360
(procParams, &initialPolicyMappingInhibit, plContext),
361
PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED);
363
PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited
364
(procParams, &initialAnyPolicyInhibit, plContext),
365
PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED);
367
PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired
368
(procParams, &initialExplicitPolicy, plContext),
369
PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED);
371
PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
372
(procParams, &certStores, plContext),
373
PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
375
PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
376
(procParams, &userCheckersList, plContext),
377
PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
379
/* now, initialize all the checkers */
380
PKIX_CHECK(pkix_TargetCertChecker_Initialize
381
(certSelector, numCerts, &targetCertChecker, plContext),
382
PKIX_TARGETCERTCHECKERINITIALIZEFAILED);
384
PKIX_CHECK(pkix_ExpirationChecker_Initialize
385
(testDate, &expirationChecker, plContext),
386
PKIX_EXPIRATIONCHECKERINITIALIZEFAILED);
388
PKIX_CHECK(pkix_NameChainingChecker_Initialize
389
(trustedCAName, &nameChainingChecker, plContext),
390
PKIX_NAMECHAININGCHECKERINITIALIZEFAILED);
392
PKIX_CHECK(pkix_NameConstraintsChecker_Initialize
393
(trustedNC, numCerts, &nameConstraintsChecker, plContext),
394
PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED);
396
PKIX_CHECK(pkix_BasicConstraintsChecker_Initialize
397
(numCerts, &basicConstraintsChecker, plContext),
398
PKIX_BASICCONSTRAINTSCHECKERINITIALIZEFAILED);
400
PKIX_CHECK(pkix_PolicyChecker_Initialize
402
policyQualifiersRejected,
403
initialPolicyMappingInhibit,
404
initialExplicitPolicy,
405
initialAnyPolicyInhibit,
409
PKIX_POLICYCHECKERINITIALIZEFAILED);
411
PKIX_CHECK(pkix_SignatureChecker_Initialize
412
(trustedPubKey, numCerts, &sigChecker, plContext),
413
PKIX_SIGNATURECHECKERINITIALIZEFAILED);
415
if (userCheckersList != NULL) {
417
PKIX_CHECK(PKIX_List_GetLength
418
(userCheckersList, &numCertCheckers, plContext),
419
PKIX_LISTGETLENGTHFAILED);
421
for (i = 0; i < numCertCheckers; i++) {
423
PKIX_CHECK(PKIX_List_GetItem
426
(PKIX_PL_Object **) &userChecker,
428
PKIX_LISTGETITEMFAILED);
430
PKIX_CHECK(PKIX_List_AppendItem
432
(PKIX_PL_Object *)userChecker,
434
PKIX_LISTAPPENDITEMFAILED);
436
PKIX_DECREF(userChecker);
440
PKIX_CHECK(PKIX_List_AppendItem
441
(checkers, (PKIX_PL_Object *)targetCertChecker, plContext),
442
PKIX_LISTAPPENDITEMFAILED);
444
PKIX_CHECK(PKIX_List_AppendItem
445
(checkers, (PKIX_PL_Object *)expirationChecker, plContext),
446
PKIX_LISTAPPENDITEMFAILED);
448
PKIX_CHECK(PKIX_List_AppendItem
449
(checkers, (PKIX_PL_Object *)nameChainingChecker, plContext),
450
PKIX_LISTAPPENDITEMFAILED);
452
PKIX_CHECK(PKIX_List_AppendItem
453
(checkers, (PKIX_PL_Object *)nameConstraintsChecker, plContext),
454
PKIX_LISTAPPENDITEMFAILED);
456
PKIX_CHECK(PKIX_List_AppendItem
457
(checkers, (PKIX_PL_Object *)basicConstraintsChecker, plContext),
458
PKIX_LISTAPPENDITEMFAILED);
460
PKIX_CHECK(PKIX_List_AppendItem
461
(checkers, (PKIX_PL_Object *)policyChecker, plContext),
462
PKIX_LISTAPPENDITEMFAILED);
464
PKIX_CHECK(PKIX_List_AppendItem
465
(checkers, (PKIX_PL_Object *)sigChecker, plContext),
466
PKIX_LISTAPPENDITEMFAILED);
468
*pCheckers = checkers;
472
if (PKIX_ERROR_RECEIVED){
473
PKIX_DECREF(checkers);
476
PKIX_DECREF(certSelector);
477
PKIX_DECREF(testDate);
478
PKIX_DECREF(initialPolicies);
479
PKIX_DECREF(targetCertChecker);
480
PKIX_DECREF(expirationChecker);
481
PKIX_DECREF(nameChainingChecker);
482
PKIX_DECREF(nameConstraintsChecker);
483
PKIX_DECREF(basicConstraintsChecker);
484
PKIX_DECREF(policyChecker);
485
PKIX_DECREF(sigChecker);
486
PKIX_DECREF(trustedCAName);
487
PKIX_DECREF(trustedPubKey);
488
PKIX_DECREF(trustedNC);
489
PKIX_DECREF(trustedCert);
490
PKIX_DECREF(defaultCrlChecker);
491
PKIX_DECREF(userCheckersList);
492
PKIX_DECREF(certStores);
493
PKIX_DECREF(userChecker);
495
PKIX_RETURN(VALIDATE);
499
* FUNCTION: pkix_RetrieveOutputs
502
* This function queries the respective states of the List of checkers in
503
* "checkers" to to obtain the final public key from the SignatureChecker
504
* and the policy tree from the PolicyChecker, storing those values at
505
* "pFinalSubjPubKey" and "pPolicyTree", respectively.
509
* Address of List of checkers to be queried. Must be non-NULL.
511
* Address where final public key will be stored. Must be non-NULL.
513
* Address where policy tree will be stored. Must be non-NULL.
515
* Platform-specific context pointer.
517
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
519
* Returns NULL if the function succeeds.
520
* Returns a Validate Error if the function fails in a non-fatal way.
521
* Returns a Fatal Error if the function fails in an unrecoverable way.
524
pkix_RetrieveOutputs(
526
PKIX_PL_PublicKey **pFinalSubjPubKey,
527
PKIX_PolicyNode **pPolicyTree,
530
PKIX_PL_PublicKey *finalSubjPubKey = NULL;
531
PKIX_PolicyNode *validPolicyTree = NULL;
532
PKIX_CertChainChecker *checker = NULL;
533
PKIX_PL_Object *state = NULL;
534
PKIX_UInt32 numCheckers = 0;
538
PKIX_ENTER(VALIDATE, "pkix_RetrieveOutputs");
540
PKIX_NULLCHECK_TWO(checkers, pPolicyTree);
543
* To optimize the search, we guess that the sigChecker is
544
* last in the tree and is preceded by the policyChecker. We
545
* search toward the front of the chain. Remember that List
546
* items are indexed 0..(numItems - 1).
549
PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
550
PKIX_LISTGETLENGTHFAILED);
552
for (j = numCheckers - 1; j >= 0; j--){
553
PKIX_CHECK(PKIX_List_GetItem
554
(checkers, j, (PKIX_PL_Object **)&checker, plContext),
555
PKIX_LISTGETITEMFAILED);
557
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
558
(checker, &state, plContext),
559
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
561
/* user defined checker may have no state */
564
PKIX_CHECK(PKIX_PL_Object_GetType(state, &type, plContext),
565
PKIX_OBJECTGETTYPEFAILED);
567
if (type == PKIX_SIGNATURECHECKERSTATE_TYPE){
568
/* final pubKey will include any inherited DSA params */
570
((pkix_SignatureCheckerState *)state)->
572
PKIX_INCREF(finalSubjPubKey);
573
*pFinalSubjPubKey = finalSubjPubKey;
576
if (type == PKIX_CERTPOLICYCHECKERSTATE_TYPE) {
578
((PKIX_PolicyCheckerState *)state)->validPolicyTree;
583
PKIX_DECREF(checker);
587
PKIX_INCREF(validPolicyTree);
588
*pPolicyTree = validPolicyTree;
592
PKIX_DECREF(checker);
595
PKIX_RETURN(VALIDATE);
600
* FUNCTION: pkix_CheckChain
603
* Checks whether the List of Certs pointed to by "certs", containing
604
* "numCerts" entries, successfully validates using each CertChainChecker in
605
* the List pointed to by "checkers" and has not been revoked, according to any
606
* of the Revocation Checkers in the List pointed to by "revChecker". Checkers
607
* are expected to remove from "removeCheckedExtOIDs" and extensions that they
608
* process. Indices to the certChain and the checkerChain are obtained and
609
* returned in "pCertCheckedIndex" and "pCheckerIndex", respectively. These
610
* should be set to zero prior to the initial call, but may be changed (and
611
* must be supplied on subsequent calls) if processing is suspended for non-
612
* blocking I/O. Each time a Cert passes from being validated by one of the
613
* CertChainCheckers to being checked by a Revocation Checker, the Boolean
614
* stored at "pRevChecking" is changed from FALSE to TRUE. If the Cert is
615
* rejected by a Revocation Checker, its reason code is returned at
616
* "pReasonCode. If the List of Certs successfully validates, the public key i
617
* the final certificate is obtained and stored at "pFinalSubjPubKey" and the
618
* validPolicyTree, which could be NULL, is stored at pPolicyTree. If the List
619
* of Certs fails to validate, an Error pointer is returned.
621
* If "pVerifyTree" is non-NULL, a chain of VerifyNodes is created which
622
* tracks the results of the validation. That is, either each node in the
623
* chain has a NULL Error component, or the last node contains an Error
624
* which indicates why the validation failed.
626
* The number of Certs in the List, represented by "numCerts", is used to
627
* determine which Cert is the final Cert.
631
* Address of List of Certs to validate. Must be non-NULL.
633
* Number of certificates in the List of certificates.
635
* List of CertChainCheckers which must each validate the List of
636
* certificates. Must be non-NULL.
638
* List of RevocationCheckers which must each not reject the List of
639
* certificates. May be empty, but must be non-NULL.
640
* "removeCheckedExtOIDs"
641
* List of PKIX_PL_OID that has been processed. If called from building
642
* chain, it is the list of critical extension OIDs that has been
643
* processed prior to validation. Extension OIDs that may be processed by
644
* user defined checker processes are also in the list. May be NULL.
646
* Address of ProcessingParams used to initialize various checkers. Must
648
* "pCertCheckedIndex"
649
* Address where Int32 index to the Cert chain is obtained and
650
* returned. Must be non-NULL.
652
* Address where Int32 index to the CheckerChain is obtained and
653
* returned. Must be non-NULL.
655
* Address where Boolean is obtained and returned, indicating, if FALSE,
656
* that CertChainCheckers are being called; or, if TRUE, that RevChecker
657
* are being called. Must be non-NULL.
659
* Address where UInt32 results of revocation checking are stored. Must be
662
* Address where platform-dependent context is stored if checking is
663
* suspended for non-blocking I/O. Must be non-NULL.
665
* Address where the final public key will be stored. Must be non-NULL.
667
* Address where the final validPolicyTree is stored. Must be non-NULL.
669
* Address where a VerifyTree is stored, if non-NULL.
671
* Platform-specific context pointer.
673
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
675
* Returns NULL if the function succeeds.
676
* Returns a Validate Error if the function fails in a non-fatal way.
677
* Returns a Fatal Error if the function fails in an unrecoverable way.
682
PKIX_UInt32 numCerts,
683
PKIX_TrustAnchor *anchor,
685
PKIX_RevocationChecker *revChecker,
686
PKIX_List *removeCheckedExtOIDs,
687
PKIX_ProcessingParams *procParams,
688
PKIX_UInt32 *pCertCheckedIndex,
689
PKIX_UInt32 *pCheckerIndex,
690
PKIX_Boolean *pRevChecking,
691
PKIX_UInt32 *pReasonCode,
693
PKIX_PL_PublicKey **pFinalSubjPubKey,
694
PKIX_PolicyNode **pPolicyTree,
695
PKIX_VerifyNode **pVerifyTree,
699
PKIX_Boolean revChecking = PKIX_FALSE;
700
PKIX_Error *checkCertError = NULL;
701
void *nbioContext = NULL;
702
PKIX_PL_Cert *cert = NULL;
703
PKIX_PL_Cert *issuer = NULL;
704
PKIX_PL_NssContext *nssContext = NULL;
705
CERTCertList *certList = NULL;
706
const CERTChainVerifyCallback *chainVerifyCallback = NULL;
707
CERTCertificate *nssCert = NULL;
709
PKIX_ENTER(VALIDATE, "pkix_CheckChain");
710
PKIX_NULLCHECK_FOUR(certs, checkers, revChecker, pCertCheckedIndex);
711
PKIX_NULLCHECK_FOUR(pCheckerIndex, pRevChecking, pReasonCode, anchor);
712
PKIX_NULLCHECK_THREE(pNBIOContext, pFinalSubjPubKey, pPolicyTree);
714
nbioContext = *pNBIOContext;
715
*pNBIOContext = NULL;
716
revChecking = *pRevChecking;
717
nssContext = (PKIX_PL_NssContext *)plContext;
718
chainVerifyCallback = &nssContext->chainVerifyCallback;
720
if (chainVerifyCallback->isChainValid != NULL) {
721
PRBool chainOK = PR_FALSE; /*assume failure*/
724
certList = CERT_NewCertList();
725
if (certList == NULL) {
726
PKIX_ERROR_ALLOC_ERROR();
729
/* Add the trust anchor to the list */
730
PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
731
(anchor, &cert, plContext),
732
PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
735
PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext),
736
PKIX_CERTGETCERTCERTIFICATEFAILED);
738
rv = CERT_AddCertToListHead(certList, nssCert);
739
if (rv != SECSuccess) {
740
PKIX_ERROR_ALLOC_ERROR();
742
/* the certList takes ownership of nssCert on success */
746
/* Add the rest of the chain to the list */
747
for (j = *pCertCheckedIndex; j < numCerts; j++) {
748
PKIX_CHECK(PKIX_List_GetItem(
749
certs, j, (PKIX_PL_Object **)&cert, plContext),
750
PKIX_LISTGETITEMFAILED);
753
PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext),
754
PKIX_CERTGETCERTCERTIFICATEFAILED);
756
rv = CERT_AddCertToListHead(certList, nssCert);
757
if (rv != SECSuccess) {
758
PKIX_ERROR_ALLOC_ERROR();
760
/* the certList takes ownership of nssCert on success */
765
rv = (*chainVerifyCallback->isChainValid)
766
(chainVerifyCallback->isChainValidArg, certList, &chainOK);
767
if (rv != SECSuccess) {
768
PKIX_ERROR_FATAL(PKIX_CHAINVERIFYCALLBACKFAILED);
772
PKIX_ERROR(PKIX_CHAINVERIFYCALLBACKFAILED);
777
PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
778
(anchor, &cert, plContext),
779
PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
781
for (j = *pCertCheckedIndex; j < numCerts; j++) {
788
PKIX_CHECK(PKIX_List_GetItem(
789
certs, j, (PKIX_PL_Object **)&cert, plContext),
790
PKIX_LISTGETITEMFAILED);
792
/* check if cert pointer is valid */
798
if (revChecking == PKIX_FALSE) {
800
PKIX_CHECK(pkix_CheckCert
803
removeCheckedExtOIDs,
807
PKIX_CHECKCERTFAILED);
809
if (nbioContext != NULL) {
810
*pCertCheckedIndex = j;
811
*pRevChecking = revChecking;
812
*pNBIOContext = nbioContext;
816
revChecking = PKIX_TRUE;
820
if (revChecking == PKIX_TRUE) {
821
PKIX_RevocationStatus revStatus;
823
PKIX_RevocationChecker_Check(
824
cert, issuer, revChecker,
825
procParams, PKIX_TRUE,
826
(j == numCerts - 1) ? PKIX_TRUE : PKIX_FALSE,
827
&revStatus, pReasonCode,
828
&nbioContext, plContext);
829
if (nbioContext != NULL) {
830
*pCertCheckedIndex = j;
831
*pRevChecking = revChecking;
832
*pNBIOContext = nbioContext;
835
if (revStatus == PKIX_RevStatus_Revoked ||
837
if (!pkixErrorResult) {
838
/* if pkixErrorResult is returned then
839
* use it as it has a detailed revocation
840
* error code. Otherwise create a new error */
841
PKIX_ERROR_CREATE(VALIDATE,
842
PKIX_CERTIFICATEREVOKED,
847
revChecking = PKIX_FALSE;
851
PKIX_CHECK(pkix_AddToVerifyLog
852
(cert, j, NULL, pVerifyTree, plContext),
853
PKIX_ADDTOVERIFYLOGFAILED);
856
PKIX_CHECK(pkix_RetrieveOutputs
857
(checkers, pFinalSubjPubKey, pPolicyTree, plContext),
858
PKIX_RETRIEVEOUTPUTSFAILED);
860
*pNBIOContext = NULL;
863
if (PKIX_ERROR_RECEIVED && cert) {
864
checkCertError = pkixErrorResult;
867
pkix_AddToVerifyLog(cert, j, checkCertError, pVerifyTree,
869
PKIX_ADDTOVERIFYLOGFAILED);
870
pkixErrorResult = checkCertError;
871
pkixErrorCode = pkixErrorResult->errCode;
872
checkCertError = NULL;
877
CERT_DestroyCertificate(nssCert);
881
CERT_DestroyCertList(certList);
884
PKIX_DECREF(checkCertError);
888
PKIX_RETURN(VALIDATE);
892
* FUNCTION: pkix_ExtractParameters
895
* Extracts several parameters from the ValidateParams object pointed to by
896
* "valParams" and stores the CertChain at "pChain", the List of Certs at
897
* "pCerts", the number of Certs in the chain at "pNumCerts", the
898
* ProcessingParams object at "pProcParams", the List of TrustAnchors at
899
* "pAnchors", and the number of TrustAnchors at "pNumAnchors".
903
* Address of ValidateParams from which the parameters are extracted.
906
* Address where object pointer for List of Certs will be stored.
909
* Address where number of Certs will be stored. Must be non-NULL.
911
* Address where object pointer for ProcessingParams will be stored.
914
* Address where object pointer for List of Anchors will be stored.
917
* Address where number of Anchors will be stored. Must be non-NULL.
919
* Platform-specific context pointer.
921
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
923
* Returns NULL if the function succeeds.
924
* Returns a Validate Error if the function fails in a non-fatal way.
925
* Returns a Fatal Error if the function fails in an unrecoverable way.
928
pkix_ExtractParameters(
929
PKIX_ValidateParams *valParams,
931
PKIX_UInt32 *pNumCerts,
932
PKIX_ProcessingParams **pProcParams,
933
PKIX_List **pAnchors,
934
PKIX_UInt32 *pNumAnchors,
937
PKIX_ENTER(VALIDATE, "pkix_ExtractParameters");
938
PKIX_NULLCHECK_THREE(valParams, pCerts, pNumCerts);
939
PKIX_NULLCHECK_THREE(pProcParams, pAnchors, pNumAnchors);
941
/* extract relevant parameters from chain */
942
PKIX_CHECK(PKIX_ValidateParams_GetCertChain
943
(valParams, pCerts, plContext),
944
PKIX_VALIDATEPARAMSGETCERTCHAINFAILED);
946
PKIX_CHECK(PKIX_List_GetLength(*pCerts, pNumCerts, plContext),
947
PKIX_LISTGETLENGTHFAILED);
949
/* extract relevant parameters from procParams */
950
PKIX_CHECK(PKIX_ValidateParams_GetProcessingParams
951
(valParams, pProcParams, plContext),
952
PKIX_VALIDATEPARAMSGETPROCESSINGPARAMSFAILED);
954
PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors
955
(*pProcParams, pAnchors, plContext),
956
PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED);
958
PKIX_CHECK(PKIX_List_GetLength(*pAnchors, pNumAnchors, plContext),
959
PKIX_LISTGETLENGTHFAILED);
963
PKIX_RETURN(VALIDATE);
966
/* --Public-Functions--------------------------------------------- */
969
* FUNCTION: PKIX_ValidateChain (see comments in pkix.h)
973
PKIX_ValidateParams *valParams,
974
PKIX_ValidateResult **pResult,
975
PKIX_VerifyNode **pVerifyTree,
978
PKIX_Error *chainFailed = NULL;
980
PKIX_ProcessingParams *procParams = NULL;
981
PKIX_CertChainChecker *userChecker = NULL;
982
PKIX_RevocationChecker *revChecker = NULL;
983
PKIX_List *certs = NULL;
984
PKIX_List *checkers = NULL;
985
PKIX_List *anchors = NULL;
986
PKIX_List *userCheckers = NULL;
987
PKIX_List *userCheckerExtOIDs = NULL;
988
PKIX_List *validateCheckedCritExtOIDsList = NULL;
989
PKIX_TrustAnchor *anchor = NULL;
990
PKIX_ValidateResult *valResult = NULL;
991
PKIX_PL_PublicKey *finalPubKey = NULL;
992
PKIX_PolicyNode *validPolicyTree = NULL;
993
PKIX_Boolean supportForwarding = PKIX_FALSE;
994
PKIX_Boolean revChecking = PKIX_FALSE;
995
PKIX_UInt32 i, numCerts, numAnchors;
996
PKIX_UInt32 numUserCheckers = 0;
997
PKIX_UInt32 certCheckedIndex = 0;
998
PKIX_UInt32 checkerIndex = 0;
999
PKIX_UInt32 reasonCode = 0;
1000
void *nbioContext = NULL;
1002
PKIX_ENTER(VALIDATE, "PKIX_ValidateChain");
1003
PKIX_NULLCHECK_TWO(valParams, pResult);
1005
/* extract various parameters from valParams */
1006
PKIX_CHECK(pkix_ExtractParameters
1014
PKIX_EXTRACTPARAMETERSFAILED);
1017
* setup an extension OID list that user had defined for his checker
1018
* processing. User checker is not responsible for taking out OIDs
1019
* from unresolved critical extension list as the libpkix checker
1020
* is doing. Here we add those user checkers' OIDs to the removal
1021
* list to be taken out by CheckChain
1023
PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
1024
(procParams, &userCheckers, plContext),
1025
PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
1027
if (userCheckers != NULL) {
1029
PKIX_CHECK(PKIX_List_Create
1030
(&validateCheckedCritExtOIDsList,
1032
PKIX_LISTCREATEFAILED);
1034
PKIX_CHECK(PKIX_List_GetLength
1035
(userCheckers, &numUserCheckers, plContext),
1036
PKIX_LISTGETLENGTHFAILED);
1038
for (i = 0; i < numUserCheckers; i++) {
1040
PKIX_CHECK(PKIX_List_GetItem
1043
(PKIX_PL_Object **) &userChecker,
1045
PKIX_LISTGETITEMFAILED);
1048
(PKIX_CertChainChecker_IsForwardCheckingSupported
1049
(userChecker, &supportForwarding, plContext),
1050
PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
1052
if (supportForwarding == PKIX_FALSE) {
1055
(PKIX_CertChainChecker_GetSupportedExtensions
1056
(userChecker, &userCheckerExtOIDs, plContext),
1057
PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
1059
if (userCheckerExtOIDs != NULL) {
1060
PKIX_CHECK(pkix_List_AppendList
1061
(validateCheckedCritExtOIDsList,
1064
PKIX_LISTAPPENDLISTFAILED);
1068
PKIX_DECREF(userCheckerExtOIDs);
1069
PKIX_DECREF(userChecker);
1073
PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
1074
(procParams, &revChecker, plContext),
1075
PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
1077
/* try to validate the chain with each anchor */
1078
for (i = 0; i < numAnchors; i++){
1080
/* get trust anchor */
1081
PKIX_CHECK(PKIX_List_GetItem
1082
(anchors, i, (PKIX_PL_Object **)&anchor, plContext),
1083
PKIX_LISTGETITEMFAILED);
1085
/* initialize checkers using information from trust anchor */
1086
PKIX_CHECK(pkix_InitializeCheckers
1087
(anchor, procParams, numCerts, &checkers, plContext),
1088
PKIX_INITIALIZECHECKERSFAILED);
1091
* Validate the chain using this trust anchor and these
1092
* checkers. (WARNING: checkers that use non-blocking I/O
1093
* are not currently supported.)
1095
certCheckedIndex = 0;
1097
revChecking = PKIX_FALSE;
1098
chainFailed = pkix_CheckChain
1104
validateCheckedCritExtOIDsList,
1116
if (chainFailed || (reasonCode != 0)) {
1118
/* cert chain failed to validate */
1120
PKIX_DECREF(chainFailed);
1121
PKIX_DECREF(anchor);
1122
PKIX_DECREF(checkers);
1123
PKIX_DECREF(validPolicyTree);
1125
/* if last anchor, we fail; else, we try next anchor */
1126
if (i == (numAnchors - 1)) { /* last anchor */
1127
PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
1132
/* cert chain successfully validated! */
1133
PKIX_CHECK(pkix_ValidateResult_Create
1139
PKIX_VALIDATERESULTCREATEFAILED);
1141
*pResult = valResult;
1143
/* no need to try any more anchors in the loop */
1150
PKIX_DECREF(finalPubKey);
1152
PKIX_DECREF(anchors);
1153
PKIX_DECREF(anchor);
1154
PKIX_DECREF(checkers);
1155
PKIX_DECREF(revChecker);
1156
PKIX_DECREF(validPolicyTree);
1157
PKIX_DECREF(chainFailed);
1158
PKIX_DECREF(procParams);
1159
PKIX_DECREF(userCheckers);
1160
PKIX_DECREF(validateCheckedCritExtOIDsList);
1162
PKIX_RETURN(VALIDATE);
1166
* FUNCTION: pkix_Validate_BuildUserOIDs
1169
* This function creates a List of the OIDs that are processed by the user
1170
* checkers in the List pointed to by "userCheckers", storing the resulting
1171
* List at "pUserCritOIDs". If the List of userCheckers is NULL, the output
1172
* List will be NULL. Otherwise the output List will be non-NULL, but may be
1177
* The address of the List of userCheckers.
1179
* The address at which the List is stored. Must be non-NULL.
1181
* Platform-specific context pointer.
1183
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1185
* Returns NULL if the function succeeds.
1186
* Returns a VALIDATE Error if the function fails in a non-fatal way.
1187
* Returns a Fatal Error if the function fails in an unrecoverable way.
1190
pkix_Validate_BuildUserOIDs(
1191
PKIX_List *userCheckers,
1192
PKIX_List **pUserCritOIDs,
1195
PKIX_UInt32 numUserCheckers = 0;
1197
PKIX_List *userCritOIDs = NULL;
1198
PKIX_List *userCheckerExtOIDs = NULL;
1199
PKIX_Boolean supportForwarding = PKIX_FALSE;
1200
PKIX_CertChainChecker *userChecker = NULL;
1202
PKIX_ENTER(VALIDATE, "pkix_Validate_BuildUserOIDs");
1203
PKIX_NULLCHECK_ONE(pUserCritOIDs);
1205
if (userCheckers != NULL) {
1206
PKIX_CHECK(PKIX_List_Create(&userCritOIDs, plContext),
1207
PKIX_LISTCREATEFAILED);
1209
PKIX_CHECK(PKIX_List_GetLength
1210
(userCheckers, &numUserCheckers, plContext),
1211
PKIX_LISTGETLENGTHFAILED);
1213
for (i = 0; i < numUserCheckers; i++) {
1214
PKIX_CHECK(PKIX_List_GetItem
1217
(PKIX_PL_Object **) &userChecker,
1219
PKIX_LISTGETITEMFAILED);
1221
PKIX_CHECK(PKIX_CertChainChecker_IsForwardCheckingSupported
1222
(userChecker, &supportForwarding, plContext),
1223
PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
1225
if (supportForwarding == PKIX_FALSE) {
1227
PKIX_CHECK(PKIX_CertChainChecker_GetSupportedExtensions
1228
(userChecker, &userCheckerExtOIDs, plContext),
1229
PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
1231
if (userCheckerExtOIDs != NULL) {
1232
PKIX_CHECK(pkix_List_AppendList
1233
(userCritOIDs, userCheckerExtOIDs, plContext),
1234
PKIX_LISTAPPENDLISTFAILED);
1238
PKIX_DECREF(userCheckerExtOIDs);
1239
PKIX_DECREF(userChecker);
1243
*pUserCritOIDs = userCritOIDs;
1247
if (PKIX_ERROR_RECEIVED){
1248
PKIX_DECREF(userCritOIDs);
1251
PKIX_DECREF(userCheckerExtOIDs);
1252
PKIX_DECREF(userChecker);
1254
PKIX_RETURN(VALIDATE);
1258
* FUNCTION: PKIX_ValidateChain_nb (see comments in pkix.h)
1261
PKIX_ValidateChain_NB(
1262
PKIX_ValidateParams *valParams,
1263
PKIX_UInt32 *pCertIndex,
1264
PKIX_UInt32 *pAnchorIndex,
1265
PKIX_UInt32 *pCheckerIndex,
1266
PKIX_Boolean *pRevChecking,
1267
PKIX_List **pCheckers,
1268
void **pNBIOContext,
1269
PKIX_ValidateResult **pResult,
1270
PKIX_VerifyNode **pVerifyTree,
1273
PKIX_UInt32 numCerts = 0;
1274
PKIX_UInt32 numAnchors = 0;
1276
PKIX_UInt32 certIndex = 0;
1277
PKIX_UInt32 anchorIndex = 0;
1278
PKIX_UInt32 checkerIndex = 0;
1279
PKIX_UInt32 reasonCode = 0;
1280
PKIX_Boolean revChecking = PKIX_FALSE;
1281
PKIX_List *certs = NULL;
1282
PKIX_List *anchors = NULL;
1283
PKIX_List *checkers = NULL;
1284
PKIX_List *userCheckers = NULL;
1285
PKIX_List *validateCheckedCritExtOIDsList = NULL;
1286
PKIX_TrustAnchor *anchor = NULL;
1287
PKIX_ValidateResult *valResult = NULL;
1288
PKIX_PL_PublicKey *finalPubKey = NULL;
1289
PKIX_PolicyNode *validPolicyTree = NULL;
1290
PKIX_ProcessingParams *procParams = NULL;
1291
PKIX_RevocationChecker *revChecker = NULL;
1292
PKIX_Error *chainFailed = NULL;
1293
void *nbioContext = NULL;
1295
PKIX_ENTER(VALIDATE, "PKIX_ValidateChain_NB");
1297
(valParams, pCertIndex, pAnchorIndex, pCheckerIndex);
1298
PKIX_NULLCHECK_FOUR(pRevChecking, pCheckers, pNBIOContext, pResult);
1300
nbioContext = *pNBIOContext;
1301
*pNBIOContext = NULL;
1303
/* extract various parameters from valParams */
1304
PKIX_CHECK(pkix_ExtractParameters
1312
PKIX_EXTRACTPARAMETERSFAILED);
1315
* Create a List of the OIDs that will be processed by the user
1316
* checkers. User checkers are not responsible for removing OIDs from
1317
* the List of unresolved critical extensions, as libpkix checkers are.
1318
* So we add those user checkers' OIDs to the removal list to be taken
1319
* out by CheckChain.
1321
PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
1322
(procParams, &userCheckers, plContext),
1323
PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
1325
PKIX_CHECK(pkix_Validate_BuildUserOIDs
1326
(userCheckers, &validateCheckedCritExtOIDsList, plContext),
1327
PKIX_VALIDATEBUILDUSEROIDSFAILED);
1329
PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
1330
(procParams, &revChecker, plContext),
1331
PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
1333
/* Are we resuming after a WOULDBLOCK return, or starting anew ? */
1334
if (nbioContext != NULL) {
1336
certIndex = *pCertIndex;
1337
anchorIndex = *pAnchorIndex;
1338
checkerIndex = *pCheckerIndex;
1339
revChecking = *pRevChecking;
1340
checkers = *pCheckers;
1344
/* try to validate the chain with each anchor */
1345
for (i = anchorIndex; i < numAnchors; i++) {
1347
/* get trust anchor */
1348
PKIX_CHECK(PKIX_List_GetItem
1349
(anchors, i, (PKIX_PL_Object **)&anchor, plContext),
1350
PKIX_LISTGETITEMFAILED);
1352
/* initialize checkers using information from trust anchor */
1353
if (nbioContext == NULL) {
1354
PKIX_CHECK(pkix_InitializeCheckers
1360
PKIX_INITIALIZECHECKERSFAILED);
1364
* Validate the chain using this trust anchor and these
1367
chainFailed = pkix_CheckChain
1373
validateCheckedCritExtOIDsList,
1385
if (nbioContext != NULL) {
1386
*pCertIndex = certIndex;
1387
*pAnchorIndex = anchorIndex;
1388
*pCheckerIndex = checkerIndex;
1389
*pRevChecking = revChecking;
1390
PKIX_INCREF(checkers);
1391
*pCheckers = checkers;
1392
*pNBIOContext = nbioContext;
1396
if (chainFailed || (reasonCode != 0)) {
1398
/* cert chain failed to validate */
1400
PKIX_DECREF(chainFailed);
1401
PKIX_DECREF(anchor);
1402
PKIX_DECREF(checkers);
1403
PKIX_DECREF(validPolicyTree);
1405
/* if last anchor, we fail; else, we try next anchor */
1406
if (i == (numAnchors - 1)) { /* last anchor */
1407
PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
1412
/* cert chain successfully validated! */
1413
PKIX_CHECK(pkix_ValidateResult_Create
1419
PKIX_VALIDATERESULTCREATEFAILED);
1421
*pResult = valResult;
1423
/* no need to try any more anchors in the loop */
1430
PKIX_DECREF(finalPubKey);
1432
PKIX_DECREF(anchors);
1433
PKIX_DECREF(anchor);
1434
PKIX_DECREF(checkers);
1435
PKIX_DECREF(revChecker);
1436
PKIX_DECREF(validPolicyTree);
1437
PKIX_DECREF(chainFailed);
1438
PKIX_DECREF(procParams);
1439
PKIX_DECREF(userCheckers);
1440
PKIX_DECREF(validateCheckedCritExtOIDsList);
1442
PKIX_RETURN(VALIDATE);