summaryrefslogtreecommitdiff
path: root/security/nss/lib/libpkix/pkix/top
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/libpkix/pkix/top')
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/manifest.mn25
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.c3821
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.h123
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_lifecycle.c210
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_lifecycle.h23
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.c1443
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.h42
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, &paramsNeeded, 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, &currentIssuer, 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, &notAfter, 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 */