Blame nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
/*
Packit 40b132
 * pkix_revocationchecker.c
Packit 40b132
 *
Packit 40b132
 * RevocationChecker Object Functions
Packit 40b132
 *
Packit 40b132
 */
Packit 40b132
Packit 40b132
#include "pkix_revocationchecker.h"
Packit 40b132
#include "pkix_tools.h"
Packit 40b132
Packit 40b132
/* --Private-Functions-------------------------------------------- */
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_RevocationChecker_Destroy
Packit 40b132
 *      (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_RevocationChecker_Destroy(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_RevocationChecker *checker = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Destroy");
Packit 40b132
        PKIX_NULLCHECK_ONE(object);
Packit 40b132
Packit 40b132
        /* Check that this object is a revocation checker */
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
Packit 40b132
                    PKIX_OBJECTNOTREVOCATIONCHECKER);
Packit 40b132
Packit 40b132
        checker = (PKIX_RevocationChecker *)object;
Packit 40b132
Packit 40b132
        PKIX_DECREF(checker->leafMethodList);
Packit 40b132
        PKIX_DECREF(checker->chainMethodList);
Packit 40b132
        
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_RevocationChecker_Duplicate
Packit 40b132
 * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_RevocationChecker_Duplicate(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        PKIX_PL_Object **pNewObject,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_RevocationChecker *checker = NULL;
Packit 40b132
        PKIX_RevocationChecker *checkerDuplicate = NULL;
Packit 40b132
        PKIX_List *dupLeafList = NULL;
Packit 40b132
        PKIX_List *dupChainList = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Duplicate");
Packit 40b132
        PKIX_NULLCHECK_TWO(object, pNewObject);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
Packit 40b132
                    PKIX_OBJECTNOTCERTCHAINCHECKER);
Packit 40b132
Packit 40b132
        checker = (PKIX_RevocationChecker *)object;
Packit 40b132
Packit 40b132
        if (checker->leafMethodList){
Packit 40b132
                PKIX_CHECK(PKIX_PL_Object_Duplicate
Packit 40b132
                            ((PKIX_PL_Object *)checker->leafMethodList,
Packit 40b132
                            (PKIX_PL_Object **)&dupLeafList,
Packit 40b132
                            plContext),
Packit 40b132
                            PKIX_OBJECTDUPLICATEFAILED);
Packit 40b132
        }
Packit 40b132
        if (checker->chainMethodList){
Packit 40b132
                PKIX_CHECK(PKIX_PL_Object_Duplicate
Packit 40b132
                            ((PKIX_PL_Object *)checker->chainMethodList,
Packit 40b132
                            (PKIX_PL_Object **)&dupChainList,
Packit 40b132
                            plContext),
Packit 40b132
                            PKIX_OBJECTDUPLICATEFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(
Packit 40b132
            PKIX_RevocationChecker_Create(checker->leafMethodListFlags,
Packit 40b132
                                          checker->chainMethodListFlags,
Packit 40b132
                                          &checkerDuplicate,
Packit 40b132
                                          plContext),
Packit 40b132
            PKIX_REVOCATIONCHECKERCREATEFAILED);
Packit 40b132
Packit 40b132
        checkerDuplicate->leafMethodList = dupLeafList;
Packit 40b132
        checkerDuplicate->chainMethodList = dupChainList;
Packit 40b132
        dupLeafList = NULL;
Packit 40b132
        dupChainList = NULL;
Packit 40b132
Packit 40b132
        *pNewObject = (PKIX_PL_Object *)checkerDuplicate;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
        PKIX_DECREF(dupLeafList);
Packit 40b132
        PKIX_DECREF(dupChainList);
Packit 40b132
Packit 40b132
        PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_RevocationChecker_RegisterSelf
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *  Registers PKIX_REVOCATIONCHECKER_TYPE and its related functions with
Packit 40b132
 *  systemClasses[]
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - for performance and complexity reasons
Packit 40b132
 *
Packit 40b132
 *  Since this function is only called by PKIX_PL_Initialize, which should
Packit 40b132
 *  only be called once, it is acceptable that this function is not
Packit 40b132
 *  thread-safe.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_RevocationChecker_RegisterSelf(void *plContext)
Packit 40b132
{
Packit 40b132
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
Packit 40b132
        pkix_ClassTable_Entry entry;
Packit 40b132
Packit 40b132
        PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_RegisterSelf");
Packit 40b132
Packit 40b132
        entry.description = "RevocationChecker";
Packit 40b132
        entry.objCounter = 0;
Packit 40b132
        entry.typeObjectSize = sizeof(PKIX_RevocationChecker);
Packit 40b132
        entry.destructor = pkix_RevocationChecker_Destroy;
Packit 40b132
        entry.equalsFunction = NULL;
Packit 40b132
        entry.hashcodeFunction = NULL;
Packit 40b132
        entry.toStringFunction = NULL;
Packit 40b132
        entry.comparator = NULL;
Packit 40b132
        entry.duplicateFunction = pkix_RevocationChecker_Duplicate;
Packit 40b132
Packit 40b132
        systemClasses[PKIX_REVOCATIONCHECKER_TYPE] = entry;
Packit 40b132
Packit 40b132
        PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132
Packit 40b132
/* Sort methods by their priorities (lower priority = higher preference) */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_RevocationChecker_SortComparator(
Packit 40b132
        PKIX_PL_Object *obj1,
Packit 40b132
        PKIX_PL_Object *obj2,
Packit 40b132
        PKIX_Int32 *pResult,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
    pkix_RevocationMethod *method1 = NULL, *method2 = NULL;
Packit 40b132
    
Packit 40b132
    PKIX_ENTER(BUILD, "pkix_RevocationChecker_SortComparator");
Packit 40b132
    
Packit 40b132
    method1 = (pkix_RevocationMethod *)obj1;
Packit 40b132
    method2 = (pkix_RevocationMethod *)obj2;
Packit 40b132
    
Packit 40b132
    if (method1->priority < method2->priority) {
Packit 40b132
      *pResult = -1;
Packit 40b132
    } else if (method1->priority > method2->priority) {
Packit 40b132
      *pResult = 1;
Packit 40b132
    } else {
Packit 40b132
      *pResult = 0;
Packit 40b132
    }
Packit 40b132
    
Packit 40b132
    PKIX_RETURN(BUILD);
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
/* --Public-Functions--------------------------------------------- */
Packit 40b132
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_RevocationChecker_Create (see comments in pkix_revchecker.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_RevocationChecker_Create(
Packit 40b132
    PKIX_UInt32 leafMethodListFlags,
Packit 40b132
    PKIX_UInt32 chainMethodListFlags,
Packit 40b132
    PKIX_RevocationChecker **pChecker,
Packit 40b132
    void *plContext)
Packit 40b132
{
Packit 40b132
    PKIX_RevocationChecker *checker = NULL;
Packit 40b132
    
Packit 40b132
    PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Create");
Packit 40b132
    PKIX_NULLCHECK_ONE(pChecker);
Packit 40b132
    
Packit 40b132
    PKIX_CHECK(
Packit 40b132
        PKIX_PL_Object_Alloc(PKIX_REVOCATIONCHECKER_TYPE,
Packit 40b132
                             sizeof (PKIX_RevocationChecker),
Packit 40b132
                             (PKIX_PL_Object **)&checker,
Packit 40b132
                             plContext),
Packit 40b132
        PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
Packit 40b132
    
Packit 40b132
    checker->leafMethodListFlags = leafMethodListFlags;
Packit 40b132
    checker->chainMethodListFlags = chainMethodListFlags;
Packit 40b132
    checker->leafMethodList = NULL;
Packit 40b132
    checker->chainMethodList = NULL;
Packit 40b132
    
Packit 40b132
    *pChecker = checker;
Packit 40b132
    checker = NULL;
Packit 40b132
    
Packit 40b132
cleanup:
Packit 40b132
    PKIX_DECREF(checker);
Packit 40b132
    
Packit 40b132
    PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_RevocationChecker_CreateAndAddMethod(
Packit 40b132
    PKIX_RevocationChecker *revChecker,
Packit 40b132
    PKIX_ProcessingParams *params,
Packit 40b132
    PKIX_RevocationMethodType methodType,
Packit 40b132
    PKIX_UInt32 flags,
Packit 40b132
    PKIX_UInt32 priority,
Packit 40b132
    PKIX_PL_VerifyCallback verificationFn,
Packit 40b132
    PKIX_Boolean isLeafMethod,
Packit 40b132
    void *plContext)
Packit 40b132
{
Packit 40b132
    PKIX_List **methodList = NULL;
Packit 40b132
    PKIX_List  *unsortedList = NULL;
Packit 40b132
    PKIX_List  *certStores = NULL;
Packit 40b132
    pkix_RevocationMethod *method = NULL;
Packit 40b132
    pkix_LocalRevocationCheckFn *localRevChecker = NULL;
Packit 40b132
    pkix_ExternalRevocationCheckFn *externRevChecker = NULL;
Packit 40b132
    PKIX_UInt32 miFlags;
Packit 40b132
    
Packit 40b132
    PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod");
Packit 40b132
    PKIX_NULLCHECK_ONE(revChecker);
Packit 40b132
Packit 40b132
    /* If the caller has said "Either one is sufficient, then don't let the 
Packit 40b132
     * absence of any one method's info lead to an overall failure.
Packit 40b132
     */
Packit 40b132
    miFlags = isLeafMethod ? revChecker->leafMethodListFlags 
Packit 40b132
	                   : revChecker->chainMethodListFlags;
Packit 40b132
    if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE)
Packit 40b132
	flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
Packit 40b132
Packit 40b132
    switch (methodType) {
Packit 40b132
    case PKIX_RevocationMethod_CRL:
Packit 40b132
        localRevChecker = pkix_CrlChecker_CheckLocal;
Packit 40b132
        externRevChecker = pkix_CrlChecker_CheckExternal;
Packit 40b132
        PKIX_CHECK(
Packit 40b132
            PKIX_ProcessingParams_GetCertStores(params, &certStores,
Packit 40b132
                                                plContext),
Packit 40b132
            PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
Packit 40b132
        PKIX_CHECK(
Packit 40b132
            pkix_CrlChecker_Create(methodType, flags, priority,
Packit 40b132
                                   localRevChecker, externRevChecker,
Packit 40b132
                                   certStores, verificationFn,
Packit 40b132
                                   &method,
Packit 40b132
                                   plContext),
Packit 40b132
            PKIX_COULDNOTCREATECRLCHECKEROBJECT);
Packit 40b132
        break;
Packit 40b132
    case PKIX_RevocationMethod_OCSP:
Packit 40b132
        localRevChecker = pkix_OcspChecker_CheckLocal;
Packit 40b132
        externRevChecker = pkix_OcspChecker_CheckExternal;
Packit 40b132
        PKIX_CHECK(
Packit 40b132
            pkix_OcspChecker_Create(methodType, flags, priority,
Packit 40b132
                                    localRevChecker, externRevChecker,
Packit 40b132
                                    verificationFn,
Packit 40b132
                                    &method,
Packit 40b132
                                    plContext),
Packit 40b132
            PKIX_COULDNOTCREATEOCSPCHECKEROBJECT);
Packit 40b132
        break;
Packit 40b132
    default:
Packit 40b132
        PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (isLeafMethod) {
Packit 40b132
        methodList = &revChecker->leafMethodList;
Packit 40b132
    } else {
Packit 40b132
        methodList = &revChecker->chainMethodList;
Packit 40b132
    }
Packit 40b132
    
Packit 40b132
    if (*methodList == NULL) {
Packit 40b132
        PKIX_CHECK(
Packit 40b132
            PKIX_List_Create(methodList, plContext),
Packit 40b132
            PKIX_LISTCREATEFAILED);
Packit 40b132
    }
Packit 40b132
    unsortedList = *methodList;
Packit 40b132
    PKIX_CHECK(
Packit 40b132
        PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext),
Packit 40b132
        PKIX_LISTAPPENDITEMFAILED);
Packit 40b132
    PKIX_CHECK(
Packit 40b132
        pkix_List_BubbleSort(unsortedList, 
Packit 40b132
                             pkix_RevocationChecker_SortComparator,
Packit 40b132
                             methodList, plContext),
Packit 40b132
        PKIX_LISTBUBBLESORTFAILED);
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
    PKIX_DECREF(method);
Packit 40b132
    PKIX_DECREF(unsortedList);
Packit 40b132
    PKIX_DECREF(certStores);
Packit 40b132
    
Packit 40b132
    PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_RevocationChecker_Check
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_RevocationChecker_Check(
Packit 40b132
    PKIX_PL_Cert *cert,
Packit 40b132
    PKIX_PL_Cert *issuer,
Packit 40b132
    PKIX_RevocationChecker *revChecker,
Packit 40b132
    PKIX_ProcessingParams *procParams,
Packit 40b132
    PKIX_Boolean chainVerificationState,
Packit 40b132
    PKIX_Boolean testingLeafCert,
Packit 40b132
    PKIX_RevocationStatus *pRevStatus,
Packit 40b132
    PKIX_UInt32 *pReasonCode,
Packit 40b132
    void **pNbioContext,
Packit 40b132
    void *plContext)
Packit 40b132
{
Packit 40b132
    PKIX_RevocationStatus overallStatus = PKIX_RevStatus_NoInfo;
Packit 40b132
    PKIX_RevocationStatus methodStatus[PKIX_RevocationMethod_MAX];
Packit 40b132
    PKIX_Boolean onlyUseRemoteMethods = PKIX_FALSE;
Packit 40b132
    PKIX_UInt32 revFlags = 0;
Packit 40b132
    PKIX_List *revList = NULL;
Packit 40b132
    PKIX_PL_Date *date = NULL;
Packit 40b132
    pkix_RevocationMethod *method = NULL;
Packit 40b132
    void *nbioContext;
Packit 40b132
    int tries;
Packit 40b132
    
Packit 40b132
    PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Check");
Packit 40b132
    PKIX_NULLCHECK_TWO(revChecker, procParams);
Packit 40b132
Packit 40b132
    nbioContext = *pNbioContext;
Packit 40b132
    *pNbioContext = NULL;
Packit 40b132
    
Packit 40b132
    if (testingLeafCert) {
Packit 40b132
        revList = revChecker->leafMethodList;
Packit 40b132
        revFlags = revChecker->leafMethodListFlags;        
Packit 40b132
    } else {
Packit 40b132
        revList = revChecker->chainMethodList;
Packit 40b132
        revFlags = revChecker->chainMethodListFlags;
Packit 40b132
    }
Packit 40b132
    if (!revList) {
Packit 40b132
        /* Return NoInfo status */
Packit 40b132
        goto cleanup;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_Memset(methodStatus, PKIX_RevStatus_NoInfo,
Packit 40b132
                sizeof(PKIX_RevocationStatus) * PKIX_RevocationMethod_MAX);
Packit 40b132
Packit 40b132
    date = procParams->date;
Packit 40b132
Packit 40b132
    /* Need to have two loops if we testing all local info first:
Packit 40b132
     *    first we are going to test all local(cached) info
Packit 40b132
     *    second, all remote info(fetching) */
Packit 40b132
    for (tries = 0;tries < 2;tries++) {
Packit 40b132
        int methodNum = 0;
Packit 40b132
        for (;methodNum < revList->length;methodNum++) {
Packit 40b132
            PKIX_UInt32 methodFlags = 0;
Packit 40b132
Packit 40b132
            PKIX_DECREF(method);
Packit 40b132
            PKIX_CHECK(
Packit 40b132
                PKIX_List_GetItem(revList, methodNum,
Packit 40b132
                                  (PKIX_PL_Object**)&method, plContext),
Packit 40b132
                PKIX_LISTGETITEMFAILED);
Packit 40b132
            methodFlags = method->flags;
Packit 40b132
            if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) {
Packit 40b132
                /* Will not check with this method. Skipping... */
Packit 40b132
                continue;
Packit 40b132
            }
Packit 40b132
            if (!onlyUseRemoteMethods &&
Packit 40b132
                methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
Packit 40b132
                PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
Packit 40b132
                PKIX_CHECK_NO_GOTO(
Packit 40b132
                    (*method->localRevChecker)(cert, issuer, date,
Packit 40b132
                                               method, procParams,
Packit 40b132
                                               methodFlags, 
Packit 40b132
                                               chainVerificationState,
Packit 40b132
                                               &revStatus,
Packit 40b132
                                               pReasonCode, plContext),
Packit 40b132
                    PKIX_REVCHECKERCHECKFAILED);
Packit 40b132
                methodStatus[methodNum] = revStatus;
Packit 40b132
                if (revStatus == PKIX_RevStatus_Revoked) {
Packit 40b132
                    /* if error was generated use it as final error. */
Packit 40b132
                    overallStatus = PKIX_RevStatus_Revoked;
Packit 40b132
                    goto cleanup;
Packit 40b132
                }
Packit 40b132
                if (pkixErrorResult) {
Packit 40b132
                    /* Disregard errors. Only returned revStatus matters. */
Packit 40b132
                    PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
Packit 40b132
                                          plContext);
Packit 40b132
                    pkixErrorResult = NULL;
Packit 40b132
                }
Packit 40b132
            }
Packit 40b132
            if ((!(revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST) ||
Packit 40b132
                 onlyUseRemoteMethods) &&
Packit 40b132
                chainVerificationState &&
Packit 40b132
                methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
Packit 40b132
                if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) {
Packit 40b132
                    PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
Packit 40b132
                    PKIX_CHECK_NO_GOTO(
Packit 40b132
                        (*method->externalRevChecker)(cert, issuer, date,
Packit 40b132
                                                      method,
Packit 40b132
                                                      procParams, methodFlags,
Packit 40b132
                                                      &revStatus, pReasonCode,
Packit 40b132
                                                      &nbioContext, plContext),
Packit 40b132
                        PKIX_REVCHECKERCHECKFAILED);
Packit 40b132
                    methodStatus[methodNum] = revStatus;
Packit 40b132
                    if (revStatus == PKIX_RevStatus_Revoked) {
Packit 40b132
                        /* if error was generated use it as final error. */
Packit 40b132
                        overallStatus = PKIX_RevStatus_Revoked;
Packit 40b132
                        goto cleanup;
Packit 40b132
                    }
Packit 40b132
                    if (pkixErrorResult) {
Packit 40b132
                        /* Disregard errors. Only returned revStatus matters. */
Packit 40b132
                        PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
Packit 40b132
                                              plContext);
Packit 40b132
                        pkixErrorResult = NULL;
Packit 40b132
                    }
Packit 40b132
                } else if (methodFlags &
Packit 40b132
                           PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
Packit 40b132
                    /* Info is not in the local cache. Network fetching is not
Packit 40b132
                     * allowed. If need to fail on missing fresh info for the
Packit 40b132
                     * the method, then we should fail right here.*/
Packit 40b132
                    overallStatus = PKIX_RevStatus_Revoked;
Packit 40b132
                    goto cleanup;
Packit 40b132
                }
Packit 40b132
            }
Packit 40b132
            /* If success and we should not check the next method, then
Packit 40b132
             * return a success. */
Packit 40b132
            if (methodStatus[methodNum] == PKIX_RevStatus_Success &&
Packit 40b132
                !(methodFlags & PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO)) {
Packit 40b132
                overallStatus = PKIX_RevStatus_Success;
Packit 40b132
                goto cleanup;
Packit 40b132
            }
Packit 40b132
        } /* inner loop */
Packit 40b132
        if (!onlyUseRemoteMethods &&
Packit 40b132
            revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST &&
Packit 40b132
            chainVerificationState) {
Packit 40b132
            onlyUseRemoteMethods = PKIX_TRUE;
Packit 40b132
            continue;
Packit 40b132
        }
Packit 40b132
        break;
Packit 40b132
    } /* outer loop */
Packit 40b132
    
Packit 40b132
    if (overallStatus == PKIX_RevStatus_NoInfo &&
Packit 40b132
        chainVerificationState) {
Packit 40b132
        /* The following check makes sence only for chain
Packit 40b132
         * validation step, sinse we do not fetch info while
Packit 40b132
         * in the process of finding trusted anchor. 
Packit 40b132
         * For chain building step it is enough to know, that
Packit 40b132
         * the cert was not directly revoked by any of the
Packit 40b132
         * methods. */
Packit 40b132
Packit 40b132
        /* Still have no info. But one of the method could
Packit 40b132
         * have returned success status(possible if CONTINUE
Packit 40b132
         * TESTING ON FRESH INFO flag was used).
Packit 40b132
         * If any of the methods have returned Success status,
Packit 40b132
         * the overallStatus should be success. */
Packit 40b132
        int methodNum = 0;
Packit 40b132
        for (;methodNum < PKIX_RevocationMethod_MAX;methodNum++) {
Packit 40b132
            if (methodStatus[methodNum] == PKIX_RevStatus_Success) {
Packit 40b132
                overallStatus = PKIX_RevStatus_Success;
Packit 40b132
                goto cleanup;
Packit 40b132
            }
Packit 40b132
        }
Packit 40b132
        if (revFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) {
Packit 40b132
            overallStatus = PKIX_RevStatus_Revoked;
Packit 40b132
        }
Packit 40b132
    }
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
    *pRevStatus = overallStatus;
Packit 40b132
    PKIX_DECREF(method);
Packit 40b132
Packit 40b132
    PKIX_RETURN(REVOCATIONCHECKER);
Packit 40b132
}
Packit 40b132