| /* 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_pl_nameconstraints.c |
| * |
| * Name Constraints Object Functions Definitions |
| * |
| */ |
| |
| #include "pkix_pl_nameconstraints.h" |
| |
| |
| /* --Private-NameConstraints-Functions----------------------------- */ |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_GetPermitted |
| * DESCRIPTION: |
| * |
| * This function retrieve name constraints permitted list from NSS |
| * data in "nameConstraints" and returns a PKIX_PL_GeneralName list |
| * in "pPermittedList". |
| * |
| * PARAMETERS |
| * "nameConstraints" |
| * Address of CertNameConstraints which has a pointer to |
| * CERTNameConstraints data. Must be non-NULL. |
| * "pPermittedList" |
| * Address where returned permitted name list is stored. Must be non-NULL. |
| * "plContext" - Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Conditionally Thread Safe |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns NULL if the function succeeds. |
| * Returns a NameConstraints 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_pl_CertNameConstraints_GetPermitted( |
| PKIX_PL_CertNameConstraints *nameConstraints, |
| PKIX_List **pPermittedList, |
| void *plContext) |
| { |
| CERTNameConstraints *nssNameConstraints = NULL; |
| CERTNameConstraints **nssNameConstraintsList = NULL; |
| CERTNameConstraint *nssPermitted = NULL; |
| CERTNameConstraint *firstPermitted = NULL; |
| PKIX_List *permittedList = NULL; |
| PKIX_PL_GeneralName *name = NULL; |
| PKIX_UInt32 numItems = 0; |
| PKIX_UInt32 i; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_GetPermitted"); |
| PKIX_NULLCHECK_TWO(nameConstraints, pPermittedList); |
| |
| /* |
| * nssNameConstraints is an array of CERTNameConstraints |
| * pointers where CERTNameConstraints keep its permitted and excluded |
| * lists as pointer array of CERTNameConstraint. |
| */ |
| |
| if (nameConstraints->permittedList == NULL) { |
| |
| PKIX_OBJECT_LOCK(nameConstraints); |
| |
| if (nameConstraints->permittedList == NULL) { |
| |
| PKIX_CHECK(PKIX_List_Create(&permittedList, plContext), |
| PKIX_LISTCREATEFAILED); |
| |
| numItems = nameConstraints->numNssNameConstraints; |
| nssNameConstraintsList = |
| nameConstraints->nssNameConstraintsList; |
| |
| for (i = 0; i < numItems; i++) { |
| |
| PKIX_NULLCHECK_ONE(nssNameConstraintsList); |
| nssNameConstraints = *(nssNameConstraintsList + i); |
| PKIX_NULLCHECK_ONE(nssNameConstraints); |
| |
| if (nssNameConstraints->permited != NULL) { |
| |
| nssPermitted = nssNameConstraints->permited; |
| firstPermitted = nssPermitted; |
| |
| do { |
| |
| PKIX_CHECK(pkix_pl_GeneralName_Create |
| (&nssPermitted->name, &name, plContext), |
| PKIX_GENERALNAMECREATEFAILED); |
| |
| PKIX_CHECK(PKIX_List_AppendItem |
| (permittedList, |
| (PKIX_PL_Object *)name, |
| plContext), |
| PKIX_LISTAPPENDITEMFAILED); |
| |
| PKIX_DECREF(name); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_GetNextNameConstraint\n"); |
| nssPermitted = CERT_GetNextNameConstraint |
| (nssPermitted); |
| |
| } while (nssPermitted != firstPermitted); |
| |
| } |
| } |
| |
| PKIX_CHECK(PKIX_List_SetImmutable(permittedList, plContext), |
| PKIX_LISTSETIMMUTABLEFAILED); |
| |
| nameConstraints->permittedList = permittedList; |
| |
| } |
| |
| PKIX_OBJECT_UNLOCK(nameConstraints); |
| |
| } |
| |
| PKIX_INCREF(nameConstraints->permittedList); |
| |
| *pPermittedList = nameConstraints->permittedList; |
| |
| cleanup: |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_GetExcluded |
| * DESCRIPTION: |
| * |
| * This function retrieve name constraints excluded list from NSS |
| * data in "nameConstraints" and returns a PKIX_PL_GeneralName list |
| * in "pExcludedList". |
| * |
| * PARAMETERS |
| * "nameConstraints" |
| * Address of CertNameConstraints which has a pointer to NSS data. |
| * Must be non-NULL. |
| * "pPermittedList" |
| * Address where returned excluded name list is stored. Must be non-NULL. |
| * "plContext" - Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Conditionally Thread Safe |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns NULL if the function succeeds. |
| * Returns a NameConstraints 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_pl_CertNameConstraints_GetExcluded( |
| PKIX_PL_CertNameConstraints *nameConstraints, |
| PKIX_List **pExcludedList, |
| void *plContext) |
| { |
| CERTNameConstraints *nssNameConstraints = NULL; |
| CERTNameConstraints **nssNameConstraintsList = NULL; |
| CERTNameConstraint *nssExcluded = NULL; |
| CERTNameConstraint *firstExcluded = NULL; |
| PKIX_List *excludedList = NULL; |
| PKIX_PL_GeneralName *name = NULL; |
| PKIX_UInt32 numItems = 0; |
| PKIX_UInt32 i; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_GetExcluded"); |
| PKIX_NULLCHECK_TWO(nameConstraints, pExcludedList); |
| |
| if (nameConstraints->excludedList == NULL) { |
| |
| PKIX_OBJECT_LOCK(nameConstraints); |
| |
| if (nameConstraints->excludedList == NULL) { |
| |
| PKIX_CHECK(PKIX_List_Create(&excludedList, plContext), |
| PKIX_LISTCREATEFAILED); |
| |
| numItems = nameConstraints->numNssNameConstraints; |
| nssNameConstraintsList = |
| nameConstraints->nssNameConstraintsList; |
| |
| for (i = 0; i < numItems; i++) { |
| |
| PKIX_NULLCHECK_ONE(nssNameConstraintsList); |
| nssNameConstraints = *(nssNameConstraintsList + i); |
| PKIX_NULLCHECK_ONE(nssNameConstraints); |
| |
| if (nssNameConstraints->excluded != NULL) { |
| |
| nssExcluded = nssNameConstraints->excluded; |
| firstExcluded = nssExcluded; |
| |
| do { |
| |
| PKIX_CHECK(pkix_pl_GeneralName_Create |
| (&nssExcluded->name, &name, plContext), |
| PKIX_GENERALNAMECREATEFAILED); |
| |
| PKIX_CHECK(PKIX_List_AppendItem |
| (excludedList, |
| (PKIX_PL_Object *)name, |
| plContext), |
| PKIX_LISTAPPENDITEMFAILED); |
| |
| PKIX_DECREF(name); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_GetNextNameConstraint\n"); |
| nssExcluded = CERT_GetNextNameConstraint |
| (nssExcluded); |
| |
| } while (nssExcluded != firstExcluded); |
| |
| } |
| |
| } |
| PKIX_CHECK(PKIX_List_SetImmutable(excludedList, plContext), |
| PKIX_LISTSETIMMUTABLEFAILED); |
| |
| nameConstraints->excludedList = excludedList; |
| |
| } |
| |
| PKIX_OBJECT_UNLOCK(nameConstraints); |
| } |
| |
| PKIX_INCREF(nameConstraints->excludedList); |
| |
| *pExcludedList = nameConstraints->excludedList; |
| |
| cleanup: |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_CheckNameSpaceNssNames |
| * DESCRIPTION: |
| * |
| * This function checks if CERTGeneralNames in "nssSubjectNames" comply |
| * with the permitted and excluded names in "nameConstraints". It returns |
| * PKIX_TRUE in "pCheckPass", if the Names satify the name space of the |
| * permitted list and if the Names are not in the excluded list. Otherwise, |
| * it returns PKIX_FALSE. |
| * |
| * PARAMETERS |
| * "nssSubjectNames" |
| * List of CERTGeneralName that nameConstraints verification is based on. |
| * "nameConstraints" |
| * Address of CertNameConstraints that provides lists of permitted |
| * and excluded names. Must be non-NULL. |
| * "pCheckPass" |
| * Address where PKIX_TRUE is returned if the all names in "nameList" are |
| * valid. |
| * "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 NameConstraints 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_pl_CertNameConstraints_CheckNameSpaceNssNames( |
| CERTGeneralName *nssSubjectNames, |
| PKIX_PL_CertNameConstraints *nameConstraints, |
| PKIX_Boolean *pCheckPass, |
| void *plContext) |
| { |
| CERTNameConstraints **nssNameConstraintsList = NULL; |
| CERTNameConstraints *nssNameConstraints = NULL; |
| CERTGeneralName *nssMatchName = NULL; |
| PLArenaPool *arena = NULL; |
| PKIX_UInt32 numItems = 0; |
| PKIX_UInt32 i; |
| SECStatus status = SECSuccess; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_CheckNameSpaceNssNames"); |
| PKIX_NULLCHECK_THREE(nssSubjectNames, nameConstraints, pCheckPass); |
| |
| *pCheckPass = PKIX_TRUE; |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n"); |
| arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| if (arena == NULL) { |
| PKIX_ERROR(PKIX_OUTOFMEMORY); |
| } |
| |
| nssMatchName = nssSubjectNames; |
| nssNameConstraintsList = nameConstraints->nssNameConstraintsList; |
| |
| /* |
| * CERTNameConstraint items in each permitted or excluded list |
| * is verified as OR condition. That means, if one item matched, |
| * then the checking on the remaining items on the list is skipped. |
| * (see NSS cert_CompareNameWithConstraints(...)). |
| * Items on PKIX_PL_NameConstraint's nssNameConstraints are verified |
| * as AND condition. PKIX_PL_NameConstraint keeps an array of pointers |
| * of CERTNameConstraints resulting from merging multiple |
| * PKIX_PL_NameConstraints. Since each CERTNameConstraint are created |
| * for different entity, a union condition of these entities then is |
| * performed. |
| */ |
| |
| do { |
| |
| numItems = nameConstraints->numNssNameConstraints; |
| |
| for (i = 0; i < numItems; i++) { |
| |
| PKIX_NULLCHECK_ONE(nssNameConstraintsList); |
| nssNameConstraints = *(nssNameConstraintsList + i); |
| PKIX_NULLCHECK_ONE(nssNameConstraints); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_CheckNameSpace\n"); |
| status = CERT_CheckNameSpace |
| (arena, nssNameConstraints, nssMatchName); |
| if (status != SECSuccess) { |
| break; |
| } |
| |
| } |
| |
| if (status != SECSuccess) { |
| break; |
| } |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_GetNextGeneralName\n"); |
| nssMatchName = CERT_GetNextGeneralName(nssMatchName); |
| |
| } while (nssMatchName != nssSubjectNames); |
| |
| if (status == SECFailure) { |
| |
| *pCheckPass = PKIX_FALSE; |
| } |
| |
| cleanup: |
| |
| if (arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(arena, PR_FALSE); |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_NameConstraints_Destroy |
| * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
| */ |
| static PKIX_Error * |
| pkix_pl_CertNameConstraints_Destroy( |
| PKIX_PL_Object *object, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Destroy"); |
| PKIX_NULLCHECK_ONE(object); |
| |
| PKIX_CHECK(pkix_CheckType |
| (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext), |
| PKIX_OBJECTNOTCERTNAMECONSTRAINTS); |
| |
| nameConstraints = (PKIX_PL_CertNameConstraints *)object; |
| |
| PKIX_CHECK(PKIX_PL_Free |
| (nameConstraints->nssNameConstraintsList, plContext), |
| PKIX_FREEFAILED); |
| |
| if (nameConstraints->arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(nameConstraints->arena, PR_FALSE); |
| nameConstraints->arena = NULL; |
| } |
| |
| PKIX_DECREF(nameConstraints->permittedList); |
| PKIX_DECREF(nameConstraints->excludedList); |
| |
| cleanup: |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_ToString_Helper |
| * DESCRIPTION: |
| * |
| * Helper function that creates a string representation of the object |
| * NameConstraints and stores it at "pString". |
| * |
| * PARAMETERS |
| * "nameConstraints" |
| * Address of CertNameConstraints whose string representation is |
| * desired. Must be non-NULL. |
| * "pString" |
| * Address where string 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 NameConstraints 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_pl_CertNameConstraints_ToString_Helper( |
| PKIX_PL_CertNameConstraints *nameConstraints, |
| PKIX_PL_String **pString, |
| void *plContext) |
| { |
| char *asciiFormat = NULL; |
| PKIX_PL_String *formatString = NULL; |
| PKIX_List *permittedList = NULL; |
| PKIX_List *excludedList = NULL; |
| PKIX_PL_String *permittedListString = NULL; |
| PKIX_PL_String *excludedListString = NULL; |
| PKIX_PL_String *nameConstraintsString = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_ToString_Helper"); |
| PKIX_NULLCHECK_TWO(nameConstraints, pString); |
| |
| asciiFormat = |
| "[\n" |
| "\t\tPermitted Name: %s\n" |
| "\t\tExcluded Name: %s\n" |
| "\t]\n"; |
| |
| PKIX_CHECK(PKIX_PL_String_Create |
| (PKIX_ESCASCII, |
| asciiFormat, |
| 0, |
| &formatString, |
| plContext), |
| PKIX_STRINGCREATEFAILED); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted |
| (nameConstraints, &permittedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED); |
| |
| PKIX_TOSTRING(permittedList, &permittedListString, plContext, |
| PKIX_LISTTOSTRINGFAILED); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded |
| (nameConstraints, &excludedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED); |
| |
| PKIX_TOSTRING(excludedList, &excludedListString, plContext, |
| PKIX_LISTTOSTRINGFAILED); |
| |
| PKIX_CHECK(PKIX_PL_Sprintf |
| (&nameConstraintsString, |
| plContext, |
| formatString, |
| permittedListString, |
| excludedListString), |
| PKIX_SPRINTFFAILED); |
| |
| *pString = nameConstraintsString; |
| |
| cleanup: |
| |
| PKIX_DECREF(formatString); |
| PKIX_DECREF(permittedList); |
| PKIX_DECREF(excludedList); |
| PKIX_DECREF(permittedListString); |
| PKIX_DECREF(excludedListString); |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_ToString |
| * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) |
| */ |
| static PKIX_Error * |
| pkix_pl_CertNameConstraints_ToString( |
| PKIX_PL_Object *object, |
| PKIX_PL_String **pString, |
| void *plContext) |
| { |
| PKIX_PL_String *nameConstraintsString = NULL; |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_ToString"); |
| PKIX_NULLCHECK_TWO(object, pString); |
| |
| PKIX_CHECK(pkix_CheckType( |
| object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext), |
| PKIX_OBJECTNOTCERTNAMECONSTRAINTS); |
| |
| nameConstraints = (PKIX_PL_CertNameConstraints *)object; |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_ToString_Helper |
| (nameConstraints, &nameConstraintsString, plContext), |
| PKIX_CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED); |
| |
| *pString = nameConstraintsString; |
| |
| cleanup: |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_Hashcode |
| * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) |
| */ |
| static PKIX_Error * |
| pkix_pl_CertNameConstraints_Hashcode( |
| PKIX_PL_Object *object, |
| PKIX_UInt32 *pHashcode, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| PKIX_List *permittedList = NULL; |
| PKIX_List *excludedList = NULL; |
| PKIX_UInt32 permitHash = 0; |
| PKIX_UInt32 excludeHash = 0; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Hashcode"); |
| PKIX_NULLCHECK_TWO(object, pHashcode); |
| |
| PKIX_CHECK(pkix_CheckType |
| (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext), |
| PKIX_OBJECTNOTCERTNAMECONSTRAINTS); |
| |
| nameConstraints = (PKIX_PL_CertNameConstraints *)object; |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted |
| (nameConstraints, &permittedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED); |
| |
| PKIX_HASHCODE(permittedList, &permitHash, plContext, |
| PKIX_OBJECTHASHCODEFAILED); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded |
| (nameConstraints, &excludedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED); |
| |
| PKIX_HASHCODE(excludedList, &excludeHash, plContext, |
| PKIX_OBJECTHASHCODEFAILED); |
| |
| *pHashcode = (((permitHash << 7) + excludeHash) << 7) + |
| nameConstraints->numNssNameConstraints; |
| |
| cleanup: |
| |
| PKIX_DECREF(permittedList); |
| PKIX_DECREF(excludedList); |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_Equals |
| * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) |
| */ |
| static PKIX_Error * |
| pkix_pl_CertNameConstraints_Equals( |
| PKIX_PL_Object *firstObject, |
| PKIX_PL_Object *secondObject, |
| PKIX_Boolean *pResult, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *firstNC = NULL; |
| PKIX_PL_CertNameConstraints *secondNC = NULL; |
| PKIX_List *firstPermittedList = NULL; |
| PKIX_List *secondPermittedList = NULL; |
| PKIX_List *firstExcludedList = NULL; |
| PKIX_List *secondExcludedList = NULL; |
| PKIX_UInt32 secondType; |
| PKIX_Boolean cmpResult = PKIX_FALSE; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Equals"); |
| PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); |
| |
| /* test that firstObject is a CertNameConstraints */ |
| PKIX_CHECK(pkix_CheckType |
| (firstObject, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext), |
| PKIX_FIRSTOBJECTNOTCERTNAMECONSTRAINTS); |
| |
| firstNC = (PKIX_PL_CertNameConstraints *)firstObject; |
| secondNC = (PKIX_PL_CertNameConstraints *)secondObject; |
| |
| /* |
| * Since we know firstObject is a CertNameConstraints, if both |
| * references are identical, they must be equal |
| */ |
| if (firstNC == secondNC){ |
| *pResult = PKIX_TRUE; |
| goto cleanup; |
| } |
| |
| /* |
| * If secondNC isn't a CertNameConstraints, we don't throw an error. |
| * We simply return a Boolean result of FALSE |
| */ |
| *pResult = PKIX_FALSE; |
| |
| PKIX_CHECK(PKIX_PL_Object_GetType |
| ((PKIX_PL_Object *)secondNC, &secondType, plContext), |
| PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); |
| |
| if (secondType != PKIX_CERTNAMECONSTRAINTS_TYPE) { |
| goto cleanup; |
| } |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted |
| (firstNC, &firstPermittedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted |
| (secondNC, &secondPermittedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED); |
| |
| PKIX_EQUALS |
| (firstPermittedList, secondPermittedList, &cmpResult, plContext, |
| PKIX_OBJECTEQUALSFAILED); |
| |
| if (cmpResult != PKIX_TRUE) { |
| goto cleanup; |
| } |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded |
| (firstNC, &firstExcludedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded |
| (secondNC, &secondExcludedList, plContext), |
| PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED); |
| |
| PKIX_EQUALS |
| (firstExcludedList, secondExcludedList, &cmpResult, plContext, |
| PKIX_OBJECTEQUALSFAILED); |
| |
| if (cmpResult != PKIX_TRUE) { |
| goto cleanup; |
| } |
| |
| /* |
| * numNssNameConstraints is not checked because it is basically a |
| * merge count, it cannot determine the data equality. |
| */ |
| |
| *pResult = PKIX_TRUE; |
| |
| cleanup: |
| |
| PKIX_DECREF(firstPermittedList); |
| PKIX_DECREF(secondPermittedList); |
| PKIX_DECREF(firstExcludedList); |
| PKIX_DECREF(secondExcludedList); |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_RegisterSelf |
| * DESCRIPTION: |
| * Registers PKIX_CERTNAMECONSTRAINTS_TYPE and its related functions with |
| * systemClasses[] |
| * 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_pl_CertNameConstraints_RegisterSelf(void *plContext) |
| { |
| extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
| pkix_ClassTable_Entry entry; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_RegisterSelf"); |
| |
| entry.description = "CertNameConstraints"; |
| entry.objCounter = 0; |
| entry.typeObjectSize = sizeof(PKIX_PL_CertNameConstraints); |
| entry.destructor = pkix_pl_CertNameConstraints_Destroy; |
| entry.equalsFunction = pkix_pl_CertNameConstraints_Equals; |
| entry.hashcodeFunction = pkix_pl_CertNameConstraints_Hashcode; |
| entry.toStringFunction = pkix_pl_CertNameConstraints_ToString; |
| entry.comparator = NULL; |
| entry.duplicateFunction = pkix_duplicateImmutable; |
| |
| systemClasses[PKIX_CERTNAMECONSTRAINTS_TYPE] = entry; |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_Create_Helper |
| * |
| * DESCRIPTION: |
| * This function retrieves name constraints in "nssNameConstraints", |
| * converts and stores the result in a PKIX_PL_CertNameConstraints object. |
| * |
| * PARAMETERS |
| * "nssNameConstraints" |
| * Address of CERTNameConstraints that contains this object's data. |
| * Must be non-NULL. |
| * "pNameConstraints" |
| * Address where object pointer will be stored. Must be non-NULL. |
| * A NULL value will be returned if there is no Name Constraints extension. |
| * "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 NameConstraints 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_pl_CertNameConstraints_Create_Helper( |
| CERTNameConstraints *nssNameConstraints, |
| PKIX_PL_CertNameConstraints **pNameConstraints, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| CERTNameConstraints **nssNameConstraintPtr = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_Create_Helper"); |
| PKIX_NULLCHECK_TWO(nssNameConstraints, pNameConstraints); |
| |
| PKIX_CHECK(PKIX_PL_Object_Alloc |
| (PKIX_CERTNAMECONSTRAINTS_TYPE, |
| sizeof (PKIX_PL_CertNameConstraints), |
| (PKIX_PL_Object **)&nameConstraints, |
| plContext), |
| PKIX_COULDNOTCREATECERTNAMECONSTRAINTSOBJECT); |
| |
| PKIX_CHECK(PKIX_PL_Malloc |
| (sizeof (CERTNameConstraint *), |
| (void *)&nssNameConstraintPtr, |
| plContext), |
| PKIX_MALLOCFAILED); |
| |
| nameConstraints->numNssNameConstraints = 1; |
| nameConstraints->nssNameConstraintsList = nssNameConstraintPtr; |
| *nssNameConstraintPtr = nssNameConstraints; |
| |
| nameConstraints->permittedList = NULL; |
| nameConstraints->excludedList = NULL; |
| nameConstraints->arena = NULL; |
| |
| *pNameConstraints = nameConstraints; |
| |
| cleanup: |
| |
| if (PKIX_ERROR_RECEIVED){ |
| PKIX_DECREF(nameConstraints); |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_Create |
| * |
| * DESCRIPTION: |
| * function that allocates and initialize the object CertNameConstraints. |
| * |
| * PARAMETERS |
| * "nssCert" |
| * Address of CERT that contains this object's data. |
| * Must be non-NULL. |
| * "pNameConstraints" |
| * Address where object pointer will be stored. Must be non-NULL. |
| * A NULL value will be returned if there is no Name Constraints extension. |
| * "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 NameConstraints 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_pl_CertNameConstraints_Create( |
| CERTCertificate *nssCert, |
| PKIX_PL_CertNameConstraints **pNameConstraints, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| CERTNameConstraints *nssNameConstraints = NULL; |
| PLArenaPool *arena = NULL; |
| SECStatus status; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Create"); |
| PKIX_NULLCHECK_THREE(nssCert, pNameConstraints, nssCert->arena); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n"); |
| arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| if (arena == NULL) { |
| PKIX_ERROR(PKIX_OUTOFMEMORY); |
| } |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_FindNameConstraintsExten\n"); |
| status = CERT_FindNameConstraintsExten |
| (arena, nssCert, &nssNameConstraints); |
| |
| if (status != SECSuccess) { |
| PKIX_ERROR(PKIX_DECODINGCERTNAMECONSTRAINTSFAILED); |
| } |
| |
| if (nssNameConstraints == NULL) { |
| *pNameConstraints = NULL; |
| /* we free the arnea here because PKIX_ERROR_RECEIVED |
| * may not be set. Setting arena to NULL makes sure |
| * we don't try to free it again (and makes scanners |
| * happy). */ |
| if (arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(arena, PR_FALSE); |
| arena = NULL; |
| } |
| goto cleanup; |
| } |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper |
| (nssNameConstraints, &nameConstraints, plContext), |
| PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED); |
| |
| nameConstraints->arena = arena; |
| |
| *pNameConstraints = nameConstraints; |
| |
| cleanup: |
| |
| if (PKIX_ERROR_RECEIVED){ |
| if (arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(arena, PR_FALSE); |
| } |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_CreateByMerge |
| * |
| * DESCRIPTION: |
| * |
| * This function allocates and creates a PKIX_PL_NameConstraint object |
| * for merging. It also allocates CERTNameConstraints data space for the |
| * merged NSS NameConstraints data. |
| * |
| * PARAMETERS |
| * "pNameConstraints" |
| * Address where object pointer will be stored and 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 NameConstraints 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_pl_CertNameConstraints_CreateByMerge( |
| PKIX_PL_CertNameConstraints **pNameConstraints, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| CERTNameConstraints *nssNameConstraints = NULL; |
| PLArenaPool *arena = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_CreateByMerge"); |
| PKIX_NULLCHECK_ONE(pNameConstraints); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n"); |
| arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| if (arena == NULL) { |
| PKIX_ERROR(PKIX_OUTOFMEMORY); |
| } |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n"); |
| nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints); |
| if (nssNameConstraints == NULL) { |
| PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); |
| } |
| |
| nssNameConstraints->permited = NULL; |
| nssNameConstraints->excluded = NULL; |
| nssNameConstraints->DERPermited = NULL; |
| nssNameConstraints->DERExcluded = NULL; |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper |
| (nssNameConstraints, &nameConstraints, plContext), |
| PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED); |
| |
| nameConstraints->arena = arena; |
| |
| *pNameConstraints = nameConstraints; |
| |
| cleanup: |
| |
| if (PKIX_ERROR_RECEIVED){ |
| if (arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(arena, PR_FALSE); |
| } |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_CopyNssNameConstraints |
| * |
| * DESCRIPTION: |
| * |
| * This function allocates and copies data to a NSS CERTNameConstraints from |
| * the NameConstraints given by "srcNC" and stores the result at "pDestNC". It |
| * copies items on both the permitted and excluded lists, but not the |
| * DERPermited and DERExcluded. |
| * |
| * PARAMETERS |
| * "arena" |
| * Memory pool where object data is allocated from. Must be non-NULL. |
| * "srcNC" |
| * Address of the NameConstraints to copy from. Must be non-NULL. |
| * "pDestNC" |
| * Address where new copied object is stored and 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 NameConstraints 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_pl_CertNameConstraints_CopyNssNameConstraints( |
| PLArenaPool *arena, |
| CERTNameConstraints *srcNC, |
| CERTNameConstraints **pDestNC, |
| void *plContext) |
| { |
| CERTNameConstraints *nssNameConstraints = NULL; |
| CERTNameConstraint *nssNameConstraintHead = NULL; |
| CERTNameConstraint *nssCurrent = NULL; |
| CERTNameConstraint *nssCopyTo = NULL; |
| CERTNameConstraint *nssCopyFrom = NULL; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "pkix_pl_CertNameConstraints_CopyNssNameConstraints"); |
| PKIX_NULLCHECK_THREE(arena, srcNC, pDestNC); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n"); |
| nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints); |
| if (nssNameConstraints == NULL) { |
| PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); |
| } |
| |
| if (srcNC->permited) { |
| |
| nssCopyFrom = srcNC->permited; |
| |
| do { |
| |
| nssCopyTo = NULL; |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_CopyNameConstraint).\n"); |
| nssCopyTo = CERT_CopyNameConstraint |
| (arena, nssCopyTo, nssCopyFrom); |
| if (nssCopyTo == NULL) { |
| PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED); |
| } |
| if (nssCurrent == NULL) { |
| nssCurrent = nssNameConstraintHead = nssCopyTo; |
| } else { |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_AddNameConstraint).\n"); |
| nssCurrent = CERT_AddNameConstraint |
| (nssCurrent, nssCopyTo); |
| } |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_GetNextNameConstrain).\n"); |
| nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom); |
| |
| } while (nssCopyFrom != srcNC->permited); |
| |
| nssNameConstraints->permited = nssNameConstraintHead; |
| } |
| |
| if (srcNC->excluded) { |
| |
| nssCurrent = NULL; |
| nssCopyFrom = srcNC->excluded; |
| |
| do { |
| |
| /* |
| * Cannot use CERT_DupGeneralNameList, which just increments |
| * refcount. We need our own copy since arena is for each |
| * PKIX_PL_NameConstraints. Perhaps contribute this code |
| * as CERT_CopyGeneralNameList (in the future). |
| */ |
| nssCopyTo = NULL; |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_CopyNameConstraint).\n"); |
| nssCopyTo = CERT_CopyNameConstraint |
| (arena, nssCopyTo, nssCopyFrom); |
| if (nssCopyTo == NULL) { |
| PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED); |
| } |
| if (nssCurrent == NULL) { |
| nssCurrent = nssNameConstraintHead = nssCopyTo; |
| } else { |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_AddNameConstraint).\n"); |
| nssCurrent = CERT_AddNameConstraint |
| (nssCurrent, nssCopyTo); |
| } |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_GetNextNameConstrain).\n"); |
| nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom); |
| |
| } while (nssCopyFrom != srcNC->excluded); |
| |
| nssNameConstraints->excluded = nssNameConstraintHead; |
| } |
| |
| *pDestNC = nssNameConstraints; |
| |
| cleanup: |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* |
| * FUNCTION: pkix_pl_CertNameConstraints_Merge |
| * |
| * DESCRIPTION: |
| * |
| * This function merges two NameConstraints pointed to by "firstNC" and |
| * "secondNC" and stores the result in "pMergedNC". |
| * |
| * PARAMETERS |
| * "firstNC" |
| * Address of the first NameConstraints to be merged. Must be non-NULL. |
| * "secondNC" |
| * Address of the second NameConstraints to be merged. Must be non-NULL. |
| * "pMergedNC" |
| * Address where the merge result is stored and 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 NameConstraints 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_pl_CertNameConstraints_Merge( |
| PKIX_PL_CertNameConstraints *firstNC, |
| PKIX_PL_CertNameConstraints *secondNC, |
| PKIX_PL_CertNameConstraints **pMergedNC, |
| void *plContext) |
| { |
| PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
| CERTNameConstraints **nssNCto = NULL; |
| CERTNameConstraints **nssNCfrom = NULL; |
| CERTNameConstraints *nssNameConstraints = NULL; |
| PKIX_UInt32 numNssItems = 0; |
| PKIX_UInt32 i; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Merge"); |
| PKIX_NULLCHECK_THREE(firstNC, secondNC, pMergedNC); |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_CreateByMerge |
| (&nameConstraints, plContext), |
| PKIX_CERTNAMECONSTRAINTSCREATEBYMERGEFAILED); |
| |
| /* Merge NSSCertConstraint lists */ |
| |
| numNssItems = firstNC->numNssNameConstraints + |
| secondNC->numNssNameConstraints; |
| |
| /* Free the default space (only one entry) allocated by create */ |
| PKIX_CHECK(PKIX_PL_Free |
| (nameConstraints->nssNameConstraintsList, plContext), |
| PKIX_FREEFAILED); |
| |
| /* Reallocate the size we need */ |
| PKIX_CHECK(PKIX_PL_Malloc |
| (numNssItems * sizeof (CERTNameConstraint *), |
| (void *)&nssNCto, |
| plContext), |
| PKIX_MALLOCFAILED); |
| |
| nameConstraints->nssNameConstraintsList = nssNCto; |
| |
| nssNCfrom = firstNC->nssNameConstraintsList; |
| |
| for (i = 0; i < firstNC->numNssNameConstraints; i++) { |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints |
| (nameConstraints->arena, |
| *nssNCfrom, |
| &nssNameConstraints, |
| plContext), |
| PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED); |
| |
| *nssNCto = nssNameConstraints; |
| |
| nssNCto++; |
| nssNCfrom++; |
| } |
| |
| nssNCfrom = secondNC->nssNameConstraintsList; |
| |
| for (i = 0; i < secondNC->numNssNameConstraints; i++) { |
| |
| PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints |
| (nameConstraints->arena, |
| *nssNCfrom, |
| &nssNameConstraints, |
| plContext), |
| PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED); |
| |
| *nssNCto = nssNameConstraints; |
| |
| nssNCto++; |
| nssNCfrom++; |
| } |
| |
| nameConstraints->numNssNameConstraints = numNssItems; |
| nameConstraints->permittedList = NULL; |
| nameConstraints->excludedList = NULL; |
| |
| *pMergedNC = nameConstraints; |
| |
| cleanup: |
| |
| if (PKIX_ERROR_RECEIVED){ |
| PKIX_DECREF(nameConstraints); |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |
| |
| /* --Public-NameConstraints-Functions-------------------------------- */ |
| |
| /* |
| * FUNCTION: PKIX_PL_CertNameConstraints_CheckNamesInNameSpace |
| * (see comments in pkix_pl_system.h) |
| */ |
| PKIX_Error * |
| PKIX_PL_CertNameConstraints_CheckNamesInNameSpace( |
| PKIX_List *nameList, /* List of PKIX_PL_GeneralName */ |
| PKIX_PL_CertNameConstraints *nameConstraints, |
| PKIX_Boolean *pCheckPass, |
| void *plContext) |
| { |
| CERTNameConstraints **nssNameConstraintsList = NULL; |
| CERTNameConstraints *nssNameConstraints = NULL; |
| CERTGeneralName *nssMatchName = NULL; |
| PLArenaPool *arena = NULL; |
| PKIX_PL_GeneralName *name = NULL; |
| PKIX_UInt32 numNameItems = 0; |
| PKIX_UInt32 numNCItems = 0; |
| PKIX_UInt32 i, j; |
| SECStatus status = SECSuccess; |
| |
| PKIX_ENTER(CERTNAMECONSTRAINTS, |
| "PKIX_PL_CertNameConstraints_CheckNamesInNameSpace"); |
| PKIX_NULLCHECK_TWO(nameConstraints, pCheckPass); |
| |
| *pCheckPass = PKIX_TRUE; |
| |
| if (nameList != NULL) { |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n"); |
| arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| if (arena == NULL) { |
| PKIX_ERROR(PKIX_OUTOFMEMORY); |
| } |
| |
| nssNameConstraintsList = |
| nameConstraints->nssNameConstraintsList; |
| PKIX_NULLCHECK_ONE(nssNameConstraintsList); |
| numNCItems = nameConstraints->numNssNameConstraints; |
| |
| PKIX_CHECK(PKIX_List_GetLength |
| (nameList, &numNameItems, plContext), |
| PKIX_LISTGETLENGTHFAILED); |
| |
| for (i = 0; i < numNameItems; i++) { |
| |
| PKIX_CHECK(PKIX_List_GetItem |
| (nameList, |
| i, |
| (PKIX_PL_Object **) &name, |
| plContext), |
| PKIX_LISTGETITEMFAILED); |
| |
| PKIX_CHECK(pkix_pl_GeneralName_GetNssGeneralName |
| (name, &nssMatchName, plContext), |
| PKIX_GENERALNAMEGETNSSGENERALNAMEFAILED); |
| |
| PKIX_DECREF(name); |
| |
| for (j = 0; j < numNCItems; j++) { |
| |
| nssNameConstraints = *(nssNameConstraintsList + j); |
| PKIX_NULLCHECK_ONE(nssNameConstraints); |
| |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling CERT_CheckNameSpace\n"); |
| status = CERT_CheckNameSpace |
| (arena, nssNameConstraints, nssMatchName); |
| if (status != SECSuccess) { |
| break; |
| } |
| |
| } |
| |
| if (status != SECSuccess) { |
| break; |
| } |
| |
| } |
| } |
| |
| if (status == SECFailure) { |
| *pCheckPass = PKIX_FALSE; |
| } |
| |
| cleanup: |
| |
| if (arena){ |
| PKIX_CERTNAMECONSTRAINTS_DEBUG |
| ("\t\tCalling PORT_FreeArena).\n"); |
| PORT_FreeArena(arena, PR_FALSE); |
| } |
| |
| PKIX_RETURN(CERTNAMECONSTRAINTS); |
| } |