Index: mozilla/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c (working copy) |
@@ -1,2783 +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_policychecker.c |
- * |
- * Functions for Policy Checker |
- * |
- */ |
-#include "pkix_policychecker.h" |
- |
-/* --Forward declarations----------------------------------------------- */ |
- |
-static PKIX_Error * |
-pkix_PolicyChecker_MakeSingleton( |
- PKIX_PL_Object *listItem, |
- PKIX_Boolean immutability, |
- PKIX_List **pList, |
- void *plContext); |
- |
-/* --Private-PolicyCheckerState-Functions---------------------------------- */ |
- |
-/* |
- * FUNCTION:pkix_PolicyCheckerState_Destroy |
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_PolicyCheckerState_Destroy( |
- PKIX_PL_Object *object, |
- void *plContext) |
-{ |
- PKIX_PolicyCheckerState *checkerState = NULL; |
- |
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Destroy"); |
- PKIX_NULLCHECK_ONE(object); |
- |
- PKIX_CHECK(pkix_CheckType |
- (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext), |
- PKIX_OBJECTNOTPOLICYCHECKERSTATE); |
- |
- checkerState = (PKIX_PolicyCheckerState *)object; |
- |
- PKIX_DECREF(checkerState->certPoliciesExtension); |
- PKIX_DECREF(checkerState->policyMappingsExtension); |
- PKIX_DECREF(checkerState->policyConstraintsExtension); |
- PKIX_DECREF(checkerState->inhibitAnyPolicyExtension); |
- PKIX_DECREF(checkerState->anyPolicyOID); |
- PKIX_DECREF(checkerState->validPolicyTree); |
- PKIX_DECREF(checkerState->userInitialPolicySet); |
- PKIX_DECREF(checkerState->mappedUserInitialPolicySet); |
- |
- checkerState->policyQualifiersRejected = PKIX_FALSE; |
- checkerState->explicitPolicy = 0; |
- checkerState->inhibitAnyPolicy = 0; |
- checkerState->policyMapping = 0; |
- checkerState->numCerts = 0; |
- checkerState->certsProcessed = 0; |
- checkerState->certPoliciesCritical = PKIX_FALSE; |
- |
- PKIX_DECREF(checkerState->anyPolicyNodeAtBottom); |
- PKIX_DECREF(checkerState->newAnyPolicyNode); |
- PKIX_DECREF(checkerState->mappedPolicyOIDs); |
- |
-cleanup: |
- |
- PKIX_RETURN(CERTPOLICYCHECKERSTATE); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyCheckerState_ToString |
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_PolicyCheckerState_ToString( |
- PKIX_PL_Object *object, |
- PKIX_PL_String **pCheckerStateString, |
- void *plContext) |
-{ |
- PKIX_PolicyCheckerState *state = NULL; |
- PKIX_PL_String *resultString = NULL; |
- PKIX_PL_String *policiesExtOIDString = NULL; |
- PKIX_PL_String *policyMapOIDString = NULL; |
- PKIX_PL_String *policyConstrOIDString = NULL; |
- PKIX_PL_String *inhAnyPolOIDString = NULL; |
- PKIX_PL_String *anyPolicyOIDString = NULL; |
- PKIX_PL_String *validPolicyTreeString = NULL; |
- PKIX_PL_String *userInitialPolicySetString = NULL; |
- PKIX_PL_String *mappedUserPolicySetString = NULL; |
- PKIX_PL_String *mappedPolicyOIDsString = NULL; |
- PKIX_PL_String *anyAtBottomString = NULL; |
- PKIX_PL_String *newAnyPolicyString = NULL; |
- PKIX_PL_String *formatString = NULL; |
- PKIX_PL_String *trueString = NULL; |
- PKIX_PL_String *falseString = NULL; |
- PKIX_PL_String *nullString = NULL; |
- PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; |
- PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; |
- PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; |
- PKIX_Boolean initialIsAnyPolicy = PKIX_FALSE; |
- PKIX_Boolean policyQualifiersRejected = PKIX_FALSE; |
- PKIX_Boolean certPoliciesCritical = PKIX_FALSE; |
- char *asciiFormat = |
- "{\n" |
- "\tcertPoliciesExtension: \t%s\n" |
- "\tpolicyMappingsExtension: \t%s\n" |
- "\tpolicyConstraintsExtension:\t%s\n" |
- "\tinhibitAnyPolicyExtension:\t%s\n" |
- "\tanyPolicyOID: \t%s\n" |
- "\tinitialIsAnyPolicy: \t%s\n" |
- "\tvalidPolicyTree: \t%s\n" |
- "\tuserInitialPolicySet: \t%s\n" |
- "\tmappedUserPolicySet: \t%s\n" |
- "\tpolicyQualifiersRejected: \t%s\n" |
- "\tinitialPolMappingInhibit: \t%s\n" |
- "\tinitialExplicitPolicy: \t%s\n" |
- "\tinitialAnyPolicyInhibit: \t%s\n" |
- "\texplicitPolicy: \t%d\n" |
- "\tinhibitAnyPolicy: \t%d\n" |
- "\tpolicyMapping: \t%d\n" |
- "\tnumCerts: \t%d\n" |
- "\tcertsProcessed: \t%d\n" |
- "\tanyPolicyNodeAtBottom: \t%s\n" |
- "\tnewAnyPolicyNode: \t%s\n" |
- "\tcertPoliciesCritical: \t%s\n" |
- "\tmappedPolicyOIDs: \t%s\n" |
- "}"; |
- |
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_ToString"); |
- |
- PKIX_NULLCHECK_TWO(object, pCheckerStateString); |
- |
- PKIX_CHECK(pkix_CheckType |
- (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext), |
- PKIX_OBJECTNOTPOLICYCHECKERSTATE); |
- |
- state = (PKIX_PolicyCheckerState *)object; |
- PKIX_NULLCHECK_THREE |
- (state->certPoliciesExtension, |
- state->policyMappingsExtension, |
- state->policyConstraintsExtension); |
- PKIX_NULLCHECK_THREE |
- (state->inhibitAnyPolicyExtension, |
- state->anyPolicyOID, |
- state->userInitialPolicySet); |
- |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- /* |
- * Create TRUE, FALSE, and "NULL" PKIX_PL_Strings. But creating a |
- * PKIX_PL_String is complicated enough, it's worth checking, for |
- * each, to make sure the string is needed. |
- */ |
- initialPolicyMappingInhibit = state->initialPolicyMappingInhibit; |
- initialExplicitPolicy = state->initialExplicitPolicy; |
- initialAnyPolicyInhibit = state->initialAnyPolicyInhibit; |
- initialIsAnyPolicy = state->initialIsAnyPolicy; |
- policyQualifiersRejected = state->policyQualifiersRejected; |
- certPoliciesCritical = state->certPoliciesCritical; |
- |
- if (initialPolicyMappingInhibit || initialExplicitPolicy || |
- initialAnyPolicyInhibit || initialIsAnyPolicy || |
- policyQualifiersRejected || certPoliciesCritical) { |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, "TRUE", 0, &trueString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- } |
- if (!initialPolicyMappingInhibit || !initialExplicitPolicy || |
- !initialAnyPolicyInhibit || !initialIsAnyPolicy || |
- !policyQualifiersRejected || !certPoliciesCritical) { |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, "FALSE", 0, &falseString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- } |
- if (!(state->anyPolicyNodeAtBottom) || !(state->newAnyPolicyNode)) { |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, "(null)", 0, &nullString, plContext), |
- PKIX_STRINGCREATEFAILED); |
- } |
- |
- PKIX_TOSTRING |
- (state->certPoliciesExtension, &policiesExtOIDString, plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING |
- (state->policyMappingsExtension, |
- &policyMapOIDString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING |
- (state->policyConstraintsExtension, |
- &policyConstrOIDString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING |
- (state->inhibitAnyPolicyExtension, |
- &inhAnyPolOIDString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING(state->anyPolicyOID, &anyPolicyOIDString, plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING(state->validPolicyTree, &validPolicyTreeString, plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING |
- (state->userInitialPolicySet, |
- &userInitialPolicySetString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_TOSTRING |
- (state->mappedUserInitialPolicySet, |
- &mappedUserPolicySetString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- if (state->anyPolicyNodeAtBottom) { |
- PKIX_CHECK(pkix_SinglePolicyNode_ToString |
- (state->anyPolicyNodeAtBottom, |
- &anyAtBottomString, |
- plContext), |
- PKIX_SINGLEPOLICYNODETOSTRINGFAILED); |
- } else { |
- PKIX_INCREF(nullString); |
- anyAtBottomString = nullString; |
- } |
- |
- if (state->newAnyPolicyNode) { |
- PKIX_CHECK(pkix_SinglePolicyNode_ToString |
- (state->newAnyPolicyNode, |
- &newAnyPolicyString, |
- plContext), |
- PKIX_SINGLEPOLICYNODETOSTRINGFAILED); |
- } else { |
- PKIX_INCREF(nullString); |
- newAnyPolicyString = nullString; |
- } |
- |
- PKIX_TOSTRING |
- (state->mappedPolicyOIDs, |
- &mappedPolicyOIDsString, |
- plContext, |
- PKIX_OBJECTTOSTRINGFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Sprintf |
- (&resultString, |
- plContext, |
- formatString, |
- policiesExtOIDString, |
- policyMapOIDString, |
- policyConstrOIDString, |
- inhAnyPolOIDString, |
- anyPolicyOIDString, |
- initialIsAnyPolicy?trueString:falseString, |
- validPolicyTreeString, |
- userInitialPolicySetString, |
- mappedUserPolicySetString, |
- policyQualifiersRejected?trueString:falseString, |
- initialPolicyMappingInhibit?trueString:falseString, |
- initialExplicitPolicy?trueString:falseString, |
- initialAnyPolicyInhibit?trueString:falseString, |
- state->explicitPolicy, |
- state->inhibitAnyPolicy, |
- state->policyMapping, |
- state->numCerts, |
- state->certsProcessed, |
- anyAtBottomString, |
- newAnyPolicyString, |
- certPoliciesCritical?trueString:falseString, |
- mappedPolicyOIDsString), |
- PKIX_SPRINTFFAILED); |
- |
- *pCheckerStateString = resultString; |
- |
-cleanup: |
- PKIX_DECREF(policiesExtOIDString); |
- PKIX_DECREF(policyMapOIDString); |
- PKIX_DECREF(policyConstrOIDString); |
- PKIX_DECREF(inhAnyPolOIDString); |
- PKIX_DECREF(anyPolicyOIDString); |
- PKIX_DECREF(validPolicyTreeString); |
- PKIX_DECREF(userInitialPolicySetString); |
- PKIX_DECREF(mappedUserPolicySetString); |
- PKIX_DECREF(anyAtBottomString); |
- PKIX_DECREF(newAnyPolicyString); |
- PKIX_DECREF(mappedPolicyOIDsString); |
- PKIX_DECREF(formatString); |
- PKIX_DECREF(trueString); |
- PKIX_DECREF(falseString); |
- PKIX_DECREF(nullString); |
- |
- PKIX_RETURN(CERTPOLICYCHECKERSTATE); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyCheckerState_RegisterSelf |
- * DESCRIPTION: |
- * |
- * Registers PKIX_POLICYCHECKERSTATE_TYPE and its related functions |
- * with systemClasses[] |
- * |
- * PARAMETERS: |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe - for performance and complexity reasons |
- * |
- * 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_PolicyCheckerState_RegisterSelf(void *plContext) |
-{ |
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
- pkix_ClassTable_Entry entry; |
- |
- PKIX_ENTER |
- (CERTPOLICYCHECKERSTATE, |
- "pkix_PolicyCheckerState_RegisterSelf"); |
- |
- entry.description = "PolicyCheckerState"; |
- entry.objCounter = 0; |
- entry.typeObjectSize = sizeof(PKIX_PolicyCheckerState); |
- entry.destructor = pkix_PolicyCheckerState_Destroy; |
- entry.equalsFunction = NULL; |
- entry.hashcodeFunction = NULL; |
- entry.toStringFunction = pkix_PolicyCheckerState_ToString; |
- entry.comparator = NULL; |
- entry.duplicateFunction = NULL; |
- |
- systemClasses[PKIX_CERTPOLICYCHECKERSTATE_TYPE] = entry; |
- |
- PKIX_RETURN(CERTPOLICYCHECKERSTATE); |
-} |
- |
-/* |
- * FUNCTION:pkix_PolicyCheckerState_Create |
- * DESCRIPTION: |
- * |
- * Creates a PolicyCheckerState Object, using the List pointed to |
- * by "initialPolicies" for the user-initial-policy-set, the Boolean value |
- * of "policyQualifiersRejected" for the policyQualifiersRejected parameter, |
- * the Boolean value of "initialPolicyMappingInhibit" for the |
- * inhibitPolicyMappings parameter, the Boolean value of |
- * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the |
- * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy |
- * parameter, and the UInt32 value of "numCerts" as the number of |
- * certificates in the chain; and stores the Object at "pCheckerState". |
- * |
- * PARAMETERS: |
- * "initialPolicies" |
- * Address of List of OIDs comprising the user-initial-policy-set; the List |
- * may be empty, but must be non-NULL |
- * "policyQualifiersRejected" |
- * Boolean value of the policyQualifiersRejected parameter |
- * "initialPolicyMappingInhibit" |
- * Boolean value of the inhibitPolicyMappings parameter |
- * "initialExplicitPolicy" |
- * Boolean value of the initialExplicitPolicy parameter |
- * "initialAnyPolicyInhibit" |
- * Boolean value of the inhibitAnyPolicy parameter |
- * "numCerts" |
- * Number of certificates in the chain to be validated |
- * "pCheckerState" |
- * Address where PolicyCheckerState 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 CertPolicyCheckerState Error if the functions fails in a |
- * non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyCheckerState_Create( |
- PKIX_List *initialPolicies, |
- PKIX_Boolean policyQualifiersRejected, |
- PKIX_Boolean initialPolicyMappingInhibit, |
- PKIX_Boolean initialExplicitPolicy, |
- PKIX_Boolean initialAnyPolicyInhibit, |
- PKIX_UInt32 numCerts, |
- PKIX_PolicyCheckerState **pCheckerState, |
- void *plContext) |
-{ |
- PKIX_PolicyCheckerState *checkerState = NULL; |
- PKIX_PolicyNode *policyNode = NULL; |
- PKIX_List *anyPolicyList = NULL; |
- PKIX_Boolean initialPoliciesIsEmpty = PKIX_FALSE; |
- |
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Create"); |
- PKIX_NULLCHECK_TWO(initialPolicies, pCheckerState); |
- |
- PKIX_CHECK(PKIX_PL_Object_Alloc |
- (PKIX_CERTPOLICYCHECKERSTATE_TYPE, |
- sizeof (PKIX_PolicyCheckerState), |
- (PKIX_PL_Object **)&checkerState, |
- plContext), |
- PKIX_COULDNOTCREATEPOLICYCHECKERSTATEOBJECT); |
- |
- /* Create constant PKIX_PL_OIDs: */ |
- |
- PKIX_CHECK(PKIX_PL_OID_Create |
- (PKIX_CERTIFICATEPOLICIES_OID, |
- &(checkerState->certPoliciesExtension), |
- plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_PL_OID_Create |
- (PKIX_POLICYMAPPINGS_OID, |
- &(checkerState->policyMappingsExtension), |
- plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_PL_OID_Create |
- (PKIX_POLICYCONSTRAINTS_OID, |
- &(checkerState->policyConstraintsExtension), |
- plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_PL_OID_Create |
- (PKIX_INHIBITANYPOLICY_OID, |
- &(checkerState->inhibitAnyPolicyExtension), |
- plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_PL_OID_Create |
- (PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID, |
- &(checkerState->anyPolicyOID), |
- plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* Create an initial policy set from argument supplied */ |
- PKIX_INCREF(initialPolicies); |
- checkerState->userInitialPolicySet = initialPolicies; |
- PKIX_INCREF(initialPolicies); |
- checkerState->mappedUserInitialPolicySet = initialPolicies; |
- |
- PKIX_CHECK(PKIX_List_IsEmpty |
- (initialPolicies, |
- &initialPoliciesIsEmpty, |
- plContext), |
- PKIX_LISTISEMPTYFAILED); |
- if (initialPoliciesIsEmpty) { |
- checkerState->initialIsAnyPolicy = PKIX_TRUE; |
- } else { |
- PKIX_CHECK(pkix_List_Contains |
- (initialPolicies, |
- (PKIX_PL_Object *)(checkerState->anyPolicyOID), |
- &(checkerState->initialIsAnyPolicy), |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- } |
- |
- checkerState->policyQualifiersRejected = |
- policyQualifiersRejected; |
- checkerState->initialExplicitPolicy = initialExplicitPolicy; |
- checkerState->explicitPolicy = |
- (initialExplicitPolicy? 0: numCerts + 1); |
- checkerState->initialAnyPolicyInhibit = initialAnyPolicyInhibit; |
- checkerState->inhibitAnyPolicy = |
- (initialAnyPolicyInhibit? 0: numCerts + 1); |
- checkerState->initialPolicyMappingInhibit = initialPolicyMappingInhibit; |
- checkerState->policyMapping = |
- (initialPolicyMappingInhibit? 0: numCerts + 1); |
- ; |
- checkerState->numCerts = numCerts; |
- checkerState->certsProcessed = 0; |
- checkerState->certPoliciesCritical = PKIX_FALSE; |
- |
- /* Create a valid_policy_tree as in RFC3280 6.1.2(a) */ |
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton |
- ((PKIX_PL_Object *)(checkerState->anyPolicyOID), |
- PKIX_TRUE, |
- &anyPolicyList, |
- plContext), |
- PKIX_POLICYCHECKERMAKESINGLETONFAILED); |
- |
- PKIX_CHECK(pkix_PolicyNode_Create |
- (checkerState->anyPolicyOID, /* validPolicy */ |
- NULL, /* qualifier set */ |
- PKIX_FALSE, /* criticality */ |
- anyPolicyList, /* expectedPolicySet */ |
- &policyNode, |
- plContext), |
- PKIX_POLICYNODECREATEFAILED); |
- checkerState->validPolicyTree = policyNode; |
- |
- /* |
- * Since the initial validPolicyTree specifies |
- * ANY_POLICY, begin with a pointer to the root node. |
- */ |
- PKIX_INCREF(policyNode); |
- checkerState->anyPolicyNodeAtBottom = policyNode; |
- |
- checkerState->newAnyPolicyNode = NULL; |
- |
- checkerState->mappedPolicyOIDs = NULL; |
- |
- *pCheckerState = checkerState; |
- checkerState = NULL; |
- |
-cleanup: |
- |
- PKIX_DECREF(checkerState); |
- |
- PKIX_DECREF(anyPolicyList); |
- |
- PKIX_RETURN(CERTPOLICYCHECKERSTATE); |
-} |
- |
-/* --Private-PolicyChecker-Functions--------------------------------------- */ |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_MapContains |
- * DESCRIPTION: |
- * |
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to |
- * determine whether the OID pointed to by "policy" is among the |
- * issuerDomainPolicies or subjectDomainPolicies of "certPolicyMaps", and |
- * stores the result in "pFound". |
- * |
- * This function is intended to allow an efficient check that the proscription |
- * against anyPolicy being mapped, described in RFC3280 Section 6.1.4(a), is |
- * not violated. |
- * |
- * PARAMETERS: |
- * "certPolicyMaps" |
- * Address of List of CertPolicyMaps to be searched. May be empty, but |
- * must be non-NULL |
- * "policy" |
- * Address of OID to be checked for. Must be non-NULL |
- * "pFound" |
- * Address where the result of the search 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 CertChainChecker 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_PolicyChecker_MapContains( |
- PKIX_List *certPolicyMaps, |
- PKIX_PL_OID *policy, |
- PKIX_Boolean *pFound, |
- void *plContext) |
-{ |
- PKIX_PL_CertPolicyMap *map = NULL; |
- PKIX_UInt32 numEntries = 0; |
- PKIX_UInt32 index = 0; |
- PKIX_Boolean match = PKIX_FALSE; |
- PKIX_PL_OID *issuerDomainPolicy = NULL; |
- PKIX_PL_OID *subjectDomainPolicy = NULL; |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MapContains"); |
- PKIX_NULLCHECK_THREE(certPolicyMaps, policy, pFound); |
- |
- PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (index = 0; (!match) && (index < numEntries); index++) { |
- PKIX_CHECK(PKIX_List_GetItem |
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(map); |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy |
- (map, &issuerDomainPolicy, plContext), |
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); |
- |
- PKIX_EQUALS |
- (policy, issuerDomainPolicy, &match, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- |
- if (!match) { |
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy |
- (map, &subjectDomainPolicy, plContext), |
- PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED); |
- |
- PKIX_EQUALS |
- (policy, subjectDomainPolicy, &match, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- } |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- PKIX_DECREF(subjectDomainPolicy); |
- } |
- |
- *pFound = match; |
- |
-cleanup: |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- PKIX_DECREF(subjectDomainPolicy); |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_MapGetSubjectDomainPolicies |
- * DESCRIPTION: |
- * |
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to create |
- * a list of all SubjectDomainPolicies for which the IssuerDomainPolicy is the |
- * policy pointed to by "policy", and stores the result in |
- * "pSubjectDomainPolicies". |
- * |
- * If the List of CertPolicyMaps provided in "certPolicyMaps" is NULL, the |
- * resulting List will be NULL. If there are CertPolicyMaps, but none that |
- * include "policy" as an IssuerDomainPolicy, the returned List pointer will |
- * be NULL. Otherwise, the returned List will contain the SubjectDomainPolicies |
- * of all CertPolicyMaps for which "policy" is the IssuerDomainPolicy. If a |
- * List is returned it will be immutable. |
- * |
- * PARAMETERS: |
- * "certPolicyMaps" |
- * Address of List of CertPolicyMaps to be searched. May be empty or NULL. |
- * "policy" |
- * Address of OID to be checked for. Must be non-NULL |
- * "pSubjectDomainPolicies" |
- * Address where the result of the search 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 CertChainChecker 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_PolicyChecker_MapGetSubjectDomainPolicies( |
- PKIX_List *certPolicyMaps, |
- PKIX_PL_OID *policy, |
- PKIX_List **pSubjectDomainPolicies, |
- void *plContext) |
-{ |
- PKIX_PL_CertPolicyMap *map = NULL; |
- PKIX_List *subjectList = NULL; |
- PKIX_UInt32 numEntries = 0; |
- PKIX_UInt32 index = 0; |
- PKIX_Boolean match = PKIX_FALSE; |
- PKIX_PL_OID *issuerDomainPolicy = NULL; |
- PKIX_PL_OID *subjectDomainPolicy = NULL; |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, |
- "pkix_PolicyChecker_MapGetSubjectDomainPolicies"); |
- PKIX_NULLCHECK_TWO(policy, pSubjectDomainPolicies); |
- |
- if (certPolicyMaps) { |
- PKIX_CHECK(PKIX_List_GetLength |
- (certPolicyMaps, |
- &numEntries, |
- plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- } |
- |
- for (index = 0; index < numEntries; index++) { |
- PKIX_CHECK(PKIX_List_GetItem |
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(map); |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy |
- (map, &issuerDomainPolicy, plContext), |
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); |
- |
- PKIX_EQUALS |
- (policy, issuerDomainPolicy, &match, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- |
- if (match) { |
- if (!subjectList) { |
- PKIX_CHECK(PKIX_List_Create(&subjectList, plContext), |
- PKIX_LISTCREATEFAILED); |
- } |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy |
- (map, &subjectDomainPolicy, plContext), |
- PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (subjectList, |
- (PKIX_PL_Object *)subjectDomainPolicy, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- } |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- PKIX_DECREF(subjectDomainPolicy); |
- } |
- |
- if (subjectList) { |
- PKIX_CHECK(PKIX_List_SetImmutable(subjectList, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- } |
- |
- *pSubjectDomainPolicies = subjectList; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(subjectList); |
- } |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- PKIX_DECREF(subjectDomainPolicy); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_MapGetMappedPolicies |
- * DESCRIPTION: |
- * |
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps" to create a |
- * List of all IssuerDomainPolicies, and stores the result in |
- * "pMappedPolicies". |
- * |
- * The caller may not rely on the IssuerDomainPolicies to be in any particular |
- * order. IssuerDomainPolicies that appear in more than one CertPolicyMap will |
- * only appear once in "pMappedPolicies". If "certPolicyMaps" is empty the |
- * result will be an empty List. The created List is mutable. |
- * |
- * PARAMETERS: |
- * "certPolicyMaps" |
- * Address of List of CertPolicyMaps to be searched. May be empty, but |
- * must be non-NULL. |
- * "pMappedPolicies" |
- * Address where the result 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 CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-PKIX_Error * |
-pkix_PolicyChecker_MapGetMappedPolicies( |
- PKIX_List *certPolicyMaps, |
- PKIX_List **pMappedPolicies, |
- void *plContext) |
-{ |
- PKIX_PL_CertPolicyMap *map = NULL; |
- PKIX_List *mappedList = NULL; |
- PKIX_UInt32 numEntries = 0; |
- PKIX_UInt32 index = 0; |
- PKIX_Boolean isContained = PKIX_FALSE; |
- PKIX_PL_OID *issuerDomainPolicy = NULL; |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, "pkix_PolicyChecker_MapGetMappedPolicies"); |
- PKIX_NULLCHECK_TWO(certPolicyMaps, pMappedPolicies); |
- |
- PKIX_CHECK(PKIX_List_Create(&mappedList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (index = 0; index < numEntries; index++) { |
- PKIX_CHECK(PKIX_List_GetItem |
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(map); |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy |
- (map, &issuerDomainPolicy, plContext), |
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); |
- |
- PKIX_CHECK(pkix_List_Contains |
- (mappedList, |
- (PKIX_PL_Object *)issuerDomainPolicy, |
- &isContained, |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- |
- if (isContained == PKIX_FALSE) { |
- PKIX_CHECK(PKIX_List_AppendItem |
- (mappedList, |
- (PKIX_PL_Object *)issuerDomainPolicy, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- } |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- } |
- |
- *pMappedPolicies = mappedList; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(mappedList); |
- } |
- |
- PKIX_DECREF(map); |
- PKIX_DECREF(issuerDomainPolicy); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_MakeMutableCopy |
- * DESCRIPTION: |
- * |
- * Creates a mutable copy of the List pointed to by "list", which may or may |
- * not be immutable, and stores the address at "pMutableCopy". |
- * |
- * PARAMETERS: |
- * "list" |
- * Address of List to be copied. Must be non-NULL. |
- * "pMutableCopy" |
- * Address where mutable copy 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 CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_MakeMutableCopy( |
- PKIX_List *list, |
- PKIX_List **pMutableCopy, |
- void *plContext) |
-{ |
- PKIX_List *newList = NULL; |
- PKIX_UInt32 listLen = 0; |
- PKIX_UInt32 listIx = 0; |
- PKIX_PL_Object *object = NULL; |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeMutableCopy"); |
- PKIX_NULLCHECK_TWO(list, pMutableCopy); |
- |
- PKIX_CHECK(PKIX_List_Create(&newList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength(list, &listLen, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (listIx = 0; listIx < listLen; listIx++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem(list, listIx, &object, plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem(newList, object, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- PKIX_DECREF(object); |
- } |
- |
- *pMutableCopy = newList; |
- newList = NULL; |
- |
-cleanup: |
- PKIX_DECREF(newList); |
- PKIX_DECREF(object); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_MakeSingleton |
- * DESCRIPTION: |
- * |
- * Creates a new List containing the Object pointed to by "listItem", using |
- * the Boolean value of "immutability" to determine whether to set the List |
- * immutable, and stores the address at "pList". |
- * |
- * PARAMETERS: |
- * "listItem" |
- * Address of Object to be inserted into the new List. Must be non-NULL. |
- * "immutability" |
- * Boolean value indicating whether new List is to be immutable |
- * "pList" |
- * Address where List 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 CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_MakeSingleton( |
- PKIX_PL_Object *listItem, |
- PKIX_Boolean immutability, |
- PKIX_List **pList, |
- void *plContext) |
-{ |
- PKIX_List *newList = NULL; |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeSingleton"); |
- PKIX_NULLCHECK_TWO(listItem, pList); |
- |
- PKIX_CHECK(PKIX_List_Create(&newList, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_AppendItem |
- (newList, (PKIX_PL_Object *)listItem, plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- |
- if (immutability) { |
- PKIX_CHECK(PKIX_List_SetImmutable(newList, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- } |
- |
- *pList = newList; |
- |
-cleanup: |
- if (PKIX_ERROR_RECEIVED) { |
- PKIX_DECREF(newList); |
- } |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_Spawn |
- * DESCRIPTION: |
- * |
- * Creates a new childNode for the parent pointed to by "parent", using |
- * the OID pointed to by "policyOID", the List of CertPolicyQualifiers |
- * pointed to by "qualifiers", the List of OIDs pointed to by |
- * "subjectDomainPolicies", and the PolicyCheckerState pointed to by |
- * "state". The new node will be added to "parent". |
- * |
- * The validPolicy of the new node is set from the OID pointed to by |
- * "policyOID". The policy qualifiers for the new node is set from the |
- * List of qualifiers pointed to by "qualifiers", and may be NULL or |
- * empty if the argument provided was NULL or empty. The criticality is |
- * set according to the criticality obtained from the PolicyCheckerState. |
- * If "subjectDomainPolicies" is NULL, the expectedPolicySet of the |
- * child is set to contain the same policy as the validPolicy. If |
- * "subjectDomainPolicies" is not NULL, it is used as the value for |
- * the expectedPolicySet. |
- * |
- * The PolicyCheckerState also contains a constant, anyPolicy, which is |
- * compared to "policyOID". If they match, the address of the childNode |
- * is saved in the state's newAnyPolicyNode. |
- * |
- * PARAMETERS: |
- * "parent" |
- * Address of PolicyNode to which the child will be linked. Must be |
- * non-NULL. |
- * "policyOID" |
- * Address of OID of the new child's validPolicy and also, if |
- * subjectDomainPolicies is NULL, of the new child's expectedPolicySet. |
- * Must be non-NULL. |
- * "qualifiers" |
- * Address of List of CertPolicyQualifiers. May be NULL or empty. |
- * "subjectDomainPolicies" |
- * Address of List of OIDs indicating the policies to which "policy" is |
- * mapped. May be empty or NULL. |
- * "state" |
- * Address of the current PKIX_PolicyCheckerState. Must be non-NULL.. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_Spawn( |
- PKIX_PolicyNode *parent, |
- PKIX_PL_OID *policyOID, |
- PKIX_List *qualifiers, /* CertPolicyQualifiers */ |
- PKIX_List *subjectDomainPolicies, |
- PKIX_PolicyCheckerState *state, |
- void *plContext) |
-{ |
- PKIX_List *expectedSet = NULL; /* OIDs */ |
- PKIX_PolicyNode *childNode = NULL; |
- PKIX_Boolean match = PKIX_FALSE; |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Spawn"); |
- PKIX_NULLCHECK_THREE(policyOID, parent, state); |
- |
- if (subjectDomainPolicies) { |
- |
- PKIX_INCREF(subjectDomainPolicies); |
- expectedSet = subjectDomainPolicies; |
- |
- } else { |
- /* Create the child's ExpectedPolicy Set */ |
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton |
- ((PKIX_PL_Object *)policyOID, |
- PKIX_TRUE, /* make expectedPolicySet immutable */ |
- &expectedSet, |
- plContext), |
- PKIX_POLICYCHECKERMAKESINGLETONFAILED); |
- } |
- |
- PKIX_CHECK(pkix_PolicyNode_Create |
- (policyOID, |
- qualifiers, |
- state->certPoliciesCritical, |
- expectedSet, |
- &childNode, |
- plContext), |
- PKIX_POLICYNODECREATEFAILED); |
- |
- /* |
- * If we had a non-empty mapping, we know the new node could not |
- * have been created with a validPolicy of anyPolicy. Otherwise, |
- * check whether we just created a new node with anyPolicy, because |
- * in that case we want to save the child pointer in newAnyPolicyNode. |
- */ |
- if (!subjectDomainPolicies) { |
- PKIX_EQUALS(policyOID, state->anyPolicyOID, &match, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- |
- if (match) { |
- PKIX_DECREF(state->newAnyPolicyNode); |
- PKIX_INCREF(childNode); |
- state->newAnyPolicyNode = childNode; |
- } |
- } |
- |
- PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, childNode, plContext), |
- PKIX_POLICYNODEADDTOPARENTFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
-cleanup: |
- PKIX_DECREF(childNode); |
- PKIX_DECREF(expectedSet); |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_CheckPolicyRecursive |
- * DESCRIPTION: |
- * |
- * Performs policy processing for the policy whose OID is pointed to by |
- * "policyOID" and whose List of CertPolicyQualifiers is pointed to by |
- * "policyQualifiers", using the List of policy OIDs pointed to by |
- * "subjectDomainPolicies" and the PolicyNode pointed to by "currentNode", |
- * in accordance with the current PolicyCheckerState pointed to by "state", |
- * and setting "pChildNodeCreated" to TRUE if a new childNode is created. |
- * Note: "pChildNodeCreated" is not set to FALSE if no childNode is created. |
- * The intent of the design is that the caller can set a variable to FALSE |
- * initially, prior to a recursive set of calls. At the end, the variable |
- * can be tested to see whether *any* of the calls created a child node. |
- * |
- * If the currentNode is not at the bottom of the tree, this function |
- * calls itself recursively for each child of currentNode. At the bottom of |
- * the tree, it creates new child nodes as appropriate. This function will |
- * never be called with policy = anyPolicy. |
- * |
- * This function implements the processing described in RFC3280 |
- * Section 6.1.3(d)(1)(i). |
- * |
- * PARAMETERS: |
- * "policyOID" |
- * Address of OID of the policy to be checked for. Must be non-NULL. |
- * "policyQualifiers" |
- * Address of List of CertPolicyQualifiers of the policy to be checked for. |
- * May be empty or NULL. |
- * "subjectDomainPolicies" |
- * Address of List of OIDs indicating the policies to which "policy" is |
- * mapped. May be empty or NULL. |
- * "currentNode" |
- * Address of PolicyNode whose descendants will be checked, if not at the |
- * bottom of the tree; or whose expectedPolicySet will be compared to |
- * "policy", if at the bottom. Must be non-NULL. |
- * "state" |
- * Address of PolicyCheckerState of the current PolicyChecker. Must be |
- * non-NULL. |
- * "pChildNodeCreated" |
- * Address of the Boolean that will be set TRUE if this function |
- * creates a child node. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_CheckPolicyRecursive( |
- PKIX_PL_OID *policyOID, |
- PKIX_List *policyQualifiers, |
- PKIX_List *subjectDomainPolicies, |
- PKIX_PolicyNode *currentNode, |
- PKIX_PolicyCheckerState *state, |
- PKIX_Boolean *pChildNodeCreated, |
- void *plContext) |
-{ |
- PKIX_UInt32 depth = 0; |
- PKIX_UInt32 numChildren = 0; |
- PKIX_UInt32 childIx = 0; |
- PKIX_Boolean isIncluded = PKIX_FALSE; |
- PKIX_List *children = NULL; /* PolicyNodes */ |
- PKIX_PolicyNode *childNode = NULL; |
- PKIX_List *expectedPolicies = NULL; /* OIDs */ |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, |
- "pkix_PolicyChecker_CheckPolicyRecursive"); |
- PKIX_NULLCHECK_FOUR(policyOID, currentNode, state, pChildNodeCreated); |
- |
- /* if not at the bottom of the tree */ |
- PKIX_CHECK(PKIX_PolicyNode_GetDepth |
- (currentNode, &depth, plContext), |
- PKIX_POLICYNODEGETDEPTHFAILED); |
- |
- if (depth < (state->certsProcessed)) { |
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable |
- (currentNode, &children, plContext), |
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); |
- |
- if (children) { |
- PKIX_CHECK(PKIX_List_GetLength |
- (children, &numChildren, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- } |
- |
- for (childIx = 0; childIx < numChildren; childIx++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (children, |
- childIx, |
- (PKIX_PL_Object **)&childNode, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive |
- (policyOID, |
- policyQualifiers, |
- subjectDomainPolicies, |
- childNode, |
- state, |
- pChildNodeCreated, |
- plContext), |
- PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED); |
- |
- PKIX_DECREF(childNode); |
- } |
- } else { /* if at the bottom of the tree */ |
- |
- /* Check whether policy is in this node's expectedPolicySet */ |
- PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies |
- (currentNode, &expectedPolicies, plContext), |
- PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED); |
- |
- PKIX_NULLCHECK_ONE(expectedPolicies); |
- |
- PKIX_CHECK(pkix_List_Contains |
- (expectedPolicies, |
- (PKIX_PL_Object *)policyOID, |
- &isIncluded, |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- |
- if (isIncluded) { |
- PKIX_CHECK(pkix_PolicyChecker_Spawn |
- (currentNode, |
- policyOID, |
- policyQualifiers, |
- subjectDomainPolicies, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERSPAWNFAILED); |
- |
- *pChildNodeCreated = PKIX_TRUE; |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(children); |
- PKIX_DECREF(childNode); |
- PKIX_DECREF(expectedPolicies); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_CheckPolicy |
- * DESCRIPTION: |
- * |
- * Performs the non-recursive portion of the policy processing for the policy |
- * whose OID is pointed to by "policyOID" and whose List of |
- * CertPolicyQualifiers is pointed to by "policyQualifiers", for the |
- * Certificate pointed to by "cert" with the List of CertPolicyMaps pointed |
- * to by "maps", in accordance with the current PolicyCheckerState pointed |
- * to by "state". |
- * |
- * This function implements the processing described in RFC3280 |
- * Section 6.1.3(d)(1)(i). |
- * |
- * PARAMETERS: |
- * "policyOID" |
- * Address of OID of the policy to be checked for. Must be non-NULL. |
- * "policyQualifiers" |
- * Address of List of CertPolicyQualifiers of the policy to be checked for. |
- * May be empty or NULL. |
- * "cert" |
- * Address of the current certificate. Must be non-NULL. |
- * "maps" |
- * Address of List of CertPolicyMaps for the current certificate |
- * "state" |
- * Address of PolicyCheckerState of the current PolicyChecker. Must be |
- * non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_CheckPolicy( |
- PKIX_PL_OID *policyOID, |
- PKIX_List *policyQualifiers, |
- PKIX_PL_Cert *cert, |
- PKIX_List *maps, |
- PKIX_PolicyCheckerState *state, |
- void *plContext) |
-{ |
- PKIX_Boolean childNodeCreated = PKIX_FALSE; |
- PKIX_Boolean okToSpawn = PKIX_FALSE; |
- PKIX_Boolean found = PKIX_FALSE; |
- PKIX_List *subjectDomainPolicies = NULL; |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckPolicy"); |
- PKIX_NULLCHECK_THREE(policyOID, cert, state); |
- |
- /* |
- * If this is not the last certificate, get the set of |
- * subjectDomainPolicies that "policy" maps to, according to the |
- * current cert's policy mapping extension. That set will be NULL |
- * if the current cert does not have a policy mapping extension, |
- * or if the current policy is not mapped. |
- */ |
- if (state->certsProcessed != (state->numCerts - 1)) { |
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies |
- (maps, policyOID, &subjectDomainPolicies, plContext), |
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); |
- } |
- |
- /* |
- * Section 6.1.4(b)(2) tells us that if policyMapping is zero, we |
- * will have to delete any nodes created with validPolicies equal to |
- * policies that appear as issuerDomainPolicies in a policy mapping |
- * extension. Let's avoid creating any such nodes. |
- */ |
- if ((state->policyMapping) == 0) { |
- if (subjectDomainPolicies) { |
- goto cleanup; |
- } |
- } |
- |
- PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive |
- (policyOID, |
- policyQualifiers, |
- subjectDomainPolicies, |
- state->validPolicyTree, |
- state, |
- &childNodeCreated, |
- plContext), |
- PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED); |
- |
- if (!childNodeCreated) { |
- /* |
- * Section 6.1.3(d)(1)(ii) |
- * There was no match. If there was a node at |
- * depth i-1 with valid policy anyPolicy, |
- * generate a node subordinate to that. |
- * |
- * But that means this created node would be in |
- * the valid-policy-node-set, and will be |
- * pruned in 6.1.5(g)(iii)(2) unless it is in |
- * the user-initial-policy-set or the user- |
- * initial-policy-set is {anyPolicy}. So check, |
- * and don't create it if it will be pruned. |
- */ |
- if (state->anyPolicyNodeAtBottom) { |
- if (state->initialIsAnyPolicy) { |
- okToSpawn = PKIX_TRUE; |
- } else { |
- PKIX_CHECK(pkix_List_Contains |
- (state->mappedUserInitialPolicySet, |
- (PKIX_PL_Object *)policyOID, |
- &okToSpawn, |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- } |
- if (okToSpawn) { |
- PKIX_CHECK(pkix_PolicyChecker_Spawn |
- (state->anyPolicyNodeAtBottom, |
- policyOID, |
- policyQualifiers, |
- subjectDomainPolicies, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERSPAWNFAILED); |
- childNodeCreated = PKIX_TRUE; |
- } |
- } |
- } |
- |
- if (childNodeCreated) { |
- /* |
- * If this policy had qualifiers, and the certificate policies |
- * extension was marked critical, and the user cannot deal with |
- * policy qualifiers, throw an error. |
- */ |
- if (policyQualifiers && |
- state->certPoliciesCritical && |
- state->policyQualifiersRejected) { |
- PKIX_ERROR |
- (PKIX_QUALIFIERSINCRITICALCERTIFICATEPOLICYEXTENSION); |
- } |
- /* |
- * If the policy we just propagated was in the list of mapped |
- * policies, remove it from the list. That list is used, at the |
- * end, to determine policies that have not been propagated. |
- */ |
- if (state->mappedPolicyOIDs) { |
- PKIX_CHECK(pkix_List_Contains |
- (state->mappedPolicyOIDs, |
- (PKIX_PL_Object *)policyOID, |
- &found, |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- if (found) { |
- PKIX_CHECK(pkix_List_Remove |
- (state->mappedPolicyOIDs, |
- (PKIX_PL_Object *)policyOID, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- } |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(subjectDomainPolicies); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_CheckAny |
- * DESCRIPTION: |
- * Performs the creation of PolicyNodes, for the PolicyNode pointed to by |
- * "currentNode" and PolicyNodes subordinate to it, using the List of |
- * qualifiers pointed to by "qualsOfAny", in accordance with the current |
- * certificate's PolicyMaps pointed to by "policyMaps" and the current |
- * PolicyCheckerState pointed to by "state". |
- * |
- * If the currentNode is not just above the bottom of the validPolicyTree, this |
- * function calls itself recursively for each child of currentNode. At the |
- * level just above the bottom, for each policy in the currentNode's |
- * expectedPolicySet not already present in a child node, it creates a new |
- * child node. The validPolicy of the child created, and its expectedPolicySet, |
- * will be the policy from the currentNode's expectedPolicySet. The policy |
- * qualifiers will be the qualifiers from the current certificate's anyPolicy, |
- * the "qualsOfAny" parameter. If the currentNode's expectedSet includes |
- * anyPolicy, a childNode will be created with a policy of anyPolicy. This is |
- * the only way such a node can be created. |
- * |
- * This function is called only when anyPolicy is one of the current |
- * certificate's policies. This function implements the processing described |
- * in RFC3280 Section 6.1.3(d)(2). |
- * |
- * PARAMETERS: |
- * "currentNode" |
- * Address of PolicyNode whose descendants will be checked, if not at the |
- * bottom of the tree; or whose expectedPolicySet will be compared to those |
- * in "alreadyPresent", if at the bottom. Must be non-NULL. |
- * "qualsOfAny" |
- * Address of List of qualifiers of the anyPolicy in the current |
- * certificate. May be empty or NULL. |
- * "policyMaps" |
- * Address of the List of PolicyMaps of the current certificate. May be |
- * empty or NULL. |
- * "state" |
- * Address of the current state of the PKIX_PolicyChecker. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_CheckAny( |
- PKIX_PolicyNode *currentNode, |
- PKIX_List *qualsOfAny, /* CertPolicyQualifiers */ |
- PKIX_List *policyMaps, /* CertPolicyMaps */ |
- PKIX_PolicyCheckerState *state, |
- void *plContext) |
-{ |
- PKIX_UInt32 depth = 0; |
- PKIX_UInt32 numChildren = 0; |
- PKIX_UInt32 childIx = 0; |
- PKIX_UInt32 numPolicies = 0; |
- PKIX_UInt32 polx = 0; |
- PKIX_Boolean isIncluded = PKIX_FALSE; |
- PKIX_List *children = NULL; /* PolicyNodes */ |
- PKIX_PolicyNode *childNode = NULL; |
- PKIX_List *expectedPolicies = NULL; /* OIDs */ |
- PKIX_PL_OID *policyOID = NULL; |
- PKIX_PL_OID *childPolicy = NULL; |
- PKIX_List *subjectDomainPolicies = NULL; /* OIDs */ |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckAny"); |
- PKIX_NULLCHECK_TWO(currentNode, state); |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetDepth |
- (currentNode, &depth, plContext), |
- PKIX_POLICYNODEGETDEPTHFAILED); |
- |
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable |
- (currentNode, &children, plContext), |
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); |
- |
- if (children) { |
- PKIX_CHECK(PKIX_List_GetLength |
- (children, &numChildren, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- } |
- |
- if (depth < (state->certsProcessed)) { |
- for (childIx = 0; childIx < numChildren; childIx++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (children, |
- childIx, |
- (PKIX_PL_Object **)&childNode, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(childNode); |
- PKIX_CHECK(pkix_PolicyChecker_CheckAny |
- (childNode, |
- qualsOfAny, |
- policyMaps, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERCHECKANYFAILED); |
- |
- PKIX_DECREF(childNode); |
- } |
- } else { /* if at the bottom of the tree */ |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies |
- (currentNode, &expectedPolicies, plContext), |
- PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED); |
- |
- /* Expected Policy Set is not allowed to be NULL */ |
- PKIX_NULLCHECK_ONE(expectedPolicies); |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (expectedPolicies, &numPolicies, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (polx = 0; polx < numPolicies; polx++) { |
- PKIX_CHECK(PKIX_List_GetItem |
- (expectedPolicies, |
- polx, |
- (PKIX_PL_Object **)&policyOID, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(policyOID); |
- |
- isIncluded = PKIX_FALSE; |
- |
- for (childIx = 0; |
- (!isIncluded && (childIx < numChildren)); |
- childIx++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (children, |
- childIx, |
- (PKIX_PL_Object **)&childNode, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_NULLCHECK_ONE(childNode); |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy |
- (childNode, &childPolicy, plContext), |
- PKIX_POLICYNODEGETVALIDPOLICYFAILED); |
- |
- PKIX_NULLCHECK_ONE(childPolicy); |
- |
- PKIX_EQUALS(policyOID, childPolicy, &isIncluded, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- |
- PKIX_DECREF(childNode); |
- PKIX_DECREF(childPolicy); |
- } |
- |
- if (!isIncluded) { |
- if (policyMaps) { |
- PKIX_CHECK |
- (pkix_PolicyChecker_MapGetSubjectDomainPolicies |
- (policyMaps, |
- policyOID, |
- &subjectDomainPolicies, |
- plContext), |
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); |
- } |
- PKIX_CHECK(pkix_PolicyChecker_Spawn |
- (currentNode, |
- policyOID, |
- qualsOfAny, |
- subjectDomainPolicies, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERSPAWNFAILED); |
- PKIX_DECREF(subjectDomainPolicies); |
- } |
- |
- PKIX_DECREF(policyOID); |
- } |
- } |
- |
-cleanup: |
- |
- PKIX_DECREF(children); |
- PKIX_DECREF(childNode); |
- PKIX_DECREF(expectedPolicies); |
- PKIX_DECREF(policyOID); |
- PKIX_DECREF(childPolicy); |
- PKIX_DECREF(subjectDomainPolicies); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_CalculateIntersection |
- * DESCRIPTION: |
- * |
- * Processes the PolicyNode pointed to by "currentNode", and its descendants, |
- * using the PolicyCheckerState pointed to by "state", using the List at |
- * the address pointed to by "nominees" the OIDs of policies that are in the |
- * user-initial-policy-set but are not represented among the nodes at the |
- * bottom of the tree, and storing at "pShouldBePruned" the value TRUE if |
- * currentNode is childless at the end of this processing, FALSE if it has |
- * children or is at the bottom of the tree. |
- * |
- * When this function is called at the top level, "nominees" should be the List |
- * of all policies in the user-initial-policy-set. Policies that are |
- * represented in the valid-policy-node-set are removed from this List. As a |
- * result when nodes are created according to 6.1.5.(g)(iii)(3)(b), a node will |
- * be created for each policy remaining in this List. |
- * |
- * This function implements the calculation of the intersection of the |
- * validPolicyTree with the user-initial-policy-set, as described in |
- * RFC 3280 6.1.5(g)(iii). |
- * |
- * PARAMETERS: |
- * "currentNode" |
- * Address of PolicyNode whose descendants will be processed as described. |
- * Must be non-NULL. |
- * "state" |
- * Address of the current state of the PKIX_PolicyChecker. Must be non-NULL |
- * "nominees" |
- * Address of List of the OIDs for which nodes should be created to replace |
- * anyPolicy nodes. Must be non-NULL but may be empty. |
- * "pShouldBePruned" |
- * Address where Boolean return value, set to TRUE if this PolicyNode |
- * should be deleted, is stored. Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_CalculateIntersection( |
- PKIX_PolicyNode *currentNode, |
- PKIX_PolicyCheckerState *state, |
- PKIX_List *nominees, /* OIDs */ |
- PKIX_Boolean *pShouldBePruned, |
- void *plContext) |
-{ |
- PKIX_Boolean currentPolicyIsAny = PKIX_FALSE; |
- PKIX_Boolean parentPolicyIsAny = PKIX_FALSE; |
- PKIX_Boolean currentPolicyIsValid = PKIX_FALSE; |
- PKIX_Boolean shouldBePruned = PKIX_FALSE; |
- PKIX_Boolean priorCriticality = PKIX_FALSE; |
- PKIX_UInt32 depth = 0; |
- PKIX_UInt32 numChildren = 0; |
- PKIX_UInt32 childIndex = 0; |
- PKIX_UInt32 numNominees = 0; |
- PKIX_UInt32 polIx = 0; |
- PKIX_PL_OID *currentPolicy = NULL; |
- PKIX_PL_OID *parentPolicy = NULL; |
- PKIX_PL_OID *substPolicy = NULL; |
- PKIX_PolicyNode *parent = NULL; |
- PKIX_PolicyNode *child = NULL; |
- PKIX_List *children = NULL; /* PolicyNodes */ |
- PKIX_List *policyQualifiers = NULL; |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, |
- "pkix_PolicyChecker_CalculateIntersection"); |
- |
- /* |
- * We call this function if the valid_policy_tree is not NULL and |
- * the user-initial-policy-set is not any-policy. |
- */ |
- if (!state->validPolicyTree || state->initialIsAnyPolicy) { |
- PKIX_ERROR(PKIX_PRECONDITIONFAILED); |
- } |
- |
- PKIX_NULLCHECK_FOUR(currentNode, state, nominees, pShouldBePruned); |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy |
- (currentNode, ¤tPolicy, plContext), |
- PKIX_POLICYNODEGETVALIDPOLICYFAILED); |
- |
- PKIX_NULLCHECK_TWO(state->anyPolicyOID, currentPolicy); |
- |
- PKIX_EQUALS |
- (state->anyPolicyOID, |
- currentPolicy, |
- ¤tPolicyIsAny, |
- plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetParent(currentNode, &parent, plContext), |
- PKIX_POLICYNODEGETPARENTFAILED); |
- |
- if (currentPolicyIsAny == PKIX_FALSE) { |
- |
- /* |
- * If we are at the top of the tree, or if our |
- * parent's validPolicy is anyPolicy, we are in |
- * the valid policy node set. |
- */ |
- if (parent) { |
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy |
- (parent, &parentPolicy, plContext), |
- PKIX_POLICYNODEGETVALIDPOLICYFAILED); |
- |
- PKIX_NULLCHECK_ONE(parentPolicy); |
- |
- PKIX_EQUALS |
- (state->anyPolicyOID, |
- parentPolicy, |
- &parentPolicyIsAny, |
- plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- } |
- |
- /* |
- * Section 6.1.5(g)(iii)(2) |
- * If this node's policy is not in the user-initial-policy-set, |
- * it is not in the intersection. Prune it. |
- */ |
- if (!parent || parentPolicyIsAny) { |
- PKIX_CHECK(pkix_List_Contains |
- (state->userInitialPolicySet, |
- (PKIX_PL_Object *)currentPolicy, |
- ¤tPolicyIsValid, |
- plContext), |
- PKIX_LISTCONTAINSFAILED); |
- if (!currentPolicyIsValid) { |
- *pShouldBePruned = PKIX_TRUE; |
- goto cleanup; |
- } |
- |
- /* |
- * If this node's policy is in the user-initial-policy- |
- * set, it will propagate that policy into the next |
- * level of the tree. Remove the policy from the list |
- * of policies that an anyPolicy will spawn. |
- */ |
- PKIX_CHECK(pkix_List_Remove |
- (nominees, |
- (PKIX_PL_Object *)currentPolicy, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- } |
- } |
- |
- |
- /* Are we at the bottom of the tree? */ |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetDepth |
- (currentNode, &depth, plContext), |
- PKIX_POLICYNODEGETDEPTHFAILED); |
- |
- if (depth == (state->numCerts)) { |
- /* |
- * Section 6.1.5(g)(iii)(3) |
- * Replace anyPolicy nodes... |
- */ |
- if (currentPolicyIsAny == PKIX_TRUE) { |
- |
- /* replace this node */ |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (nominees, &numNominees, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- if (numNominees) { |
- |
- PKIX_CHECK(PKIX_PolicyNode_GetPolicyQualifiers |
- (currentNode, |
- &policyQualifiers, |
- plContext), |
- PKIX_POLICYNODEGETPOLICYQUALIFIERSFAILED); |
- |
- PKIX_CHECK(PKIX_PolicyNode_IsCritical |
- (currentNode, &priorCriticality, plContext), |
- PKIX_POLICYNODEISCRITICALFAILED); |
- } |
- |
- PKIX_NULLCHECK_ONE(parent); |
- |
- for (polIx = 0; polIx < numNominees; polIx++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (nominees, |
- polIx, |
- (PKIX_PL_Object **)&substPolicy, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_Spawn |
- (parent, |
- substPolicy, |
- policyQualifiers, |
- NULL, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERSPAWNFAILED); |
- |
- PKIX_DECREF(substPolicy); |
- |
- } |
- /* remove currentNode from parent */ |
- *pShouldBePruned = PKIX_TRUE; |
- /* |
- * We can get away with augmenting the parent's List |
- * of children because we started at the end and went |
- * toward the beginning. New nodes are added at the end. |
- */ |
- } |
- } else { |
- /* |
- * Section 6.1.5(g)(iii)(4) |
- * Prune any childless nodes above the bottom level |
- */ |
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable |
- (currentNode, &children, plContext), |
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); |
- |
- /* CurrentNode should have been pruned if childless. */ |
- PKIX_NULLCHECK_ONE(children); |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (children, &numChildren, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (childIndex = numChildren; childIndex > 0; childIndex--) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (children, |
- childIndex - 1, |
- (PKIX_PL_Object **)&child, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection |
- (child, state, nominees, &shouldBePruned, plContext), |
- PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED); |
- |
- if (PKIX_TRUE == shouldBePruned) { |
- |
- PKIX_CHECK(PKIX_List_DeleteItem |
- (children, childIndex - 1, plContext), |
- PKIX_LISTDELETEITEMFAILED); |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } |
- |
- PKIX_DECREF(child); |
- } |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (children, &numChildren, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- if (numChildren == 0) { |
- *pShouldBePruned = PKIX_TRUE; |
- } |
- } |
-cleanup: |
- PKIX_DECREF(currentPolicy); |
- PKIX_DECREF(parentPolicy); |
- PKIX_DECREF(substPolicy); |
- PKIX_DECREF(parent); |
- PKIX_DECREF(child); |
- PKIX_DECREF(children); |
- PKIX_DECREF(policyQualifiers); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
- |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_PolicyMapProcessing |
- * DESCRIPTION: |
- * |
- * Performs the processing of Policies in the List of CertPolicyMaps pointed |
- * to by "policyMaps", using and updating the PolicyCheckerState pointed to by |
- * "state". |
- * |
- * This function implements the policyMap processing described in RFC3280 |
- * Section 6.1.4(b)(1), after certificate i has been processed, in preparation |
- * for certificate i+1. Section references are to that document. |
- * |
- * PARAMETERS: |
- * "policyMaps" |
- * Address of the List of CertPolicyMaps presented by certificate i. |
- * Must be non-NULL. |
- * "certPoliciesIncludeAny" |
- * Boolean value which is PKIX_TRUE if the current certificate asserts |
- * anyPolicy, PKIX_FALSE otherwise. |
- * "qualsOfAny" |
- * Address of List of qualifiers of the anyPolicy in the current |
- * certificate. May be empty or NULL. |
- * "state" |
- * Address of the current state of the PKIX_PolicyChecker. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_PolicyMapProcessing( |
- PKIX_List *policyMaps, /* CertPolicyMaps */ |
- PKIX_Boolean certPoliciesIncludeAny, |
- PKIX_List *qualsOfAny, |
- PKIX_PolicyCheckerState *state, |
- void *plContext) |
-{ |
- PKIX_UInt32 numPolicies = 0; |
- PKIX_UInt32 polX = 0; |
- PKIX_PL_OID *policyOID = NULL; |
- PKIX_List *newMappedPolicies = NULL; /* OIDs */ |
- PKIX_List *subjectDomainPolicies = NULL; /* OIDs */ |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, |
- "pkix_PolicyChecker_PolicyMapProcessing"); |
- PKIX_NULLCHECK_THREE |
- (policyMaps, |
- state, |
- state->mappedUserInitialPolicySet); |
- |
- /* |
- * For each policy in mappedUserInitialPolicySet, if it is not mapped, |
- * append it to new policySet; if it is mapped, append its |
- * subjectDomainPolicies to new policySet. When done, this new |
- * policySet will replace mappedUserInitialPolicySet. |
- */ |
- PKIX_CHECK(PKIX_List_Create |
- (&newMappedPolicies, plContext), |
- PKIX_LISTCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (state->mappedUserInitialPolicySet, |
- &numPolicies, |
- plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (polX = 0; polX < numPolicies; polX++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (state->mappedUserInitialPolicySet, |
- polX, |
- (PKIX_PL_Object **)&policyOID, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies |
- (policyMaps, |
- policyOID, |
- &subjectDomainPolicies, |
- plContext), |
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); |
- |
- if (subjectDomainPolicies) { |
- |
- PKIX_CHECK(pkix_List_AppendUnique |
- (newMappedPolicies, |
- subjectDomainPolicies, |
- plContext), |
- PKIX_LISTAPPENDUNIQUEFAILED); |
- |
- PKIX_DECREF(subjectDomainPolicies); |
- |
- } else { |
- PKIX_CHECK(PKIX_List_AppendItem |
- (newMappedPolicies, |
- (PKIX_PL_Object *)policyOID, |
- plContext), |
- PKIX_LISTAPPENDITEMFAILED); |
- } |
- PKIX_DECREF(policyOID); |
- } |
- |
- /* |
- * For each policy ID-P remaining in mappedPolicyOIDs, it has not been |
- * propagated to the bottom of the tree (depth i). If policyMapping |
- * is greater than zero and this cert contains anyPolicy and the tree |
- * contains an anyPolicy node at depth i-1, then we must create a node |
- * with validPolicy ID-P, the policy qualifiers of anyPolicy in |
- * this certificate, and expectedPolicySet the subjectDomainPolicies |
- * that ID-P maps to. We also then add those subjectDomainPolicies to |
- * the list of policies that will be accepted in the next certificate, |
- * the mappedUserInitialPolicySet. |
- */ |
- |
- if ((state->policyMapping > 0) && (certPoliciesIncludeAny) && |
- (state->anyPolicyNodeAtBottom) && (state->mappedPolicyOIDs)) { |
- |
- PKIX_CHECK(PKIX_List_GetLength |
- (state->mappedPolicyOIDs, |
- &numPolicies, |
- plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- |
- for (polX = 0; polX < numPolicies; polX++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (state->mappedPolicyOIDs, |
- polX, |
- (PKIX_PL_Object **)&policyOID, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies |
- (policyMaps, |
- policyOID, |
- &subjectDomainPolicies, |
- plContext), |
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_Spawn |
- (state->anyPolicyNodeAtBottom, |
- policyOID, |
- qualsOfAny, |
- subjectDomainPolicies, |
- state, |
- plContext), |
- PKIX_POLICYCHECKERSPAWNFAILED); |
- |
- PKIX_CHECK(pkix_List_AppendUnique |
- (newMappedPolicies, |
- subjectDomainPolicies, |
- plContext), |
- PKIX_LISTAPPENDUNIQUEFAILED); |
- |
- PKIX_DECREF(subjectDomainPolicies); |
- PKIX_DECREF(policyOID); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_List_SetImmutable(newMappedPolicies, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- PKIX_DECREF(state->mappedUserInitialPolicySet); |
- PKIX_INCREF(newMappedPolicies); |
- |
- state->mappedUserInitialPolicySet = newMappedPolicies; |
- |
-cleanup: |
- |
- PKIX_DECREF(policyOID); |
- PKIX_DECREF(newMappedPolicies); |
- PKIX_DECREF(subjectDomainPolicies); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_WrapUpProcessing |
- * DESCRIPTION: |
- * |
- * Performs the wrap-up processing for the Cert pointed to by "cert", |
- * using and updating the PolicyCheckerState pointed to by "state". |
- * |
- * This function implements the wrap-up processing described in RFC3280 |
- * Section 6.1.5, after the final certificate has been processed. Section |
- * references in the comments are to that document. |
- * |
- * PARAMETERS: |
- * "cert" |
- * Address of the current (presumably the end entity) certificate. |
- * Must be non-NULL. |
- * "state" |
- * Address of the current state of the PKIX_PolicyChecker. |
- * Must be non-NULL. |
- * "plContext" |
- * Platform-specific context pointer. |
- * THREAD SAFETY: |
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
- * RETURNS: |
- * Returns NULL if the function succeeds |
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_WrapUpProcessing( |
- PKIX_PL_Cert *cert, |
- PKIX_PolicyCheckerState *state, |
- void *plContext) |
-{ |
- PKIX_Int32 explicitPolicySkipCerts = 0; |
- PKIX_Boolean isSelfIssued = PKIX_FALSE; |
- PKIX_Boolean shouldBePruned = PKIX_FALSE; |
- PKIX_List *nominees = NULL; /* OIDs */ |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- PKIX_PL_String *stateString = NULL; |
- char *stateAscii = NULL; |
- PKIX_UInt32 length; |
-#endif |
- |
- PKIX_ENTER |
- (CERTCHAINCHECKER, |
- "pkix_PolicyChecker_WrapUpProcessing"); |
- PKIX_NULLCHECK_THREE(cert, state, state->userInitialPolicySet); |
- |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- 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("%s\n", stateAscii); |
- |
- PKIX_FREE(stateAscii); |
- PKIX_DECREF(stateString); |
-#endif |
- |
- /* Section 6.1.5(a) ... */ |
- PKIX_CHECK(pkix_IsCertSelfIssued |
- (cert, &isSelfIssued, plContext), |
- PKIX_ISCERTSELFISSUEDFAILED); |
- |
- if (!isSelfIssued) { |
- if (state->explicitPolicy > 0) { |
- |
- state->explicitPolicy--; |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } |
- } |
- |
- /* Section 6.1.5(b) ... */ |
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy |
- (cert, &explicitPolicySkipCerts, plContext), |
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED); |
- |
- if (explicitPolicySkipCerts == 0) { |
- state->explicitPolicy = 0; |
- } |
- |
- /* Section 6.1.5(g)(i) ... */ |
- |
- if (!(state->validPolicyTree)) { |
- goto cleanup; |
- } |
- |
- /* Section 6.1.5(g)(ii) ... */ |
- |
- if (state->initialIsAnyPolicy) { |
- goto cleanup; |
- } |
- |
- /* |
- * Section 6.1.5(g)(iii) ... |
- * Create a list of policies which could be substituted for anyPolicy. |
- * Start with a (mutable) copy of user-initial-policy-set. |
- */ |
- PKIX_CHECK(pkix_PolicyChecker_MakeMutableCopy |
- (state->userInitialPolicySet, &nominees, plContext), |
- PKIX_POLICYCHECKERMAKEMUTABLECOPYFAILED); |
- |
- PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection |
- (state->validPolicyTree, /* node at top of tree */ |
- state, |
- nominees, |
- &shouldBePruned, |
- plContext), |
- PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED); |
- |
- if (PKIX_TRUE == shouldBePruned) { |
- PKIX_DECREF(state->validPolicyTree); |
- } |
- |
- if (state->validPolicyTree) { |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state->validPolicyTree, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- if (state->validPolicyTree) { |
- 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 |
- ("After CalculateIntersection:\n%s\n", stateAscii); |
- |
- PKIX_FREE(stateAscii); |
- PKIX_DECREF(stateString); |
- } else { |
- PKIX_DEBUG("validPolicyTree is NULL\n"); |
- } |
-#endif |
- |
- /* Section 6.1.5(g)(iii)(4) ... */ |
- |
- if (state->validPolicyTree) { |
- |
- PKIX_CHECK(pkix_PolicyNode_Prune |
- (state->validPolicyTree, |
- state->numCerts, |
- &shouldBePruned, |
- plContext), |
- PKIX_POLICYNODEPRUNEFAILED); |
- |
- if (shouldBePruned) { |
- PKIX_DECREF(state->validPolicyTree); |
- } |
- } |
- |
- if (state->validPolicyTree) { |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state->validPolicyTree, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- 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("%s\n", stateAscii); |
- |
- PKIX_FREE(stateAscii); |
- PKIX_DECREF(stateString); |
-#endif |
- |
-cleanup: |
- |
- PKIX_DECREF(nominees); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_Check |
- * (see comments in pkix_checker.h for PKIX_CertChainChecker_CheckCallback) |
- * |
- * Labels referring to sections, such as "Section 6.1.3(d)", refer to |
- * sections of RFC3280, Section 6.1.3 Basic Certificate Processing. |
- * |
- * If a non-fatal error occurs, it is unlikely that policy processing can |
- * continue. But it is still possible that chain validation could succeed if |
- * policy processing is non-critical. So if this function receives a non-fatal |
- * error from a lower level routine, it aborts policy processing by setting |
- * the validPolicyTree to NULL and tries to continue. |
- * |
- */ |
-static PKIX_Error * |
-pkix_PolicyChecker_Check( |
- PKIX_CertChainChecker *checker, |
- PKIX_PL_Cert *cert, |
- PKIX_List *unresolvedCriticals, /* OIDs */ |
- void **pNBIOContext, |
- void *plContext) |
-{ |
- PKIX_UInt32 numPolicies = 0; |
- PKIX_UInt32 polX = 0; |
- PKIX_Boolean result = PKIX_FALSE; |
- PKIX_Int32 inhibitMappingSkipCerts = 0; |
- PKIX_Int32 explicitPolicySkipCerts = 0; |
- PKIX_Int32 inhibitAnyPolicySkipCerts = 0; |
- PKIX_Boolean shouldBePruned = PKIX_FALSE; |
- PKIX_Boolean isSelfIssued = PKIX_FALSE; |
- PKIX_Boolean certPoliciesIncludeAny = PKIX_FALSE; |
- PKIX_Boolean doAnyPolicyProcessing = PKIX_FALSE; |
- |
- PKIX_PolicyCheckerState *state = NULL; |
- PKIX_List *certPolicyInfos = NULL; /* CertPolicyInfos */ |
- PKIX_PL_CertPolicyInfo *policy = NULL; |
- PKIX_PL_OID *policyOID = NULL; |
- PKIX_List *qualsOfAny = NULL; /* CertPolicyQualifiers */ |
- PKIX_List *policyQualifiers = NULL; /* CertPolicyQualifiers */ |
- PKIX_List *policyMaps = NULL; /* CertPolicyMaps */ |
- PKIX_List *mappedPolicies = NULL; /* OIDs */ |
- PKIX_Error *subroutineErr = NULL; |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- PKIX_PL_String *stateString = NULL; |
- char *stateAscii = NULL; |
- PKIX_PL_String *certString = NULL; |
- char *certAscii = NULL; |
- PKIX_UInt32 length; |
-#endif |
- |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Check"); |
- PKIX_NULLCHECK_FOUR(checker, cert, unresolvedCriticals, pNBIOContext); |
- |
- *pNBIOContext = NULL; /* we never block on pending I/O */ |
- |
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState |
- (checker, (PKIX_PL_Object **)&state, plContext), |
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); |
- |
- PKIX_NULLCHECK_TWO(state, state->certPoliciesExtension); |
- |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- 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("On entry %s\n", stateAscii); |
- PKIX_FREE(stateAscii); |
- PKIX_DECREF(stateString); |
-#endif |
- |
- /* |
- * Section 6.1.4(a) |
- * If this is not the last certificate, and if |
- * policyMapping extension is present, check that no |
- * issuerDomainPolicy or subjectDomainPolicy is equal to the |
- * special policy anyPolicy. |
- */ |
- if (state->certsProcessed != (state->numCerts - 1)) { |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings |
- (cert, &policyMaps, plContext), |
- PKIX_CERTGETPOLICYMAPPINGSFAILED); |
- } |
- |
- if (policyMaps) { |
- |
- PKIX_CHECK(pkix_PolicyChecker_MapContains |
- (policyMaps, state->anyPolicyOID, &result, plContext), |
- PKIX_POLICYCHECKERMAPCONTAINSFAILED); |
- |
- if (result) { |
- PKIX_ERROR(PKIX_INVALIDPOLICYMAPPINGINCLUDESANYPOLICY); |
- } |
- |
- PKIX_CHECK(pkix_PolicyChecker_MapGetMappedPolicies |
- (policyMaps, &mappedPolicies, plContext), |
- PKIX_POLICYCHECKERMAPGETMAPPEDPOLICIESFAILED); |
- |
- PKIX_DECREF(state->mappedPolicyOIDs); |
- PKIX_INCREF(mappedPolicies); |
- state->mappedPolicyOIDs = mappedPolicies; |
- } |
- |
- /* Section 6.1.3(d) */ |
- if (state->validPolicyTree) { |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation |
- (cert, &certPolicyInfos, plContext), |
- PKIX_CERTGETPOLICYINFORMATIONFAILED); |
- |
- if (certPolicyInfos) { |
- PKIX_CHECK(PKIX_List_GetLength |
- (certPolicyInfos, &numPolicies, plContext), |
- PKIX_LISTGETLENGTHFAILED); |
- } |
- |
- if (numPolicies > 0) { |
- |
- PKIX_CHECK(PKIX_PL_Cert_AreCertPoliciesCritical |
- (cert, &(state->certPoliciesCritical), plContext), |
- PKIX_CERTARECERTPOLICIESCRITICALFAILED); |
- |
- /* Section 6.1.3(d)(1) For each policy not equal to anyPolicy */ |
- for (polX = 0; polX < numPolicies; polX++) { |
- |
- PKIX_CHECK(PKIX_List_GetItem |
- (certPolicyInfos, |
- polX, |
- (PKIX_PL_Object **)&policy, |
- plContext), |
- PKIX_LISTGETITEMFAILED); |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId |
- (policy, &policyOID, plContext), |
- PKIX_CERTPOLICYINFOGETPOLICYIDFAILED); |
- |
- PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolQualifiers |
- (policy, &policyQualifiers, plContext), |
- PKIX_CERTPOLICYINFOGETPOLQUALIFIERSFAILED); |
- |
- PKIX_EQUALS |
- (state->anyPolicyOID, |
- policyOID, |
- &result, |
- plContext, |
- PKIX_OIDEQUALFAILED); |
- |
- if (result == PKIX_FALSE) { |
- |
- /* Section 6.1.3(d)(1)(i) */ |
- subroutineErr = pkix_PolicyChecker_CheckPolicy |
- (policyOID, |
- policyQualifiers, |
- cert, |
- policyMaps, |
- state, |
- plContext); |
- if (subroutineErr) { |
- goto subrErrorCleanup; |
- } |
- |
- } else { |
- /* |
- * No descent (yet) for anyPolicy, but we will need |
- * the policyQualifiers for anyPolicy in 6.1.3(d)(2) |
- */ |
- PKIX_DECREF(qualsOfAny); |
- PKIX_INCREF(policyQualifiers); |
- qualsOfAny = policyQualifiers; |
- certPoliciesIncludeAny = PKIX_TRUE; |
- } |
- PKIX_DECREF(policy); |
- PKIX_DECREF(policyOID); |
- PKIX_DECREF(policyQualifiers); |
- } |
- |
- /* Section 6.1.3(d)(2) */ |
- if (certPoliciesIncludeAny == PKIX_TRUE) { |
- if (state->inhibitAnyPolicy > 0) { |
- doAnyPolicyProcessing = PKIX_TRUE; |
- } else { |
- /* We haven't yet counted the current cert */ |
- if (((state->certsProcessed) + 1) < |
- (state->numCerts)) { |
- |
- PKIX_CHECK(pkix_IsCertSelfIssued |
- (cert, |
- &doAnyPolicyProcessing, |
- plContext), |
- PKIX_ISCERTSELFISSUEDFAILED); |
- } |
- } |
- if (doAnyPolicyProcessing) { |
- subroutineErr = pkix_PolicyChecker_CheckAny |
- (state->validPolicyTree, |
- qualsOfAny, |
- policyMaps, |
- state, |
- plContext); |
- if (subroutineErr) { |
- goto subrErrorCleanup; |
- } |
- } |
- } |
- |
- /* Section 6.1.3(d)(3) */ |
- if (state->validPolicyTree) { |
- subroutineErr = pkix_PolicyNode_Prune |
- (state->validPolicyTree, |
- state->certsProcessed + 1, |
- &shouldBePruned, |
- plContext); |
- if (subroutineErr) { |
- goto subrErrorCleanup; |
- } |
- if (shouldBePruned) { |
- PKIX_DECREF(state->validPolicyTree); |
- PKIX_DECREF(state->anyPolicyNodeAtBottom); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- } else { |
- /* Section 6.1.3(e) */ |
- PKIX_DECREF(state->validPolicyTree); |
- PKIX_DECREF(state->anyPolicyNodeAtBottom); |
- PKIX_DECREF(state->newAnyPolicyNode); |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- } |
- } |
- |
- /* Section 6.1.3(f) */ |
- if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) { |
- PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); |
- } |
- |
- /* |
- * Remove Policy OIDs from list of unresolved critical |
- * extensions, if present. |
- */ |
- PKIX_CHECK(pkix_List_Remove |
- (unresolvedCriticals, |
- (PKIX_PL_Object *)state->certPoliciesExtension, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- |
- PKIX_CHECK(pkix_List_Remove |
- (unresolvedCriticals, |
- (PKIX_PL_Object *)state->policyMappingsExtension, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- |
- PKIX_CHECK(pkix_List_Remove |
- (unresolvedCriticals, |
- (PKIX_PL_Object *)state->policyConstraintsExtension, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- |
- PKIX_CHECK(pkix_List_Remove |
- (unresolvedCriticals, |
- (PKIX_PL_Object *)state->inhibitAnyPolicyExtension, |
- plContext), |
- PKIX_LISTREMOVEFAILED); |
- |
- state->certsProcessed++; |
- |
- /* If this was not the last certificate, do next-cert preparation */ |
- if (state->certsProcessed != state->numCerts) { |
- |
- if (policyMaps) { |
- subroutineErr = pkix_PolicyChecker_PolicyMapProcessing |
- (policyMaps, |
- certPoliciesIncludeAny, |
- qualsOfAny, |
- state, |
- plContext); |
- if (subroutineErr) { |
- goto subrErrorCleanup; |
- } |
- } |
- |
- /* update anyPolicyNodeAtBottom pointer */ |
- PKIX_DECREF(state->anyPolicyNodeAtBottom); |
- state->anyPolicyNodeAtBottom = state->newAnyPolicyNode; |
- state->newAnyPolicyNode = NULL; |
- |
- /* Section 6.1.4(h) */ |
- PKIX_CHECK(pkix_IsCertSelfIssued |
- (cert, &isSelfIssued, plContext), |
- PKIX_ISCERTSELFISSUEDFAILED); |
- |
- if (!isSelfIssued) { |
- if (state->explicitPolicy > 0) { |
- state->explicitPolicy--; |
- } |
- if (state->policyMapping > 0) { |
- state->policyMapping--; |
- } |
- if (state->inhibitAnyPolicy > 0) { |
- state->inhibitAnyPolicy--; |
- } |
- } |
- |
- /* Section 6.1.4(i) */ |
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy |
- (cert, &explicitPolicySkipCerts, plContext), |
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED); |
- |
- if (explicitPolicySkipCerts != -1) { |
- if (((PKIX_UInt32)explicitPolicySkipCerts) < |
- (state->explicitPolicy)) { |
- state->explicitPolicy = |
- ((PKIX_UInt32) explicitPolicySkipCerts); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited |
- (cert, &inhibitMappingSkipCerts, plContext), |
- PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED); |
- |
- if (inhibitMappingSkipCerts != -1) { |
- if (((PKIX_UInt32)inhibitMappingSkipCerts) < |
- (state->policyMapping)) { |
- state->policyMapping = |
- ((PKIX_UInt32)inhibitMappingSkipCerts); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy |
- (cert, &inhibitAnyPolicySkipCerts, plContext), |
- PKIX_CERTGETINHIBITANYPOLICYFAILED); |
- |
- if (inhibitAnyPolicySkipCerts != -1) { |
- if (((PKIX_UInt32)inhibitAnyPolicySkipCerts) < |
- (state->inhibitAnyPolicy)) { |
- state->inhibitAnyPolicy = |
- ((PKIX_UInt32)inhibitAnyPolicySkipCerts); |
- } |
- } |
- |
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache |
- ((PKIX_PL_Object *)state, plContext), |
- PKIX_OBJECTINVALIDATECACHEFAILED); |
- |
- } else { /* If this was the last certificate, do wrap-up processing */ |
- |
- /* Section 6.1.5 */ |
- subroutineErr = pkix_PolicyChecker_WrapUpProcessing |
- (cert, state, plContext); |
- if (subroutineErr) { |
- goto subrErrorCleanup; |
- } |
- |
- if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) { |
- PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); |
- } |
- |
- PKIX_DECREF(state->anyPolicyNodeAtBottom); |
- PKIX_DECREF(state->newAnyPolicyNode); |
- } |
- |
- |
- if (subroutineErr) { |
- |
-subrErrorCleanup: |
- /* We had an error. Was it a fatal error? */ |
- pkixErrorClass = subroutineErr->errClass; |
- if (pkixErrorClass == PKIX_FATAL_ERROR) { |
- pkixErrorResult = subroutineErr; |
- subroutineErr = NULL; |
- goto cleanup; |
- } |
- /* |
- * Abort policy processing, and then determine whether |
- * we can continue without policy processing. |
- */ |
- PKIX_DECREF(state->validPolicyTree); |
- PKIX_DECREF(state->anyPolicyNodeAtBottom); |
- PKIX_DECREF(state->newAnyPolicyNode); |
- if (state->explicitPolicy == 0) { |
- PKIX_ERROR |
- (PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); |
- } |
- } |
- |
- /* Checking is complete. Save state for the next certificate. */ |
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState |
- (checker, (PKIX_PL_Object *)state, plContext), |
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); |
- |
-cleanup: |
- |
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG |
- if (cert) { |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object*)cert, &certString, plContext), |
- PKIX_OBJECTTOSTRINGFAILED); |
- PKIX_CHECK(PKIX_PL_String_GetEncoded |
- (certString, |
- PKIX_ESCASCII, |
- (void **)&certAscii, |
- &length, |
- plContext), |
- PKIX_STRINGGETENCODEDFAILED); |
- PKIX_DEBUG_ARG("Cert was %s\n", certAscii); |
- PKIX_FREE(certAscii); |
- PKIX_DECREF(certString); |
- } |
- if (state) { |
- 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("On exit %s\n", stateAscii); |
- PKIX_FREE(stateAscii); |
- PKIX_DECREF(stateString); |
- } |
-#endif |
- |
- PKIX_DECREF(state); |
- PKIX_DECREF(certPolicyInfos); |
- PKIX_DECREF(policy); |
- PKIX_DECREF(qualsOfAny); |
- PKIX_DECREF(policyQualifiers); |
- PKIX_DECREF(policyOID); |
- PKIX_DECREF(subroutineErr); |
- PKIX_DECREF(policyMaps); |
- PKIX_DECREF(mappedPolicies); |
- |
- PKIX_RETURN(CERTCHAINCHECKER); |
-} |
- |
-/* |
- * FUNCTION: pkix_PolicyChecker_Initialize |
- * DESCRIPTION: |
- * |
- * Creates and initializes a PolicyChecker, using the List pointed to |
- * by "initialPolicies" for the user-initial-policy-set, the Boolean value |
- * of "policyQualifiersRejected" for the policyQualifiersRejected parameter, |
- * the Boolean value of "initialPolicyMappingInhibit" for the |
- * inhibitPolicyMappings parameter, the Boolean value of |
- * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the |
- * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy |
- * parameter, and the UInt32 value of "numCerts" as the number of |
- * certificates in the chain; and stores the Checker at "pChecker". |
- * |
- * PARAMETERS: |
- * "initialPolicies" |
- * Address of List of OIDs comprising the user-initial-policy-set; the List |
- * may be empty or NULL |
- * "policyQualifiersRejected" |
- * Boolean value of the policyQualifiersRejected parameter |
- * "initialPolicyMappingInhibit" |
- * Boolean value of the inhibitPolicyMappings parameter |
- * "initialExplicitPolicy" |
- * Boolean value of the initialExplicitPolicy parameter |
- * "initialAnyPolicyInhibit" |
- * Boolean value of the inhibitAnyPolicy parameter |
- * "numCerts" |
- * Number of certificates in the chain to be validated |
- * "pChecker" |
- * Address to store the created PolicyChecker. 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 CertChainChecker Error if the functions fails in a non-fatal way |
- * Returns a Fatal Error if the function fails in an unrecoverable way |
- */ |
-PKIX_Error * |
-pkix_PolicyChecker_Initialize( |
- PKIX_List *initialPolicies, |
- PKIX_Boolean policyQualifiersRejected, |
- PKIX_Boolean initialPolicyMappingInhibit, |
- PKIX_Boolean initialExplicitPolicy, |
- PKIX_Boolean initialAnyPolicyInhibit, |
- PKIX_UInt32 numCerts, |
- PKIX_CertChainChecker **pChecker, |
- void *plContext) |
-{ |
- PKIX_PolicyCheckerState *polCheckerState = NULL; |
- PKIX_List *policyExtensions = NULL; /* OIDs */ |
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Initialize"); |
- PKIX_NULLCHECK_ONE(pChecker); |
- |
- PKIX_CHECK(pkix_PolicyCheckerState_Create |
- (initialPolicies, |
- policyQualifiersRejected, |
- initialPolicyMappingInhibit, |
- initialExplicitPolicy, |
- initialAnyPolicyInhibit, |
- numCerts, |
- &polCheckerState, |
- plContext), |
- PKIX_POLICYCHECKERSTATECREATEFAILED); |
- |
- /* Create the list of extensions that we handle */ |
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton |
- ((PKIX_PL_Object *)(polCheckerState->certPoliciesExtension), |
- PKIX_TRUE, |
- &policyExtensions, |
- plContext), |
- PKIX_POLICYCHECKERMAKESINGLETONFAILED); |
- |
- PKIX_CHECK(PKIX_CertChainChecker_Create |
- (pkix_PolicyChecker_Check, |
- PKIX_FALSE, /* forwardCheckingSupported */ |
- PKIX_FALSE, |
- policyExtensions, |
- (PKIX_PL_Object *)polCheckerState, |
- pChecker, |
- plContext), |
- PKIX_CERTCHAINCHECKERCREATEFAILED); |
- |
-cleanup: |
- PKIX_DECREF(polCheckerState); |
- PKIX_DECREF(policyExtensions); |
- PKIX_RETURN(CERTCHAINCHECKER); |
- |
-} |