diff options
Diffstat (limited to 'security/nss/lib/libpkix/pkix/top')
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/Makefile | 48 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/config.mk | 15 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/manifest.mn | 25 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_build.c | 3821 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_build.h | 123 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c | 210 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h | 23 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_validate.c | 1443 | ||||
-rwxr-xr-x | security/nss/lib/libpkix/pkix/top/pkix_validate.h | 42 |
9 files changed, 0 insertions, 5750 deletions
diff --git a/security/nss/lib/libpkix/pkix/top/Makefile b/security/nss/lib/libpkix/pkix/top/Makefile deleted file mode 100755 index 36524f56a..000000000 --- a/security/nss/lib/libpkix/pkix/top/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -#! gmake -# -# 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/. - -####################################################################### -# (1) Include initial platform-independent assignments (MANDATORY). # -####################################################################### - -include manifest.mn - -####################################################################### -# (2) Include "global" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/config.mk - -####################################################################### -# (3) Include "component" configuration information. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (4) Include "local" platform-dependent assignments (OPTIONAL). # -####################################################################### - -include config.mk - -####################################################################### -# (5) Execute "global" rules. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/rules.mk - -####################################################################### -# (6) Execute "component" rules. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (7) Execute "local" rules. (OPTIONAL). # -####################################################################### - -export:: private_export - diff --git a/security/nss/lib/libpkix/pkix/top/config.mk b/security/nss/lib/libpkix/pkix/top/config.mk deleted file mode 100755 index b8c03de79..000000000 --- a/security/nss/lib/libpkix/pkix/top/config.mk +++ /dev/null @@ -1,15 +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/. - -# -# Override TARGETS variable so that only static libraries -# are specifed as dependencies within rules.mk. -# - -TARGETS = $(LIBRARY) -SHARED_LIBRARY = -IMPORT_LIBRARY = -PROGRAM = - diff --git a/security/nss/lib/libpkix/pkix/top/manifest.mn b/security/nss/lib/libpkix/pkix/top/manifest.mn deleted file mode 100755 index bb7a600b3..000000000 --- a/security/nss/lib/libpkix/pkix/top/manifest.mn +++ /dev/null @@ -1,25 +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/. -CORE_DEPTH = ../../../../.. - -EXPORTS = \ - $(NULL) - -PRIVATE_EXPORTS = \ - pkix_build.h \ - pkix_lifecycle.h \ - pkix_validate.h \ - $(NULL) - -MODULE = nss - -CSRCS = \ - pkix_validate.c \ - pkix_lifecycle.c \ - pkix_build.c \ - $(NULL) - -LIBRARY_NAME = pkixtop - diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.c b/security/nss/lib/libpkix/pkix/top/pkix_build.c deleted file mode 100755 index 574fcfbbf..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_build.c +++ /dev/null @@ -1,3821 +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_build.c - * - * Top level buildChain function - * - */ - -/* #define PKIX_BUILDDEBUG 1 */ -/* #define PKIX_FORWARDBUILDERSTATEDEBUG 1 */ - -#include "pkix_build.h" - -extern PRLogModuleInfo *pkixLog; - -/* - * List of critical extension OIDs associate with what build chain has - * checked. Those OIDs need to be removed from the unresolved critical - * extension OIDs list manually (instead of by checker automatically). - */ -static SECOidTag buildCheckedCritExtOIDs[] = { - PKIX_CERTKEYUSAGE_OID, - PKIX_CERTSUBJALTNAME_OID, - PKIX_BASICCONSTRAINTS_OID, - PKIX_NAMECONSTRAINTS_OID, - PKIX_EXTENDEDKEYUSAGE_OID, - PKIX_NSCERTTYPE_OID, - PKIX_UNKNOWN_OID -}; - -/* --Private-ForwardBuilderState-Functions---------------------------------- */ - -/* - * FUNCTION: pkix_ForwardBuilderState_Destroy - * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) - */ -static PKIX_Error * -pkix_ForwardBuilderState_Destroy( - PKIX_PL_Object *object, - void *plContext) -{ - PKIX_ForwardBuilderState *state = NULL; - - PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Destroy"); - PKIX_NULLCHECK_ONE(object); - - PKIX_CHECK(pkix_CheckType - (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext), - PKIX_OBJECTNOTFORWARDBUILDERSTATE); - - state = (PKIX_ForwardBuilderState *)object; - - state->status = BUILD_INITIAL; - state->traversedCACerts = 0; - state->certStoreIndex = 0; - state->numCerts = 0; - state->numAias = 0; - state->certIndex = 0; - state->aiaIndex = 0; - state->certCheckedIndex = 0; - state->checkerIndex = 0; - state->hintCertIndex = 0; - state->numFanout = 0; - state->numDepth = 0; - state->reasonCode = 0; - state->revCheckDelayed = PKIX_FALSE; - state->canBeCached = PKIX_FALSE; - state->useOnlyLocal = PKIX_FALSE; - state->revChecking = PKIX_FALSE; - state->usingHintCerts = PKIX_FALSE; - state->certLoopingDetected = PKIX_FALSE; - PKIX_DECREF(state->validityDate); - PKIX_DECREF(state->prevCert); - PKIX_DECREF(state->candidateCert); - PKIX_DECREF(state->traversedSubjNames); - PKIX_DECREF(state->trustChain); - PKIX_DECREF(state->aia); - PKIX_DECREF(state->candidateCerts); - PKIX_DECREF(state->reversedCertChain); - PKIX_DECREF(state->checkedCritExtOIDs); - PKIX_DECREF(state->checkerChain); - PKIX_DECREF(state->certSel); - PKIX_DECREF(state->verifyNode); - PKIX_DECREF(state->client); - - /* - * If we ever add a child link we have to be careful not to have loops - * in the Destroy process. But with one-way links we should be okay. - */ - if (state->parentState == NULL) { - state->buildConstants.numAnchors = 0; - state->buildConstants.numCertStores = 0; - state->buildConstants.numHintCerts = 0; - state->buildConstants.procParams = 0; - PKIX_DECREF(state->buildConstants.testDate); - PKIX_DECREF(state->buildConstants.timeLimit); - PKIX_DECREF(state->buildConstants.targetCert); - PKIX_DECREF(state->buildConstants.targetPubKey); - PKIX_DECREF(state->buildConstants.certStores); - PKIX_DECREF(state->buildConstants.anchors); - PKIX_DECREF(state->buildConstants.userCheckers); - PKIX_DECREF(state->buildConstants.hintCerts); - PKIX_DECREF(state->buildConstants.revChecker); - PKIX_DECREF(state->buildConstants.aiaMgr); - } else { - PKIX_DECREF(state->parentState); - } - -cleanup: - - PKIX_RETURN(FORWARDBUILDERSTATE); -} - -/* - * FUNCTION: pkix_ForwardBuilderState_Create - * - * DESCRIPTION: - * Allocate and initialize a ForwardBuilderState. - * - * PARAMETERS - * "traversedCACerts" - * Number of CA certificates traversed. - * "numFanout" - * Number of Certs that can be considered at this level (0 = no limit) - * "numDepth" - * Number of additional levels that can be searched (0 = no limit) - * "revCheckDelayed" - * Boolean value indicating whether rev check is delayed until after - * entire chain is built. - * "canBeCached" - * Boolean value indicating whether all certs on the chain can be cached. - * "validityDate" - * Address of Date at which build chain Certs' most restricted validity - * time is kept. May be NULL. - * "prevCert" - * Address of Cert just traversed. Must be non-NULL. - * "traversedSubjNames" - * Address of List of GeneralNames that have been traversed. - * Must be non-NULL. - * "trustChain" - * Address of List of certificates traversed. Must be non-NULL. - * "parentState" - * Address of previous ForwardBuilderState - * "pState" - * Address where ForwardBuilderState 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 Build 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_ForwardBuilderState_Create( - PKIX_Int32 traversedCACerts, - PKIX_UInt32 numFanout, - PKIX_UInt32 numDepth, - PKIX_Boolean revCheckDelayed, - PKIX_Boolean canBeCached, - PKIX_PL_Date *validityDate, - PKIX_PL_Cert *prevCert, - PKIX_List *traversedSubjNames, - PKIX_List *trustChain, - PKIX_ForwardBuilderState *parentState, - PKIX_ForwardBuilderState **pState, - void *plContext) -{ - PKIX_ForwardBuilderState *state = NULL; - - PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Create"); - PKIX_NULLCHECK_FOUR(prevCert, traversedSubjNames, pState, trustChain); - - PKIX_CHECK(PKIX_PL_Object_Alloc - (PKIX_FORWARDBUILDERSTATE_TYPE, - sizeof (PKIX_ForwardBuilderState), - (PKIX_PL_Object **)&state, - plContext), - PKIX_COULDNOTCREATEFORWARDBUILDERSTATEOBJECT); - - state->status = BUILD_INITIAL; - state->traversedCACerts = traversedCACerts; - state->certStoreIndex = 0; - state->numCerts = 0; - state->numAias = 0; - state->certIndex = 0; - state->aiaIndex = 0; - state->certCheckedIndex = 0; - state->checkerIndex = 0; - state->hintCertIndex = 0; - state->numFanout = numFanout; - state->numDepth = numDepth; - state->reasonCode = 0; - state->revChecking = numDepth; - state->revCheckDelayed = revCheckDelayed; - state->canBeCached = canBeCached; - state->useOnlyLocal = PKIX_TRUE; - state->revChecking = PKIX_FALSE; - state->usingHintCerts = PKIX_FALSE; - state->certLoopingDetected = PKIX_FALSE; - - PKIX_INCREF(validityDate); - state->validityDate = validityDate; - - PKIX_INCREF(prevCert); - state->prevCert = prevCert; - - state->candidateCert = NULL; - - PKIX_INCREF(traversedSubjNames); - state->traversedSubjNames = traversedSubjNames; - - PKIX_INCREF(trustChain); - state->trustChain = trustChain; - - state->aia = NULL; - state->candidateCerts = NULL; - state->reversedCertChain = NULL; - state->checkedCritExtOIDs = NULL; - state->checkerChain = NULL; - state->certSel = NULL; - state->verifyNode = NULL; - state->client = NULL; - - PKIX_INCREF(parentState); - state->parentState = parentState; - - if (parentState != NULL) { - state->buildConstants.numAnchors = - parentState->buildConstants.numAnchors; - state->buildConstants.numCertStores = - parentState->buildConstants.numCertStores; - state->buildConstants.numHintCerts = - parentState->buildConstants.numHintCerts; - state->buildConstants.maxFanout = - parentState->buildConstants.maxFanout; - state->buildConstants.maxDepth = - parentState->buildConstants.maxDepth; - state->buildConstants.maxTime = - parentState->buildConstants.maxTime; - state->buildConstants.procParams = - parentState->buildConstants.procParams; - state->buildConstants.testDate = - parentState->buildConstants.testDate; - state->buildConstants.timeLimit = - parentState->buildConstants.timeLimit; - state->buildConstants.targetCert = - parentState->buildConstants.targetCert; - state->buildConstants.targetPubKey = - parentState->buildConstants.targetPubKey; - state->buildConstants.certStores = - parentState->buildConstants.certStores; - state->buildConstants.anchors = - parentState->buildConstants.anchors; - state->buildConstants.userCheckers = - parentState->buildConstants.userCheckers; - state->buildConstants.hintCerts = - parentState->buildConstants.hintCerts; - state->buildConstants.revChecker = - parentState->buildConstants.revChecker; - state->buildConstants.aiaMgr = - parentState->buildConstants.aiaMgr; - state->buildConstants.trustOnlyUserAnchors = - parentState->buildConstants.trustOnlyUserAnchors; - } - - *pState = state; - state = NULL; -cleanup: - - PKIX_DECREF(state); - - PKIX_RETURN(FORWARDBUILDERSTATE); -} - -/* - * FUNCTION: pkix_Build_GetResourceLimits - * - * DESCRIPTION: - * Retrieve Resource Limits from ProcessingParams and initialize them in - * BuildConstants. - * - * PARAMETERS - * "buildConstants" - * Address of a BuildConstants structure containing objects and values - * that remain constant throughout the building of a chain. 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 Build 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_Build_GetResourceLimits( - BuildConstants *buildConstants, - void *plContext) -{ - PKIX_ResourceLimits *resourceLimits = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_GetResourceLimits"); - PKIX_NULLCHECK_ONE(buildConstants); - - PKIX_CHECK(PKIX_ProcessingParams_GetResourceLimits - (buildConstants->procParams, &resourceLimits, plContext), - PKIX_PROCESSINGPARAMSGETRESOURCELIMITSFAILED); - - buildConstants->maxFanout = 0; - buildConstants->maxDepth = 0; - buildConstants->maxTime = 0; - - if (resourceLimits) { - - PKIX_CHECK(PKIX_ResourceLimits_GetMaxFanout - (resourceLimits, &buildConstants->maxFanout, plContext), - PKIX_RESOURCELIMITSGETMAXFANOUTFAILED); - - PKIX_CHECK(PKIX_ResourceLimits_GetMaxDepth - (resourceLimits, &buildConstants->maxDepth, plContext), - PKIX_RESOURCELIMITSGETMAXDEPTHFAILED); - - PKIX_CHECK(PKIX_ResourceLimits_GetMaxTime - (resourceLimits, &buildConstants->maxTime, plContext), - PKIX_RESOURCELIMITSGETMAXTIMEFAILED); - } - -cleanup: - - PKIX_DECREF(resourceLimits); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_ForwardBuilderState_ToString - * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) - */ -static PKIX_Error * -pkix_ForwardBuilderState_ToString - (PKIX_PL_Object *object, - PKIX_PL_String **pString, - void *plContext) -{ - PKIX_ForwardBuilderState *state = NULL; - PKIX_PL_String *formatString = NULL; - PKIX_PL_String *resultString = NULL; - PKIX_PL_String *buildStatusString = NULL; - PKIX_PL_String *validityDateString = NULL; - PKIX_PL_String *prevCertString = NULL; - PKIX_PL_String *candidateCertString = NULL; - PKIX_PL_String *traversedSubjNamesString = NULL; - PKIX_PL_String *trustChainString = NULL; - PKIX_PL_String *candidateCertsString = NULL; - PKIX_PL_String *certSelString = NULL; - PKIX_PL_String *verifyNodeString = NULL; - PKIX_PL_String *parentStateString = NULL; - char *asciiFormat = "\n" - "\t{buildStatus: \t%s\n" - "\ttraversedCACerts: \t%d\n" - "\tcertStoreIndex: \t%d\n" - "\tnumCerts: \t%d\n" - "\tnumAias: \t%d\n" - "\tcertIndex: \t%d\n" - "\taiaIndex: \t%d\n" - "\tnumFanout: \t%d\n" - "\tnumDepth: \t%d\n" - "\treasonCode: \t%d\n" - "\trevCheckDelayed: \t%d\n" - "\tcanBeCached: \t%d\n" - "\tuseOnlyLocal: \t%d\n" - "\trevChecking: \t%d\n" - "\tvalidityDate: \t%s\n" - "\tprevCert: \t%s\n" - "\tcandidateCert: \t%s\n" - "\ttraversedSubjNames: \t%s\n" - "\ttrustChain: \t%s\n" - "\tcandidateCerts: \t%s\n" - "\tcertSel: \t%s\n" - "\tverifyNode: \t%s\n" - "\tparentState: \t%s}\n"; - char *asciiStatus = NULL; - - PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_ToString"); - PKIX_NULLCHECK_TWO(object, pString); - - PKIX_CHECK(pkix_CheckType - (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext), - PKIX_OBJECTNOTFORWARDBUILDERSTATE); - - state = (PKIX_ForwardBuilderState *)object; - - PKIX_CHECK(PKIX_PL_String_Create - (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), - PKIX_STRINGCREATEFAILED); - - switch (state->status) { - case BUILD_SHORTCUTPENDING: asciiStatus = "BUILD_SHORTCUTPENDING"; - break; - case BUILD_INITIAL: asciiStatus = "BUILD_INITIAL"; - break; - case BUILD_TRYAIA: asciiStatus = "BUILD_TRYAIA"; - break; - case BUILD_AIAPENDING: asciiStatus = "BUILD_AIAPENDING"; - break; - case BUILD_COLLECTINGCERTS: asciiStatus = "BUILD_COLLECTINGCERTS"; - break; - case BUILD_GATHERPENDING: asciiStatus = "BUILD_GATHERPENDING"; - break; - case BUILD_CERTVALIDATING: asciiStatus = "BUILD_CERTVALIDATING"; - break; - case BUILD_ABANDONNODE: asciiStatus = "BUILD_ABANDONNODE"; - break; - case BUILD_CRLPREP: asciiStatus = "BUILD_CRLPREP"; - break; - case BUILD_CRL1: asciiStatus = "BUILD_CRL1"; - break; - case BUILD_DATEPREP: asciiStatus = "BUILD_DATEPREP"; - break; - case BUILD_CHECKTRUSTED: asciiStatus = "BUILD_CHECKTRUSTED"; - break; - case BUILD_CHECKTRUSTED2: asciiStatus = "BUILD_CHECKTRUSTED2"; - break; - case BUILD_ADDTOCHAIN: asciiStatus = "BUILD_ADDTOCHAIN"; - break; - case BUILD_CRL2: asciiStatus = "BUILD_CRL2"; - break; - case BUILD_VALCHAIN: asciiStatus = "BUILD_VALCHAIN"; - break; - case BUILD_VALCHAIN2: asciiStatus = "BUILD_VALCHAIN2"; - break; - case BUILD_EXTENDCHAIN: asciiStatus = "BUILD_EXTENDCHAIN"; - break; - case BUILD_GETNEXTCERT: asciiStatus = "BUILD_GETNEXTCERT"; - break; - default: asciiStatus = "INVALID STATUS"; - break; - } - - PKIX_CHECK(PKIX_PL_String_Create - (PKIX_ESCASCII, asciiStatus, 0, &buildStatusString, plContext), - PKIX_STRINGCREATEFAILED); - - PKIX_TOSTRING - (state->validityDate, &validityDateString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->prevCert, &prevCertString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->candidateCert, &candidateCertString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->traversedSubjNames, - &traversedSubjNamesString, - plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->trustChain, &trustChainString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->candidateCerts, &candidateCertsString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->certSel, &certSelString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->verifyNode, &verifyNodeString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_TOSTRING - (state->parentState, &parentStateString, plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_CHECK(PKIX_PL_Sprintf - (&resultString, - plContext, - formatString, - buildStatusString, - (PKIX_Int32)state->traversedCACerts, - (PKIX_UInt32)state->certStoreIndex, - (PKIX_UInt32)state->numCerts, - (PKIX_UInt32)state->numAias, - (PKIX_UInt32)state->certIndex, - (PKIX_UInt32)state->aiaIndex, - (PKIX_UInt32)state->numFanout, - (PKIX_UInt32)state->numDepth, - (PKIX_UInt32)state->reasonCode, - state->revCheckDelayed, - state->canBeCached, - state->useOnlyLocal, - state->revChecking, - validityDateString, - prevCertString, - candidateCertString, - traversedSubjNamesString, - trustChainString, - candidateCertsString, - certSelString, - verifyNodeString, - parentStateString), - PKIX_SPRINTFFAILED); - - *pString = resultString; - -cleanup: - PKIX_DECREF(formatString); - PKIX_DECREF(buildStatusString); - PKIX_DECREF(validityDateString); - PKIX_DECREF(prevCertString); - PKIX_DECREF(candidateCertString); - PKIX_DECREF(traversedSubjNamesString); - PKIX_DECREF(trustChainString); - PKIX_DECREF(candidateCertsString); - PKIX_DECREF(certSelString); - PKIX_DECREF(verifyNodeString); - PKIX_DECREF(parentStateString); - - PKIX_RETURN(FORWARDBUILDERSTATE); - -} - -/* - * FUNCTION: pkix_ForwardBuilderState_RegisterSelf - * - * DESCRIPTION: - * Registers PKIX_FORWARDBUILDERSTATE_TYPE and its related functions - * with systemClasses[] - * - * THREAD SAFETY: - * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) - * - * Since this function is only called by PKIX_PL_Initialize, which should - * only be called once, it is acceptable that this function is not - * thread-safe. - */ -PKIX_Error * -pkix_ForwardBuilderState_RegisterSelf(void *plContext) -{ - - extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; - pkix_ClassTable_Entry entry; - - PKIX_ENTER(FORWARDBUILDERSTATE, - "pkix_ForwardBuilderState_RegisterSelf"); - - entry.description = "ForwardBuilderState"; - entry.objCounter = 0; - entry.typeObjectSize = sizeof(PKIX_ForwardBuilderState); - entry.destructor = pkix_ForwardBuilderState_Destroy; - entry.equalsFunction = NULL; - entry.hashcodeFunction = NULL; - entry.toStringFunction = pkix_ForwardBuilderState_ToString; - entry.comparator = NULL; - entry.duplicateFunction = NULL; - - systemClasses[PKIX_FORWARDBUILDERSTATE_TYPE] = entry; - - PKIX_RETURN(FORWARDBUILDERSTATE); -} - -#if PKIX_FORWARDBUILDERSTATEDEBUG -/* - * FUNCTION: pkix_ForwardBuilderState_DumpState - * - * DESCRIPTION: - * This function invokes the ToString function on the argument pointed to - * by "state". - * PARAMETERS: - * "state" - * The address of the ForwardBuilderState object. Must be non-NULL. - * - * THREAD SAFETY: - * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) - */ -PKIX_Error * -pkix_ForwardBuilderState_DumpState( - PKIX_ForwardBuilderState *state, - void *plContext) -{ - PKIX_PL_String *stateString = NULL; - char *stateAscii = NULL; - PKIX_UInt32 length; - - PKIX_ENTER(FORWARDBUILDERSTATE,"pkix_ForwardBuilderState_DumpState"); - PKIX_NULLCHECK_ONE(state); - - PKIX_CHECK(PKIX_PL_Object_InvalidateCache - ((PKIX_PL_Object *)state, plContext), - PKIX_OBJECTINVALIDATECACHEFAILED); - - PKIX_CHECK(PKIX_PL_Object_ToString - ((PKIX_PL_Object*)state, &stateString, plContext), - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_CHECK(PKIX_PL_String_GetEncoded - (stateString, - PKIX_ESCASCII, - (void **)&stateAscii, - &length, - plContext), - PKIX_STRINGGETENCODEDFAILED); - - PKIX_DEBUG_ARG("In Phase 1: state = %s\n", stateAscii); - - PKIX_FREE(stateAscii); - PKIX_DECREF(stateString); - -cleanup: - PKIX_RETURN(FORWARDBUILDERSTATE); -} -#endif - -/* - * FUNCTION: pkix_ForwardBuilderState_IsIOPending - * DESCRIPTION: - * - * This function determines whether the state of the ForwardBuilderState - * pointed to by "state" indicates I/O is in progress, and stores the Boolean - * result at "pPending". - * - * PARAMETERS: - * "state" - * The address of the ForwardBuilderState object. Must be non-NULL. - * "pPending" - * The address at which the result 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 ForwardBuilderState 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_ForwardBuilderState_IsIOPending( - PKIX_ForwardBuilderState *state, - PKIX_Boolean *pPending, - void *plContext) -{ - PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_IsIOPending"); - PKIX_NULLCHECK_TWO(state, pPending); - - if ((state->status == BUILD_GATHERPENDING) || - (state->status == BUILD_CRL1) || - (state->status == BUILD_CRL2) || - (state->status == BUILD_CHECKTRUSTED2) || - (state->status == BUILD_VALCHAIN2) || - (state->status == BUILD_AIAPENDING)) { - *pPending = PKIX_TRUE; - } else { - *pPending = PKIX_FALSE; - } - - PKIX_RETURN(FORWARDBUILDERSTATE); -} - -/* --Private-BuildChain-Functions------------------------------------------- */ - -/* - * FUNCTION: pkix_Build_SortCertComparator - * DESCRIPTION: - * - * This Function takes two Certificates cast in "obj1" and "obj2", - * compares their validity NotAfter dates and returns the result at - * "pResult". The comparison key(s) can be expanded by using other - * data in the Certificate in the future. - * - * PARAMETERS: - * "obj1" - * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert. - * Must be non-NULL. - * "obj2" - * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert. - * Must be non-NULL. - * "pResult" - * Address where the comparison result is returned. 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 Build 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_Build_SortCertComparator( - PKIX_PL_Object *obj1, - PKIX_PL_Object *obj2, - PKIX_Int32 *pResult, - void *plContext) -{ - PKIX_PL_Date *date1 = NULL; - PKIX_PL_Date *date2 = NULL; - PKIX_Boolean result = PKIX_FALSE; - - PKIX_ENTER(BUILD, "pkix_Build_SortCertComparator"); - PKIX_NULLCHECK_THREE(obj1, obj2, pResult); - - /* - * For sorting candidate certificates, we use NotAfter date as the - * sorted key for now (can be expanded if desired in the future). - * - * In PKIX_BuildChain, the List of CertStores was reordered so that - * trusted CertStores are ahead of untrusted CertStores. That sort, or - * this one, could be taken out if it is determined that it doesn't help - * performance, or in some way hinders the solution of choosing desired - * candidates. - */ - - PKIX_CHECK(pkix_CheckType(obj1, PKIX_CERT_TYPE, plContext), - PKIX_OBJECTNOTCERT); - PKIX_CHECK(pkix_CheckType(obj2, PKIX_CERT_TYPE, plContext), - PKIX_OBJECTNOTCERT); - - PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter - ((PKIX_PL_Cert *)obj1, &date1, plContext), - PKIX_CERTGETVALIDITYNOTAFTERFAILED); - - PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter - ((PKIX_PL_Cert *)obj2, &date2, plContext), - PKIX_CERTGETVALIDITYNOTAFTERFAILED); - - PKIX_CHECK(PKIX_PL_Object_Compare - ((PKIX_PL_Object *)date1, - (PKIX_PL_Object *)date2, - &result, - plContext), - PKIX_OBJECTCOMPARATORFAILED); - - *pResult = !result; - -cleanup: - - PKIX_DECREF(date1); - PKIX_DECREF(date2); - - PKIX_RETURN(BUILD); -} - -/* This local error check macro */ -#define ERROR_CHECK(errCode) \ - if (pkixErrorResult) { \ - if (pkixLog) { \ - PR_LOG(pkixLog, PR_LOG_DEBUG, ("====> ERROR_CHECK code %s\n", #errCode)); \ - } \ - pkixTempErrorReceived = PKIX_TRUE; \ - pkixErrorClass = pkixErrorResult->errClass; \ - if (pkixErrorClass == PKIX_FATAL_ERROR) { \ - goto cleanup; \ - } \ - if (verifyNode) { \ - PKIX_DECREF(verifyNode->error); \ - PKIX_INCREF(pkixErrorResult); \ - verifyNode->error = pkixErrorResult; \ - } \ - pkixErrorCode = errCode; \ - goto cleanup; \ - } - -/* - * FUNCTION: pkix_Build_VerifyCertificate - * DESCRIPTION: - * - * Checks whether the previous Cert stored in the ForwardBuilderState pointed - * to by "state" successfully chains, including signature verification, to the - * candidate Cert also stored in "state", using the Boolean value in "trusted" - * to determine whether "candidateCert" is trusted. Using the Boolean value in - * "revocationChecking" for the existence of revocation checking, it sets - * "pNeedsCRLChecking" to PKIX_TRUE if the candidate Cert needs to be checked - * against Certificate Revocation Lists. - * - * First it checks whether "candidateCert" has already been traversed by - * determining whether it is contained in the List of traversed Certs. It - * checks the candidate Cert with user checkers, if any, in the List pointed to - * by "userCheckers". It then runs the signature validation. Finally, it - * determines the appropriate value for "pNeedsCRLChecking". - * - * If this Certificate fails verification, and state->verifyNode is non-NULL, - * this function sets the Error code into the verifyNode. - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. Must be non-NULL. - * "userCheckers" - * Address of a List of CertChainCheckers to be used, if present, to - * validate the candidateCert. - * "revocationChecking" - * Boolean indication of whether revocation checking is available, either - * as a CertChainChecker or a List of RevocationCheckers. - * "trusted" - * Boolean value of trust for the candidate Cert - * "pNeedsCRLChecking" - * Address where Boolean CRL-checking-needed value 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 Build 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_Build_VerifyCertificate( - PKIX_ForwardBuilderState *state, - PKIX_List *userCheckers, - PKIX_Boolean revocationChecking, - PKIX_Boolean *pTrusted, - PKIX_Boolean *pNeedsCRLChecking, - PKIX_VerifyNode *verifyNode, - void *plContext) -{ - PKIX_UInt32 numUserCheckers = 0; - PKIX_UInt32 i = 0; - PKIX_Boolean loopFound = PKIX_FALSE; - PKIX_Boolean supportForwardChecking = PKIX_FALSE; - PKIX_Boolean trusted = PKIX_FALSE; - PKIX_PL_Cert *candidateCert = NULL; - PKIX_PL_PublicKey *candidatePubKey = NULL; - PKIX_CertChainChecker *userChecker = NULL; - PKIX_CertChainChecker_CheckCallback checkerCheck = NULL; - PKIX_Boolean trustOnlyUserAnchors = PKIX_FALSE; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate"); - PKIX_NULLCHECK_THREE(state, pTrusted, pNeedsCRLChecking); - PKIX_NULLCHECK_THREE - (state->candidateCerts, state->prevCert, state->trustChain); - - *pNeedsCRLChecking = PKIX_FALSE; - - PKIX_INCREF(state->candidateCert); - candidateCert = state->candidateCert; - - if (state->buildConstants.numAnchors) { - trustOnlyUserAnchors = state->buildConstants.trustOnlyUserAnchors; - } - - PKIX_CHECK( - PKIX_PL_Cert_IsCertTrusted(candidateCert, - trustOnlyUserAnchors, - &trusted, plContext), - PKIX_CERTISCERTTRUSTEDFAILED); - - *pTrusted = trusted; - - /* check for loops */ - PKIX_CHECK(pkix_List_Contains - (state->trustChain, - (PKIX_PL_Object *)candidateCert, - &loopFound, - plContext), - PKIX_LISTCONTAINSFAILED); - - if (loopFound) { - if (verifyNode != NULL) { - PKIX_Error *verifyError = NULL; - PKIX_ERROR_CREATE - (BUILD, - PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED, - verifyError); - PKIX_DECREF(verifyNode->error); - verifyNode->error = verifyError; - } - /* Even if error logged, still need to abort - * if cert is not trusted. */ - if (!trusted) { - PKIX_ERROR(PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED); - } - state->certLoopingDetected = PKIX_TRUE; - } - - if (userCheckers != NULL) { - - 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, &supportForwardChecking, plContext), - PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED); - - if (supportForwardChecking == PKIX_TRUE) { - - PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback - (userChecker, &checkerCheck, plContext), - PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED); - - pkixErrorResult = - checkerCheck(userChecker, candidateCert, NULL, - &nbioContext, plContext); - - ERROR_CHECK(PKIX_USERCHECKERCHECKFAILED); - } - - PKIX_DECREF(userChecker); - } - } - - /* Check that public key of the trusted dsa cert has - * dsa parameters */ - if (trusted) { - PKIX_Boolean paramsNeeded = PKIX_FALSE; - PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey - (candidateCert, &candidatePubKey, plContext), - PKIX_CERTGETSUBJECTPUBLICKEYFAILED); - PKIX_CHECK(PKIX_PL_PublicKey_NeedsDSAParameters - (candidatePubKey, ¶msNeeded, plContext), - PKIX_PUBLICKEYNEEDSDSAPARAMETERSFAILED); - if (paramsNeeded) { - PKIX_ERROR(PKIX_MISSINGDSAPARAMETERS); - } - } - - - if (revocationChecking) { - if (!trusted) { - if (state->revCheckDelayed) { - goto cleanup; - } else { - PKIX_Boolean isSelfIssued = PKIX_FALSE; - PKIX_CHECK( - pkix_IsCertSelfIssued(candidateCert, &isSelfIssued, - plContext), - PKIX_ISCERTSELFISSUEDFAILED); - if (isSelfIssued) { - state->revCheckDelayed = PKIX_TRUE; - goto cleanup; - } - } - } - *pNeedsCRLChecking = PKIX_TRUE; - } - -cleanup: - PKIX_DECREF(candidateCert); - PKIX_DECREF(candidatePubKey); - PKIX_DECREF(userChecker); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_ValidationCheckers - * DESCRIPTION: - * - * Creates a List of Objects to be used in determining whether the List of - * Certs pointed to by "certChain" successfully validates using the - * ForwardBuilderState pointed to by "state", and the TrustAnchor pointed to by - * "anchor". These objects are a reversed Cert Chain, consisting of the certs - * in "certChain" in reversed order, suitable for presenting to the - * CertChainCheckers; a List of critical extension OIDS that have already been - * processed in forward building; a List of CertChainCheckers to be called, and - * a List of RevocationCheckers to be called. These results are stored in - * fields of "state". - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. Must be non-NULL. - * "certChain" - * Address of List of Certs to be validated. Must be non-NULL. - * "anchor" - * Address of TrustAnchor to be used. Must be non-NULL. - * "addEkuChecker" - * Boolean flags that tells to add eku checker to the list - * of checkers. Only needs to be done for existing chain revalidation. - * "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 Build 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_Build_ValidationCheckers( - PKIX_ForwardBuilderState *state, - PKIX_List *certChain, - PKIX_TrustAnchor *anchor, - PKIX_Boolean chainRevalidationStage, - void *plContext) -{ - PKIX_List *checkers = NULL; - PKIX_List *initialPolicies = NULL; - PKIX_List *reversedCertChain = NULL; - PKIX_List *buildCheckedCritExtOIDsList = NULL; - PKIX_ProcessingParams *procParams = NULL; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_PL_PublicKey *trustedPubKey = NULL; - PKIX_CertChainChecker *sigChecker = NULL; - PKIX_CertChainChecker *policyChecker = NULL; - PKIX_CertChainChecker *userChecker = NULL; - PKIX_CertChainChecker *checker = NULL; - PKIX_CertSelector *certSelector = NULL; - PKIX_List *userCheckerExtOIDs = NULL; - PKIX_PL_OID *oid = NULL; - PKIX_Boolean supportForwardChecking = PKIX_FALSE; - PKIX_Boolean policyQualifiersRejected = PKIX_FALSE; - PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; - PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; - PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; - PKIX_UInt32 numChainCerts; - PKIX_UInt32 numCertCheckers; - PKIX_UInt32 i; - - PKIX_ENTER(BUILD, "pkix_Build_ValidationCheckers"); - PKIX_NULLCHECK_THREE(state, certChain, anchor); - - PKIX_CHECK(PKIX_List_Create(&checkers, plContext), - PKIX_LISTCREATEFAILED); - - PKIX_CHECK(PKIX_List_ReverseList - (certChain, &reversedCertChain, plContext), - PKIX_LISTREVERSELISTFAILED); - - PKIX_CHECK(PKIX_List_GetLength - (reversedCertChain, &numChainCerts, plContext), - PKIX_LISTGETLENGTHFAILED); - - procParams = state->buildConstants.procParams; - - /* Do need to add a number of checker to revalidate - * a built chain. KU, EKU, CertType and Validity Date - * get checked by certificate selector during chain - * construction, but needed to be checked for chain from - * the cache.*/ - if (chainRevalidationStage) { - PKIX_CHECK(pkix_ExpirationChecker_Initialize - (state->buildConstants.testDate, &checker, plContext), - PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); - PKIX_CHECK(PKIX_List_AppendItem - (checkers, (PKIX_PL_Object *)checker, plContext), - PKIX_LISTAPPENDITEMFAILED); - PKIX_DECREF(checker); - - PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints - (procParams, &certSelector, plContext), - PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); - - PKIX_CHECK(pkix_TargetCertChecker_Initialize - (certSelector, numChainCerts, &checker, plContext), - PKIX_EXPIRATIONCHECKERINITIALIZEFAILED); - PKIX_CHECK(PKIX_List_AppendItem - (checkers, (PKIX_PL_Object *)checker, plContext), - PKIX_LISTAPPENDITEMFAILED); - PKIX_DECREF(checker); - } - - 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_PolicyChecker_Initialize - (initialPolicies, - policyQualifiersRejected, - initialPolicyMappingInhibit, - initialExplicitPolicy, - initialAnyPolicyInhibit, - numChainCerts, - &policyChecker, - plContext), - PKIX_POLICYCHECKERINITIALIZEFAILED); - - PKIX_CHECK(PKIX_List_AppendItem - (checkers, (PKIX_PL_Object *)policyChecker, plContext), - PKIX_LISTAPPENDITEMFAILED); - - /* - * Create an OID list that contains critical extensions processed - * by BuildChain. These are specified in a static const array. - */ - PKIX_CHECK(PKIX_List_Create(&buildCheckedCritExtOIDsList, plContext), - PKIX_LISTCREATEFAILED); - - for (i = 0; buildCheckedCritExtOIDs[i] != PKIX_UNKNOWN_OID; i++) { - PKIX_CHECK(PKIX_PL_OID_Create - (buildCheckedCritExtOIDs[i], &oid, plContext), - PKIX_OIDCREATEFAILED); - - PKIX_CHECK(PKIX_List_AppendItem - (buildCheckedCritExtOIDsList, - (PKIX_PL_Object *) oid, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - PKIX_DECREF(oid); - } - - if (state->buildConstants.userCheckers != NULL) { - - PKIX_CHECK(PKIX_List_GetLength - (state->buildConstants.userCheckers, - &numCertCheckers, - plContext), - PKIX_LISTGETLENGTHFAILED); - - for (i = 0; i < numCertCheckers; i++) { - - PKIX_CHECK(PKIX_List_GetItem - (state->buildConstants.userCheckers, - i, - (PKIX_PL_Object **) &userChecker, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK - (PKIX_CertChainChecker_IsForwardCheckingSupported - (userChecker, &supportForwardChecking, plContext), - PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); - - /* - * If this userChecker supports forwardChecking then it - * should have been checked during build chain. Skip - * checking but need to add checker's extension OIDs - * to buildCheckedCritExtOIDsList. - */ - if (supportForwardChecking == PKIX_TRUE) { - - PKIX_CHECK - (PKIX_CertChainChecker_GetSupportedExtensions - (userChecker, &userCheckerExtOIDs, plContext), - PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED); - - if (userCheckerExtOIDs != NULL) { - PKIX_CHECK(pkix_List_AppendList - (buildCheckedCritExtOIDsList, - userCheckerExtOIDs, - plContext), - PKIX_LISTAPPENDLISTFAILED); - } - - } else { - PKIX_CHECK(PKIX_List_AppendItem - (checkers, - (PKIX_PL_Object *)userChecker, - plContext), - PKIX_LISTAPPENDITEMFAILED); - } - - PKIX_DECREF(userCheckerExtOIDs); - PKIX_DECREF(userChecker); - } - } - - /* Inabling post chain building signature check on the certs. */ - PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert - (anchor, &trustedCert, plContext), - PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - - PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey - (trustedCert, &trustedPubKey, plContext), - PKIX_CERTGETSUBJECTPUBLICKEYFAILED); - - PKIX_CHECK(pkix_SignatureChecker_Initialize - (trustedPubKey, - numChainCerts, - &sigChecker, - plContext), - PKIX_SIGNATURECHECKERINITIALIZEFAILED); - - PKIX_CHECK(PKIX_List_AppendItem - (checkers, - (PKIX_PL_Object *)sigChecker, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - PKIX_DECREF(state->reversedCertChain); - PKIX_INCREF(reversedCertChain); - state->reversedCertChain = reversedCertChain; - PKIX_DECREF(state->checkedCritExtOIDs); - PKIX_INCREF(buildCheckedCritExtOIDsList); - state->checkedCritExtOIDs = buildCheckedCritExtOIDsList; - PKIX_DECREF(state->checkerChain); - state->checkerChain = checkers; - checkers = NULL; - state->certCheckedIndex = 0; - state->checkerIndex = 0; - state->revChecking = PKIX_FALSE; - - -cleanup: - - PKIX_DECREF(oid); - PKIX_DECREF(reversedCertChain); - PKIX_DECREF(buildCheckedCritExtOIDsList); - PKIX_DECREF(checker); - PKIX_DECREF(checkers); - PKIX_DECREF(initialPolicies); - PKIX_DECREF(trustedCert); - PKIX_DECREF(trustedPubKey); - PKIX_DECREF(certSelector); - PKIX_DECREF(sigChecker); - PKIX_DECREF(policyChecker); - PKIX_DECREF(userChecker); - PKIX_DECREF(userCheckerExtOIDs); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_ValidateEntireChain - * DESCRIPTION: - * - * Checks whether the current List of Certs successfully validates using the - * TrustAnchor pointed to by "anchor" and other parameters contained, as was - * the Cert List, in "state". - * - * If a checker using non-blocking I/O returns with a non-NULL non-blocking I/O - * context (NBIOContext), an indication that I/O is in progress and the - * checking has not been completed, this function stores that context at - * "pNBIOContext". Otherwise, it stores NULL at "pNBIOContext". - * - * If not awaiting I/O and if successful, a ValidateResult is created - * containing the Public Key of the target certificate (including DSA parameter - * inheritance, if any) and the PolicyNode representing the policy tree output - * by the validation algorithm. If not successful, an Error pointer is - * returned. - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. Must be non-NULL. - * "anchor" - * Address of TrustAnchor to be used. Must be non-NULL. - * "pNBIOContext" - * Address at which the NBIOContext is stored indicating whether the - * validation is complete. Must be non-NULL. - * "pValResult" - * Address at which the ValidateResult 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 Build 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_Build_ValidateEntireChain( - PKIX_ForwardBuilderState *state, - PKIX_TrustAnchor *anchor, - void **pNBIOContext, - PKIX_ValidateResult **pValResult, - PKIX_VerifyNode *verifyNode, - void *plContext) -{ - PKIX_UInt32 numChainCerts = 0; - PKIX_PL_PublicKey *subjPubKey = NULL; - PKIX_PolicyNode *policyTree = NULL; - PKIX_ValidateResult *valResult = NULL; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_ValidateEntireChain"); - PKIX_NULLCHECK_FOUR(state, anchor, pNBIOContext, pValResult); - - *pNBIOContext = NULL; /* prepare for case of error exit */ - - PKIX_CHECK(PKIX_List_GetLength - (state->reversedCertChain, &numChainCerts, plContext), - PKIX_LISTGETLENGTHFAILED); - - pkixErrorResult = - pkix_CheckChain(state->reversedCertChain, numChainCerts, anchor, - state->checkerChain, - state->buildConstants.revChecker, - state->checkedCritExtOIDs, - state->buildConstants.procParams, - &state->certCheckedIndex, &state->checkerIndex, - &state->revChecking, &state->reasonCode, - &nbioContext, &subjPubKey, &policyTree, NULL, - plContext); - - if (nbioContext != NULL) { - *pNBIOContext = nbioContext; - goto cleanup; - } - - ERROR_CHECK(PKIX_CHECKCHAINFAILED); - - if (state->reasonCode != 0) { - PKIX_ERROR(PKIX_CHAINREJECTEDBYREVOCATIONCHECKER); - } - - PKIX_CHECK(pkix_ValidateResult_Create - (subjPubKey, anchor, policyTree, &valResult, plContext), - PKIX_VALIDATERESULTCREATEFAILED); - - *pValResult = valResult; - valResult = NULL; - -cleanup: - PKIX_DECREF(subjPubKey); - PKIX_DECREF(policyTree); - PKIX_DECREF(valResult); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_SortCandidateCerts - * DESCRIPTION: - * - * This function sorts a List of candidate Certs pointed to by "candidates" - * using an algorithm that places Certs most likely to produce a successful - * chain at the front of the list, storing the resulting sorted List at - * "pSortedCandidates". - * - * At present the only sort criterion is that trusted Certs go ahead of - * untrusted Certs. - * - * PARAMETERS: - * "candidates" - * Address of List of Candidate Certs to be sorted. Must be non-NULL. - * "pSortedCandidates" - * Address at which sorted 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 Build 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_Build_SortCandidateCerts( - PKIX_List *candidates, - PKIX_List **pSortedCandidates, - void *plContext) -{ - PKIX_List *sortedList = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_SortCandidateCerts"); - PKIX_NULLCHECK_TWO(candidates, pSortedCandidates); - - /* - * Both bubble and quick sort algorithms are available. - * For a list of fewer than around 100 items, the bubble sort is more - * efficient. (This number was determined by experimenting with both - * algorithms on a Java List.) - * If the candidate list is very small, using the sort can drag down - * the performance a little bit. - */ - - PKIX_CHECK(pkix_List_BubbleSort - (candidates, - pkix_Build_SortCertComparator, - &sortedList, - plContext), - PKIX_LISTBUBBLESORTFAILED); - - *pSortedCandidates = sortedList; - -cleanup: - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_BuildSelectorAndParams - * DESCRIPTION: - * - * This function creates a CertSelector, initialized with an appropriate - * ComCertSelParams, using the variables provided in the ForwardBuilderState - * pointed to by "state". The CertSelector created is stored in the certsel - * element of "state". - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. 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 Build 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_Build_BuildSelectorAndParams( - PKIX_ForwardBuilderState *state, - void *plContext) -{ - PKIX_ComCertSelParams *certSelParams = NULL; - PKIX_CertSelector *certSel = NULL; - PKIX_PL_X500Name *currentIssuer = NULL; - PKIX_PL_ByteArray *authKeyId = NULL; - PKIX_PL_Date *testDate = NULL; - PKIX_CertSelector *callerCertSelector = NULL; - PKIX_ComCertSelParams *callerComCertSelParams = NULL; - PKIX_UInt32 reqKu = 0; - PKIX_List *reqEkuOids = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_BuildSelectorAndParams"); - PKIX_NULLCHECK_THREE(state, state->prevCert, state->traversedSubjNames); - - PKIX_CHECK(PKIX_PL_Cert_GetIssuer - (state->prevCert, ¤tIssuer, plContext), - PKIX_CERTGETISSUERFAILED); - - PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier - (state->prevCert, &authKeyId, plContext), - PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_Create(&certSelParams, plContext), - PKIX_COMCERTSELPARAMSCREATEFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_SetSubject - (certSelParams, currentIssuer, plContext), - PKIX_COMCERTSELPARAMSSETSUBJECTFAILED); - - if (authKeyId != NULL) { - PKIX_CHECK(PKIX_ComCertSelParams_SetSubjKeyIdentifier - (certSelParams, authKeyId, plContext), - PKIX_COMCERTSELPARAMSSETSUBJKEYIDENTIFIERFAILED); - } - - PKIX_INCREF(state->buildConstants.testDate); - testDate = state->buildConstants.testDate; - - PKIX_CHECK(PKIX_ComCertSelParams_SetCertificateValid - (certSelParams, testDate, plContext), - PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_SetBasicConstraints - (certSelParams, state->traversedCACerts, plContext), - PKIX_COMCERTSELPARAMSSETBASICCONSTRAINTSFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_SetPathToNames - (certSelParams, state->traversedSubjNames, plContext), - PKIX_COMCERTSELPARAMSSETPATHTONAMESFAILED); - - PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints - (state->buildConstants.procParams, - &callerCertSelector, plContext), - PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); - - if (callerCertSelector != NULL) { - - /* Get initial EKU OIDs from ComCertSelParams, if set */ - PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams - (callerCertSelector, &callerComCertSelParams, plContext), - PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); - - if (callerComCertSelParams != NULL) { - PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage - (callerComCertSelParams, &reqEkuOids, plContext), - PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage - (callerComCertSelParams, &reqKu, plContext), - PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); - } - } - - PKIX_CHECK( - PKIX_ComCertSelParams_SetKeyUsage(certSelParams, reqKu, - plContext), - PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED); - - PKIX_CHECK( - PKIX_ComCertSelParams_SetExtendedKeyUsage(certSelParams, - reqEkuOids, - plContext), - PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED); - - PKIX_CHECK(PKIX_CertSelector_Create - (NULL, NULL, &state->certSel, plContext), - PKIX_CERTSELECTORCREATEFAILED); - - PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams - (state->certSel, certSelParams, plContext), - PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED); - - PKIX_CHECK(PKIX_List_Create(&state->candidateCerts, plContext), - PKIX_LISTCREATEFAILED); - - state->certStoreIndex = 0; - -cleanup: - PKIX_DECREF(certSelParams); - PKIX_DECREF(certSel); - PKIX_DECREF(currentIssuer); - PKIX_DECREF(authKeyId); - PKIX_DECREF(testDate); - PKIX_DECREF(reqEkuOids); - PKIX_DECREF(callerComCertSelParams); - PKIX_DECREF(callerCertSelector); - - PKIX_RETURN(BUILD); -} - -/* Match trust anchor to select params in order to find next cert. */ -static PKIX_Error* -pkix_Build_SelectCertsFromTrustAnchors( - PKIX_List *trustAnchorsList, - PKIX_ComCertSelParams *certSelParams, - PKIX_List **pMatchList, - void *plContext) -{ - int anchorIndex = 0; - PKIX_TrustAnchor *anchor = NULL; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_List *matchList = NULL; - PKIX_CertSelector *certSel = NULL; - PKIX_CertSelector_MatchCallback selectorMatchCB = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_SelectCertsFromTrustAnchors"); - - PKIX_CHECK(PKIX_CertSelector_Create - (NULL, NULL, &certSel, plContext), - PKIX_CERTSELECTORCREATEFAILED); - PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams - (certSel, certSelParams, plContext), - PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED); - PKIX_CHECK(PKIX_CertSelector_GetMatchCallback - (certSel, &selectorMatchCB, plContext), - PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); - - for (anchorIndex = 0;anchorIndex < trustAnchorsList->length; anchorIndex++) { - PKIX_CHECK( - PKIX_List_GetItem(trustAnchorsList, - anchorIndex, - (PKIX_PL_Object **)&anchor, - plContext), - PKIX_LISTGETITEMFAILED); - PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert - (anchor, &trustedCert, plContext), - PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - pkixErrorResult = - (*selectorMatchCB)(certSel, trustedCert, plContext); - if (!pkixErrorResult) { - if (!matchList) { - PKIX_CHECK(PKIX_List_Create(&matchList, - plContext), - PKIX_LISTCREATEFAILED); - } - PKIX_CHECK( - PKIX_List_AppendItem(matchList, - (PKIX_PL_Object*)trustedCert, - plContext), - PKIX_LISTAPPENDITEMFAILED); - } else { - PKIX_DECREF(pkixErrorResult); - } - PKIX_DECREF(trustedCert); - PKIX_DECREF(anchor); - } - - *pMatchList = matchList; - matchList = NULL; - -cleanup: - PKIX_DECREF(matchList); - PKIX_DECREF(trustedCert); - PKIX_DECREF(anchor); - PKIX_DECREF(certSel); - - PKIX_RETURN(BUILD); -} - - -static PKIX_Error* -pkix_Build_RemoveDupUntrustedCerts( - PKIX_List *trustedCertList, - PKIX_List *certsFound, - void *plContext) -{ - PKIX_UInt32 trustIndex; - PKIX_PL_Cert *trustCert = NULL, *cert = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_RemoveDupUntrustedCerts"); - if (trustedCertList == NULL || certsFound == NULL) { - goto cleanup; - } - for (trustIndex = 0;trustIndex < trustedCertList->length; - trustIndex++) { - PKIX_UInt32 certIndex = 0; - PKIX_CHECK( - PKIX_List_GetItem(trustedCertList, - trustIndex, - (PKIX_PL_Object **)&trustCert, - plContext), - PKIX_LISTGETITEMFAILED); - - while (certIndex < certsFound->length) { - PKIX_Boolean result = PKIX_FALSE; - PKIX_DECREF(cert); - PKIX_CHECK( - PKIX_List_GetItem(certsFound, certIndex, - (PKIX_PL_Object **)&cert, - plContext), - PKIX_LISTGETITEMFAILED); - PKIX_CHECK( - PKIX_PL_Object_Equals((PKIX_PL_Object *)trustCert, - (PKIX_PL_Object *)cert, - &result, - plContext), - PKIX_OBJECTEQUALSFAILED); - if (!result) { - certIndex += 1; - continue; - } - PKIX_CHECK( - PKIX_List_DeleteItem(certsFound, certIndex, - plContext), - PKIX_LISTDELETEITEMFAILED); - } - PKIX_DECREF(trustCert); - } -cleanup: - PKIX_DECREF(cert); - PKIX_DECREF(trustCert); - - PKIX_RETURN(BUILD); -} - - -/* - * FUNCTION: pkix_Build_GatherCerts - * DESCRIPTION: - * - * This function traverses the CertStores in the List of CertStores contained - * in "state", using the certSelector and other parameters contained in - * "state", to obtain a List of all available Certs that satisfy the criteria. - * If a CertStore has a cache, "certSelParams" is used both to query the cache - * and, if an actual CertStore search occurred, to update the cache. (Behavior - * is undefined if "certSelParams" is different from the parameters that were - * used to initialize the certSelector in "state".) - * - * If a CertStore using non-blocking I/O returns with an indication that I/O is - * in progress and the checking has not been completed, this function stores - * platform-dependent information at "pNBIOContext". Otherwise it stores NULL - * at "pNBIOContext", and state is updated with the results of the search. - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. Must be non-NULL. - * "certSelParams" - * Address of ComCertSelParams which were used in creating the current - * CertSelector, and to be used in querying and updating any caches that - * may be associated with with the CertStores. - * "pNBIOContext" - * Address at which platform-dependent information is returned if request - * is suspended for non-blocking I/O. 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 Build Error if the function fails in a non-fatal way - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -/* return NULL if wouldblock, empty list if none found, else list of found */ -static PKIX_Error * -pkix_Build_GatherCerts( - PKIX_ForwardBuilderState *state, - PKIX_ComCertSelParams *certSelParams, - void **pNBIOContext, - void *plContext) -{ - PKIX_Boolean certStoreIsCached = PKIX_FALSE; - PKIX_Boolean certStoreIsLocal = PKIX_FALSE; - PKIX_Boolean foundInCache = PKIX_FALSE; - PKIX_CertStore *certStore = NULL; - PKIX_CertStore_CertCallback getCerts = NULL; - PKIX_List *certsFound = NULL; - PKIX_List *trustedCertList = NULL; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_GatherCerts"); - PKIX_NULLCHECK_THREE(state, certSelParams, pNBIOContext); - - nbioContext = *pNBIOContext; - *pNBIOContext = NULL; - - PKIX_DECREF(state->candidateCerts); - - while (state->certStoreIndex < state->buildConstants.numCertStores) { - - /* Get the current CertStore */ - PKIX_CHECK(PKIX_List_GetItem - (state->buildConstants.certStores, - state->certStoreIndex, - (PKIX_PL_Object **)&certStore, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK(PKIX_CertStore_GetLocalFlag - (certStore, &certStoreIsLocal, plContext), - PKIX_CERTSTOREGETLOCALFLAGFAILED); - - if (state->useOnlyLocal == certStoreIsLocal) { - /* If GATHERPENDING, we've already checked the cache */ - if (state->status == BUILD_GATHERPENDING) { - certStoreIsCached = PKIX_FALSE; - foundInCache = PKIX_FALSE; - } else { - PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag - (certStore, &certStoreIsCached, plContext), - PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); - - if (certStoreIsCached) { - /* - * Look for Certs in the cache, using the SubjectName as - * the key. Then the ComCertSelParams are used to filter - * for qualified certs. If none are found, then the - * certStores are queried. When we eventually add items - * to the cache, we will only add items that passed the - * ComCertSelParams filter, rather than all Certs which - * matched the SubjectName. - */ - - PKIX_CHECK(pkix_CacheCert_Lookup - (certStore, - certSelParams, - state->buildConstants.testDate, - &foundInCache, - &certsFound, - plContext), - PKIX_CACHECERTCHAINLOOKUPFAILED); - - } - } - - /* - * XXX need to verify if Cert is trusted, hence may not - * be worth it to have the Cert Cached or - * If it is trusted, don't cache, but once there is cached - * certs, we won't get certs from database any more. - * can use flag to force not getting certs from cache - */ - if (!foundInCache) { - - if (nbioContext == NULL) { - PKIX_CHECK(PKIX_CertStore_GetCertCallback - (certStore, &getCerts, plContext), - PKIX_CERTSTOREGETCERTCALLBACKFAILED); - - PKIX_CHECK(getCerts - (certStore, - state->certSel, - state->verifyNode, - &nbioContext, - &certsFound, - plContext), - PKIX_GETCERTSFAILED); - } else { - PKIX_CHECK(PKIX_CertStore_CertContinue - (certStore, - state->certSel, - state->verifyNode, - &nbioContext, - &certsFound, - plContext), - PKIX_CERTSTORECERTCONTINUEFAILED); - } - - if (certStoreIsCached && certsFound) { - - PKIX_CHECK(pkix_CacheCert_Add - (certStore, - certSelParams, - certsFound, - plContext), - PKIX_CACHECERTADDFAILED); - } - } - - /* - * getCerts returns an empty list for "NONE FOUND", - * a NULL list for "would block" - */ - if (certsFound == NULL) { - state->status = BUILD_GATHERPENDING; - *pNBIOContext = nbioContext; - goto cleanup; - } - } - - /* Are there any more certStores to query? */ - PKIX_DECREF(certStore); - ++(state->certStoreIndex); - } - - if (certsFound && certsFound->length > 1) { - PKIX_List *sorted = NULL; - - /* sort Certs to try to optimize search */ - PKIX_CHECK(pkix_Build_SortCandidateCerts - (certsFound, &sorted, plContext), - PKIX_BUILDSORTCANDIDATECERTSFAILED); - PKIX_DECREF(certsFound); - certsFound = sorted; - } - - PKIX_CHECK( - pkix_Build_SelectCertsFromTrustAnchors( - state->buildConstants.anchors, - certSelParams, &trustedCertList, - plContext), - PKIX_FAILTOSELECTCERTSFROMANCHORS); - PKIX_CHECK( - pkix_Build_RemoveDupUntrustedCerts(trustedCertList, - certsFound, - plContext), - PKIX_REMOVEDUPUNTRUSTEDCERTSFAILED); - - PKIX_CHECK( - pkix_List_MergeLists(trustedCertList, - certsFound, - &state->candidateCerts, - plContext), - PKIX_LISTMERGEFAILED); - - /* No, return the list we have gathered */ - PKIX_CHECK(PKIX_List_GetLength - (state->candidateCerts, &state->numCerts, plContext), - PKIX_LISTGETLENGTHFAILED); - - state->certIndex = 0; - -cleanup: - PKIX_DECREF(trustedCertList); - PKIX_DECREF(certStore); - PKIX_DECREF(certsFound); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_UpdateDate - * DESCRIPTION: - * - * This function updates the validityDate contained in "state", for the current - * CertChain contained in "state", to include the validityDate of the - * candidateCert contained in "state". The validityDate of a chain is the - * earliest of all the notAfter dates contained in the respective Certificates. - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. 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 Build 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_Build_UpdateDate( - PKIX_ForwardBuilderState *state, - void *plContext) -{ - PKIX_Boolean canBeCached = PKIX_FALSE; - PKIX_Int32 comparison = 0; - PKIX_PL_Date *notAfter = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_UpdateDate"); - PKIX_NULLCHECK_ONE(state); - - PKIX_CHECK(PKIX_PL_Cert_GetCacheFlag - (state->candidateCert, &canBeCached, plContext), - PKIX_CERTGETCACHEFLAGFAILED); - - state->canBeCached = state->canBeCached && canBeCached; - if (state->canBeCached == PKIX_TRUE) { - - /* - * So far, all certs can be cached. Update cert - * chain validity time, which is the earliest of - * all certs' notAfter times. - */ - PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter - (state->candidateCert, ¬After, plContext), - PKIX_CERTGETVALIDITYNOTAFTERFAILED); - - if (state->validityDate == NULL) { - state->validityDate = notAfter; - notAfter = NULL; - } else { - PKIX_CHECK(PKIX_PL_Object_Compare - ((PKIX_PL_Object *)state->validityDate, - (PKIX_PL_Object *)notAfter, - &comparison, - plContext), - PKIX_OBJECTCOMPARATORFAILED); - if (comparison > 0) { - PKIX_DECREF(state->validityDate); - state->validityDate = notAfter; - notAfter = NULL; - } - } - } - -cleanup: - - PKIX_DECREF(notAfter); - - PKIX_RETURN(BUILD); -} - -/* Prepare 'state' for the AIA round. */ -static void -pkix_PrepareForwardBuilderStateForAIA( - PKIX_ForwardBuilderState *state) -{ - PORT_Assert(state->useOnlyLocal == PKIX_TRUE); - state->useOnlyLocal = PKIX_FALSE; - state->certStoreIndex = 0; - state->numFanout = state->buildConstants.maxFanout; - state->status = BUILD_TRYAIA; -} - -/* - * FUNCTION: pkix_BuildForwardDepthFirstSearch - * DESCRIPTION: - * - * This function performs a depth first search in the "forward" direction (from - * the target Cert to the trust anchor). A non-NULL targetCert must be stored - * in the ForwardBuilderState before this function is called. It is not written - * recursively since execution may be suspended in in any of several places - * pending completion of non-blocking I/O. This iterative structure makes it - * much easier to resume where it left off. - * - * Since the nature of the search is recursive, the recursion is handled by - * chaining states. That is, each new step involves creating a new - * ForwardBuilderState linked to its predecessor. If a step turns out to be - * fruitless, the state of the predecessor is restored and the next alternative - * is tried. When a search is successful, values needed from the last state - * (canBeCached and validityDate) are copied to the state provided by the - * caller, so that the caller can retrieve those values. - * - * There are three return arguments, the NBIOContext, the ValidateResult and - * the ForwardBuilderState. If NBIOContext is non-NULL, it means the search is - * suspended until the results of a non-blocking IO become available. The - * caller may wait for the completion using platform-dependent methods and then - * call this function again, allowing it to resume the search. If NBIOContext - * is NULL and the ValidateResult is non-NULL, it means the search has - * concluded successfully. If the NBIOContext is NULL but the ValidateResult is - * NULL, it means the search was unsuccessful. - * - * This function performs several steps at each node in the constructed chain: - * - * 1) It retrieves Certs from the registered CertStores that match the - * criteria established by the ForwardBuilderState pointed to by "state", such - * as a subject name matching the issuer name of the previous Cert. If there - * are no matching Certs, the function returns to the previous, or "parent", - * state and tries to continue the chain building with another of the Certs - * obtained from the CertStores as possible issuers for that parent Cert. - * - * 2) For each candidate Cert returned by the CertStores, this function checks - * whether the Cert is valid. If it is trusted, this function checks whether - * this Cert might serve as a TrustAnchor for a complete chain. - * - * 3) It determines whether this Cert, in conjunction with any of the - * TrustAnchors, might complete a chain. A complete chain, from this or the - * preceding step, is checked to see whether it is valid as a complete - * chain, including the checks that cannot be done in the forward direction. - * - * 4) If this Cert chains successfully, but is not a complete chain, that is, - * we have not reached a trusted Cert, a new ForwardBuilderState is created - * with this Cert as the immediate predecessor, and we continue in step (1), - * attempting to get Certs from the CertStores with this Certs "issuer" as - * their subject. - * - * 5) If an entire chain validates successfully, then we are done. A - * ValidateResult is created containing the Public Key of the target - * certificate (including DSA parameter inheritance, if any) and the - * PolicyNode representing the policy tree output by the validation algorithm, - * and stored at pValResult, and the function exits returning NULL. - * - * 5) If the entire chain does not validate successfully, the algorithm - * discards the latest Cert and continues in step 2 with the next candidate - * Cert, backing up to a parent state when no more possibilities exist at a - * given level, and returning failure when we try to back up but discover we - * are at the top level. - * - * PARAMETERS: - * "pNBIOContext" - * Address at which platform-dependent information is returned if building - * is suspended for non-blocking I/O. Must be non-NULL. - * "pState" - * Address at which input ForwardBuilderState is found, and at which output - * ForwardBuilderState is stored. Must be non-NULL. - * "pValResult" - * Address at which the ValidateResult 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 Build 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_BuildForwardDepthFirstSearch( - void **pNBIOContext, - PKIX_ForwardBuilderState *state, - PKIX_ValidateResult **pValResult, - void *plContext) -{ - PKIX_Boolean outOfOptions = PKIX_FALSE; - PKIX_Boolean trusted = PKIX_FALSE; - PKIX_Boolean isSelfIssued = PKIX_FALSE; - PKIX_Boolean canBeCached = PKIX_FALSE; - PKIX_Boolean revocationCheckingExists = PKIX_FALSE; - PKIX_Boolean needsCRLChecking = PKIX_FALSE; - PKIX_Boolean ioPending = PKIX_FALSE; - PKIX_PL_Date *validityDate = NULL; - PKIX_PL_Date *currTime = NULL; - PKIX_Int32 childTraversedCACerts = 0; - PKIX_UInt32 numSubjectNames = 0; - PKIX_UInt32 numChained = 0; - PKIX_Int32 cmpTimeResult = 0; - PKIX_UInt32 i = 0; - PKIX_UInt32 certsSoFar = 0; - PKIX_List *childTraversedSubjNames = NULL; - PKIX_List *subjectNames = NULL; - PKIX_List *unfilteredCerts = NULL; - PKIX_List *filteredCerts = NULL; - PKIX_PL_Object *subjectName = NULL; - PKIX_ValidateResult *valResult = NULL; - PKIX_ForwardBuilderState *childState = NULL; - PKIX_ForwardBuilderState *parentState = NULL; - PKIX_PL_Object *revCheckerState = NULL; - PKIX_ComCertSelParams *certSelParams = NULL; - PKIX_TrustAnchor *trustAnchor = NULL; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_VerifyNode *verifyNode = NULL; - PKIX_Error *verifyError = NULL; - PKIX_Error *finalError = NULL; - void *nbio = NULL; - PKIX_UInt32 numIterations = 0; - - PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch"); - PKIX_NULLCHECK_THREE(pNBIOContext, state, pValResult); - - nbio = *pNBIOContext; - *pNBIOContext = NULL; - PKIX_INCREF(state->validityDate); - validityDate = state->validityDate; - canBeCached = state->canBeCached; - PKIX_DECREF(*pValResult); - - /* - * We return if successful; if we fall off the end - * of this "while" clause our search has failed. - */ - while (outOfOptions == PKIX_FALSE) { - /* - * The maximum number of iterations works around a bug that - * causes this while loop to never exit when AIA and cross - * certificates are involved. See bug xxxxx. - */ - if (numIterations++ > 250) - PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS); - - if (state->buildConstants.maxTime != 0) { - PKIX_DECREF(currTime); - PKIX_CHECK(PKIX_PL_Date_Create_UTCTime - (NULL, &currTime, plContext), - PKIX_DATECREATEUTCTIMEFAILED); - - PKIX_CHECK(PKIX_PL_Object_Compare - ((PKIX_PL_Object *)state->buildConstants.timeLimit, - (PKIX_PL_Object *)currTime, - &cmpTimeResult, - plContext), - PKIX_OBJECTCOMPARATORFAILED); - - if (cmpTimeResult < 0) { - if (state->verifyNode != NULL) { - PKIX_ERROR_CREATE - (BUILD, - PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS, - verifyError); - PKIX_CHECK_FATAL(pkix_VerifyNode_SetError - (state->verifyNode, - verifyError, - plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - } - /* Even if we logged error, we still have to abort */ - PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS); - } - } - - if (state->status == BUILD_INITIAL) { - - PKIX_CHECK(pkix_Build_BuildSelectorAndParams(state, plContext), - PKIX_BUILDBUILDSELECTORANDPARAMSFAILED); - - /* - * If the caller supplied a partial certChain (hintCerts) try - * the next one from that List before we go to the certStores. - */ - if (state->buildConstants.numHintCerts > 0) { - /* How many Certs does our trust chain have already? */ - PKIX_CHECK(PKIX_List_GetLength - (state->trustChain, &certsSoFar, plContext), - PKIX_LISTGETLENGTHFAILED); - - /* That includes the target Cert. Don't count it. */ - certsSoFar--; - - /* Are we still within range of the partial chain? */ - if (certsSoFar >= state->buildConstants.numHintCerts) { - state->status = BUILD_TRYAIA; - } else { - /* - * If we already have n certs, we want the n+1th - * (i.e., index = n) from the list of hints. - */ - PKIX_DECREF(state->candidateCert); - PKIX_CHECK(PKIX_List_GetItem - (state->buildConstants.hintCerts, - certsSoFar, - (PKIX_PL_Object **)&state->candidateCert, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK(PKIX_List_AppendItem - (state->candidateCerts, - (PKIX_PL_Object *)state->candidateCert, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - state->numCerts = 1; - state->usingHintCerts = PKIX_TRUE; - state->status = BUILD_CERTVALIDATING; - } - } else { - state->status = BUILD_TRYAIA; - } - - } - - if (state->status == BUILD_TRYAIA) { - if (state->useOnlyLocal == PKIX_TRUE) { - state->status = BUILD_COLLECTINGCERTS; - } else { - state->status = BUILD_AIAPENDING; - } - } - - if (state->status == BUILD_AIAPENDING && - state->buildConstants.aiaMgr) { - pkixErrorResult = PKIX_PL_AIAMgr_GetAIACerts - (state->buildConstants.aiaMgr, - state->prevCert, - &nbio, - &unfilteredCerts, - plContext); - - if (nbio != NULL) { - /* IO still pending, resume later */ - *pNBIOContext = nbio; - goto cleanup; - } - state->numCerts = 0; - if (pkixErrorResult) { - pkixErrorClass = pkixErrorResult->errClass; - if (pkixErrorClass == PKIX_FATAL_ERROR) { - goto fatal; - } - PKIX_DECREF(finalError); - finalError = pkixErrorResult; - pkixErrorResult = NULL; - if (state->verifyNode != NULL) { - /* state->verifyNode is the object that contains a list - * of verifyNodes. verifyNodes contains cert chain - * build failures that occurred on this level of chain - * building. Here, creating new verify node - * to log the failure and adding it to the list. */ - PKIX_CHECK_FATAL(pkix_VerifyNode_Create - (state->prevCert, - 0, NULL, - &verifyNode, - plContext), - PKIX_VERIFYNODECREATEFAILED); - PKIX_CHECK_FATAL(pkix_VerifyNode_SetError - (verifyNode, finalError, plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - } -#ifdef PKIX_BUILDDEBUG - /* Turn this on to trace the List of Certs, before CertSelect */ - { - PKIX_PL_String *unString; - char *unAscii; - PKIX_UInt32 length; - PKIX_TOSTRING - ((PKIX_PL_Object*)unfilteredCerts, - &unString, - plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_CHECK(PKIX_PL_String_GetEncoded - (unString, - PKIX_ESCASCII, - (void **)&unAscii, - &length, - plContext), - PKIX_STRINGGETENCODEDFAILED); - - PKIX_DEBUG_ARG - ("unfilteredCerts = %s\n", unAscii); - PKIX_DECREF(unString); - PKIX_FREE(unAscii); - } -#endif - - /* Note: Certs winnowed here don't get into VerifyTree. */ - if (unfilteredCerts) { - PKIX_CHECK(pkix_CertSelector_Select - (state->certSel, - unfilteredCerts, - &filteredCerts, - plContext), - PKIX_CERTSELECTORSELECTFAILED); - - PKIX_DECREF(unfilteredCerts); - - PKIX_CHECK(PKIX_List_GetLength - (filteredCerts, &(state->numCerts), plContext), - PKIX_LISTGETLENGTHFAILED); - -#ifdef PKIX_BUILDDEBUG - /* Turn this on to trace the List of Certs, after CertSelect */ - { - PKIX_PL_String *unString; - char *unAscii; - PKIX_UInt32 length; - PKIX_TOSTRING - ((PKIX_PL_Object*)filteredCerts, - &unString, - plContext, - PKIX_OBJECTTOSTRINGFAILED); - - PKIX_CHECK(PKIX_PL_String_GetEncoded - (unString, - PKIX_ESCASCII, - (void **)&unAscii, - &length, - plContext), - PKIX_STRINGGETENCODEDFAILED); - - PKIX_DEBUG_ARG("filteredCerts = %s\n", unAscii); - PKIX_DECREF(unString); - PKIX_FREE(unAscii); - } -#endif - - PKIX_DECREF(state->candidateCerts); - state->candidateCerts = filteredCerts; - state->certIndex = 0; - filteredCerts = NULL; - } - - /* Are there any Certs to try? */ - if (state->numCerts > 0) { - state->status = BUILD_CERTVALIDATING; - } else { - state->status = BUILD_COLLECTINGCERTS; - } - } - - PKIX_DECREF(certSelParams); - PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams - (state->certSel, &certSelParams, plContext), - PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); - - /* **** Querying the CertStores ***** */ - if ((state->status == BUILD_COLLECTINGCERTS) || - (state->status == BUILD_GATHERPENDING)) { - -#if PKIX_FORWARDBUILDERSTATEDEBUG - PKIX_CHECK(pkix_ForwardBuilderState_DumpState - (state, plContext), - PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED); -#endif - - PKIX_CHECK(pkix_Build_GatherCerts - (state, certSelParams, &nbio, plContext), - PKIX_BUILDGATHERCERTSFAILED); - - if (nbio != NULL) { - /* IO still pending, resume later */ - *pNBIOContext = nbio; - goto cleanup; - } - - /* Are there any Certs to try? */ - if (state->numCerts > 0) { - state->status = BUILD_CERTVALIDATING; - } else { - state->status = BUILD_ABANDONNODE; - } - } - - /* ****Phase 2 - Chain building***** */ - -#if PKIX_FORWARDBUILDERSTATEDEBUG - PKIX_CHECK(pkix_ForwardBuilderState_DumpState(state, plContext), - PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED); -#endif - - if (state->status == BUILD_CERTVALIDATING) { - revocationCheckingExists = - (state->buildConstants.revChecker != NULL); - - PKIX_DECREF(state->candidateCert); - PKIX_CHECK(PKIX_List_GetItem - (state->candidateCerts, - state->certIndex, - (PKIX_PL_Object **)&(state->candidateCert), - plContext), - PKIX_LISTGETITEMFAILED); - - if ((state->verifyNode) != NULL) { - PKIX_CHECK_FATAL(pkix_VerifyNode_Create - (state->candidateCert, - 0, - NULL, - &verifyNode, - plContext), - PKIX_VERIFYNODECREATEFAILED); - } - - /* If failure, this function sets Error in verifyNode */ - verifyError = pkix_Build_VerifyCertificate - (state, - state->buildConstants.userCheckers, - revocationCheckingExists, - &trusted, - &needsCRLChecking, - verifyNode, - plContext); - - if (verifyError) { - pkixTempErrorReceived = PKIX_TRUE; - pkixErrorClass = verifyError->errClass; - if (pkixErrorClass == PKIX_FATAL_ERROR) { - pkixErrorResult = verifyError; - verifyError = NULL; - goto fatal; - } - } - - if (PKIX_ERROR_RECEIVED) { - if (state->verifyNode != NULL) { - PKIX_CHECK_FATAL(pkix_VerifyNode_SetError - (verifyNode, verifyError, plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - pkixTempErrorReceived = PKIX_FALSE; - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - if (state->certLoopingDetected) { - PKIX_ERROR - (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED); - } - state->status = BUILD_GETNEXTCERT; - } else if (needsCRLChecking) { - state->status = BUILD_CRLPREP; - } else { - state->status = BUILD_DATEPREP; - } - } - - if (state->status == BUILD_CRLPREP) { - PKIX_RevocationStatus revStatus; - PKIX_UInt32 reasonCode; - - verifyError = - PKIX_RevocationChecker_Check( - state->prevCert, state->candidateCert, - state->buildConstants.revChecker, - state->buildConstants.procParams, - PKIX_FALSE, - (state->parentState == NULL) ? - PKIX_TRUE : PKIX_FALSE, - &revStatus, &reasonCode, - &nbio, plContext); - if (nbio != NULL) { - *pNBIOContext = nbio; - goto cleanup; - } - if (revStatus == PKIX_RevStatus_Revoked || verifyError) { - if (!verifyError) { - /* if verifyError is returned then use it as - * it has a detailed revocation error code. - * Otherwise create a new error */ - PKIX_ERROR_CREATE(VALIDATE, PKIX_CERTIFICATEREVOKED, - verifyError); - } - if (state->verifyNode != NULL) { - PKIX_CHECK_FATAL(pkix_VerifyNode_SetError - (verifyNode, verifyError, plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - if (state->certLoopingDetected) { - PKIX_ERROR - (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED); - } - state->status = BUILD_GETNEXTCERT; - } else { - state->status = BUILD_DATEPREP; - } - } - - if (state->status == BUILD_DATEPREP) { - /* Keep track of whether this chain can be cached */ - PKIX_CHECK(pkix_Build_UpdateDate(state, plContext), - PKIX_BUILDUPDATEDATEFAILED); - - canBeCached = state->canBeCached; - PKIX_DECREF(validityDate); - PKIX_INCREF(state->validityDate); - validityDate = state->validityDate; - if (trusted == PKIX_TRUE) { - state->status = BUILD_CHECKTRUSTED; - } else { - state->status = BUILD_ADDTOCHAIN; - } - } - - if (state->status == BUILD_CHECKTRUSTED) { - - /* - * If this cert is trusted, try to validate the entire - * chain using this certificate as trust anchor. - */ - PKIX_CHECK(PKIX_TrustAnchor_CreateWithCert - (state->candidateCert, - &trustAnchor, - plContext), - PKIX_TRUSTANCHORCREATEWITHCERTFAILED); - - PKIX_CHECK(pkix_Build_ValidationCheckers - (state, - state->trustChain, - trustAnchor, - PKIX_FALSE, /* do not add eku checker - * since eku was already - * checked */ - plContext), - PKIX_BUILDVALIDATIONCHECKERSFAILED); - - state->status = BUILD_CHECKTRUSTED2; - } - - if (state->status == BUILD_CHECKTRUSTED2) { - verifyError = - pkix_Build_ValidateEntireChain(state, - trustAnchor, - &nbio, &valResult, - verifyNode, - plContext); - if (nbio != NULL) { - /* IO still pending, resume later */ - goto cleanup; - } else { - /* checking the error for fatal status */ - if (verifyError) { - pkixTempErrorReceived = PKIX_TRUE; - pkixErrorClass = verifyError->errClass; - if (pkixErrorClass == PKIX_FATAL_ERROR) { - pkixErrorResult = verifyError; - verifyError = NULL; - goto fatal; - } - } - if (state->verifyNode != NULL) { - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - if (!PKIX_ERROR_RECEIVED) { - *pValResult = valResult; - valResult = NULL; - /* Change state so IsIOPending is FALSE */ - state->status = BUILD_CHECKTRUSTED; - goto cleanup; - } - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - /* Reset temp error that was set by - * PKIX_CHECK_ONLY_FATAL and continue */ - pkixTempErrorReceived = PKIX_FALSE; - PKIX_DECREF(trustAnchor); - } - - /* - * If chain doesn't validate with a trusted Cert, - * adding more Certs to it can't help. - */ - if (state->certLoopingDetected) { - PKIX_DECREF(verifyError); - PKIX_ERROR_CREATE(BUILD, - PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED, - verifyError); - PKIX_CHECK_FATAL( - pkix_VerifyNode_SetError(state->verifyNode, - verifyError, - plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_DECREF(verifyError); - } - state->status = BUILD_GETNEXTCERT; - } - - /* - * This Cert was not trusted. Add it to our chain, and - * continue building. If we don't reach a trust anchor, - * we'll take it off later and continue without it. - */ - if (state->status == BUILD_ADDTOCHAIN) { - PKIX_CHECK(PKIX_List_AppendItem - (state->trustChain, - (PKIX_PL_Object *)state->candidateCert, - plContext), - PKIX_LISTAPPENDITEMFAILED); - - state->status = BUILD_EXTENDCHAIN; - } - - if (state->status == BUILD_EXTENDCHAIN) { - - /* Check whether we are allowed to extend the chain */ - if ((state->buildConstants.maxDepth != 0) && - (state->numDepth <= 1)) { - - if (state->verifyNode != NULL) { - PKIX_ERROR_CREATE - (BUILD, - PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS, - verifyError); - PKIX_CHECK_FATAL(pkix_VerifyNode_SetError - (verifyNode, verifyError, plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, verifyNode, plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - } - /* Even if error logged, still need to abort */ - PKIX_ERROR(PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS); - } - - PKIX_CHECK(pkix_IsCertSelfIssued - (state->candidateCert, &isSelfIssued, plContext), - PKIX_ISCERTSELFISSUEDFAILED); - - PKIX_CHECK(PKIX_PL_Object_Duplicate - ((PKIX_PL_Object *)state->traversedSubjNames, - (PKIX_PL_Object **)&childTraversedSubjNames, - plContext), - PKIX_OBJECTDUPLICATEFAILED); - - if (isSelfIssued) { - childTraversedCACerts = state->traversedCACerts; - } else { - childTraversedCACerts = state->traversedCACerts + 1; - - PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames - (state->candidateCert, - &subjectNames, - plContext), - PKIX_CERTGETALLSUBJECTNAMESFAILED); - - if (subjectNames) { - PKIX_CHECK(PKIX_List_GetLength - (subjectNames, - &numSubjectNames, - plContext), - PKIX_LISTGETLENGTHFAILED); - - } else { - numSubjectNames = 0; - } - - for (i = 0; i < numSubjectNames; i++) { - PKIX_CHECK(PKIX_List_GetItem - (subjectNames, - i, - &subjectName, - plContext), - PKIX_LISTGETITEMFAILED); - PKIX_NULLCHECK_ONE - (state->traversedSubjNames); - PKIX_CHECK(PKIX_List_AppendItem - (state->traversedSubjNames, - subjectName, - plContext), - PKIX_LISTAPPENDITEMFAILED); - PKIX_DECREF(subjectName); - } - PKIX_DECREF(subjectNames); - } - - PKIX_CHECK(pkix_ForwardBuilderState_Create - (childTraversedCACerts, - state->buildConstants.maxFanout, - state->numDepth - 1, - state->revCheckDelayed, - canBeCached, - validityDate, - state->candidateCert, - childTraversedSubjNames, - state->trustChain, - state, - &childState, - plContext), - PKIX_FORWARDBUILDSTATECREATEFAILED); - - PKIX_DECREF(childTraversedSubjNames); - PKIX_DECREF(certSelParams); - childState->verifyNode = verifyNode; - verifyNode = NULL; - PKIX_DECREF(state); - state = childState; /* state->status == BUILD_INITIAL */ - childState = NULL; - continue; /* with while (!outOfOptions) */ - } - - if (state->status == BUILD_GETNEXTCERT) { - pkixTempErrorReceived = PKIX_FALSE; - PKIX_DECREF(state->candidateCert); - - /* - * If we were using a Cert from the callier-supplied partial - * chain, delete it and go to the certStores. - */ - if (state->usingHintCerts == PKIX_TRUE) { - PKIX_DECREF(state->candidateCerts); - PKIX_CHECK(PKIX_List_Create - (&state->candidateCerts, plContext), - PKIX_LISTCREATEFAILED); - - state->numCerts = 0; - state->usingHintCerts = PKIX_FALSE; - state->status = BUILD_TRYAIA; - continue; - } else if (++(state->certIndex) < (state->numCerts)) { - if ((state->buildConstants.maxFanout != 0) && - (--(state->numFanout) == 0)) { - - if (state->verifyNode != NULL) { - PKIX_ERROR_CREATE - (BUILD, - PKIX_FANOUTEXCEEDSRESOURCELIMITS, - verifyError); - PKIX_CHECK_FATAL - (pkix_VerifyNode_SetError - (state->verifyNode, - verifyError, - plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_DECREF(finalError); - finalError = verifyError; - verifyError = NULL; - } - /* Even if error logged, still need to abort */ - PKIX_ERROR - (PKIX_FANOUTEXCEEDSRESOURCELIMITS); - } - state->status = BUILD_CERTVALIDATING; - continue; - } - } - - /* - * Adding the current cert to the chain didn't help. If our search - * has been restricted to local certStores, try opening up the - * search and see whether that helps. Otherwise, back up to the - * parent cert, and see if there are any more to try. - */ - if (state->useOnlyLocal == PKIX_TRUE) { - pkix_PrepareForwardBuilderStateForAIA(state); - } else do { - if (state->parentState == NULL) { - /* We are at the top level, and can't back up! */ - outOfOptions = PKIX_TRUE; - } else { - /* - * Try the next cert, if any, for this parent. - * Otherwise keep backing up until we reach a - * parent with more certs to try. - */ - PKIX_CHECK(PKIX_List_GetLength - (state->trustChain, &numChained, plContext), - PKIX_LISTGETLENGTHFAILED); - PKIX_CHECK(PKIX_List_DeleteItem - (state->trustChain, numChained - 1, plContext), - PKIX_LISTDELETEITEMFAILED); - - /* local and aia fetching returned no good certs. - * Creating a verify node in the parent that tells - * us this. */ - if (!state->verifyNode) { - PKIX_CHECK_FATAL( - pkix_VerifyNode_Create(state->prevCert, - 0, NULL, - &state->verifyNode, - plContext), - PKIX_VERIFYNODECREATEFAILED); - } - /* Updating the log with the error. */ - PKIX_DECREF(verifyError); - PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER, - verifyError); - PKIX_CHECK_FATAL( - pkix_VerifyNode_SetError(state->verifyNode, - verifyError, - plContext), - PKIX_VERIFYNODESETERRORFAILED); - PKIX_DECREF(verifyError); - - PKIX_INCREF(state->parentState); - parentState = state->parentState; - PKIX_DECREF(verifyNode); - verifyNode = state->verifyNode; - state->verifyNode = NULL; - PKIX_DECREF(state); - state = parentState; - parentState = NULL; - if (state->verifyNode != NULL && verifyNode) { - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - PKIX_DECREF(validityDate); - PKIX_INCREF(state->validityDate); - validityDate = state->validityDate; - canBeCached = state->canBeCached; - - /* Are there any more Certs to try? */ - if (++(state->certIndex) < (state->numCerts)) { - state->status = BUILD_CERTVALIDATING; - PKIX_DECREF(state->candidateCert); - break; - } - if (state->useOnlyLocal == PKIX_TRUE) { - /* Clean up and go for AIA round. */ - pkix_PrepareForwardBuilderStateForAIA(state); - break; - } - } - PKIX_DECREF(state->candidateCert); - } while (outOfOptions == PKIX_FALSE); - - } /* while (outOfOptions == PKIX_FALSE) */ - -cleanup: - - if (pkixErrorClass == PKIX_FATAL_ERROR) { - goto fatal; - } - - /* verifyNode should be equal to NULL at this point. Assert it. - * Temporarelly use verifyError to store an error ref to which we - * have in pkixErrorResult. This is done to prevent error cloberring - * while using macros below. */ - PORT_Assert(verifyError == NULL); - verifyError = pkixErrorResult; - - /* - * We were called with an initialState that had no parent. If we are - * returning with an error or with a result, we must destroy any state - * that we created (any state with a parent). - */ - - PKIX_CHECK_FATAL(pkix_ForwardBuilderState_IsIOPending - (state, &ioPending, plContext), - PKIX_FORWARDBUILDERSTATEISIOPENDINGFAILED); - - if (ioPending == PKIX_FALSE) { - while (state->parentState) { - PKIX_INCREF(state->parentState); - parentState = state->parentState; - PKIX_DECREF(verifyNode); - verifyNode = state->verifyNode; - state->verifyNode = NULL; - PKIX_DECREF(state); - state = parentState; - parentState = NULL; - if (state->verifyNode != NULL && verifyNode) { - PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree - (state->verifyNode, - verifyNode, - plContext), - PKIX_VERIFYNODEADDTOTREEFAILED); - PKIX_DECREF(verifyNode); - } - } - state->canBeCached = canBeCached; - PKIX_DECREF(state->validityDate); - state->validityDate = validityDate; - validityDate = NULL; - } - if (!*pValResult && !verifyError) { - if (!finalError) { - PKIX_CHECK_FATAL( - pkix_VerifyNode_FindError(state->verifyNode, - &finalError, - plContext), - PKIX_VERIFYNODEFINDERRORFAILED); - } - if (finalError) { - pkixErrorResult = finalError; - pkixErrorCode = PKIX_BUILDFORWARDDEPTHFIRSTSEARCHFAILED; - finalError = NULL; - goto fatal; - } - pkixErrorCode = PKIX_SECERRORUNKNOWNISSUER; - pkixErrorReceived = PKIX_TRUE; - PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER, - verifyError); - PKIX_CHECK_FATAL( - pkix_VerifyNode_SetError(state->verifyNode, verifyError, - plContext), - PKIX_VERIFYNODESETERRORFAILED); - } else { - pkixErrorResult = verifyError; - verifyError = NULL; - } - -fatal: - if (state->parentState) { - /* parentState in "state" object should be NULL at this point. - * If itn't, that means that we got fatal error(we have jumped to - * "fatal" label) and we should destroy all state except the top one. */ - while (state->parentState) { - PKIX_Error *error = NULL; - PKIX_ForwardBuilderState *prntState = state->parentState; - /* Dumb: need to increment parentState to avoid destruction - * of "build constants"(they get destroyed when parentState is - * set to NULL. */ - PKIX_INCREF(prntState); - error = PKIX_PL_Object_DecRef((PKIX_PL_Object*)state, plContext); - if (error) { - PKIX_PL_Object_DecRef((PKIX_PL_Object*)error, plContext); - } - /* No need to decref the parent state. It was already done by - * pkix_ForwardBuilderState_Destroy function. */ - state = prntState; - } - } - PKIX_DECREF(parentState); - PKIX_DECREF(childState); - PKIX_DECREF(valResult); - PKIX_DECREF(verifyError); - PKIX_DECREF(finalError); - PKIX_DECREF(verifyNode); - PKIX_DECREF(childTraversedSubjNames); - PKIX_DECREF(certSelParams); - PKIX_DECREF(subjectNames); - PKIX_DECREF(subjectName); - PKIX_DECREF(trustAnchor); - PKIX_DECREF(validityDate); - PKIX_DECREF(revCheckerState); - PKIX_DECREF(currTime); - PKIX_DECREF(filteredCerts); - PKIX_DECREF(unfilteredCerts); - PKIX_DECREF(trustedCert); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_CheckInCache - * DESCRIPTION: - * - * The function tries to locate a chain for a cert in the cert chain cache. - * If found, the chain goes through revocation chacking and returned back to - * caller. Chains that fail revocation check get removed from cache. - * - * PARAMETERS: - * "state" - * Address of ForwardBuilderState to be used. Must be non-NULL. - * "pBuildResult" - * Address at which the BuildResult is stored, after a successful build. - * Must be non-NULL. - * "pNBIOContext" - * Address at which the NBIOContext is stored indicating whether the - * validation is complete. 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 Build 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_Build_CheckInCache( - PKIX_ForwardBuilderState *state, - PKIX_BuildResult **pBuildResult, - void **pNBIOContext, - void *plContext) -{ - PKIX_PL_Cert *targetCert = NULL; - PKIX_List *anchors = NULL; - PKIX_PL_Date *testDate = NULL; - PKIX_BuildResult *buildResult = NULL; - PKIX_ValidateResult *valResult = NULL; - PKIX_Error *buildError = NULL; - PKIX_TrustAnchor *matchingAnchor = NULL; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_List *certList = NULL; - PKIX_Boolean cacheHit = PKIX_FALSE; - PKIX_Boolean trusted = PKIX_FALSE; - PKIX_Boolean stillValid = PKIX_FALSE; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_CheckInCache"); - - nbioContext = *pNBIOContext; - *pNBIOContext = NULL; - - targetCert = state->buildConstants.targetCert; - anchors = state->buildConstants.anchors; - testDate = state->buildConstants.testDate; - - /* Check whether this cert verification has been cached. */ - PKIX_CHECK(pkix_CacheCertChain_Lookup - (targetCert, - anchors, - testDate, - &cacheHit, - &buildResult, - plContext), - PKIX_CACHECERTCHAINLOOKUPFAILED); - - if (!cacheHit) { - goto cleanup; - } - - /* - * We found something in cache. Verify that the anchor - * cert is still trusted, - */ - PKIX_CHECK(PKIX_BuildResult_GetValidateResult - (buildResult, &valResult, plContext), - PKIX_BUILDRESULTGETVALIDATERESULTFAILED); - - PKIX_CHECK(PKIX_ValidateResult_GetTrustAnchor - (valResult, &matchingAnchor, plContext), - PKIX_VALIDATERESULTGETTRUSTANCHORFAILED); - - PKIX_DECREF(valResult); - - PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert - (matchingAnchor, &trustedCert, plContext), - PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - - if (state->buildConstants.anchors && - state->buildConstants.anchors->length) { - /* Check if it is one of the trust anchors */ - PKIX_CHECK( - pkix_List_Contains(state->buildConstants.anchors, - (PKIX_PL_Object *)matchingAnchor, - &trusted, - plContext), - PKIX_LISTCONTAINSFAILED); - } else { - PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted - (trustedCert, PKIX_FALSE, &trusted, plContext), - PKIX_CERTISCERTTRUSTEDFAILED); - } - - if (!trusted) { - goto cleanup; - } - /* - * Since the key usage may vary for different - * applications, we need to verify the chain again. - * Reverification will be improved with a fix for 397805. - */ - PKIX_CHECK(PKIX_BuildResult_GetCertChain - (buildResult, &certList, plContext), - PKIX_BUILDRESULTGETCERTCHAINFAILED); - - PKIX_CHECK(pkix_Build_ValidationCheckers - (state, - certList, - matchingAnchor, - PKIX_TRUE, /* Chain revalidation stage. */ - plContext), - PKIX_BUILDVALIDATIONCHECKERSFAILED); - - PKIX_CHECK_ONLY_FATAL( - pkix_Build_ValidateEntireChain(state, matchingAnchor, - &nbioContext, &valResult, - state->verifyNode, plContext), - PKIX_BUILDVALIDATEENTIRECHAINFAILED); - - if (nbioContext != NULL) { - /* IO still pending, resume later */ - *pNBIOContext = nbioContext; - goto cleanup; - } - if (!PKIX_ERROR_RECEIVED) { - /* The result from cache is still valid. But we replace an old*/ - *pBuildResult = buildResult; - buildResult = NULL; - stillValid = PKIX_TRUE; - } - -cleanup: - - if (!nbioContext && cacheHit && !(trusted && stillValid)) { - /* The anchor of this chain is no longer trusted or - * chain cert(s) has been revoked. - * Invalidate this result in the cache */ - buildError = pkixErrorResult; - PKIX_CHECK_FATAL(pkix_CacheCertChain_Remove - (targetCert, - anchors, - plContext), - PKIX_CACHECERTCHAINREMOVEFAILED); - pkixErrorResult = buildError; - buildError = NULL; - } - -fatal: - PKIX_DECREF(buildResult); - PKIX_DECREF(valResult); - PKIX_DECREF(buildError); - PKIX_DECREF(certList); - PKIX_DECREF(matchingAnchor); - PKIX_DECREF(trustedCert); - - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_InitiateBuildChain - * DESCRIPTION: - * - * This function initiates the search for a BuildChain, using the parameters - * provided in "procParams" and, if continuing a search that was suspended - * for I/O, using the ForwardBuilderState pointed to by "pState". - * - * If a successful chain is built, this function stores the BuildResult at - * "pBuildResult". Alternatively, if an operation using non-blocking I/O - * is in progress and the operation has not been completed, this function - * stores the platform-dependent non-blocking I/O context (nbioContext) at - * "pNBIOContext", the FowardBuilderState at "pState", and NULL at - * "pBuildResult". Finally, if chain building was unsuccessful, this function - * stores NULL at both "pState" and at "pBuildResult". - * - * Note: This function is re-entered only for the case of non-blocking I/O - * in the "short-cut" attempt to build a chain using the target Certificate - * directly with one of the trustAnchors. For all other cases, resumption - * after non-blocking I/O is via pkix_Build_ResumeBuildChain. - * - * PARAMETERS: - * "procParams" - * Address of the ProcessingParams for the search. Must be non-NULL. - * "pNBIOContext" - * Address at which the NBIOContext is stored indicating whether the - * validation is complete. Must be non-NULL. - * "pState" - * Address at which the ForwardBuilderState is stored, if the chain - * building is suspended for waiting I/O; also, the address at which the - * ForwardBuilderState is provided for resumption of the chain building - * attempt. Must be non-NULL. - * "pBuildResult" - * Address at which the BuildResult is stored, after a successful build. - * Must be non-NULL. - * "pVerifyNode" - * Address at which a VerifyNode chain is returned, 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 Build 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_Build_InitiateBuildChain( - PKIX_ProcessingParams *procParams, - void **pNBIOContext, - PKIX_ForwardBuilderState **pState, - PKIX_BuildResult **pBuildResult, - PKIX_VerifyNode **pVerifyNode, - void *plContext) -{ - PKIX_UInt32 numAnchors = 0; - PKIX_UInt32 numCertStores = 0; - PKIX_UInt32 numHintCerts = 0; - PKIX_UInt32 i = 0; - PKIX_Boolean isDuplicate = PKIX_FALSE; - PKIX_PL_Cert *trustedCert = NULL; - PKIX_CertSelector *targetConstraints = NULL; - PKIX_ComCertSelParams *targetParams = NULL; - PKIX_List *anchors = NULL; - PKIX_List *targetSubjNames = NULL; - PKIX_PL_Cert *targetCert = NULL; - PKIX_PL_Object *firstHintCert = NULL; - PKIX_RevocationChecker *revChecker = NULL; - PKIX_List *certStores = NULL; - PKIX_CertStore *certStore = NULL; - PKIX_List *userCheckers = NULL; - PKIX_List *hintCerts = NULL; - PKIX_PL_Date *testDate = NULL; - PKIX_PL_PublicKey *targetPubKey = NULL; - void *nbioContext = NULL; - BuildConstants buildConstants; - - PKIX_List *tentativeChain = NULL; - PKIX_ValidateResult *valResult = NULL; - PKIX_BuildResult *buildResult = NULL; - PKIX_List *certList = NULL; - PKIX_ForwardBuilderState *state = NULL; - PKIX_CertStore_CheckTrustCallback trustCallback = NULL; - PKIX_CertSelector_MatchCallback selectorCallback = NULL; - PKIX_Boolean trusted = PKIX_FALSE; - PKIX_PL_AIAMgr *aiaMgr = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain"); - PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult); - - nbioContext = *pNBIOContext; - *pNBIOContext = NULL; - - state = *pState; - *pState = NULL; /* no net change in reference count */ - - if (state == NULL) { - PKIX_CHECK(PKIX_ProcessingParams_GetDate - (procParams, &testDate, plContext), - PKIX_PROCESSINGPARAMSGETDATEFAILED); - - PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors - (procParams, &anchors, plContext), - PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED); - - PKIX_CHECK(PKIX_List_GetLength(anchors, &numAnchors, plContext), - PKIX_LISTGETLENGTHFAILED); - - /* retrieve stuff from targetCertConstraints */ - PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints - (procParams, &targetConstraints, plContext), - PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); - - PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams - (targetConstraints, &targetParams, plContext), - PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); - - PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate - (targetParams, &targetCert, plContext), - PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED); - - PKIX_CHECK( - PKIX_ComCertSelParams_SetLeafCertFlag(targetParams, - PKIX_TRUE, plContext), - PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED); - - PKIX_CHECK(PKIX_ProcessingParams_GetHintCerts - (procParams, &hintCerts, plContext), - PKIX_PROCESSINGPARAMSGETHINTCERTSFAILED); - - if (hintCerts != NULL) { - PKIX_CHECK(PKIX_List_GetLength - (hintCerts, &numHintCerts, plContext), - PKIX_LISTGETLENGTHFAILED); - } - - /* - * Caller must provide either a target Cert - * (in ComCertSelParams->Certificate) or a partial Cert - * chain (in ProcParams->HintCerts). - */ - - if (targetCert == NULL) { - - /* Use first cert of hintCerts as the targetCert */ - if (numHintCerts == 0) { - PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED); - } - - PKIX_CHECK(PKIX_List_GetItem - (hintCerts, - 0, - (PKIX_PL_Object **)&targetCert, - plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK(PKIX_List_DeleteItem(hintCerts, 0, plContext), - PKIX_LISTGETITEMFAILED); - } else { - - /* - * If the first hintCert is the same as the targetCert, - * delete it from hintCerts. - */ - if (numHintCerts != 0) { - PKIX_CHECK(PKIX_List_GetItem - (hintCerts, 0, &firstHintCert, plContext), - PKIX_LISTGETITEMFAILED); - - PKIX_CHECK(PKIX_PL_Object_Equals - ((PKIX_PL_Object *)targetCert, - firstHintCert, - &isDuplicate, - plContext), - PKIX_OBJECTEQUALSFAILED); - - if (isDuplicate) { - PKIX_CHECK(PKIX_List_DeleteItem - (hintCerts, 0, plContext), - PKIX_LISTGETITEMFAILED); - } - PKIX_DECREF(firstHintCert); - } - - } - - if (targetCert == NULL) { - PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED); - } - - PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted - (targetCert, - &trusted, - plContext), - PKIX_CERTISCERTTRUSTEDFAILED); - - PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames - (targetCert, - &targetSubjNames, - plContext), - PKIX_CERTGETALLSUBJECTNAMESFAILED); - - PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey - (targetCert, &targetPubKey, plContext), - PKIX_CERTGETSUBJECTPUBLICKEYFAILED); - - PKIX_CHECK(PKIX_List_Create(&tentativeChain, plContext), - PKIX_LISTCREATEFAILED); - - PKIX_CHECK(PKIX_List_AppendItem - (tentativeChain, (PKIX_PL_Object *)targetCert, plContext), - PKIX_LISTAPPENDITEMFAILED); - - if (procParams->qualifyTargetCert) { - /* EE cert validation */ - /* Sync up the time on the target selector parameter struct. */ - PKIX_CHECK( - PKIX_ComCertSelParams_SetCertificateValid(targetParams, - testDate, - plContext), - PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED); - - PKIX_CHECK(PKIX_CertSelector_GetMatchCallback - (targetConstraints, &selectorCallback, plContext), - PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); - - pkixErrorResult = - (*selectorCallback)(targetConstraints, targetCert, - plContext); - if (pkixErrorResult) { - pkixErrorClass = pkixErrorResult->errClass; - if (pkixErrorClass == PKIX_FATAL_ERROR) { - goto cleanup; - } - if (pVerifyNode != NULL) { - PKIX_Error *tempResult = - pkix_VerifyNode_Create(targetCert, 0, - pkixErrorResult, - pVerifyNode, - plContext); - if (tempResult) { - PKIX_DECREF(pkixErrorResult); - pkixErrorResult = tempResult; - pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; - pkixErrorClass = PKIX_FATAL_ERROR; - goto cleanup; - } - } - pkixErrorCode = PKIX_CERTCHECKVALIDITYFAILED; - goto cleanup; - } - } - - /* If the EE cert is trusted, force success. We only want to do - * this if we aren't validating against a policy (like EV). */ - if (trusted && procParams->initialPolicies == NULL) { - if (pVerifyNode != NULL) { - PKIX_Error *tempResult = - pkix_VerifyNode_Create(targetCert, 0, NULL, - pVerifyNode, - plContext); - if (tempResult) { - pkixErrorResult = tempResult; - pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; - pkixErrorClass = PKIX_FATAL_ERROR; - goto cleanup; - } - } - PKIX_CHECK(pkix_ValidateResult_Create - (targetPubKey, NULL /* anchor */, - NULL /* policyTree */, &valResult, plContext), - PKIX_VALIDATERESULTCREATEFAILED); - PKIX_CHECK( - pkix_BuildResult_Create(valResult, tentativeChain, - &buildResult, plContext), - PKIX_BUILDRESULTCREATEFAILED); - *pBuildResult = buildResult; - /* Note that *pState is NULL. The only side effect is that - * the cert chain won't be cached in PKIX_BuildChain, which - * is fine. */ - goto cleanup; - } - - PKIX_CHECK(PKIX_ProcessingParams_GetCertStores - (procParams, &certStores, plContext), - PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED); - - PKIX_CHECK(PKIX_List_GetLength - (certStores, &numCertStores, plContext), - PKIX_LISTGETLENGTHFAILED); - - /* Reorder CertStores so trusted are at front of the List */ - if (numCertStores > 1) { - for (i = numCertStores - 1; i > 0; i--) { - PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem - (certStores, - i, - (PKIX_PL_Object **)&certStore, - plContext), - PKIX_LISTGETITEMFAILED); - PKIX_CHECK_ONLY_FATAL(PKIX_CertStore_GetTrustCallback - (certStore, &trustCallback, plContext), - PKIX_CERTSTOREGETTRUSTCALLBACKFAILED); - - if (trustCallback != NULL) { - /* Is a trusted Cert, move CertStore to front */ - PKIX_CHECK(PKIX_List_DeleteItem - (certStores, i, plContext), - PKIX_LISTDELETEITEMFAILED); - PKIX_CHECK(PKIX_List_InsertItem - (certStores, - 0, - (PKIX_PL_Object *)certStore, - plContext), - PKIX_LISTINSERTITEMFAILED); - - } - - PKIX_DECREF(certStore); - } - } - - PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers - (procParams, &userCheckers, plContext), - PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED); - - PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker - (procParams, &revChecker, plContext), - PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED); - /* Do not initialize AIA manager if we are not going to fetch - * cert using aia url. */ - if (procParams->useAIAForCertFetching) { - PKIX_CHECK(PKIX_PL_AIAMgr_Create(&aiaMgr, plContext), - PKIX_AIAMGRCREATEFAILED); - } - - /* - * We initialize all the fields of buildConstants here, in one place, - * just to help keep track and ensure that we got everything. - */ - - buildConstants.numAnchors = numAnchors; - buildConstants.numCertStores = numCertStores; - buildConstants.numHintCerts = numHintCerts; - buildConstants.procParams = procParams; - buildConstants.testDate = testDate; - buildConstants.timeLimit = NULL; - buildConstants.targetCert = targetCert; - buildConstants.targetPubKey = targetPubKey; - buildConstants.certStores = certStores; - buildConstants.anchors = anchors; - buildConstants.userCheckers = userCheckers; - buildConstants.hintCerts = hintCerts; - buildConstants.revChecker = revChecker; - buildConstants.aiaMgr = aiaMgr; - buildConstants.trustOnlyUserAnchors = - procParams->useOnlyTrustAnchors; - - PKIX_CHECK(pkix_Build_GetResourceLimits(&buildConstants, plContext), - PKIX_BUILDGETRESOURCELIMITSFAILED); - - PKIX_CHECK(pkix_ForwardBuilderState_Create - (0, /* PKIX_UInt32 traversedCACerts */ - buildConstants.maxFanout, - buildConstants.maxDepth, - PKIX_FALSE, /* PKIX_Boolean revCheckDelayed */ - PKIX_TRUE, /* PKIX_Boolean canBeCached */ - NULL, /* PKIX_Date *validityDate */ - targetCert, /* PKIX_PL_Cert *prevCert */ - targetSubjNames, /* PKIX_List *traversedSubjNames */ - tentativeChain, /* PKIX_List *trustChain */ - NULL, /* PKIX_ForwardBuilderState *parent */ - &state, /* PKIX_ForwardBuilderState **pState */ - plContext), - PKIX_BUILDSTATECREATEFAILED); - - state->buildConstants.numAnchors = buildConstants.numAnchors; - state->buildConstants.numCertStores = buildConstants.numCertStores; - state->buildConstants.numHintCerts = buildConstants.numHintCerts; - state->buildConstants.maxFanout = buildConstants.maxFanout; - state->buildConstants.maxDepth = buildConstants.maxDepth; - state->buildConstants.maxTime = buildConstants.maxTime; - state->buildConstants.procParams = buildConstants.procParams; - PKIX_INCREF(buildConstants.testDate); - state->buildConstants.testDate = buildConstants.testDate; - state->buildConstants.timeLimit = buildConstants.timeLimit; - PKIX_INCREF(buildConstants.targetCert); - state->buildConstants.targetCert = buildConstants.targetCert; - PKIX_INCREF(buildConstants.targetPubKey); - state->buildConstants.targetPubKey = - buildConstants.targetPubKey; - PKIX_INCREF(buildConstants.certStores); - state->buildConstants.certStores = buildConstants.certStores; - PKIX_INCREF(buildConstants.anchors); - state->buildConstants.anchors = buildConstants.anchors; - PKIX_INCREF(buildConstants.userCheckers); - state->buildConstants.userCheckers = - buildConstants.userCheckers; - PKIX_INCREF(buildConstants.hintCerts); - state->buildConstants.hintCerts = buildConstants.hintCerts; - PKIX_INCREF(buildConstants.revChecker); - state->buildConstants.revChecker = buildConstants.revChecker; - state->buildConstants.aiaMgr = buildConstants.aiaMgr; - aiaMgr = NULL; - state->buildConstants.trustOnlyUserAnchors = - buildConstants.trustOnlyUserAnchors; - - if (buildConstants.maxTime != 0) { - PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds - (buildConstants.maxTime, - &state->buildConstants.timeLimit, - plContext), - PKIX_DATECREATECURRENTOFFBYSECONDSFAILED); - } - - if (pVerifyNode != NULL) { - PKIX_Error *tempResult = - pkix_VerifyNode_Create(targetCert, 0, NULL, - &(state->verifyNode), - plContext); - if (tempResult) { - pkixErrorResult = tempResult; - pkixErrorCode = PKIX_VERIFYNODECREATEFAILED; - pkixErrorClass = PKIX_FATAL_ERROR; - goto cleanup; - } - } - - PKIX_CHECK_ONLY_FATAL( - pkix_Build_CheckInCache(state, &buildResult, - &nbioContext, plContext), - PKIX_UNABLETOBUILDCHAIN); - if (nbioContext) { - *pNBIOContext = nbioContext; - *pState = state; - state = NULL; - goto cleanup; - } - if (buildResult) { - *pBuildResult = buildResult; - if (pVerifyNode != NULL) { - *pVerifyNode = state->verifyNode; - state->verifyNode = NULL; - } - goto cleanup; - } - } - - /* If we're resuming after non-blocking I/O we need to get SubjNames */ - if (targetSubjNames == NULL) { - PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames - (state->buildConstants.targetCert, - &targetSubjNames, - plContext), - PKIX_CERTGETALLSUBJECTNAMESFAILED); - } - - state->status = BUILD_INITIAL; - - pkixErrorResult = - pkix_BuildForwardDepthFirstSearch(&nbioContext, state, - &valResult, plContext); - - /* non-null nbioContext means the build would block */ - if (pkixErrorResult == NULL && nbioContext != NULL) { - - *pNBIOContext = nbioContext; - *pBuildResult = NULL; - - /* no valResult means the build has failed */ - } else { - if (pVerifyNode != NULL) { - PKIX_INCREF(state->verifyNode); - *pVerifyNode = state->verifyNode; - } - - if (valResult == NULL || pkixErrorResult) - PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); - PKIX_CHECK( - pkix_BuildResult_Create(valResult, state->trustChain, - &buildResult, plContext), - PKIX_BUILDRESULTCREATEFAILED); - *pBuildResult = buildResult; - } - - *pState = state; - state = NULL; - -cleanup: - - PKIX_DECREF(targetConstraints); - PKIX_DECREF(targetParams); - PKIX_DECREF(anchors); - PKIX_DECREF(targetSubjNames); - PKIX_DECREF(targetCert); - PKIX_DECREF(revChecker); - PKIX_DECREF(certStores); - PKIX_DECREF(certStore); - PKIX_DECREF(userCheckers); - PKIX_DECREF(hintCerts); - PKIX_DECREF(firstHintCert); - PKIX_DECREF(testDate); - PKIX_DECREF(targetPubKey); - PKIX_DECREF(tentativeChain); - PKIX_DECREF(valResult); - PKIX_DECREF(certList); - PKIX_DECREF(trustedCert); - PKIX_DECREF(state); - PKIX_DECREF(aiaMgr); - - PKIX_RETURN(BUILD); -} - -/* - * FUNCTION: pkix_Build_ResumeBuildChain - * DESCRIPTION: - * - * This function continues the search for a BuildChain, using the parameters - * provided in "procParams" and the ForwardBuilderState pointed to by "state". - * - * If a successful chain is built, this function stores the BuildResult at - * "pBuildResult". Alternatively, if an operation using non-blocking I/O - * is in progress and the operation has not been completed, this function - * stores the FowardBuilderState at "pState" and NULL at "pBuildResult". - * Finally, if chain building was unsuccessful, this function stores NULL - * at both "pState" and at "pBuildResult". - * - * PARAMETERS: - * "pNBIOContext" - * Address at which the NBIOContext is stored indicating whether the - * validation is complete. Must be non-NULL. - * "pState" - * Address at which the ForwardBuilderState is provided for resumption of - * the chain building attempt; also, the address at which the - * ForwardBuilderStateis stored, if the chain building is suspended for - * waiting I/O. Must be non-NULL. - * "pBuildResult" - * Address at which the BuildResult is stored, after a successful build. - * 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 Build 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_Build_ResumeBuildChain( - void **pNBIOContext, - PKIX_ForwardBuilderState *state, - PKIX_BuildResult **pBuildResult, - PKIX_VerifyNode **pVerifyNode, - void *plContext) -{ - PKIX_ValidateResult *valResult = NULL; - PKIX_BuildResult *buildResult = NULL; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "pkix_Build_ResumeBuildChain"); - PKIX_NULLCHECK_TWO(state, pBuildResult); - - nbioContext = *pNBIOContext; - *pNBIOContext = NULL; - - pkixErrorResult = - pkix_BuildForwardDepthFirstSearch(&nbioContext, state, - &valResult, plContext); - - /* non-null nbioContext means the build would block */ - if (pkixErrorResult == NULL && nbioContext != NULL) { - - *pNBIOContext = nbioContext; - *pBuildResult = NULL; - - /* no valResult means the build has failed */ - } else { - if (pVerifyNode != NULL) { - PKIX_INCREF(state->verifyNode); - *pVerifyNode = state->verifyNode; - } - - if (valResult == NULL || pkixErrorResult) - PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); - - PKIX_CHECK( - pkix_BuildResult_Create(valResult, state->trustChain, - &buildResult, plContext), - PKIX_BUILDRESULTCREATEFAILED); - *pBuildResult = buildResult; - } - -cleanup: - - PKIX_DECREF(valResult); - - PKIX_RETURN(BUILD); -} - -/* --Public-Functions--------------------------------------------- */ - -/* - * FUNCTION: PKIX_BuildChain (see comments in pkix.h) - */ -PKIX_Error * -PKIX_BuildChain( - PKIX_ProcessingParams *procParams, - void **pNBIOContext, - void **pState, - PKIX_BuildResult **pBuildResult, - PKIX_VerifyNode **pVerifyNode, - void *plContext) -{ - PKIX_ForwardBuilderState *state = NULL; - PKIX_BuildResult *buildResult = NULL; - void *nbioContext = NULL; - - PKIX_ENTER(BUILD, "PKIX_BuildChain"); - PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult); - - nbioContext = *pNBIOContext; - *pNBIOContext = NULL; - - if (*pState == NULL) { - PKIX_CHECK(pkix_Build_InitiateBuildChain - (procParams, - &nbioContext, - &state, - &buildResult, - pVerifyNode, - plContext), - PKIX_BUILDINITIATEBUILDCHAINFAILED); - } else { - state = (PKIX_ForwardBuilderState *)(*pState); - *pState = NULL; /* no net change in reference count */ - if (state->status == BUILD_SHORTCUTPENDING) { - PKIX_CHECK(pkix_Build_InitiateBuildChain - (procParams, - &nbioContext, - &state, - &buildResult, - pVerifyNode, - plContext), - PKIX_BUILDINITIATEBUILDCHAINFAILED); - } else { - PKIX_CHECK(pkix_Build_ResumeBuildChain - (&nbioContext, - state, - &buildResult, - pVerifyNode, - plContext), - PKIX_BUILDINITIATEBUILDCHAINFAILED); - } - } - - /* non-null nbioContext means the build would block */ - if (nbioContext != NULL) { - - *pNBIOContext = nbioContext; - *pState = state; - state = NULL; - *pBuildResult = NULL; - - /* no buildResult means the build has failed */ - } else if (buildResult == NULL) { - PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN); - } else { - /* - * If we made a successful chain by combining the target Cert - * with one of the Trust Anchors, we may have never created a - * validityDate. We treat this situation as - * canBeCached = PKIX_FALSE. - */ - if ((state != NULL) && - ((state->validityDate) != NULL) && - (state->canBeCached)) { - PKIX_CHECK(pkix_CacheCertChain_Add - (state->buildConstants.targetCert, - state->buildConstants.anchors, - state->validityDate, - buildResult, - plContext), - PKIX_CACHECERTCHAINADDFAILED); - } - - *pState = NULL; - *pBuildResult = buildResult; - buildResult = NULL; - } - -cleanup: - PKIX_DECREF(buildResult); - PKIX_DECREF(state); - - PKIX_RETURN(BUILD); -} diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.h b/security/nss/lib/libpkix/pkix/top/pkix_build.h deleted file mode 100755 index 91916d4c8..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_build.h +++ /dev/null @@ -1,123 +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_build.h - * - * Header file for buildChain function - * - */ - -#ifndef _PKIX_BUILD_H -#define _PKIX_BUILD_H -#include "pkix_tools.h" -#include "pkix_pl_ldapt.h" -#include "pkix_ekuchecker.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - BUILD_SHORTCUTPENDING, - BUILD_INITIAL, - BUILD_TRYAIA, - BUILD_AIAPENDING, - BUILD_COLLECTINGCERTS, - BUILD_GATHERPENDING, - BUILD_CERTVALIDATING, - BUILD_ABANDONNODE, - BUILD_CRLPREP, - BUILD_CRL1, - BUILD_DATEPREP, - BUILD_CHECKTRUSTED, - BUILD_CHECKTRUSTED2, - BUILD_ADDTOCHAIN, - BUILD_CRL2PREP, - BUILD_CRL2, - BUILD_VALCHAIN, - BUILD_VALCHAIN2, - BUILD_EXTENDCHAIN, - BUILD_GETNEXTCERT -} BuildStatus; - -typedef struct BuildConstantsStruct BuildConstants; - -/* - * These fields (the ones that are objects) are not reference-counted - * in *each* state, but only in the root, the state that has no parent. - * That saves time in creation and destruction of child states, but is - * safe enough since they are constants. - */ -struct BuildConstantsStruct { - PKIX_UInt32 numAnchors; - PKIX_UInt32 numCertStores; - PKIX_UInt32 numHintCerts; - PKIX_UInt32 maxDepth; - PKIX_UInt32 maxFanout; - PKIX_UInt32 maxTime; - PKIX_ProcessingParams *procParams; - PKIX_PL_Date *testDate; - PKIX_PL_Date *timeLimit; - PKIX_PL_Cert *targetCert; - PKIX_PL_PublicKey *targetPubKey; - PKIX_List *certStores; - PKIX_List *anchors; - PKIX_List *userCheckers; - PKIX_List *hintCerts; - PKIX_RevocationChecker *revChecker; - PKIX_PL_AIAMgr *aiaMgr; - PKIX_Boolean useAIAForCertFetching; - PKIX_Boolean trustOnlyUserAnchors; -}; - -struct PKIX_ForwardBuilderStateStruct{ - BuildStatus status; - PKIX_Int32 traversedCACerts; - PKIX_UInt32 certStoreIndex; - PKIX_UInt32 numCerts; - PKIX_UInt32 numAias; - PKIX_UInt32 certIndex; - PKIX_UInt32 aiaIndex; - PKIX_UInt32 certCheckedIndex; - PKIX_UInt32 checkerIndex; - PKIX_UInt32 hintCertIndex; - PKIX_UInt32 numFanout; - PKIX_UInt32 numDepth; - PKIX_UInt32 reasonCode; - PKIX_Boolean revCheckDelayed; - PKIX_Boolean canBeCached; - PKIX_Boolean useOnlyLocal; - PKIX_Boolean revChecking; - PKIX_Boolean usingHintCerts; - PKIX_Boolean certLoopingDetected; - PKIX_PL_Date *validityDate; - PKIX_PL_Cert *prevCert; - PKIX_PL_Cert *candidateCert; - PKIX_List *traversedSubjNames; - PKIX_List *trustChain; - PKIX_List *aia; - PKIX_List *candidateCerts; - PKIX_List *reversedCertChain; - PKIX_List *checkedCritExtOIDs; - PKIX_List *checkerChain; - PKIX_CertSelector *certSel; - PKIX_VerifyNode *verifyNode; - void *client; /* messageHandler, such as LDAPClient */ - PKIX_ForwardBuilderState *parentState; - BuildConstants buildConstants; -}; - -/* --Private-Functions-------------------------------------------- */ - -PKIX_Error * -pkix_ForwardBuilderState_RegisterSelf(void *plContext); - -PKIX_Error * -PKIX_Build_GetNBIOContext(void *state, void **pNBIOContext, void *plContext); - -#ifdef __cplusplus -} -#endif - -#endif /* _PKIX_BUILD_H */ diff --git a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c b/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c deleted file mode 100755 index aad0e1aaf..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c +++ /dev/null @@ -1,210 +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_lifecycle.c - * - * Top level initialize and shutdown functions - * - */ - -#include "pkix_lifecycle.h" - -static PKIX_Boolean pkixIsInitialized; - -/* Lock used by Logger - is reentrant by the same thread */ -extern PKIX_PL_MonitorLock *pkixLoggerLock; - -/* - * Following pkix_* variables are for debugging purpose. They should be taken - * out eventually. The purpose is to verify cache tables usage (via debugger). - */ -int pkix_ccAddCount = 0; -int pkix_ccLookupCount = 0; -int pkix_ccRemoveCount = 0; -int pkix_cAddCount = 0; -int pkix_cLookupCount = 0; -int pkix_cRemoveCount = 0; -int pkix_ceAddCount = 0; -int pkix_ceLookupCount = 0; - -PKIX_PL_HashTable *cachedCrlSigTable = NULL; -PKIX_PL_HashTable *cachedCertSigTable = NULL; -PKIX_PL_HashTable *cachedCertChainTable = NULL; -PKIX_PL_HashTable *cachedCertTable = NULL; -PKIX_PL_HashTable *cachedCrlEntryTable = NULL; -PKIX_PL_HashTable *aiaConnectionCache = NULL; -PKIX_PL_HashTable *httpSocketCache = NULL; - -extern PKIX_List *pkixLoggers; -extern PKIX_List *pkixLoggersErrors; -extern PKIX_List *pkixLoggersDebugTrace; - -/* --Public-Functions--------------------------------------------- */ - -/* - * FUNCTION: PKIX_Initialize (see comments in pkix.h) - */ -PKIX_Error * -PKIX_Initialize( - PKIX_Boolean platformInitNeeded, - PKIX_UInt32 desiredMajorVersion, - PKIX_UInt32 minDesiredMinorVersion, - PKIX_UInt32 maxDesiredMinorVersion, - PKIX_UInt32 *pActualMinorVersion, - void **pPlContext) -{ - void *plContext = NULL; - - PKIX_ENTER(LIFECYCLE, "PKIX_Initialize"); - PKIX_NULLCHECK_ONE(pPlContext); - - /* - * If we are called a second time other than in the situation handled - * above, we return a positive status. - */ - if (pkixIsInitialized){ - /* Already initialized */ - PKIX_RETURN(LIFECYCLE); - } - - PKIX_CHECK(PKIX_PL_Initialize - (platformInitNeeded, PKIX_FALSE, &plContext), - PKIX_INITIALIZEFAILED); - - *pPlContext = plContext; - - if (desiredMajorVersion != PKIX_MAJOR_VERSION){ - PKIX_ERROR(PKIX_MAJORVERSIONSDONTMATCH); - } - - if ((minDesiredMinorVersion > PKIX_MINOR_VERSION) || - (maxDesiredMinorVersion < PKIX_MINOR_VERSION)){ - PKIX_ERROR(PKIX_MINORVERSIONNOTBETWEENDESIREDMINANDMAX); - } - - *pActualMinorVersion = PKIX_MINOR_VERSION; - - /* Create Cache Tables - * Do not initialize hash tables for object leak test */ -#if !defined(PKIX_OBJECT_LEAK_TEST) - PKIX_CHECK(PKIX_PL_HashTable_Create - (32, 0, &cachedCertSigTable, plContext), - PKIX_HASHTABLECREATEFAILED); - - PKIX_CHECK(PKIX_PL_HashTable_Create - (32, 0, &cachedCrlSigTable, plContext), - PKIX_HASHTABLECREATEFAILED); - - PKIX_CHECK(PKIX_PL_HashTable_Create - (32, 10, &cachedCertChainTable, plContext), - PKIX_HASHTABLECREATEFAILED); - - PKIX_CHECK(PKIX_PL_HashTable_Create - (32, 10, &cachedCertTable, plContext), - PKIX_HASHTABLECREATEFAILED); - - PKIX_CHECK(PKIX_PL_HashTable_Create - (32, 10, &cachedCrlEntryTable, plContext), - PKIX_HASHTABLECREATEFAILED); - - PKIX_CHECK(PKIX_PL_HashTable_Create - (5, 5, &aiaConnectionCache, plContext), - PKIX_HASHTABLECREATEFAILED); - -#ifdef PKIX_SOCKETCACHE - PKIX_CHECK(PKIX_PL_HashTable_Create - (5, 5, &httpSocketCache, plContext), - PKIX_HASHTABLECREATEFAILED); -#endif - if (pkixLoggerLock == NULL) { - PKIX_CHECK(PKIX_PL_MonitorLock_Create - (&pkixLoggerLock, plContext), - PKIX_MONITORLOCKCREATEFAILED); - } -#else - fnInvTable = PL_NewHashTable(0, pkix_ErrorGen_Hash, - PL_CompareValues, - PL_CompareValues, NULL, NULL); - if (!fnInvTable) { - PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); - } - - fnStackNameArr = PORT_ZNewArray(char*, MAX_STACK_DEPTH); - if (!fnStackNameArr) { - PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); - } - - fnStackInvCountArr = PORT_ZNewArray(PKIX_UInt32, MAX_STACK_DEPTH); - if (!fnStackInvCountArr) { - PKIX_ERROR(PKIX_HASHTABLECREATEFAILED); - } -#endif /* PKIX_OBJECT_LEAK_TEST */ - - pkixIsInitialized = PKIX_TRUE; - -cleanup: - - PKIX_RETURN(LIFECYCLE); -} - -/* - * FUNCTION: PKIX_Shutdown (see comments in pkix.h) - */ -PKIX_Error * -PKIX_Shutdown(void *plContext) -{ - PKIX_List *savedPkixLoggers = NULL; - PKIX_List *savedPkixLoggersErrors = NULL; - PKIX_List *savedPkixLoggersDebugTrace = NULL; - - PKIX_ENTER(LIFECYCLE, "PKIX_Shutdown"); - - if (!pkixIsInitialized){ - /* The library was not initialized */ - PKIX_RETURN(LIFECYCLE); - } - - pkixIsInitialized = PKIX_FALSE; - - if (pkixLoggers) { - savedPkixLoggers = pkixLoggers; - savedPkixLoggersErrors = pkixLoggersErrors; - savedPkixLoggersDebugTrace = pkixLoggersDebugTrace; - pkixLoggers = NULL; - pkixLoggersErrors = NULL; - pkixLoggersDebugTrace = NULL; - PKIX_DECREF(savedPkixLoggers); - PKIX_DECREF(savedPkixLoggersErrors); - PKIX_DECREF(savedPkixLoggersDebugTrace); - } - PKIX_DECREF(pkixLoggerLock); - - /* Destroy Cache Tables */ - PKIX_DECREF(cachedCertSigTable); - PKIX_DECREF(cachedCrlSigTable); - PKIX_DECREF(cachedCertChainTable); - PKIX_DECREF(cachedCertTable); - PKIX_DECREF(cachedCrlEntryTable); - PKIX_DECREF(aiaConnectionCache); - PKIX_DECREF(httpSocketCache); - - /* Clean up any temporary errors that happened during shutdown */ - if (pkixErrorList) { - PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorList, plContext); - pkixErrorList = NULL; - } - - PKIX_CHECK(PKIX_PL_Shutdown(plContext), - PKIX_SHUTDOWNFAILED); - -#ifdef PKIX_OBJECT_LEAK_TEST - PORT_Free(fnStackInvCountArr); - PORT_Free(fnStackNameArr); - PL_HashTableDestroy(fnInvTable); -#endif - -cleanup: - - PKIX_RETURN(LIFECYCLE); -} diff --git a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h b/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h deleted file mode 100755 index 02631229c..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h +++ /dev/null @@ -1,23 +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_lifecycle.h - * - * Header file for initialize and shutdown functions. - * - */ - -#ifndef _PKIX_LIFECYCLE_H -#define _PKIX_LIFECYCLE_H -#include "pkix_tools.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _PKIX_LIFECYCLE_H */ diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.c b/security/nss/lib/libpkix/pkix/top/pkix_validate.c deleted file mode 100755 index edee9f32e..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_validate.c +++ /dev/null @@ -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); -} diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.h b/security/nss/lib/libpkix/pkix/top/pkix_validate.h deleted file mode 100755 index 7692e3bab..000000000 --- a/security/nss/lib/libpkix/pkix/top/pkix_validate.h +++ /dev/null @@ -1,42 +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.h - * - * Header file for validateChain function - * - */ - -#ifndef _PKIX_VALIDATE_H -#define _PKIX_VALIDATE_H -#include "pkix_tools.h" - -#ifdef __cplusplus -extern "C" { -#endif - -PKIX_Error * -pkix_CheckChain( - PKIX_List *certs, - PKIX_UInt32 numCerts, - PKIX_TrustAnchor *anchor, - PKIX_List *checkers, - PKIX_RevocationChecker *revChecker, - PKIX_List *buildCheckedExtOIDs, - 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); - -#ifdef __cplusplus -} -#endif - -#endif /* _PKIX_VALIDATE_H */ |