tor-browser

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

pkix_certselector.c (56555B)


      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_certselector.c
      6 *
      7 * CertSelector Object Functions
      8 *
      9 */
     10 
     11 #include "pkix_certselector.h"
     12 
     13 /* --Private-Functions-------------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_CertSelector_Destroy
     17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     18 */
     19 static PKIX_Error *
     20 pkix_CertSelector_Destroy(
     21        PKIX_PL_Object *object,
     22        void *plContext)
     23 {
     24        PKIX_CertSelector *selector = NULL;
     25 
     26        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Destroy");
     27        PKIX_NULLCHECK_ONE(object);
     28 
     29        /* Check that this object is a cert selector */
     30        PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
     31                    PKIX_OBJECTNOTCERTSELECTOR);
     32 
     33        selector = (PKIX_CertSelector *)object;
     34        PKIX_DECREF(selector->params);
     35        PKIX_DECREF(selector->context);
     36 
     37 cleanup:
     38 
     39        PKIX_RETURN(CERTSELECTOR);
     40 }
     41 
     42 /*
     43 * FUNCTION: pkix_CertSelector_Duplicate
     44 * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
     45 */
     46 static PKIX_Error *
     47 pkix_CertSelector_Duplicate(
     48        PKIX_PL_Object *object,
     49        PKIX_PL_Object **pNewObject,
     50        void *plContext)
     51 {
     52        PKIX_CertSelector *certSelector = NULL;
     53        PKIX_CertSelector *certSelectorDuplicate = NULL;
     54 
     55        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Duplicate");
     56        PKIX_NULLCHECK_TWO(object, pNewObject);
     57 
     58        PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
     59                    PKIX_OBJECTNOTCERTSELECTOR);
     60 
     61        certSelector = (PKIX_CertSelector *)object;
     62 
     63        PKIX_CHECK(PKIX_CertSelector_Create
     64                    (certSelector->matchCallback,
     65                    certSelector->context,
     66                    &certSelectorDuplicate,
     67                    plContext),
     68                    PKIX_CERTSELECTORCREATEFAILED);
     69 
     70        PKIX_CHECK(PKIX_PL_Object_Duplicate
     71                    ((PKIX_PL_Object *)certSelector->params,
     72                    (PKIX_PL_Object **)&certSelectorDuplicate->params,
     73                    plContext),
     74                    PKIX_OBJECTDUPLICATEFAILED);
     75 
     76        *pNewObject = (PKIX_PL_Object *)certSelectorDuplicate;
     77 
     78 cleanup:
     79 
     80        if (PKIX_ERROR_RECEIVED){
     81                PKIX_DECREF(certSelectorDuplicate);
     82        }
     83 
     84        PKIX_RETURN(CERTSELECTOR);
     85 }
     86 
     87 /*
     88 * FUNCTION: pkix_CertSelector_Match_BasicConstraint
     89 * DESCRIPTION:
     90 *
     91 *  Determines whether the Cert pointed to by "cert" matches the basic
     92 *  constraints criterion using the basic constraints field of the
     93 *  ComCertSelParams pointed to by "params". If the basic constraints field is
     94 *  -1, no basic constraints check is done and the Cert is considered to match
     95 *  the basic constraints criterion. If the Cert does not match the basic
     96 *  constraints criterion, an Error pointer is returned.
     97 *
     98 *  In order to match against this criterion, there are several possibilities.
     99 *
    100 *  1) If the criterion's minimum path length is greater than or equal to zero,
    101 *  a certificate must include a BasicConstraints extension with a pathLen of
    102 *  at least this value.
    103 *
    104 *  2) If the criterion's minimum path length is -2, a certificate must be an
    105 *  end-entity certificate.
    106 *
    107 *  3) If the criterion's minimum path length is -1, no basic constraints check
    108 *  is done and all certificates are considered to match this criterion.
    109 *
    110 * PARAMETERS:
    111 *  "params"
    112 *      Address of ComCertSelParams whose basic constraints field is used.
    113 *      Must be non-NULL.
    114 *  "cert"
    115 *      Address of Cert that is to be matched. Must be non-NULL.
    116 *  "pResult"
    117 *      Address of PKIX_Boolean that returns the match result.
    118 *  "plContext"
    119 *      Platform-specific context pointer.
    120 * OUTPUT PARAMETERS ON FAILURE:
    121 *   If the function returns a failure,
    122 *   the output parameters of this function are undefined.
    123 * THREAD SAFETY:
    124 *  Conditionally Thread Safe
    125 *      (see Thread Safety Definitions in Programmer's Guide)
    126 * RETURNS:
    127 *  Returns NULL if the function succeeds.
    128 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    129 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    130 */
    131 static PKIX_Error *
    132 pkix_CertSelector_Match_BasicConstraint(
    133        PKIX_ComCertSelParams *params,
    134        PKIX_PL_Cert *cert,
    135        PKIX_Boolean *pResult,
    136        void *plContext)
    137 {
    138        PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
    139        PKIX_Boolean caFlag = PKIX_FALSE; /* EE Cert by default */
    140        PKIX_Int32 pathLength = 0;
    141        PKIX_Int32 minPathLength = 0;
    142 
    143        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_BasicConstraint");
    144        PKIX_NULLCHECK_THREE(params, cert, pResult);
    145        *pResult = PKIX_TRUE;
    146 
    147        PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
    148                (params, &minPathLength, plContext),
    149                PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
    150 
    151        /* If the minPathLength is unlimited (-1), no checking */
    152        if (minPathLength == PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH) {
    153                goto cleanup;
    154        }
    155 
    156        PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
    157                    (cert, &basicConstraints, plContext),
    158                    PKIX_CERTGETBASICCONSTRAINTSFAILED);
    159 
    160        if (basicConstraints != NULL) {
    161                PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
    162                            (basicConstraints, &caFlag, plContext),
    163                            PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
    164 
    165                PKIX_CHECK(PKIX_PL_BasicConstraints_GetPathLenConstraint
    166                        (basicConstraints, &pathLength, plContext),
    167                        PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
    168        }
    169 
    170        /*
    171         * if minPathLength >= 0, the cert must have a BasicConstraints ext and
    172         * the pathLength in this cert
    173         * BasicConstraints needs to be >= minPathLength.
    174         */
    175        if (minPathLength >= 0){
    176                if ((!basicConstraints) || (caFlag == PKIX_FALSE)){
    177                        PKIX_ERROR(PKIX_CERTNOTALLOWEDTOSIGNCERTIFICATES);
    178                } else if ((pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) &&
    179                            (pathLength < minPathLength)){
    180                        PKIX_CERTSELECTOR_DEBUG
    181                            ("Basic Constraints path length match failed\n");
    182                        *pResult = PKIX_FALSE;
    183                        PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
    184                }
    185        }
    186 
    187        /* if the minPathLength is -2, this cert must be an end-entity cert. */
    188        if (minPathLength == PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH) {
    189                if (caFlag == PKIX_TRUE) {
    190                    PKIX_CERTSELECTOR_DEBUG
    191                        ("Basic Constraints end-entity match failed\n");
    192                    *pResult = PKIX_FALSE;
    193                    PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
    194                }
    195        }
    196 
    197 cleanup:
    198 
    199        PKIX_DECREF(basicConstraints);
    200        PKIX_RETURN(CERTSELECTOR);
    201 }
    202 
    203 /*
    204 * FUNCTION: pkix_CertSelector_Match_Policies
    205 * DESCRIPTION:
    206 *
    207 *  Determines whether the Cert pointed to by "cert" matches the policy
    208 *  constraints specified in the ComCertsSelParams given by "params".
    209 *  If "params" specifies a policy constraint of NULL, all certificates
    210 *  match. If "params" specifies an empty list, "cert" must have at least
    211 *  some policy. Otherwise "cert" must include at least one of the
    212 *  policies in the list. See the description of PKIX_CertSelector in
    213 *  pkix_certsel.h for more.
    214 *
    215 * PARAMETERS:
    216 *  "params"
    217 *      Address of ComCertSelParams whose policy criterion (if any) is used.
    218 *      Must be non-NULL.
    219 *  "cert"
    220 *      Address of Cert that is to be matched. Must be non-NULL.
    221 *  "pResult"
    222 *      Address of PKIX_Boolean that returns the match result.
    223 *  "plContext"
    224 *      Platform-specific context pointer.
    225 * THREAD SAFETY:
    226 *  Conditionally Thread Safe
    227 *      (see Thread Safety Definitions in Programmer's Guide)
    228 * RETURNS:
    229 *  Returns NULL if the function succeeds.
    230 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    231 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    232 */
    233 static PKIX_Error *
    234 pkix_CertSelector_Match_Policies(
    235        PKIX_ComCertSelParams *params,
    236        PKIX_PL_Cert *cert,
    237        PKIX_Boolean *pResult,
    238        void *plContext)
    239 {
    240        PKIX_UInt32 numConstraintPolicies = 0;
    241        PKIX_UInt32 numCertPolicies = 0;
    242        PKIX_UInt32 certPolicyIndex = 0;
    243        PKIX_Boolean result = PKIX_FALSE;
    244        PKIX_List *constraintPolicies = NULL; /* List of PKIX_PL_OID */
    245        PKIX_List *certPolicyInfos = NULL; /* List of PKIX_PL_CertPolicyInfo */
    246        PKIX_PL_CertPolicyInfo *policyInfo = NULL;
    247        PKIX_PL_OID *polOID = NULL;
    248 
    249        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_Policies");
    250        PKIX_NULLCHECK_THREE(params, cert, pResult);
    251 
    252        PKIX_CHECK(PKIX_ComCertSelParams_GetPolicy
    253                (params, &constraintPolicies, plContext),
    254                PKIX_COMCERTSELPARAMSGETPOLICYFAILED);
    255 
    256        /* If constraintPolicies is NULL, all certificates "match" */
    257        if (constraintPolicies) {
    258            PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
    259                (cert, &certPolicyInfos, plContext),
    260                PKIX_CERTGETPOLICYINFORMATIONFAILED);
    261 
    262            /* No hope of a match if cert has no policies */
    263            if (!certPolicyInfos) {
    264                PKIX_CERTSELECTOR_DEBUG("Certificate has no policies\n");
    265                *pResult = PKIX_FALSE;
    266                PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
    267            }
    268 
    269            PKIX_CHECK(PKIX_List_GetLength
    270                (constraintPolicies, &numConstraintPolicies, plContext),
    271                PKIX_LISTGETLENGTHFAILED);
    272 
    273            if (numConstraintPolicies > 0) {
    274 
    275                PKIX_CHECK(PKIX_List_GetLength
    276                        (certPolicyInfos, &numCertPolicies, plContext),
    277                        PKIX_LISTGETLENGTHFAILED);
    278 
    279                for (certPolicyIndex = 0;
    280                        ((!result) && (certPolicyIndex < numCertPolicies));
    281                        certPolicyIndex++) {
    282 
    283                        PKIX_CHECK(PKIX_List_GetItem
    284                                (certPolicyInfos,
    285                                certPolicyIndex,
    286                                (PKIX_PL_Object **)&policyInfo,
    287                                plContext),
    288                                PKIX_LISTGETELEMENTFAILED);
    289                        PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
    290                                (policyInfo, &polOID, plContext),
    291                                PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
    292 
    293                        PKIX_CHECK(pkix_List_Contains
    294                                (constraintPolicies,
    295                                (PKIX_PL_Object *)polOID,
    296                                &result,
    297                                plContext),
    298                                PKIX_LISTCONTAINSFAILED);
    299                        PKIX_DECREF(policyInfo);
    300                        PKIX_DECREF(polOID);
    301                }
    302                if (!result) {
    303                    *pResult = PKIX_FALSE;
    304                    PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
    305                }
    306            }
    307        }
    308 
    309 cleanup:
    310 
    311        PKIX_DECREF(constraintPolicies);
    312        PKIX_DECREF(certPolicyInfos);
    313        PKIX_DECREF(policyInfo);
    314        PKIX_DECREF(polOID);
    315 
    316        PKIX_RETURN(CERTSELECTOR);
    317 
    318 }
    319 
    320 /*
    321 * FUNCTION: pkix_CertSelector_Match_CertificateValid
    322 * DESCRIPTION:
    323 *
    324 *  Determines whether the Cert pointed to by "cert" matches the certificate
    325 *  validity criterion using the CertificateValid field of the
    326 *  ComCertSelParams pointed to by "params". If the CertificateValid field is
    327 *  NULL, no validity check is done and the Cert is considered to match
    328 *  the CertificateValid criterion. If the CertificateValid field specifies a
    329 *  Date prior to the notBefore field in the Cert, or greater than the notAfter
    330 *  field in the Cert, an Error is returned.
    331 *
    332 * PARAMETERS:
    333 *  "params"
    334 *      Address of ComCertSelParams whose certValid field is used.
    335 *      Must be non-NULL.
    336 *  "cert"
    337 *      Address of Cert that is to be matched. Must be non-NULL.
    338 *  "pResult"
    339 *      Address of PKIX_Boolean that returns the match result.
    340 *  "plContext"
    341 *      Platform-specific context pointer.
    342 * THREAD SAFETY:
    343 *  Conditionally Thread Safe
    344 *      (see Thread Safety Definitions in Programmer's Guide)
    345 * RETURNS:
    346 *  Returns NULL if the function succeeds.
    347 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    348 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    349 */
    350 static PKIX_Error *
    351 pkix_CertSelector_Match_CertificateValid(
    352        PKIX_ComCertSelParams *params,
    353        PKIX_PL_Cert *cert,
    354        PKIX_Boolean *pResult,
    355        void *plContext)
    356 {
    357        PKIX_PL_Date *validityTime = NULL;
    358 
    359        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_CertificateValid");
    360        PKIX_NULLCHECK_THREE(params, cert, pResult);
    361 
    362        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
    363                (params, &validityTime, plContext),
    364                PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
    365 
    366        /* If the validityTime is not set, all certificates are acceptable */
    367        if (validityTime) {
    368                PKIX_CHECK(PKIX_PL_Cert_CheckValidity
    369                        (cert, validityTime, plContext),
    370                        PKIX_CERTCHECKVALIDITYFAILED);
    371        }
    372 
    373 cleanup:
    374        if (PKIX_ERROR_RECEIVED) {
    375            *pResult = PKIX_FALSE;
    376        }
    377        PKIX_DECREF(validityTime);
    378 
    379        PKIX_RETURN(CERTSELECTOR);
    380 }
    381 
    382 /*
    383 * FUNCTION: pkix_CertSelector_Match_NameConstraints
    384 * DESCRIPTION:
    385 *
    386 *  Determines whether the Cert pointed to by "cert" matches the name
    387 *  constraints criterion specified in the ComCertSelParams pointed to by
    388 *  "params". If the name constraints field is NULL, no name constraints check
    389 *  is done and the Cert is considered to match the name constraints criterion.
    390 *  If the Cert does not match the name constraints criterion, an Error pointer
    391 *  is returned.
    392 *
    393 * PARAMETERS:
    394 *  "params"
    395 *      Address of ComCertSelParams whose name constraints field is used.
    396 *      Must be non-NULL.
    397 *  "cert"
    398 *      Address of Cert that is to be matched. Must be non-NULL.
    399 *  "pResult"
    400 *      Address of PKIX_Boolean that returns the match result.
    401 *  "plContext"
    402 *      Platform-specific context pointer.
    403 * THREAD SAFETY:
    404 *  Conditionally Thread Safe
    405 *      (see Thread Safety Definitions in Programmer's Guide)
    406 * RETURNS:
    407 *  Returns NULL if the function succeeds.
    408 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    409 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    410 */
    411 static PKIX_Error *
    412 pkix_CertSelector_Match_NameConstraints(
    413        PKIX_ComCertSelParams *params,
    414        PKIX_PL_Cert *cert,
    415        PKIX_Boolean *pResult,
    416        void *plContext)
    417 {
    418        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    419 
    420        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_NameConstraints");
    421        PKIX_NULLCHECK_THREE(params, cert, pResult);
    422 
    423        PKIX_CHECK(PKIX_ComCertSelParams_GetNameConstraints
    424                (params, &nameConstraints, plContext),
    425                PKIX_COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED);
    426 
    427        if (nameConstraints != NULL) {
    428                /* As only the end-entity certificate should have
    429                 * the common name constrained as if it was a dNSName,
    430                 * do not constrain the common name when building a
    431                 * forward path.
    432                 */
    433                PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
    434                    (cert, nameConstraints, PKIX_FALSE, plContext),
    435                    PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
    436        }
    437 
    438 cleanup:
    439        if (PKIX_ERROR_RECEIVED) {
    440            *pResult = PKIX_FALSE;
    441        }
    442 
    443        PKIX_DECREF(nameConstraints);
    444        PKIX_RETURN(CERTSELECTOR);
    445 }
    446 
    447 /*
    448 * FUNCTION: pkix_CertSelector_Match_PathToNames
    449 * DESCRIPTION:
    450 *
    451 *  Determines whether the names at pathToNames in "params" complies with the
    452 *  NameConstraints pointed to by "cert". If the pathToNames field is NULL
    453 *  or there is no name constraints for this "cert", no checking is done
    454 *  and the Cert is considered to match the name constraints criterion.
    455 *  If the Cert does not match the name constraints criterion, an Error
    456 *  pointer is returned.
    457 *
    458 * PARAMETERS:
    459 *  "params"
    460 *      Address of ComCertSelParams whose PathToNames field is used.
    461 *      Must be non-NULL.
    462 *  "cert"
    463 *      Address of Cert that is to be matched. Must be non-NULL.
    464 *  "pResult"
    465 *      Address of PKIX_Boolean that returns the match result.
    466 *  "plContext"
    467 *      Platform-specific context pointer.
    468 * THREAD SAFETY:
    469 *  Conditionally Thread Safe
    470 *      (see Thread Safety Definitions in Programmer's Guide)
    471 * RETURNS:
    472 *  Returns NULL if the function succeeds.
    473 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    474 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    475 */
    476 static PKIX_Error *
    477 pkix_CertSelector_Match_PathToNames(
    478        PKIX_ComCertSelParams *params,
    479        PKIX_PL_Cert *cert,
    480        PKIX_Boolean *pResult,
    481        void *plContext)
    482 {
    483        PKIX_List *pathToNamesList = NULL;
    484        PKIX_Boolean passed = PKIX_FALSE;
    485        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
    486 
    487        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_PathToNames");
    488        PKIX_NULLCHECK_THREE(params, cert, pResult);
    489 
    490        PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
    491                (params, &pathToNamesList, plContext),
    492                PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
    493 
    494        if (pathToNamesList != NULL) {
    495 
    496            PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
    497                    (cert, &nameConstraints, plContext),
    498                    PKIX_CERTGETNAMECONSTRAINTSFAILED);
    499 
    500            if (nameConstraints != NULL) {
    501 
    502                PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
    503                        (pathToNamesList, nameConstraints, &passed, plContext),
    504                        PKIX_CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED);
    505 
    506                if (passed != PKIX_TRUE) {
    507                    *pResult = PKIX_FALSE;
    508                    PKIX_ERROR(PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
    509                }
    510            }
    511 
    512        }
    513 
    514 cleanup:
    515 
    516        PKIX_DECREF(nameConstraints);
    517        PKIX_DECREF(pathToNamesList);
    518 
    519        PKIX_RETURN(CERTSELECTOR);
    520 }
    521 
    522 /*
    523 * FUNCTION: pkix_CertSelector_Match_SubjAltNames
    524 * DESCRIPTION:
    525 *
    526 *  Determines whether the names at subjAltNames in "params" match with the
    527 *  SubjAltNames pointed to by "cert". If the subjAltNames field is NULL,
    528 *  no name checking is done and the Cert is considered to match the
    529 *  criterion. If the Cert does not match the criterion, an Error pointer
    530 *  is returned.
    531 *
    532 * PARAMETERS:
    533 *  "params"
    534 *      Address of ComCertSelParams whose SubjAltNames field is used.
    535 *      Must be non-NULL.
    536 *  "cert"
    537 *      Address of Cert that is to be matched. Must be non-NULL.
    538 *  "pResult"
    539 *      Address of PKIX_Boolean that returns the match result.
    540 *  "plContext"
    541 *      Platform-specific context pointer.
    542 * THREAD SAFETY:
    543 *  Conditionally Thread Safe
    544 *      (see Thread Safety Definitions in Programmer's Guide)
    545 * RETURNS:
    546 *  Returns NULL if the function succeeds.
    547 *  Returns a CertSelector 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 static PKIX_Error *
    551 pkix_CertSelector_Match_SubjAltNames(
    552        PKIX_ComCertSelParams *params,
    553        PKIX_PL_Cert *cert,
    554        PKIX_Boolean *pResult,
    555        void *plContext)
    556 {
    557        PKIX_List *subjAltNamesList = NULL;
    558        PKIX_List *certSubjAltNames = NULL;
    559        PKIX_PL_GeneralName *name = NULL;
    560        PKIX_Boolean checkPassed = PKIX_FALSE;
    561        PKIX_Boolean matchAll = PKIX_TRUE;
    562        PKIX_UInt32 i, numItems;
    563        PKIX_UInt32 matchCount = 0;
    564 
    565        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjAltNames");
    566        PKIX_NULLCHECK_THREE(params, cert, pResult);
    567 
    568        PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
    569                    (params, &matchAll, plContext),
    570                    PKIX_COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED);
    571 
    572        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
    573                    (params, &subjAltNamesList, plContext),
    574                    PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
    575 
    576        if (subjAltNamesList != NULL) {
    577 
    578            PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
    579                    (cert, &certSubjAltNames, plContext),
    580                    PKIX_CERTGETSUBJALTNAMESFAILED);
    581 
    582            if (certSubjAltNames == NULL) {
    583                *pResult = PKIX_FALSE;
    584                PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
    585            }
    586 
    587            PKIX_CHECK(PKIX_List_GetLength
    588                       (subjAltNamesList, &numItems, plContext),
    589                       PKIX_LISTGETLENGTHFAILED);
    590            
    591            for (i = 0; i < numItems; i++) {
    592                
    593                PKIX_CHECK(PKIX_List_GetItem
    594                           (subjAltNamesList,
    595                            i,
    596                            (PKIX_PL_Object **) &name,
    597                            plContext),
    598                           PKIX_LISTGETITEMFAILED);
    599                
    600                PKIX_CHECK(pkix_List_Contains
    601                           (certSubjAltNames,
    602                            (PKIX_PL_Object *) name,
    603                            &checkPassed,
    604                            plContext),
    605                           PKIX_LISTCONTAINSFAILED);
    606                
    607                PKIX_DECREF(name);
    608                
    609                if (checkPassed == PKIX_TRUE) {
    610                    
    611                    if (matchAll == PKIX_FALSE) {
    612                        /* one match is good enough */
    613                        matchCount = numItems;
    614                        break;
    615                    } else {
    616                        /* else continue checking next */
    617                        matchCount++;
    618                    }
    619                    
    620                }
    621                
    622            }
    623            
    624            if (matchCount != numItems) {
    625                *pResult = PKIX_FALSE;
    626                PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
    627            }
    628        }
    629 
    630 cleanup:
    631 
    632        PKIX_DECREF(name);
    633        PKIX_DECREF(certSubjAltNames);
    634        PKIX_DECREF(subjAltNamesList);
    635 
    636        PKIX_RETURN(CERTSELECTOR);
    637 }
    638 
    639 /*
    640 * FUNCTION: pkix_CertSelector_Match_ExtendedKeyUsage
    641 * DESCRIPTION:
    642 *
    643 *  Determines whether the names at ExtKeyUsage in "params" matches with the
    644 *  ExtKeyUsage pointed to by "cert". If the ExtKeyUsage criterion or
    645 *  ExtKeyUsage in "cert" is NULL, no checking is done and the Cert is
    646 *  considered a match. If the Cert does not match, an Error pointer is
    647 *  returned.
    648 *
    649 * PARAMETERS:
    650 *  "params"
    651 *      Address of ComCertSelParams whose ExtKeyUsage field is used.
    652 *      Must be non-NULL.
    653 *  "cert"
    654 *      Address of Cert that is to be matched. Must be non-NULL.
    655 *  "pResult"
    656 *      Address of PKIX_Boolean that returns the match result.
    657 *  "plContext"
    658 *      Platform-specific context pointer.
    659 * THREAD SAFETY:
    660 *  Conditionally Thread Safe
    661 *      (see Thread Safety Definitions in Programmer's Guide)
    662 * RETURNS:
    663 *  Returns NULL if the function succeeds.
    664 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    665 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    666 */
    667 static PKIX_Error *
    668 pkix_CertSelector_Match_ExtendedKeyUsage(
    669        PKIX_ComCertSelParams *params,
    670        PKIX_PL_Cert *cert,
    671        PKIX_Boolean *pResult,
    672        void *plContext)
    673 {
    674        PKIX_List *extKeyUsageList = NULL;
    675        PKIX_List *certExtKeyUsageList = NULL;
    676        PKIX_PL_OID *ekuOid = NULL;
    677        PKIX_Boolean isContained = PKIX_FALSE;
    678        PKIX_UInt32 numItems = 0;
    679        PKIX_UInt32 i;
    680 
    681        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_ExtendedKeyUsage");
    682        PKIX_NULLCHECK_THREE(params, cert, pResult);
    683 
    684        PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
    685                    (params, &extKeyUsageList, plContext),
    686                    PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
    687 
    688        if (extKeyUsageList == NULL) {
    689                goto cleanup;
    690        }
    691 
    692        PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
    693                    (cert, &certExtKeyUsageList, plContext),
    694                    PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
    695 
    696        if (certExtKeyUsageList != NULL) {
    697 
    698            PKIX_CHECK(PKIX_List_GetLength
    699                    (extKeyUsageList, &numItems, plContext),
    700                    PKIX_LISTGETLENGTHFAILED);
    701 
    702            for (i = 0; i < numItems; i++) {
    703 
    704                PKIX_CHECK(PKIX_List_GetItem
    705                    (extKeyUsageList, i, (PKIX_PL_Object **)&ekuOid, plContext),
    706                    PKIX_LISTGETITEMFAILED);
    707 
    708                PKIX_CHECK(pkix_List_Contains
    709                    (certExtKeyUsageList,
    710                    (PKIX_PL_Object *)ekuOid,
    711                    &isContained,
    712                    plContext),
    713                    PKIX_LISTCONTAINSFAILED);
    714 
    715                PKIX_DECREF(ekuOid);
    716 
    717                if (isContained != PKIX_TRUE) {
    718                    *pResult = PKIX_FALSE;
    719                    PKIX_ERROR(PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
    720                }
    721            }
    722        }
    723 
    724 cleanup:
    725 
    726        PKIX_DECREF(ekuOid);
    727        PKIX_DECREF(extKeyUsageList);
    728        PKIX_DECREF(certExtKeyUsageList);
    729 
    730        PKIX_RETURN(CERTSELECTOR);
    731 }
    732 
    733 /*
    734 * FUNCTION: pkix_CertSelector_Match_KeyUsage
    735 * DESCRIPTION:
    736 *
    737 *  Determines whether the bits at KeyUsage in "params" matches with the
    738 *  KeyUsage pointed to by "cert". If the KeyUsage in params is 0
    739 *  no checking is done and the Cert is considered a match. If the Cert does
    740 *  not match, an Error pointer is returned.
    741 *
    742 * PARAMETERS:
    743 *  "params"
    744 *      Address of ComCertSelParams whose ExtKeyUsage field is used.
    745 *      Must be non-NULL.
    746 *  "cert"
    747 *      Address of Cert that is to be matched. Must be non-NULL.
    748 *  "pResult"
    749 *      Address of PKIX_Boolean that returns the match result.
    750 *  "plContext"
    751 *      Platform-specific context pointer.
    752 * THREAD SAFETY:
    753 *  Conditionally Thread Safe
    754 *      (see Thread Safety Definitions in Programmer's Guide)
    755 * RETURNS:
    756 *  Returns NULL if the function succeeds.
    757 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    758 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    759 */
    760 static PKIX_Error *
    761 pkix_CertSelector_Match_KeyUsage(
    762        PKIX_ComCertSelParams *params,
    763        PKIX_PL_Cert *cert,
    764        PKIX_Boolean *pResult,
    765        void *plContext)
    766 {
    767        PKIX_UInt32 keyUsage = 0;
    768 
    769        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_KeyUsage");
    770        PKIX_NULLCHECK_THREE(params, cert, pResult);
    771 
    772        PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
    773                    (params, &keyUsage, plContext),
    774                    PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED);
    775 
    776        if (keyUsage != 0) {
    777 
    778            PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage
    779                        (cert, keyUsage, plContext),
    780                        PKIX_CERTVERIFYKEYUSAGEFAILED);
    781 
    782        }
    783 
    784 cleanup:
    785        if (PKIX_ERROR_RECEIVED) {
    786            *pResult = PKIX_FALSE;
    787        }
    788 
    789        PKIX_RETURN(CERTSELECTOR);
    790 }
    791 
    792 /*
    793 * FUNCTION: pkix_CertSelector_Match_SubjKeyId
    794 * DESCRIPTION:
    795 *
    796 *  Determines whether the bytes at subjKeyId in "params" matches with the
    797 *  Subject Key Identifier pointed to by "cert". If the subjKeyId in params is
    798 *  set to NULL or the Cert doesn't have a Subject Key Identifier, no checking
    799 *  is done and the Cert is considered a match. If the Cert does not match, an
    800 *  Error pointer is returned.
    801 *
    802 * PARAMETERS:
    803 *  "params"
    804 *      Address of ComCertSelParams whose subjKeyId field is used.
    805 *      Must be non-NULL.
    806 *  "cert"
    807 *      Address of Cert that is to be matched. Must be non-NULL.
    808 *  "pResult"
    809 *      Address of PKIX_Boolean that returns the match result.
    810 *  "plContext"
    811 *      Platform-specific context pointer.
    812 * THREAD SAFETY:
    813 *  Conditionally Thread Safe
    814 *      (see Thread Safety Definitions in Programmer's Guide)
    815 * RETURNS:
    816 *  Returns NULL if the function succeeds.
    817 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    818 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    819 */
    820 static PKIX_Error *
    821 pkix_CertSelector_Match_SubjKeyId(
    822        PKIX_ComCertSelParams *params,
    823        PKIX_PL_Cert *cert,
    824        PKIX_Boolean *pResult,
    825        void *plContext)
    826 {
    827        PKIX_PL_ByteArray *selSubjKeyId = NULL;
    828        PKIX_PL_ByteArray *certSubjKeyId = NULL;
    829        PKIX_Boolean equals = PKIX_FALSE;
    830 
    831        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjKeyId");
    832        PKIX_NULLCHECK_THREE(params, cert, pResult);
    833 
    834        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjKeyIdentifier
    835                    (params, &selSubjKeyId, plContext),
    836                    PKIX_COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED);
    837 
    838        if (selSubjKeyId != NULL) {
    839 
    840                PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
    841                    (cert, &certSubjKeyId, plContext),
    842                    PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
    843 
    844                if (certSubjKeyId == NULL) {
    845                    goto cleanup;
    846                }
    847 
    848                PKIX_CHECK(PKIX_PL_Object_Equals
    849                           ((PKIX_PL_Object *)selSubjKeyId,
    850                            (PKIX_PL_Object *)certSubjKeyId,
    851                            &equals,
    852                            plContext),
    853                           PKIX_OBJECTEQUALSFAILED);
    854                
    855                if (equals == PKIX_FALSE) {
    856                    *pResult = PKIX_FALSE;
    857                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
    858                }
    859        }
    860 
    861 cleanup:
    862 
    863        PKIX_DECREF(selSubjKeyId);
    864        PKIX_DECREF(certSubjKeyId);
    865 
    866        PKIX_RETURN(CERTSELECTOR);
    867 }
    868 
    869 /*
    870 * FUNCTION: pkix_CertSelector_Match_AuthKeyId
    871 * DESCRIPTION:
    872 *
    873 *  Determines whether the bytes at authKeyId in "params" matches with the
    874 *  Authority Key Identifier pointed to by "cert". If the authKeyId in params
    875 *  is set to NULL, no checking is done and the Cert is considered a match. If
    876 *  the Cert does not match, an Error pointer is returned.
    877 *
    878 * PARAMETERS:
    879 *  "params"
    880 *      Address of ComCertSelParams whose authKeyId field is used.
    881 *      Must be non-NULL.
    882 *  "cert"
    883 *      Address of Cert that is to be matched. Must be non-NULL.
    884 *  "pResult"
    885 *      Address of PKIX_Boolean that returns the match result.
    886 *  "plContext"
    887 *      Platform-specific context pointer.
    888 * THREAD SAFETY:
    889 *  Conditionally Thread Safe
    890 *      (see Thread Safety Definitions in Programmer's Guide)
    891 * RETURNS:
    892 *  Returns NULL if the function succeeds.
    893 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    894 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    895 */
    896 static PKIX_Error *
    897 pkix_CertSelector_Match_AuthKeyId(
    898        PKIX_ComCertSelParams *params,
    899        PKIX_PL_Cert *cert,
    900        PKIX_Boolean *pResult,
    901        void *plContext)
    902 {
    903        PKIX_PL_ByteArray *selAuthKeyId = NULL;
    904        PKIX_PL_ByteArray *certAuthKeyId = NULL;
    905        PKIX_Boolean equals = PKIX_FALSE;
    906 
    907        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_AuthKeyId");
    908        PKIX_NULLCHECK_THREE(params, cert, pResult);
    909 
    910        PKIX_CHECK(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
    911                    (params, &selAuthKeyId, plContext),
    912                    PKIX_COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED);
    913 
    914        if (selAuthKeyId != NULL) {
    915 
    916                PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
    917                    (cert, &certAuthKeyId, plContext),
    918                    PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
    919 
    920                if (certAuthKeyId == NULL) {
    921                    *pResult = PKIX_FALSE;
    922                    PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
    923                }
    924                PKIX_CHECK(PKIX_PL_Object_Equals
    925                           ((PKIX_PL_Object *)selAuthKeyId,
    926                            (PKIX_PL_Object *)certAuthKeyId,
    927                            &equals,
    928                            plContext),
    929                           PKIX_OBJECTEQUALSFAILED);
    930                
    931                if (equals != PKIX_TRUE) {
    932                    *pResult = PKIX_FALSE;
    933                    PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
    934                }
    935        }
    936 
    937 cleanup:
    938 
    939        PKIX_DECREF(selAuthKeyId);
    940        PKIX_DECREF(certAuthKeyId);
    941 
    942        PKIX_RETURN(CERTSELECTOR);
    943 }
    944 
    945 /*
    946 * FUNCTION: pkix_CertSelector_Match_SubjPKAlgId
    947 * DESCRIPTION:
    948 *
    949 *  Determines whether the OID at subjPKAlgId in "params" matches with the
    950 *  Subject Public Key Alg Id pointed to by "cert". If the subjPKAlgId in params
    951 *  is set to NULL, no checking is done and the Cert is considered a match. If
    952 *  the Cert does not match, an Error pointer is returned.
    953 *
    954 * PARAMETERS:
    955 *  "params"
    956 *      Address of ComCertSelParams whose subjPKAlgId field is used.
    957 *      Must be non-NULL.
    958 *  "cert"
    959 *      Address of Cert that is to be matched. Must be non-NULL.
    960 *  "pResult"
    961 *      Address of PKIX_Boolean that returns the match result.
    962 *  "plContext"
    963 *      Platform-specific context pointer.
    964 * THREAD SAFETY:
    965 *  Conditionally Thread Safe
    966 *      (see Thread Safety Definitions in Programmer's Guide)
    967 * RETURNS:
    968 *  Returns NULL if the function succeeds.
    969 *  Returns a CertSelector Error if the function fails in a non-fatal way.
    970 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    971 */
    972 static PKIX_Error *
    973 pkix_CertSelector_Match_SubjPKAlgId(
    974        PKIX_ComCertSelParams *params,
    975        PKIX_PL_Cert *cert,
    976        PKIX_Boolean *pResult,
    977        void *plContext)
    978 {
    979        PKIX_PL_OID *selPKAlgId = NULL;
    980        PKIX_PL_OID *certPKAlgId = NULL;
    981        PKIX_Boolean equals = PKIX_FALSE;
    982 
    983        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPKAlgId");
    984        PKIX_NULLCHECK_THREE(params, cert, pResult);
    985 
    986        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPKAlgId
    987                    (params, &selPKAlgId, plContext),
    988                    PKIX_COMCERTSELPARAMSGETSUBJPKALGIDFAILED);
    989 
    990        if (selPKAlgId != NULL) {
    991 
    992                PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKeyAlgId
    993                    (cert, &certPKAlgId, plContext),
    994                    PKIX_CERTGETSUBJECTPUBLICKEYALGIDFAILED);
    995 
    996                if (certPKAlgId != NULL) {
    997                    *pResult = PKIX_FALSE;
    998                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
    999                }
   1000                PKIX_CHECK(PKIX_PL_Object_Equals
   1001                           ((PKIX_PL_Object *)selPKAlgId,
   1002                            (PKIX_PL_Object *)certPKAlgId,
   1003                            &equals,
   1004                            plContext),
   1005                           PKIX_OBJECTEQUALSFAILED);
   1006                
   1007                if (equals != PKIX_TRUE) {
   1008                    *pResult = PKIX_FALSE;
   1009                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
   1010                }
   1011        }
   1012 
   1013 cleanup:
   1014 
   1015        PKIX_DECREF(selPKAlgId);
   1016        PKIX_DECREF(certPKAlgId);
   1017 
   1018        PKIX_RETURN(CERTSELECTOR);
   1019 }
   1020 
   1021 /*
   1022 * FUNCTION: pkix_CertSelector_Match_SubjPubKey
   1023 * DESCRIPTION:
   1024 *
   1025 *  Determines whether the key at subjPubKey in "params" matches with the
   1026 *  Subject Public Key pointed to by "cert". If the subjPubKey in params
   1027 *  is set to NULL, no checking is done and the Cert is considered a match. If
   1028 *  the Cert does not match, an Error pointer is returned.
   1029 *
   1030 * PARAMETERS:
   1031 *  "params"
   1032 *      Address of ComCertSelParams whose subPubKey field is used.
   1033 *      Must be non-NULL.
   1034 *  "cert"
   1035 *      Address of Cert that is to be matched. Must be non-NULL.
   1036 *  "pResult"
   1037 *      Address of PKIX_Boolean that returns the match result.
   1038 *  "plContext"
   1039 *      Platform-specific context pointer.
   1040 * THREAD SAFETY:
   1041 *  Conditionally Thread Safe
   1042 *      (see Thread Safety Definitions in Programmer's Guide)
   1043 * RETURNS:
   1044 *  Returns NULL if the function succeeds.
   1045 *  Returns a CertSelector Error if the function fails in a non-fatal way.
   1046 *  Returns a Fatal Error if the function fails in an unrecoverable way.
   1047 */
   1048 static PKIX_Error *
   1049 pkix_CertSelector_Match_SubjPubKey(
   1050        PKIX_ComCertSelParams *params,
   1051        PKIX_PL_Cert *cert,
   1052        PKIX_Boolean *pResult,
   1053        void *plContext)
   1054 {
   1055        PKIX_PL_PublicKey *selPK = NULL;
   1056        PKIX_PL_PublicKey *certPK = NULL;
   1057        PKIX_Boolean equals = PKIX_FALSE;
   1058 
   1059        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPubKey");
   1060        PKIX_NULLCHECK_THREE(params, cert, pResult);
   1061 
   1062        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPubKey
   1063                    (params, &selPK, plContext),
   1064                    PKIX_COMCERTSELPARAMSGETSUBJPUBKEYFAILED);
   1065 
   1066        if (selPK != NULL) {
   1067 
   1068                PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
   1069                    (cert, &certPK, plContext),
   1070                    PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
   1071 
   1072                if (certPK == NULL) {
   1073                    *pResult = PKIX_FALSE;
   1074                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
   1075                }
   1076                PKIX_CHECK(PKIX_PL_Object_Equals
   1077                           ((PKIX_PL_Object *)selPK,
   1078                            (PKIX_PL_Object *)certPK,
   1079                            &equals,
   1080                            plContext),
   1081                           PKIX_OBJECTEQUALSFAILED);
   1082                
   1083                if (equals != PKIX_TRUE) {
   1084                    *pResult = PKIX_FALSE;
   1085                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
   1086                }
   1087        }
   1088 
   1089 cleanup:
   1090 
   1091        PKIX_DECREF(selPK);
   1092        PKIX_DECREF(certPK);
   1093 
   1094        PKIX_RETURN(CERTSELECTOR);
   1095 }
   1096 
   1097 /*
   1098 * FUNCTION: pkix_CertSelector_DefaultMatch
   1099 * DESCRIPTION:
   1100 *
   1101 *  This default match function determines whether the specified Cert pointed
   1102 *  to by "cert" matches the criteria of the CertSelector pointed to by
   1103 *  "selector". If the Cert does not match the CertSelector's
   1104 *  criteria, an error will be thrown.
   1105 *
   1106 *  This default match function understands how to process the most common
   1107 *  parameters. Any common parameter that is not set is assumed to be disabled,
   1108 *  which means this function will select all certificates without regard to
   1109 *  that particular disabled parameter. For example, if the SerialNumber
   1110 *  parameter is not set, this function will not filter out any certificate
   1111 *  based on its serial number. As such, if no parameters are set, all are
   1112 *  disabled and any certificate will match. If a parameter is disabled, its
   1113 *  associated PKIX_ComCertSelParams_Get* function returns a default value.
   1114 *  That value is -1 for PKIX_ComCertSelParams_GetBasicConstraints and
   1115 *  PKIX_ComCertSelParams_GetVersion, 0 for PKIX_ComCertSelParams_GetKeyUsage,
   1116 *  and NULL for all other Get functions.
   1117 *
   1118 * PARAMETERS:
   1119 *  "selector"
   1120 *      Address of CertSelector whose MatchCallback logic and parameters are
   1121 *      to be used. Must be non-NULL.
   1122 *  "cert"
   1123 *      Address of Cert that is to be matched using "selector".
   1124 *      Must be non-NULL.
   1125 *  "plContext"
   1126 *      Platform-specific context pointer.
   1127 * THREAD SAFETY:
   1128 *  Conditionally Thread Safe
   1129 *      (see Thread Safety Definitions in Programmer's Guide)
   1130 * RETURNS:
   1131 *  Returns NULL if the function succeeds.
   1132 *  Returns a CertSelector Error if the function fails in a non-fatal way.
   1133 *  Returns a Fatal Error if the function fails in an unrecoverable way.
   1134 */
   1135 static PKIX_Error *
   1136 pkix_CertSelector_DefaultMatch(
   1137        PKIX_CertSelector *selector,
   1138        PKIX_PL_Cert *cert,
   1139        void *plContext)
   1140 {
   1141        PKIX_ComCertSelParams *params = NULL;
   1142        PKIX_PL_X500Name *certSubject = NULL;
   1143        PKIX_PL_X500Name *selSubject = NULL;
   1144        PKIX_PL_X500Name *certIssuer = NULL;
   1145        PKIX_PL_X500Name *selIssuer = NULL;
   1146        PKIX_PL_BigInt *certSerialNumber = NULL;
   1147        PKIX_PL_BigInt *selSerialNumber = NULL;
   1148        PKIX_PL_Cert *selCert = NULL;
   1149        PKIX_PL_Date *selDate = NULL;
   1150        PKIX_UInt32 selVersion = 0xFFFFFFFF;
   1151        PKIX_UInt32 certVersion = 0;
   1152        PKIX_Boolean result = PKIX_TRUE;
   1153        PKIX_Boolean isLeafCert = PKIX_TRUE;
   1154 
   1155 #ifdef PKIX_BUILDDEBUG
   1156        PKIX_PL_String *certString = NULL;
   1157        void *certAscii = NULL;
   1158        PKIX_UInt32 certAsciiLen;
   1159 #endif
   1160 
   1161        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_DefaultMatch");
   1162        PKIX_NULLCHECK_TWO(selector, cert);
   1163 
   1164        PKIX_INCREF(selector->params);
   1165        params = selector->params;
   1166 
   1167        /* Are we looking for CAs? */
   1168        PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag
   1169                    (params, &isLeafCert, plContext),
   1170                    PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED);
   1171 
   1172        if (params == NULL){
   1173                goto cleanup;
   1174        }
   1175 
   1176        PKIX_CHECK(PKIX_ComCertSelParams_GetVersion
   1177                    (params, &selVersion, plContext),
   1178                    PKIX_COMCERTSELPARAMSGETVERSIONFAILED);
   1179 
   1180        if (selVersion != 0xFFFFFFFF){
   1181                PKIX_CHECK(PKIX_PL_Cert_GetVersion
   1182                            (cert, &certVersion, plContext),
   1183                            PKIX_CERTGETVERSIONFAILED);
   1184 
   1185                if (selVersion != certVersion) {
   1186                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTVERSIONFAILED);
   1187                }
   1188        }
   1189 
   1190        PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
   1191                    (params, &selSubject, plContext),
   1192                    PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
   1193 
   1194        if (selSubject){
   1195                PKIX_CHECK(PKIX_PL_Cert_GetSubject
   1196                            (cert, &certSubject, plContext),
   1197                            PKIX_CERTGETSUBJECTFAILED);
   1198 
   1199                if (certSubject){
   1200                        PKIX_CHECK(PKIX_PL_X500Name_Match
   1201                            (selSubject, certSubject, &result, plContext),
   1202                            PKIX_X500NAMEMATCHFAILED);
   1203 
   1204                        if (result == PKIX_FALSE){
   1205                            PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
   1206                        }
   1207                } else { /* cert has no subject */
   1208                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
   1209                }
   1210        }
   1211 
   1212        PKIX_CHECK(PKIX_ComCertSelParams_GetIssuer
   1213                    (params, &selIssuer, plContext),
   1214                    PKIX_COMCERTSELPARAMSGETISSUERFAILED);
   1215 
   1216        if (selIssuer){
   1217                PKIX_CHECK(PKIX_PL_Cert_GetIssuer
   1218                            (cert, &certIssuer, plContext),
   1219                            PKIX_CERTGETISSUERFAILED);
   1220 
   1221                PKIX_CHECK(PKIX_PL_X500Name_Match
   1222                            (selIssuer, certIssuer, &result, plContext),
   1223                            PKIX_X500NAMEMATCHFAILED);
   1224 
   1225                if (result == PKIX_FALSE){
   1226                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTISSUERFAILED);
   1227                }
   1228        }
   1229 
   1230        PKIX_CHECK(PKIX_ComCertSelParams_GetSerialNumber
   1231                    (params, &selSerialNumber, plContext),
   1232                    PKIX_COMCERTSELPARAMSGETSERIALNUMBERFAILED);
   1233 
   1234        if (selSerialNumber){
   1235                PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber
   1236                            (cert, &certSerialNumber, plContext),
   1237                            PKIX_CERTGETSERIALNUMBERFAILED);
   1238 
   1239                PKIX_CHECK(PKIX_PL_Object_Equals
   1240                            ((PKIX_PL_Object *)selSerialNumber,
   1241                            (PKIX_PL_Object *)certSerialNumber,
   1242                            &result,
   1243                            plContext),
   1244                            PKIX_OBJECTEQUALSFAILED);
   1245 
   1246                if (result == PKIX_FALSE){
   1247                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSERIALNUMFAILED);
   1248                }
   1249        }
   1250 
   1251        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
   1252                    (params, &selCert, plContext),
   1253                    PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
   1254 
   1255        if (selCert){
   1256                PKIX_CHECK(PKIX_PL_Object_Equals
   1257                            ((PKIX_PL_Object *) selCert,
   1258                            (PKIX_PL_Object *) cert,
   1259                            &result,
   1260                            plContext),
   1261                            PKIX_OBJECTEQUALSFAILED);
   1262 
   1263                if (result == PKIX_FALSE){
   1264                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTOBJECTFAILED);
   1265                }
   1266        }
   1267 
   1268        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
   1269                    (params, &selDate, plContext),
   1270                    PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
   1271 
   1272        if (selDate){
   1273                PKIX_CHECK(PKIX_PL_Cert_CheckValidity
   1274                            (cert, selDate, plContext),
   1275                            PKIX_CERTCHECKVALIDITYFAILED);
   1276        }
   1277 
   1278        PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint
   1279                    (params, cert, &result, plContext),
   1280                    PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED);
   1281 
   1282        PKIX_CHECK(pkix_CertSelector_Match_Policies
   1283                    (params, cert, &result, plContext),
   1284                    PKIX_CERTSELECTORMATCHPOLICIESFAILED);
   1285 
   1286        PKIX_CHECK(pkix_CertSelector_Match_CertificateValid
   1287                    (params, cert, &result, plContext),
   1288                    PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED);
   1289 
   1290        PKIX_CHECK(pkix_CertSelector_Match_NameConstraints
   1291                    (params, cert, &result, plContext),
   1292                    PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED);
   1293 
   1294        PKIX_CHECK(pkix_CertSelector_Match_PathToNames
   1295                    (params, cert, &result, plContext),
   1296                    PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
   1297 
   1298        PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames
   1299                    (params, cert, &result, plContext),
   1300                    PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
   1301 
   1302        /* Check key usage and cert type based on certificate usage. */
   1303        PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert,
   1304                                                     plContext),
   1305                   PKIX_CERTVERIFYCERTTYPEFAILED);
   1306 
   1307        /* Next two check are for user supplied additional KU and EKU. */
   1308        PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage
   1309                    (params, cert, &result, plContext),
   1310                    PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
   1311 
   1312        PKIX_CHECK(pkix_CertSelector_Match_KeyUsage
   1313                    (params, cert, &result, plContext),
   1314                    PKIX_CERTSELECTORMATCHKEYUSAGEFAILED);
   1315 
   1316        PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId
   1317                    (params, cert, &result, plContext),
   1318                    PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
   1319 
   1320        PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId
   1321                    (params, cert, &result, plContext),
   1322                    PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
   1323 
   1324        PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId
   1325                    (params, cert, &result, plContext),
   1326                    PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
   1327 
   1328        PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey
   1329                    (params, cert, &result, plContext),
   1330                    PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
   1331 
   1332        /* if we reach here, the cert has successfully matched criteria */
   1333 
   1334 
   1335 #ifdef PKIX_BUILDDEBUG
   1336 
   1337        PKIX_CHECK(pkix_pl_Cert_ToString_Helper
   1338                    (cert, PKIX_TRUE, &certString, plContext),
   1339                    PKIX_CERTTOSTRINGHELPERFAILED);
   1340 
   1341        PKIX_CHECK(PKIX_PL_String_GetEncoded
   1342                (certString,
   1343                PKIX_ESCASCII,
   1344                &certAscii,
   1345                &certAsciiLen,
   1346                plContext),
   1347                PKIX_STRINGGETENCODEDFAILED);
   1348 
   1349        PKIX_CERTSELECTOR_DEBUG_ARG("Cert Selected:\n%s\n", certAscii);
   1350 
   1351 #endif
   1352 
   1353 cleanup:
   1354 
   1355 #ifdef PKIX_BUILDDEBUG
   1356        PKIX_DECREF(certString);
   1357        PKIX_FREE(certAscii);
   1358 #endif
   1359 
   1360        PKIX_DECREF(certSubject);
   1361        PKIX_DECREF(selSubject);
   1362        PKIX_DECREF(certIssuer);
   1363        PKIX_DECREF(selIssuer);
   1364        PKIX_DECREF(certSerialNumber);
   1365        PKIX_DECREF(selSerialNumber);
   1366        PKIX_DECREF(selCert);
   1367        PKIX_DECREF(selDate);
   1368        PKIX_DECREF(params);
   1369        PKIX_RETURN(CERTSELECTOR);
   1370 }
   1371 
   1372 /*
   1373 * FUNCTION: pkix_CertSelector_RegisterSelf
   1374 * DESCRIPTION:
   1375 *  Registers PKIX_CERTSELECTOR_TYPE and its related functions with
   1376 *  systemClasses[]
   1377 * THREAD SAFETY:
   1378 *  Not Thread Safe - for performance and complexity reasons
   1379 *
   1380 *  Since this function is only called by PKIX_PL_Initialize, which should
   1381 *  only be called once, it is acceptable that this function is not
   1382 *  thread-safe.
   1383 */
   1384 PKIX_Error *
   1385 pkix_CertSelector_RegisterSelf(void *plContext)
   1386 {
   1387        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
   1388        pkix_ClassTable_Entry entry;
   1389 
   1390        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_RegisterSelf");
   1391 
   1392        entry.description = "CertSelector";
   1393        entry.objCounter = 0;
   1394        entry.typeObjectSize = sizeof(PKIX_CertSelector);
   1395        entry.destructor = pkix_CertSelector_Destroy;
   1396        entry.equalsFunction = NULL;
   1397        entry.hashcodeFunction = NULL;
   1398        entry.toStringFunction = NULL;
   1399        entry.comparator = NULL;
   1400        entry.duplicateFunction = pkix_CertSelector_Duplicate;
   1401 
   1402        systemClasses[PKIX_CERTSELECTOR_TYPE] = entry;
   1403 
   1404        PKIX_RETURN(CERTSELECTOR);
   1405 }
   1406 
   1407 /* --Public-Functions--------------------------------------------- */
   1408 
   1409 
   1410 /*
   1411 * FUNCTION: PKIX_CertSelector_Create (see comments in pkix_certsel.h)
   1412 */
   1413 PKIX_Error *
   1414 PKIX_CertSelector_Create(
   1415        PKIX_CertSelector_MatchCallback callback,
   1416        PKIX_PL_Object *certSelectorContext,
   1417        PKIX_CertSelector **pSelector,
   1418        void *plContext)
   1419 {
   1420        PKIX_CertSelector *selector = NULL;
   1421 
   1422        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Create");
   1423        PKIX_NULLCHECK_ONE(pSelector);
   1424 
   1425        PKIX_CHECK(PKIX_PL_Object_Alloc
   1426                    (PKIX_CERTSELECTOR_TYPE,
   1427                    sizeof (PKIX_CertSelector),
   1428                    (PKIX_PL_Object **)&selector,
   1429                    plContext),
   1430                    PKIX_COULDNOTCREATECERTSELECTOROBJECT);
   1431 
   1432        /*
   1433         * if user specified a particular match callback, we use that one.
   1434         * otherwise, we use the default match implementation which
   1435         * understands how to process PKIX_ComCertSelParams
   1436         */
   1437 
   1438        if (callback){
   1439                selector->matchCallback = callback;
   1440        } else {
   1441                selector->matchCallback = pkix_CertSelector_DefaultMatch;
   1442        }
   1443 
   1444        /* initialize other fields */
   1445        selector->params = NULL;
   1446 
   1447        PKIX_INCREF(certSelectorContext);
   1448        selector->context = certSelectorContext;
   1449 
   1450        *pSelector = selector;
   1451 
   1452 cleanup:
   1453 
   1454        PKIX_RETURN(CERTSELECTOR);
   1455 
   1456 }
   1457 
   1458 /*
   1459 * FUNCTION: PKIX_CertSelector_GetMatchCallback
   1460 *      (see comments in pkix_certsel.h)
   1461 */
   1462 PKIX_Error *
   1463 PKIX_CertSelector_GetMatchCallback(
   1464        PKIX_CertSelector *selector,
   1465        PKIX_CertSelector_MatchCallback *pCallback,
   1466        void *plContext)
   1467 {
   1468        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetMatchCallback");
   1469        PKIX_NULLCHECK_TWO(selector, pCallback);
   1470 
   1471        *pCallback = selector->matchCallback;
   1472 
   1473        PKIX_RETURN(CERTSELECTOR);
   1474 }
   1475 
   1476 /*
   1477 * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
   1478 *      (see comments in pkix_certsel.h)
   1479 */
   1480 PKIX_Error *
   1481 PKIX_CertSelector_GetCertSelectorContext(
   1482        PKIX_CertSelector *selector,
   1483        PKIX_PL_Object **pCertSelectorContext,
   1484        void *plContext)
   1485 {
   1486        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetCertSelectorContext");
   1487        PKIX_NULLCHECK_TWO(selector, pCertSelectorContext);
   1488 
   1489        PKIX_INCREF(selector->context);
   1490 
   1491        *pCertSelectorContext = selector->context;
   1492 
   1493 cleanup:
   1494        PKIX_RETURN(CERTSELECTOR);
   1495 }
   1496 
   1497 /*
   1498 * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
   1499 *      (see comments in pkix_certsel.h)
   1500 */
   1501 PKIX_Error *
   1502 PKIX_CertSelector_GetCommonCertSelectorParams(
   1503        PKIX_CertSelector *selector,
   1504        PKIX_ComCertSelParams **pParams,
   1505        void *plContext)
   1506 {
   1507        PKIX_ENTER(CERTSELECTOR,
   1508                    "PKIX_CertSelector_GetCommonCertSelectorParams");
   1509 
   1510        PKIX_NULLCHECK_TWO(selector, pParams);
   1511 
   1512        PKIX_INCREF(selector->params);
   1513        *pParams = selector->params;
   1514 
   1515 cleanup:
   1516        PKIX_RETURN(CERTSELECTOR);
   1517 
   1518 }
   1519 
   1520 /*
   1521 * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
   1522 *      (see comments in pkix_certsel.h)
   1523 */
   1524 PKIX_Error *
   1525 PKIX_CertSelector_SetCommonCertSelectorParams(
   1526        PKIX_CertSelector *selector,
   1527        PKIX_ComCertSelParams *params,
   1528        void *plContext)
   1529 {
   1530        PKIX_ENTER(CERTSELECTOR,
   1531                    "PKIX_CertSelector_SetCommonCertSelectorParams");
   1532 
   1533        PKIX_NULLCHECK_ONE(selector);
   1534 
   1535        PKIX_DECREF(selector->params);
   1536        PKIX_INCREF(params);
   1537        selector->params = params;
   1538 
   1539        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   1540                    ((PKIX_PL_Object *)selector, plContext),
   1541                    PKIX_OBJECTINVALIDATECACHEFAILED);
   1542 
   1543 cleanup:
   1544 
   1545        PKIX_RETURN(CERTSELECTOR);
   1546 
   1547 }
   1548 
   1549 /*
   1550 * FUNCTION: pkix_CertSelector_Select
   1551 * DESCRIPTION:
   1552 *
   1553 *  This function applies the selector pointed to by "selector" to each Cert,
   1554 *  in turn, in the List pointed to by "before", and creates a List containing
   1555 *  all the Certs that matched, or passed the selection process, storing that
   1556 *  List at "pAfter". If no Certs match, an empty List is stored at "pAfter".
   1557 *
   1558 *  The List returned in "pAfter" is immutable.
   1559 *
   1560 * PARAMETERS:
   1561 *  "selector"
   1562 *      Address of CertSelelector to be applied to the List. Must be non-NULL.
   1563 *  "before"
   1564 *      Address of List that is to be filtered. Must be non-NULL.
   1565 *  "pAfter"
   1566 *      Address at which resulting List, possibly empty, is stored. Must be
   1567 *      non-NULL.
   1568 *  "plContext"
   1569 *      Platform-specific context pointer.
   1570 * THREAD SAFETY:
   1571 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   1572 * RETURNS:
   1573 *  Returns NULL if the function succeeds.
   1574 *  Returns a CertSelector Error if the function fails in a non-fatal way.
   1575 *  Returns a Fatal Error if the function fails in an unrecoverable way.
   1576 */
   1577 PKIX_Error *
   1578 pkix_CertSelector_Select(
   1579 PKIX_CertSelector *selector,
   1580 PKIX_List *before,
   1581 PKIX_List **pAfter,
   1582 void *plContext)
   1583 {
   1584 PKIX_UInt32 numBefore = 0;
   1585 PKIX_UInt32 i = 0;
   1586 PKIX_List *filtered = NULL;
   1587 PKIX_PL_Cert *candidate = NULL;
   1588 
   1589        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Select");
   1590        PKIX_NULLCHECK_THREE(selector, before, pAfter);
   1591 
   1592        PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
   1593                PKIX_LISTCREATEFAILED);
   1594 
   1595        PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
   1596                PKIX_LISTGETLENGTHFAILED);
   1597 
   1598        for (i = 0; i < numBefore; i++) {
   1599 
   1600                PKIX_CHECK(PKIX_List_GetItem
   1601                        (before, i, (PKIX_PL_Object **)&candidate, plContext),
   1602                        PKIX_LISTGETITEMFAILED);
   1603 
   1604                PKIX_CHECK_ONLY_FATAL(selector->matchCallback
   1605                        (selector, candidate, plContext),
   1606                        PKIX_CERTSELECTORMATCHCALLBACKFAILED);
   1607 
   1608                if (!(PKIX_ERROR_RECEIVED)) {
   1609 
   1610                        PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
   1611                                (filtered,
   1612                                (PKIX_PL_Object *)candidate,
   1613                                plContext),
   1614                                PKIX_LISTAPPENDITEMFAILED);
   1615                }
   1616 
   1617                pkixTempErrorReceived = PKIX_FALSE;
   1618                PKIX_DECREF(candidate);
   1619        }
   1620 
   1621        PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
   1622                PKIX_LISTSETIMMUTABLEFAILED);
   1623 
   1624        /* Don't throw away the list if one Cert was bad! */
   1625        pkixTempErrorReceived = PKIX_FALSE;
   1626 
   1627        *pAfter = filtered;
   1628        filtered = NULL;
   1629 
   1630 cleanup:
   1631 
   1632        PKIX_DECREF(filtered);
   1633        PKIX_DECREF(candidate);
   1634 
   1635        PKIX_RETURN(CERTSELECTOR);
   1636 
   1637 }