| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 /* | |
| 5 * pkix_validate.c | |
| 6 * | |
| 7 * Top level validateChain function | |
| 8 * | |
| 9 */ | |
| 10 | |
| 11 #include "pkix_validate.h" | |
| 12 #include "pkix_pl_common.h" | |
| 13 | |
| 14 /* --Private-Functions-------------------------------------------- */ | |
| 15 | |
| 16 /* | |
| 17 * FUNCTION: pkix_AddToVerifyLog | |
| 18 * DESCRIPTION: | |
| 19 * | |
| 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. | |
| 25 * | |
| 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. | |
| 29 * | |
| 30 * PARAMETERS: | |
| 31 * "cert" | |
| 32 * The address of the Cert to be included in the new VerifyNode. Must be | |
| 33 * non-NULL. | |
| 34 * "depth" | |
| 35 * The UInt32 value of the depth. | |
| 36 * "error" | |
| 37 * The address of the Error to be included in the new VerifyNode. | |
| 38 * "pVerifyTree" | |
| 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. | |
| 41 * "plContext" | |
| 42 * Platform-specific context pointer. | |
| 43 * THREAD SAFETY: | |
| 44 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 45 * RETURNS: | |
| 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. | |
| 49 */ | |
| 50 static PKIX_Error * | |
| 51 pkix_AddToVerifyLog( | |
| 52 PKIX_PL_Cert *cert, | |
| 53 PKIX_UInt32 depth, | |
| 54 PKIX_Error *error, | |
| 55 PKIX_VerifyNode **pVerifyTree, | |
| 56 void *plContext) | |
| 57 { | |
| 58 | |
| 59 PKIX_VerifyNode *verifyNode = NULL; | |
| 60 | |
| 61 PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog"); | |
| 62 PKIX_NULLCHECK_ONE(cert); | |
| 63 | |
| 64 if (pVerifyTree) { /* nothing to do if no address given for log */ | |
| 65 | |
| 66 PKIX_CHECK(pkix_VerifyNode_Create | |
| 67 (cert, depth, error, &verifyNode, plContext), | |
| 68 PKIX_VERIFYNODECREATEFAILED); | |
| 69 | |
| 70 if (depth == 0) { | |
| 71 /* We just created the root node */ | |
| 72 *pVerifyTree = verifyNode; | |
| 73 } else { | |
| 74 PKIX_CHECK(pkix_VerifyNode_AddToChain | |
| 75 (*pVerifyTree, verifyNode, plContext), | |
| 76 PKIX_VERIFYNODEADDTOCHAINFAILED); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 cleanup: | |
| 81 | |
| 82 PKIX_RETURN(VALIDATE); | |
| 83 | |
| 84 } | |
| 85 | |
| 86 /* | |
| 87 * FUNCTION: pkix_CheckCert | |
| 88 * DESCRIPTION: | |
| 89 * | |
| 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. | |
| 93 * | |
| 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". | |
| 102 * | |
| 103 * PARAMETERS: | |
| 104 * "cert" | |
| 105 * Address of Cert to validate. Must be non-NULL. | |
| 106 * "checkers" | |
| 107 * List of CertChainCheckers which must each validate the certificate. | |
| 108 * Must be non-NULL. | |
| 109 * "checkedExtOIDs" | |
| 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. | |
| 113 * "pCheckerIndex" | |
| 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. | |
| 116 * Must be non-NULL. | |
| 117 * "pNBIOContext" | |
| 118 * Address at which is stored platform-specific non-blocking I/O context. | |
| 119 * Must be non-NULL. | |
| 120 * "plContext" | |
| 121 * Platform-specific context pointer. | |
| 122 * THREAD SAFETY: | |
| 123 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 124 * RETURNS: | |
| 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. | |
| 128 */ | |
| 129 static PKIX_Error * | |
| 130 pkix_CheckCert( | |
| 131 PKIX_PL_Cert *cert, | |
| 132 PKIX_List *checkers, | |
| 133 PKIX_List *checkedExtOIDsList, | |
| 134 PKIX_UInt32 *pCheckerIndex, | |
| 135 void **pNBIOContext, | |
| 136 void *plContext) | |
| 137 { | |
| 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; | |
| 145 | |
| 146 PKIX_ENTER(VALIDATE, "pkix_CheckCert"); | |
| 147 PKIX_NULLCHECK_FOUR(cert, checkers, pCheckerIndex, pNBIOContext); | |
| 148 | |
| 149 nbioContext = *pNBIOContext; | |
| 150 *pNBIOContext = NULL; /* prepare for case of error exit */ | |
| 151 | |
| 152 PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs | |
| 153 (cert, &unresCritExtOIDs, plContext), | |
| 154 PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED); | |
| 155 | |
| 156 PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext), | |
| 157 PKIX_LISTGETLENGTHFAILED); | |
| 158 | |
| 159 for (checkerIndex = *pCheckerIndex; | |
| 160 checkerIndex < numCheckers; | |
| 161 checkerIndex++) { | |
| 162 | |
| 163 PKIX_CHECK(PKIX_List_GetItem | |
| 164 (checkers, | |
| 165 checkerIndex, | |
| 166 (PKIX_PL_Object **)&checker, | |
| 167 plContext), | |
| 168 PKIX_LISTGETITEMFAILED); | |
| 169 | |
| 170 PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback | |
| 171 (checker, &checkerCheck, plContext), | |
| 172 PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED); | |
| 173 | |
| 174 PKIX_CHECK(checkerCheck(checker, cert, unresCritExtOIDs, | |
| 175 &nbioContext, plContext), | |
| 176 PKIX_CERTCHAINCHECKERCHECKFAILED); | |
| 177 | |
| 178 if (nbioContext != NULL) { | |
| 179 *pCheckerIndex = checkerIndex; | |
| 180 *pNBIOContext = nbioContext; | |
| 181 goto cleanup; | |
| 182 } | |
| 183 | |
| 184 PKIX_DECREF(checker); | |
| 185 } | |
| 186 | |
| 187 if (unresCritExtOIDs){ | |
| 188 | |
| 189 #ifdef PKIX_VALIDATEDEBUG | |
| 190 { | |
| 191 PKIX_PL_String *oidString = NULL; | |
| 192 PKIX_UInt32 length; | |
| 193 char *oidAscii = NULL; | |
| 194 PKIX_TOSTRING(unresCritExtOIDs, &oidString, plContext, | |
| 195 PKIX_LISTTOSTRINGFAILED); | |
| 196 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
| 197 (oidString, | |
| 198 PKIX_ESCASCII, | |
| 199 (void **) &oidAscii, | |
| 200 &length, | |
| 201 plContext), | |
| 202 PKIX_STRINGGETENCODEDFAILED); | |
| 203 PKIX_VALIDATE_DEBUG_ARG | |
| 204 ("unrecognized critical extension OIDs:" | |
| 205 " %s\n", oidAscii); | |
| 206 PKIX_DECREF(oidString); | |
| 207 PKIX_PL_Free(oidAscii, plContext); | |
| 208 } | |
| 209 #endif | |
| 210 | |
| 211 if (checkedExtOIDsList != NULL) { | |
| 212 /* Take out OID's that had been processed, if any */ | |
| 213 PKIX_CHECK(pkix_List_RemoveItems | |
| 214 (unresCritExtOIDs, | |
| 215 checkedExtOIDsList, | |
| 216 plContext), | |
| 217 PKIX_LISTREMOVEITEMSFAILED); | |
| 218 } | |
| 219 | |
| 220 PKIX_CHECK(PKIX_List_GetLength | |
| 221 (unresCritExtOIDs, &numUnresCritExtOIDs, plContext), | |
| 222 PKIX_LISTGETLENGTHFAILED); | |
| 223 | |
| 224 if (numUnresCritExtOIDs != 0){ | |
| 225 PKIX_ERROR(PKIX_UNRECOGNIZEDCRITICALEXTENSION); | |
| 226 } | |
| 227 | |
| 228 } | |
| 229 | |
| 230 cleanup: | |
| 231 | |
| 232 PKIX_DECREF(checker); | |
| 233 PKIX_DECREF(unresCritExtOIDs); | |
| 234 | |
| 235 PKIX_RETURN(VALIDATE); | |
| 236 | |
| 237 } | |
| 238 | |
| 239 /* | |
| 240 * FUNCTION: pkix_InitializeCheckers | |
| 241 * DESCRIPTION: | |
| 242 * | |
| 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". | |
| 247 * | |
| 248 * PARAMETERS: | |
| 249 * "anchor" | |
| 250 * Address of TrustAnchor used to initialize the SignatureChecker and | |
| 251 * NameChainingChecker. Must be non-NULL. | |
| 252 * "procParams" | |
| 253 * Address of ProcessingParams used to initialize the ExpirationChecker | |
| 254 * and TargetCertChecker. Must be non-NULL. | |
| 255 * "numCerts" | |
| 256 * Number of certificates in the CertChain. | |
| 257 * "pCheckers" | |
| 258 * Address where object pointer will be stored. Must be non-NULL. | |
| 259 * "plContext" | |
| 260 * Platform-specific context pointer. | |
| 261 * THREAD SAFETY: | |
| 262 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 263 * RETURNS: | |
| 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. | |
| 267 */ | |
| 268 static PKIX_Error * | |
| 269 pkix_InitializeCheckers( | |
| 270 PKIX_TrustAnchor *anchor, | |
| 271 PKIX_ProcessingParams *procParams, | |
| 272 PKIX_UInt32 numCerts, | |
| 273 PKIX_List **pCheckers, | |
| 274 void *plContext) | |
| 275 { | |
| 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; | |
| 300 PKIX_UInt32 i; | |
| 301 | |
| 302 PKIX_ENTER(VALIDATE, "pkix_InitializeCheckers"); | |
| 303 PKIX_NULLCHECK_THREE(anchor, procParams, pCheckers); | |
| 304 PKIX_CHECK(PKIX_List_Create(&checkers, plContext), | |
| 305 PKIX_LISTCREATEFAILED); | |
| 306 | |
| 307 /* | |
| 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. | |
| 313 */ | |
| 314 | |
| 315 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert | |
| 316 (anchor, &trustedCert, plContext), | |
| 317 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); | |
| 318 | |
| 319 if (trustedCert){ | |
| 320 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey | |
| 321 (trustedCert, &trustedPubKey, plContext), | |
| 322 PKIX_CERTGETSUBJECTPUBLICKEYFAILED); | |
| 323 | |
| 324 PKIX_CHECK(PKIX_PL_Cert_GetSubject | |
| 325 (trustedCert, &trustedCAName, plContext), | |
| 326 PKIX_CERTGETSUBJECTFAILED); | |
| 327 } else { | |
| 328 PKIX_CHECK(PKIX_TrustAnchor_GetCAPublicKey | |
| 329 (anchor, &trustedPubKey, plContext), | |
| 330 PKIX_TRUSTANCHORGETCAPUBLICKEYFAILED); | |
| 331 | |
| 332 PKIX_CHECK(PKIX_TrustAnchor_GetCAName | |
| 333 (anchor, &trustedCAName, plContext), | |
| 334 PKIX_TRUSTANCHORGETCANAMEFAILED); | |
| 335 } | |
| 336 | |
| 337 PKIX_NULLCHECK_TWO(trustedPubKey, trustedCAName); | |
| 338 | |
| 339 PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints | |
| 340 (anchor, &trustedNC, plContext), | |
| 341 PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED); | |
| 342 | |
| 343 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints | |
| 344 (procParams, &certSelector, plContext), | |
| 345 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); | |
| 346 | |
| 347 PKIX_CHECK(PKIX_ProcessingParams_GetDate | |
| 348 (procParams, &testDate, plContext), | |
| 349 PKIX_PROCESSINGPARAMSGETDATEFAILED); | |
| 350 | |
| 351 PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies | |
| 352 (procParams, &initialPolicies, plContext), | |
| 353 PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED); | |
| 354 | |
| 355 PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected | |
| 356 (procParams, &policyQualifiersRejected, plContext), | |
| 357 PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED); | |
| 358 | |
| 359 PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited | |
| 360 (procParams, &initialPolicyMappingInhibit, plContext), | |
| 361 PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED); | |
| 362 | |
| 363 PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited | |
| 364 (procParams, &initialAnyPolicyInhibit, plContext), | |
| 365 PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED); | |
| 366 | |
| 367 PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired | |
| 368 (procParams, &initialExplicitPolicy, plContext), | |
| 369 PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED); | |
| 370 | |
| 371 PKIX_CHECK(PKIX_ProcessingParams_GetCertStores | |
| 372 (procParams, &certStores, plContext), | |
| 373 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED); | |
| 374 | |
| 375 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers | |
| 376 (procParams, &userCheckersList, plContext), | |
| 377 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); | |
| 378 | |
| 379 /* now, initialize all the checkers */ | |
| 380 PKIX_CHECK(pkix_TargetCertChecker_Initialize | |
| 381 (certSelector, numCerts, &targetCertChecker, plContext), | |
| 382 PKIX_TARGETCERTCHECKERINITIALIZEFAILED); | |
| 383 | |
| 384 PKIX_CHECK(pkix_ExpirationChecker_Initialize | |
| 385 (testDate, &expirationChecker, plContext), | |
| 386 PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); | |
| 387 | |
| 388 PKIX_CHECK(pkix_NameChainingChecker_Initialize | |
| 389 (trustedCAName, &nameChainingChecker, plContext), | |
| 390 PKIX_NAMECHAININGCHECKERINITIALIZEFAILED); | |
| 391 | |
| 392 PKIX_CHECK(pkix_NameConstraintsChecker_Initialize | |
| 393 (trustedNC, numCerts, &nameConstraintsChecker, plContext), | |
| 394 PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED); | |
| 395 | |
| 396 PKIX_CHECK(pkix_BasicConstraintsChecker_Initialize | |
| 397 (numCerts, &basicConstraintsChecker, plContext), | |
| 398 PKIX_BASICCONSTRAINTSCHECKERINITIALIZEFAILED); | |
| 399 | |
| 400 PKIX_CHECK(pkix_PolicyChecker_Initialize | |
| 401 (initialPolicies, | |
| 402 policyQualifiersRejected, | |
| 403 initialPolicyMappingInhibit, | |
| 404 initialExplicitPolicy, | |
| 405 initialAnyPolicyInhibit, | |
| 406 numCerts, | |
| 407 &policyChecker, | |
| 408 plContext), | |
| 409 PKIX_POLICYCHECKERINITIALIZEFAILED); | |
| 410 | |
| 411 PKIX_CHECK(pkix_SignatureChecker_Initialize | |
| 412 (trustedPubKey, numCerts, &sigChecker, plContext), | |
| 413 PKIX_SIGNATURECHECKERINITIALIZEFAILED); | |
| 414 | |
| 415 if (userCheckersList != NULL) { | |
| 416 | |
| 417 PKIX_CHECK(PKIX_List_GetLength | |
| 418 (userCheckersList, &numCertCheckers, plContext), | |
| 419 PKIX_LISTGETLENGTHFAILED); | |
| 420 | |
| 421 for (i = 0; i < numCertCheckers; i++) { | |
| 422 | |
| 423 PKIX_CHECK(PKIX_List_GetItem | |
| 424 (userCheckersList, | |
| 425 i, | |
| 426 (PKIX_PL_Object **) &userChecker, | |
| 427 plContext), | |
| 428 PKIX_LISTGETITEMFAILED); | |
| 429 | |
| 430 PKIX_CHECK(PKIX_List_AppendItem | |
| 431 (checkers, | |
| 432 (PKIX_PL_Object *)userChecker, | |
| 433 plContext), | |
| 434 PKIX_LISTAPPENDITEMFAILED); | |
| 435 | |
| 436 PKIX_DECREF(userChecker); | |
| 437 } | |
| 438 } | |
| 439 | |
| 440 PKIX_CHECK(PKIX_List_AppendItem | |
| 441 (checkers, (PKIX_PL_Object *)targetCertChecker, plContext), | |
| 442 PKIX_LISTAPPENDITEMFAILED); | |
| 443 | |
| 444 PKIX_CHECK(PKIX_List_AppendItem | |
| 445 (checkers, (PKIX_PL_Object *)expirationChecker, plContext), | |
| 446 PKIX_LISTAPPENDITEMFAILED); | |
| 447 | |
| 448 PKIX_CHECK(PKIX_List_AppendItem | |
| 449 (checkers, (PKIX_PL_Object *)nameChainingChecker, plContext), | |
| 450 PKIX_LISTAPPENDITEMFAILED); | |
| 451 | |
| 452 PKIX_CHECK(PKIX_List_AppendItem | |
| 453 (checkers, (PKIX_PL_Object *)nameConstraintsChecker, plContext), | |
| 454 PKIX_LISTAPPENDITEMFAILED); | |
| 455 | |
| 456 PKIX_CHECK(PKIX_List_AppendItem | |
| 457 (checkers, (PKIX_PL_Object *)basicConstraintsChecker, plContext), | |
| 458 PKIX_LISTAPPENDITEMFAILED); | |
| 459 | |
| 460 PKIX_CHECK(PKIX_List_AppendItem | |
| 461 (checkers, (PKIX_PL_Object *)policyChecker, plContext), | |
| 462 PKIX_LISTAPPENDITEMFAILED); | |
| 463 | |
| 464 PKIX_CHECK(PKIX_List_AppendItem | |
| 465 (checkers, (PKIX_PL_Object *)sigChecker, plContext), | |
| 466 PKIX_LISTAPPENDITEMFAILED); | |
| 467 | |
| 468 *pCheckers = checkers; | |
| 469 | |
| 470 cleanup: | |
| 471 | |
| 472 if (PKIX_ERROR_RECEIVED){ | |
| 473 PKIX_DECREF(checkers); | |
| 474 } | |
| 475 | |
| 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); | |
| 494 | |
| 495 PKIX_RETURN(VALIDATE); | |
| 496 } | |
| 497 | |
| 498 /* | |
| 499 * FUNCTION: pkix_RetrieveOutputs | |
| 500 * DESCRIPTION: | |
| 501 * | |
| 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. | |
| 506 * | |
| 507 * PARAMETERS: | |
| 508 * "checkers" | |
| 509 * Address of List of checkers to be queried. Must be non-NULL. | |
| 510 * "pFinalSubjPubKey" | |
| 511 * Address where final public key will be stored. Must be non-NULL. | |
| 512 * "pPolicyTree" | |
| 513 * Address where policy tree will be stored. Must be non-NULL. | |
| 514 * "plContext" | |
| 515 * Platform-specific context pointer. | |
| 516 * THREAD SAFETY: | |
| 517 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 518 * RETURNS: | |
| 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. | |
| 522 */ | |
| 523 static PKIX_Error * | |
| 524 pkix_RetrieveOutputs( | |
| 525 PKIX_List *checkers, | |
| 526 PKIX_PL_PublicKey **pFinalSubjPubKey, | |
| 527 PKIX_PolicyNode **pPolicyTree, | |
| 528 void *plContext) | |
| 529 { | |
| 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; | |
| 535 PKIX_UInt32 type; | |
| 536 PKIX_Int32 j; | |
| 537 | |
| 538 PKIX_ENTER(VALIDATE, "pkix_RetrieveOutputs"); | |
| 539 | |
| 540 PKIX_NULLCHECK_TWO(checkers, pPolicyTree); | |
| 541 | |
| 542 /* | |
| 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). | |
| 547 */ | |
| 548 | |
| 549 PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext), | |
| 550 PKIX_LISTGETLENGTHFAILED); | |
| 551 | |
| 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); | |
| 556 | |
| 557 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState | |
| 558 (checker, &state, plContext), | |
| 559 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); | |
| 560 | |
| 561 /* user defined checker may have no state */ | |
| 562 if (state != NULL) { | |
| 563 | |
| 564 PKIX_CHECK(PKIX_PL_Object_GetType(state, &type, plContext), | |
| 565 PKIX_OBJECTGETTYPEFAILED); | |
| 566 | |
| 567 if (type == PKIX_SIGNATURECHECKERSTATE_TYPE){ | |
| 568 /* final pubKey will include any inherited DSA params */ | |
| 569 finalSubjPubKey = | |
| 570 ((pkix_SignatureCheckerState *)state)-> | |
| 571 prevPublicKey; | |
| 572 PKIX_INCREF(finalSubjPubKey); | |
| 573 *pFinalSubjPubKey = finalSubjPubKey; | |
| 574 } | |
| 575 | |
| 576 if (type == PKIX_CERTPOLICYCHECKERSTATE_TYPE) { | |
| 577 validPolicyTree = | |
| 578 ((PKIX_PolicyCheckerState *)state)->validPolicyTree; | |
| 579 break; | |
| 580 } | |
| 581 } | |
| 582 | |
| 583 PKIX_DECREF(checker); | |
| 584 PKIX_DECREF(state); | |
| 585 } | |
| 586 | |
| 587 PKIX_INCREF(validPolicyTree); | |
| 588 *pPolicyTree = validPolicyTree; | |
| 589 | |
| 590 cleanup: | |
| 591 | |
| 592 PKIX_DECREF(checker); | |
| 593 PKIX_DECREF(state); | |
| 594 | |
| 595 PKIX_RETURN(VALIDATE); | |
| 596 | |
| 597 } | |
| 598 | |
| 599 /* | |
| 600 * FUNCTION: pkix_CheckChain | |
| 601 * DESCRIPTION: | |
| 602 * | |
| 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. | |
| 620 * | |
| 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. | |
| 625 * | |
| 626 * The number of Certs in the List, represented by "numCerts", is used to | |
| 627 * determine which Cert is the final Cert. | |
| 628 * | |
| 629 * PARAMETERS: | |
| 630 * "certs" | |
| 631 * Address of List of Certs to validate. Must be non-NULL. | |
| 632 * "numCerts" | |
| 633 * Number of certificates in the List of certificates. | |
| 634 * "checkers" | |
| 635 * List of CertChainCheckers which must each validate the List of | |
| 636 * certificates. Must be non-NULL. | |
| 637 * "revChecker" | |
| 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. | |
| 645 * "procParams" | |
| 646 * Address of ProcessingParams used to initialize various checkers. Must | |
| 647 * be non-NULL. | |
| 648 * "pCertCheckedIndex" | |
| 649 * Address where Int32 index to the Cert chain is obtained and | |
| 650 * returned. Must be non-NULL. | |
| 651 * "pCheckerIndex" | |
| 652 * Address where Int32 index to the CheckerChain is obtained and | |
| 653 * returned. Must be non-NULL. | |
| 654 * "pRevChecking" | |
| 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. | |
| 658 * "pReasonCode" | |
| 659 * Address where UInt32 results of revocation checking are stored. Must be | |
| 660 * non-NULL. | |
| 661 * "pNBIOContext" | |
| 662 * Address where platform-dependent context is stored if checking is | |
| 663 * suspended for non-blocking I/O. Must be non-NULL. | |
| 664 * "pFinalSubjPubKey" | |
| 665 * Address where the final public key will be stored. Must be non-NULL. | |
| 666 * "pPolicyTree" | |
| 667 * Address where the final validPolicyTree is stored. Must be non-NULL. | |
| 668 * "pVerifyTree" | |
| 669 * Address where a VerifyTree is stored, if non-NULL. | |
| 670 * "plContext" | |
| 671 * Platform-specific context pointer. | |
| 672 * THREAD SAFETY: | |
| 673 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 674 * RETURNS: | |
| 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. | |
| 678 */ | |
| 679 PKIX_Error * | |
| 680 pkix_CheckChain( | |
| 681 PKIX_List *certs, | |
| 682 PKIX_UInt32 numCerts, | |
| 683 PKIX_TrustAnchor *anchor, | |
| 684 PKIX_List *checkers, | |
| 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, | |
| 692 void **pNBIOContext, | |
| 693 PKIX_PL_PublicKey **pFinalSubjPubKey, | |
| 694 PKIX_PolicyNode **pPolicyTree, | |
| 695 PKIX_VerifyNode **pVerifyTree, | |
| 696 void *plContext) | |
| 697 { | |
| 698 PKIX_UInt32 j = 0; | |
| 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; | |
| 708 | |
| 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); | |
| 713 | |
| 714 nbioContext = *pNBIOContext; | |
| 715 *pNBIOContext = NULL; | |
| 716 revChecking = *pRevChecking; | |
| 717 nssContext = (PKIX_PL_NssContext *)plContext; | |
| 718 chainVerifyCallback = &nssContext->chainVerifyCallback; | |
| 719 | |
| 720 if (chainVerifyCallback->isChainValid != NULL) { | |
| 721 PRBool chainOK = PR_FALSE; /*assume failure*/ | |
| 722 SECStatus rv; | |
| 723 | |
| 724 certList = CERT_NewCertList(); | |
| 725 if (certList == NULL) { | |
| 726 PKIX_ERROR_ALLOC_ERROR(); | |
| 727 } | |
| 728 | |
| 729 /* Add the trust anchor to the list */ | |
| 730 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert | |
| 731 (anchor, &cert, plContext), | |
| 732 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); | |
| 733 | |
| 734 PKIX_CHECK( | |
| 735 PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContex
t), | |
| 736 PKIX_CERTGETCERTCERTIFICATEFAILED); | |
| 737 | |
| 738 rv = CERT_AddCertToListHead(certList, nssCert); | |
| 739 if (rv != SECSuccess) { | |
| 740 PKIX_ERROR_ALLOC_ERROR(); | |
| 741 } | |
| 742 /* the certList takes ownership of nssCert on success */ | |
| 743 nssCert = NULL; | |
| 744 PKIX_DECREF(cert); | |
| 745 | |
| 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); | |
| 751 | |
| 752 PKIX_CHECK( | |
| 753 PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert,
plContext), | |
| 754 PKIX_CERTGETCERTCERTIFICATEFAILED); | |
| 755 | |
| 756 rv = CERT_AddCertToListHead(certList, nssCert); | |
| 757 if (rv != SECSuccess) { | |
| 758 PKIX_ERROR_ALLOC_ERROR(); | |
| 759 } | |
| 760 /* the certList takes ownership of nssCert on success */ | |
| 761 nssCert = NULL; | |
| 762 PKIX_DECREF(cert); | |
| 763 } | |
| 764 | |
| 765 rv = (*chainVerifyCallback->isChainValid) | |
| 766 (chainVerifyCallback->isChainValidArg, certList, &chainOK); | |
| 767 if (rv != SECSuccess) { | |
| 768 PKIX_ERROR_FATAL(PKIX_CHAINVERIFYCALLBACKFAILED); | |
| 769 } | |
| 770 | |
| 771 if (!chainOK) { | |
| 772 PKIX_ERROR(PKIX_CHAINVERIFYCALLBACKFAILED); | |
| 773 } | |
| 774 | |
| 775 } | |
| 776 | |
| 777 PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert | |
| 778 (anchor, &cert, plContext), | |
| 779 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); | |
| 780 | |
| 781 for (j = *pCertCheckedIndex; j < numCerts; j++) { | |
| 782 | |
| 783 PORT_Assert(cert); | |
| 784 PKIX_DECREF(issuer); | |
| 785 issuer = cert; | |
| 786 cert = NULL; | |
| 787 | |
| 788 PKIX_CHECK(PKIX_List_GetItem( | |
| 789 certs, j, (PKIX_PL_Object **)&cert, plContext), | |
| 790 PKIX_LISTGETITEMFAILED); | |
| 791 | |
| 792 /* check if cert pointer is valid */ | |
| 793 PORT_Assert(cert); | |
| 794 if (cert == NULL) { | |
| 795 continue; | |
| 796 } | |
| 797 | |
| 798 if (revChecking == PKIX_FALSE) { | |
| 799 | |
| 800 PKIX_CHECK(pkix_CheckCert | |
| 801 (cert, | |
| 802 checkers, | |
| 803 removeCheckedExtOIDs, | |
| 804 pCheckerIndex, | |
| 805 &nbioContext, | |
| 806 plContext), | |
| 807 PKIX_CHECKCERTFAILED); | |
| 808 | |
| 809 if (nbioContext != NULL) { | |
| 810 *pCertCheckedIndex = j; | |
| 811 *pRevChecking = revChecking; | |
| 812 *pNBIOContext = nbioContext; | |
| 813 goto cleanup; | |
| 814 } | |
| 815 | |
| 816 revChecking = PKIX_TRUE; | |
| 817 *pCheckerIndex = 0; | |
| 818 } | |
| 819 | |
| 820 if (revChecking == PKIX_TRUE) { | |
| 821 PKIX_RevocationStatus revStatus; | |
| 822 pkixErrorResult = | |
| 823 PKIX_RevocationChecker_Check( | |
| 824 cert, issuer, revChecker, | |
| 825 procParams, PKIX_TRUE, | |
| 826 (j == numCerts - 1) ? PKIX_TRUE : PKIX_FAL
SE, | |
| 827 &revStatus, pReasonCode, | |
| 828 &nbioContext, plContext); | |
| 829 if (nbioContext != NULL) { | |
| 830 *pCertCheckedIndex = j; | |
| 831 *pRevChecking = revChecking; | |
| 832 *pNBIOContext = nbioContext; | |
| 833 goto cleanup; | |
| 834 } | |
| 835 if (revStatus == PKIX_RevStatus_Revoked || | |
| 836 pkixErrorResult) { | |
| 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, | |
| 843 pkixErrorResult); | |
| 844 } | |
| 845 goto cleanup; | |
| 846 } | |
| 847 revChecking = PKIX_FALSE; | |
| 848 *pCheckerIndex = 0; | |
| 849 } | |
| 850 | |
| 851 PKIX_CHECK(pkix_AddToVerifyLog | |
| 852 (cert, j, NULL, pVerifyTree, plContext), | |
| 853 PKIX_ADDTOVERIFYLOGFAILED); | |
| 854 } | |
| 855 | |
| 856 PKIX_CHECK(pkix_RetrieveOutputs | |
| 857 (checkers, pFinalSubjPubKey, pPolicyTree, plContext), | |
| 858 PKIX_RETRIEVEOUTPUTSFAILED); | |
| 859 | |
| 860 *pNBIOContext = NULL; | |
| 861 | |
| 862 cleanup: | |
| 863 if (PKIX_ERROR_RECEIVED && cert) { | |
| 864 checkCertError = pkixErrorResult; | |
| 865 | |
| 866 PKIX_CHECK_FATAL( | |
| 867 pkix_AddToVerifyLog(cert, j, checkCertError, pVerifyTree, | |
| 868 plContext), | |
| 869 PKIX_ADDTOVERIFYLOGFAILED); | |
| 870 pkixErrorResult = checkCertError; | |
| 871 pkixErrorCode = pkixErrorResult->errCode; | |
| 872 checkCertError = NULL; | |
| 873 } | |
| 874 | |
| 875 fatal: | |
| 876 if (nssCert) { | |
| 877 CERT_DestroyCertificate(nssCert); | |
| 878 } | |
| 879 | |
| 880 if (certList) { | |
| 881 CERT_DestroyCertList(certList); | |
| 882 } | |
| 883 | |
| 884 PKIX_DECREF(checkCertError); | |
| 885 PKIX_DECREF(cert); | |
| 886 PKIX_DECREF(issuer); | |
| 887 | |
| 888 PKIX_RETURN(VALIDATE); | |
| 889 } | |
| 890 | |
| 891 /* | |
| 892 * FUNCTION: pkix_ExtractParameters | |
| 893 * DESCRIPTION: | |
| 894 * | |
| 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". | |
| 900 * | |
| 901 * PARAMETERS: | |
| 902 * "valParams" | |
| 903 * Address of ValidateParams from which the parameters are extracted. | |
| 904 * Must be non-NULL. | |
| 905 * "pCerts" | |
| 906 * Address where object pointer for List of Certs will be stored. | |
| 907 * Must be non-NULL. | |
| 908 * "pNumCerts" | |
| 909 * Address where number of Certs will be stored. Must be non-NULL. | |
| 910 * "pProcParams" | |
| 911 * Address where object pointer for ProcessingParams will be stored. | |
| 912 * Must be non-NULL. | |
| 913 * "pAnchors" | |
| 914 * Address where object pointer for List of Anchors will be stored. | |
| 915 * Must be non-NULL. | |
| 916 * "pNumAnchors" | |
| 917 * Address where number of Anchors will be stored. Must be non-NULL. | |
| 918 * "plContext" | |
| 919 * Platform-specific context pointer. | |
| 920 * THREAD SAFETY: | |
| 921 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 922 * RETURNS: | |
| 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. | |
| 926 */ | |
| 927 static PKIX_Error * | |
| 928 pkix_ExtractParameters( | |
| 929 PKIX_ValidateParams *valParams, | |
| 930 PKIX_List **pCerts, | |
| 931 PKIX_UInt32 *pNumCerts, | |
| 932 PKIX_ProcessingParams **pProcParams, | |
| 933 PKIX_List **pAnchors, | |
| 934 PKIX_UInt32 *pNumAnchors, | |
| 935 void *plContext) | |
| 936 { | |
| 937 PKIX_ENTER(VALIDATE, "pkix_ExtractParameters"); | |
| 938 PKIX_NULLCHECK_THREE(valParams, pCerts, pNumCerts); | |
| 939 PKIX_NULLCHECK_THREE(pProcParams, pAnchors, pNumAnchors); | |
| 940 | |
| 941 /* extract relevant parameters from chain */ | |
| 942 PKIX_CHECK(PKIX_ValidateParams_GetCertChain | |
| 943 (valParams, pCerts, plContext), | |
| 944 PKIX_VALIDATEPARAMSGETCERTCHAINFAILED); | |
| 945 | |
| 946 PKIX_CHECK(PKIX_List_GetLength(*pCerts, pNumCerts, plContext), | |
| 947 PKIX_LISTGETLENGTHFAILED); | |
| 948 | |
| 949 /* extract relevant parameters from procParams */ | |
| 950 PKIX_CHECK(PKIX_ValidateParams_GetProcessingParams | |
| 951 (valParams, pProcParams, plContext), | |
| 952 PKIX_VALIDATEPARAMSGETPROCESSINGPARAMSFAILED); | |
| 953 | |
| 954 PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors | |
| 955 (*pProcParams, pAnchors, plContext), | |
| 956 PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED); | |
| 957 | |
| 958 PKIX_CHECK(PKIX_List_GetLength(*pAnchors, pNumAnchors, plContext), | |
| 959 PKIX_LISTGETLENGTHFAILED); | |
| 960 | |
| 961 cleanup: | |
| 962 | |
| 963 PKIX_RETURN(VALIDATE); | |
| 964 } | |
| 965 | |
| 966 /* --Public-Functions--------------------------------------------- */ | |
| 967 | |
| 968 /* | |
| 969 * FUNCTION: PKIX_ValidateChain (see comments in pkix.h) | |
| 970 */ | |
| 971 PKIX_Error * | |
| 972 PKIX_ValidateChain( | |
| 973 PKIX_ValidateParams *valParams, | |
| 974 PKIX_ValidateResult **pResult, | |
| 975 PKIX_VerifyNode **pVerifyTree, | |
| 976 void *plContext) | |
| 977 { | |
| 978 PKIX_Error *chainFailed = NULL; | |
| 979 | |
| 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; | |
| 1001 | |
| 1002 PKIX_ENTER(VALIDATE, "PKIX_ValidateChain"); | |
| 1003 PKIX_NULLCHECK_TWO(valParams, pResult); | |
| 1004 | |
| 1005 /* extract various parameters from valParams */ | |
| 1006 PKIX_CHECK(pkix_ExtractParameters | |
| 1007 (valParams, | |
| 1008 &certs, | |
| 1009 &numCerts, | |
| 1010 &procParams, | |
| 1011 &anchors, | |
| 1012 &numAnchors, | |
| 1013 plContext), | |
| 1014 PKIX_EXTRACTPARAMETERSFAILED); | |
| 1015 | |
| 1016 /* | |
| 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 | |
| 1022 */ | |
| 1023 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers | |
| 1024 (procParams, &userCheckers, plContext), | |
| 1025 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); | |
| 1026 | |
| 1027 if (userCheckers != NULL) { | |
| 1028 | |
| 1029 PKIX_CHECK(PKIX_List_Create | |
| 1030 (&validateCheckedCritExtOIDsList, | |
| 1031 plContext), | |
| 1032 PKIX_LISTCREATEFAILED); | |
| 1033 | |
| 1034 PKIX_CHECK(PKIX_List_GetLength | |
| 1035 (userCheckers, &numUserCheckers, plContext), | |
| 1036 PKIX_LISTGETLENGTHFAILED); | |
| 1037 | |
| 1038 for (i = 0; i < numUserCheckers; i++) { | |
| 1039 | |
| 1040 PKIX_CHECK(PKIX_List_GetItem | |
| 1041 (userCheckers, | |
| 1042 i, | |
| 1043 (PKIX_PL_Object **) &userChecker, | |
| 1044 plContext), | |
| 1045 PKIX_LISTGETITEMFAILED); | |
| 1046 | |
| 1047 PKIX_CHECK | |
| 1048 (PKIX_CertChainChecker_IsForwardCheckingSupported | |
| 1049 (userChecker, &supportForwarding, plContext), | |
| 1050 PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); | |
| 1051 | |
| 1052 if (supportForwarding == PKIX_FALSE) { | |
| 1053 | |
| 1054 PKIX_CHECK | |
| 1055 (PKIX_CertChainChecker_GetSupportedExtensions | |
| 1056 (userChecker, &userCheckerExtOIDs, plContext), | |
| 1057 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); | |
| 1058 | |
| 1059 if (userCheckerExtOIDs != NULL) { | |
| 1060 PKIX_CHECK(pkix_List_AppendList | |
| 1061 (validateCheckedCritExtOIDsList, | |
| 1062 userCheckerExtOIDs, | |
| 1063 plContext), | |
| 1064 PKIX_LISTAPPENDLISTFAILED); | |
| 1065 } | |
| 1066 } | |
| 1067 | |
| 1068 PKIX_DECREF(userCheckerExtOIDs); | |
| 1069 PKIX_DECREF(userChecker); | |
| 1070 } | |
| 1071 } | |
| 1072 | |
| 1073 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker | |
| 1074 (procParams, &revChecker, plContext), | |
| 1075 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); | |
| 1076 | |
| 1077 /* try to validate the chain with each anchor */ | |
| 1078 for (i = 0; i < numAnchors; i++){ | |
| 1079 | |
| 1080 /* get trust anchor */ | |
| 1081 PKIX_CHECK(PKIX_List_GetItem | |
| 1082 (anchors, i, (PKIX_PL_Object **)&anchor, plContext), | |
| 1083 PKIX_LISTGETITEMFAILED); | |
| 1084 | |
| 1085 /* initialize checkers using information from trust anchor */ | |
| 1086 PKIX_CHECK(pkix_InitializeCheckers | |
| 1087 (anchor, procParams, numCerts, &checkers, plContext), | |
| 1088 PKIX_INITIALIZECHECKERSFAILED); | |
| 1089 | |
| 1090 /* | |
| 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.) | |
| 1094 */ | |
| 1095 certCheckedIndex = 0; | |
| 1096 checkerIndex = 0; | |
| 1097 revChecking = PKIX_FALSE; | |
| 1098 chainFailed = pkix_CheckChain | |
| 1099 (certs, | |
| 1100 numCerts, | |
| 1101 anchor, | |
| 1102 checkers, | |
| 1103 revChecker, | |
| 1104 validateCheckedCritExtOIDsList, | |
| 1105 procParams, | |
| 1106 &certCheckedIndex, | |
| 1107 &checkerIndex, | |
| 1108 &revChecking, | |
| 1109 &reasonCode, | |
| 1110 &nbioContext, | |
| 1111 &finalPubKey, | |
| 1112 &validPolicyTree, | |
| 1113 pVerifyTree, | |
| 1114 plContext); | |
| 1115 | |
| 1116 if (chainFailed) { | |
| 1117 | |
| 1118 /* cert chain failed to validate */ | |
| 1119 | |
| 1120 PKIX_DECREF(chainFailed); | |
| 1121 PKIX_DECREF(anchor); | |
| 1122 PKIX_DECREF(checkers); | |
| 1123 PKIX_DECREF(validPolicyTree); | |
| 1124 | |
| 1125 /* if last anchor, we fail; else, we try next anchor */ | |
| 1126 if (i == (numAnchors - 1)) { /* last anchor */ | |
| 1127 PKIX_ERROR(PKIX_VALIDATECHAINFAILED); | |
| 1128 } | |
| 1129 | |
| 1130 } else { | |
| 1131 | |
| 1132 /* XXX Remove this assertion after 2014-12-31. | |
| 1133 * See bug 946984. */ | |
| 1134 PORT_Assert(reasonCode == 0); | |
| 1135 | |
| 1136 /* cert chain successfully validated! */ | |
| 1137 PKIX_CHECK(pkix_ValidateResult_Create | |
| 1138 (finalPubKey, | |
| 1139 anchor, | |
| 1140 validPolicyTree, | |
| 1141 &valResult, | |
| 1142 plContext), | |
| 1143 PKIX_VALIDATERESULTCREATEFAILED); | |
| 1144 | |
| 1145 *pResult = valResult; | |
| 1146 | |
| 1147 /* no need to try any more anchors in the loop */ | |
| 1148 goto cleanup; | |
| 1149 } | |
| 1150 } | |
| 1151 | |
| 1152 cleanup: | |
| 1153 | |
| 1154 PKIX_DECREF(finalPubKey); | |
| 1155 PKIX_DECREF(certs); | |
| 1156 PKIX_DECREF(anchors); | |
| 1157 PKIX_DECREF(anchor); | |
| 1158 PKIX_DECREF(checkers); | |
| 1159 PKIX_DECREF(revChecker); | |
| 1160 PKIX_DECREF(validPolicyTree); | |
| 1161 PKIX_DECREF(chainFailed); | |
| 1162 PKIX_DECREF(procParams); | |
| 1163 PKIX_DECREF(userCheckers); | |
| 1164 PKIX_DECREF(validateCheckedCritExtOIDsList); | |
| 1165 | |
| 1166 PKIX_RETURN(VALIDATE); | |
| 1167 } | |
| 1168 | |
| 1169 /* | |
| 1170 * FUNCTION: pkix_Validate_BuildUserOIDs | |
| 1171 * DESCRIPTION: | |
| 1172 * | |
| 1173 * This function creates a List of the OIDs that are processed by the user | |
| 1174 * checkers in the List pointed to by "userCheckers", storing the resulting | |
| 1175 * List at "pUserCritOIDs". If the List of userCheckers is NULL, the output | |
| 1176 * List will be NULL. Otherwise the output List will be non-NULL, but may be | |
| 1177 * empty. | |
| 1178 * | |
| 1179 * PARAMETERS: | |
| 1180 * "userCheckers" | |
| 1181 * The address of the List of userCheckers. | |
| 1182 * "pUserCritOIDs" | |
| 1183 * The address at which the List is stored. Must be non-NULL. | |
| 1184 * "plContext" | |
| 1185 * Platform-specific context pointer. | |
| 1186 * THREAD SAFETY: | |
| 1187 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 1188 * RETURNS: | |
| 1189 * Returns NULL if the function succeeds. | |
| 1190 * Returns a VALIDATE Error if the function fails in a non-fatal way. | |
| 1191 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 1192 */ | |
| 1193 static PKIX_Error * | |
| 1194 pkix_Validate_BuildUserOIDs( | |
| 1195 PKIX_List *userCheckers, | |
| 1196 PKIX_List **pUserCritOIDs, | |
| 1197 void *plContext) | |
| 1198 { | |
| 1199 PKIX_UInt32 numUserCheckers = 0; | |
| 1200 PKIX_UInt32 i = 0; | |
| 1201 PKIX_List *userCritOIDs = NULL; | |
| 1202 PKIX_List *userCheckerExtOIDs = NULL; | |
| 1203 PKIX_Boolean supportForwarding = PKIX_FALSE; | |
| 1204 PKIX_CertChainChecker *userChecker = NULL; | |
| 1205 | |
| 1206 PKIX_ENTER(VALIDATE, "pkix_Validate_BuildUserOIDs"); | |
| 1207 PKIX_NULLCHECK_ONE(pUserCritOIDs); | |
| 1208 | |
| 1209 if (userCheckers != NULL) { | |
| 1210 PKIX_CHECK(PKIX_List_Create(&userCritOIDs, plContext), | |
| 1211 PKIX_LISTCREATEFAILED); | |
| 1212 | |
| 1213 PKIX_CHECK(PKIX_List_GetLength | |
| 1214 (userCheckers, &numUserCheckers, plContext), | |
| 1215 PKIX_LISTGETLENGTHFAILED); | |
| 1216 | |
| 1217 for (i = 0; i < numUserCheckers; i++) { | |
| 1218 PKIX_CHECK(PKIX_List_GetItem | |
| 1219 (userCheckers, | |
| 1220 i, | |
| 1221 (PKIX_PL_Object **) &userChecker, | |
| 1222 plContext), | |
| 1223 PKIX_LISTGETITEMFAILED); | |
| 1224 | |
| 1225 PKIX_CHECK(PKIX_CertChainChecker_IsForwardCheckingSupported | |
| 1226 (userChecker, &supportForwarding, plContext), | |
| 1227 PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); | |
| 1228 | |
| 1229 if (supportForwarding == PKIX_FALSE) { | |
| 1230 | |
| 1231 PKIX_CHECK(PKIX_CertChainChecker_GetSupportedExtensions | |
| 1232 (userChecker, &userCheckerExtOIDs, plContext), | |
| 1233 PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); | |
| 1234 | |
| 1235 if (userCheckerExtOIDs != NULL) { | |
| 1236 PKIX_CHECK(pkix_List_AppendList | |
| 1237 (userCritOIDs, userCheckerExtOIDs, plContext), | |
| 1238 PKIX_LISTAPPENDLISTFAILED); | |
| 1239 } | |
| 1240 } | |
| 1241 | |
| 1242 PKIX_DECREF(userCheckerExtOIDs); | |
| 1243 PKIX_DECREF(userChecker); | |
| 1244 } | |
| 1245 } | |
| 1246 | |
| 1247 *pUserCritOIDs = userCritOIDs; | |
| 1248 | |
| 1249 cleanup: | |
| 1250 | |
| 1251 if (PKIX_ERROR_RECEIVED){ | |
| 1252 PKIX_DECREF(userCritOIDs); | |
| 1253 } | |
| 1254 | |
| 1255 PKIX_DECREF(userCheckerExtOIDs); | |
| 1256 PKIX_DECREF(userChecker); | |
| 1257 | |
| 1258 PKIX_RETURN(VALIDATE); | |
| 1259 } | |
| 1260 | |
| 1261 /* | |
| 1262 * FUNCTION: PKIX_ValidateChain_nb (see comments in pkix.h) | |
| 1263 */ | |
| 1264 PKIX_Error * | |
| 1265 PKIX_ValidateChain_NB( | |
| 1266 PKIX_ValidateParams *valParams, | |
| 1267 PKIX_UInt32 *pCertIndex, | |
| 1268 PKIX_UInt32 *pAnchorIndex, | |
| 1269 PKIX_UInt32 *pCheckerIndex, | |
| 1270 PKIX_Boolean *pRevChecking, | |
| 1271 PKIX_List **pCheckers, | |
| 1272 void **pNBIOContext, | |
| 1273 PKIX_ValidateResult **pResult, | |
| 1274 PKIX_VerifyNode **pVerifyTree, | |
| 1275 void *plContext) | |
| 1276 { | |
| 1277 PKIX_UInt32 numCerts = 0; | |
| 1278 PKIX_UInt32 numAnchors = 0; | |
| 1279 PKIX_UInt32 i = 0; | |
| 1280 PKIX_UInt32 certIndex = 0; | |
| 1281 PKIX_UInt32 anchorIndex = 0; | |
| 1282 PKIX_UInt32 checkerIndex = 0; | |
| 1283 PKIX_UInt32 reasonCode = 0; | |
| 1284 PKIX_Boolean revChecking = PKIX_FALSE; | |
| 1285 PKIX_List *certs = NULL; | |
| 1286 PKIX_List *anchors = NULL; | |
| 1287 PKIX_List *checkers = NULL; | |
| 1288 PKIX_List *userCheckers = NULL; | |
| 1289 PKIX_List *validateCheckedCritExtOIDsList = NULL; | |
| 1290 PKIX_TrustAnchor *anchor = NULL; | |
| 1291 PKIX_ValidateResult *valResult = NULL; | |
| 1292 PKIX_PL_PublicKey *finalPubKey = NULL; | |
| 1293 PKIX_PolicyNode *validPolicyTree = NULL; | |
| 1294 PKIX_ProcessingParams *procParams = NULL; | |
| 1295 PKIX_RevocationChecker *revChecker = NULL; | |
| 1296 PKIX_Error *chainFailed = NULL; | |
| 1297 void *nbioContext = NULL; | |
| 1298 | |
| 1299 PKIX_ENTER(VALIDATE, "PKIX_ValidateChain_NB"); | |
| 1300 PKIX_NULLCHECK_FOUR | |
| 1301 (valParams, pCertIndex, pAnchorIndex, pCheckerIndex); | |
| 1302 PKIX_NULLCHECK_FOUR(pRevChecking, pCheckers, pNBIOContext, pResult); | |
| 1303 | |
| 1304 nbioContext = *pNBIOContext; | |
| 1305 *pNBIOContext = NULL; | |
| 1306 | |
| 1307 /* extract various parameters from valParams */ | |
| 1308 PKIX_CHECK(pkix_ExtractParameters | |
| 1309 (valParams, | |
| 1310 &certs, | |
| 1311 &numCerts, | |
| 1312 &procParams, | |
| 1313 &anchors, | |
| 1314 &numAnchors, | |
| 1315 plContext), | |
| 1316 PKIX_EXTRACTPARAMETERSFAILED); | |
| 1317 | |
| 1318 /* | |
| 1319 * Create a List of the OIDs that will be processed by the user | |
| 1320 * checkers. User checkers are not responsible for removing OIDs from | |
| 1321 * the List of unresolved critical extensions, as libpkix checkers are. | |
| 1322 * So we add those user checkers' OIDs to the removal list to be taken | |
| 1323 * out by CheckChain. | |
| 1324 */ | |
| 1325 PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers | |
| 1326 (procParams, &userCheckers, plContext), | |
| 1327 PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); | |
| 1328 | |
| 1329 PKIX_CHECK(pkix_Validate_BuildUserOIDs | |
| 1330 (userCheckers, &validateCheckedCritExtOIDsList, plContext), | |
| 1331 PKIX_VALIDATEBUILDUSEROIDSFAILED); | |
| 1332 | |
| 1333 PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker | |
| 1334 (procParams, &revChecker, plContext), | |
| 1335 PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); | |
| 1336 | |
| 1337 /* Are we resuming after a WOULDBLOCK return, or starting anew ? */ | |
| 1338 if (nbioContext != NULL) { | |
| 1339 /* Resuming */ | |
| 1340 certIndex = *pCertIndex; | |
| 1341 anchorIndex = *pAnchorIndex; | |
| 1342 checkerIndex = *pCheckerIndex; | |
| 1343 revChecking = *pRevChecking; | |
| 1344 checkers = *pCheckers; | |
| 1345 *pCheckers = NULL; | |
| 1346 } | |
| 1347 | |
| 1348 /* try to validate the chain with each anchor */ | |
| 1349 for (i = anchorIndex; i < numAnchors; i++) { | |
| 1350 | |
| 1351 /* get trust anchor */ | |
| 1352 PKIX_CHECK(PKIX_List_GetItem | |
| 1353 (anchors, i, (PKIX_PL_Object **)&anchor, plContext), | |
| 1354 PKIX_LISTGETITEMFAILED); | |
| 1355 | |
| 1356 /* initialize checkers using information from trust anchor */ | |
| 1357 if (nbioContext == NULL) { | |
| 1358 PKIX_CHECK(pkix_InitializeCheckers | |
| 1359 (anchor, | |
| 1360 procParams, | |
| 1361 numCerts, | |
| 1362 &checkers, | |
| 1363 plContext), | |
| 1364 PKIX_INITIALIZECHECKERSFAILED); | |
| 1365 } | |
| 1366 | |
| 1367 /* | |
| 1368 * Validate the chain using this trust anchor and these | |
| 1369 * checkers. | |
| 1370 */ | |
| 1371 chainFailed = pkix_CheckChain | |
| 1372 (certs, | |
| 1373 numCerts, | |
| 1374 anchor, | |
| 1375 checkers, | |
| 1376 revChecker, | |
| 1377 validateCheckedCritExtOIDsList, | |
| 1378 procParams, | |
| 1379 &certIndex, | |
| 1380 &checkerIndex, | |
| 1381 &revChecking, | |
| 1382 &reasonCode, | |
| 1383 &nbioContext, | |
| 1384 &finalPubKey, | |
| 1385 &validPolicyTree, | |
| 1386 pVerifyTree, | |
| 1387 plContext); | |
| 1388 | |
| 1389 if (nbioContext != NULL) { | |
| 1390 *pCertIndex = certIndex; | |
| 1391 *pAnchorIndex = anchorIndex; | |
| 1392 *pCheckerIndex = checkerIndex; | |
| 1393 *pRevChecking = revChecking; | |
| 1394 PKIX_INCREF(checkers); | |
| 1395 *pCheckers = checkers; | |
| 1396 *pNBIOContext = nbioContext; | |
| 1397 goto cleanup; | |
| 1398 } | |
| 1399 | |
| 1400 if (chainFailed) { | |
| 1401 | |
| 1402 /* cert chain failed to validate */ | |
| 1403 | |
| 1404 PKIX_DECREF(chainFailed); | |
| 1405 PKIX_DECREF(anchor); | |
| 1406 PKIX_DECREF(checkers); | |
| 1407 PKIX_DECREF(validPolicyTree); | |
| 1408 | |
| 1409 /* if last anchor, we fail; else, we try next anchor */ | |
| 1410 if (i == (numAnchors - 1)) { /* last anchor */ | |
| 1411 PKIX_ERROR(PKIX_VALIDATECHAINFAILED); | |
| 1412 } | |
| 1413 | |
| 1414 } else { | |
| 1415 | |
| 1416 /* XXX Remove this assertion after 2014-12-31. | |
| 1417 * See bug 946984. */ | |
| 1418 PORT_Assert(reasonCode == 0); | |
| 1419 | |
| 1420 /* cert chain successfully validated! */ | |
| 1421 PKIX_CHECK(pkix_ValidateResult_Create | |
| 1422 (finalPubKey, | |
| 1423 anchor, | |
| 1424 validPolicyTree, | |
| 1425 &valResult, | |
| 1426 plContext), | |
| 1427 PKIX_VALIDATERESULTCREATEFAILED); | |
| 1428 | |
| 1429 *pResult = valResult; | |
| 1430 | |
| 1431 /* no need to try any more anchors in the loop */ | |
| 1432 goto cleanup; | |
| 1433 } | |
| 1434 } | |
| 1435 | |
| 1436 cleanup: | |
| 1437 | |
| 1438 PKIX_DECREF(finalPubKey); | |
| 1439 PKIX_DECREF(certs); | |
| 1440 PKIX_DECREF(anchors); | |
| 1441 PKIX_DECREF(anchor); | |
| 1442 PKIX_DECREF(checkers); | |
| 1443 PKIX_DECREF(revChecker); | |
| 1444 PKIX_DECREF(validPolicyTree); | |
| 1445 PKIX_DECREF(chainFailed); | |
| 1446 PKIX_DECREF(procParams); | |
| 1447 PKIX_DECREF(userCheckers); | |
| 1448 PKIX_DECREF(validateCheckedCritExtOIDsList); | |
| 1449 | |
| 1450 PKIX_RETURN(VALIDATE); | |
| 1451 } | |
| OLD | NEW |