/* 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_generalname.c * * GeneralName Object Definitions * */ #include "pkix_pl_generalname.h" /* --Private-GeneralName-Functions------------------------------------- */ /* * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName * DESCRIPTION: * * Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by * "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName * is stored in this object when the object was created. * * PARAMETERS: * "genName" * Address of PKIX_PL_GeneralName. Must be non-NULL. * "pNssGenName" * Address where CERTGeneralName 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 GeneralName 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_GeneralName_GetNssGeneralName( PKIX_PL_GeneralName *genName, CERTGeneralName **pNssGenName, void *plContext) { CERTGeneralName *nssGenName = NULL; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName"); PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList); nssGenName = genName->nssGeneralNameList->name; *pNssGenName = nssGenName; PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_OtherName_Create * DESCRIPTION: * * Creates new OtherName which represents the CERTGeneralName pointed to by * "nssAltName" and stores it at "pOtherName". * * PARAMETERS: * "nssAltName" * Address of CERTGeneralName. Must be non-NULL. * "pOtherName" * Address where object pointer will be stored. Must be non-NULL. * "plContext" - Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a GeneralName 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_OtherName_Create( CERTGeneralName *nssAltName, OtherName **pOtherName, void *plContext) { OtherName *otherName = NULL; SECItem secItemName; SECItem secItemOID; SECStatus rv; PKIX_ENTER(GENERALNAME, "pkix_pl_OtherName_Create"); PKIX_NULLCHECK_TWO(nssAltName, pOtherName); PKIX_CHECK(PKIX_PL_Malloc (sizeof (OtherName), (void **)&otherName, plContext), PKIX_MALLOCFAILED); /* make a copy of the name field */ PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n"); rv = SECITEM_CopyItem (NULL, &otherName->name, &nssAltName->name.OthName.name); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OUTOFMEMORY); } /* make a copy of the oid field */ PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n"); rv = SECITEM_CopyItem (NULL, &otherName->oid, &nssAltName->name.OthName.oid); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OUTOFMEMORY); } *pOtherName = otherName; cleanup: if (otherName && PKIX_ERROR_RECEIVED){ secItemName = otherName->name; secItemOID = otherName->oid; PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); SECITEM_FreeItem(&secItemName, PR_FALSE); PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); SECITEM_FreeItem(&secItemOID, PR_FALSE); PKIX_FREE(otherName); otherName = NULL; } PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_DirectoryName_Create * DESCRIPTION: * * Creates a new X500Name which represents the directoryName component of the * CERTGeneralName pointed to by "nssAltName" and stores it at "pX500Name". * * PARAMETERS: * "nssAltName" * Address of CERTGeneralName. Must be non-NULL. * "pX500Name" * Address where object pointer will be stored. Must be non-NULL. * "plContext" - Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a GeneralName 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_DirectoryName_Create( CERTGeneralName *nssAltName, PKIX_PL_X500Name **pX500Name, void *plContext) { PKIX_PL_X500Name *pkixDN = NULL; CERTName *dirName = NULL; PKIX_PL_String *pkixDNString = NULL; char *utf8String = NULL; PKIX_ENTER(GENERALNAME, "pkix_pl_DirectoryName_Create"); PKIX_NULLCHECK_TWO(nssAltName, pX500Name); dirName = &nssAltName->name.directoryName; PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName(NULL, dirName, &pkixDN, plContext), PKIX_X500NAMECREATEFROMCERTNAMEFAILED); *pX500Name = pkixDN; cleanup: PR_Free(utf8String); PKIX_DECREF(pkixDNString); PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_Create * DESCRIPTION: * * Creates new GeneralName which represents the CERTGeneralName pointed to by * "nssAltName" and stores it at "pGenName". * * PARAMETERS: * "nssAltName" * Address of CERTGeneralName. Must be non-NULL. * "pGenName" * Address where object pointer will be stored. Must be non-NULL. * "plContext" - Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a GeneralName 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_GeneralName_Create( CERTGeneralName *nssAltName, PKIX_PL_GeneralName **pGenName, void *plContext) { PKIX_PL_GeneralName *genName = NULL; PKIX_PL_X500Name *pkixDN = NULL; PKIX_PL_OID *pkixOID = NULL; OtherName *otherName = NULL; CERTGeneralNameList *nssGenNameList = NULL; CERTGeneralNameType nameType; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create"); PKIX_NULLCHECK_TWO(nssAltName, pGenName); /* create a PKIX_PL_GeneralName object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_GENERALNAME_TYPE, sizeof (PKIX_PL_GeneralName), (PKIX_PL_Object **)&genName, plContext), PKIX_COULDNOTCREATEOBJECT); nameType = nssAltName->type; /* * We use CERT_CreateGeneralNameList to create just one CERTGeneralName * item for memory allocation reason. If we want to just create one * item, we have to use the calling path CERT_NewGeneralName, then * CERT_CopyOneGeneralName. With this calling path, if we pass * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent * call to CERT_CopyName, it assumes arena should be valid, hence * segmentation error (not sure this is a NSS bug, certainly it is * not consistent). But on the other hand, we don't want to keep an * arena record here explicitely for every PKIX_PL_GeneralName. * So I concluded it is better to use CERT_CreateGeneralNameList, * which keeps an arena pointer in its data structure and also masks * out details calls from this libpkix level. */ PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n"); nssGenNameList = CERT_CreateGeneralNameList(nssAltName); if (nssGenNameList == NULL) { PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED); } genName->nssGeneralNameList = nssGenNameList; /* initialize fields */ genName->type = nameType; genName->directoryName = NULL; genName->OthName = NULL; genName->other = NULL; genName->oid = NULL; switch (nameType){ case certOtherName: PKIX_CHECK(pkix_pl_OtherName_Create (nssAltName, &otherName, plContext), PKIX_OTHERNAMECREATEFAILED); genName->OthName = otherName; break; case certDirectoryName: PKIX_CHECK(pkix_pl_DirectoryName_Create (nssAltName, &pkixDN, plContext), PKIX_DIRECTORYNAMECREATEFAILED); genName->directoryName = pkixDN; break; case certRegisterID: PKIX_CHECK(PKIX_PL_OID_CreateBySECItem(&nssAltName->name.other, &pkixOID, plContext), PKIX_OIDCREATEFAILED); genName->oid = pkixOID; break; case certDNSName: case certEDIPartyName: case certIPAddress: case certRFC822Name: case certX400Address: case certURI: genName->other = SECITEM_DupItem(&nssAltName->name.other); if (!genName->other) { PKIX_ERROR(PKIX_OUTOFMEMORY); } break; default: PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED); } *pGenName = genName; genName = NULL; cleanup: PKIX_DECREF(genName); PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_ToString_Helper * DESCRIPTION: * * Helper function that creates a string representation of the GeneralName * pointed to by "name" and stores it at "pString" Different mechanisms are * used to create the string, depending on the type of the GeneralName. * * PARAMETERS * "name" * Address of GeneralName whose string representation is desired. * Must be non-NULL. * "pString" * Address where object pointer will be stored. Must be non-NULL. * "plContext" - Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a GeneralName 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_GeneralName_ToString_Helper( PKIX_PL_GeneralName *name, PKIX_PL_String **pString, void *plContext) { PKIX_PL_X500Name *pkixDN = NULL; PKIX_PL_OID *pkixOID = NULL; char *x400AsciiName = NULL; char *ediPartyName = NULL; char *asciiName = NULL; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper"); PKIX_NULLCHECK_TWO(name, pString); switch (name->type) { case certRFC822Name: case certDNSName: case certURI: /* * Note that we can't use PKIX_ESCASCII here because * name->other->data is not guaranteed to be null-terminated. */ PKIX_NULLCHECK_ONE(name->other); PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8, (name->other)->data, (name->other)->len, pString, plContext), PKIX_STRINGCREATEFAILED); break; case certEDIPartyName: /* XXX print out the actual bytes */ ediPartyName = "EDIPartyName: "; PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, ediPartyName, 0, pString, plContext), PKIX_STRINGCREATEFAILED); break; case certX400Address: /* XXX print out the actual bytes */ x400AsciiName = "X400Address: "; PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, x400AsciiName, 0, pString, plContext), PKIX_STRINGCREATEFAILED); break; case certIPAddress: PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii (name->other, &asciiName, plContext), PKIX_IPADDRBYTES2ASCIIFAILED); PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, asciiName, 0, pString, plContext), PKIX_STRINGCREATEFAILED); break; case certOtherName: PKIX_NULLCHECK_ONE(name->OthName); /* we only print type-id - don't know how to print value */ /* XXX print out the bytes of the value */ PKIX_CHECK(pkix_pl_oidBytes2Ascii (&name->OthName->oid, &asciiName, plContext), PKIX_OIDBYTES2ASCIIFAILED); PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, asciiName, 0, pString, plContext), PKIX_STRINGCREATEFAILED); break; case certRegisterID: pkixOID = name->oid; PKIX_CHECK(PKIX_PL_Object_ToString ((PKIX_PL_Object *)pkixOID, pString, plContext), PKIX_OIDTOSTRINGFAILED); break; case certDirectoryName: pkixDN = name->directoryName; PKIX_CHECK(PKIX_PL_Object_ToString ((PKIX_PL_Object *)pkixDN, pString, plContext), PKIX_X500NAMETOSTRINGFAILED); break; default: PKIX_ERROR (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED); } cleanup: PKIX_FREE(asciiName); PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_Destroy * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_GeneralName_Destroy( PKIX_PL_Object *object, void *plContext) { PKIX_PL_GeneralName *name = NULL; SECItem secItemName; SECItem secItemOID; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Destroy"); PKIX_NULLCHECK_ONE(object); PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), PKIX_OBJECTNOTGENERALNAME); name = (PKIX_PL_GeneralName *)object; PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); SECITEM_FreeItem(name->other, PR_TRUE); name->other = NULL; if (name->OthName){ secItemName = name->OthName->name; secItemOID = name->OthName->oid; PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); SECITEM_FreeItem(&secItemName, PR_FALSE); PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); SECITEM_FreeItem(&secItemOID, PR_FALSE); PKIX_FREE(name->OthName); name->OthName = NULL; } if (name->nssGeneralNameList != NULL) { PKIX_GENERALNAME_DEBUG ("\t\tCalling CERT_DestroyGeneralNameList).\n"); CERT_DestroyGeneralNameList(name->nssGeneralNameList); } PKIX_DECREF(name->directoryName); PKIX_DECREF(name->oid); cleanup: PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_ToString * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_GeneralName_ToString( PKIX_PL_Object *object, PKIX_PL_String **pString, void *plContext) { PKIX_PL_String *nameString = NULL; PKIX_PL_GeneralName *name = NULL; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_toString"); PKIX_NULLCHECK_TWO(object, pString); PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), PKIX_OBJECTNOTGENERALNAME); name = (PKIX_PL_GeneralName *)object; PKIX_CHECK(pkix_pl_GeneralName_ToString_Helper (name, &nameString, plContext), PKIX_GENERALNAMETOSTRINGHELPERFAILED); *pString = nameString; cleanup: PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_Hashcode * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_GeneralName_Hashcode( PKIX_PL_Object *object, PKIX_UInt32 *pHashcode, void *plContext) { PKIX_PL_GeneralName *name = NULL; PKIX_UInt32 firstHash, secondHash, nameHash; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode"); PKIX_NULLCHECK_TWO(object, pHashcode); PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), PKIX_OBJECTNOTGENERALNAME); name = (PKIX_PL_GeneralName *)object; switch (name->type) { case certRFC822Name: case certDNSName: case certX400Address: case certEDIPartyName: case certURI: case certIPAddress: PKIX_NULLCHECK_ONE(name->other); PKIX_CHECK(pkix_hash ((const unsigned char *) name->other->data, name->other->len, &nameHash, plContext), PKIX_HASHFAILED); break; case certRegisterID: PKIX_CHECK(PKIX_PL_Object_Hashcode ((PKIX_PL_Object *)name->oid, &nameHash, plContext), PKIX_OIDHASHCODEFAILED); break; case certOtherName: PKIX_NULLCHECK_ONE(name->OthName); PKIX_CHECK(pkix_hash ((const unsigned char *) name->OthName->oid.data, name->OthName->oid.len, &firstHash, plContext), PKIX_HASHFAILED); PKIX_CHECK(pkix_hash ((const unsigned char *) name->OthName->name.data, name->OthName->name.len, &secondHash, plContext), PKIX_HASHFAILED); nameHash = firstHash + secondHash; break; case certDirectoryName: PKIX_CHECK(PKIX_PL_Object_Hashcode ((PKIX_PL_Object *) name->directoryName, &nameHash, plContext), PKIX_X500NAMEHASHCODEFAILED); break; } *pHashcode = nameHash; cleanup: PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_Equals * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_GeneralName_Equals( PKIX_PL_Object *firstObject, PKIX_PL_Object *secondObject, PKIX_Boolean *pResult, void *plContext) { PKIX_PL_GeneralName *firstName = NULL; PKIX_PL_GeneralName *secondName = NULL; PKIX_UInt32 secondType; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Equals"); PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); /* test that firstObject is a GeneralName */ PKIX_CHECK(pkix_CheckType (firstObject, PKIX_GENERALNAME_TYPE, plContext), PKIX_FIRSTOBJECTNOTGENERALNAME); /* * Since we know firstObject is a GeneralName, if both references are * identical, they must be equal */ if (firstObject == secondObject){ *pResult = PKIX_TRUE; goto cleanup; } /* * If secondObject isn't a GeneralName, we don't throw an error. * We simply return a Boolean result of FALSE */ *pResult = PKIX_FALSE; PKIX_CHECK(PKIX_PL_Object_GetType (secondObject, &secondType, plContext), PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); if (secondType != PKIX_GENERALNAME_TYPE){ goto cleanup; } firstName = (PKIX_PL_GeneralName *)firstObject; secondName = (PKIX_PL_GeneralName *)secondObject; if (firstName->type != secondName->type){ goto cleanup; } switch (firstName->type) { case certRFC822Name: case certDNSName: case certX400Address: case certEDIPartyName: case certURI: case certIPAddress: PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n"); if (SECITEM_CompareItem(firstName->other, secondName->other) != SECEqual) { goto cleanup; } break; case certRegisterID: PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)firstName->oid, (PKIX_PL_Object *)secondName->oid, pResult, plContext), PKIX_OIDEQUALSFAILED); goto cleanup; case certOtherName: PKIX_NULLCHECK_TWO(firstName->OthName, secondName->OthName); PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n"); if (SECITEM_CompareItem(&firstName->OthName->oid, &secondName->OthName->oid) != SECEqual || SECITEM_CompareItem(&firstName->OthName->name, &secondName->OthName->name) != SECEqual) { goto cleanup; } break; case certDirectoryName: PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)firstName->directoryName, (PKIX_PL_Object *)secondName->directoryName, pResult, plContext), PKIX_X500NAMEEQUALSFAILED); goto cleanup; } *pResult = PKIX_TRUE; cleanup: PKIX_RETURN(GENERALNAME); } /* * FUNCTION: pkix_pl_GeneralName_RegisterSelf * DESCRIPTION: * Registers PKIX_GENERALNAME_TYPE and 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_GeneralName_RegisterSelf(void *plContext) { extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; pkix_ClassTable_Entry entry; PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_RegisterSelf"); entry.description = "GeneralName"; entry.objCounter = 0; entry.typeObjectSize = sizeof(PKIX_PL_GeneralName); entry.destructor = pkix_pl_GeneralName_Destroy; entry.equalsFunction = pkix_pl_GeneralName_Equals; entry.hashcodeFunction = pkix_pl_GeneralName_Hashcode; entry.toStringFunction = pkix_pl_GeneralName_ToString; entry.comparator = NULL; entry.duplicateFunction = pkix_duplicateImmutable; systemClasses[PKIX_GENERALNAME_TYPE] = entry; PKIX_RETURN(GENERALNAME); } /* --Public-Functions------------------------------------------------------- */ #ifdef BUILD_LIBPKIX_TESTS /* * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h) */ PKIX_Error * PKIX_PL_GeneralName_Create( PKIX_UInt32 nameType, PKIX_PL_String *stringRep, PKIX_PL_GeneralName **pGName, void *plContext) { PKIX_PL_X500Name *pkixDN = NULL; PKIX_PL_OID *pkixOID = NULL; SECItem *secItem = NULL; char *asciiString = NULL; PKIX_UInt32 length = 0; PKIX_PL_GeneralName *genName = NULL; CERTGeneralName *nssGenName = NULL; CERTGeneralNameList *nssGenNameList = NULL; CERTName *nssCertName = NULL; PLArenaPool *arena = NULL; PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create"); PKIX_NULLCHECK_TWO(pGName, stringRep); PKIX_CHECK(PKIX_PL_String_GetEncoded (stringRep, PKIX_ESCASCII, (void **)&asciiString, &length, plContext), PKIX_STRINGGETENCODEDFAILED); /* Create a temporary CERTGeneralName */ PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n"); length = PL_strlen(asciiString); PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n"); secItem = SECITEM_AllocItem(NULL, NULL, length); PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n"); (void) PORT_Memcpy(secItem->data, asciiString, length); PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n"); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { PKIX_ERROR(PKIX_OUTOFMEMORY); } PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n"); nssGenName = CERT_NewGeneralName(arena, nameType); if (nssGenName == NULL) { PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED); } switch (nameType) { case certRFC822Name: case certDNSName: case certURI: nssGenName->name.other = *secItem; break; case certDirectoryName: PKIX_CHECK(PKIX_PL_X500Name_Create (stringRep, &pkixDN, plContext), PKIX_X500NAMECREATEFAILED); PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n"); nssCertName = CERT_AsciiToName(asciiString); nssGenName->name.directoryName = *nssCertName; break; case certRegisterID: PKIX_CHECK(PKIX_PL_OID_Create (asciiString, &pkixOID, plContext), PKIX_OIDCREATEFAILED); nssGenName->name.other = *secItem; break; default: /* including IPAddress, EDIPartyName, OtherName, X400Address */ PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE); } /* create a PKIX_PL_GeneralName object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_GENERALNAME_TYPE, sizeof (PKIX_PL_GeneralName), (PKIX_PL_Object **)&genName, plContext), PKIX_COULDNOTCREATEOBJECT); /* create a CERTGeneralNameList */ nssGenName->type = nameType; PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n"); nssGenNameList = CERT_CreateGeneralNameList(nssGenName); if (nssGenNameList == NULL) { PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED); } genName->nssGeneralNameList = nssGenNameList; /* initialize fields */ genName->type = nameType; genName->directoryName = pkixDN; genName->OthName = NULL; genName->other = secItem; genName->oid = pkixOID; *pGName = genName; cleanup: PKIX_FREE(asciiString); if (nssCertName != NULL) { PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n"); CERT_DestroyName(nssCertName); } if (arena){ /* will free nssGenName */ PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n"); PORT_FreeArena(arena, PR_FALSE); } if (PKIX_ERROR_RECEIVED){ PKIX_DECREF(pkixDN); PKIX_DECREF(pkixOID); PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); if (secItem){ SECITEM_FreeItem(secItem, PR_TRUE); secItem = NULL; } } PKIX_RETURN(GENERALNAME); } #endif /* BUILD_LIBPKIX_TESTS */