tor-browser

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

pkix_pl_nameconstraints.c (44118B)


      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_nameconstraints.c
      6 *
      7 * Name Constraints Object Functions Definitions
      8 *
      9 */
     10 
     11 #include "pkix_pl_nameconstraints.h"
     12 
     13 
     14 /* --Private-NameConstraints-Functions----------------------------- */
     15 
     16 /*
     17 * FUNCTION: pkix_pl_CertNameConstraints_GetPermitted
     18 * DESCRIPTION:
     19 *
     20 *  This function retrieve name constraints permitted list from NSS
     21 *  data in "nameConstraints" and returns a PKIX_PL_GeneralName list
     22 *  in "pPermittedList".
     23 *
     24 * PARAMETERS
     25 *  "nameConstraints"
     26 *      Address of CertNameConstraints which has a pointer to
     27 *      CERTNameConstraints data. Must be non-NULL.
     28 *  "pPermittedList"
     29 *      Address where returned permitted name list is stored. Must be non-NULL.
     30 *  "plContext" - Platform-specific context pointer.
     31 * THREAD SAFETY:
     32 *  Conditionally Thread Safe
     33 *      (see Thread Safety Definitions in Programmer's Guide)
     34 * RETURNS:
     35 *  Returns NULL if the function succeeds.
     36 *  Returns a NameConstraints Error if the function fails in a
     37 *  non-fatal way.
     38 *  Returns a Fatal Error if the function fails in an unrecoverable way.
     39 */
     40 static PKIX_Error *
     41 pkix_pl_CertNameConstraints_GetPermitted(
     42        PKIX_PL_CertNameConstraints *nameConstraints,
     43        PKIX_List **pPermittedList,
     44        void *plContext)
     45 {
     46        CERTNameConstraints *nssNameConstraints = NULL;
     47        CERTNameConstraints **nssNameConstraintsList = NULL;
     48        CERTNameConstraint *nssPermitted = NULL;
     49        CERTNameConstraint *firstPermitted = NULL;
     50        PKIX_List *permittedList = NULL;
     51        PKIX_PL_GeneralName *name = NULL;
     52        PKIX_UInt32 numItems = 0;
     53        PKIX_UInt32 i;
     54 
     55        PKIX_ENTER(CERTNAMECONSTRAINTS,
     56                "pkix_pl_CertNameConstraints_GetPermitted");
     57        PKIX_NULLCHECK_TWO(nameConstraints, pPermittedList);
     58 
     59        /*
     60         * nssNameConstraints is an array of CERTNameConstraints
     61         * pointers where CERTNameConstraints keep its permitted and excluded
     62         * lists as pointer array of CERTNameConstraint.
     63         */
     64 
     65        if (nameConstraints->permittedList == NULL) {
     66 
     67            PKIX_OBJECT_LOCK(nameConstraints);
     68 
     69            if (nameConstraints->permittedList == NULL) {
     70 
     71                PKIX_CHECK(PKIX_List_Create(&permittedList, plContext),
     72                        PKIX_LISTCREATEFAILED);
     73 
     74                numItems = nameConstraints->numNssNameConstraints;
     75                nssNameConstraintsList =
     76                        nameConstraints->nssNameConstraintsList;
     77 
     78                for (i = 0; i < numItems; i++) {
     79 
     80                    PKIX_NULLCHECK_ONE(nssNameConstraintsList);
     81                    nssNameConstraints = *(nssNameConstraintsList + i);
     82                    PKIX_NULLCHECK_ONE(nssNameConstraints);
     83 
     84                    if (nssNameConstraints->permited != NULL) {
     85 
     86                        nssPermitted = nssNameConstraints->permited;
     87                        firstPermitted = nssPermitted;
     88 
     89                        do {
     90 
     91                            PKIX_CHECK(pkix_pl_GeneralName_Create
     92                                (&nssPermitted->name, &name, plContext),
     93                                PKIX_GENERALNAMECREATEFAILED);
     94 
     95                            PKIX_CHECK(PKIX_List_AppendItem
     96                                (permittedList,
     97                                (PKIX_PL_Object *)name,
     98                                plContext),
     99                                PKIX_LISTAPPENDITEMFAILED);
    100 
    101                            PKIX_DECREF(name);
    102 
    103                            PKIX_CERTNAMECONSTRAINTS_DEBUG
    104                                ("\t\tCalling CERT_GetNextNameConstraint\n");
    105                            nssPermitted = CERT_GetNextNameConstraint
    106                                (nssPermitted);
    107 
    108                        } while (nssPermitted != firstPermitted);
    109 
    110                    }
    111                }
    112 
    113                PKIX_CHECK(PKIX_List_SetImmutable(permittedList, plContext),
    114                            PKIX_LISTSETIMMUTABLEFAILED);
    115 
    116                nameConstraints->permittedList = permittedList;
    117 
    118            }
    119 
    120            PKIX_OBJECT_UNLOCK(nameConstraints);
    121 
    122        }
    123 
    124        PKIX_INCREF(nameConstraints->permittedList);
    125 
    126        *pPermittedList = nameConstraints->permittedList;
    127 
    128 cleanup:
    129 
    130        PKIX_RETURN(CERTNAMECONSTRAINTS);
    131 }
    132 
    133 /*
    134 * FUNCTION: pkix_pl_CertNameConstraints_GetExcluded
    135 * DESCRIPTION:
    136 *
    137 *  This function retrieve name constraints excluded list from NSS
    138 *  data in "nameConstraints" and returns a PKIX_PL_GeneralName list
    139 *  in "pExcludedList".
    140 *
    141 * PARAMETERS
    142 *  "nameConstraints"
    143 *      Address of CertNameConstraints which has a pointer to NSS data.
    144 *      Must be non-NULL.
    145 *  "pPermittedList"
    146 *      Address where returned excluded name list is stored. Must be non-NULL.
    147 *  "plContext" - Platform-specific context pointer.
    148 * THREAD SAFETY:
    149 *  Conditionally Thread Safe
    150 *      (see Thread Safety Definitions in Programmer's Guide)
    151 * RETURNS:
    152 *  Returns NULL if the function succeeds.
    153 *  Returns a NameConstraints Error if the function fails in a
    154 *  non-fatal way.
    155 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    156 */
    157 static PKIX_Error *
    158 pkix_pl_CertNameConstraints_GetExcluded(
    159        PKIX_PL_CertNameConstraints *nameConstraints,
    160        PKIX_List **pExcludedList,
    161        void *plContext)
    162 {
    163        CERTNameConstraints *nssNameConstraints = NULL;
    164        CERTNameConstraints **nssNameConstraintsList = NULL;
    165        CERTNameConstraint *nssExcluded = NULL;
    166        CERTNameConstraint *firstExcluded = NULL;
    167        PKIX_List *excludedList = NULL;
    168        PKIX_PL_GeneralName *name = NULL;
    169        PKIX_UInt32 numItems = 0;
    170        PKIX_UInt32 i;
    171 
    172        PKIX_ENTER(CERTNAMECONSTRAINTS,
    173                "pkix_pl_CertNameConstraints_GetExcluded");
    174        PKIX_NULLCHECK_TWO(nameConstraints, pExcludedList);
    175 
    176        if (nameConstraints->excludedList == NULL) {
    177 
    178            PKIX_OBJECT_LOCK(nameConstraints);
    179 
    180            if (nameConstraints->excludedList == NULL) {
    181 
    182                PKIX_CHECK(PKIX_List_Create(&excludedList, plContext),
    183                            PKIX_LISTCREATEFAILED);
    184 
    185                numItems = nameConstraints->numNssNameConstraints;
    186                nssNameConstraintsList =
    187                        nameConstraints->nssNameConstraintsList;
    188 
    189                for (i = 0; i < numItems; i++) {
    190 
    191                    PKIX_NULLCHECK_ONE(nssNameConstraintsList);
    192                    nssNameConstraints = *(nssNameConstraintsList + i);
    193                    PKIX_NULLCHECK_ONE(nssNameConstraints);
    194 
    195                    if (nssNameConstraints->excluded != NULL) {
    196 
    197                        nssExcluded = nssNameConstraints->excluded;
    198                        firstExcluded = nssExcluded;
    199 
    200                        do {
    201 
    202                            PKIX_CHECK(pkix_pl_GeneralName_Create
    203                                (&nssExcluded->name, &name, plContext),
    204                                PKIX_GENERALNAMECREATEFAILED);
    205 
    206                            PKIX_CHECK(PKIX_List_AppendItem
    207                                (excludedList,
    208                                (PKIX_PL_Object *)name,
    209                                plContext),
    210                                PKIX_LISTAPPENDITEMFAILED);
    211 
    212                            PKIX_DECREF(name);
    213 
    214                            PKIX_CERTNAMECONSTRAINTS_DEBUG
    215                                ("\t\tCalling CERT_GetNextNameConstraint\n");
    216                            nssExcluded = CERT_GetNextNameConstraint
    217                                (nssExcluded);
    218 
    219                        } while (nssExcluded != firstExcluded);
    220 
    221                    }
    222 
    223                }
    224                PKIX_CHECK(PKIX_List_SetImmutable(excludedList, plContext),
    225                            PKIX_LISTSETIMMUTABLEFAILED);
    226 
    227                nameConstraints->excludedList = excludedList;
    228 
    229            }
    230 
    231            PKIX_OBJECT_UNLOCK(nameConstraints);
    232        }
    233 
    234        PKIX_INCREF(nameConstraints->excludedList);
    235 
    236        *pExcludedList = nameConstraints->excludedList;
    237 
    238 cleanup:
    239 
    240        PKIX_RETURN(CERTNAMECONSTRAINTS);
    241 }
    242 
    243 /*
    244 * FUNCTION: pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
    245 * DESCRIPTION:
    246 *
    247 *  This function checks if CERTGeneralNames in "nssSubjectNames" comply
    248 *  with the permitted and excluded names in "nameConstraints". It returns
    249 *  PKIX_TRUE in "pCheckPass", if the Names satify the name space of the
    250 *  permitted list and if the Names are not in the excluded list. Otherwise,
    251 *  it returns PKIX_FALSE.
    252 *
    253 * PARAMETERS
    254 *  "nssSubjectNames"
    255 *      List of CERTGeneralName that nameConstraints verification is based on.
    256 *  "nameConstraints"
    257 *      Address of CertNameConstraints that provides lists of permitted
    258 *      and excluded names. Must be non-NULL.
    259 *  "pCheckPass"
    260 *      Address where PKIX_TRUE is returned if the all names in "nameList" are
    261 *      valid.
    262 *  "plContext" - Platform-specific context pointer.
    263 * THREAD SAFETY:
    264 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    265 * RETURNS:
    266 *  Returns NULL if the function succeeds.
    267 *  Returns a NameConstraints Error if the function fails in a
    268 *  non-fatal way.
    269 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    270 */
    271 PKIX_Error *
    272 pkix_pl_CertNameConstraints_CheckNameSpaceNssNames(
    273        CERTGeneralName *nssSubjectNames,
    274        PKIX_PL_CertNameConstraints *nameConstraints,
    275        PKIX_Boolean *pCheckPass,
    276        void *plContext)
    277 {
    278        CERTNameConstraints **nssNameConstraintsList = NULL;
    279        CERTNameConstraints *nssNameConstraints = NULL;
    280        CERTGeneralName *nssMatchName = NULL;
    281        PLArenaPool *arena = NULL;
    282        PKIX_UInt32 numItems = 0;
    283        PKIX_UInt32 i;
    284        SECStatus status = SECSuccess;
    285 
    286        PKIX_ENTER(CERTNAMECONSTRAINTS,
    287                "pkix_pl_CertNameConstraints_CheckNameSpaceNssNames");
    288        PKIX_NULLCHECK_THREE(nssSubjectNames, nameConstraints, pCheckPass);
    289 
    290        *pCheckPass = PKIX_TRUE;
    291 
    292        PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
    293        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    294        if (arena == NULL) {
    295                PKIX_ERROR(PKIX_OUTOFMEMORY);
    296        }
    297 
    298        nssMatchName = nssSubjectNames;
    299        nssNameConstraintsList = nameConstraints->nssNameConstraintsList;
    300 
    301        /*
    302         * CERTNameConstraint items in each permitted or excluded list
    303         * is verified as OR condition. That means, if one item matched,
    304         * then the checking on the remaining items on the list is skipped.
    305         * (see NSS cert_CompareNameWithConstraints(...)).
    306         * Items on PKIX_PL_NameConstraint's nssNameConstraints are verified
    307         * as AND condition. PKIX_PL_NameConstraint keeps an array of pointers
    308         * of CERTNameConstraints resulting from merging multiple
    309         * PKIX_PL_NameConstraints. Since each CERTNameConstraint are created
    310         * for different entity, a union condition of these entities then is
    311         * performed.
    312         */
    313 
    314        do {
    315 
    316            numItems = nameConstraints->numNssNameConstraints;
    317 
    318            for (i = 0; i < numItems; i++) {
    319 
    320                PKIX_NULLCHECK_ONE(nssNameConstraintsList);
    321                nssNameConstraints = *(nssNameConstraintsList + i);
    322                PKIX_NULLCHECK_ONE(nssNameConstraints);
    323 
    324                PKIX_CERTNAMECONSTRAINTS_DEBUG
    325                        ("\t\tCalling CERT_CheckNameSpace\n");
    326                status = CERT_CheckNameSpace
    327                        (arena, nssNameConstraints, nssMatchName);
    328                if (status != SECSuccess) {
    329                        break;
    330                }
    331 
    332            }
    333 
    334            if (status != SECSuccess) {
    335                    break;
    336            }
    337 
    338            PKIX_CERTNAMECONSTRAINTS_DEBUG
    339                    ("\t\tCalling CERT_GetNextGeneralName\n");
    340            nssMatchName = CERT_GetNextGeneralName(nssMatchName);
    341 
    342        } while (nssMatchName != nssSubjectNames);
    343 
    344        if (status == SECFailure) {
    345 
    346                *pCheckPass = PKIX_FALSE;
    347        }
    348 
    349 cleanup:
    350 
    351        if (arena){
    352                PKIX_CERTNAMECONSTRAINTS_DEBUG
    353                        ("\t\tCalling PORT_FreeArena).\n");
    354                PORT_FreeArena(arena, PR_FALSE);
    355        }
    356 
    357        PKIX_RETURN(CERTNAMECONSTRAINTS);
    358 }
    359 
    360 /*
    361 * FUNCTION: pkix_pl_NameConstraints_Destroy
    362 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
    363 */
    364 static PKIX_Error *
    365 pkix_pl_CertNameConstraints_Destroy(
    366        PKIX_PL_Object *object,
    367        void *plContext)
    368 {
    369        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    370 
    371        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Destroy");
    372        PKIX_NULLCHECK_ONE(object);
    373 
    374        PKIX_CHECK(pkix_CheckType
    375                (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
    376                PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
    377 
    378        nameConstraints = (PKIX_PL_CertNameConstraints *)object;
    379 
    380        PKIX_CHECK(PKIX_PL_Free
    381                    (nameConstraints->nssNameConstraintsList, plContext),
    382                    PKIX_FREEFAILED);
    383 
    384        if (nameConstraints->arena){
    385                PKIX_CERTNAMECONSTRAINTS_DEBUG
    386                        ("\t\tCalling PORT_FreeArena).\n");
    387                PORT_FreeArena(nameConstraints->arena, PR_FALSE);
    388                nameConstraints->arena = NULL;
    389        }
    390 
    391        PKIX_DECREF(nameConstraints->permittedList);
    392        PKIX_DECREF(nameConstraints->excludedList);
    393 
    394 cleanup:
    395 
    396        PKIX_RETURN(CERTNAMECONSTRAINTS);
    397 }
    398 
    399 /*
    400 * FUNCTION: pkix_pl_CertNameConstraints_ToString_Helper
    401 * DESCRIPTION:
    402 *
    403 *  Helper function that creates a string representation of the object
    404 *  NameConstraints and stores it at "pString".
    405 *
    406 * PARAMETERS
    407 *  "nameConstraints"
    408 *      Address of CertNameConstraints whose string representation is
    409 *      desired. Must be non-NULL.
    410 *  "pString"
    411 *      Address where string object pointer will be stored. Must be non-NULL.
    412 *  "plContext" - Platform-specific context pointer.
    413 * THREAD SAFETY:
    414 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    415 * RETURNS:
    416 *  Returns NULL if the function succeeds.
    417 *  Returns a NameConstraints Error if the function fails in a
    418 *  non-fatal way.
    419 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    420 */
    421 static PKIX_Error *
    422 pkix_pl_CertNameConstraints_ToString_Helper(
    423        PKIX_PL_CertNameConstraints *nameConstraints,
    424        PKIX_PL_String **pString,
    425        void *plContext)
    426 {
    427        char *asciiFormat = NULL;
    428        PKIX_PL_String *formatString = NULL;
    429        PKIX_List *permittedList = NULL;
    430        PKIX_List *excludedList = NULL;
    431        PKIX_PL_String *permittedListString = NULL;
    432        PKIX_PL_String *excludedListString = NULL;
    433        PKIX_PL_String *nameConstraintsString = NULL;
    434 
    435        PKIX_ENTER(CERTNAMECONSTRAINTS,
    436                    "pkix_pl_CertNameConstraints_ToString_Helper");
    437        PKIX_NULLCHECK_TWO(nameConstraints, pString);
    438 
    439        asciiFormat =
    440                "[\n"
    441                "\t\tPermitted Name:  %s\n"
    442                "\t\tExcluded Name:   %s\n"
    443                "\t]\n";
    444 
    445        PKIX_CHECK(PKIX_PL_String_Create
    446                    (PKIX_ESCASCII,
    447                    asciiFormat,
    448                    0,
    449                    &formatString,
    450                    plContext),
    451                    PKIX_STRINGCREATEFAILED);
    452 
    453        PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
    454                    (nameConstraints, &permittedList, plContext),
    455                    PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
    456 
    457        PKIX_TOSTRING(permittedList, &permittedListString, plContext,
    458                    PKIX_LISTTOSTRINGFAILED);
    459 
    460        PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
    461                    (nameConstraints, &excludedList, plContext),
    462                    PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
    463 
    464        PKIX_TOSTRING(excludedList, &excludedListString, plContext,
    465                    PKIX_LISTTOSTRINGFAILED);
    466 
    467        PKIX_CHECK(PKIX_PL_Sprintf
    468                    (&nameConstraintsString,
    469                    plContext,
    470                    formatString,
    471                    permittedListString,
    472                    excludedListString),
    473                    PKIX_SPRINTFFAILED);
    474 
    475        *pString = nameConstraintsString;
    476 
    477 cleanup:
    478 
    479        PKIX_DECREF(formatString);
    480        PKIX_DECREF(permittedList);
    481        PKIX_DECREF(excludedList);
    482        PKIX_DECREF(permittedListString);
    483        PKIX_DECREF(excludedListString);
    484 
    485        PKIX_RETURN(CERTNAMECONSTRAINTS);
    486 }
    487 
    488 /*
    489 * FUNCTION: pkix_pl_CertNameConstraints_ToString
    490 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
    491 */
    492 static PKIX_Error *
    493 pkix_pl_CertNameConstraints_ToString(
    494        PKIX_PL_Object *object,
    495        PKIX_PL_String **pString,
    496        void *plContext)
    497 {
    498        PKIX_PL_String *nameConstraintsString = NULL;
    499        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    500 
    501        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_ToString");
    502        PKIX_NULLCHECK_TWO(object, pString);
    503 
    504        PKIX_CHECK(pkix_CheckType(
    505                    object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
    506                    PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
    507 
    508        nameConstraints = (PKIX_PL_CertNameConstraints *)object;
    509 
    510        PKIX_CHECK(pkix_pl_CertNameConstraints_ToString_Helper
    511                    (nameConstraints, &nameConstraintsString, plContext),
    512                    PKIX_CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED);
    513 
    514        *pString = nameConstraintsString;
    515 
    516 cleanup:
    517 
    518        PKIX_RETURN(CERTNAMECONSTRAINTS);
    519 }
    520 
    521 /*
    522 * FUNCTION: pkix_pl_CertNameConstraints_Hashcode
    523 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
    524 */
    525 static PKIX_Error *
    526 pkix_pl_CertNameConstraints_Hashcode(
    527        PKIX_PL_Object *object,
    528        PKIX_UInt32 *pHashcode,
    529        void *plContext)
    530 {
    531        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    532        PKIX_List *permittedList = NULL;
    533        PKIX_List *excludedList = NULL;
    534        PKIX_UInt32 permitHash = 0;
    535        PKIX_UInt32 excludeHash = 0;
    536 
    537        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Hashcode");
    538        PKIX_NULLCHECK_TWO(object, pHashcode);
    539 
    540        PKIX_CHECK(pkix_CheckType
    541                    (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
    542                    PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
    543 
    544        nameConstraints = (PKIX_PL_CertNameConstraints *)object;
    545 
    546        PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
    547                    (nameConstraints, &permittedList, plContext),
    548                    PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
    549 
    550        PKIX_HASHCODE(permittedList, &permitHash, plContext,
    551                    PKIX_OBJECTHASHCODEFAILED);
    552 
    553        PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
    554                    (nameConstraints, &excludedList, plContext),
    555                    PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
    556 
    557        PKIX_HASHCODE(excludedList, &excludeHash, plContext,
    558                    PKIX_OBJECTHASHCODEFAILED);
    559 
    560        *pHashcode = (((permitHash << 7) + excludeHash) << 7) +
    561                nameConstraints->numNssNameConstraints;
    562 
    563 cleanup:
    564 
    565        PKIX_DECREF(permittedList);
    566        PKIX_DECREF(excludedList);
    567        PKIX_RETURN(CERTNAMECONSTRAINTS);
    568 }
    569 
    570 /*
    571 * FUNCTION: pkix_pl_CertNameConstraints_Equals
    572 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
    573 */
    574 static PKIX_Error *
    575 pkix_pl_CertNameConstraints_Equals(
    576        PKIX_PL_Object *firstObject,
    577        PKIX_PL_Object *secondObject,
    578        PKIX_Boolean *pResult,
    579        void *plContext)
    580 {
    581        PKIX_PL_CertNameConstraints *firstNC = NULL;
    582        PKIX_PL_CertNameConstraints *secondNC = NULL;
    583        PKIX_List *firstPermittedList = NULL;
    584        PKIX_List *secondPermittedList = NULL;
    585        PKIX_List *firstExcludedList = NULL;
    586        PKIX_List *secondExcludedList = NULL;
    587        PKIX_UInt32 secondType;
    588        PKIX_Boolean cmpResult = PKIX_FALSE;
    589 
    590        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Equals");
    591        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
    592 
    593        /* test that firstObject is a CertNameConstraints */
    594        PKIX_CHECK(pkix_CheckType
    595                (firstObject, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
    596                PKIX_FIRSTOBJECTNOTCERTNAMECONSTRAINTS);
    597 
    598        firstNC = (PKIX_PL_CertNameConstraints *)firstObject;
    599        secondNC = (PKIX_PL_CertNameConstraints *)secondObject;
    600 
    601        /*
    602         * Since we know firstObject is a CertNameConstraints, if both
    603         * references are identical, they must be equal
    604         */
    605        if (firstNC == secondNC){
    606                *pResult = PKIX_TRUE;
    607                goto cleanup;
    608        }
    609 
    610        /*
    611         * If secondNC isn't a CertNameConstraints, we don't throw an error.
    612         * We simply return a Boolean result of FALSE
    613         */
    614        *pResult = PKIX_FALSE;
    615 
    616        PKIX_CHECK(PKIX_PL_Object_GetType
    617                    ((PKIX_PL_Object *)secondNC, &secondType, plContext),
    618                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
    619 
    620        if (secondType != PKIX_CERTNAMECONSTRAINTS_TYPE) {
    621                goto cleanup;
    622        }
    623 
    624        PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
    625                    (firstNC, &firstPermittedList, plContext),
    626                    PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
    627 
    628        PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
    629                    (secondNC, &secondPermittedList, plContext),
    630                    PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
    631 
    632        PKIX_EQUALS
    633                (firstPermittedList, secondPermittedList, &cmpResult, plContext,
    634                PKIX_OBJECTEQUALSFAILED);
    635 
    636        if (cmpResult != PKIX_TRUE) {
    637                goto cleanup;
    638        }
    639 
    640        PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
    641                    (firstNC, &firstExcludedList, plContext),
    642                    PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
    643 
    644        PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
    645                    (secondNC, &secondExcludedList, plContext),
    646                    PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
    647 
    648        PKIX_EQUALS
    649                (firstExcludedList, secondExcludedList, &cmpResult, plContext,
    650                PKIX_OBJECTEQUALSFAILED);
    651 
    652        if (cmpResult != PKIX_TRUE) {
    653                goto cleanup;
    654        }
    655 
    656        /*
    657         * numNssNameConstraints is not checked because it is basically a
    658         * merge count, it cannot determine the data equality.
    659         */
    660 
    661        *pResult = PKIX_TRUE;
    662 
    663 cleanup:
    664 
    665        PKIX_DECREF(firstPermittedList);
    666        PKIX_DECREF(secondPermittedList);
    667        PKIX_DECREF(firstExcludedList);
    668        PKIX_DECREF(secondExcludedList);
    669 
    670        PKIX_RETURN(CERTNAMECONSTRAINTS);
    671 }
    672 
    673 /*
    674 * FUNCTION: pkix_pl_CertNameConstraints_RegisterSelf
    675 * DESCRIPTION:
    676 *  Registers PKIX_CERTNAMECONSTRAINTS_TYPE and its related functions with
    677 *  systemClasses[]
    678 * THREAD SAFETY:
    679 *  Not Thread Safe - for performance and complexity reasons
    680 *
    681 *  Since this function is only called by PKIX_PL_Initialize, which should
    682 *  only be called once, it is acceptable that this function is not
    683 *  thread-safe.
    684 */
    685 PKIX_Error *
    686 pkix_pl_CertNameConstraints_RegisterSelf(void *plContext)
    687 {
    688        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    689        pkix_ClassTable_Entry entry;
    690 
    691        PKIX_ENTER(CERTNAMECONSTRAINTS,
    692                    "pkix_pl_CertNameConstraints_RegisterSelf");
    693 
    694        entry.description = "CertNameConstraints";
    695        entry.objCounter = 0;
    696        entry.typeObjectSize = sizeof(PKIX_PL_CertNameConstraints);
    697        entry.destructor = pkix_pl_CertNameConstraints_Destroy;
    698        entry.equalsFunction = pkix_pl_CertNameConstraints_Equals;
    699        entry.hashcodeFunction = pkix_pl_CertNameConstraints_Hashcode;
    700        entry.toStringFunction = pkix_pl_CertNameConstraints_ToString;
    701        entry.comparator = NULL;
    702        entry.duplicateFunction = pkix_duplicateImmutable;
    703 
    704        systemClasses[PKIX_CERTNAMECONSTRAINTS_TYPE] = entry;
    705 
    706        PKIX_RETURN(CERTNAMECONSTRAINTS);
    707 }
    708 
    709 /*
    710 * FUNCTION: pkix_pl_CertNameConstraints_Create_Helper
    711 *
    712 * DESCRIPTION:
    713 *  This function retrieves name constraints in "nssNameConstraints",
    714 *  converts and stores the result in a PKIX_PL_CertNameConstraints object.
    715 *
    716 * PARAMETERS
    717 *  "nssNameConstraints"
    718 *      Address of CERTNameConstraints that contains this object's data.
    719 *      Must be non-NULL.
    720 *  "pNameConstraints"
    721 *      Address where object pointer will be stored. Must be non-NULL.
    722 *      A NULL value will be returned if there is no Name Constraints extension.
    723 *  "plContext" - Platform-specific context pointer.
    724 *
    725 * THREAD SAFETY:
    726 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    727 *
    728 * RETURNS:
    729 *  Returns NULL if the function succeeds.
    730 *  Returns a NameConstraints Error if the function fails in a non-fatal way.
    731 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    732 */
    733 static PKIX_Error *
    734 pkix_pl_CertNameConstraints_Create_Helper(
    735        CERTNameConstraints *nssNameConstraints,
    736        PKIX_PL_CertNameConstraints **pNameConstraints,
    737        void *plContext)
    738 {
    739        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    740        CERTNameConstraints **nssNameConstraintPtr = NULL;
    741 
    742        PKIX_ENTER(CERTNAMECONSTRAINTS,
    743                    "pkix_pl_CertNameConstraints_Create_Helper");
    744        PKIX_NULLCHECK_TWO(nssNameConstraints, pNameConstraints);
    745 
    746        PKIX_CHECK(PKIX_PL_Object_Alloc
    747                    (PKIX_CERTNAMECONSTRAINTS_TYPE,
    748                    sizeof (PKIX_PL_CertNameConstraints),
    749                    (PKIX_PL_Object **)&nameConstraints,
    750                    plContext),
    751                    PKIX_COULDNOTCREATECERTNAMECONSTRAINTSOBJECT);
    752 
    753        PKIX_CHECK(PKIX_PL_Malloc
    754                    (sizeof (CERTNameConstraint *),
    755                    (void *)&nssNameConstraintPtr,
    756                    plContext),
    757                    PKIX_MALLOCFAILED);
    758 
    759        nameConstraints->numNssNameConstraints = 1;
    760        nameConstraints->nssNameConstraintsList = nssNameConstraintPtr;
    761        *nssNameConstraintPtr = nssNameConstraints;
    762 
    763        nameConstraints->permittedList = NULL;
    764        nameConstraints->excludedList = NULL;
    765        nameConstraints->arena = NULL;
    766 
    767        *pNameConstraints = nameConstraints;
    768 
    769 cleanup:
    770 
    771        if (PKIX_ERROR_RECEIVED){
    772                PKIX_DECREF(nameConstraints);
    773        }
    774 
    775        PKIX_RETURN(CERTNAMECONSTRAINTS);
    776 }
    777 
    778 /*
    779 * FUNCTION: pkix_pl_CertNameConstraints_Create
    780 *
    781 * DESCRIPTION:
    782 *  function that allocates and initialize the object CertNameConstraints.
    783 *
    784 * PARAMETERS
    785 *  "nssCert"
    786 *      Address of CERT that contains this object's data.
    787 *      Must be non-NULL.
    788 *  "pNameConstraints"
    789 *      Address where object pointer will be stored. Must be non-NULL.
    790 *      A NULL value will be returned if there is no Name Constraints extension.
    791 *  "plContext" - Platform-specific context pointer.
    792 *
    793 * THREAD SAFETY:
    794 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    795 *
    796 * RETURNS:
    797 *  Returns NULL if the function succeeds.
    798 *  Returns a NameConstraints Error if the function fails in a non-fatal way.
    799 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    800 */
    801 PKIX_Error *
    802 pkix_pl_CertNameConstraints_Create(
    803        CERTCertificate *nssCert,
    804        PKIX_PL_CertNameConstraints **pNameConstraints,
    805        void *plContext)
    806 {
    807        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    808        CERTNameConstraints *nssNameConstraints = NULL;
    809        PLArenaPool *arena = NULL;
    810        SECStatus status;
    811 
    812        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Create");
    813        PKIX_NULLCHECK_THREE(nssCert, pNameConstraints, nssCert->arena);
    814 
    815        PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
    816        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    817        if (arena == NULL) {
    818                PKIX_ERROR(PKIX_OUTOFMEMORY);
    819        }
    820 
    821        PKIX_CERTNAMECONSTRAINTS_DEBUG
    822                ("\t\tCalling CERT_FindNameConstraintsExten\n");
    823        status = CERT_FindNameConstraintsExten
    824                (arena, nssCert, &nssNameConstraints);
    825 
    826        if (status != SECSuccess) {
    827                PKIX_ERROR(PKIX_DECODINGCERTNAMECONSTRAINTSFAILED);
    828        }
    829 
    830        if (nssNameConstraints == NULL) {
    831                *pNameConstraints = NULL;
    832                 /* we free the arnea here because PKIX_ERROR_RECEIVED
    833                  * may not be set. Setting arena to NULL makes sure
    834                  * we don't try to free it again (and makes scanners
    835                  * happy). */
    836                if (arena){
    837                        PKIX_CERTNAMECONSTRAINTS_DEBUG
    838                                ("\t\tCalling PORT_FreeArena).\n");
    839                        PORT_FreeArena(arena, PR_FALSE);
    840                        arena = NULL;
    841                }
    842                goto cleanup;
    843        }
    844 
    845        PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
    846                    (nssNameConstraints, &nameConstraints, plContext),
    847                    PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED);
    848 
    849        nameConstraints->arena = arena;
    850 
    851        *pNameConstraints = nameConstraints;
    852 
    853 cleanup:
    854 
    855        if (PKIX_ERROR_RECEIVED){
    856                if (arena){
    857                        PKIX_CERTNAMECONSTRAINTS_DEBUG
    858                                ("\t\tCalling PORT_FreeArena).\n");
    859                        PORT_FreeArena(arena, PR_FALSE);
    860                }
    861        }
    862 
    863        PKIX_RETURN(CERTNAMECONSTRAINTS);
    864 }
    865 
    866 /*
    867 * FUNCTION: pkix_pl_CertNameConstraints_CreateByMerge
    868 *
    869 * DESCRIPTION:
    870 *
    871 *  This function allocates and creates a PKIX_PL_NameConstraint object
    872 *  for merging. It also allocates CERTNameConstraints data space for the
    873 *  merged NSS NameConstraints data.
    874 *
    875 * PARAMETERS
    876 *  "pNameConstraints"
    877 *      Address where object pointer will be stored and returned.
    878 *      Must be non-NULL.
    879 *  "plContext" - Platform-specific context pointer.
    880 *
    881 * THREAD SAFETY:
    882 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    883 *
    884 * RETURNS:
    885 *  Returns NULL if the function succeeds.
    886 *  Returns a NameConstraints Error if the function fails in a non-fatal way.
    887 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    888 */
    889 static PKIX_Error *
    890 pkix_pl_CertNameConstraints_CreateByMerge(
    891        PKIX_PL_CertNameConstraints **pNameConstraints,
    892        void *plContext)
    893 {
    894        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    895        CERTNameConstraints *nssNameConstraints = NULL;
    896        PLArenaPool *arena = NULL;
    897 
    898        PKIX_ENTER(CERTNAMECONSTRAINTS,
    899                    "pkix_pl_CertNameConstraints_CreateByMerge");
    900        PKIX_NULLCHECK_ONE(pNameConstraints);
    901 
    902        PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
    903        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    904        if (arena == NULL) {
    905                PKIX_ERROR(PKIX_OUTOFMEMORY);
    906        }
    907 
    908        PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
    909        nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints);
    910        if (nssNameConstraints == NULL) {
    911                PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
    912        }
    913 
    914        nssNameConstraints->permited = NULL;
    915        nssNameConstraints->excluded = NULL;
    916        nssNameConstraints->DERPermited = NULL;
    917        nssNameConstraints->DERExcluded = NULL;
    918 
    919        PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
    920                    (nssNameConstraints, &nameConstraints, plContext),
    921                    PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED);
    922 
    923        nameConstraints->arena = arena;
    924 
    925        *pNameConstraints = nameConstraints;
    926 
    927 cleanup:
    928 
    929        if (PKIX_ERROR_RECEIVED){
    930                if (arena){
    931                        PKIX_CERTNAMECONSTRAINTS_DEBUG
    932                                ("\t\tCalling PORT_FreeArena).\n");
    933                        PORT_FreeArena(arena, PR_FALSE);
    934                }
    935        }
    936 
    937        PKIX_RETURN(CERTNAMECONSTRAINTS);
    938 }
    939 
    940 /*
    941 * FUNCTION: pkix_pl_CertNameConstraints_CopyNssNameConstraints
    942 *
    943 * DESCRIPTION:
    944 *
    945 *  This function allocates and copies data to a NSS CERTNameConstraints from
    946 *  the NameConstraints given by "srcNC" and stores the result at "pDestNC". It
    947 *  copies items on both the permitted and excluded lists, but not the
    948 *  DERPermited and DERExcluded.
    949 *
    950 * PARAMETERS
    951 *  "arena"
    952 *      Memory pool where object data is allocated from. Must be non-NULL.
    953 *  "srcNC"
    954 *      Address of the NameConstraints to copy from. Must be non-NULL.
    955 *  "pDestNC"
    956 *      Address where new copied object is stored and returned.
    957 *      Must be non-NULL.
    958 *  "plContext" - Platform-specific context pointer.
    959 *
    960 * THREAD SAFETY:
    961 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    962 *
    963 * RETURNS:
    964 *  Returns NULL if the function succeeds.
    965 *  Returns a NameConstraints Error if the function fails in a non-fatal way.
    966 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    967 */
    968 static PKIX_Error *
    969 pkix_pl_CertNameConstraints_CopyNssNameConstraints(
    970        PLArenaPool *arena,
    971        CERTNameConstraints *srcNC,
    972        CERTNameConstraints **pDestNC,
    973        void *plContext)
    974 {
    975        CERTNameConstraints *nssNameConstraints = NULL;
    976        CERTNameConstraint *nssNameConstraintHead = NULL;
    977        CERTNameConstraint *nssCurrent = NULL;
    978        CERTNameConstraint *nssCopyTo = NULL;
    979        CERTNameConstraint *nssCopyFrom = NULL;
    980 
    981        PKIX_ENTER(CERTNAMECONSTRAINTS,
    982                    "pkix_pl_CertNameConstraints_CopyNssNameConstraints");
    983        PKIX_NULLCHECK_THREE(arena, srcNC, pDestNC);
    984 
    985        PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
    986        nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints);
    987        if (nssNameConstraints == NULL) {
    988                PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
    989        }
    990 
    991        if (srcNC->permited) {
    992 
    993            nssCopyFrom = srcNC->permited;
    994 
    995            do {
    996 
    997                nssCopyTo = NULL;
    998                PKIX_CERTNAMECONSTRAINTS_DEBUG
    999                        ("\t\tCalling CERT_CopyNameConstraint).\n");
   1000                nssCopyTo = CERT_CopyNameConstraint
   1001                        (arena, nssCopyTo, nssCopyFrom);
   1002                if (nssCopyTo == NULL) {
   1003                        PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED);
   1004                }
   1005                if (nssCurrent == NULL) {
   1006                        nssCurrent = nssNameConstraintHead = nssCopyTo;
   1007                } else {
   1008                        PKIX_CERTNAMECONSTRAINTS_DEBUG
   1009                                ("\t\tCalling CERT_AddNameConstraint).\n");
   1010                        nssCurrent = CERT_AddNameConstraint
   1011                                (nssCurrent, nssCopyTo);
   1012                }
   1013 
   1014                PKIX_CERTNAMECONSTRAINTS_DEBUG
   1015                        ("\t\tCalling CERT_GetNextNameConstrain).\n");
   1016                nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom);
   1017 
   1018            } while (nssCopyFrom != srcNC->permited);
   1019 
   1020            nssNameConstraints->permited = nssNameConstraintHead;
   1021        }
   1022 
   1023        if (srcNC->excluded) {
   1024 
   1025            nssCurrent = NULL;
   1026            nssCopyFrom = srcNC->excluded;
   1027 
   1028            do {
   1029 
   1030                /*
   1031                 * Cannot use CERT_DupGeneralNameList, which just increments
   1032                 * refcount. We need our own copy since arena is for each
   1033                 * PKIX_PL_NameConstraints. Perhaps contribute this code
   1034                 * as CERT_CopyGeneralNameList (in the future).
   1035                 */
   1036                nssCopyTo = NULL;
   1037                PKIX_CERTNAMECONSTRAINTS_DEBUG
   1038                        ("\t\tCalling CERT_CopyNameConstraint).\n");
   1039                nssCopyTo = CERT_CopyNameConstraint
   1040                        (arena, nssCopyTo, nssCopyFrom);
   1041                if (nssCopyTo == NULL) {
   1042                        PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED);
   1043                }
   1044                if (nssCurrent == NULL) {
   1045                        nssCurrent = nssNameConstraintHead = nssCopyTo;
   1046                } else {
   1047                        PKIX_CERTNAMECONSTRAINTS_DEBUG
   1048                                ("\t\tCalling CERT_AddNameConstraint).\n");
   1049                        nssCurrent = CERT_AddNameConstraint
   1050                                (nssCurrent, nssCopyTo);
   1051                }
   1052 
   1053                PKIX_CERTNAMECONSTRAINTS_DEBUG
   1054                        ("\t\tCalling CERT_GetNextNameConstrain).\n");
   1055                nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom);
   1056 
   1057            } while (nssCopyFrom != srcNC->excluded);
   1058 
   1059            nssNameConstraints->excluded = nssNameConstraintHead;
   1060        }
   1061 
   1062        *pDestNC = nssNameConstraints;
   1063 
   1064 cleanup:
   1065 
   1066        PKIX_RETURN(CERTNAMECONSTRAINTS);
   1067 }
   1068 
   1069 /*
   1070 * FUNCTION: pkix_pl_CertNameConstraints_Merge
   1071 *
   1072 * DESCRIPTION:
   1073 *
   1074 *  This function merges two NameConstraints pointed to by "firstNC" and
   1075 *  "secondNC" and stores the result in "pMergedNC".
   1076 *
   1077 * PARAMETERS
   1078 *  "firstNC"
   1079 *      Address of the first NameConstraints to be merged. Must be non-NULL.
   1080 *  "secondNC"
   1081 *      Address of the second NameConstraints to be merged. Must be non-NULL.
   1082 *  "pMergedNC"
   1083 *      Address where the merge result is stored and returned. Must be non-NULL.
   1084 *  "plContext" - Platform-specific context pointer.
   1085 *
   1086 * THREAD SAFETY:
   1087 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1088 *
   1089 * RETURNS:
   1090 *  Returns NULL if the function succeeds.
   1091 *  Returns a NameConstraints Error if the function fails in a non-fatal way.
   1092 *  Returns a Fatal Error if the function fails in an unrecoverable way.
   1093 */
   1094 PKIX_Error *
   1095 pkix_pl_CertNameConstraints_Merge(
   1096        PKIX_PL_CertNameConstraints *firstNC,
   1097        PKIX_PL_CertNameConstraints *secondNC,
   1098        PKIX_PL_CertNameConstraints **pMergedNC,
   1099        void *plContext)
   1100 {
   1101        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
   1102        CERTNameConstraints **nssNCto = NULL;
   1103        CERTNameConstraints **nssNCfrom = NULL;
   1104        CERTNameConstraints *nssNameConstraints = NULL;
   1105        PKIX_UInt32 numNssItems = 0;
   1106        PKIX_UInt32 i;
   1107 
   1108        PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Merge");
   1109        PKIX_NULLCHECK_THREE(firstNC, secondNC, pMergedNC);
   1110 
   1111        PKIX_CHECK(pkix_pl_CertNameConstraints_CreateByMerge
   1112                    (&nameConstraints, plContext),
   1113                    PKIX_CERTNAMECONSTRAINTSCREATEBYMERGEFAILED);
   1114 
   1115        /* Merge NSSCertConstraint lists */
   1116 
   1117        numNssItems = firstNC->numNssNameConstraints +
   1118                    secondNC->numNssNameConstraints;
   1119 
   1120        /* Free the default space (only one entry) allocated by create */
   1121        PKIX_CHECK(PKIX_PL_Free
   1122                    (nameConstraints->nssNameConstraintsList, plContext),
   1123                    PKIX_FREEFAILED);
   1124 
   1125        /* Reallocate the size we need */
   1126        PKIX_CHECK(PKIX_PL_Malloc
   1127                    (numNssItems * sizeof (CERTNameConstraint *),
   1128                    (void *)&nssNCto,
   1129                    plContext),
   1130                    PKIX_MALLOCFAILED);
   1131 
   1132        nameConstraints->nssNameConstraintsList = nssNCto;
   1133 
   1134        nssNCfrom = firstNC->nssNameConstraintsList;
   1135 
   1136        for (i = 0; i < firstNC->numNssNameConstraints; i++) {
   1137 
   1138                PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
   1139                        (nameConstraints->arena,
   1140                        *nssNCfrom,
   1141                        &nssNameConstraints,
   1142                        plContext),
   1143                        PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED);
   1144 
   1145                *nssNCto = nssNameConstraints;
   1146 
   1147                nssNCto++;
   1148                nssNCfrom++;
   1149        }
   1150 
   1151        nssNCfrom = secondNC->nssNameConstraintsList;
   1152 
   1153        for (i = 0; i < secondNC->numNssNameConstraints; i++) {
   1154 
   1155                PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
   1156                        (nameConstraints->arena,
   1157                        *nssNCfrom,
   1158                        &nssNameConstraints,
   1159                        plContext),
   1160                        PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED);
   1161 
   1162                *nssNCto = nssNameConstraints;
   1163 
   1164                nssNCto++;
   1165                nssNCfrom++;
   1166        }
   1167 
   1168        nameConstraints->numNssNameConstraints = numNssItems;
   1169        nameConstraints->permittedList = NULL;
   1170        nameConstraints->excludedList = NULL;
   1171 
   1172        *pMergedNC = nameConstraints;
   1173 
   1174 cleanup:
   1175 
   1176        if (PKIX_ERROR_RECEIVED){
   1177                PKIX_DECREF(nameConstraints);
   1178        }
   1179 
   1180        PKIX_RETURN(CERTNAMECONSTRAINTS);
   1181 }
   1182 
   1183 /* --Public-NameConstraints-Functions-------------------------------- */
   1184 
   1185 /*
   1186 * FUNCTION:  PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
   1187 * (see comments in pkix_pl_system.h)
   1188 */
   1189 PKIX_Error *
   1190 PKIX_PL_CertNameConstraints_CheckNamesInNameSpace(
   1191        PKIX_List *nameList, /* List of PKIX_PL_GeneralName */
   1192        PKIX_PL_CertNameConstraints *nameConstraints,
   1193        PKIX_Boolean *pCheckPass,
   1194        void *plContext)
   1195 {
   1196        CERTNameConstraints **nssNameConstraintsList = NULL;
   1197        CERTNameConstraints *nssNameConstraints = NULL;
   1198        CERTGeneralName *nssMatchName = NULL;
   1199        PLArenaPool *arena = NULL;
   1200        PKIX_PL_GeneralName *name = NULL;
   1201        PKIX_UInt32 numNameItems = 0;
   1202        PKIX_UInt32 numNCItems = 0;
   1203        PKIX_UInt32 i, j;
   1204        SECStatus status = SECSuccess;
   1205 
   1206        PKIX_ENTER(CERTNAMECONSTRAINTS,
   1207                "PKIX_PL_CertNameConstraints_CheckNamesInNameSpace");
   1208        PKIX_NULLCHECK_TWO(nameConstraints, pCheckPass);
   1209 
   1210        *pCheckPass = PKIX_TRUE;
   1211 
   1212        if (nameList != NULL) {
   1213 
   1214                PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
   1215                arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   1216                if (arena == NULL) {
   1217                        PKIX_ERROR(PKIX_OUTOFMEMORY);
   1218                }
   1219 
   1220                nssNameConstraintsList =
   1221                        nameConstraints->nssNameConstraintsList;
   1222                PKIX_NULLCHECK_ONE(nssNameConstraintsList);
   1223                numNCItems = nameConstraints->numNssNameConstraints;
   1224 
   1225                PKIX_CHECK(PKIX_List_GetLength
   1226                        (nameList, &numNameItems, plContext),
   1227                        PKIX_LISTGETLENGTHFAILED);
   1228 
   1229                for (i = 0; i < numNameItems; i++) {
   1230 
   1231                        PKIX_CHECK(PKIX_List_GetItem
   1232                                (nameList,
   1233                                i,
   1234                                (PKIX_PL_Object **) &name,
   1235                                plContext),
   1236                                PKIX_LISTGETITEMFAILED);
   1237 
   1238                        PKIX_CHECK(pkix_pl_GeneralName_GetNssGeneralName
   1239                                (name, &nssMatchName, plContext),
   1240                                PKIX_GENERALNAMEGETNSSGENERALNAMEFAILED);
   1241 
   1242                        PKIX_DECREF(name);
   1243 
   1244                        for (j = 0; j < numNCItems; j++) {
   1245 
   1246                            nssNameConstraints = *(nssNameConstraintsList + j);
   1247                            PKIX_NULLCHECK_ONE(nssNameConstraints);
   1248 
   1249                            PKIX_CERTNAMECONSTRAINTS_DEBUG
   1250                                ("\t\tCalling CERT_CheckNameSpace\n");
   1251                            status = CERT_CheckNameSpace
   1252                                (arena, nssNameConstraints, nssMatchName);
   1253                            if (status != SECSuccess) {
   1254                                break;
   1255                            }
   1256 
   1257                        }
   1258 
   1259                        if (status != SECSuccess) {
   1260                            break;
   1261                        }
   1262 
   1263                }
   1264        }
   1265 
   1266        if (status == SECFailure) {
   1267                *pCheckPass = PKIX_FALSE;
   1268        }
   1269 
   1270 cleanup:
   1271 
   1272        if (arena){
   1273                PKIX_CERTNAMECONSTRAINTS_DEBUG
   1274                        ("\t\tCalling PORT_FreeArena).\n");
   1275                PORT_FreeArena(arena, PR_FALSE);
   1276        }
   1277 
   1278        PKIX_RETURN(CERTNAMECONSTRAINTS);
   1279 }