tor-browser

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

pkix_policychecker.c (106309B)


      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_policychecker.c
      6 *
      7 * Functions for Policy Checker
      8 *
      9 */
     10 #include "pkix_policychecker.h"
     11 
     12 /* --Forward declarations----------------------------------------------- */
     13 
     14 static PKIX_Error *
     15 pkix_PolicyChecker_MakeSingleton(
     16        PKIX_PL_Object *listItem,
     17        PKIX_Boolean immutability,
     18        PKIX_List **pList,
     19        void *plContext);
     20 
     21 /* --Private-PolicyCheckerState-Functions---------------------------------- */
     22 
     23 /*
     24 * FUNCTION:pkix_PolicyCheckerState_Destroy
     25 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     26 */
     27 static PKIX_Error *
     28 pkix_PolicyCheckerState_Destroy(
     29        PKIX_PL_Object *object,
     30        void *plContext)
     31 {
     32        PKIX_PolicyCheckerState *checkerState = NULL;
     33 
     34        PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Destroy");
     35        PKIX_NULLCHECK_ONE(object);
     36 
     37        PKIX_CHECK(pkix_CheckType
     38                (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext),
     39                PKIX_OBJECTNOTPOLICYCHECKERSTATE);
     40 
     41        checkerState = (PKIX_PolicyCheckerState *)object;
     42 
     43        PKIX_DECREF(checkerState->certPoliciesExtension);
     44        PKIX_DECREF(checkerState->policyMappingsExtension);
     45        PKIX_DECREF(checkerState->policyConstraintsExtension);
     46        PKIX_DECREF(checkerState->inhibitAnyPolicyExtension);
     47        PKIX_DECREF(checkerState->anyPolicyOID);
     48        PKIX_DECREF(checkerState->validPolicyTree);
     49        PKIX_DECREF(checkerState->userInitialPolicySet);
     50        PKIX_DECREF(checkerState->mappedUserInitialPolicySet);
     51 
     52        checkerState->policyQualifiersRejected = PKIX_FALSE;
     53        checkerState->explicitPolicy = 0;
     54        checkerState->inhibitAnyPolicy = 0;
     55        checkerState->policyMapping = 0;
     56        checkerState->numCerts = 0;
     57        checkerState->certsProcessed = 0;
     58        checkerState->certPoliciesCritical = PKIX_FALSE;
     59 
     60        PKIX_DECREF(checkerState->anyPolicyNodeAtBottom);
     61        PKIX_DECREF(checkerState->newAnyPolicyNode);
     62        PKIX_DECREF(checkerState->mappedPolicyOIDs);
     63 
     64 cleanup:
     65 
     66        PKIX_RETURN(CERTPOLICYCHECKERSTATE);
     67 }
     68 
     69 /*
     70 * FUNCTION: pkix_PolicyCheckerState_ToString
     71 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
     72 */
     73 static PKIX_Error *
     74 pkix_PolicyCheckerState_ToString(
     75        PKIX_PL_Object *object,
     76        PKIX_PL_String **pCheckerStateString,
     77        void *plContext)
     78 {
     79        PKIX_PolicyCheckerState *state = NULL;
     80        PKIX_PL_String *resultString = NULL;
     81        PKIX_PL_String *policiesExtOIDString = NULL;
     82        PKIX_PL_String *policyMapOIDString = NULL;
     83        PKIX_PL_String *policyConstrOIDString = NULL;
     84        PKIX_PL_String *inhAnyPolOIDString = NULL;
     85        PKIX_PL_String *anyPolicyOIDString = NULL;
     86        PKIX_PL_String *validPolicyTreeString = NULL;
     87        PKIX_PL_String *userInitialPolicySetString = NULL;
     88        PKIX_PL_String *mappedUserPolicySetString = NULL;
     89        PKIX_PL_String *mappedPolicyOIDsString = NULL;
     90        PKIX_PL_String *anyAtBottomString = NULL;
     91        PKIX_PL_String *newAnyPolicyString = NULL;
     92        PKIX_PL_String *formatString = NULL;
     93        PKIX_PL_String *trueString = NULL;
     94        PKIX_PL_String *falseString = NULL;
     95        PKIX_PL_String *nullString = NULL;
     96        PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
     97        PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
     98        PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
     99        PKIX_Boolean initialIsAnyPolicy = PKIX_FALSE;
    100        PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
    101        PKIX_Boolean certPoliciesCritical = PKIX_FALSE;
    102        char *asciiFormat =
    103                "{\n"
    104                "\tcertPoliciesExtension:    \t%s\n"
    105                "\tpolicyMappingsExtension:  \t%s\n"
    106                "\tpolicyConstraintsExtension:\t%s\n"
    107                "\tinhibitAnyPolicyExtension:\t%s\n"
    108                "\tanyPolicyOID:             \t%s\n"
    109                "\tinitialIsAnyPolicy:       \t%s\n"
    110                "\tvalidPolicyTree:          \t%s\n"
    111                "\tuserInitialPolicySet:     \t%s\n"
    112                "\tmappedUserPolicySet:      \t%s\n"
    113                "\tpolicyQualifiersRejected: \t%s\n"
    114                "\tinitialPolMappingInhibit: \t%s\n"
    115                "\tinitialExplicitPolicy:    \t%s\n"
    116                "\tinitialAnyPolicyInhibit:  \t%s\n"
    117                "\texplicitPolicy:           \t%d\n"
    118                "\tinhibitAnyPolicy:         \t%d\n"
    119                "\tpolicyMapping:            \t%d\n"
    120                "\tnumCerts:                 \t%d\n"
    121                "\tcertsProcessed:           \t%d\n"
    122                "\tanyPolicyNodeAtBottom:    \t%s\n"
    123                "\tnewAnyPolicyNode:         \t%s\n"
    124                "\tcertPoliciesCritical:     \t%s\n"
    125                "\tmappedPolicyOIDs:         \t%s\n"
    126                "}";
    127 
    128        PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_ToString");
    129 
    130        PKIX_NULLCHECK_TWO(object, pCheckerStateString);
    131 
    132        PKIX_CHECK(pkix_CheckType
    133                (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext),
    134                PKIX_OBJECTNOTPOLICYCHECKERSTATE);
    135 
    136        state = (PKIX_PolicyCheckerState *)object;
    137        PKIX_NULLCHECK_THREE
    138                (state->certPoliciesExtension,
    139                state->policyMappingsExtension,
    140                state->policyConstraintsExtension);
    141        PKIX_NULLCHECK_THREE
    142                (state->inhibitAnyPolicyExtension,
    143                state->anyPolicyOID,
    144                state->userInitialPolicySet);
    145 
    146        PKIX_CHECK(PKIX_PL_String_Create
    147                (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
    148                PKIX_STRINGCREATEFAILED);
    149        /*
    150         * Create TRUE, FALSE, and "NULL" PKIX_PL_Strings. But creating a
    151         * PKIX_PL_String is complicated enough, it's worth checking, for
    152         * each, to make sure the string is needed.
    153         */
    154        initialPolicyMappingInhibit = state->initialPolicyMappingInhibit;
    155        initialExplicitPolicy = state->initialExplicitPolicy;
    156        initialAnyPolicyInhibit = state->initialAnyPolicyInhibit;
    157        initialIsAnyPolicy = state->initialIsAnyPolicy;
    158        policyQualifiersRejected = state->policyQualifiersRejected;
    159        certPoliciesCritical = state->certPoliciesCritical;
    160 
    161        if (initialPolicyMappingInhibit || initialExplicitPolicy ||
    162            initialAnyPolicyInhibit || initialIsAnyPolicy ||
    163            policyQualifiersRejected || certPoliciesCritical) {
    164                PKIX_CHECK(PKIX_PL_String_Create
    165                        (PKIX_ESCASCII, "TRUE", 0, &trueString, plContext),
    166                        PKIX_STRINGCREATEFAILED);
    167        }
    168        if (!initialPolicyMappingInhibit || !initialExplicitPolicy ||
    169            !initialAnyPolicyInhibit || !initialIsAnyPolicy ||
    170            !policyQualifiersRejected || !certPoliciesCritical) {
    171                PKIX_CHECK(PKIX_PL_String_Create
    172                        (PKIX_ESCASCII, "FALSE", 0, &falseString, plContext),
    173                        PKIX_STRINGCREATEFAILED);
    174        }
    175        if (!(state->anyPolicyNodeAtBottom) || !(state->newAnyPolicyNode)) {
    176                PKIX_CHECK(PKIX_PL_String_Create
    177                        (PKIX_ESCASCII, "(null)", 0, &nullString, plContext),
    178                        PKIX_STRINGCREATEFAILED);
    179        }
    180 
    181        PKIX_TOSTRING
    182                (state->certPoliciesExtension, &policiesExtOIDString, plContext,
    183                PKIX_OBJECTTOSTRINGFAILED);
    184 
    185        PKIX_TOSTRING
    186                (state->policyMappingsExtension,
    187                &policyMapOIDString,
    188                plContext,
    189                PKIX_OBJECTTOSTRINGFAILED);
    190 
    191        PKIX_TOSTRING
    192                (state->policyConstraintsExtension,
    193                &policyConstrOIDString,
    194                plContext,
    195                PKIX_OBJECTTOSTRINGFAILED);
    196 
    197        PKIX_TOSTRING
    198                (state->inhibitAnyPolicyExtension,
    199                &inhAnyPolOIDString,
    200                plContext,
    201                PKIX_OBJECTTOSTRINGFAILED);
    202 
    203        PKIX_TOSTRING(state->anyPolicyOID, &anyPolicyOIDString, plContext,
    204                PKIX_OBJECTTOSTRINGFAILED);
    205 
    206        PKIX_TOSTRING(state->validPolicyTree, &validPolicyTreeString, plContext,
    207                PKIX_OBJECTTOSTRINGFAILED);
    208 
    209        PKIX_TOSTRING
    210                (state->userInitialPolicySet,
    211                &userInitialPolicySetString,
    212                plContext,
    213                PKIX_OBJECTTOSTRINGFAILED);
    214 
    215        PKIX_TOSTRING
    216                (state->mappedUserInitialPolicySet,
    217                &mappedUserPolicySetString,
    218                plContext,
    219                PKIX_OBJECTTOSTRINGFAILED);
    220 
    221        if (state->anyPolicyNodeAtBottom) {
    222                PKIX_CHECK(pkix_SinglePolicyNode_ToString
    223                        (state->anyPolicyNodeAtBottom,
    224                        &anyAtBottomString,
    225                        plContext),
    226                        PKIX_SINGLEPOLICYNODETOSTRINGFAILED);
    227        } else {
    228                PKIX_INCREF(nullString);
    229                anyAtBottomString = nullString;
    230        }
    231 
    232        if (state->newAnyPolicyNode) {
    233                PKIX_CHECK(pkix_SinglePolicyNode_ToString
    234                        (state->newAnyPolicyNode,
    235                        &newAnyPolicyString,
    236                        plContext),
    237                        PKIX_SINGLEPOLICYNODETOSTRINGFAILED);
    238        } else {
    239                PKIX_INCREF(nullString);
    240                newAnyPolicyString = nullString;
    241        }
    242 
    243        PKIX_TOSTRING
    244                (state->mappedPolicyOIDs,
    245                &mappedPolicyOIDsString,
    246                plContext,
    247                PKIX_OBJECTTOSTRINGFAILED);
    248 
    249        PKIX_CHECK(PKIX_PL_Sprintf
    250                (&resultString,
    251                plContext,
    252                formatString,
    253                policiesExtOIDString,
    254                policyMapOIDString,
    255                policyConstrOIDString,
    256                inhAnyPolOIDString,
    257                anyPolicyOIDString,
    258                initialIsAnyPolicy?trueString:falseString,
    259                validPolicyTreeString,
    260                userInitialPolicySetString,
    261                mappedUserPolicySetString,
    262                policyQualifiersRejected?trueString:falseString,
    263                initialPolicyMappingInhibit?trueString:falseString,
    264                initialExplicitPolicy?trueString:falseString,
    265                initialAnyPolicyInhibit?trueString:falseString,
    266                state->explicitPolicy,
    267                state->inhibitAnyPolicy,
    268                state->policyMapping,
    269                state->numCerts,
    270                state->certsProcessed,
    271                anyAtBottomString,
    272                newAnyPolicyString,
    273                certPoliciesCritical?trueString:falseString,
    274                mappedPolicyOIDsString),
    275                PKIX_SPRINTFFAILED);
    276 
    277        *pCheckerStateString = resultString;
    278 
    279 cleanup:
    280        PKIX_DECREF(policiesExtOIDString);
    281        PKIX_DECREF(policyMapOIDString);
    282        PKIX_DECREF(policyConstrOIDString);
    283        PKIX_DECREF(inhAnyPolOIDString);
    284        PKIX_DECREF(anyPolicyOIDString);
    285        PKIX_DECREF(validPolicyTreeString);
    286        PKIX_DECREF(userInitialPolicySetString);
    287        PKIX_DECREF(mappedUserPolicySetString);
    288        PKIX_DECREF(anyAtBottomString);
    289        PKIX_DECREF(newAnyPolicyString);
    290        PKIX_DECREF(mappedPolicyOIDsString);
    291        PKIX_DECREF(formatString);
    292        PKIX_DECREF(trueString);
    293        PKIX_DECREF(falseString);
    294        PKIX_DECREF(nullString);
    295 
    296        PKIX_RETURN(CERTPOLICYCHECKERSTATE);
    297 }
    298 
    299 /*
    300 * FUNCTION: pkix_PolicyCheckerState_RegisterSelf
    301 * DESCRIPTION:
    302 *
    303 *  Registers PKIX_POLICYCHECKERSTATE_TYPE and its related functions
    304 *      with systemClasses[]
    305 *
    306 * PARAMETERS:
    307 *  "plContext"
    308 *      Platform-specific context pointer.
    309 * THREAD SAFETY:
    310 *  Not Thread Safe - for performance and complexity reasons
    311 *
    312 *  Since this function is only called by PKIX_PL_Initialize, which should
    313 *  only be called once, it is acceptable that this function is not
    314 *  thread-safe.
    315 */
    316 PKIX_Error *
    317 pkix_PolicyCheckerState_RegisterSelf(void *plContext)
    318 {
    319        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    320        pkix_ClassTable_Entry entry;
    321 
    322        PKIX_ENTER
    323                (CERTPOLICYCHECKERSTATE,
    324                "pkix_PolicyCheckerState_RegisterSelf");
    325 
    326        entry.description = "PolicyCheckerState";
    327        entry.objCounter = 0;
    328        entry.typeObjectSize = sizeof(PKIX_PolicyCheckerState);
    329        entry.destructor = pkix_PolicyCheckerState_Destroy;
    330        entry.equalsFunction = NULL;
    331        entry.hashcodeFunction = NULL;
    332        entry.toStringFunction = pkix_PolicyCheckerState_ToString;
    333        entry.comparator = NULL;
    334        entry.duplicateFunction = NULL;
    335 
    336        systemClasses[PKIX_CERTPOLICYCHECKERSTATE_TYPE] = entry;
    337 
    338        PKIX_RETURN(CERTPOLICYCHECKERSTATE);
    339 }
    340 
    341 /*
    342 * FUNCTION:pkix_PolicyCheckerState_Create
    343 * DESCRIPTION:
    344 *
    345 *  Creates a PolicyCheckerState Object, using the List pointed to
    346 *  by "initialPolicies" for the user-initial-policy-set, the Boolean value
    347 *  of "policyQualifiersRejected" for the policyQualifiersRejected parameter,
    348 *  the Boolean value of "initialPolicyMappingInhibit" for the
    349 *  inhibitPolicyMappings parameter, the Boolean value of
    350 *  "initialExplicitPolicy" for the initialExplicitPolicy parameter, the
    351 *  Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy
    352 *  parameter, and the UInt32 value of "numCerts" as the number of
    353 *  certificates in the chain; and stores the Object at "pCheckerState".
    354 *
    355 * PARAMETERS:
    356 *  "initialPolicies"
    357 *      Address of List of OIDs comprising the user-initial-policy-set; the List
    358 *      may be empty, but must be non-NULL
    359 *  "policyQualifiersRejected"
    360 *      Boolean value of the policyQualifiersRejected parameter
    361 *  "initialPolicyMappingInhibit"
    362 *      Boolean value of the inhibitPolicyMappings parameter
    363 *  "initialExplicitPolicy"
    364 *      Boolean value of the initialExplicitPolicy parameter
    365 *  "initialAnyPolicyInhibit"
    366 *      Boolean value of the inhibitAnyPolicy parameter
    367 *  "numCerts"
    368 *      Number of certificates in the chain to be validated
    369 *  "pCheckerState"
    370 *      Address where PolicyCheckerState will be stored. Must be non-NULL.
    371 *  "plContext"
    372 *      Platform-specific context pointer.
    373 * THREAD SAFETY:
    374 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    375 * RETURNS:
    376 *  Returns NULL if the function succeeds
    377 *  Returns a CertPolicyCheckerState Error if the functions fails in a
    378 *      non-fatal way
    379 *  Returns a Fatal Error if the function fails in an unrecoverable way
    380 */
    381 static PKIX_Error *
    382 pkix_PolicyCheckerState_Create(
    383        PKIX_List *initialPolicies,
    384        PKIX_Boolean policyQualifiersRejected,
    385        PKIX_Boolean initialPolicyMappingInhibit,
    386        PKIX_Boolean initialExplicitPolicy,
    387        PKIX_Boolean initialAnyPolicyInhibit,
    388        PKIX_UInt32 numCerts,
    389        PKIX_PolicyCheckerState **pCheckerState,
    390        void *plContext)
    391 {
    392        PKIX_PolicyCheckerState *checkerState = NULL;
    393        PKIX_PolicyNode *policyNode = NULL;
    394        PKIX_List *anyPolicyList = NULL;
    395        PKIX_Boolean initialPoliciesIsEmpty = PKIX_FALSE;
    396 
    397        PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Create");
    398        PKIX_NULLCHECK_TWO(initialPolicies, pCheckerState);
    399 
    400        PKIX_CHECK(PKIX_PL_Object_Alloc
    401                (PKIX_CERTPOLICYCHECKERSTATE_TYPE,
    402                sizeof (PKIX_PolicyCheckerState),
    403                (PKIX_PL_Object **)&checkerState,
    404                plContext),
    405                PKIX_COULDNOTCREATEPOLICYCHECKERSTATEOBJECT);
    406 
    407        /* Create constant PKIX_PL_OIDs: */
    408 
    409        PKIX_CHECK(PKIX_PL_OID_Create
    410                (PKIX_CERTIFICATEPOLICIES_OID,
    411                &(checkerState->certPoliciesExtension),
    412                plContext),
    413                PKIX_OIDCREATEFAILED);
    414 
    415        PKIX_CHECK(PKIX_PL_OID_Create
    416                (PKIX_POLICYMAPPINGS_OID,
    417                &(checkerState->policyMappingsExtension),
    418                plContext),
    419                PKIX_OIDCREATEFAILED);
    420 
    421        PKIX_CHECK(PKIX_PL_OID_Create
    422                (PKIX_POLICYCONSTRAINTS_OID,
    423                &(checkerState->policyConstraintsExtension),
    424                plContext),
    425                PKIX_OIDCREATEFAILED);
    426 
    427        PKIX_CHECK(PKIX_PL_OID_Create
    428                (PKIX_INHIBITANYPOLICY_OID,
    429                &(checkerState->inhibitAnyPolicyExtension),
    430                plContext),
    431                PKIX_OIDCREATEFAILED);
    432 
    433        PKIX_CHECK(PKIX_PL_OID_Create
    434                (PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID,
    435                &(checkerState->anyPolicyOID),
    436                plContext),
    437                PKIX_OIDCREATEFAILED);
    438 
    439        /* Create an initial policy set from argument supplied */
    440        PKIX_INCREF(initialPolicies);
    441        checkerState->userInitialPolicySet = initialPolicies;
    442        PKIX_INCREF(initialPolicies);
    443        checkerState->mappedUserInitialPolicySet = initialPolicies;
    444 
    445        PKIX_CHECK(PKIX_List_IsEmpty
    446                (initialPolicies,
    447                &initialPoliciesIsEmpty,
    448                plContext),
    449                PKIX_LISTISEMPTYFAILED);
    450        if (initialPoliciesIsEmpty) {
    451                checkerState->initialIsAnyPolicy = PKIX_TRUE;
    452        } else {
    453                PKIX_CHECK(pkix_List_Contains
    454                        (initialPolicies,
    455                        (PKIX_PL_Object *)(checkerState->anyPolicyOID),
    456                        &(checkerState->initialIsAnyPolicy),
    457                        plContext),
    458                        PKIX_LISTCONTAINSFAILED);
    459        }
    460 
    461        checkerState->policyQualifiersRejected =
    462                policyQualifiersRejected;
    463        checkerState->initialExplicitPolicy = initialExplicitPolicy;
    464        checkerState->explicitPolicy =
    465                (initialExplicitPolicy? 0: numCerts + 1);
    466        checkerState->initialAnyPolicyInhibit = initialAnyPolicyInhibit;
    467        checkerState->inhibitAnyPolicy =
    468                (initialAnyPolicyInhibit? 0: numCerts + 1);
    469        checkerState->initialPolicyMappingInhibit = initialPolicyMappingInhibit;
    470        checkerState->policyMapping =
    471                (initialPolicyMappingInhibit? 0: numCerts + 1);
    472                ;
    473        checkerState->numCerts = numCerts;
    474        checkerState->certsProcessed = 0;
    475        checkerState->certPoliciesCritical = PKIX_FALSE;
    476 
    477        /* Create a valid_policy_tree as in RFC3280 6.1.2(a) */
    478        PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
    479                ((PKIX_PL_Object *)(checkerState->anyPolicyOID),
    480                PKIX_TRUE,
    481                &anyPolicyList,
    482                plContext),
    483                PKIX_POLICYCHECKERMAKESINGLETONFAILED);
    484 
    485        PKIX_CHECK(pkix_PolicyNode_Create
    486                (checkerState->anyPolicyOID,    /* validPolicy */
    487                NULL,                           /* qualifier set */
    488                PKIX_FALSE,                     /* criticality */
    489                anyPolicyList,                  /* expectedPolicySet */
    490                &policyNode,
    491                plContext),
    492                PKIX_POLICYNODECREATEFAILED);
    493        checkerState->validPolicyTree = policyNode;
    494 
    495        /*
    496         * Since the initial validPolicyTree specifies
    497         * ANY_POLICY, begin with a pointer to the root node.
    498         */
    499        PKIX_INCREF(policyNode);
    500        checkerState->anyPolicyNodeAtBottom = policyNode;
    501 
    502        checkerState->newAnyPolicyNode = NULL;
    503 
    504        checkerState->mappedPolicyOIDs = NULL;
    505 
    506        *pCheckerState = checkerState;
    507        checkerState = NULL;
    508 
    509 cleanup:
    510 
    511        PKIX_DECREF(checkerState);
    512 
    513        PKIX_DECREF(anyPolicyList);
    514 
    515        PKIX_RETURN(CERTPOLICYCHECKERSTATE);
    516 }
    517 
    518 /* --Private-PolicyChecker-Functions--------------------------------------- */
    519 
    520 /*
    521 * FUNCTION: pkix_PolicyChecker_MapContains
    522 * DESCRIPTION:
    523 *
    524 *  Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to
    525 *  determine whether the OID pointed to by "policy" is among the
    526 *  issuerDomainPolicies or subjectDomainPolicies of "certPolicyMaps", and
    527 *  stores the result in "pFound".
    528 *
    529 *  This function is intended to allow an efficient check that the proscription
    530 *  against anyPolicy being mapped, described in RFC3280 Section 6.1.4(a), is
    531 *  not violated.
    532 *
    533 * PARAMETERS:
    534 *  "certPolicyMaps"
    535 *      Address of List of CertPolicyMaps to be searched. May be empty, but
    536 *      must be non-NULL
    537 *  "policy"
    538 *      Address of OID to be checked for. Must be non-NULL
    539 *  "pFound"
    540 *      Address where the result of the search will be stored. Must be non-NULL.
    541 *  "plContext"
    542 *      platform-specific context pointer
    543 * THREAD SAFETY:
    544 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    545 * RETURNS:
    546 *  Returns NULL if the function succeeds
    547 *  Returns a CertChainChecker Error if the function fails in a non-fatal way.
    548 *  Returns a Fatal Error if the function fails in an unrecoverable way
    549 */
    550 PKIX_Error *
    551 pkix_PolicyChecker_MapContains(
    552        PKIX_List *certPolicyMaps,
    553        PKIX_PL_OID *policy,
    554        PKIX_Boolean *pFound,
    555        void *plContext)
    556 {
    557        PKIX_PL_CertPolicyMap *map = NULL;
    558        PKIX_UInt32 numEntries = 0;
    559        PKIX_UInt32 index = 0;
    560        PKIX_Boolean match = PKIX_FALSE;
    561        PKIX_PL_OID *issuerDomainPolicy = NULL;
    562        PKIX_PL_OID *subjectDomainPolicy = NULL;
    563 
    564        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MapContains");
    565        PKIX_NULLCHECK_THREE(certPolicyMaps, policy, pFound);
    566 
    567        PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext),
    568                PKIX_LISTGETLENGTHFAILED);
    569 
    570        for (index = 0; (!match) && (index < numEntries); index++) {
    571                PKIX_CHECK(PKIX_List_GetItem
    572                    (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
    573                    PKIX_LISTGETITEMFAILED);
    574 
    575                PKIX_NULLCHECK_ONE(map);
    576 
    577                PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
    578                        (map, &issuerDomainPolicy, plContext),
    579                        PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
    580 
    581                PKIX_EQUALS
    582                        (policy, issuerDomainPolicy, &match, plContext,
    583                        PKIX_OBJECTEQUALSFAILED);
    584 
    585                if (!match) {
    586                        PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
    587                                (map, &subjectDomainPolicy, plContext),
    588                                PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED);
    589 
    590                        PKIX_EQUALS
    591                                (policy, subjectDomainPolicy, &match, plContext,
    592                                PKIX_OBJECTEQUALSFAILED);
    593                }
    594 
    595                PKIX_DECREF(map);
    596                PKIX_DECREF(issuerDomainPolicy);
    597                PKIX_DECREF(subjectDomainPolicy);
    598        }
    599 
    600        *pFound = match;
    601 
    602 cleanup:
    603 
    604        PKIX_DECREF(map);
    605        PKIX_DECREF(issuerDomainPolicy);
    606        PKIX_DECREF(subjectDomainPolicy);
    607        PKIX_RETURN(CERTCHAINCHECKER);
    608 }
    609 
    610 /*
    611 * FUNCTION: pkix_PolicyChecker_MapGetSubjectDomainPolicies
    612 * DESCRIPTION:
    613 *
    614 *  Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to create
    615 *  a list of all SubjectDomainPolicies for which the IssuerDomainPolicy is the
    616 *  policy pointed to by "policy", and stores the result in
    617 *  "pSubjectDomainPolicies".
    618 *
    619 *  If the List of CertPolicyMaps provided in "certPolicyMaps" is NULL, the
    620 *  resulting List will be NULL. If there are CertPolicyMaps, but none that
    621 *  include "policy" as an IssuerDomainPolicy, the returned List pointer will
    622 *  be NULL. Otherwise, the returned List will contain the SubjectDomainPolicies
    623 *  of all CertPolicyMaps for which "policy" is the IssuerDomainPolicy. If a
    624 *  List is returned it will be immutable.
    625 *
    626 * PARAMETERS:
    627 *  "certPolicyMaps"
    628 *      Address of List of CertPolicyMaps to be searched. May be empty or NULL.
    629 *  "policy"
    630 *      Address of OID to be checked for. Must be non-NULL
    631 *  "pSubjectDomainPolicies"
    632 *      Address where the result of the search will be stored. Must be non-NULL.
    633 *  "plContext"
    634 *      platform-specific context pointer
    635 * THREAD SAFETY:
    636 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    637 * RETURNS:
    638 *  Returns NULL if the function succeeds
    639 *  Returns a CertChainChecker Error if the function fails in a non-fatal way.
    640 *  Returns a Fatal Error if the function fails in an unrecoverable way
    641 */
    642 PKIX_Error *
    643 pkix_PolicyChecker_MapGetSubjectDomainPolicies(
    644        PKIX_List *certPolicyMaps,
    645        PKIX_PL_OID *policy,
    646        PKIX_List **pSubjectDomainPolicies,
    647        void *plContext)
    648 {
    649        PKIX_PL_CertPolicyMap *map = NULL;
    650        PKIX_List *subjectList = NULL;
    651        PKIX_UInt32 numEntries = 0;
    652        PKIX_UInt32 index = 0;
    653        PKIX_Boolean match = PKIX_FALSE;
    654        PKIX_PL_OID *issuerDomainPolicy = NULL;
    655        PKIX_PL_OID *subjectDomainPolicy = NULL;
    656 
    657        PKIX_ENTER
    658                (CERTCHAINCHECKER,
    659                "pkix_PolicyChecker_MapGetSubjectDomainPolicies");
    660        PKIX_NULLCHECK_TWO(policy, pSubjectDomainPolicies);
    661 
    662        if (certPolicyMaps) {
    663                PKIX_CHECK(PKIX_List_GetLength
    664                    (certPolicyMaps,
    665                    &numEntries,
    666                    plContext),
    667                    PKIX_LISTGETLENGTHFAILED);
    668        }
    669 
    670        for (index = 0; index < numEntries; index++) {
    671                PKIX_CHECK(PKIX_List_GetItem
    672                    (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
    673                    PKIX_LISTGETITEMFAILED);
    674 
    675                PKIX_NULLCHECK_ONE(map);
    676 
    677                PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
    678                        (map, &issuerDomainPolicy, plContext),
    679                        PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
    680 
    681                PKIX_EQUALS
    682                    (policy, issuerDomainPolicy, &match, plContext,
    683                    PKIX_OBJECTEQUALSFAILED);
    684 
    685                if (match) {
    686                    if (!subjectList) {
    687                        PKIX_CHECK(PKIX_List_Create(&subjectList, plContext),
    688                                PKIX_LISTCREATEFAILED);
    689                    }
    690 
    691                    PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
    692                        (map, &subjectDomainPolicy, plContext),
    693                        PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED);
    694 
    695                    PKIX_CHECK(PKIX_List_AppendItem
    696                        (subjectList,
    697                        (PKIX_PL_Object *)subjectDomainPolicy,
    698                        plContext),
    699                        PKIX_LISTAPPENDITEMFAILED);
    700                }
    701 
    702                PKIX_DECREF(map);
    703                PKIX_DECREF(issuerDomainPolicy);
    704                PKIX_DECREF(subjectDomainPolicy);
    705        }
    706 
    707        if (subjectList) {
    708                PKIX_CHECK(PKIX_List_SetImmutable(subjectList, plContext),
    709                        PKIX_LISTSETIMMUTABLEFAILED);
    710        }
    711 
    712        *pSubjectDomainPolicies = subjectList;
    713 
    714 cleanup:
    715 
    716        if (PKIX_ERROR_RECEIVED) {
    717                PKIX_DECREF(subjectList);
    718        }
    719 
    720        PKIX_DECREF(map);
    721        PKIX_DECREF(issuerDomainPolicy);
    722        PKIX_DECREF(subjectDomainPolicy);
    723 
    724        PKIX_RETURN(CERTCHAINCHECKER);
    725 }
    726 
    727 /*
    728 * FUNCTION: pkix_PolicyChecker_MapGetMappedPolicies
    729 * DESCRIPTION:
    730 *
    731 *  Checks the List of CertPolicyMaps pointed to by "certPolicyMaps" to create a
    732 *  List of all IssuerDomainPolicies, and stores the result in
    733 * "pMappedPolicies".
    734 *
    735 *  The caller may not rely on the IssuerDomainPolicies to be in any particular
    736 *  order. IssuerDomainPolicies that appear in more than one CertPolicyMap will
    737 *  only appear once in "pMappedPolicies". If "certPolicyMaps" is empty the
    738 *  result will be an empty List. The created List is mutable.
    739 *
    740 * PARAMETERS:
    741 *  "certPolicyMaps"
    742 *      Address of List of CertPolicyMaps to be searched. May be empty, but
    743 *      must be non-NULL.
    744 *  "pMappedPolicies"
    745 *      Address where the result will be stored. Must be non-NULL.
    746 *  "plContext"
    747 *      platform-specific context pointer
    748 * THREAD SAFETY:
    749 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    750 * RETURNS:
    751 *  Returns NULL if the function succeeds
    752 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
    753 *  Returns a Fatal Error if the function fails in an unrecoverable way
    754 */
    755 PKIX_Error *
    756 pkix_PolicyChecker_MapGetMappedPolicies(
    757        PKIX_List *certPolicyMaps,
    758        PKIX_List **pMappedPolicies,
    759        void *plContext)
    760 {
    761        PKIX_PL_CertPolicyMap *map = NULL;
    762        PKIX_List *mappedList = NULL;
    763        PKIX_UInt32 numEntries = 0;
    764        PKIX_UInt32 index = 0;
    765        PKIX_Boolean isContained = PKIX_FALSE;
    766        PKIX_PL_OID *issuerDomainPolicy = NULL;
    767 
    768        PKIX_ENTER
    769                (CERTCHAINCHECKER, "pkix_PolicyChecker_MapGetMappedPolicies");
    770        PKIX_NULLCHECK_TWO(certPolicyMaps, pMappedPolicies);
    771 
    772        PKIX_CHECK(PKIX_List_Create(&mappedList, plContext),
    773                PKIX_LISTCREATEFAILED);
    774 
    775        PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext),
    776                PKIX_LISTGETLENGTHFAILED);
    777 
    778        for (index = 0; index < numEntries; index++) {
    779                PKIX_CHECK(PKIX_List_GetItem
    780                    (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
    781                    PKIX_LISTGETITEMFAILED);
    782 
    783                PKIX_NULLCHECK_ONE(map);
    784 
    785                PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
    786                        (map, &issuerDomainPolicy, plContext),
    787                        PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
    788 
    789                PKIX_CHECK(pkix_List_Contains
    790                        (mappedList,
    791                        (PKIX_PL_Object *)issuerDomainPolicy,
    792                        &isContained,
    793                        plContext),
    794                        PKIX_LISTCONTAINSFAILED);
    795 
    796                if (isContained == PKIX_FALSE) {
    797                        PKIX_CHECK(PKIX_List_AppendItem
    798                                (mappedList,
    799                                (PKIX_PL_Object *)issuerDomainPolicy,
    800                                plContext),
    801                                PKIX_LISTAPPENDITEMFAILED);
    802                }
    803 
    804                PKIX_DECREF(map);
    805                PKIX_DECREF(issuerDomainPolicy);
    806        }
    807 
    808        *pMappedPolicies = mappedList;
    809 
    810 cleanup:
    811 
    812        if (PKIX_ERROR_RECEIVED) {
    813                PKIX_DECREF(mappedList);
    814        }
    815 
    816        PKIX_DECREF(map);
    817        PKIX_DECREF(issuerDomainPolicy);
    818 
    819        PKIX_RETURN(CERTCHAINCHECKER);
    820 }
    821 
    822 /*
    823 * FUNCTION: pkix_PolicyChecker_MakeMutableCopy
    824 * DESCRIPTION:
    825 *
    826 *  Creates a mutable copy of the List pointed to by "list", which may or may
    827 *  not be immutable, and stores the address at "pMutableCopy".
    828 *
    829 * PARAMETERS:
    830 *  "list"
    831 *      Address of List to be copied. Must be non-NULL.
    832 *  "pMutableCopy"
    833 *      Address where mutable copy will be stored. Must be non-NULL.
    834 *  "plContext"
    835 *      Platform-specific context pointer.
    836 * THREAD SAFETY:
    837 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    838 * RETURNS:
    839 *  Returns NULL if the function succeeds
    840 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
    841 *  Returns a Fatal Error if the function fails in an unrecoverable way
    842 */
    843 static PKIX_Error *
    844 pkix_PolicyChecker_MakeMutableCopy(
    845        PKIX_List *list,
    846        PKIX_List **pMutableCopy,
    847        void *plContext)
    848 {
    849        PKIX_List *newList = NULL;
    850        PKIX_UInt32 listLen = 0;
    851        PKIX_UInt32 listIx = 0;
    852        PKIX_PL_Object *object = NULL;
    853 
    854        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeMutableCopy");
    855        PKIX_NULLCHECK_TWO(list, pMutableCopy);
    856 
    857        PKIX_CHECK(PKIX_List_Create(&newList, plContext),
    858                PKIX_LISTCREATEFAILED);
    859 
    860        PKIX_CHECK(PKIX_List_GetLength(list, &listLen, plContext),
    861                PKIX_LISTGETLENGTHFAILED);
    862 
    863        for (listIx = 0; listIx < listLen; listIx++) {
    864 
    865                PKIX_CHECK(PKIX_List_GetItem(list, listIx, &object, plContext),
    866                        PKIX_LISTGETITEMFAILED);
    867 
    868                PKIX_CHECK(PKIX_List_AppendItem(newList, object, plContext),
    869                        PKIX_LISTAPPENDITEMFAILED);
    870 
    871                PKIX_DECREF(object);
    872        }
    873 
    874        *pMutableCopy = newList;
    875        newList = NULL;
    876        
    877 cleanup:
    878        PKIX_DECREF(newList);
    879        PKIX_DECREF(object);
    880 
    881        PKIX_RETURN(CERTCHAINCHECKER);
    882 }
    883 
    884 /*
    885 * FUNCTION: pkix_PolicyChecker_MakeSingleton
    886 * DESCRIPTION:
    887 *
    888 *  Creates a new List containing the Object pointed to by "listItem", using
    889 *  the Boolean value of "immutability" to determine whether to set the List
    890 *  immutable, and stores the address at "pList".
    891 *
    892 * PARAMETERS:
    893 *  "listItem"
    894 *      Address of Object to be inserted into the new List. Must be non-NULL.
    895 *  "immutability"
    896 *      Boolean value indicating whether new List is to be immutable
    897 *  "pList"
    898 *      Address where List will be stored. Must be non-NULL.
    899 *  "plContext"
    900 *      Platform-specific context pointer.
    901 * THREAD SAFETY:
    902 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    903 * RETURNS:
    904 *  Returns NULL if the function succeeds
    905 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
    906 *  Returns a Fatal Error if the function fails in an unrecoverable way
    907 */
    908 static PKIX_Error *
    909 pkix_PolicyChecker_MakeSingleton(
    910        PKIX_PL_Object *listItem,
    911        PKIX_Boolean immutability,
    912        PKIX_List **pList,
    913        void *plContext)
    914 {
    915        PKIX_List *newList = NULL;
    916 
    917        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeSingleton");
    918        PKIX_NULLCHECK_TWO(listItem, pList);
    919 
    920        PKIX_CHECK(PKIX_List_Create(&newList, plContext),
    921                PKIX_LISTCREATEFAILED);
    922 
    923        PKIX_CHECK(PKIX_List_AppendItem
    924                (newList, (PKIX_PL_Object *)listItem, plContext),
    925                PKIX_LISTAPPENDITEMFAILED);
    926 
    927        if (immutability) {
    928                PKIX_CHECK(PKIX_List_SetImmutable(newList, plContext),
    929                        PKIX_LISTSETIMMUTABLEFAILED);
    930        }
    931 
    932        *pList = newList;
    933 
    934 cleanup:
    935        if (PKIX_ERROR_RECEIVED) {
    936                PKIX_DECREF(newList);
    937        }
    938 
    939        PKIX_RETURN(CERTCHAINCHECKER);
    940 }
    941 
    942 /*
    943 * FUNCTION: pkix_PolicyChecker_Spawn
    944 * DESCRIPTION:
    945 *
    946 *  Creates a new childNode for the parent pointed to by "parent", using
    947 *  the OID pointed to by "policyOID", the List of CertPolicyQualifiers
    948 *  pointed to by "qualifiers", the List of OIDs pointed to by
    949 *  "subjectDomainPolicies", and the PolicyCheckerState pointed to by
    950 *  "state". The new node will be added to "parent".
    951 *
    952 *  The validPolicy of the new node is set from the OID pointed to by
    953 *  "policyOID". The policy qualifiers for the new node is set from the
    954 *  List of qualifiers pointed to by "qualifiers", and may be NULL or
    955 *  empty if the argument provided was NULL or empty. The criticality is
    956 *  set according to the criticality obtained from the PolicyCheckerState.
    957 *  If "subjectDomainPolicies" is NULL, the expectedPolicySet of the
    958 *  child is set to contain the same policy as the validPolicy. If
    959 *  "subjectDomainPolicies" is not NULL, it is used as the value for
    960 *  the expectedPolicySet.
    961 *
    962 *  The PolicyCheckerState also contains a constant, anyPolicy, which is
    963 *  compared to "policyOID". If they match, the address of the childNode
    964 * is saved in the state's newAnyPolicyNode.
    965 *
    966 * PARAMETERS:
    967 *  "parent"
    968 *      Address of PolicyNode to which the child will be linked. Must be
    969 *      non-NULL.
    970 *  "policyOID"
    971 *      Address of OID of the new child's validPolicy and also, if
    972 *      subjectDomainPolicies is NULL, of the new child's expectedPolicySet.
    973 *      Must be non-NULL.
    974 *  "qualifiers"
    975 *      Address of List of CertPolicyQualifiers. May be NULL or empty.
    976 *  "subjectDomainPolicies"
    977 *      Address of List of OIDs indicating the policies to which "policy" is
    978 *      mapped. May be empty or NULL.
    979 *  "state"
    980 *      Address of the current PKIX_PolicyCheckerState. Must be non-NULL..
    981 *  "plContext"
    982 *      Platform-specific context pointer.
    983 * THREAD SAFETY:
    984 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    985 * RETURNS:
    986 *  Returns NULL if the function succeeds
    987 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
    988 *  Returns a Fatal Error if the function fails in an unrecoverable way
    989 */
    990 static PKIX_Error *
    991 pkix_PolicyChecker_Spawn(
    992        PKIX_PolicyNode *parent,
    993        PKIX_PL_OID *policyOID,
    994        PKIX_List *qualifiers,  /* CertPolicyQualifiers */
    995        PKIX_List *subjectDomainPolicies,
    996        PKIX_PolicyCheckerState *state,
    997        void *plContext)
    998 {
    999        PKIX_List *expectedSet = NULL; /* OIDs */
   1000        PKIX_PolicyNode *childNode = NULL;
   1001        PKIX_Boolean match = PKIX_FALSE;
   1002 
   1003        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Spawn");
   1004        PKIX_NULLCHECK_THREE(policyOID, parent, state);
   1005 
   1006        if (subjectDomainPolicies) {
   1007 
   1008                PKIX_INCREF(subjectDomainPolicies);
   1009                expectedSet = subjectDomainPolicies;
   1010 
   1011        } else {
   1012                /* Create the child's ExpectedPolicy Set */
   1013                PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
   1014                        ((PKIX_PL_Object *)policyOID,
   1015                        PKIX_TRUE,      /* make expectedPolicySet immutable */
   1016                        &expectedSet,
   1017                        plContext),
   1018                        PKIX_POLICYCHECKERMAKESINGLETONFAILED);
   1019        }
   1020 
   1021        PKIX_CHECK(pkix_PolicyNode_Create
   1022                (policyOID,
   1023                qualifiers,
   1024                state->certPoliciesCritical,
   1025                expectedSet,
   1026                &childNode,
   1027                plContext),
   1028                PKIX_POLICYNODECREATEFAILED);
   1029 
   1030        /*
   1031         * If we had a non-empty mapping, we know the new node could not
   1032         * have been created with a validPolicy of anyPolicy. Otherwise,
   1033         * check whether we just created a new node with anyPolicy, because
   1034         * in that case we want to save the child pointer in newAnyPolicyNode.
   1035         */
   1036        if (!subjectDomainPolicies) {
   1037                PKIX_EQUALS(policyOID, state->anyPolicyOID, &match, plContext,
   1038                        PKIX_OBJECTEQUALSFAILED);
   1039 
   1040                if (match) {
   1041                        PKIX_DECREF(state->newAnyPolicyNode);
   1042                        PKIX_INCREF(childNode);
   1043                        state->newAnyPolicyNode = childNode;
   1044                }
   1045        }
   1046 
   1047        PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, childNode, plContext),
   1048                PKIX_POLICYNODEADDTOPARENTFAILED);
   1049 
   1050        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   1051                ((PKIX_PL_Object *)state, plContext),
   1052                PKIX_OBJECTINVALIDATECACHEFAILED);
   1053 
   1054 cleanup:
   1055        PKIX_DECREF(childNode);
   1056        PKIX_DECREF(expectedSet);
   1057        PKIX_RETURN(CERTCHAINCHECKER);
   1058 }
   1059 
   1060 /*
   1061 * FUNCTION: pkix_PolicyChecker_CheckPolicyRecursive
   1062 * DESCRIPTION:
   1063 *
   1064 *  Performs policy processing for the policy whose OID is pointed to by
   1065 *  "policyOID" and whose List of CertPolicyQualifiers is pointed to by
   1066 *  "policyQualifiers", using the List of policy OIDs pointed to by
   1067 *  "subjectDomainPolicies" and the PolicyNode pointed to by "currentNode",
   1068 *  in accordance with the current PolicyCheckerState pointed to by "state",
   1069 *  and setting "pChildNodeCreated" to TRUE if a new childNode is created.
   1070 *  Note: "pChildNodeCreated" is not set to FALSE if no childNode is created.
   1071 *  The intent of the design is that the caller can set a variable to FALSE
   1072 *  initially, prior to a recursive set of calls. At the end, the variable
   1073 *  can be tested to see whether *any* of the calls created a child node.
   1074 *
   1075 *  If the currentNode is not at the bottom of the tree, this function
   1076 *  calls itself recursively for each child of currentNode. At the bottom of
   1077 *  the tree, it creates new child nodes as appropriate. This function will
   1078 *  never be called with policy = anyPolicy.
   1079 *
   1080 *  This function implements the processing described in RFC3280
   1081 *  Section 6.1.3(d)(1)(i).
   1082 *
   1083 * PARAMETERS:
   1084 *  "policyOID"
   1085 *      Address of OID of the policy to be checked for. Must be non-NULL.
   1086 *  "policyQualifiers"
   1087 *      Address of List of CertPolicyQualifiers of the policy to be checked for.
   1088 *      May be empty or NULL.
   1089 *  "subjectDomainPolicies"
   1090 *      Address of List of OIDs indicating the policies to which "policy" is
   1091 *      mapped. May be empty or NULL.
   1092 *  "currentNode"
   1093 *      Address of PolicyNode whose descendants will be checked, if not at the
   1094 *      bottom of the tree; or whose expectedPolicySet will be compared to
   1095 *      "policy", if at the bottom. Must be non-NULL.
   1096 *  "state"
   1097 *      Address of PolicyCheckerState of the current PolicyChecker. Must be
   1098 *      non-NULL.
   1099 *  "pChildNodeCreated"
   1100 *      Address of the Boolean that will be set TRUE if this function
   1101 *      creates a child node. Must be non-NULL.
   1102 *  "plContext"
   1103 *      Platform-specific context pointer.
   1104 * THREAD SAFETY:
   1105 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1106 * RETURNS:
   1107 *  Returns NULL if the function succeeds
   1108 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   1109 *  Returns a Fatal Error if the function fails in an unrecoverable way
   1110 */
   1111 static PKIX_Error *
   1112 pkix_PolicyChecker_CheckPolicyRecursive(
   1113        PKIX_PL_OID *policyOID,
   1114        PKIX_List *policyQualifiers,
   1115        PKIX_List *subjectDomainPolicies,
   1116        PKIX_PolicyNode *currentNode,
   1117        PKIX_PolicyCheckerState *state,
   1118        PKIX_Boolean *pChildNodeCreated,
   1119        void *plContext)
   1120 {
   1121        PKIX_UInt32 depth = 0;
   1122        PKIX_UInt32 numChildren = 0;
   1123        PKIX_UInt32 childIx = 0;
   1124        PKIX_Boolean isIncluded = PKIX_FALSE;
   1125        PKIX_List *children = NULL;     /* PolicyNodes */
   1126        PKIX_PolicyNode *childNode = NULL;
   1127        PKIX_List *expectedPolicies = NULL; /* OIDs */
   1128 
   1129        PKIX_ENTER
   1130                (CERTCHAINCHECKER,
   1131                "pkix_PolicyChecker_CheckPolicyRecursive");
   1132        PKIX_NULLCHECK_FOUR(policyOID, currentNode, state, pChildNodeCreated);
   1133 
   1134        /* if not at the bottom of the tree */
   1135        PKIX_CHECK(PKIX_PolicyNode_GetDepth
   1136                (currentNode, &depth, plContext),
   1137                PKIX_POLICYNODEGETDEPTHFAILED);
   1138 
   1139        if (depth < (state->certsProcessed)) {
   1140                PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
   1141                        (currentNode, &children, plContext),
   1142                        PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
   1143 
   1144                if (children) {
   1145                        PKIX_CHECK(PKIX_List_GetLength
   1146                                (children, &numChildren, plContext),
   1147                                PKIX_LISTGETLENGTHFAILED);
   1148                }
   1149 
   1150                for (childIx = 0; childIx < numChildren; childIx++) {
   1151 
   1152                        PKIX_CHECK(PKIX_List_GetItem
   1153                            (children,
   1154                            childIx,
   1155                            (PKIX_PL_Object **)&childNode,
   1156                            plContext),
   1157                            PKIX_LISTGETITEMFAILED);
   1158 
   1159                        PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive
   1160                            (policyOID,
   1161                            policyQualifiers,
   1162                            subjectDomainPolicies,
   1163                            childNode,
   1164                            state,
   1165                            pChildNodeCreated,
   1166                            plContext),
   1167                            PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED);
   1168 
   1169                        PKIX_DECREF(childNode);
   1170                }
   1171        } else { /* if at the bottom of the tree */
   1172 
   1173                /* Check whether policy is in this node's expectedPolicySet */
   1174                PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies
   1175                        (currentNode, &expectedPolicies, plContext),
   1176                        PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED);
   1177 
   1178                PKIX_NULLCHECK_ONE(expectedPolicies);
   1179 
   1180                PKIX_CHECK(pkix_List_Contains
   1181                        (expectedPolicies,
   1182                        (PKIX_PL_Object *)policyOID,
   1183                        &isIncluded,
   1184                        plContext),
   1185                        PKIX_LISTCONTAINSFAILED);
   1186 
   1187                if (isIncluded) {
   1188                        PKIX_CHECK(pkix_PolicyChecker_Spawn
   1189                                (currentNode,
   1190                                policyOID,
   1191                                policyQualifiers,
   1192                                subjectDomainPolicies,
   1193                                state,
   1194                                plContext),
   1195                                PKIX_POLICYCHECKERSPAWNFAILED);
   1196 
   1197                        *pChildNodeCreated = PKIX_TRUE;
   1198                }
   1199        }
   1200 
   1201 cleanup:
   1202 
   1203        PKIX_DECREF(children);
   1204        PKIX_DECREF(childNode);
   1205        PKIX_DECREF(expectedPolicies);
   1206 
   1207        PKIX_RETURN(CERTCHAINCHECKER);
   1208 }
   1209 
   1210 /*
   1211 * FUNCTION: pkix_PolicyChecker_CheckPolicy
   1212 * DESCRIPTION:
   1213 *
   1214 *  Performs the non-recursive portion of the policy processing for the policy
   1215 *  whose OID is pointed to by "policyOID" and whose List of
   1216 *  CertPolicyQualifiers is pointed to by "policyQualifiers", for the
   1217 *  Certificate pointed to by "cert" with the List of CertPolicyMaps pointed
   1218 *  to by "maps", in accordance with the current PolicyCheckerState pointed
   1219 *  to by "state".
   1220 *
   1221 *  This function implements the processing described in RFC3280
   1222 *  Section 6.1.3(d)(1)(i).
   1223 *
   1224 * PARAMETERS:
   1225 *  "policyOID"
   1226 *      Address of OID of the policy to be checked for. Must be non-NULL.
   1227 *  "policyQualifiers"
   1228 *      Address of List of CertPolicyQualifiers of the policy to be checked for.
   1229 *      May be empty or NULL.
   1230 *  "cert"
   1231 *      Address of the current certificate. Must be non-NULL.
   1232 *  "maps"
   1233 *      Address of List of CertPolicyMaps for the current certificate
   1234 *  "state"
   1235 *      Address of PolicyCheckerState of the current PolicyChecker. Must be
   1236 *      non-NULL.
   1237 *  "plContext"
   1238 *      Platform-specific context pointer.
   1239 * THREAD SAFETY:
   1240 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1241 * RETURNS:
   1242 *  Returns NULL if the function succeeds
   1243 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   1244 *  Returns a Fatal Error if the function fails in an unrecoverable way
   1245 */
   1246 static PKIX_Error *
   1247 pkix_PolicyChecker_CheckPolicy(
   1248        PKIX_PL_OID *policyOID,
   1249        PKIX_List *policyQualifiers,
   1250        PKIX_PL_Cert *cert,
   1251        PKIX_List *maps,
   1252        PKIX_PolicyCheckerState *state,
   1253        void *plContext)
   1254 {
   1255        PKIX_Boolean childNodeCreated = PKIX_FALSE;
   1256        PKIX_Boolean okToSpawn = PKIX_FALSE;
   1257        PKIX_Boolean found = PKIX_FALSE;
   1258        PKIX_List *subjectDomainPolicies = NULL;
   1259 
   1260        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckPolicy");
   1261        PKIX_NULLCHECK_THREE(policyOID, cert, state);
   1262 
   1263        /*
   1264         * If this is not the last certificate, get the set of
   1265         * subjectDomainPolicies that "policy" maps to, according to the
   1266         * current cert's policy mapping extension. That set will be NULL
   1267         * if the current cert does not have a policy mapping extension,
   1268         * or if the current policy is not mapped.
   1269         */
   1270        if (state->certsProcessed != (state->numCerts - 1)) {
   1271            PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
   1272                (maps, policyOID, &subjectDomainPolicies, plContext),
   1273                PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
   1274        }
   1275 
   1276        /*
   1277         * Section 6.1.4(b)(2) tells us that if policyMapping is zero, we
   1278         * will have to delete any nodes created with validPolicies equal to
   1279         * policies that appear as issuerDomainPolicies in a policy mapping
   1280         * extension. Let's avoid creating any such nodes.
   1281         */
   1282        if ((state->policyMapping) == 0) {
   1283                if (subjectDomainPolicies) {
   1284                        goto cleanup;
   1285                }
   1286        }
   1287 
   1288        PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive
   1289                (policyOID,
   1290                policyQualifiers,
   1291                subjectDomainPolicies,
   1292                state->validPolicyTree,
   1293                state,
   1294                &childNodeCreated,
   1295                plContext),
   1296                PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED);
   1297 
   1298        if (!childNodeCreated) {
   1299                /*
   1300                 * Section 6.1.3(d)(1)(ii)
   1301                 * There was no match. If there was a node at
   1302                 * depth i-1 with valid policy anyPolicy,
   1303                 * generate a node subordinate to that.
   1304                 *
   1305                 * But that means this created node would be in
   1306                 * the valid-policy-node-set, and will be
   1307                 * pruned in 6.1.5(g)(iii)(2) unless it is in
   1308                 * the user-initial-policy-set or the user-
   1309                 * initial-policy-set is {anyPolicy}. So check,
   1310                 * and don't create it if it will be pruned.
   1311                 */
   1312                if (state->anyPolicyNodeAtBottom) {
   1313                        if (state->initialIsAnyPolicy) {
   1314                                okToSpawn = PKIX_TRUE;
   1315                        } else {
   1316                                PKIX_CHECK(pkix_List_Contains
   1317                                        (state->mappedUserInitialPolicySet,
   1318                                        (PKIX_PL_Object *)policyOID,
   1319                                        &okToSpawn,
   1320                                        plContext),
   1321                                        PKIX_LISTCONTAINSFAILED);
   1322                        }
   1323                        if (okToSpawn) {
   1324                                PKIX_CHECK(pkix_PolicyChecker_Spawn
   1325                                        (state->anyPolicyNodeAtBottom,
   1326                                        policyOID,
   1327                                        policyQualifiers,
   1328                                        subjectDomainPolicies,
   1329                                        state,
   1330                                        plContext),
   1331                                        PKIX_POLICYCHECKERSPAWNFAILED);
   1332                                childNodeCreated = PKIX_TRUE;
   1333                        }
   1334                }
   1335        }
   1336 
   1337        if (childNodeCreated) {
   1338                /*
   1339                 * If this policy had qualifiers, and the certificate policies
   1340                 * extension was marked critical, and the user cannot deal with
   1341                 * policy qualifiers, throw an error.
   1342                 */
   1343                if (policyQualifiers &&
   1344                    state->certPoliciesCritical &&
   1345                    state->policyQualifiersRejected) {
   1346                    PKIX_ERROR
   1347                        (PKIX_QUALIFIERSINCRITICALCERTIFICATEPOLICYEXTENSION);
   1348                }
   1349                /*
   1350                 * If the policy we just propagated was in the list of mapped
   1351                 * policies, remove it from the list. That list is used, at the
   1352                 * end, to determine policies that have not been propagated.
   1353                 */
   1354                if (state->mappedPolicyOIDs) {
   1355                        PKIX_CHECK(pkix_List_Contains
   1356                                (state->mappedPolicyOIDs,
   1357                                (PKIX_PL_Object *)policyOID,
   1358                                &found,
   1359                                plContext),
   1360                                PKIX_LISTCONTAINSFAILED);
   1361                        if (found) {
   1362                                PKIX_CHECK(pkix_List_Remove
   1363                                        (state->mappedPolicyOIDs,
   1364                                        (PKIX_PL_Object *)policyOID,
   1365                                        plContext),
   1366                                        PKIX_LISTREMOVEFAILED);
   1367                        }
   1368                }
   1369        }
   1370 
   1371 cleanup:
   1372 
   1373        PKIX_DECREF(subjectDomainPolicies);
   1374 
   1375        PKIX_RETURN(CERTCHAINCHECKER);
   1376 }
   1377 
   1378 /*
   1379 * FUNCTION: pkix_PolicyChecker_CheckAny
   1380 * DESCRIPTION:
   1381 *  Performs the creation of PolicyNodes, for the PolicyNode pointed to by
   1382 *  "currentNode" and PolicyNodes subordinate to it, using the List of
   1383 *  qualifiers pointed to by "qualsOfAny", in accordance with the current
   1384 *  certificate's PolicyMaps pointed to by "policyMaps" and the current
   1385 *  PolicyCheckerState pointed to by "state".
   1386 *
   1387 *  If the currentNode is not just above the bottom of the validPolicyTree, this
   1388 *  function calls itself recursively for each child of currentNode. At the
   1389 *  level just above the bottom, for each policy in the currentNode's
   1390 *  expectedPolicySet not already present in a child node, it creates a new
   1391 *  child node. The validPolicy of the child created, and its expectedPolicySet,
   1392 *  will be the policy from the currentNode's expectedPolicySet. The policy
   1393 *  qualifiers will be the qualifiers from the current certificate's anyPolicy,
   1394 *  the "qualsOfAny" parameter. If the currentNode's expectedSet includes
   1395 *  anyPolicy, a childNode will be created with a policy of anyPolicy. This is
   1396 *  the only way such a node can be created.
   1397 *
   1398 *  This function is called only when anyPolicy is one of the current
   1399 *  certificate's policies. This function implements the processing described
   1400 *  in RFC3280 Section 6.1.3(d)(2).
   1401 *
   1402 * PARAMETERS:
   1403 *  "currentNode"
   1404 *      Address of PolicyNode whose descendants will be checked, if not at the
   1405 *      bottom of the tree; or whose expectedPolicySet will be compared to those
   1406 *      in "alreadyPresent", if at the bottom. Must be non-NULL.
   1407 *  "qualsOfAny"
   1408 *      Address of List of qualifiers of the anyPolicy in the current
   1409 *      certificate. May be empty or NULL.
   1410 *  "policyMaps"
   1411 *      Address of the List of PolicyMaps of the current certificate. May be
   1412 *      empty or NULL.
   1413 *  "state"
   1414 *      Address of the current state of the PKIX_PolicyChecker.
   1415 *      Must be non-NULL.
   1416 *  "plContext"
   1417 *      Platform-specific context pointer.
   1418 * THREAD SAFETY:
   1419 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1420 * RETURNS:
   1421 *  Returns NULL if the function succeeds
   1422 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   1423 *  Returns a Fatal Error if the function fails in an unrecoverable way
   1424 */
   1425 static PKIX_Error *
   1426 pkix_PolicyChecker_CheckAny(
   1427        PKIX_PolicyNode *currentNode,
   1428        PKIX_List *qualsOfAny,  /* CertPolicyQualifiers */
   1429        PKIX_List *policyMaps,  /* CertPolicyMaps */
   1430        PKIX_PolicyCheckerState *state,
   1431        void *plContext)
   1432 {
   1433        PKIX_UInt32 depth = 0;
   1434        PKIX_UInt32 numChildren = 0;
   1435        PKIX_UInt32 childIx = 0;
   1436        PKIX_UInt32 numPolicies = 0;
   1437        PKIX_UInt32 polx = 0;
   1438        PKIX_Boolean isIncluded = PKIX_FALSE;
   1439        PKIX_List *children = NULL;     /* PolicyNodes */
   1440        PKIX_PolicyNode *childNode = NULL;
   1441        PKIX_List *expectedPolicies = NULL; /* OIDs */
   1442        PKIX_PL_OID *policyOID = NULL;
   1443        PKIX_PL_OID *childPolicy = NULL;
   1444        PKIX_List *subjectDomainPolicies = NULL;  /* OIDs */
   1445 
   1446        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckAny");
   1447        PKIX_NULLCHECK_TWO(currentNode, state);
   1448 
   1449        PKIX_CHECK(PKIX_PolicyNode_GetDepth
   1450                (currentNode, &depth, plContext),
   1451                PKIX_POLICYNODEGETDEPTHFAILED);
   1452 
   1453        PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
   1454                (currentNode, &children, plContext),
   1455                PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
   1456 
   1457        if (children) {
   1458                PKIX_CHECK(PKIX_List_GetLength
   1459                        (children, &numChildren, plContext),
   1460                        PKIX_LISTGETLENGTHFAILED);
   1461        }
   1462 
   1463        if (depth < (state->certsProcessed)) {
   1464                for (childIx = 0; childIx < numChildren; childIx++) {
   1465 
   1466                        PKIX_CHECK(PKIX_List_GetItem
   1467                                (children,
   1468                                childIx,
   1469                                (PKIX_PL_Object **)&childNode,
   1470                                plContext),
   1471                                PKIX_LISTGETITEMFAILED);
   1472 
   1473                        PKIX_NULLCHECK_ONE(childNode);
   1474                        PKIX_CHECK(pkix_PolicyChecker_CheckAny
   1475                                (childNode,
   1476                                qualsOfAny,
   1477                                policyMaps,
   1478                                state,
   1479                                plContext),
   1480                                PKIX_POLICYCHECKERCHECKANYFAILED);
   1481 
   1482                        PKIX_DECREF(childNode);
   1483                }
   1484        } else { /* if at the bottom of the tree */
   1485 
   1486            PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies
   1487                (currentNode, &expectedPolicies, plContext),
   1488                PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED);
   1489 
   1490            /* Expected Policy Set is not allowed to be NULL */
   1491            PKIX_NULLCHECK_ONE(expectedPolicies);
   1492 
   1493            PKIX_CHECK(PKIX_List_GetLength
   1494                (expectedPolicies, &numPolicies, plContext),
   1495                PKIX_LISTGETLENGTHFAILED);
   1496 
   1497            for (polx = 0; polx < numPolicies; polx++) {
   1498                PKIX_CHECK(PKIX_List_GetItem
   1499                    (expectedPolicies,
   1500                    polx,
   1501                    (PKIX_PL_Object **)&policyOID,
   1502                    plContext),
   1503                    PKIX_LISTGETITEMFAILED);
   1504 
   1505                PKIX_NULLCHECK_ONE(policyOID);
   1506 
   1507                isIncluded = PKIX_FALSE;
   1508 
   1509                for (childIx = 0;
   1510                    (!isIncluded && (childIx < numChildren));
   1511                    childIx++) {
   1512 
   1513                    PKIX_CHECK(PKIX_List_GetItem
   1514                        (children,
   1515                        childIx,
   1516                        (PKIX_PL_Object **)&childNode,
   1517                        plContext),
   1518                        PKIX_LISTGETITEMFAILED);
   1519 
   1520                    PKIX_NULLCHECK_ONE(childNode);
   1521 
   1522                    PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
   1523                        (childNode, &childPolicy, plContext),
   1524                        PKIX_POLICYNODEGETVALIDPOLICYFAILED);
   1525 
   1526                    PKIX_NULLCHECK_ONE(childPolicy);
   1527 
   1528                    PKIX_EQUALS(policyOID, childPolicy, &isIncluded, plContext,
   1529                        PKIX_OBJECTEQUALSFAILED);
   1530 
   1531                    PKIX_DECREF(childNode);
   1532                    PKIX_DECREF(childPolicy);
   1533                }
   1534 
   1535                if (!isIncluded) {
   1536                    if (policyMaps) {
   1537                        PKIX_CHECK
   1538                          (pkix_PolicyChecker_MapGetSubjectDomainPolicies
   1539                          (policyMaps,
   1540                          policyOID,
   1541                          &subjectDomainPolicies,
   1542                          plContext),
   1543                          PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
   1544                    }
   1545                    PKIX_CHECK(pkix_PolicyChecker_Spawn
   1546                        (currentNode,
   1547                        policyOID,
   1548                        qualsOfAny,
   1549                        subjectDomainPolicies,
   1550                        state,
   1551                        plContext),
   1552                        PKIX_POLICYCHECKERSPAWNFAILED);
   1553                    PKIX_DECREF(subjectDomainPolicies);
   1554                }
   1555 
   1556                PKIX_DECREF(policyOID);
   1557            }
   1558        }
   1559 
   1560 cleanup:
   1561 
   1562        PKIX_DECREF(children);
   1563        PKIX_DECREF(childNode);
   1564        PKIX_DECREF(expectedPolicies);
   1565        PKIX_DECREF(policyOID);
   1566        PKIX_DECREF(childPolicy);
   1567        PKIX_DECREF(subjectDomainPolicies);
   1568 
   1569        PKIX_RETURN(CERTCHAINCHECKER);
   1570 
   1571 }
   1572 
   1573 /*
   1574 * FUNCTION: pkix_PolicyChecker_CalculateIntersection
   1575 * DESCRIPTION:
   1576 *
   1577 *  Processes the PolicyNode pointed to by "currentNode", and its descendants,
   1578 *  using the PolicyCheckerState pointed to by "state", using the List at
   1579 *  the address pointed to by "nominees" the OIDs of policies that are in the
   1580 *  user-initial-policy-set but are not represented among the nodes at the
   1581 *  bottom of the tree, and storing at "pShouldBePruned" the value TRUE if
   1582 *  currentNode is childless at the end of this processing, FALSE if it has
   1583 *  children or is at the bottom of the tree.
   1584 *
   1585 *  When this function is called at the top level, "nominees" should be the List
   1586 *  of all policies in the user-initial-policy-set. Policies that are
   1587 *  represented in the valid-policy-node-set are removed from this List. As a
   1588 *  result when nodes are created according to 6.1.5.(g)(iii)(3)(b), a node will
   1589 *  be created for each policy remaining in this List.
   1590 *
   1591 *  This function implements the calculation of the intersection of the
   1592 *  validPolicyTree with the user-initial-policy-set, as described in
   1593 *  RFC 3280 6.1.5(g)(iii).
   1594 *
   1595 * PARAMETERS:
   1596 *  "currentNode"
   1597 *      Address of PolicyNode whose descendants will be processed as described.
   1598 *      Must be non-NULL.
   1599 *  "state"
   1600 *      Address of the current state of the PKIX_PolicyChecker. Must be non-NULL
   1601 *  "nominees"
   1602 *      Address of List of the OIDs for which nodes should be created to replace
   1603 *      anyPolicy nodes. Must be non-NULL but may be empty.
   1604 *  "pShouldBePruned"
   1605 *      Address where Boolean return value, set to TRUE if this PolicyNode
   1606 *      should be deleted, is stored. Must be non-NULL.
   1607 *  "plContext"
   1608 *      Platform-specific context pointer.
   1609 * THREAD SAFETY:
   1610 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1611 * RETURNS:
   1612 *  Returns NULL if the function succeeds
   1613 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   1614 *  Returns a Fatal Error if the function fails in an unrecoverable way
   1615 */
   1616 static PKIX_Error *
   1617 pkix_PolicyChecker_CalculateIntersection(
   1618        PKIX_PolicyNode *currentNode,
   1619        PKIX_PolicyCheckerState *state,
   1620        PKIX_List *nominees, /* OIDs */
   1621        PKIX_Boolean *pShouldBePruned,
   1622        void *plContext)
   1623 {
   1624        PKIX_Boolean currentPolicyIsAny = PKIX_FALSE;
   1625        PKIX_Boolean parentPolicyIsAny = PKIX_FALSE;
   1626        PKIX_Boolean currentPolicyIsValid = PKIX_FALSE;
   1627        PKIX_Boolean shouldBePruned = PKIX_FALSE;
   1628        PKIX_Boolean priorCriticality = PKIX_FALSE;
   1629        PKIX_UInt32 depth = 0;
   1630        PKIX_UInt32 numChildren = 0;
   1631        PKIX_UInt32 childIndex = 0;
   1632        PKIX_UInt32 numNominees = 0;
   1633        PKIX_UInt32 polIx = 0;
   1634        PKIX_PL_OID *currentPolicy = NULL;
   1635        PKIX_PL_OID *parentPolicy = NULL;
   1636        PKIX_PL_OID *substPolicy = NULL;
   1637        PKIX_PolicyNode *parent = NULL;
   1638        PKIX_PolicyNode *child = NULL;
   1639        PKIX_List *children = NULL; /* PolicyNodes */
   1640        PKIX_List *policyQualifiers = NULL;
   1641 
   1642        PKIX_ENTER
   1643                (CERTCHAINCHECKER,
   1644                "pkix_PolicyChecker_CalculateIntersection");
   1645 
   1646        /*
   1647         * We call this function if the valid_policy_tree is not NULL and
   1648         * the user-initial-policy-set is not any-policy.
   1649         */
   1650        if (!state->validPolicyTree || state->initialIsAnyPolicy) {
   1651                PKIX_ERROR(PKIX_PRECONDITIONFAILED);
   1652        }
   1653 
   1654        PKIX_NULLCHECK_FOUR(currentNode, state, nominees, pShouldBePruned);
   1655 
   1656        PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
   1657                (currentNode, &currentPolicy, plContext),
   1658                PKIX_POLICYNODEGETVALIDPOLICYFAILED);
   1659 
   1660        PKIX_NULLCHECK_TWO(state->anyPolicyOID, currentPolicy);
   1661 
   1662        PKIX_EQUALS
   1663                (state->anyPolicyOID,
   1664                currentPolicy,
   1665                &currentPolicyIsAny,
   1666                plContext,
   1667                PKIX_OBJECTEQUALSFAILED);
   1668 
   1669        PKIX_CHECK(PKIX_PolicyNode_GetParent(currentNode, &parent, plContext),
   1670                PKIX_POLICYNODEGETPARENTFAILED);
   1671 
   1672        if (currentPolicyIsAny == PKIX_FALSE) {
   1673 
   1674                /*
   1675                 * If we are at the top of the tree, or if our
   1676                 * parent's validPolicy is anyPolicy, we are in
   1677                 * the valid policy node set.
   1678                 */
   1679                if (parent) {
   1680                        PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
   1681                                (parent, &parentPolicy, plContext),
   1682                                PKIX_POLICYNODEGETVALIDPOLICYFAILED);
   1683 
   1684                        PKIX_NULLCHECK_ONE(parentPolicy);
   1685 
   1686                        PKIX_EQUALS
   1687                                (state->anyPolicyOID,
   1688                                parentPolicy,
   1689                                &parentPolicyIsAny,
   1690                                plContext,
   1691                                PKIX_OBJECTEQUALSFAILED);
   1692                }
   1693 
   1694                /*
   1695                 * Section 6.1.5(g)(iii)(2)
   1696                 * If this node's policy is not in the user-initial-policy-set,
   1697                 * it is not in the intersection. Prune it.
   1698                 */
   1699                if (!parent || parentPolicyIsAny) {
   1700                        PKIX_CHECK(pkix_List_Contains
   1701                                (state->userInitialPolicySet,
   1702                                (PKIX_PL_Object *)currentPolicy,
   1703                                &currentPolicyIsValid,
   1704                                plContext),
   1705                                PKIX_LISTCONTAINSFAILED);
   1706                        if (!currentPolicyIsValid) {
   1707                                *pShouldBePruned = PKIX_TRUE;
   1708                                goto cleanup;
   1709                        }
   1710 
   1711                        /*
   1712                         * If this node's policy is in the user-initial-policy-
   1713                         * set, it will propagate that policy into the next
   1714                         * level of the tree. Remove the policy from the list
   1715                         * of policies that an anyPolicy will spawn.
   1716                         */
   1717                        PKIX_CHECK(pkix_List_Remove
   1718                                (nominees,
   1719                                (PKIX_PL_Object *)currentPolicy,
   1720                                plContext),
   1721                                PKIX_LISTREMOVEFAILED);
   1722                }
   1723        }
   1724 
   1725 
   1726        /* Are we at the bottom of the tree? */
   1727 
   1728        PKIX_CHECK(PKIX_PolicyNode_GetDepth
   1729                (currentNode, &depth, plContext),
   1730                PKIX_POLICYNODEGETDEPTHFAILED);
   1731 
   1732        if (depth == (state->numCerts)) {
   1733                /*
   1734                 * Section 6.1.5(g)(iii)(3)
   1735                 * Replace anyPolicy nodes...
   1736                 */
   1737                if (currentPolicyIsAny == PKIX_TRUE) {
   1738 
   1739                        /* replace this node */
   1740 
   1741                        PKIX_CHECK(PKIX_List_GetLength
   1742                            (nominees, &numNominees, plContext),
   1743                            PKIX_LISTGETLENGTHFAILED);
   1744 
   1745                        if (numNominees) {
   1746 
   1747                            PKIX_CHECK(PKIX_PolicyNode_GetPolicyQualifiers
   1748                                (currentNode,
   1749                                &policyQualifiers,
   1750                                plContext),
   1751                                PKIX_POLICYNODEGETPOLICYQUALIFIERSFAILED);
   1752 
   1753                            PKIX_CHECK(PKIX_PolicyNode_IsCritical
   1754                                (currentNode, &priorCriticality, plContext),
   1755                                PKIX_POLICYNODEISCRITICALFAILED);
   1756                        }
   1757 
   1758                        PKIX_NULLCHECK_ONE(parent);
   1759 
   1760                        for (polIx = 0; polIx < numNominees; polIx++) {
   1761 
   1762                            PKIX_CHECK(PKIX_List_GetItem
   1763                                (nominees,
   1764                                polIx,
   1765                                (PKIX_PL_Object **)&substPolicy,
   1766                                plContext),
   1767                                PKIX_LISTGETITEMFAILED);
   1768 
   1769                            PKIX_CHECK(pkix_PolicyChecker_Spawn
   1770                                (parent,
   1771                                substPolicy,
   1772                                policyQualifiers,
   1773                                NULL,
   1774                                state,
   1775                                plContext),
   1776                                PKIX_POLICYCHECKERSPAWNFAILED);
   1777 
   1778                            PKIX_DECREF(substPolicy);
   1779 
   1780                        }
   1781                        /* remove currentNode from parent */
   1782                        *pShouldBePruned = PKIX_TRUE;
   1783                        /*
   1784                         * We can get away with augmenting the parent's List
   1785                         * of children because we started at the end and went
   1786                         * toward the beginning. New nodes are added at the end.
   1787                         */
   1788                }
   1789        } else {
   1790                /*
   1791                 * Section 6.1.5(g)(iii)(4)
   1792                 * Prune any childless nodes above the bottom level
   1793                 */
   1794                PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
   1795                        (currentNode, &children, plContext),
   1796                        PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
   1797 
   1798                /* CurrentNode should have been pruned if childless. */
   1799                PKIX_NULLCHECK_ONE(children);
   1800 
   1801                PKIX_CHECK(PKIX_List_GetLength
   1802                        (children, &numChildren, plContext),
   1803                        PKIX_LISTGETLENGTHFAILED);
   1804 
   1805                for (childIndex = numChildren; childIndex > 0; childIndex--) {
   1806 
   1807                    PKIX_CHECK(PKIX_List_GetItem
   1808                        (children,
   1809                        childIndex - 1,
   1810                        (PKIX_PL_Object **)&child,
   1811                        plContext),
   1812                        PKIX_LISTGETITEMFAILED);
   1813 
   1814                    PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection
   1815                        (child, state, nominees, &shouldBePruned, plContext),
   1816                        PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED);
   1817 
   1818                    if (PKIX_TRUE == shouldBePruned) {
   1819 
   1820                        PKIX_CHECK(PKIX_List_DeleteItem
   1821                                (children, childIndex - 1, plContext),
   1822                                PKIX_LISTDELETEITEMFAILED);
   1823                        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   1824                                ((PKIX_PL_Object *)state, plContext),
   1825                                PKIX_OBJECTINVALIDATECACHEFAILED);
   1826                    }
   1827 
   1828                    PKIX_DECREF(child);
   1829                }
   1830 
   1831                PKIX_CHECK(PKIX_List_GetLength
   1832                        (children, &numChildren, plContext),
   1833                        PKIX_LISTGETLENGTHFAILED);
   1834 
   1835                if (numChildren == 0) {
   1836                        *pShouldBePruned = PKIX_TRUE;
   1837                }
   1838        }
   1839 cleanup:
   1840        PKIX_DECREF(currentPolicy);
   1841        PKIX_DECREF(parentPolicy);
   1842        PKIX_DECREF(substPolicy);
   1843        PKIX_DECREF(parent);
   1844        PKIX_DECREF(child);
   1845        PKIX_DECREF(children);
   1846        PKIX_DECREF(policyQualifiers);
   1847 
   1848        PKIX_RETURN(CERTCHAINCHECKER);
   1849 
   1850 }
   1851 
   1852 /*
   1853 * FUNCTION: pkix_PolicyChecker_PolicyMapProcessing
   1854 * DESCRIPTION:
   1855 *
   1856 *  Performs the processing of Policies in the List of CertPolicyMaps pointed
   1857 *  to by "policyMaps", using and updating the PolicyCheckerState pointed to by
   1858 *  "state".
   1859 *
   1860 *  This function implements the policyMap processing described in RFC3280
   1861 *  Section 6.1.4(b)(1), after certificate i has been processed, in preparation
   1862 *  for certificate i+1. Section references are to that document.
   1863 *
   1864 * PARAMETERS:
   1865 *  "policyMaps"
   1866 *      Address of the List of CertPolicyMaps presented by certificate i.
   1867 *      Must be non-NULL.
   1868 *  "certPoliciesIncludeAny"
   1869 *      Boolean value which is PKIX_TRUE if the current certificate asserts
   1870 *      anyPolicy, PKIX_FALSE otherwise.
   1871 *  "qualsOfAny"
   1872 *      Address of List of qualifiers of the anyPolicy in the current
   1873 *      certificate. May be empty or NULL.
   1874 *  "state"
   1875 *      Address of the current state of the PKIX_PolicyChecker.
   1876 *      Must be non-NULL.
   1877 *  "plContext"
   1878 *      Platform-specific context pointer.
   1879 * THREAD SAFETY:
   1880 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1881 * RETURNS:
   1882 *  Returns NULL if the function succeeds
   1883 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   1884 *  Returns a Fatal Error if the function fails in an unrecoverable way
   1885 */
   1886 static PKIX_Error *
   1887 pkix_PolicyChecker_PolicyMapProcessing(
   1888        PKIX_List *policyMaps,  /* CertPolicyMaps */
   1889        PKIX_Boolean certPoliciesIncludeAny,
   1890        PKIX_List *qualsOfAny,
   1891        PKIX_PolicyCheckerState *state,
   1892        void *plContext)
   1893 {
   1894        PKIX_UInt32 numPolicies = 0;
   1895        PKIX_UInt32 polX = 0;
   1896        PKIX_PL_OID *policyOID = NULL;
   1897        PKIX_List *newMappedPolicies = NULL;  /* OIDs */
   1898        PKIX_List *subjectDomainPolicies = NULL;  /* OIDs */
   1899 
   1900        PKIX_ENTER
   1901                (CERTCHAINCHECKER,
   1902                "pkix_PolicyChecker_PolicyMapProcessing");
   1903        PKIX_NULLCHECK_THREE
   1904                (policyMaps,
   1905                state,
   1906                state->mappedUserInitialPolicySet);
   1907 
   1908        /*
   1909         * For each policy in mappedUserInitialPolicySet, if it is not mapped,
   1910         * append it to new policySet; if it is mapped, append its
   1911         * subjectDomainPolicies to new policySet. When done, this new
   1912         * policySet will replace mappedUserInitialPolicySet.
   1913         */
   1914        PKIX_CHECK(PKIX_List_Create
   1915                (&newMappedPolicies, plContext),
   1916                PKIX_LISTCREATEFAILED);
   1917 
   1918        PKIX_CHECK(PKIX_List_GetLength
   1919                (state->mappedUserInitialPolicySet,
   1920                &numPolicies,
   1921                plContext),
   1922                PKIX_LISTGETLENGTHFAILED);
   1923 
   1924        for (polX = 0; polX < numPolicies; polX++) {
   1925 
   1926            PKIX_CHECK(PKIX_List_GetItem
   1927                (state->mappedUserInitialPolicySet,
   1928                polX,
   1929                (PKIX_PL_Object **)&policyOID,
   1930                plContext),
   1931                PKIX_LISTGETITEMFAILED);
   1932 
   1933            PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
   1934                (policyMaps,
   1935                policyOID,
   1936                &subjectDomainPolicies,
   1937                plContext),
   1938                PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
   1939 
   1940            if (subjectDomainPolicies) {
   1941 
   1942                PKIX_CHECK(pkix_List_AppendUnique
   1943                        (newMappedPolicies,
   1944                        subjectDomainPolicies,
   1945                        plContext),
   1946                        PKIX_LISTAPPENDUNIQUEFAILED);
   1947 
   1948                PKIX_DECREF(subjectDomainPolicies);
   1949 
   1950            } else {
   1951                PKIX_CHECK(PKIX_List_AppendItem
   1952                        (newMappedPolicies,
   1953                        (PKIX_PL_Object *)policyOID,
   1954                        plContext),
   1955                        PKIX_LISTAPPENDITEMFAILED);
   1956            }
   1957            PKIX_DECREF(policyOID);
   1958        }
   1959 
   1960        /*
   1961         * For each policy ID-P remaining in mappedPolicyOIDs, it has not been
   1962         * propagated to the bottom of the tree (depth i). If policyMapping
   1963         * is greater than zero and this cert contains anyPolicy and the tree
   1964         * contains an anyPolicy node at depth i-1, then we must create a node
   1965         * with validPolicy ID-P, the policy qualifiers of anyPolicy in
   1966         * this certificate, and expectedPolicySet the subjectDomainPolicies
   1967         * that ID-P maps to. We also then add those subjectDomainPolicies to
   1968         * the list of policies that will be accepted in the next certificate,
   1969         * the mappedUserInitialPolicySet.
   1970         */
   1971 
   1972        if ((state->policyMapping > 0) && (certPoliciesIncludeAny) &&
   1973            (state->anyPolicyNodeAtBottom) && (state->mappedPolicyOIDs)) {
   1974 
   1975                PKIX_CHECK(PKIX_List_GetLength
   1976                    (state->mappedPolicyOIDs,
   1977                    &numPolicies,
   1978                    plContext),
   1979                    PKIX_LISTGETLENGTHFAILED);
   1980 
   1981                for (polX = 0; polX < numPolicies; polX++) {
   1982 
   1983                    PKIX_CHECK(PKIX_List_GetItem
   1984                        (state->mappedPolicyOIDs,
   1985                        polX,
   1986                        (PKIX_PL_Object **)&policyOID,
   1987                        plContext),
   1988                        PKIX_LISTGETITEMFAILED);
   1989 
   1990                    PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
   1991                        (policyMaps,
   1992                        policyOID,
   1993                        &subjectDomainPolicies,
   1994                        plContext),
   1995                        PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
   1996 
   1997                    PKIX_CHECK(pkix_PolicyChecker_Spawn
   1998                        (state->anyPolicyNodeAtBottom,
   1999                        policyOID,
   2000                        qualsOfAny,
   2001                        subjectDomainPolicies,
   2002                        state,
   2003                        plContext),
   2004                        PKIX_POLICYCHECKERSPAWNFAILED);
   2005 
   2006                    PKIX_CHECK(pkix_List_AppendUnique
   2007                        (newMappedPolicies,
   2008                        subjectDomainPolicies,
   2009                        plContext),
   2010                        PKIX_LISTAPPENDUNIQUEFAILED);
   2011 
   2012                    PKIX_DECREF(subjectDomainPolicies);
   2013                    PKIX_DECREF(policyOID);
   2014                }
   2015        }
   2016 
   2017        PKIX_CHECK(PKIX_List_SetImmutable(newMappedPolicies, plContext),
   2018                PKIX_LISTSETIMMUTABLEFAILED);
   2019 
   2020        PKIX_DECREF(state->mappedUserInitialPolicySet);
   2021        PKIX_INCREF(newMappedPolicies);
   2022 
   2023        state->mappedUserInitialPolicySet = newMappedPolicies;
   2024 
   2025 cleanup:
   2026 
   2027        PKIX_DECREF(policyOID);
   2028        PKIX_DECREF(newMappedPolicies);
   2029        PKIX_DECREF(subjectDomainPolicies);
   2030 
   2031        PKIX_RETURN(CERTCHAINCHECKER);
   2032 }
   2033 
   2034 /*
   2035 * FUNCTION: pkix_PolicyChecker_WrapUpProcessing
   2036 * DESCRIPTION:
   2037 *
   2038 *  Performs the wrap-up processing for the Cert pointed to by "cert",
   2039 *  using and updating the PolicyCheckerState pointed to by "state".
   2040 *
   2041 *  This function implements the wrap-up processing described in RFC3280
   2042 *  Section 6.1.5, after the final certificate has been processed. Section
   2043 *  references in the comments are to that document.
   2044 *
   2045 * PARAMETERS:
   2046 *  "cert"
   2047 *      Address of the current (presumably the end entity) certificate.
   2048 *      Must be non-NULL.
   2049 *  "state"
   2050 *      Address of the current state of the PKIX_PolicyChecker.
   2051 *      Must be non-NULL.
   2052 *  "plContext"
   2053 *      Platform-specific context pointer.
   2054 * THREAD SAFETY:
   2055 *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   2056 * RETURNS:
   2057 *  Returns NULL if the function succeeds
   2058 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   2059 *  Returns a Fatal Error if the function fails in an unrecoverable way
   2060 */
   2061 static PKIX_Error *
   2062 pkix_PolicyChecker_WrapUpProcessing(
   2063        PKIX_PL_Cert *cert,
   2064        PKIX_PolicyCheckerState *state,
   2065        void *plContext)
   2066 {
   2067        PKIX_Int32 explicitPolicySkipCerts = 0;
   2068        PKIX_Boolean isSelfIssued = PKIX_FALSE;
   2069        PKIX_Boolean shouldBePruned = PKIX_FALSE;
   2070        PKIX_List *nominees = NULL; /* OIDs */
   2071 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2072        PKIX_PL_String *stateString = NULL;
   2073        char *stateAscii = NULL;
   2074        PKIX_UInt32 length;
   2075 #endif
   2076 
   2077        PKIX_ENTER
   2078                (CERTCHAINCHECKER,
   2079                "pkix_PolicyChecker_WrapUpProcessing");
   2080        PKIX_NULLCHECK_THREE(cert, state, state->userInitialPolicySet);
   2081 
   2082 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2083        PKIX_CHECK(PKIX_PL_Object_ToString
   2084                ((PKIX_PL_Object*)state, &stateString, plContext),
   2085                PKIX_OBJECTTOSTRINGFAILED);
   2086 
   2087        PKIX_CHECK(PKIX_PL_String_GetEncoded
   2088                    (stateString,
   2089                    PKIX_ESCASCII,
   2090                    (void **)&stateAscii,
   2091                    &length,
   2092                    plContext),
   2093                    PKIX_STRINGGETENCODEDFAILED);
   2094 
   2095        PKIX_DEBUG_ARG("%s\n", stateAscii);
   2096 
   2097        PKIX_FREE(stateAscii);
   2098        PKIX_DECREF(stateString);
   2099 #endif
   2100 
   2101        /* Section 6.1.5(a) ... */
   2102        PKIX_CHECK(pkix_IsCertSelfIssued
   2103                (cert, &isSelfIssued, plContext),
   2104                PKIX_ISCERTSELFISSUEDFAILED);
   2105 
   2106        if (!isSelfIssued) {
   2107                if (state->explicitPolicy > 0) {
   2108 
   2109                        state->explicitPolicy--;
   2110 
   2111                        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2112                                ((PKIX_PL_Object *)state, plContext),
   2113                                PKIX_OBJECTINVALIDATECACHEFAILED);
   2114                }
   2115        }
   2116 
   2117        /* Section 6.1.5(b) ... */
   2118        PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
   2119                (cert, &explicitPolicySkipCerts, plContext),
   2120                PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
   2121 
   2122        if (explicitPolicySkipCerts  == 0) {
   2123                state->explicitPolicy = 0;
   2124        }
   2125 
   2126        /* Section 6.1.5(g)(i) ... */
   2127 
   2128        if (!(state->validPolicyTree)) {
   2129                goto cleanup;
   2130        }
   2131 
   2132        /* Section 6.1.5(g)(ii) ... */
   2133 
   2134        if (state->initialIsAnyPolicy) {
   2135                goto cleanup;
   2136        }
   2137 
   2138        /*
   2139         * Section 6.1.5(g)(iii) ...
   2140         * Create a list of policies which could be substituted for anyPolicy.
   2141         * Start with a (mutable) copy of user-initial-policy-set.
   2142         */
   2143        PKIX_CHECK(pkix_PolicyChecker_MakeMutableCopy
   2144                (state->userInitialPolicySet, &nominees, plContext),
   2145                PKIX_POLICYCHECKERMAKEMUTABLECOPYFAILED);
   2146 
   2147        PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection
   2148                (state->validPolicyTree, /* node at top of tree */
   2149                state,
   2150                nominees,
   2151                &shouldBePruned,
   2152                plContext),
   2153                PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED);
   2154 
   2155        if (PKIX_TRUE == shouldBePruned) {
   2156                PKIX_DECREF(state->validPolicyTree);
   2157        }
   2158 
   2159        if (state->validPolicyTree) {
   2160                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2161                        ((PKIX_PL_Object *)state->validPolicyTree, plContext),
   2162                        PKIX_OBJECTINVALIDATECACHEFAILED);
   2163        }
   2164 
   2165        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2166                ((PKIX_PL_Object *)state, plContext),
   2167                PKIX_OBJECTINVALIDATECACHEFAILED);
   2168 
   2169 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2170        if (state->validPolicyTree) {
   2171                PKIX_CHECK(PKIX_PL_Object_ToString
   2172                        ((PKIX_PL_Object*)state, &stateString, plContext),
   2173                        PKIX_OBJECTTOSTRINGFAILED);
   2174 
   2175                PKIX_CHECK(PKIX_PL_String_GetEncoded
   2176                            (stateString,
   2177                            PKIX_ESCASCII,
   2178                            (void **)&stateAscii,
   2179                            &length,
   2180                            plContext),
   2181                            PKIX_STRINGGETENCODEDFAILED);
   2182 
   2183                PKIX_DEBUG_ARG
   2184                        ("After CalculateIntersection:\n%s\n", stateAscii);
   2185 
   2186                PKIX_FREE(stateAscii);
   2187                PKIX_DECREF(stateString);
   2188        } else {
   2189                PKIX_DEBUG("validPolicyTree is NULL\n");
   2190        }
   2191 #endif
   2192 
   2193        /* Section 6.1.5(g)(iii)(4) ... */
   2194 
   2195        if (state->validPolicyTree) {
   2196 
   2197                PKIX_CHECK(pkix_PolicyNode_Prune
   2198                        (state->validPolicyTree,
   2199                        state->numCerts,
   2200                        &shouldBePruned,
   2201                        plContext),
   2202                        PKIX_POLICYNODEPRUNEFAILED);
   2203 
   2204                if (shouldBePruned) {
   2205                        PKIX_DECREF(state->validPolicyTree);
   2206                }
   2207        }
   2208 
   2209        if (state->validPolicyTree) {
   2210                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2211                        ((PKIX_PL_Object *)state->validPolicyTree, plContext),
   2212                        PKIX_OBJECTINVALIDATECACHEFAILED);
   2213        }
   2214 
   2215        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2216                ((PKIX_PL_Object *)state, plContext),
   2217                PKIX_OBJECTINVALIDATECACHEFAILED);
   2218 
   2219 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2220        PKIX_CHECK(PKIX_PL_Object_ToString
   2221                ((PKIX_PL_Object*)state, &stateString, plContext),
   2222                PKIX_OBJECTTOSTRINGFAILED);
   2223        PKIX_CHECK(PKIX_PL_String_GetEncoded
   2224                    (stateString,
   2225                    PKIX_ESCASCII,
   2226                    (void **)&stateAscii,
   2227                    &length,
   2228                    plContext),
   2229                    PKIX_STRINGGETENCODEDFAILED);
   2230        PKIX_DEBUG_ARG("%s\n", stateAscii);
   2231 
   2232        PKIX_FREE(stateAscii);
   2233        PKIX_DECREF(stateString);
   2234 #endif
   2235 
   2236 cleanup:
   2237 
   2238        PKIX_DECREF(nominees);
   2239 
   2240        PKIX_RETURN(CERTCHAINCHECKER);
   2241 }
   2242 
   2243 
   2244 /*
   2245 * FUNCTION: pkix_PolicyChecker_Check
   2246 * (see comments in pkix_checker.h for PKIX_CertChainChecker_CheckCallback)
   2247 *
   2248 * Labels referring to sections, such as "Section 6.1.3(d)", refer to
   2249 * sections of RFC3280, Section 6.1.3 Basic Certificate Processing.
   2250 *
   2251 * If a non-fatal error occurs, it is unlikely that policy processing can
   2252 * continue. But it is still possible that chain validation could succeed if
   2253 * policy processing is non-critical. So if this function receives a non-fatal
   2254 * error from a lower level routine, it aborts policy processing by setting
   2255 * the validPolicyTree to NULL and tries to continue.
   2256 *
   2257 */
   2258 static PKIX_Error *
   2259 pkix_PolicyChecker_Check(
   2260        PKIX_CertChainChecker *checker,
   2261        PKIX_PL_Cert *cert,
   2262        PKIX_List *unresolvedCriticals,  /* OIDs */
   2263        void **pNBIOContext,
   2264        void *plContext)
   2265 {
   2266        PKIX_UInt32 numPolicies = 0;
   2267        PKIX_UInt32 polX = 0;
   2268        PKIX_Boolean result = PKIX_FALSE;
   2269        PKIX_Int32 inhibitMappingSkipCerts = 0;
   2270        PKIX_Int32 explicitPolicySkipCerts = 0;
   2271        PKIX_Int32 inhibitAnyPolicySkipCerts = 0;
   2272        PKIX_Boolean shouldBePruned = PKIX_FALSE;
   2273        PKIX_Boolean isSelfIssued = PKIX_FALSE;
   2274        PKIX_Boolean certPoliciesIncludeAny = PKIX_FALSE;
   2275        PKIX_Boolean doAnyPolicyProcessing = PKIX_FALSE;
   2276 
   2277        PKIX_PolicyCheckerState *state = NULL;
   2278        PKIX_List *certPolicyInfos = NULL; /* CertPolicyInfos */
   2279        PKIX_PL_CertPolicyInfo *policy = NULL;
   2280        PKIX_PL_OID *policyOID = NULL;
   2281        PKIX_List *qualsOfAny = NULL; /* CertPolicyQualifiers */
   2282        PKIX_List *policyQualifiers = NULL; /* CertPolicyQualifiers */
   2283        PKIX_List *policyMaps = NULL; /* CertPolicyMaps */
   2284        PKIX_List *mappedPolicies = NULL; /* OIDs */
   2285        PKIX_Error *subroutineErr = NULL;
   2286 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2287        PKIX_PL_String *stateString = NULL;
   2288        char *stateAscii = NULL;
   2289        PKIX_PL_String *certString = NULL;
   2290        char *certAscii = NULL;
   2291        PKIX_UInt32 length;
   2292 #endif
   2293 
   2294        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Check");
   2295        PKIX_NULLCHECK_FOUR(checker, cert, unresolvedCriticals, pNBIOContext);
   2296 
   2297        *pNBIOContext = NULL; /* we never block on pending I/O */
   2298 
   2299        PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
   2300                    (checker, (PKIX_PL_Object **)&state, plContext),
   2301                    PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
   2302 
   2303        PKIX_NULLCHECK_TWO(state, state->certPoliciesExtension);
   2304 
   2305 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2306        PKIX_CHECK(PKIX_PL_Object_ToString
   2307                ((PKIX_PL_Object*)state, &stateString, plContext),
   2308                PKIX_OBJECTTOSTRINGFAILED);
   2309        PKIX_CHECK(PKIX_PL_String_GetEncoded
   2310                    (stateString,
   2311                    PKIX_ESCASCII,
   2312                    (void **)&stateAscii,
   2313                    &length,
   2314                    plContext),
   2315                    PKIX_STRINGGETENCODEDFAILED);
   2316        PKIX_DEBUG_ARG("On entry %s\n", stateAscii);
   2317        PKIX_FREE(stateAscii);
   2318        PKIX_DECREF(stateString);
   2319 #endif
   2320 
   2321        /*
   2322         * Section 6.1.4(a)
   2323         * If this is not the last certificate, and if
   2324         * policyMapping extension is present, check that no
   2325         * issuerDomainPolicy or subjectDomainPolicy is equal to the
   2326         * special policy anyPolicy.
   2327         */
   2328        if (state->certsProcessed != (state->numCerts - 1)) {
   2329                PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
   2330                        (cert, &policyMaps, plContext),
   2331                        PKIX_CERTGETPOLICYMAPPINGSFAILED);
   2332        }
   2333 
   2334        if (policyMaps) {
   2335 
   2336                PKIX_CHECK(pkix_PolicyChecker_MapContains
   2337                        (policyMaps, state->anyPolicyOID, &result, plContext),
   2338                        PKIX_POLICYCHECKERMAPCONTAINSFAILED);
   2339 
   2340                if (result) {
   2341                        PKIX_ERROR(PKIX_INVALIDPOLICYMAPPINGINCLUDESANYPOLICY);
   2342                }
   2343 
   2344                PKIX_CHECK(pkix_PolicyChecker_MapGetMappedPolicies
   2345                        (policyMaps, &mappedPolicies, plContext),
   2346                        PKIX_POLICYCHECKERMAPGETMAPPEDPOLICIESFAILED);
   2347 
   2348                PKIX_DECREF(state->mappedPolicyOIDs);
   2349                PKIX_INCREF(mappedPolicies);
   2350                state->mappedPolicyOIDs = mappedPolicies;
   2351        }
   2352 
   2353        /* Section 6.1.3(d) */
   2354        if (state->validPolicyTree) {
   2355 
   2356            PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
   2357                (cert, &certPolicyInfos, plContext),
   2358                PKIX_CERTGETPOLICYINFORMATIONFAILED);
   2359 
   2360            if (certPolicyInfos) {
   2361                PKIX_CHECK(PKIX_List_GetLength
   2362                        (certPolicyInfos, &numPolicies, plContext),
   2363                        PKIX_LISTGETLENGTHFAILED);
   2364            }
   2365 
   2366            if (numPolicies > 0) {
   2367 
   2368                PKIX_CHECK(PKIX_PL_Cert_AreCertPoliciesCritical
   2369                        (cert, &(state->certPoliciesCritical), plContext),
   2370                        PKIX_CERTARECERTPOLICIESCRITICALFAILED);
   2371 
   2372                /* Section 6.1.3(d)(1) For each policy not equal to anyPolicy */
   2373                for (polX = 0; polX < numPolicies; polX++) {
   2374 
   2375                    PKIX_CHECK(PKIX_List_GetItem
   2376                        (certPolicyInfos,
   2377                        polX,
   2378                        (PKIX_PL_Object **)&policy,
   2379                        plContext),
   2380                        PKIX_LISTGETITEMFAILED);
   2381 
   2382                    PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
   2383                        (policy, &policyOID, plContext),
   2384                        PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
   2385 
   2386                    PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolQualifiers
   2387                        (policy, &policyQualifiers, plContext),
   2388                        PKIX_CERTPOLICYINFOGETPOLQUALIFIERSFAILED);
   2389 
   2390                    PKIX_EQUALS
   2391                        (state->anyPolicyOID,
   2392                        policyOID,
   2393                        &result,
   2394                        plContext,
   2395                        PKIX_OIDEQUALFAILED);
   2396 
   2397                    if (result == PKIX_FALSE) {
   2398 
   2399                        /* Section 6.1.3(d)(1)(i) */
   2400                        subroutineErr = pkix_PolicyChecker_CheckPolicy
   2401                                (policyOID,
   2402                                policyQualifiers,
   2403                                cert,
   2404                                policyMaps,
   2405                                state,
   2406                                plContext);
   2407                        if (subroutineErr) {
   2408                                goto subrErrorCleanup;
   2409                        }
   2410 
   2411                    } else {
   2412                        /*
   2413                         * No descent (yet) for anyPolicy, but we will need
   2414                         * the policyQualifiers for anyPolicy in 6.1.3(d)(2)
   2415                         */
   2416                        PKIX_DECREF(qualsOfAny);
   2417                        PKIX_INCREF(policyQualifiers);
   2418                        qualsOfAny = policyQualifiers;
   2419                        certPoliciesIncludeAny = PKIX_TRUE;
   2420                    }
   2421                    PKIX_DECREF(policy);
   2422                    PKIX_DECREF(policyOID);
   2423                    PKIX_DECREF(policyQualifiers);
   2424                }
   2425 
   2426                /* Section 6.1.3(d)(2) */
   2427                if (certPoliciesIncludeAny == PKIX_TRUE) {
   2428                        if (state->inhibitAnyPolicy > 0) {
   2429                                doAnyPolicyProcessing = PKIX_TRUE;
   2430                        } else {
   2431                            /* We haven't yet counted the current cert */
   2432                            if (((state->certsProcessed) + 1) <
   2433                                (state->numCerts)) {
   2434 
   2435                                PKIX_CHECK(pkix_IsCertSelfIssued
   2436                                        (cert,
   2437                                        &doAnyPolicyProcessing,
   2438                                        plContext),
   2439                                        PKIX_ISCERTSELFISSUEDFAILED);
   2440                            }
   2441                        }
   2442                        if (doAnyPolicyProcessing) {
   2443                            subroutineErr = pkix_PolicyChecker_CheckAny
   2444                                (state->validPolicyTree,
   2445                                qualsOfAny,
   2446                                policyMaps,
   2447                                state,
   2448                                plContext);
   2449                            if (subroutineErr) {
   2450                                goto subrErrorCleanup;
   2451                            }
   2452                        }
   2453                }
   2454 
   2455                /* Section 6.1.3(d)(3) */
   2456                if (state->validPolicyTree) {
   2457                        subroutineErr = pkix_PolicyNode_Prune
   2458                                (state->validPolicyTree,
   2459                                state->certsProcessed + 1,
   2460                                &shouldBePruned,
   2461                                plContext);
   2462                        if (subroutineErr) {
   2463                                goto subrErrorCleanup;
   2464                        }
   2465                        if (shouldBePruned) {
   2466                                PKIX_DECREF(state->validPolicyTree);
   2467                                PKIX_DECREF(state->anyPolicyNodeAtBottom);
   2468                        }
   2469                }
   2470 
   2471                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2472                        ((PKIX_PL_Object *)state, plContext),
   2473                        PKIX_OBJECTINVALIDATECACHEFAILED);
   2474 
   2475            } else {
   2476                /* Section 6.1.3(e) */
   2477                PKIX_DECREF(state->validPolicyTree);
   2478                PKIX_DECREF(state->anyPolicyNodeAtBottom);
   2479                PKIX_DECREF(state->newAnyPolicyNode);
   2480 
   2481                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2482                        ((PKIX_PL_Object *)state, plContext),
   2483                        PKIX_OBJECTINVALIDATECACHEFAILED);
   2484            }
   2485        }
   2486 
   2487        /* Section 6.1.3(f) */
   2488        if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) {
   2489                PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
   2490        }
   2491 
   2492        /*
   2493         * Remove Policy OIDs from list of unresolved critical
   2494         * extensions, if present.
   2495         */
   2496        PKIX_CHECK(pkix_List_Remove
   2497                (unresolvedCriticals,
   2498                (PKIX_PL_Object *)state->certPoliciesExtension,
   2499                plContext),
   2500                PKIX_LISTREMOVEFAILED);
   2501 
   2502        PKIX_CHECK(pkix_List_Remove
   2503                (unresolvedCriticals,
   2504                (PKIX_PL_Object *)state->policyMappingsExtension,
   2505                plContext),
   2506                PKIX_LISTREMOVEFAILED);
   2507 
   2508        PKIX_CHECK(pkix_List_Remove
   2509                (unresolvedCriticals,
   2510                (PKIX_PL_Object *)state->policyConstraintsExtension,
   2511                plContext),
   2512                PKIX_LISTREMOVEFAILED);
   2513 
   2514        PKIX_CHECK(pkix_List_Remove
   2515                (unresolvedCriticals,
   2516                (PKIX_PL_Object *)state->inhibitAnyPolicyExtension,
   2517                plContext),
   2518                PKIX_LISTREMOVEFAILED);
   2519 
   2520        state->certsProcessed++;
   2521 
   2522        /* If this was not the last certificate, do next-cert preparation */
   2523        if (state->certsProcessed != state->numCerts) {
   2524 
   2525                if (policyMaps) {
   2526                        subroutineErr = pkix_PolicyChecker_PolicyMapProcessing
   2527                                (policyMaps,
   2528                                certPoliciesIncludeAny,
   2529                                qualsOfAny,
   2530                                state,
   2531                                plContext);
   2532                        if (subroutineErr) {
   2533                                goto subrErrorCleanup;
   2534                        }
   2535                }
   2536 
   2537                /* update anyPolicyNodeAtBottom pointer */
   2538                PKIX_DECREF(state->anyPolicyNodeAtBottom);
   2539                state->anyPolicyNodeAtBottom = state->newAnyPolicyNode;
   2540                state->newAnyPolicyNode = NULL;
   2541 
   2542                /* Section 6.1.4(h) */
   2543                PKIX_CHECK(pkix_IsCertSelfIssued
   2544                        (cert, &isSelfIssued, plContext),
   2545                        PKIX_ISCERTSELFISSUEDFAILED);
   2546 
   2547                if (!isSelfIssued) {
   2548                        if (state->explicitPolicy > 0) {
   2549                            state->explicitPolicy--;
   2550                        }
   2551                        if (state->policyMapping > 0) {
   2552                            state->policyMapping--;
   2553                        }
   2554                        if (state->inhibitAnyPolicy > 0) {
   2555                            state->inhibitAnyPolicy--;
   2556                        }
   2557                }
   2558 
   2559                /* Section 6.1.4(i) */
   2560                PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
   2561                        (cert, &explicitPolicySkipCerts, plContext),
   2562                        PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
   2563 
   2564                if (explicitPolicySkipCerts != -1) {
   2565                        if (((PKIX_UInt32)explicitPolicySkipCerts) <
   2566                            (state->explicitPolicy)) {
   2567                                state->explicitPolicy =
   2568                                   ((PKIX_UInt32) explicitPolicySkipCerts);
   2569                        }
   2570                }
   2571 
   2572                PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
   2573                        (cert, &inhibitMappingSkipCerts, plContext),
   2574                        PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
   2575 
   2576                if (inhibitMappingSkipCerts != -1) {
   2577                        if (((PKIX_UInt32)inhibitMappingSkipCerts) <
   2578                            (state->policyMapping)) {
   2579                                state->policyMapping =
   2580                                    ((PKIX_UInt32)inhibitMappingSkipCerts);
   2581                        }
   2582                }
   2583 
   2584                PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
   2585                        (cert, &inhibitAnyPolicySkipCerts, plContext),
   2586                        PKIX_CERTGETINHIBITANYPOLICYFAILED);
   2587 
   2588                if (inhibitAnyPolicySkipCerts != -1) {
   2589                        if (((PKIX_UInt32)inhibitAnyPolicySkipCerts) <
   2590                            (state->inhibitAnyPolicy)) {
   2591                                state->inhibitAnyPolicy =
   2592                                    ((PKIX_UInt32)inhibitAnyPolicySkipCerts);
   2593                        }
   2594                }
   2595 
   2596                PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   2597                        ((PKIX_PL_Object *)state, plContext),
   2598                        PKIX_OBJECTINVALIDATECACHEFAILED);
   2599 
   2600        } else { /* If this was the last certificate, do wrap-up processing */
   2601 
   2602                /* Section 6.1.5 */
   2603                subroutineErr = pkix_PolicyChecker_WrapUpProcessing
   2604                        (cert, state, plContext);
   2605                if (subroutineErr) {
   2606                        goto subrErrorCleanup;
   2607                }
   2608 
   2609                if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) {
   2610                    PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
   2611                }
   2612 
   2613                PKIX_DECREF(state->anyPolicyNodeAtBottom);
   2614                PKIX_DECREF(state->newAnyPolicyNode);
   2615        }
   2616 
   2617 
   2618        if (subroutineErr) {
   2619 
   2620 subrErrorCleanup:
   2621                /* We had an error. Was it a fatal error? */
   2622                pkixErrorClass = subroutineErr->errClass;
   2623                if (pkixErrorClass == PKIX_FATAL_ERROR) {
   2624                    pkixErrorResult = subroutineErr;
   2625                    subroutineErr = NULL;
   2626                    goto cleanup;
   2627                }
   2628                /*
   2629                 * Abort policy processing, and then determine whether
   2630                 * we can continue without policy processing.
   2631                 */
   2632                PKIX_DECREF(state->validPolicyTree);
   2633                PKIX_DECREF(state->anyPolicyNodeAtBottom);
   2634                PKIX_DECREF(state->newAnyPolicyNode);
   2635                if (state->explicitPolicy == 0) {
   2636                    PKIX_ERROR
   2637                        (PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
   2638                }
   2639        }
   2640 
   2641        /* Checking is complete. Save state for the next certificate. */
   2642        PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
   2643                (checker, (PKIX_PL_Object *)state, plContext),
   2644                PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
   2645 
   2646 cleanup:
   2647 
   2648 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG
   2649        if (cert) {
   2650                PKIX_CHECK(PKIX_PL_Object_ToString
   2651                        ((PKIX_PL_Object*)cert, &certString, plContext),
   2652                        PKIX_OBJECTTOSTRINGFAILED);
   2653                PKIX_CHECK(PKIX_PL_String_GetEncoded
   2654                            (certString,
   2655                            PKIX_ESCASCII,
   2656                            (void **)&certAscii,
   2657                            &length,
   2658                            plContext),
   2659                            PKIX_STRINGGETENCODEDFAILED);
   2660                PKIX_DEBUG_ARG("Cert was %s\n", certAscii);
   2661                PKIX_FREE(certAscii);
   2662                PKIX_DECREF(certString);
   2663        }
   2664        if (state) {
   2665                PKIX_CHECK(PKIX_PL_Object_ToString
   2666                        ((PKIX_PL_Object*)state, &stateString, plContext),
   2667                        PKIX_OBJECTTOSTRINGFAILED);
   2668                PKIX_CHECK(PKIX_PL_String_GetEncoded
   2669                            (stateString,
   2670                            PKIX_ESCASCII,
   2671                            (void **)&stateAscii,
   2672                            &length,
   2673                            plContext),
   2674                            PKIX_STRINGGETENCODEDFAILED);
   2675                PKIX_DEBUG_ARG("On exit %s\n", stateAscii);
   2676                PKIX_FREE(stateAscii);
   2677                PKIX_DECREF(stateString);
   2678        }
   2679 #endif
   2680 
   2681        PKIX_DECREF(state);
   2682        PKIX_DECREF(certPolicyInfos);
   2683        PKIX_DECREF(policy);
   2684        PKIX_DECREF(qualsOfAny);
   2685        PKIX_DECREF(policyQualifiers);
   2686        PKIX_DECREF(policyOID);
   2687        PKIX_DECREF(subroutineErr);
   2688        PKIX_DECREF(policyMaps);
   2689        PKIX_DECREF(mappedPolicies);
   2690 
   2691        PKIX_RETURN(CERTCHAINCHECKER);
   2692 }
   2693 
   2694 /*
   2695 * FUNCTION: pkix_PolicyChecker_Initialize
   2696 * DESCRIPTION:
   2697 *
   2698 *  Creates and initializes a PolicyChecker, using the List pointed to
   2699 *  by "initialPolicies" for the user-initial-policy-set, the Boolean value
   2700 *  of "policyQualifiersRejected" for the policyQualifiersRejected parameter,
   2701 *  the Boolean value of "initialPolicyMappingInhibit" for the
   2702 *  inhibitPolicyMappings parameter, the Boolean value of
   2703 *  "initialExplicitPolicy" for the initialExplicitPolicy parameter, the
   2704 *  Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy
   2705 *  parameter, and the UInt32 value of "numCerts" as the number of
   2706 *  certificates in the chain; and stores the Checker at "pChecker".
   2707 *
   2708 * PARAMETERS:
   2709 *  "initialPolicies"
   2710 *      Address of List of OIDs comprising the user-initial-policy-set; the List
   2711 *      may be empty or NULL
   2712 *  "policyQualifiersRejected"
   2713 *      Boolean value of the policyQualifiersRejected parameter
   2714 *  "initialPolicyMappingInhibit"
   2715 *      Boolean value of the inhibitPolicyMappings parameter
   2716 *  "initialExplicitPolicy"
   2717 *      Boolean value of the initialExplicitPolicy parameter
   2718 *  "initialAnyPolicyInhibit"
   2719 *      Boolean value of the inhibitAnyPolicy parameter
   2720 *  "numCerts"
   2721 *      Number of certificates in the chain to be validated
   2722 *  "pChecker"
   2723 *      Address to store the created PolicyChecker. Must be non-NULL.
   2724 *  "plContext"
   2725 *      Platform-specific context pointer.
   2726 * THREAD SAFETY:
   2727 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   2728 * RETURNS:
   2729 *  Returns NULL if the function succeeds
   2730 *  Returns a CertChainChecker Error if the functions fails in a non-fatal way
   2731 *  Returns a Fatal Error if the function fails in an unrecoverable way
   2732 */
   2733 PKIX_Error *
   2734 pkix_PolicyChecker_Initialize(
   2735        PKIX_List *initialPolicies,
   2736        PKIX_Boolean policyQualifiersRejected,
   2737        PKIX_Boolean initialPolicyMappingInhibit,
   2738        PKIX_Boolean initialExplicitPolicy,
   2739        PKIX_Boolean initialAnyPolicyInhibit,
   2740        PKIX_UInt32 numCerts,
   2741        PKIX_CertChainChecker **pChecker,
   2742        void *plContext)
   2743 {
   2744        PKIX_PolicyCheckerState *polCheckerState = NULL;
   2745        PKIX_List *policyExtensions = NULL;     /* OIDs */
   2746        PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Initialize");
   2747        PKIX_NULLCHECK_ONE(pChecker);
   2748 
   2749        PKIX_CHECK(pkix_PolicyCheckerState_Create
   2750                (initialPolicies,
   2751                policyQualifiersRejected,
   2752                initialPolicyMappingInhibit,
   2753                initialExplicitPolicy,
   2754                initialAnyPolicyInhibit,
   2755                numCerts,
   2756                &polCheckerState,
   2757                plContext),
   2758                PKIX_POLICYCHECKERSTATECREATEFAILED);
   2759 
   2760        /* Create the list of extensions that we handle */
   2761        PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
   2762                ((PKIX_PL_Object *)(polCheckerState->certPoliciesExtension),
   2763                PKIX_TRUE,
   2764                &policyExtensions,
   2765                plContext),
   2766                PKIX_POLICYCHECKERMAKESINGLETONFAILED);
   2767 
   2768        PKIX_CHECK(PKIX_CertChainChecker_Create
   2769                (pkix_PolicyChecker_Check,
   2770                PKIX_FALSE,     /* forwardCheckingSupported */
   2771                PKIX_FALSE,
   2772                policyExtensions,
   2773                (PKIX_PL_Object *)polCheckerState,
   2774                pChecker,
   2775                plContext),
   2776                PKIX_CERTCHAINCHECKERCREATEFAILED);
   2777 
   2778 cleanup:
   2779        PKIX_DECREF(polCheckerState);
   2780        PKIX_DECREF(policyExtensions);
   2781        PKIX_RETURN(CERTCHAINCHECKER);
   2782 
   2783 }