diff nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,873 @@
+/* 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: <DER-encoded value>";
+                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: <DER-encoded value>";
+                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 */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)