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