tor-browser

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

pkix_pl_x500name.c (19535B)


      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_x500name.c
      6 *
      7 * X500Name Object Functions
      8 *
      9 */
     10 
     11 #include "pkix_pl_x500name.h"
     12 
     13 /* --Private-X500Name-Functions------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_pl_X500Name_Destroy
     17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     18 */
     19 static PKIX_Error *
     20 pkix_pl_X500Name_Destroy(
     21        PKIX_PL_Object *object,
     22        void *plContext)
     23 {
     24        PKIX_PL_X500Name *name = NULL;
     25 
     26        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Destroy");
     27        PKIX_NULLCHECK_ONE(object);
     28 
     29        PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
     30                    PKIX_OBJECTNOTANX500NAME);
     31 
     32        name = (PKIX_PL_X500Name *)object;
     33 
     34        /* PORT_FreeArena will destroy arena, and, allocated on it, CERTName
     35         * and SECItem */
     36        if (name->arena) {
     37            PORT_FreeArena(name->arena, PR_FALSE);
     38            name->arena = NULL;
     39        }
     40 
     41 cleanup:
     42 
     43        PKIX_RETURN(X500NAME);
     44 }
     45 
     46 /*
     47 * FUNCTION: pkix_pl_X500Name_ToString
     48 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
     49 */
     50 static PKIX_Error *
     51 pkix_pl_X500Name_ToString(
     52        PKIX_PL_Object *object,
     53        PKIX_PL_String **pString,
     54        void *plContext)
     55 {
     56        PKIX_PL_X500Name *name = NULL;
     57        char *string = NULL;
     58        PKIX_UInt32 strLength = 0;
     59 
     60        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_toString");
     61        PKIX_NULLCHECK_TWO(object, pString);
     62 
     63        PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
     64                    PKIX_OBJECTNOTANX500NAME);
     65 
     66        name = (PKIX_PL_X500Name *)object;
     67        string = CERT_NameToAscii(&name->nssDN);
     68        if (!string){
     69                PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED);
     70        }
     71        strLength = PL_strlen(string);
     72 
     73        PKIX_CHECK(PKIX_PL_String_Create
     74                    (PKIX_ESCASCII, string, strLength, pString, plContext),
     75                    PKIX_STRINGCREATEFAILED);
     76 
     77 cleanup:
     78 
     79        PKIX_RETURN(X500NAME);
     80 }
     81 
     82 /*
     83 * FUNCTION: pkix_pl_X500Name_Hashcode
     84 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
     85 */
     86 static PKIX_Error *
     87 pkix_pl_X500Name_Hashcode(
     88        PKIX_PL_Object *object,
     89        PKIX_UInt32 *pHashcode,
     90        void *plContext)
     91 {
     92        PKIX_PL_X500Name *name = NULL;
     93        SECItem *derBytes = NULL;
     94        PKIX_UInt32 nameHash;
     95 
     96        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Hashcode");
     97        PKIX_NULLCHECK_TWO(object, pHashcode);
     98 
     99        PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
    100                    PKIX_OBJECTNOTANX500NAME);
    101 
    102        name = (PKIX_PL_X500Name *)object;
    103 
    104        /* we hash over the bytes in the DER encoding */
    105 
    106        derBytes = &name->derName;
    107 
    108        PKIX_CHECK(pkix_hash
    109                    (derBytes->data, derBytes->len, &nameHash, plContext),
    110                    PKIX_HASHFAILED);
    111 
    112        *pHashcode = nameHash;
    113 
    114 cleanup:
    115 
    116        PKIX_RETURN(X500NAME);
    117 }
    118 
    119 
    120 /*
    121 * FUNCTION: pkix_pl_X500Name_Equals
    122 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
    123 */
    124 static PKIX_Error *
    125 pkix_pl_X500Name_Equals(
    126        PKIX_PL_Object *firstObject,
    127        PKIX_PL_Object *secondObject,
    128        PKIX_Boolean *pResult,
    129        void *plContext)
    130 {
    131        PKIX_UInt32 secondType;
    132 
    133        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Equals");
    134        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
    135 
    136        /* test that firstObject is an X500Name */
    137        PKIX_CHECK(pkix_CheckType(firstObject, PKIX_X500NAME_TYPE, plContext),
    138                    PKIX_FIRSTOBJECTARGUMENTNOTANX500NAME);
    139 
    140        /*
    141         * Since we know firstObject is an X500Name, if both references are
    142         * identical, they must be equal
    143         */
    144        if (firstObject == secondObject){
    145                *pResult = PKIX_TRUE;
    146                goto cleanup;
    147        }
    148 
    149        /*
    150         * If secondObject isn't an X500Name, we don't throw an error.
    151         * We simply return a Boolean result of FALSE
    152         */
    153        *pResult = PKIX_FALSE;
    154        PKIX_CHECK(PKIX_PL_Object_GetType
    155                    (secondObject, &secondType, plContext),
    156                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
    157        if (secondType != PKIX_X500NAME_TYPE) goto cleanup;
    158 
    159        PKIX_CHECK(
    160            PKIX_PL_X500Name_Match((PKIX_PL_X500Name *)firstObject,
    161                                   (PKIX_PL_X500Name *)secondObject,
    162                                   pResult, plContext),
    163            PKIX_X500NAMEMATCHFAILED);
    164 
    165 cleanup:
    166 
    167        PKIX_RETURN(X500NAME);
    168 }
    169 
    170 /*
    171 * FUNCTION: pkix_pl_X500Name_RegisterSelf
    172 * DESCRIPTION:
    173 *  Registers PKIX_X500NAME_TYPE and its related functions with systemClasses[]
    174 * THREAD SAFETY:
    175 *  Not Thread Safe - for performance and complexity reasons
    176 *
    177 *  Since this function is only called by PKIX_PL_Initialize, which should
    178 *  only be called once, it is acceptable that this function is not
    179 *  thread-safe.
    180 */
    181 PKIX_Error *
    182 pkix_pl_X500Name_RegisterSelf(void *plContext)
    183 {
    184 
    185        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    186        pkix_ClassTable_Entry entry;
    187 
    188        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_RegisterSelf");
    189 
    190        entry.description = "X500Name";
    191        entry.objCounter = 0;
    192        entry.typeObjectSize = sizeof(PKIX_PL_X500Name);
    193        entry.destructor = pkix_pl_X500Name_Destroy;
    194        entry.equalsFunction = pkix_pl_X500Name_Equals;
    195        entry.hashcodeFunction = pkix_pl_X500Name_Hashcode;
    196        entry.toStringFunction = pkix_pl_X500Name_ToString;
    197        entry.comparator = NULL;
    198        entry.duplicateFunction = pkix_duplicateImmutable;
    199 
    200        systemClasses[PKIX_X500NAME_TYPE] = entry;
    201 
    202        PKIX_RETURN(X500NAME);
    203 }
    204 
    205 #ifdef BUILD_LIBPKIX_TESTS
    206 /*
    207 * FUNCTION: pkix_pl_X500Name_CreateFromUtf8
    208 *
    209 * DESCRIPTION:
    210 *  Creates an X500Name object from the RFC1485 string representation pointed
    211 *  to by "stringRep", and stores the result at "pName". If the string cannot
    212 *  be successfully converted, a non-fatal error is returned.
    213 *
    214 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed to be
    215 * called only by pkix tests programs.
    216 * 
    217 * PARAMETERS:
    218 *  "stringRep"
    219 *      Address of the RFC1485 string to be converted. Must be non-NULL.
    220 *  "pName"
    221 *      Address where the X500Name result will be stored. Must be non-NULL.
    222 *  "plContext"
    223 *      Platform-specific context pointer.
    224 *
    225 * THREAD SAFETY:
    226 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    227 *
    228 * RETURNS:
    229 *  Returns NULL if the function succeeds.
    230 *  Returns an X500NAME Error if the function fails in a non-fatal way.
    231 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    232 */
    233 PKIX_Error *
    234 pkix_pl_X500Name_CreateFromUtf8(
    235        char *stringRep,
    236        PKIX_PL_X500Name **pName,
    237        void *plContext)
    238 {
    239        PKIX_PL_X500Name *x500Name = NULL;
    240        PLArenaPool *arena = NULL;
    241        CERTName *nssDN = NULL;
    242        SECItem *resultSecItem = NULL;
    243        
    244        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_CreateFromUtf8");
    245        PKIX_NULLCHECK_TWO(pName, stringRep);
    246 
    247        nssDN = CERT_AsciiToName(stringRep);
    248        if (nssDN == NULL) {
    249            PKIX_ERROR(PKIX_COULDNOTCREATENSSDN);
    250        }
    251 
    252        arena = nssDN->arena;
    253 
    254        /* create a PKIX_PL_X500Name object */
    255        PKIX_CHECK(PKIX_PL_Object_Alloc
    256                    (PKIX_X500NAME_TYPE,
    257                    sizeof (PKIX_PL_X500Name),
    258                    (PKIX_PL_Object **)&x500Name,
    259                    plContext),
    260                    PKIX_COULDNOTCREATEX500NAMEOBJECT);
    261 
    262        /* populate the nssDN field */
    263        x500Name->arena = arena;
    264        x500Name->nssDN.arena = arena;
    265        x500Name->nssDN.rdns = nssDN->rdns;
    266        
    267        resultSecItem =
    268            SEC_ASN1EncodeItem(arena, &x500Name->derName, nssDN,
    269                               CERT_NameTemplate);
    270        
    271        if (resultSecItem == NULL){
    272            PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
    273        }
    274 
    275        *pName = x500Name;
    276 
    277 cleanup:
    278 
    279        if (PKIX_ERROR_RECEIVED){
    280            if (x500Name) {
    281                PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name,
    282                                      plContext);
    283            } else if (nssDN) {
    284                CERT_DestroyName(nssDN);
    285            }
    286        }
    287 
    288        PKIX_RETURN(X500NAME);
    289 }
    290 #endif /* BUILD_LIBPKIX_TESTS */
    291 
    292 /*
    293 * FUNCTION: pkix_pl_X500Name_GetCERTName
    294 *
    295 * DESCRIPTION:
    296 * 
    297 * Returns the pointer to CERTName member of X500Name structure.
    298 *
    299 * Returned pointed should not be freed.2
    300 *
    301 * PARAMETERS:
    302 *  "xname"
    303 *      Address of X500Name whose OrganizationName is to be extracted. Must be
    304 *      non-NULL.
    305 *  "pCERTName"
    306 *      Address where result will be stored. Must be non-NULL.
    307 *  "plContext"
    308 *      Platform-specific context pointer.
    309 *
    310 * THREAD SAFETY:
    311 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    312 *
    313 * RETURNS:
    314 *  Returns NULL if the function succeeds.
    315 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    316 */
    317 PKIX_Error *
    318 pkix_pl_X500Name_GetCERTName(
    319        PKIX_PL_X500Name *xname,
    320        CERTName **pCERTName,
    321        void *plContext)
    322 {
    323        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCERTName");
    324        PKIX_NULLCHECK_TWO(xname, pCERTName);
    325 
    326        *pCERTName = &xname->nssDN;
    327 
    328        PKIX_RETURN(X500NAME);
    329 }
    330 
    331 /* --Public-Functions------------------------------------------------------- */
    332 
    333 /*
    334 * FUNCTION: PKIX_PL_X500Name_CreateFromCERTName (see comments in pkix_pl_pki.h)
    335 */
    336 
    337 PKIX_Error *
    338 PKIX_PL_X500Name_CreateFromCERTName(
    339        SECItem *derName,
    340        CERTName *name, 
    341        PKIX_PL_X500Name **pName,
    342        void *plContext)
    343 {
    344        PLArenaPool *arena = NULL;
    345        SECStatus rv = SECFailure;
    346        PKIX_PL_X500Name *x500Name = NULL;
    347 
    348        PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_CreateFromCERTName");
    349        PKIX_NULLCHECK_ONE(pName);
    350        if (derName == NULL && name == NULL) {
    351            PKIX_ERROR(PKIX_NULLARGUMENT);
    352        }
    353 
    354        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    355        if (arena == NULL) {
    356            PKIX_ERROR(PKIX_OUTOFMEMORY);
    357        }
    358        
    359        PKIX_CHECK(PKIX_PL_Object_Alloc
    360                    (PKIX_X500NAME_TYPE,
    361                    sizeof (PKIX_PL_X500Name),
    362                    (PKIX_PL_Object **)&x500Name,
    363                    plContext),
    364                    PKIX_COULDNOTCREATEX500NAMEOBJECT);
    365 
    366        x500Name->arena = arena;
    367        x500Name->nssDN.arena = NULL;
    368 
    369        if (derName != NULL) {
    370            rv = SECITEM_CopyItem(arena, &x500Name->derName, derName);
    371            if (rv == SECFailure) {
    372                PKIX_ERROR(PKIX_OUTOFMEMORY);
    373            }
    374        }            
    375 
    376        if (name != NULL) {
    377            rv = CERT_CopyName(arena, &x500Name->nssDN, name);
    378            if (rv == SECFailure) {
    379                PKIX_ERROR(PKIX_CERTCOPYNAMEFAILED);
    380            }
    381        } else {
    382            rv = SEC_QuickDERDecodeItem(arena, &x500Name->nssDN,
    383                                        CERT_NameTemplate,
    384                                        &x500Name->derName);
    385            if (rv == SECFailure) {
    386                PKIX_ERROR(PKIX_SECQUICKDERDECODERFAILED);
    387            }
    388        }
    389 
    390        *pName = x500Name;
    391 
    392 cleanup:
    393        if (PKIX_ERROR_RECEIVED) {
    394            if (x500Name) {
    395                PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name,
    396                                      plContext);
    397            } else if (arena) {                
    398                PORT_FreeArena(arena, PR_FALSE);
    399            }
    400        }
    401 
    402        PKIX_RETURN(X500NAME);
    403 }
    404 
    405 #ifdef BUILD_LIBPKIX_TESTS
    406 /*
    407 * FUNCTION: PKIX_PL_X500Name_Create (see comments in pkix_pl_pki.h)
    408 *
    409 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed
    410 * to be called only by pkix tests programs.
    411 */
    412 PKIX_Error *
    413 PKIX_PL_X500Name_Create(
    414        PKIX_PL_String *stringRep,
    415        PKIX_PL_X500Name **pName,
    416        void *plContext)
    417 {
    418        char *utf8String = NULL;
    419        PKIX_UInt32 utf8Length = 0;
    420 
    421        PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Create");
    422        PKIX_NULLCHECK_TWO(pName, stringRep);
    423 
    424        /*
    425         * convert the input PKIX_PL_String to PKIX_UTF8_NULL_TERM.
    426         * we need to use this format specifier because
    427         * CERT_AsciiToName expects a NULL-terminated UTF8 string.
    428         * Since UTF8 allow NUL characters in the middle of the
    429         * string, this is buggy. However, as a workaround, using
    430         * PKIX_UTF8_NULL_TERM gives us a NULL-terminated UTF8 string.
    431         */
    432 
    433        PKIX_CHECK(PKIX_PL_String_GetEncoded
    434                    (stringRep,
    435                    PKIX_UTF8_NULL_TERM,
    436                    (void **)&utf8String,
    437                    &utf8Length,
    438                    plContext),
    439                    PKIX_STRINGGETENCODEDFAILED);
    440 
    441        PKIX_CHECK(
    442            pkix_pl_X500Name_CreateFromUtf8(utf8String,
    443                                            pName, plContext),
    444            PKIX_X500NAMECREATEFROMUTF8FAILED);
    445 
    446 cleanup:
    447        PKIX_FREE(utf8String);
    448 
    449        PKIX_RETURN(X500NAME);
    450 }
    451 #endif /* BUILD_LIBPKIX_TESTS */
    452 
    453 /*
    454 * FUNCTION: PKIX_PL_X500Name_Match (see comments in pkix_pl_pki.h)
    455 */
    456 PKIX_Error *
    457 PKIX_PL_X500Name_Match(
    458        PKIX_PL_X500Name *firstX500Name,
    459        PKIX_PL_X500Name *secondX500Name,
    460        PKIX_Boolean *pResult,
    461        void *plContext)
    462 {
    463        SECItem *firstDerName = NULL;
    464        SECItem *secondDerName = NULL;
    465        SECComparison cmpResult;
    466 
    467        PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Match");
    468        PKIX_NULLCHECK_THREE(firstX500Name, secondX500Name, pResult);
    469 
    470        if (firstX500Name == secondX500Name){
    471                *pResult = PKIX_TRUE;
    472                goto cleanup;
    473        }
    474 
    475        firstDerName = &firstX500Name->derName;
    476        secondDerName = &secondX500Name->derName;
    477 
    478        PKIX_NULLCHECK_TWO(firstDerName->data, secondDerName->data);
    479 
    480        cmpResult = SECITEM_CompareItem(firstDerName, secondDerName);
    481        if (cmpResult != SECEqual) {
    482            cmpResult = CERT_CompareName(&firstX500Name->nssDN,
    483                                         &secondX500Name->nssDN);
    484        }
    485 
    486        *pResult = (cmpResult == SECEqual);
    487                   
    488 cleanup:
    489 
    490        PKIX_RETURN(X500NAME);
    491 }
    492 
    493 /*
    494 * FUNCTION: pkix_pl_X500Name_GetSECName
    495 *
    496 * DESCRIPTION:
    497 *  Returns a copy of CERTName DER representation allocated on passed in arena.
    498 *  If allocation on arena can not be done, NULL is stored at "pSECName".
    499 *
    500 * PARAMETERS:
    501 *  "xname"
    502 *      Address of X500Name whose CERTName flag is to be encoded. Must be
    503 *      non-NULL.
    504 *  "arena"
    505 *      Address of the PLArenaPool to be used in the encoding, and in which
    506 *      "pSECName" will be allocated. Must be non-NULL.
    507 *  "pSECName"
    508 *      Address where result will be stored. Must be non-NULL.
    509 *  "plContext"
    510 *      Platform-specific context pointer.
    511 *
    512 * THREAD SAFETY:
    513 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    514 *
    515 * RETURNS:
    516 *  Returns NULL if the function succeeds.
    517 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    518 */
    519 PKIX_Error *
    520 pkix_pl_X500Name_GetDERName(
    521        PKIX_PL_X500Name *xname,
    522        PLArenaPool *arena,
    523        SECItem **pDERName,
    524        void *plContext)
    525 {
    526        SECItem *derName = NULL;
    527 
    528        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetDERName");
    529 
    530        PKIX_NULLCHECK_THREE(xname, arena, pDERName);
    531 
    532        /* Return NULL is X500Name was not created from DER  */
    533        if (xname->derName.data == NULL) {
    534            *pDERName = NULL;
    535            goto cleanup;
    536        }
    537 
    538        derName = SECITEM_ArenaDupItem(arena, &xname->derName);
    539        if (derName == NULL) {
    540            PKIX_ERROR(PKIX_OUTOFMEMORY);
    541        }
    542 
    543        *pDERName = derName;
    544 cleanup:
    545 
    546        PKIX_RETURN(X500NAME);
    547 }
    548 
    549 /*
    550 * FUNCTION: pkix_pl_X500Name_GetCommonName
    551 *
    552 * DESCRIPTION:
    553 *  Extracts the CommonName component of the X500Name object pointed to by
    554 *  "xname", and stores the result at "pCommonName". If the CommonName cannot
    555 *  be successfully extracted, NULL is stored at "pCommonName".
    556 *
    557 *  The returned string must be freed with PORT_Free.
    558 *
    559 * PARAMETERS:
    560 *  "xname"
    561 *      Address of X500Name whose CommonName is to be extracted. Must be
    562 *      non-NULL.
    563 *  "pCommonName"
    564 *      Address where result will be stored. Must be non-NULL.
    565 *  "plContext"
    566 *      Platform-specific context pointer.
    567 *
    568 * THREAD SAFETY:
    569 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    570 *
    571 * RETURNS:
    572 *  Returns NULL if the function succeeds.
    573 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    574 */
    575 PKIX_Error *
    576 pkix_pl_X500Name_GetCommonName(
    577        PKIX_PL_X500Name *xname,
    578        unsigned char **pCommonName,
    579        void *plContext)
    580 {
    581        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCommonName");
    582        PKIX_NULLCHECK_TWO(xname, pCommonName);
    583 
    584        *pCommonName = (unsigned char *)CERT_GetCommonName(&xname->nssDN);
    585 
    586        PKIX_RETURN(X500NAME);
    587 }
    588 
    589 /*
    590 * FUNCTION: pkix_pl_X500Name_GetCountryName
    591 *
    592 * DESCRIPTION:
    593 *  Extracts the CountryName component of the X500Name object pointed to by
    594 *  "xname", and stores the result at "pCountryName". If the CountryName cannot
    595 *  be successfully extracted, NULL is stored at "pCountryName".
    596 *
    597 *  The returned string must be freed with PORT_Free.
    598 *
    599 * PARAMETERS:
    600 *  "xname"
    601 *      Address of X500Name whose CountryName is to be extracted. Must be
    602 *      non-NULL.
    603 *  "pCountryName"
    604 *      Address where result will be stored. Must be non-NULL.
    605 *  "plContext"
    606 *      Platform-specific context pointer.
    607 *
    608 * THREAD SAFETY:
    609 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    610 *
    611 * RETURNS:
    612 *  Returns NULL if the function succeeds.
    613 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    614 */
    615 PKIX_Error *
    616 pkix_pl_X500Name_GetCountryName(
    617        PKIX_PL_X500Name *xname,
    618        unsigned char **pCountryName,
    619        void *plContext)
    620 {
    621        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCountryName");
    622        PKIX_NULLCHECK_TWO(xname, pCountryName);
    623 
    624        *pCountryName = (unsigned char*)CERT_GetCountryName(&xname->nssDN);
    625 
    626        PKIX_RETURN(X500NAME);
    627 }
    628 
    629 /*
    630 * FUNCTION: pkix_pl_X500Name_GetOrgName
    631 *
    632 * DESCRIPTION:
    633 *  Extracts the OrganizationName component of the X500Name object pointed to by
    634 *  "xname", and stores the result at "pOrgName". If the OrganizationName cannot
    635 *  be successfully extracted, NULL is stored at "pOrgName".
    636 *
    637 *  The returned string must be freed with PORT_Free.
    638 *
    639 * PARAMETERS:
    640 *  "xname"
    641 *      Address of X500Name whose OrganizationName is to be extracted. Must be
    642 *      non-NULL.
    643 *  "pOrgName"
    644 *      Address where result will be stored. Must be non-NULL.
    645 *  "plContext"
    646 *      Platform-specific context pointer.
    647 *
    648 * THREAD SAFETY:
    649 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    650 *
    651 * RETURNS:
    652 *  Returns NULL if the function succeeds.
    653 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    654 */
    655 PKIX_Error *
    656 pkix_pl_X500Name_GetOrgName(
    657        PKIX_PL_X500Name *xname,
    658        unsigned char **pOrgName,
    659        void *plContext)
    660 {
    661        PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetOrgName");
    662        PKIX_NULLCHECK_TWO(xname, pOrgName);
    663 
    664        *pOrgName = (unsigned char*)CERT_GetOrgName(&xname->nssDN);
    665 
    666        PKIX_RETURN(X500NAME);
    667 }