Index: mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix/top/pkix_validate.c (working copy) |
@@ -1,1443 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
-/* |
- * pkix_validate.c |
- * |
- * Top level validateChain function |
- * |
- */ |
- |
-#include "pkix_validate.h" |
-#include "pkix_pl_common.h" |
- |
-/* --Private-Functions-------------------------------------------- */ |
- |
-/* |
- * FUNCTION: pkix_AddToVerifyLog |
- * DESCRIPTION: |
- * |
- * This function returns immediately if the address for the VerifyNode tree |
- * pointed to by "pVerifyTree" is NULL. Otherwise it creates a new VerifyNode |
- * from the Cert pointed to by "cert" and the Error pointed to by "error", |
- * and inserts it at the depth in the VerifyNode tree determined by "depth". A |
- * depth of zero means that this function creates the root node of a new tree. |
- * |
- * Note: this function does not include the means of choosing among branches |
- * of a tree. It is intended for non-branching trees, that is, where each |
- * parent node has only a single child node. |
- * |
- * PARAMETERS: |
- * "cert" |
- * The address of the Cert to be included in the new VerifyNode. Must be |
- * non-NULL. |
- * "depth" |
- * The UInt32 value of the depth. |
- * "error" |
- * The address of the Error to be included in the new VerifyNode. |
- * "pVerifyTree" |
- * The address of the VerifyNode tree into which the created VerifyNode |
- * is to be inserted. The node is not created if VerifyTree is NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_AddToVerifyLog( |
- PKIX_PL_Cert *cert, |
- PKIX_UInt32 depth, |
- PKIX_Error *error, |
- PKIX_VerifyNode **pVerifyTree, |
- void *plContext) |
-{ |
- |
- PKIX_VerifyNode *verifyNode = NULL; |
- |
- PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog"); |
- PKIX_NULLCHECK_ONE(cert); |
- |
- if (pVerifyTree) { /* nothing to do if no address given for log */ |
- |
- PKIX_CHECK(pkix_VerifyNode_Create |
- (cert, depth, error, &verifyNode, plContext), |
- PKIX_VERIFYNODECREATEFAILED); |
- |
- if (depth == 0) { |
- /* We just created the root node */ |
- *pVerifyTree = verifyNode; |
- } else { |
- PKIX_CHECK(pkix_VerifyNode_AddToChain |
- (*pVerifyTree, verifyNode, plContext), |
- PKIX_VERIFYNODEADDTOCHAINFAILED); |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(VALIDATE); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_CheckCert |
- * DESCRIPTION: |
- * |
- * Checks whether the Cert pointed to by "cert" successfully validates |
- * using the List of CertChainCheckers pointed to by "checkers". If the |
- * certificate does not validate, an Error pointer is returned. |
- * |
- * This function should be called initially with the UInt32 pointed to by |
- * "pCheckerIndex" containing zero, and the pointer at "pNBIOContext" |
- * containing NULL. If a checker does non-blocking I/O, this function will |
- * return with the index of that checker stored at "pCheckerIndex" and a |
- * platform-dependent non-blocking I/O context stored at "pNBIOContext". |
- * A subsequent call to this function with those values intact will allow the |
- * checking to resume where it left off. This should be repeated until the |
- * function returns with NULL stored at "pNBIOContext". |
- * |
- * PARAMETERS: |
- * "cert" |
- * Address of Cert to validate. Must be non-NULL. |
- * "checkers" |
- * List of CertChainCheckers which must each validate the certificate. |
- * Must be non-NULL. |
- * "checkedExtOIDs" |
- * List of PKIX_PL_OID that has been processed. If called from building |
- * chain, it is the list of critical extension OIDs that has been |
- * processed prior to validation. May be NULL. |
- * "pCheckerIndex" |
- * Address at which is stored the the index, within the List "checkers", |
- * of a checker whose processing was interrupted by non-blocking I/O. |
- * Must be non-NULL. |
- * "pNBIOContext" |
- * Address at which is stored platform-specific non-blocking I/O context. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_CheckCert( |
- PKIX_PL_Cert *cert, |
- PKIX_List *checkers, |
- PKIX_List *checkedExtOIDsList, |
- PKIX_UInt32 *pCheckerIndex, |
- void **pNBIOContext, |
- void *plContext) |
-{ |
- PKIX_CertChainChecker_CheckCallback checkerCheck = NULL; |
- PKIX_CertChainChecker *checker = NULL; |
- PKIX_List *unresCritExtOIDs = NULL; |
- PKIX_UInt32 numCheckers; |
- PKIX_UInt32 numUnresCritExtOIDs = 0; |
- PKIX_UInt32 checkerIndex = 0; |
- void *nbioContext = NULL; |
- |
- PKIX_ENTER(VALIDATE, "pkix_CheckCert"); |
- PKIX_NULLCHECK_FOUR(cert, checkers, pCheckerIndex, pNBIOContext); |
- |
- nbioContext = *pNBIOContext; |
- *pNBIOContext = NULL; /* prepare for case of error exit */ |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs |
- (cert, &unresCritExtOIDs, plContext), |
- PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (checkerIndex = *pCheckerIndex; |
- checkerIndex < numCheckers; |
- checkerIndex++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (checkers, |
- checkerIndex, |
- (PKIX_PL_Object **)&checker, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback |
- (checker, &checkerCheck, plContext), |
- PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED); |
- |
- PKIX_CHECK(checkerCheck(checker, cert, unresCritExtOIDs, |
- &nbioContext, plContext), |
- PKIX_CERTCHAINCHECKERCHECKFAILED); |
- |
- if (nbioContext != NULL) { |
- *pCheckerIndex = checkerIndex; |
- *pNBIOContext = nbioContext; |
- goto cleanup; |
- } |
- |
- PKIX_DECREF(checker); |
- } |
- |
- if (unresCritExtOIDs){ |
- |
-#ifdef PKIX_VALIDATEDEBUG |
- { |
- PKIX_PL_String *oidString = NULL; |
- PKIX_UInt32 length; |
- char *oidAscii = NULL; |
- PKIX_TOSTRING(unresCritExtOIDs, &oidString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- PKIX_CHECK(PKIX_PL_String_GetEncoded |
- (oidString, |
- PKIX_ESCASCII, |
- (void **) &oidAscii, |
- &length, |
- plContext), |
- PKIX_STRINGGETENCODEDFAILED); |
- PKIX_VALIDATE_DEBUG_ARG |
- ("unrecognized critical extension OIDs:" |
- " %s\n", oidAscii); |
- PKIX_DECREF(oidString); |
- PKIX_PL_Free(oidAscii, plContext); |
- } |
-#endif |
- |
- if (checkedExtOIDsList != NULL) { |
- /* Take out OID's that had been processed, if any */ |
- PKIX_CHECK(pkix_List_RemoveItems |
- (unresCritExtOIDs, |
- checkedExtOIDsList, |
- plContext), |
- PKIX_LISTREMOVEITEMSFAILED); |
- } |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (unresCritExtOIDs, &numUnresCritExtOIDs, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- if (numUnresCritExtOIDs != 0){ |
- PKIX_ERROR(PKIX_UNRECOGNIZEDCRITICALEXTENSION); |
- } |
- |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(checker); |
- PKIX_DECREF(unresCritExtOIDs); |
- |
- PKIX_RETURN(VALIDATE); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_InitializeCheckers |
- * DESCRIPTION: |
- * |
- * Creates several checkers and initializes them with values derived from the |
- * TrustAnchor pointed to by "anchor", the ProcessingParams pointed to by |
- * "procParams", and the number of Certs in the Chain, represented by |
- * "numCerts". The List of checkers is stored at "pCheckers". |
- * |
- * PARAMETERS: |
- * "anchor" |
- * Address of TrustAnchor used to initialize the SignatureChecker and |
- * NameChainingChecker. Must be non-NULL. |
- * "procParams" |
- * Address of ProcessingParams used to initialize the ExpirationChecker |
- * and TargetCertChecker. Must be non-NULL. |
- * "numCerts" |
- * Number of certificates in the CertChain. |
- * "pCheckers" |
- * Address where object pointer will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_InitializeCheckers( |
- PKIX_TrustAnchor *anchor, |
- PKIX_ProcessingParams *procParams, |
- PKIX_UInt32 numCerts, |
- PKIX_List **pCheckers, |
- void *plContext) |
-{ |
- PKIX_CertChainChecker *targetCertChecker = NULL; |
- PKIX_CertChainChecker *expirationChecker = NULL; |
- PKIX_CertChainChecker *nameChainingChecker = NULL; |
- PKIX_CertChainChecker *nameConstraintsChecker = NULL; |
- PKIX_CertChainChecker *basicConstraintsChecker = NULL; |
- PKIX_CertChainChecker *policyChecker = NULL; |
- PKIX_CertChainChecker *sigChecker = NULL; |
- PKIX_CertChainChecker *defaultCrlChecker = NULL; |
- PKIX_CertChainChecker *userChecker = NULL; |
- PKIX_PL_X500Name *trustedCAName = NULL; |
- PKIX_PL_PublicKey *trustedPubKey = NULL; |
- PKIX_List *checkers = NULL; |
- PKIX_PL_Date *testDate = NULL; |
- PKIX_CertSelector *certSelector = NULL; |
- PKIX_PL_Cert *trustedCert = NULL; |
- PKIX_PL_CertNameConstraints *trustedNC = NULL; |
- PKIX_List *initialPolicies = NULL; |
- PKIX_Boolean policyQualifiersRejected = PKIX_FALSE; |
- PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; |
- PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; |
- PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; |
- PKIX_List *userCheckersList = NULL; |
- PKIX_List *certStores = NULL; |
- PKIX_UInt32 numCertCheckers = 0; |
- PKIX_UInt32 i; |
- |
- PKIX_ENTER(VALIDATE, "pkix_InitializeCheckers"); |
- PKIX_NULLCHECK_THREE(anchor, procParams, pCheckers); |
- PKIX_CHECK(PKIX_List_Create(&checkers, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- /* |
- * The TrustAnchor may have been created using CreateWithCert |
- * (in which case GetCAPublicKey and GetCAName will return NULL) |
- * or may have been created using CreateWithNameKeyPair (in which |
- * case GetTrustedCert will return NULL. So we call GetTrustedCert |
- * and populate trustedPubKey and trustedCAName accordingly. |
- */ |
- |
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert |
- (anchor, &trustedCert, plContext), |
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
- |
- if (trustedCert){ |
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey |
- (trustedCert, &trustedPubKey, plContext), |
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetSubject |
- (trustedCert, &trustedCAName, plContext), |
- PKIX_CERTGETSUBJECTFAILED); |
- } else { |
- PKIX_CHECK(PKIX_TrustAnchor_GetCAPublicKey |
- (anchor, &trustedPubKey, plContext), |
- PKIX_TRUSTANCHORGETCAPUBLICKEYFAILED); |
- |
- PKIX_CHECK(PKIX_TrustAnchor_GetCAName |
- (anchor, &trustedCAName, plContext), |
- PKIX_TRUSTANCHORGETCANAMEFAILED); |
- } |
- |
- PKIX_NULLCHECK_TWO(trustedPubKey, trustedCAName); |
- |
- PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints |
- (anchor, &trustedNC, plContext), |
- PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints |
- (procParams, &certSelector, plContext), |
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetDate |
- (procParams, &testDate, plContext), |
- PKIX_PROCESSINGPARAMSGETDATEFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies |
- (procParams, &initialPolicies, plContext), |
- PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected |
- (procParams, &policyQualifiersRejected, plContext), |
- PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited |
- (procParams, &initialPolicyMappingInhibit, plContext), |
- PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited |
- (procParams, &initialAnyPolicyInhibit, plContext), |
- PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired |
- (procParams, &initialExplicitPolicy, plContext), |
- PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetCertStores |
- (procParams, &certStores, plContext), |
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers |
- (procParams, &userCheckersList, plContext), |
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); |
- |
- /* now, initialize all the checkers */ |
- PKIX_CHECK(pkix_TargetCertChecker_Initialize |
- (certSelector, numCerts, &targetCertChecker, plContext), |
- PKIX_TARGETCERTCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_ExpirationChecker_Initialize |
- (testDate, &expirationChecker, plContext), |
- PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_NameChainingChecker_Initialize |
- (trustedCAName, &nameChainingChecker, plContext), |
- PKIX_NAMECHAININGCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_NameConstraintsChecker_Initialize |
- (trustedNC, numCerts, &nameConstraintsChecker, plContext), |
- PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_BasicConstraintsChecker_Initialize |
- (numCerts, &basicConstraintsChecker, plContext), |
- PKIX_BASICCONSTRAINTSCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_Initialize |
- (initialPolicies, |
- policyQualifiersRejected, |
- initialPolicyMappingInhibit, |
- initialExplicitPolicy, |
- initialAnyPolicyInhibit, |
- numCerts, |
- &policyChecker, |
- plContext), |
- PKIX_POLICYCHECKERINITIALIZEFAILED); |
- |
- PKIX_CHECK(pkix_SignatureChecker_Initialize |
- (trustedPubKey, numCerts, &sigChecker, plContext), |
- PKIX_SIGNATURECHECKERINITIALIZEFAILED); |
- |
- if (userCheckersList != NULL) { |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (userCheckersList, &numCertCheckers, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (i = 0; i < numCertCheckers; i++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (userCheckersList, |
- i, |
- (PKIX_PL_Object **) &userChecker, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, |
- (PKIX_PL_Object *)userChecker, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(userChecker); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)targetCertChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)expirationChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)nameChainingChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)nameConstraintsChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)basicConstraintsChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)policyChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (checkers, (PKIX_PL_Object *)sigChecker, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- *pCheckers = checkers; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED){ |
- PKIX_DECREF(checkers); |
- } |
- |
- PKIX_DECREF(certSelector); |
- PKIX_DECREF(testDate); |
- PKIX_DECREF(initialPolicies); |
- PKIX_DECREF(targetCertChecker); |
- PKIX_DECREF(expirationChecker); |
- PKIX_DECREF(nameChainingChecker); |
- PKIX_DECREF(nameConstraintsChecker); |
- PKIX_DECREF(basicConstraintsChecker); |
- PKIX_DECREF(policyChecker); |
- PKIX_DECREF(sigChecker); |
- PKIX_DECREF(trustedCAName); |
- PKIX_DECREF(trustedPubKey); |
- PKIX_DECREF(trustedNC); |
- PKIX_DECREF(trustedCert); |
- PKIX_DECREF(defaultCrlChecker); |
- PKIX_DECREF(userCheckersList); |
- PKIX_DECREF(certStores); |
- PKIX_DECREF(userChecker); |
- |
- PKIX_RETURN(VALIDATE); |
-} |
- |
-/* |
- * FUNCTION: pkix_RetrieveOutputs |
- * DESCRIPTION: |
- * |
- * This function queries the respective states of the List of checkers in |
- * "checkers" to to obtain the final public key from the SignatureChecker |
- * and the policy tree from the PolicyChecker, storing those values at |
- * "pFinalSubjPubKey" and "pPolicyTree", respectively. |
- * |
- * PARAMETERS: |
- * "checkers" |
- * Address of List of checkers to be queried. Must be non-NULL. |
- * "pFinalSubjPubKey" |
- * Address where final public key will be stored. Must be non-NULL. |
- * "pPolicyTree" |
- * Address where policy tree will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_RetrieveOutputs( |
- PKIX_List *checkers, |
- PKIX_PL_PublicKey **pFinalSubjPubKey, |
- PKIX_PolicyNode **pPolicyTree, |
- void *plContext) |
-{ |
- PKIX_PL_PublicKey *finalSubjPubKey = NULL; |
- PKIX_PolicyNode *validPolicyTree = NULL; |
- PKIX_CertChainChecker *checker = NULL; |
- PKIX_PL_Object *state = NULL; |
- PKIX_UInt32 numCheckers = 0; |
- PKIX_UInt32 type; |
- PKIX_Int32 j; |
- |
- PKIX_ENTER(VALIDATE, "pkix_RetrieveOutputs"); |
- |
- PKIX_NULLCHECK_TWO(checkers, pPolicyTree); |
- |
- /* |
- * To optimize the search, we guess that the sigChecker is |
- * last in the tree and is preceded by the policyChecker. We |
- * search toward the front of the chain. Remember that List |
- * items are indexed 0..(numItems - 1). |
- */ |
- |
- PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (j = numCheckers - 1; j >= 0; j--){ |
- PKIX_CHECK(PKIX_List_GetItem |
- (checkers, j, (PKIX_PL_Object **)&checker, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState |
- (checker, &state, plContext), |
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); |
- |
- /* user defined checker may have no state */ |
- if (state != NULL) { |
- |
- PKIX_CHECK(PKIX_PL_Object_GetType(state, &type, plContext), |
- PKIX_OBJECTGETTYPEFAILED); |
- |
- if (type == PKIX_SIGNATURECHECKERSTATE_TYPE){ |
- /* final pubKey will include any inherited DSA params */ |
- finalSubjPubKey = |
- ((pkix_SignatureCheckerState *)state)-> |
- prevPublicKey; |
- PKIX_INCREF(finalSubjPubKey); |
- *pFinalSubjPubKey = finalSubjPubKey; |
- } |
- |
- if (type == PKIX_CERTPOLICYCHECKERSTATE_TYPE) { |
- validPolicyTree = |
- ((PKIX_PolicyCheckerState *)state)->validPolicyTree; |
- break; |
- } |
- } |
- |
- PKIX_DECREF(checker); |
- PKIX_DECREF(state); |
- } |
- |
- PKIX_INCREF(validPolicyTree); |
- *pPolicyTree = validPolicyTree; |
- |
-cleanup: |
- |
- PKIX_DECREF(checker); |
- PKIX_DECREF(state); |
- |
- PKIX_RETURN(VALIDATE); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_CheckChain |
- * DESCRIPTION: |
- * |
- * Checks whether the List of Certs pointed to by "certs", containing |
- * "numCerts" entries, successfully validates using each CertChainChecker in |
- * the List pointed to by "checkers" and has not been revoked, according to any |
- * of the Revocation Checkers in the List pointed to by "revChecker". Checkers |
- * are expected to remove from "removeCheckedExtOIDs" and extensions that they |
- * process. Indices to the certChain and the checkerChain are obtained and |
- * returned in "pCertCheckedIndex" and "pCheckerIndex", respectively. These |
- * should be set to zero prior to the initial call, but may be changed (and |
- * must be supplied on subsequent calls) if processing is suspended for non- |
- * blocking I/O. Each time a Cert passes from being validated by one of the |
- * CertChainCheckers to being checked by a Revocation Checker, the Boolean |
- * stored at "pRevChecking" is changed from FALSE to TRUE. If the Cert is |
- * rejected by a Revocation Checker, its reason code is returned at |
- * "pReasonCode. If the List of Certs successfully validates, the public key i |
- * the final certificate is obtained and stored at "pFinalSubjPubKey" and the |
- * validPolicyTree, which could be NULL, is stored at pPolicyTree. If the List |
- * of Certs fails to validate, an Error pointer is returned. |
- * |
- * If "pVerifyTree" is non-NULL, a chain of VerifyNodes is created which |
- * tracks the results of the validation. That is, either each node in the |
- * chain has a NULL Error component, or the last node contains an Error |
- * which indicates why the validation failed. |
- * |
- * The number of Certs in the List, represented by "numCerts", is used to |
- * determine which Cert is the final Cert. |
- * |
- * PARAMETERS: |
- * "certs" |
- * Address of List of Certs to validate. Must be non-NULL. |
- * "numCerts" |
- * Number of certificates in the List of certificates. |
- * "checkers" |
- * List of CertChainCheckers which must each validate the List of |
- * certificates. Must be non-NULL. |
- * "revChecker" |
- * List of RevocationCheckers which must each not reject the List of |
- * certificates. May be empty, but must be non-NULL. |
- * "removeCheckedExtOIDs" |
- * List of PKIX_PL_OID that has been processed. If called from building |
- * chain, it is the list of critical extension OIDs that has been |
- * processed prior to validation. Extension OIDs that may be processed by |
- * user defined checker processes are also in the list. May be NULL. |
- * "procParams" |
- * Address of ProcessingParams used to initialize various checkers. Must |
- * be non-NULL. |
- * "pCertCheckedIndex" |
- * Address where Int32 index to the Cert chain is obtained and |
- * returned. Must be non-NULL. |
- * "pCheckerIndex" |
- * Address where Int32 index to the CheckerChain is obtained and |
- * returned. Must be non-NULL. |
- * "pRevChecking" |
- * Address where Boolean is obtained and returned, indicating, if FALSE, |
- * that CertChainCheckers are being called; or, if TRUE, that RevChecker |
- * are being called. Must be non-NULL. |
- * "pReasonCode" |
- * Address where UInt32 results of revocation checking are stored. Must be |
- * non-NULL. |
- * "pNBIOContext" |
- * Address where platform-dependent context is stored if checking is |
- * suspended for non-blocking I/O. Must be non-NULL. |
- * "pFinalSubjPubKey" |
- * Address where the final public key will be stored. Must be non-NULL. |
- * "pPolicyTree" |
- * Address where the final validPolicyTree is stored. Must be non-NULL. |
- * "pVerifyTree" |
- * Address where a VerifyTree is stored, if non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-PKIX_Error * |
-pkix_CheckChain( |
- PKIX_List *certs, |
- PKIX_UInt32 numCerts, |
- PKIX_TrustAnchor *anchor, |
- PKIX_List *checkers, |
- PKIX_RevocationChecker *revChecker, |
- PKIX_List *removeCheckedExtOIDs, |
- PKIX_ProcessingParams *procParams, |
- PKIX_UInt32 *pCertCheckedIndex, |
- PKIX_UInt32 *pCheckerIndex, |
- PKIX_Boolean *pRevChecking, |
- PKIX_UInt32 *pReasonCode, |
- void **pNBIOContext, |
- PKIX_PL_PublicKey **pFinalSubjPubKey, |
- PKIX_PolicyNode **pPolicyTree, |
- PKIX_VerifyNode **pVerifyTree, |
- void *plContext) |
-{ |
- PKIX_UInt32 j = 0; |
- PKIX_Boolean revChecking = PKIX_FALSE; |
- PKIX_Error *checkCertError = NULL; |
- void *nbioContext = NULL; |
- PKIX_PL_Cert *cert = NULL; |
- PKIX_PL_Cert *issuer = NULL; |
- PKIX_PL_NssContext *nssContext = NULL; |
- CERTCertList *certList = NULL; |
- const CERTChainVerifyCallback *chainVerifyCallback = NULL; |
- CERTCertificate *nssCert = NULL; |
- |
- PKIX_ENTER(VALIDATE, "pkix_CheckChain"); |
- PKIX_NULLCHECK_FOUR(certs, checkers, revChecker, pCertCheckedIndex); |
- PKIX_NULLCHECK_FOUR(pCheckerIndex, pRevChecking, pReasonCode, anchor); |
- PKIX_NULLCHECK_THREE(pNBIOContext, pFinalSubjPubKey, pPolicyTree); |
- |
- nbioContext = *pNBIOContext; |
- *pNBIOContext = NULL; |
- revChecking = *pRevChecking; |
- nssContext = (PKIX_PL_NssContext *)plContext; |
- chainVerifyCallback = &nssContext->chainVerifyCallback; |
- |
- if (chainVerifyCallback->isChainValid != NULL) { |
- PRBool chainOK = PR_FALSE; /*assume failure*/ |
- SECStatus rv; |
- |
- certList = CERT_NewCertList(); |
- if (certList == NULL) { |
- PKIX_ERROR_ALLOC_ERROR(); |
- } |
- |
- /* Add the trust anchor to the list */ |
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert |
- (anchor, &cert, plContext), |
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
- |
- PKIX_CHECK( |
- PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext), |
- PKIX_CERTGETCERTCERTIFICATEFAILED); |
- |
- rv = CERT_AddCertToListHead(certList, nssCert); |
- if (rv != SECSuccess) { |
- PKIX_ERROR_ALLOC_ERROR(); |
- } |
- /* the certList takes ownership of nssCert on success */ |
- nssCert = NULL; |
- PKIX_DECREF(cert); |
- |
- /* Add the rest of the chain to the list */ |
- for (j = *pCertCheckedIndex; j < numCerts; j++) { |
- PKIX_CHECK(PKIX_List_GetItem( |
- certs, j, (PKIX_PL_Object **)&cert, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK( |
- PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext), |
- PKIX_CERTGETCERTCERTIFICATEFAILED); |
- |
- rv = CERT_AddCertToListHead(certList, nssCert); |
- if (rv != SECSuccess) { |
- PKIX_ERROR_ALLOC_ERROR(); |
- } |
- /* the certList takes ownership of nssCert on success */ |
- nssCert = NULL; |
- PKIX_DECREF(cert); |
- } |
- |
- rv = (*chainVerifyCallback->isChainValid) |
- (chainVerifyCallback->isChainValidArg, certList, &chainOK); |
- if (rv != SECSuccess) { |
- PKIX_ERROR_FATAL(PKIX_CHAINVERIFYCALLBACKFAILED); |
- } |
- |
- if (!chainOK) { |
- PKIX_ERROR(PKIX_CHAINVERIFYCALLBACKFAILED); |
- } |
- |
- } |
- |
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert |
- (anchor, &cert, plContext), |
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
- |
- for (j = *pCertCheckedIndex; j < numCerts; j++) { |
- |
- PORT_Assert(cert); |
- PKIX_DECREF(issuer); |
- issuer = cert; |
- cert = NULL; |
- |
- PKIX_CHECK(PKIX_List_GetItem( |
- certs, j, (PKIX_PL_Object **)&cert, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- /* check if cert pointer is valid */ |
- PORT_Assert(cert); |
- if (cert == NULL) { |
- continue; |
- } |
- |
- if (revChecking == PKIX_FALSE) { |
- |
- PKIX_CHECK(pkix_CheckCert |
- (cert, |
- checkers, |
- removeCheckedExtOIDs, |
- pCheckerIndex, |
- &nbioContext, |
- plContext), |
- PKIX_CHECKCERTFAILED); |
- |
- if (nbioContext != NULL) { |
- *pCertCheckedIndex = j; |
- *pRevChecking = revChecking; |
- *pNBIOContext = nbioContext; |
- goto cleanup; |
- } |
- |
- revChecking = PKIX_TRUE; |
- *pCheckerIndex = 0; |
- } |
- |
- if (revChecking == PKIX_TRUE) { |
- PKIX_RevocationStatus revStatus; |
- pkixErrorResult = |
- PKIX_RevocationChecker_Check( |
- cert, issuer, revChecker, |
- procParams, PKIX_TRUE, |
- (j == numCerts - 1) ? PKIX_TRUE : PKIX_FALSE, |
- &revStatus, pReasonCode, |
- &nbioContext, plContext); |
- if (nbioContext != NULL) { |
- *pCertCheckedIndex = j; |
- *pRevChecking = revChecking; |
- *pNBIOContext = nbioContext; |
- goto cleanup; |
- } |
- if (revStatus == PKIX_RevStatus_Revoked || |
- pkixErrorResult) { |
- if (!pkixErrorResult) { |
- /* if pkixErrorResult is returned then |
- * use it as it has a detailed revocation |
- * error code. Otherwise create a new error */ |
- PKIX_ERROR_CREATE(VALIDATE, |
- PKIX_CERTIFICATEREVOKED, |
- pkixErrorResult); |
- } |
- goto cleanup; |
- } |
- revChecking = PKIX_FALSE; |
- *pCheckerIndex = 0; |
- } |
- |
- PKIX_CHECK(pkix_AddToVerifyLog |
- (cert, j, NULL, pVerifyTree, plContext), |
- PKIX_ADDTOVERIFYLOGFAILED); |
- } |
- |
- PKIX_CHECK(pkix_RetrieveOutputs |
- (checkers, pFinalSubjPubKey, pPolicyTree, plContext), |
- PKIX_RETRIEVEOUTPUTSFAILED); |
- |
- *pNBIOContext = NULL; |
- |
-cleanup: |
- if (PKIX_ERROR_RECEIVED && cert) { |
- checkCertError = pkixErrorResult; |
- |
- PKIX_CHECK_FATAL( |
- pkix_AddToVerifyLog(cert, j, checkCertError, pVerifyTree, |
- plContext), |
- PKIX_ADDTOVERIFYLOGFAILED); |
- pkixErrorResult = checkCertError; |
- pkixErrorCode = pkixErrorResult->errCode; |
- checkCertError = NULL; |
- } |
- |
-fatal: |
- if (nssCert) { |
- CERT_DestroyCertificate(nssCert); |
- } |
- |
- if (certList) { |
- CERT_DestroyCertList(certList); |
- } |
- |
- PKIX_DECREF(checkCertError); |
- PKIX_DECREF(cert); |
- PKIX_DECREF(issuer); |
- |
- PKIX_RETURN(VALIDATE); |
-} |
- |
-/* |
- * FUNCTION: pkix_ExtractParameters |
- * DESCRIPTION: |
- * |
- * Extracts several parameters from the ValidateParams object pointed to by |
- * "valParams" and stores the CertChain at "pChain", the List of Certs at |
- * "pCerts", the number of Certs in the chain at "pNumCerts", the |
- * ProcessingParams object at "pProcParams", the List of TrustAnchors at |
- * "pAnchors", and the number of TrustAnchors at "pNumAnchors". |
- * |
- * PARAMETERS: |
- * "valParams" |
- * Address of ValidateParams from which the parameters are extracted. |
- * Must be non-NULL. |
- * "pCerts" |
- * Address where object pointer for List of Certs will be stored. |
- * Must be non-NULL. |
- * "pNumCerts" |
- * Address where number of Certs will be stored. Must be non-NULL. |
- * "pProcParams" |
- * Address where object pointer for ProcessingParams will be stored. |
- * Must be non-NULL. |
- * "pAnchors" |
- * Address where object pointer for List of Anchors will be stored. |
- * Must be non-NULL. |
- * "pNumAnchors" |
- * Address where number of Anchors will be stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a Validate Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_ExtractParameters( |
- PKIX_ValidateParams *valParams, |
- PKIX_List **pCerts, |
- PKIX_UInt32 *pNumCerts, |
- PKIX_ProcessingParams **pProcParams, |
- PKIX_List **pAnchors, |
- PKIX_UInt32 *pNumAnchors, |
- void *plContext) |
-{ |
- PKIX_ENTER(VALIDATE, "pkix_ExtractParameters"); |
- PKIX_NULLCHECK_THREE(valParams, pCerts, pNumCerts); |
- PKIX_NULLCHECK_THREE(pProcParams, pAnchors, pNumAnchors); |
- |
- /* extract relevant parameters from chain */ |
- PKIX_CHECK(PKIX_ValidateParams_GetCertChain |
- (valParams, pCerts, plContext), |
- PKIX_VALIDATEPARAMSGETCERTCHAINFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength(*pCerts, pNumCerts, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- /* extract relevant parameters from procParams */ |
- PKIX_CHECK(PKIX_ValidateParams_GetProcessingParams |
- (valParams, pProcParams, plContext), |
- PKIX_VALIDATEPARAMSGETPROCESSINGPARAMSFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors |
- (*pProcParams, pAnchors, plContext), |
- PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength(*pAnchors, pNumAnchors, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
-cleanup: |
- |
- PKIX_RETURN(VALIDATE); |
-} |
- |
-/* --Public-Functions--------------------------------------------- */ |
- |
-/* |
- * FUNCTION: PKIX_ValidateChain (see comments in pkix.h) |
- */ |
-PKIX_Error * |
-PKIX_ValidateChain( |
- PKIX_ValidateParams *valParams, |
- PKIX_ValidateResult **pResult, |
- PKIX_VerifyNode **pVerifyTree, |
- void *plContext) |
-{ |
- PKIX_Error *chainFailed = NULL; |
- |
- PKIX_ProcessingParams *procParams = NULL; |
- PKIX_CertChainChecker *userChecker = NULL; |
- PKIX_RevocationChecker *revChecker = NULL; |
- PKIX_List *certs = NULL; |
- PKIX_List *checkers = NULL; |
- PKIX_List *anchors = NULL; |
- PKIX_List *userCheckers = NULL; |
- PKIX_List *userCheckerExtOIDs = NULL; |
- PKIX_List *validateCheckedCritExtOIDsList = NULL; |
- PKIX_TrustAnchor *anchor = NULL; |
- PKIX_ValidateResult *valResult = NULL; |
- PKIX_PL_PublicKey *finalPubKey = NULL; |
- PKIX_PolicyNode *validPolicyTree = NULL; |
- PKIX_Boolean supportForwarding = PKIX_FALSE; |
- PKIX_Boolean revChecking = PKIX_FALSE; |
- PKIX_UInt32 i, numCerts, numAnchors; |
- PKIX_UInt32 numUserCheckers = 0; |
- PKIX_UInt32 certCheckedIndex = 0; |
- PKIX_UInt32 checkerIndex = 0; |
- PKIX_UInt32 reasonCode = 0; |
- void *nbioContext = NULL; |
- |
- PKIX_ENTER(VALIDATE, "PKIX_ValidateChain"); |
- PKIX_NULLCHECK_TWO(valParams, pResult); |
- |
- /* extract various parameters from valParams */ |
- PKIX_CHECK(pkix_ExtractParameters |
- (valParams, |
- &certs, |
- &numCerts, |
- &procParams, |
- &anchors, |
- &numAnchors, |
- plContext), |
- PKIX_EXTRACTPARAMETERSFAILED); |
- |
- /* |
- * setup an extension OID list that user had defined for his checker |
- * processing. User checker is not responsible for taking out OIDs |
- * from unresolved critical extension list as the libpkix checker |
- * is doing. Here we add those user checkers' OIDs to the removal |
- * list to be taken out by CheckChain |
- */ |
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers |
- (procParams, &userCheckers, plContext), |
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); |
- |
- if (userCheckers != NULL) { |
- |
- PKIX_CHECK(PKIX_List_Create |
- (&validateCheckedCritExtOIDsList, |
- plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (userCheckers, &numUserCheckers, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (i = 0; i < numUserCheckers; i++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (userCheckers, |
- i, |
- (PKIX_PL_Object **) &userChecker, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK |
- (PKIX_CertChainChecker_IsForwardCheckingSupported |
- (userChecker, &supportForwarding, plContext), |
- PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); |
- |
- if (supportForwarding == PKIX_FALSE) { |
- |
- PKIX_CHECK |
- (PKIX_CertChainChecker_GetSupportedExtensions |
- (userChecker, &userCheckerExtOIDs, plContext), |
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); |
- |
- if (userCheckerExtOIDs != NULL) { |
- PKIX_CHECK(pkix_List_AppendList |
- (validateCheckedCritExtOIDsList, |
- userCheckerExtOIDs, |
- plContext), |
- PKIX_LISTAPPENDLISTFAILED); |
- } |
- } |
- |
- PKIX_DECREF(userCheckerExtOIDs); |
- PKIX_DECREF(userChecker); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker |
- (procParams, &revChecker, plContext), |
- PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); |
- |
- /* try to validate the chain with each anchor */ |
- for (i = 0; i < numAnchors; i++){ |
- |
- /* get trust anchor */ |
- PKIX_CHECK(PKIX_List_GetItem |
- (anchors, i, (PKIX_PL_Object **)&anchor, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- /* initialize checkers using information from trust anchor */ |
- PKIX_CHECK(pkix_InitializeCheckers |
- (anchor, procParams, numCerts, &checkers, plContext), |
- PKIX_INITIALIZECHECKERSFAILED); |
- |
- /* |
- * Validate the chain using this trust anchor and these |
- * checkers. (WARNING: checkers that use non-blocking I/O |
- * are not currently supported.) |
- */ |
- certCheckedIndex = 0; |
- checkerIndex = 0; |
- revChecking = PKIX_FALSE; |
- chainFailed = pkix_CheckChain |
- (certs, |
- numCerts, |
- anchor, |
- checkers, |
- revChecker, |
- validateCheckedCritExtOIDsList, |
- procParams, |
- &certCheckedIndex, |
- &checkerIndex, |
- &revChecking, |
- &reasonCode, |
- &nbioContext, |
- &finalPubKey, |
- &validPolicyTree, |
- pVerifyTree, |
- plContext); |
- |
- if (chainFailed || (reasonCode != 0)) { |
- |
- /* cert chain failed to validate */ |
- |
- PKIX_DECREF(chainFailed); |
- PKIX_DECREF(anchor); |
- PKIX_DECREF(checkers); |
- PKIX_DECREF(validPolicyTree); |
- |
- /* if last anchor, we fail; else, we try next anchor */ |
- if (i == (numAnchors - 1)) { /* last anchor */ |
- PKIX_ERROR(PKIX_VALIDATECHAINFAILED); |
- } |
- |
- } else { |
- |
- /* cert chain successfully validated! */ |
- PKIX_CHECK(pkix_ValidateResult_Create |
- (finalPubKey, |
- anchor, |
- validPolicyTree, |
- &valResult, |
- plContext), |
- PKIX_VALIDATERESULTCREATEFAILED); |
- |
- *pResult = valResult; |
- |
- /* no need to try any more anchors in the loop */ |
- goto cleanup; |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(finalPubKey); |
- PKIX_DECREF(certs); |
- PKIX_DECREF(anchors); |
- PKIX_DECREF(anchor); |
- PKIX_DECREF(checkers); |
- PKIX_DECREF(revChecker); |
- PKIX_DECREF(validPolicyTree); |
- PKIX_DECREF(chainFailed); |
- PKIX_DECREF(procParams); |
- PKIX_DECREF(userCheckers); |
- PKIX_DECREF(validateCheckedCritExtOIDsList); |
- |
- PKIX_RETURN(VALIDATE); |
-} |
- |
-/* |
- * FUNCTION: pkix_Validate_BuildUserOIDs |
- * DESCRIPTION: |
- * |
- * This function creates a List of the OIDs that are processed by the user |
- * checkers in the List pointed to by "userCheckers", storing the resulting |
- * List at "pUserCritOIDs". If the List of userCheckers is NULL, the output |
- * List will be NULL. Otherwise the output List will be non-NULL, but may be |
- * empty. |
- * |
- * PARAMETERS: |
- * "userCheckers" |
- * The address of the List of userCheckers. |
- * "pUserCritOIDs" |
- * The address at which the List is stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds. |
- * Returns a VALIDATE Error if the function fails in a non-fatal way. |
- * Returns a Fatal Error if the function fails in an unrecoverable way. |
- */ |
-static PKIX_Error * |
-pkix_Validate_BuildUserOIDs( |
- PKIX_List *userCheckers, |
- PKIX_List **pUserCritOIDs, |
- void *plContext) |
-{ |
- PKIX_UInt32 numUserCheckers = 0; |
- PKIX_UInt32 i = 0; |
- PKIX_List *userCritOIDs = NULL; |
- PKIX_List *userCheckerExtOIDs = NULL; |
- PKIX_Boolean supportForwarding = PKIX_FALSE; |
- PKIX_CertChainChecker *userChecker = NULL; |
- |
- PKIX_ENTER(VALIDATE, "pkix_Validate_BuildUserOIDs"); |
- PKIX_NULLCHECK_ONE(pUserCritOIDs); |
- |
- if (userCheckers != NULL) { |
- PKIX_CHECK(PKIX_List_Create(&userCritOIDs, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (userCheckers, &numUserCheckers, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (i = 0; i < numUserCheckers; i++) { |
- PKIX_CHECK(PKIX_List_GetItem |
- (userCheckers, |
- i, |
- (PKIX_PL_Object **) &userChecker, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_CertChainChecker_IsForwardCheckingSupported |
- (userChecker, &supportForwarding, plContext), |
- PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); |
- |
- if (supportForwarding == PKIX_FALSE) { |
- |
- PKIX_CHECK(PKIX_CertChainChecker_GetSupportedExtensions |
- (userChecker, &userCheckerExtOIDs, plContext), |
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); |
- |
- if (userCheckerExtOIDs != NULL) { |
- PKIX_CHECK(pkix_List_AppendList |
- (userCritOIDs, userCheckerExtOIDs, plContext), |
- PKIX_LISTAPPENDLISTFAILED); |
- } |
- } |
- |
- PKIX_DECREF(userCheckerExtOIDs); |
- PKIX_DECREF(userChecker); |
- } |
- } |
- |
- *pUserCritOIDs = userCritOIDs; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED){ |
- PKIX_DECREF(userCritOIDs); |
- } |
- |
- PKIX_DECREF(userCheckerExtOIDs); |
- PKIX_DECREF(userChecker); |
- |
- PKIX_RETURN(VALIDATE); |
-} |
- |
-/* |
- * FUNCTION: PKIX_ValidateChain_nb (see comments in pkix.h) |
- */ |
-PKIX_Error * |
-PKIX_ValidateChain_NB( |
- PKIX_ValidateParams *valParams, |
- PKIX_UInt32 *pCertIndex, |
- PKIX_UInt32 *pAnchorIndex, |
- PKIX_UInt32 *pCheckerIndex, |
- PKIX_Boolean *pRevChecking, |
- PKIX_List **pCheckers, |
- void **pNBIOContext, |
- PKIX_ValidateResult **pResult, |
- PKIX_VerifyNode **pVerifyTree, |
- void *plContext) |
-{ |
- PKIX_UInt32 numCerts = 0; |
- PKIX_UInt32 numAnchors = 0; |
- PKIX_UInt32 i = 0; |
- PKIX_UInt32 certIndex = 0; |
- PKIX_UInt32 anchorIndex = 0; |
- PKIX_UInt32 checkerIndex = 0; |
- PKIX_UInt32 reasonCode = 0; |
- PKIX_Boolean revChecking = PKIX_FALSE; |
- PKIX_List *certs = NULL; |
- PKIX_List *anchors = NULL; |
- PKIX_List *checkers = NULL; |
- PKIX_List *userCheckers = NULL; |
- PKIX_List *validateCheckedCritExtOIDsList = NULL; |
- PKIX_TrustAnchor *anchor = NULL; |
- PKIX_ValidateResult *valResult = NULL; |
- PKIX_PL_PublicKey *finalPubKey = NULL; |
- PKIX_PolicyNode *validPolicyTree = NULL; |
- PKIX_ProcessingParams *procParams = NULL; |
- PKIX_RevocationChecker *revChecker = NULL; |
- PKIX_Error *chainFailed = NULL; |
- void *nbioContext = NULL; |
- |
- PKIX_ENTER(VALIDATE, "PKIX_ValidateChain_NB"); |
- PKIX_NULLCHECK_FOUR |
- (valParams, pCertIndex, pAnchorIndex, pCheckerIndex); |
- PKIX_NULLCHECK_FOUR(pRevChecking, pCheckers, pNBIOContext, pResult); |
- |
- nbioContext = *pNBIOContext; |
- *pNBIOContext = NULL; |
- |
- /* extract various parameters from valParams */ |
- PKIX_CHECK(pkix_ExtractParameters |
- (valParams, |
- &certs, |
- &numCerts, |
- &procParams, |
- &anchors, |
- &numAnchors, |
- plContext), |
- PKIX_EXTRACTPARAMETERSFAILED); |
- |
- /* |
- * Create a List of the OIDs that will be processed by the user |
- * checkers. User checkers are not responsible for removing OIDs from |
- * the List of unresolved critical extensions, as libpkix checkers are. |
- * So we add those user checkers' OIDs to the removal list to be taken |
- * out by CheckChain. |
- */ |
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers |
- (procParams, &userCheckers, plContext), |
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); |
- |
- PKIX_CHECK(pkix_Validate_BuildUserOIDs |
- (userCheckers, &validateCheckedCritExtOIDsList, plContext), |
- PKIX_VALIDATEBUILDUSEROIDSFAILED); |
- |
- PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker |
- (procParams, &revChecker, plContext), |
- PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); |
- |
- /* Are we resuming after a WOULDBLOCK return, or starting anew ? */ |
- if (nbioContext != NULL) { |
- /* Resuming */ |
- certIndex = *pCertIndex; |
- anchorIndex = *pAnchorIndex; |
- checkerIndex = *pCheckerIndex; |
- revChecking = *pRevChecking; |
- checkers = *pCheckers; |
- *pCheckers = NULL; |
- } |
- |
- /* try to validate the chain with each anchor */ |
- for (i = anchorIndex; i < numAnchors; i++) { |
- |
- /* get trust anchor */ |
- PKIX_CHECK(PKIX_List_GetItem |
- (anchors, i, (PKIX_PL_Object **)&anchor, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- /* initialize checkers using information from trust anchor */ |
- if (nbioContext == NULL) { |
- PKIX_CHECK(pkix_InitializeCheckers |
- (anchor, |
- procParams, |
- numCerts, |
- &checkers, |
- plContext), |
- PKIX_INITIALIZECHECKERSFAILED); |
- } |
- |
- /* |
- * Validate the chain using this trust anchor and these |
- * checkers. |
- */ |
- chainFailed = pkix_CheckChain |
- (certs, |
- numCerts, |
- anchor, |
- checkers, |
- revChecker, |
- validateCheckedCritExtOIDsList, |
- procParams, |
- &certIndex, |
- &checkerIndex, |
- &revChecking, |
- &reasonCode, |
- &nbioContext, |
- &finalPubKey, |
- &validPolicyTree, |
- pVerifyTree, |
- plContext); |
- |
- if (nbioContext != NULL) { |
- *pCertIndex = certIndex; |
- *pAnchorIndex = anchorIndex; |
- *pCheckerIndex = checkerIndex; |
- *pRevChecking = revChecking; |
- PKIX_INCREF(checkers); |
- *pCheckers = checkers; |
- *pNBIOContext = nbioContext; |
- goto cleanup; |
- } |
- |
- if (chainFailed || (reasonCode != 0)) { |
- |
- /* cert chain failed to validate */ |
- |
- PKIX_DECREF(chainFailed); |
- PKIX_DECREF(anchor); |
- PKIX_DECREF(checkers); |
- PKIX_DECREF(validPolicyTree); |
- |
- /* if last anchor, we fail; else, we try next anchor */ |
- if (i == (numAnchors - 1)) { /* last anchor */ |
- PKIX_ERROR(PKIX_VALIDATECHAINFAILED); |
- } |
- |
- } else { |
- |
- /* cert chain successfully validated! */ |
- PKIX_CHECK(pkix_ValidateResult_Create |
- (finalPubKey, |
- anchor, |
- validPolicyTree, |
- &valResult, |
- plContext), |
- PKIX_VALIDATERESULTCREATEFAILED); |
- |
- *pResult = valResult; |
- |
- /* no need to try any more anchors in the loop */ |
- goto cleanup; |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(finalPubKey); |
- PKIX_DECREF(certs); |
- PKIX_DECREF(anchors); |
- PKIX_DECREF(anchor); |
- PKIX_DECREF(checkers); |
- PKIX_DECREF(revChecker); |
- PKIX_DECREF(validPolicyTree); |
- PKIX_DECREF(chainFailed); |
- PKIX_DECREF(procParams); |
- PKIX_DECREF(userCheckers); |
- PKIX_DECREF(validateCheckedCritExtOIDsList); |
- |
- PKIX_RETURN(VALIDATE); |
-} |