summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c')
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c1274
1 files changed, 1274 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
new file mode 100644
index 000000000..affea8741
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
@@ -0,0 +1,1274 @@
+/* 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;
+ if (arena){
+ PKIX_CERTNAMECONSTRAINTS_DEBUG
+ ("\t\tCalling PORT_FreeArena).\n");
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ 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);
+}