PageRenderTime 90ms CodeModel.GetById 16ms app.highlight 64ms RepoModel.GetById 1ms app.codeStats 1ms

/security/nss/lib/libpkix/pkix/top/pkix_validate.c

http://github.com/zpao/v8monkey
C | 1404 lines | 827 code | 191 blank | 386 comment | 77 complexity | e122c38f113215b5fc747c313b5b015a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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 */
  82static PKIX_Error *
  83pkix_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
 112cleanup:
 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 */
 161static PKIX_Error *
 162pkix_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
 262cleanup:
 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 */
 300static PKIX_Error *
 301pkix_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
 502cleanup:
 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 */
 555static PKIX_Error *
 556pkix_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
 622cleanup:
 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 */
 711PKIX_Error *
 712pkix_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_FALSE,
 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
 831cleanup:
 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
 844fatal:
 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 */
 888static PKIX_Error *
 889pkix_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
 922cleanup:
 923
 924        PKIX_RETURN(VALIDATE);
 925}
 926
 927/* --Public-Functions--------------------------------------------- */
 928
 929/*
 930 * FUNCTION: PKIX_ValidateChain (see comments in pkix.h)
 931 */
 932PKIX_Error *
 933PKIX_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
1109cleanup:
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 */
1150static PKIX_Error *
1151pkix_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
1206cleanup:
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 */
1221PKIX_Error *
1222PKIX_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    

Large files files are truncated, but you can click here to view the full file