tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pkix_pl_generalname.c (30025B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /*
      5 * pkix_pl_generalname.c
      6 *
      7 * GeneralName Object Definitions
      8 *
      9 */
     10 
     11 #include "pkix_pl_generalname.h"
     12 
     13 /* --Private-GeneralName-Functions------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName
     17 * DESCRIPTION:
     18 *
     19 *  Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by
     20 *  "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName
     21 *  is stored in this object when the object was created.
     22 *
     23 * PARAMETERS:
     24 *  "genName"
     25 *      Address of PKIX_PL_GeneralName. Must be non-NULL.
     26 *  "pNssGenName"
     27 *      Address where CERTGeneralName will be stored. Must be non-NULL.
     28 *  "plContext" - Platform-specific context pointer.
     29 * THREAD SAFETY:
     30 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
     31 * RETURNS:
     32 *  Returns NULL if the function succeeds.
     33 *  Returns a GeneralName Error if the function fails in a non-fatal way.
     34 *  Returns a Fatal Error if the function fails in an unrecoverable way.
     35 */
     36 PKIX_Error *
     37 pkix_pl_GeneralName_GetNssGeneralName(
     38        PKIX_PL_GeneralName *genName,
     39        CERTGeneralName **pNssGenName,
     40        void *plContext)
     41 {
     42        CERTGeneralName *nssGenName = NULL;
     43 
     44        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName");
     45        PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList);
     46 
     47        nssGenName = genName->nssGeneralNameList->name;
     48 
     49        *pNssGenName = nssGenName;
     50 
     51        PKIX_RETURN(GENERALNAME);
     52 }
     53 
     54 /*
     55 * FUNCTION: pkix_pl_OtherName_Create
     56 * DESCRIPTION:
     57 *
     58 *  Creates new OtherName which represents the CERTGeneralName pointed to by
     59 *  "nssAltName" and stores it at "pOtherName".
     60 *
     61 * PARAMETERS:
     62 *  "nssAltName"
     63 *      Address of CERTGeneralName. Must be non-NULL.
     64 *  "pOtherName"
     65 *      Address where object pointer will be stored. Must be non-NULL.
     66 *  "plContext" - Platform-specific context pointer.
     67 * THREAD SAFETY:
     68 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
     69 * RETURNS:
     70 *  Returns NULL if the function succeeds.
     71 *  Returns a GeneralName Error if the function fails in a non-fatal way.
     72 *  Returns a Fatal Error if the function fails in an unrecoverable way.
     73 */
     74 static PKIX_Error *
     75 pkix_pl_OtherName_Create(
     76        CERTGeneralName *nssAltName,
     77        OtherName **pOtherName,
     78        void *plContext)
     79 {
     80        OtherName *otherName = NULL;
     81        SECItem secItemName;
     82        SECItem secItemOID;
     83        SECStatus rv;
     84 
     85        PKIX_ENTER(GENERALNAME, "pkix_pl_OtherName_Create");
     86        PKIX_NULLCHECK_TWO(nssAltName, pOtherName);
     87 
     88        PKIX_CHECK(PKIX_PL_Malloc
     89                    (sizeof (OtherName), (void **)&otherName, plContext),
     90                    PKIX_MALLOCFAILED);
     91 
     92        /* make a copy of the name field */
     93        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
     94        rv = SECITEM_CopyItem
     95                (NULL, &otherName->name, &nssAltName->name.OthName.name);
     96        if (rv != SECSuccess) {
     97                PKIX_ERROR(PKIX_OUTOFMEMORY);
     98        }
     99 
    100        /* make a copy of the oid field */
    101        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
    102        rv = SECITEM_CopyItem
    103                (NULL, &otherName->oid, &nssAltName->name.OthName.oid);
    104        if (rv != SECSuccess) {
    105                PKIX_ERROR(PKIX_OUTOFMEMORY);
    106        }
    107 
    108        *pOtherName = otherName;
    109 
    110 cleanup:
    111 
    112        if (otherName && PKIX_ERROR_RECEIVED){
    113                secItemName = otherName->name;
    114                secItemOID = otherName->oid;
    115 
    116                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    117                SECITEM_FreeItem(&secItemName, PR_FALSE);
    118 
    119                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    120                SECITEM_FreeItem(&secItemOID, PR_FALSE);
    121 
    122                PKIX_FREE(otherName);
    123                otherName = NULL;
    124        }
    125 
    126        PKIX_RETURN(GENERALNAME);
    127 }
    128 
    129 /*
    130 * FUNCTION: pkix_pl_DirectoryName_Create
    131 * DESCRIPTION:
    132 *
    133 *  Creates a new X500Name which represents the directoryName component of the
    134 *  CERTGeneralName pointed to by "nssAltName" and stores it at "pX500Name".
    135 *
    136 * PARAMETERS:
    137 *  "nssAltName"
    138 *      Address of CERTGeneralName. Must be non-NULL.
    139 *  "pX500Name"
    140 *      Address where object pointer will be stored. Must be non-NULL.
    141 *  "plContext" - Platform-specific context pointer.
    142 * THREAD SAFETY:
    143 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    144 * RETURNS:
    145 *  Returns NULL if the function succeeds.
    146 *  Returns a GeneralName Error if the function fails in a non-fatal way.
    147 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    148 */
    149 static PKIX_Error *
    150 pkix_pl_DirectoryName_Create(
    151        CERTGeneralName *nssAltName,
    152        PKIX_PL_X500Name **pX500Name,
    153        void *plContext)
    154 {
    155        PKIX_PL_X500Name *pkixDN = NULL;
    156        CERTName *dirName = NULL;
    157        PKIX_PL_String *pkixDNString = NULL;
    158        char *utf8String = NULL;
    159 
    160        PKIX_ENTER(GENERALNAME, "pkix_pl_DirectoryName_Create");
    161        PKIX_NULLCHECK_TWO(nssAltName, pX500Name);
    162 
    163        dirName = &nssAltName->name.directoryName;
    164 
    165        PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName(NULL, dirName, 
    166                                                       &pkixDN, plContext),
    167                   PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
    168 
    169        *pX500Name = pkixDN;
    170 
    171 cleanup:
    172 
    173        PR_Free(utf8String);
    174        PKIX_DECREF(pkixDNString);
    175 
    176        PKIX_RETURN(GENERALNAME);
    177 }
    178 
    179 /*
    180 * FUNCTION: pkix_pl_GeneralName_Create
    181 * DESCRIPTION:
    182 *
    183 *  Creates new GeneralName which represents the CERTGeneralName pointed to by
    184 *  "nssAltName" and stores it at "pGenName".
    185 *
    186 * PARAMETERS:
    187 *  "nssAltName"
    188 *      Address of CERTGeneralName. Must be non-NULL.
    189 *  "pGenName"
    190 *      Address where object pointer will be stored. Must be non-NULL.
    191 *  "plContext" - Platform-specific context pointer.
    192 * THREAD SAFETY:
    193 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    194 * RETURNS:
    195 *  Returns NULL if the function succeeds.
    196 *  Returns a GeneralName Error if the function fails in a non-fatal way.
    197 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    198 */
    199 PKIX_Error *
    200 pkix_pl_GeneralName_Create(
    201        CERTGeneralName *nssAltName,
    202        PKIX_PL_GeneralName **pGenName,
    203        void *plContext)
    204 {
    205        PKIX_PL_GeneralName *genName = NULL;
    206        PKIX_PL_X500Name *pkixDN = NULL;
    207        PKIX_PL_OID *pkixOID = NULL;
    208        OtherName *otherName = NULL;
    209        CERTGeneralNameList *nssGenNameList = NULL;
    210        CERTGeneralNameType nameType;
    211 
    212        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create");
    213        PKIX_NULLCHECK_TWO(nssAltName, pGenName);
    214 
    215        /* create a PKIX_PL_GeneralName object */
    216        PKIX_CHECK(PKIX_PL_Object_Alloc
    217                    (PKIX_GENERALNAME_TYPE,
    218                    sizeof (PKIX_PL_GeneralName),
    219                    (PKIX_PL_Object **)&genName,
    220                    plContext),
    221                    PKIX_COULDNOTCREATEOBJECT);
    222 
    223        nameType = nssAltName->type;
    224 
    225        /*
    226         * We use CERT_CreateGeneralNameList to create just one CERTGeneralName
    227         * item for memory allocation reason. If we want to just create one
    228         * item, we have to use the calling path CERT_NewGeneralName, then
    229         * CERT_CopyOneGeneralName. With this calling path, if we pass
    230         * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent
    231         * call to CERT_CopyName, it assumes arena should be valid, hence
    232         * segmentation error (not sure this is a NSS bug, certainly it is
    233         * not consistent). But on the other hand, we don't want to keep an
    234         * arena record here explicitely for every PKIX_PL_GeneralName.
    235         * So I concluded it is better to use CERT_CreateGeneralNameList,
    236         * which keeps an arena pointer in its data structure and also masks
    237         * out details calls from this libpkix level.
    238         */
    239 
    240        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
    241        nssGenNameList = CERT_CreateGeneralNameList(nssAltName);
    242 
    243        if (nssGenNameList == NULL) {
    244                PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
    245        }
    246 
    247        genName->nssGeneralNameList = nssGenNameList;
    248 
    249        /* initialize fields */
    250        genName->type = nameType;
    251        genName->directoryName = NULL;
    252        genName->OthName = NULL;
    253        genName->other = NULL;
    254        genName->oid = NULL;
    255 
    256        switch (nameType){
    257        case certOtherName:
    258 
    259                PKIX_CHECK(pkix_pl_OtherName_Create
    260                            (nssAltName, &otherName, plContext),
    261                            PKIX_OTHERNAMECREATEFAILED);
    262 
    263                genName->OthName = otherName;
    264                break;
    265 
    266        case certDirectoryName:
    267 
    268                PKIX_CHECK(pkix_pl_DirectoryName_Create
    269                            (nssAltName, &pkixDN, plContext),
    270                            PKIX_DIRECTORYNAMECREATEFAILED);
    271 
    272                genName->directoryName = pkixDN;
    273                break;
    274        case certRegisterID:
    275                PKIX_CHECK(PKIX_PL_OID_CreateBySECItem(&nssAltName->name.other,
    276                                                       &pkixOID, plContext),
    277                            PKIX_OIDCREATEFAILED);
    278 
    279                genName->oid = pkixOID;
    280                break;
    281        case certDNSName:
    282        case certEDIPartyName:
    283        case certIPAddress:
    284        case certRFC822Name:
    285        case certX400Address:
    286        case certURI:
    287                genName->other = SECITEM_DupItem(&nssAltName->name.other);
    288                if (!genName->other) {
    289                    PKIX_ERROR(PKIX_OUTOFMEMORY);
    290                }     
    291                break;
    292        default:
    293                PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED);
    294        }
    295 
    296        *pGenName = genName;
    297        genName = NULL;
    298 
    299 cleanup:
    300        PKIX_DECREF(genName);
    301 
    302        PKIX_RETURN(GENERALNAME);
    303 }
    304 
    305 /*
    306 * FUNCTION: pkix_pl_GeneralName_ToString_Helper
    307 * DESCRIPTION:
    308 *
    309 *  Helper function that creates a string representation of the GeneralName
    310 *  pointed to by "name" and stores it at "pString" Different mechanisms are
    311 *  used to create the string, depending on the type of the GeneralName.
    312 *
    313 * PARAMETERS
    314 *  "name"
    315 *      Address of GeneralName whose string representation is desired.
    316 *      Must be non-NULL.
    317 *  "pString"
    318 *      Address where object pointer will be stored. Must be non-NULL.
    319 *  "plContext" - Platform-specific context pointer.
    320 * THREAD SAFETY:
    321 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    322 * RETURNS:
    323 *  Returns NULL if the function succeeds.
    324 *  Returns a GeneralName Error if the function fails in a non-fatal way.
    325 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    326 */
    327 static PKIX_Error *
    328 pkix_pl_GeneralName_ToString_Helper(
    329        PKIX_PL_GeneralName *name,
    330        PKIX_PL_String **pString,
    331        void *plContext)
    332 {
    333        PKIX_PL_X500Name *pkixDN = NULL;
    334        PKIX_PL_OID *pkixOID = NULL;
    335        char *x400AsciiName = NULL;
    336        char *ediPartyName = NULL;
    337        char *asciiName = NULL;
    338 
    339        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper");
    340        PKIX_NULLCHECK_TWO(name, pString);
    341 
    342        switch (name->type) {
    343        case certRFC822Name:
    344        case certDNSName:
    345        case certURI:
    346                /*
    347                 * Note that we can't use PKIX_ESCASCII here because
    348                 * name->other->data is not guaranteed to be null-terminated.
    349                 */
    350 
    351                PKIX_NULLCHECK_ONE(name->other);
    352 
    353                PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8,
    354                                                (name->other)->data,
    355                                                (name->other)->len,
    356                                                pString,
    357                                                plContext),
    358                            PKIX_STRINGCREATEFAILED);
    359                break;
    360        case certEDIPartyName:
    361                /* XXX print out the actual bytes */
    362                ediPartyName = "EDIPartyName: <DER-encoded value>";
    363                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
    364                                                ediPartyName,
    365                                                0,
    366                                                pString,
    367                                                plContext),
    368                            PKIX_STRINGCREATEFAILED);
    369                break;
    370        case certX400Address:
    371                /* XXX print out the actual bytes */
    372                x400AsciiName = "X400Address: <DER-encoded value>";
    373                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
    374                                                x400AsciiName,
    375                                                0,
    376                                                pString,
    377                                                plContext),
    378                            PKIX_STRINGCREATEFAILED);
    379                break;
    380        case certIPAddress:
    381                PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii
    382                            (name->other, &asciiName, plContext),
    383                            PKIX_IPADDRBYTES2ASCIIFAILED);
    384 
    385                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
    386                                                asciiName,
    387                                                0,
    388                                                pString,
    389                                                plContext),
    390                            PKIX_STRINGCREATEFAILED);
    391                break;
    392        case certOtherName:
    393                PKIX_NULLCHECK_ONE(name->OthName);
    394 
    395                /* we only print type-id - don't know how to print value */
    396                /* XXX print out the bytes of the value */
    397                PKIX_CHECK(pkix_pl_oidBytes2Ascii
    398                            (&name->OthName->oid, &asciiName, plContext),
    399                            PKIX_OIDBYTES2ASCIIFAILED);
    400 
    401                PKIX_CHECK(PKIX_PL_String_Create
    402                            (PKIX_ESCASCII,
    403                            asciiName,
    404                            0,
    405                            pString,
    406                            plContext),
    407                            PKIX_STRINGCREATEFAILED);
    408                break;
    409        case certRegisterID:
    410                pkixOID = name->oid;
    411                PKIX_CHECK(PKIX_PL_Object_ToString
    412                            ((PKIX_PL_Object *)pkixOID, pString, plContext),
    413                            PKIX_OIDTOSTRINGFAILED);
    414                break;
    415        case certDirectoryName:
    416                pkixDN = name->directoryName;
    417                PKIX_CHECK(PKIX_PL_Object_ToString
    418                            ((PKIX_PL_Object *)pkixDN, pString, plContext),
    419                            PKIX_X500NAMETOSTRINGFAILED);
    420                break;
    421        default:
    422                PKIX_ERROR
    423                        (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED);
    424        }
    425 
    426 cleanup:
    427 
    428        PKIX_FREE(asciiName);
    429 
    430        PKIX_RETURN(GENERALNAME);
    431 }
    432 
    433 /*
    434 * FUNCTION: pkix_pl_GeneralName_Destroy
    435 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
    436 */
    437 static PKIX_Error *
    438 pkix_pl_GeneralName_Destroy(
    439        PKIX_PL_Object *object,
    440        void *plContext)
    441 {
    442        PKIX_PL_GeneralName *name = NULL;
    443        SECItem secItemName;
    444        SECItem secItemOID;
    445 
    446        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Destroy");
    447        PKIX_NULLCHECK_ONE(object);
    448 
    449        PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
    450                    PKIX_OBJECTNOTGENERALNAME);
    451 
    452        name = (PKIX_PL_GeneralName *)object;
    453 
    454        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    455        SECITEM_FreeItem(name->other, PR_TRUE);
    456        name->other = NULL;
    457 
    458        if (name->OthName){
    459                secItemName = name->OthName->name;
    460                secItemOID = name->OthName->oid;
    461 
    462                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    463                SECITEM_FreeItem(&secItemName, PR_FALSE);
    464 
    465                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    466                SECITEM_FreeItem(&secItemOID, PR_FALSE);
    467 
    468                PKIX_FREE(name->OthName);
    469                name->OthName = NULL;
    470        }
    471 
    472        if (name->nssGeneralNameList != NULL) {
    473                PKIX_GENERALNAME_DEBUG
    474                        ("\t\tCalling CERT_DestroyGeneralNameList).\n");
    475                CERT_DestroyGeneralNameList(name->nssGeneralNameList);
    476        }
    477 
    478        PKIX_DECREF(name->directoryName);
    479        PKIX_DECREF(name->oid);
    480 
    481 cleanup:
    482 
    483        PKIX_RETURN(GENERALNAME);
    484 }
    485 
    486 /*
    487 * FUNCTION: pkix_pl_GeneralName_ToString
    488 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
    489 */
    490 static PKIX_Error *
    491 pkix_pl_GeneralName_ToString(
    492        PKIX_PL_Object *object,
    493        PKIX_PL_String **pString,
    494        void *plContext)
    495 {
    496        PKIX_PL_String *nameString = NULL;
    497        PKIX_PL_GeneralName *name = NULL;
    498 
    499        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_toString");
    500        PKIX_NULLCHECK_TWO(object, pString);
    501 
    502        PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
    503                    PKIX_OBJECTNOTGENERALNAME);
    504 
    505        name = (PKIX_PL_GeneralName *)object;
    506 
    507        PKIX_CHECK(pkix_pl_GeneralName_ToString_Helper
    508                    (name, &nameString, plContext),
    509                    PKIX_GENERALNAMETOSTRINGHELPERFAILED);
    510 
    511        *pString = nameString;
    512 
    513 cleanup:
    514 
    515 
    516 
    517        PKIX_RETURN(GENERALNAME);
    518 }
    519 
    520 /*
    521 * FUNCTION: pkix_pl_GeneralName_Hashcode
    522 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
    523 */
    524 static PKIX_Error *
    525 pkix_pl_GeneralName_Hashcode(
    526        PKIX_PL_Object *object,
    527        PKIX_UInt32 *pHashcode,
    528        void *plContext)
    529 {
    530        PKIX_PL_GeneralName *name = NULL;
    531        PKIX_UInt32 firstHash, secondHash, nameHash;
    532 
    533        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode");
    534        PKIX_NULLCHECK_TWO(object, pHashcode);
    535 
    536        PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
    537                    PKIX_OBJECTNOTGENERALNAME);
    538 
    539        name = (PKIX_PL_GeneralName *)object;
    540 
    541        switch (name->type) {
    542        case certRFC822Name:
    543        case certDNSName:
    544        case certX400Address:
    545        case certEDIPartyName:
    546        case certURI:
    547        case certIPAddress:
    548                PKIX_NULLCHECK_ONE(name->other);
    549                PKIX_CHECK(pkix_hash
    550                            ((const unsigned char *)
    551                            name->other->data,
    552                            name->other->len,
    553                            &nameHash,
    554                            plContext),
    555                            PKIX_HASHFAILED);
    556                break;
    557        case certRegisterID:
    558                PKIX_CHECK(PKIX_PL_Object_Hashcode
    559                            ((PKIX_PL_Object *)name->oid,
    560                            &nameHash,
    561                            plContext),
    562                            PKIX_OIDHASHCODEFAILED);
    563                break;
    564        case certOtherName:
    565                PKIX_NULLCHECK_ONE(name->OthName);
    566                PKIX_CHECK(pkix_hash
    567                            ((const unsigned char *)
    568                            name->OthName->oid.data,
    569                            name->OthName->oid.len,
    570                            &firstHash,
    571                            plContext),
    572                            PKIX_HASHFAILED);
    573 
    574                PKIX_CHECK(pkix_hash
    575                            ((const unsigned char *)
    576                            name->OthName->name.data,
    577                            name->OthName->name.len,
    578                            &secondHash,
    579                            plContext),
    580                            PKIX_HASHFAILED);
    581 
    582                nameHash = firstHash + secondHash;
    583                break;
    584        case certDirectoryName:
    585                PKIX_CHECK(PKIX_PL_Object_Hashcode
    586                            ((PKIX_PL_Object *)
    587                            name->directoryName,
    588                            &nameHash,
    589                            plContext),
    590                            PKIX_X500NAMEHASHCODEFAILED);
    591                break;
    592        }
    593 
    594        *pHashcode = nameHash;
    595 
    596 cleanup:
    597 
    598        PKIX_RETURN(GENERALNAME);
    599 
    600 }
    601 
    602 /*
    603 * FUNCTION: pkix_pl_GeneralName_Equals
    604 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
    605 */
    606 static PKIX_Error *
    607 pkix_pl_GeneralName_Equals(
    608        PKIX_PL_Object *firstObject,
    609        PKIX_PL_Object *secondObject,
    610        PKIX_Boolean *pResult,
    611        void *plContext)
    612 {
    613        PKIX_PL_GeneralName *firstName = NULL;
    614        PKIX_PL_GeneralName *secondName = NULL;
    615        PKIX_UInt32 secondType;
    616 
    617        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Equals");
    618        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
    619 
    620        /* test that firstObject is a GeneralName */
    621        PKIX_CHECK(pkix_CheckType
    622                    (firstObject, PKIX_GENERALNAME_TYPE, plContext),
    623                    PKIX_FIRSTOBJECTNOTGENERALNAME);
    624 
    625        /*
    626         * Since we know firstObject is a GeneralName, if both references are
    627         * identical, they must be equal
    628         */
    629        if (firstObject == secondObject){
    630                *pResult = PKIX_TRUE;
    631                goto cleanup;
    632        }
    633 
    634        /*
    635         * If secondObject isn't a GeneralName, we don't throw an error.
    636         * We simply return a Boolean result of FALSE
    637         */
    638        *pResult = PKIX_FALSE;
    639        PKIX_CHECK(PKIX_PL_Object_GetType
    640                    (secondObject, &secondType, plContext),
    641                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
    642        if (secondType != PKIX_GENERALNAME_TYPE){
    643                goto cleanup;
    644        }
    645 
    646        firstName = (PKIX_PL_GeneralName *)firstObject;
    647        secondName = (PKIX_PL_GeneralName *)secondObject;
    648 
    649        if (firstName->type != secondName->type){
    650                goto cleanup;
    651        }
    652 
    653        switch (firstName->type) {
    654        case certRFC822Name:
    655        case certDNSName:
    656        case certX400Address:
    657        case certEDIPartyName:
    658        case certURI:
    659        case certIPAddress:
    660                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
    661                if (SECITEM_CompareItem(firstName->other,
    662                                        secondName->other) != SECEqual) {
    663                        goto cleanup;
    664                }
    665                break;
    666        case certRegisterID:
    667                PKIX_CHECK(PKIX_PL_Object_Equals
    668                            ((PKIX_PL_Object *)firstName->oid,
    669                            (PKIX_PL_Object *)secondName->oid,
    670                            pResult,
    671                            plContext),
    672                            PKIX_OIDEQUALSFAILED);
    673                goto cleanup;
    674        case certOtherName:
    675                PKIX_NULLCHECK_TWO(firstName->OthName, secondName->OthName);
    676                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
    677                if (SECITEM_CompareItem(&firstName->OthName->oid,
    678                                        &secondName->OthName->oid)
    679                    != SECEqual ||
    680                    SECITEM_CompareItem(&firstName->OthName->name,
    681                                        &secondName->OthName->name)
    682                    != SECEqual) {
    683                        goto cleanup;
    684                }
    685                break;
    686        case certDirectoryName:
    687                PKIX_CHECK(PKIX_PL_Object_Equals
    688                            ((PKIX_PL_Object *)firstName->directoryName,
    689                            (PKIX_PL_Object *)secondName->directoryName,
    690                            pResult,
    691                            plContext),
    692                            PKIX_X500NAMEEQUALSFAILED);
    693                goto cleanup;
    694        }
    695 
    696        *pResult = PKIX_TRUE;
    697 
    698 cleanup:
    699 
    700        PKIX_RETURN(GENERALNAME);
    701 }
    702 
    703 /*
    704 * FUNCTION: pkix_pl_GeneralName_RegisterSelf
    705 * DESCRIPTION:
    706 *  Registers PKIX_GENERALNAME_TYPE and related functions with systemClasses[]
    707 * THREAD SAFETY:
    708 *  Not Thread Safe - for performance and complexity reasons
    709 *
    710 *  Since this function is only called by PKIX_PL_Initialize, which should
    711 *  only be called once, it is acceptable that this function is not
    712 *  thread-safe.
    713 */
    714 PKIX_Error *
    715 pkix_pl_GeneralName_RegisterSelf(void *plContext)
    716 {
    717 
    718        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    719        pkix_ClassTable_Entry entry;
    720 
    721        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_RegisterSelf");
    722 
    723        entry.description = "GeneralName";
    724        entry.objCounter = 0;
    725        entry.typeObjectSize = sizeof(PKIX_PL_GeneralName);
    726        entry.destructor = pkix_pl_GeneralName_Destroy;
    727        entry.equalsFunction = pkix_pl_GeneralName_Equals;
    728        entry.hashcodeFunction = pkix_pl_GeneralName_Hashcode;
    729        entry.toStringFunction = pkix_pl_GeneralName_ToString;
    730        entry.comparator = NULL;
    731        entry.duplicateFunction = pkix_duplicateImmutable;
    732 
    733        systemClasses[PKIX_GENERALNAME_TYPE] = entry;
    734 
    735        PKIX_RETURN(GENERALNAME);
    736 }
    737 
    738 /* --Public-Functions------------------------------------------------------- */
    739 
    740 #ifdef BUILD_LIBPKIX_TESTS
    741 /*
    742 * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h)
    743 */
    744 PKIX_Error *
    745 PKIX_PL_GeneralName_Create(
    746        PKIX_UInt32 nameType,
    747        PKIX_PL_String *stringRep,
    748        PKIX_PL_GeneralName **pGName,
    749        void *plContext)
    750 {
    751        PKIX_PL_X500Name *pkixDN = NULL;
    752        PKIX_PL_OID *pkixOID = NULL;
    753        SECItem *secItem = NULL;
    754        char *asciiString = NULL;
    755        PKIX_UInt32 length = 0;
    756        PKIX_PL_GeneralName *genName = NULL;
    757        CERTGeneralName *nssGenName = NULL;
    758        CERTGeneralNameList *nssGenNameList = NULL;
    759        CERTName *nssCertName = NULL;
    760        PLArenaPool *arena = NULL;
    761 
    762        PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create");
    763        PKIX_NULLCHECK_TWO(pGName, stringRep);
    764 
    765        PKIX_CHECK(PKIX_PL_String_GetEncoded
    766                    (stringRep,
    767                    PKIX_ESCASCII,
    768                    (void **)&asciiString,
    769                    &length,
    770                    plContext),
    771                    PKIX_STRINGGETENCODEDFAILED);
    772 
    773        /* Create a temporary CERTGeneralName */
    774        PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n");
    775        length = PL_strlen(asciiString);
    776        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
    777        secItem = SECITEM_AllocItem(NULL, NULL, length);
    778        PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n");
    779        (void) PORT_Memcpy(secItem->data, asciiString, length);
    780        PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
    781        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    782        if (arena == NULL) {
    783                PKIX_ERROR(PKIX_OUTOFMEMORY);
    784        }
    785        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n");
    786        nssGenName = CERT_NewGeneralName(arena, nameType);
    787        if (nssGenName == NULL) {
    788                PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED);
    789        }
    790 
    791        switch (nameType) {
    792        case certRFC822Name:
    793        case certDNSName:
    794        case certURI:
    795                nssGenName->name.other = *secItem;
    796                break;
    797 
    798        case certDirectoryName:
    799 
    800                PKIX_CHECK(PKIX_PL_X500Name_Create
    801                            (stringRep, &pkixDN, plContext),
    802                            PKIX_X500NAMECREATEFAILED);
    803 
    804                PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n");
    805                nssCertName = CERT_AsciiToName(asciiString);
    806                nssGenName->name.directoryName = *nssCertName;
    807                break;
    808 
    809        case certRegisterID:
    810                PKIX_CHECK(PKIX_PL_OID_Create
    811                            (asciiString, &pkixOID, plContext),
    812                            PKIX_OIDCREATEFAILED);
    813                nssGenName->name.other = *secItem;
    814                break;
    815        default:
    816                /* including IPAddress, EDIPartyName, OtherName, X400Address */
    817                PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE);
    818        }
    819 
    820        /* create a PKIX_PL_GeneralName object */
    821        PKIX_CHECK(PKIX_PL_Object_Alloc
    822                    (PKIX_GENERALNAME_TYPE,
    823                    sizeof (PKIX_PL_GeneralName),
    824                    (PKIX_PL_Object **)&genName,
    825                    plContext),
    826                    PKIX_COULDNOTCREATEOBJECT);
    827 
    828        /* create a CERTGeneralNameList */
    829        nssGenName->type = nameType;
    830        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
    831        nssGenNameList = CERT_CreateGeneralNameList(nssGenName);
    832        if (nssGenNameList == NULL) {
    833                PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
    834        }
    835        genName->nssGeneralNameList = nssGenNameList;
    836 
    837        /* initialize fields */
    838        genName->type = nameType;
    839        genName->directoryName = pkixDN;
    840        genName->OthName = NULL;
    841        genName->other = secItem;
    842        genName->oid = pkixOID;
    843 
    844        *pGName = genName;
    845 cleanup:
    846 
    847        PKIX_FREE(asciiString);
    848 
    849        if (nssCertName != NULL) {
    850                PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n");
    851                CERT_DestroyName(nssCertName);
    852        }
    853 
    854        if (arena){ /* will free nssGenName */
    855                PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
    856                PORT_FreeArena(arena, PR_FALSE);
    857        }
    858 
    859        if (PKIX_ERROR_RECEIVED){
    860                PKIX_DECREF(pkixDN);
    861                PKIX_DECREF(pkixOID);
    862 
    863                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
    864                if (secItem){
    865                        SECITEM_FreeItem(secItem, PR_TRUE);
    866                        secItem = NULL;
    867                }
    868        }
    869 
    870        PKIX_RETURN(GENERALNAME);
    871 }
    872 
    873 #endif /* BUILD_LIBPKIX_TESTS */