diff nss/lib/libpkix/pkix/certsel/pkix_certselector.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/libpkix/pkix/certsel/pkix_certselector.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,1637 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * pkix_certselector.c
+ *
+ * CertSelector Object Functions
+ *
+ */
+
+#include "pkix_certselector.h"
+
+/* --Private-Functions-------------------------------------------- */
+
+/*
+ * FUNCTION: pkix_CertSelector_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_CertSelector_Destroy(
+        PKIX_PL_Object *object,
+        void *plContext)
+{
+        PKIX_CertSelector *selector = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Destroy");
+        PKIX_NULLCHECK_ONE(object);
+
+        /* Check that this object is a cert selector */
+        PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
+                    PKIX_OBJECTNOTCERTSELECTOR);
+
+        selector = (PKIX_CertSelector *)object;
+        PKIX_DECREF(selector->params);
+        PKIX_DECREF(selector->context);
+
+cleanup:
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Duplicate
+ * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_CertSelector_Duplicate(
+        PKIX_PL_Object *object,
+        PKIX_PL_Object **pNewObject,
+        void *plContext)
+{
+        PKIX_CertSelector *certSelector = NULL;
+        PKIX_CertSelector *certSelectorDuplicate = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Duplicate");
+        PKIX_NULLCHECK_TWO(object, pNewObject);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
+                    PKIX_OBJECTNOTCERTSELECTOR);
+
+        certSelector = (PKIX_CertSelector *)object;
+
+        PKIX_CHECK(PKIX_CertSelector_Create
+                    (certSelector->matchCallback,
+                    certSelector->context,
+                    &certSelectorDuplicate,
+                    plContext),
+                    PKIX_CERTSELECTORCREATEFAILED);
+
+        PKIX_CHECK(PKIX_PL_Object_Duplicate
+                    ((PKIX_PL_Object *)certSelector->params,
+                    (PKIX_PL_Object **)&certSelectorDuplicate->params,
+                    plContext),
+                    PKIX_OBJECTDUPLICATEFAILED);
+
+        *pNewObject = (PKIX_PL_Object *)certSelectorDuplicate;
+
+cleanup:
+
+        if (PKIX_ERROR_RECEIVED){
+                PKIX_DECREF(certSelectorDuplicate);
+        }
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_BasicConstraint
+ * DESCRIPTION:
+ *
+ *  Determines whether the Cert pointed to by "cert" matches the basic
+ *  constraints criterion using the basic constraints field of the
+ *  ComCertSelParams pointed to by "params". If the basic constraints field is
+ *  -1, no basic constraints check is done and the Cert is considered to match
+ *  the basic constraints criterion. If the Cert does not match the basic
+ *  constraints criterion, an Error pointer is returned.
+ *
+ *  In order to match against this criterion, there are several possibilities.
+ *
+ *  1) If the criterion's minimum path length is greater than or equal to zero,
+ *  a certificate must include a BasicConstraints extension with a pathLen of
+ *  at least this value.
+ *
+ *  2) If the criterion's minimum path length is -2, a certificate must be an
+ *  end-entity certificate.
+ *
+ *  3) If the criterion's minimum path length is -1, no basic constraints check
+ *  is done and all certificates are considered to match this criterion.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose basic constraints field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * OUTPUT PARAMETERS ON FAILURE:
+ *   If the function returns a failure,
+ *   the output parameters of this function are undefined.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_BasicConstraint(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
+        PKIX_Boolean caFlag = PKIX_FALSE; /* EE Cert by default */
+        PKIX_Int32 pathLength = 0;
+        PKIX_Int32 minPathLength = 0;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_BasicConstraint");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+        *pResult = PKIX_TRUE;
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
+                (params, &minPathLength, plContext),
+                PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
+
+        /* If the minPathLength is unlimited (-1), no checking */
+        if (minPathLength == PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH) {
+                goto cleanup;
+        }
+
+        PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
+                    (cert, &basicConstraints, plContext),
+                    PKIX_CERTGETBASICCONSTRAINTSFAILED);
+
+        if (basicConstraints != NULL) {
+                PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
+                            (basicConstraints, &caFlag, plContext),
+                            PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
+
+                PKIX_CHECK(PKIX_PL_BasicConstraints_GetPathLenConstraint
+                        (basicConstraints, &pathLength, plContext),
+                        PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
+        }
+
+        /*
+         * if minPathLength >= 0, the cert must have a BasicConstraints ext and
+         * the pathLength in this cert
+         * BasicConstraints needs to be >= minPathLength.
+         */
+        if (minPathLength >= 0){
+                if ((!basicConstraints) || (caFlag == PKIX_FALSE)){
+                        PKIX_ERROR(PKIX_CERTNOTALLOWEDTOSIGNCERTIFICATES);
+                } else if ((pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) &&
+                            (pathLength < minPathLength)){
+                        PKIX_CERTSELECTOR_DEBUG
+                            ("Basic Constraints path length match failed\n");
+                        *pResult = PKIX_FALSE;
+                        PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
+                }
+        }
+
+        /* if the minPathLength is -2, this cert must be an end-entity cert. */
+        if (minPathLength == PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH) {
+                if (caFlag == PKIX_TRUE) {
+                    PKIX_CERTSELECTOR_DEBUG
+                        ("Basic Constraints end-entity match failed\n");
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
+                }
+        }
+
+cleanup:
+
+        PKIX_DECREF(basicConstraints);
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_Policies
+ * DESCRIPTION:
+ *
+ *  Determines whether the Cert pointed to by "cert" matches the policy
+ *  constraints specified in the ComCertsSelParams given by "params".
+ *  If "params" specifies a policy constraint of NULL, all certificates
+ *  match. If "params" specifies an empty list, "cert" must have at least
+ *  some policy. Otherwise "cert" must include at least one of the
+ *  policies in the list. See the description of PKIX_CertSelector in
+ *  pkix_certsel.h for more.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose policy criterion (if any) is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_Policies(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_UInt32 numConstraintPolicies = 0;
+        PKIX_UInt32 numCertPolicies = 0;
+        PKIX_UInt32 certPolicyIndex = 0;
+        PKIX_Boolean result = PKIX_FALSE;
+        PKIX_List *constraintPolicies = NULL; /* List of PKIX_PL_OID */
+        PKIX_List *certPolicyInfos = NULL; /* List of PKIX_PL_CertPolicyInfo */
+        PKIX_PL_CertPolicyInfo *policyInfo = NULL;
+        PKIX_PL_OID *polOID = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_Policies");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetPolicy
+                (params, &constraintPolicies, plContext),
+                PKIX_COMCERTSELPARAMSGETPOLICYFAILED);
+
+        /* If constraintPolicies is NULL, all certificates "match" */
+        if (constraintPolicies) {
+            PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
+                (cert, &certPolicyInfos, plContext),
+                PKIX_CERTGETPOLICYINFORMATIONFAILED);
+
+            /* No hope of a match if cert has no policies */
+            if (!certPolicyInfos) {
+                PKIX_CERTSELECTOR_DEBUG("Certificate has no policies\n");
+                *pResult = PKIX_FALSE;
+                PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
+            }
+
+            PKIX_CHECK(PKIX_List_GetLength
+                (constraintPolicies, &numConstraintPolicies, plContext),
+                PKIX_LISTGETLENGTHFAILED);
+
+            if (numConstraintPolicies > 0) {
+
+                PKIX_CHECK(PKIX_List_GetLength
+                        (certPolicyInfos, &numCertPolicies, plContext),
+                        PKIX_LISTGETLENGTHFAILED);
+
+                for (certPolicyIndex = 0;
+                        ((!result) && (certPolicyIndex < numCertPolicies));
+                        certPolicyIndex++) {
+
+                        PKIX_CHECK(PKIX_List_GetItem
+                                (certPolicyInfos,
+                                certPolicyIndex,
+                                (PKIX_PL_Object **)&policyInfo,
+                                plContext),
+                                PKIX_LISTGETELEMENTFAILED);
+                        PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
+                                (policyInfo, &polOID, plContext),
+                                PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
+
+                        PKIX_CHECK(pkix_List_Contains
+                                (constraintPolicies,
+                                (PKIX_PL_Object *)polOID,
+                                &result,
+                                plContext),
+                                PKIX_LISTCONTAINSFAILED);
+                        PKIX_DECREF(policyInfo);
+                        PKIX_DECREF(polOID);
+                }
+                if (!result) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
+                }
+            }
+        }
+
+cleanup:
+
+        PKIX_DECREF(constraintPolicies);
+        PKIX_DECREF(certPolicyInfos);
+        PKIX_DECREF(policyInfo);
+        PKIX_DECREF(polOID);
+
+        PKIX_RETURN(CERTSELECTOR);
+
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_CertificateValid
+ * DESCRIPTION:
+ *
+ *  Determines whether the Cert pointed to by "cert" matches the certificate
+ *  validity criterion using the CertificateValid field of the
+ *  ComCertSelParams pointed to by "params". If the CertificateValid field is
+ *  NULL, no validity check is done and the Cert is considered to match
+ *  the CertificateValid criterion. If the CertificateValid field specifies a
+ *  Date prior to the notBefore field in the Cert, or greater than the notAfter
+ *  field in the Cert, an Error is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose certValid field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_CertificateValid(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_Date *validityTime = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_CertificateValid");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
+                (params, &validityTime, plContext),
+                PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
+
+        /* If the validityTime is not set, all certificates are acceptable */
+        if (validityTime) {
+                PKIX_CHECK(PKIX_PL_Cert_CheckValidity
+                        (cert, validityTime, plContext),
+                        PKIX_CERTCHECKVALIDITYFAILED);
+        }
+
+cleanup:
+        if (PKIX_ERROR_RECEIVED) {
+            *pResult = PKIX_FALSE;
+        }
+        PKIX_DECREF(validityTime);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_NameConstraints
+ * DESCRIPTION:
+ *
+ *  Determines whether the Cert pointed to by "cert" matches the name
+ *  constraints criterion specified in the ComCertSelParams pointed to by
+ *  "params". If the name constraints field is NULL, no name constraints check
+ *  is done and the Cert is considered to match the name constraints criterion.
+ *  If the Cert does not match the name constraints criterion, an Error pointer
+ *  is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose name constraints field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_NameConstraints(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_NameConstraints");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetNameConstraints
+                (params, &nameConstraints, plContext),
+                PKIX_COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED);
+
+        if (nameConstraints != NULL) {
+                /* As only the end-entity certificate should have
+                 * the common name constrained as if it was a dNSName,
+                 * do not constrain the common name when building a
+                 * forward path.
+                 */
+                PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
+                    (cert, nameConstraints, PKIX_FALSE, plContext),
+                    PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
+        }
+
+cleanup:
+        if (PKIX_ERROR_RECEIVED) {
+            *pResult = PKIX_FALSE;
+        }
+
+        PKIX_DECREF(nameConstraints);
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_PathToNames
+ * DESCRIPTION:
+ *
+ *  Determines whether the names at pathToNames in "params" complies with the
+ *  NameConstraints pointed to by "cert". If the pathToNames field is NULL
+ *  or there is no name constraints for this "cert", no checking is done
+ *  and the Cert is considered to match the name constraints criterion.
+ *  If the Cert does not match the name constraints criterion, an Error
+ *  pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose PathToNames field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_PathToNames(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_List *pathToNamesList = NULL;
+        PKIX_Boolean passed = PKIX_FALSE;
+        PKIX_PL_CertNameConstraints *nameConstraints = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_PathToNames");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
+                (params, &pathToNamesList, plContext),
+                PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
+
+        if (pathToNamesList != NULL) {
+
+            PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
+                    (cert, &nameConstraints, plContext),
+                    PKIX_CERTGETNAMECONSTRAINTSFAILED);
+
+            if (nameConstraints != NULL) {
+
+                PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
+                        (pathToNamesList, nameConstraints, &passed, plContext),
+                        PKIX_CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED);
+
+                if (passed != PKIX_TRUE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
+                }
+            }
+
+        }
+
+cleanup:
+
+        PKIX_DECREF(nameConstraints);
+        PKIX_DECREF(pathToNamesList);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_SubjAltNames
+ * DESCRIPTION:
+ *
+ *  Determines whether the names at subjAltNames in "params" match with the
+ *  SubjAltNames pointed to by "cert". If the subjAltNames field is NULL,
+ *  no name checking is done and the Cert is considered to match the
+ *  criterion. If the Cert does not match the criterion, an Error pointer
+ *  is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose SubjAltNames field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_SubjAltNames(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_List *subjAltNamesList = NULL;
+        PKIX_List *certSubjAltNames = NULL;
+        PKIX_PL_GeneralName *name = NULL;
+        PKIX_Boolean checkPassed = PKIX_FALSE;
+        PKIX_Boolean matchAll = PKIX_TRUE;
+        PKIX_UInt32 i, numItems;
+        PKIX_UInt32 matchCount = 0;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjAltNames");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
+                    (params, &matchAll, plContext),
+                    PKIX_COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
+                    (params, &subjAltNamesList, plContext),
+                    PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
+
+        if (subjAltNamesList != NULL) {
+
+            PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
+                    (cert, &certSubjAltNames, plContext),
+                    PKIX_CERTGETSUBJALTNAMESFAILED);
+
+            if (certSubjAltNames == NULL) {
+                *pResult = PKIX_FALSE;
+                PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
+            }
+
+            PKIX_CHECK(PKIX_List_GetLength
+                       (subjAltNamesList, &numItems, plContext),
+                       PKIX_LISTGETLENGTHFAILED);
+            
+            for (i = 0; i < numItems; i++) {
+                
+                PKIX_CHECK(PKIX_List_GetItem
+                           (subjAltNamesList,
+                            i,
+                            (PKIX_PL_Object **) &name,
+                            plContext),
+                           PKIX_LISTGETITEMFAILED);
+                
+                PKIX_CHECK(pkix_List_Contains
+                           (certSubjAltNames,
+                            (PKIX_PL_Object *) name,
+                            &checkPassed,
+                            plContext),
+                           PKIX_LISTCONTAINSFAILED);
+                
+                PKIX_DECREF(name);
+                
+                if (checkPassed == PKIX_TRUE) {
+                    
+                    if (matchAll == PKIX_FALSE) {
+                        /* one match is good enough */
+                        matchCount = numItems;
+                        break;
+                    } else {
+                        /* else continue checking next */
+                        matchCount++;
+                    }
+                    
+                }
+                
+            }
+            
+            if (matchCount != numItems) {
+                *pResult = PKIX_FALSE;
+                PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
+            }
+        }
+
+cleanup:
+
+        PKIX_DECREF(name);
+        PKIX_DECREF(certSubjAltNames);
+        PKIX_DECREF(subjAltNamesList);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_ExtendedKeyUsage
+ * DESCRIPTION:
+ *
+ *  Determines whether the names at ExtKeyUsage in "params" matches with the
+ *  ExtKeyUsage pointed to by "cert". If the ExtKeyUsage criterion or
+ *  ExtKeyUsage in "cert" is NULL, no checking is done and the Cert is
+ *  considered a match. If the Cert does not match, an Error pointer is
+ *  returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose ExtKeyUsage field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_ExtendedKeyUsage(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_List *extKeyUsageList = NULL;
+        PKIX_List *certExtKeyUsageList = NULL;
+        PKIX_PL_OID *ekuOid = NULL;
+        PKIX_Boolean isContained = PKIX_FALSE;
+        PKIX_UInt32 numItems = 0;
+        PKIX_UInt32 i;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_ExtendedKeyUsage");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
+                    (params, &extKeyUsageList, plContext),
+                    PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
+
+        if (extKeyUsageList == NULL) {
+                goto cleanup;
+        }
+
+        PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
+                    (cert, &certExtKeyUsageList, plContext),
+                    PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
+
+        if (certExtKeyUsageList != NULL) {
+
+            PKIX_CHECK(PKIX_List_GetLength
+                    (extKeyUsageList, &numItems, plContext),
+                    PKIX_LISTGETLENGTHFAILED);
+
+            for (i = 0; i < numItems; i++) {
+
+                PKIX_CHECK(PKIX_List_GetItem
+                    (extKeyUsageList, i, (PKIX_PL_Object **)&ekuOid, plContext),
+                    PKIX_LISTGETITEMFAILED);
+
+                PKIX_CHECK(pkix_List_Contains
+                    (certExtKeyUsageList,
+                    (PKIX_PL_Object *)ekuOid,
+                    &isContained,
+                    plContext),
+                    PKIX_LISTCONTAINSFAILED);
+
+                PKIX_DECREF(ekuOid);
+
+                if (isContained != PKIX_TRUE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
+                }
+            }
+        }
+
+cleanup:
+
+        PKIX_DECREF(ekuOid);
+        PKIX_DECREF(extKeyUsageList);
+        PKIX_DECREF(certExtKeyUsageList);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_KeyUsage
+ * DESCRIPTION:
+ *
+ *  Determines whether the bits at KeyUsage in "params" matches with the
+ *  KeyUsage pointed to by "cert". If the KeyUsage in params is 0
+ *  no checking is done and the Cert is considered a match. If the Cert does
+ *  not match, an Error pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose ExtKeyUsage field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_KeyUsage(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_UInt32 keyUsage = 0;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_KeyUsage");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
+                    (params, &keyUsage, plContext),
+                    PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED);
+
+        if (keyUsage != 0) {
+
+            PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage
+                        (cert, keyUsage, plContext),
+                        PKIX_CERTVERIFYKEYUSAGEFAILED);
+
+        }
+
+cleanup:
+        if (PKIX_ERROR_RECEIVED) {
+            *pResult = PKIX_FALSE;
+        }
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_SubjKeyId
+ * DESCRIPTION:
+ *
+ *  Determines whether the bytes at subjKeyId in "params" matches with the
+ *  Subject Key Identifier pointed to by "cert". If the subjKeyId in params is
+ *  set to NULL or the Cert doesn't have a Subject Key Identifier, no checking
+ *  is done and the Cert is considered a match. If the Cert does not match, an
+ *  Error pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose subjKeyId field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_SubjKeyId(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_ByteArray *selSubjKeyId = NULL;
+        PKIX_PL_ByteArray *certSubjKeyId = NULL;
+        PKIX_Boolean equals = PKIX_FALSE;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjKeyId");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjKeyIdentifier
+                    (params, &selSubjKeyId, plContext),
+                    PKIX_COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED);
+
+        if (selSubjKeyId != NULL) {
+
+                PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
+                    (cert, &certSubjKeyId, plContext),
+                    PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
+
+                if (certSubjKeyId == NULL) {
+                    goto cleanup;
+                }
+
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                           ((PKIX_PL_Object *)selSubjKeyId,
+                            (PKIX_PL_Object *)certSubjKeyId,
+                            &equals,
+                            plContext),
+                           PKIX_OBJECTEQUALSFAILED);
+                
+                if (equals == PKIX_FALSE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
+                }
+        }
+
+cleanup:
+
+        PKIX_DECREF(selSubjKeyId);
+        PKIX_DECREF(certSubjKeyId);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_AuthKeyId
+ * DESCRIPTION:
+ *
+ *  Determines whether the bytes at authKeyId in "params" matches with the
+ *  Authority Key Identifier pointed to by "cert". If the authKeyId in params
+ *  is set to NULL, no checking is done and the Cert is considered a match. If
+ *  the Cert does not match, an Error pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose authKeyId field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_AuthKeyId(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_ByteArray *selAuthKeyId = NULL;
+        PKIX_PL_ByteArray *certAuthKeyId = NULL;
+        PKIX_Boolean equals = PKIX_FALSE;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_AuthKeyId");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
+                    (params, &selAuthKeyId, plContext),
+                    PKIX_COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED);
+
+        if (selAuthKeyId != NULL) {
+
+                PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
+                    (cert, &certAuthKeyId, plContext),
+                    PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
+
+                if (certAuthKeyId == NULL) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
+                }
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                           ((PKIX_PL_Object *)selAuthKeyId,
+                            (PKIX_PL_Object *)certAuthKeyId,
+                            &equals,
+                            plContext),
+                           PKIX_OBJECTEQUALSFAILED);
+                
+                if (equals != PKIX_TRUE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
+                }
+        }
+
+cleanup:
+
+        PKIX_DECREF(selAuthKeyId);
+        PKIX_DECREF(certAuthKeyId);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_SubjPKAlgId
+ * DESCRIPTION:
+ *
+ *  Determines whether the OID at subjPKAlgId in "params" matches with the
+ *  Subject Public Key Alg Id pointed to by "cert". If the subjPKAlgId in params
+ *  is set to NULL, no checking is done and the Cert is considered a match. If
+ *  the Cert does not match, an Error pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose subjPKAlgId field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_SubjPKAlgId(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_OID *selPKAlgId = NULL;
+        PKIX_PL_OID *certPKAlgId = NULL;
+        PKIX_Boolean equals = PKIX_FALSE;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPKAlgId");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPKAlgId
+                    (params, &selPKAlgId, plContext),
+                    PKIX_COMCERTSELPARAMSGETSUBJPKALGIDFAILED);
+
+        if (selPKAlgId != NULL) {
+
+                PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKeyAlgId
+                    (cert, &certPKAlgId, plContext),
+                    PKIX_CERTGETSUBJECTPUBLICKEYALGIDFAILED);
+
+                if (certPKAlgId != NULL) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
+                }
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                           ((PKIX_PL_Object *)selPKAlgId,
+                            (PKIX_PL_Object *)certPKAlgId,
+                            &equals,
+                            plContext),
+                           PKIX_OBJECTEQUALSFAILED);
+                
+                if (equals != PKIX_TRUE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
+                }
+        }
+
+cleanup:
+
+        PKIX_DECREF(selPKAlgId);
+        PKIX_DECREF(certPKAlgId);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Match_SubjPubKey
+ * DESCRIPTION:
+ *
+ *  Determines whether the key at subjPubKey in "params" matches with the
+ *  Subject Public Key pointed to by "cert". If the subjPubKey in params
+ *  is set to NULL, no checking is done and the Cert is considered a match. If
+ *  the Cert does not match, an Error pointer is returned.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCertSelParams whose subPubKey field is used.
+ *      Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched. Must be non-NULL.
+ *  "pResult"
+ *      Address of PKIX_Boolean that returns the match result.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_Match_SubjPubKey(
+        PKIX_ComCertSelParams *params,
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_PublicKey *selPK = NULL;
+        PKIX_PL_PublicKey *certPK = NULL;
+        PKIX_Boolean equals = PKIX_FALSE;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPubKey");
+        PKIX_NULLCHECK_THREE(params, cert, pResult);
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPubKey
+                    (params, &selPK, plContext),
+                    PKIX_COMCERTSELPARAMSGETSUBJPUBKEYFAILED);
+
+        if (selPK != NULL) {
+
+                PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
+                    (cert, &certPK, plContext),
+                    PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
+
+                if (certPK == NULL) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
+                }
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                           ((PKIX_PL_Object *)selPK,
+                            (PKIX_PL_Object *)certPK,
+                            &equals,
+                            plContext),
+                           PKIX_OBJECTEQUALSFAILED);
+                
+                if (equals != PKIX_TRUE) {
+                    *pResult = PKIX_FALSE;
+                    PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
+                }
+        }
+
+cleanup:
+
+        PKIX_DECREF(selPK);
+        PKIX_DECREF(certPK);
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_DefaultMatch
+ * DESCRIPTION:
+ *
+ *  This default match function determines whether the specified Cert pointed
+ *  to by "cert" matches the criteria of the CertSelector pointed to by
+ *  "selector". If the Cert does not match the CertSelector's
+ *  criteria, an error will be thrown.
+ *
+ *  This default match function understands how to process the most common
+ *  parameters. Any common parameter that is not set is assumed to be disabled,
+ *  which means this function will select all certificates without regard to
+ *  that particular disabled parameter. For example, if the SerialNumber
+ *  parameter is not set, this function will not filter out any certificate
+ *  based on its serial number. As such, if no parameters are set, all are
+ *  disabled and any certificate will match. If a parameter is disabled, its
+ *  associated PKIX_ComCertSelParams_Get* function returns a default value.
+ *  That value is -1 for PKIX_ComCertSelParams_GetBasicConstraints and
+ *  PKIX_ComCertSelParams_GetVersion, 0 for PKIX_ComCertSelParams_GetKeyUsage,
+ *  and NULL for all other Get functions.
+ *
+ * PARAMETERS:
+ *  "selector"
+ *      Address of CertSelector whose MatchCallback logic and parameters are
+ *      to be used. Must be non-NULL.
+ *  "cert"
+ *      Address of Cert that is to be matched using "selector".
+ *      Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_CertSelector_DefaultMatch(
+        PKIX_CertSelector *selector,
+        PKIX_PL_Cert *cert,
+        void *plContext)
+{
+        PKIX_ComCertSelParams *params = NULL;
+        PKIX_PL_X500Name *certSubject = NULL;
+        PKIX_PL_X500Name *selSubject = NULL;
+        PKIX_PL_X500Name *certIssuer = NULL;
+        PKIX_PL_X500Name *selIssuer = NULL;
+        PKIX_PL_BigInt *certSerialNumber = NULL;
+        PKIX_PL_BigInt *selSerialNumber = NULL;
+        PKIX_PL_Cert *selCert = NULL;
+        PKIX_PL_Date *selDate = NULL;
+        PKIX_UInt32 selVersion = 0xFFFFFFFF;
+        PKIX_UInt32 certVersion = 0;
+        PKIX_Boolean result = PKIX_TRUE;
+        PKIX_Boolean isLeafCert = PKIX_TRUE;
+
+#ifdef PKIX_BUILDDEBUG
+        PKIX_PL_String *certString = NULL;
+        void *certAscii = NULL;
+        PKIX_UInt32 certAsciiLen;
+#endif
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_DefaultMatch");
+        PKIX_NULLCHECK_TWO(selector, cert);
+
+        PKIX_INCREF(selector->params);
+        params = selector->params;
+
+        /* Are we looking for CAs? */
+        PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag
+                    (params, &isLeafCert, plContext),
+                    PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED);
+
+        if (params == NULL){
+                goto cleanup;
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetVersion
+                    (params, &selVersion, plContext),
+                    PKIX_COMCERTSELPARAMSGETVERSIONFAILED);
+
+        if (selVersion != 0xFFFFFFFF){
+                PKIX_CHECK(PKIX_PL_Cert_GetVersion
+                            (cert, &certVersion, plContext),
+                            PKIX_CERTGETVERSIONFAILED);
+
+                if (selVersion != certVersion) {
+                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTVERSIONFAILED);
+                }
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
+                    (params, &selSubject, plContext),
+                    PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
+
+        if (selSubject){
+                PKIX_CHECK(PKIX_PL_Cert_GetSubject
+                            (cert, &certSubject, plContext),
+                            PKIX_CERTGETSUBJECTFAILED);
+
+                if (certSubject){
+                        PKIX_CHECK(PKIX_PL_X500Name_Match
+                            (selSubject, certSubject, &result, plContext),
+                            PKIX_X500NAMEMATCHFAILED);
+
+                        if (result == PKIX_FALSE){
+                            PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
+                        }
+                } else { /* cert has no subject */
+                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
+                }
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetIssuer
+                    (params, &selIssuer, plContext),
+                    PKIX_COMCERTSELPARAMSGETISSUERFAILED);
+
+        if (selIssuer){
+                PKIX_CHECK(PKIX_PL_Cert_GetIssuer
+                            (cert, &certIssuer, plContext),
+                            PKIX_CERTGETISSUERFAILED);
+
+                PKIX_CHECK(PKIX_PL_X500Name_Match
+                            (selIssuer, certIssuer, &result, plContext),
+                            PKIX_X500NAMEMATCHFAILED);
+
+                if (result == PKIX_FALSE){
+                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTISSUERFAILED);
+                }
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetSerialNumber
+                    (params, &selSerialNumber, plContext),
+                    PKIX_COMCERTSELPARAMSGETSERIALNUMBERFAILED);
+
+        if (selSerialNumber){
+                PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber
+                            (cert, &certSerialNumber, plContext),
+                            PKIX_CERTGETSERIALNUMBERFAILED);
+
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                            ((PKIX_PL_Object *)selSerialNumber,
+                            (PKIX_PL_Object *)certSerialNumber,
+                            &result,
+                            plContext),
+                            PKIX_OBJECTEQUALSFAILED);
+
+                if (result == PKIX_FALSE){
+                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSERIALNUMFAILED);
+                }
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
+                    (params, &selCert, plContext),
+                    PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
+
+        if (selCert){
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                            ((PKIX_PL_Object *) selCert,
+                            (PKIX_PL_Object *) cert,
+                            &result,
+                            plContext),
+                            PKIX_OBJECTEQUALSFAILED);
+
+                if (result == PKIX_FALSE){
+                        PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTOBJECTFAILED);
+                }
+        }
+
+        PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
+                    (params, &selDate, plContext),
+                    PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
+
+        if (selDate){
+                PKIX_CHECK(PKIX_PL_Cert_CheckValidity
+                            (cert, selDate, plContext),
+                            PKIX_CERTCHECKVALIDITYFAILED);
+        }
+
+        PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_Policies
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHPOLICIESFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_CertificateValid
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_NameConstraints
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_PathToNames
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
+
+        /* Check key usage and cert type based on certificate usage. */
+        PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert,
+                                                     plContext),
+                   PKIX_CERTVERIFYCERTTYPEFAILED);
+
+        /* Next two check are for user supplied additional KU and EKU. */
+        PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_KeyUsage
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHKEYUSAGEFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
+
+        PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey
+                    (params, cert, &result, plContext),
+                    PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
+
+        /* if we reach here, the cert has successfully matched criteria */
+
+
+#ifdef PKIX_BUILDDEBUG
+
+        PKIX_CHECK(pkix_pl_Cert_ToString_Helper
+                    (cert, PKIX_TRUE, &certString, plContext),
+                    PKIX_CERTTOSTRINGHELPERFAILED);
+
+        PKIX_CHECK(PKIX_PL_String_GetEncoded
+                (certString,
+                PKIX_ESCASCII,
+                &certAscii,
+                &certAsciiLen,
+                plContext),
+                PKIX_STRINGGETENCODEDFAILED);
+
+        PKIX_CERTSELECTOR_DEBUG_ARG("Cert Selected:\n%s\n", certAscii);
+
+#endif
+
+cleanup:
+
+#ifdef PKIX_BUILDDEBUG
+        PKIX_DECREF(certString);
+        PKIX_FREE(certAscii);
+#endif
+
+        PKIX_DECREF(certSubject);
+        PKIX_DECREF(selSubject);
+        PKIX_DECREF(certIssuer);
+        PKIX_DECREF(selIssuer);
+        PKIX_DECREF(certSerialNumber);
+        PKIX_DECREF(selSerialNumber);
+        PKIX_DECREF(selCert);
+        PKIX_DECREF(selDate);
+        PKIX_DECREF(params);
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_RegisterSelf
+ * DESCRIPTION:
+ *  Registers PKIX_CERTSELECTOR_TYPE and its related functions with
+ *  systemClasses[]
+ * THREAD SAFETY:
+ *  Not Thread Safe - for performance and complexity reasons
+ *
+ *  Since this function is only called by PKIX_PL_Initialize, which should
+ *  only be called once, it is acceptable that this function is not
+ *  thread-safe.
+ */
+PKIX_Error *
+pkix_CertSelector_RegisterSelf(void *plContext)
+{
+        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+        pkix_ClassTable_Entry entry;
+
+        PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_RegisterSelf");
+
+        entry.description = "CertSelector";
+        entry.objCounter = 0;
+        entry.typeObjectSize = sizeof(PKIX_CertSelector);
+        entry.destructor = pkix_CertSelector_Destroy;
+        entry.equalsFunction = NULL;
+        entry.hashcodeFunction = NULL;
+        entry.toStringFunction = NULL;
+        entry.comparator = NULL;
+        entry.duplicateFunction = pkix_CertSelector_Duplicate;
+
+        systemClasses[PKIX_CERTSELECTOR_TYPE] = entry;
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/* --Public-Functions--------------------------------------------- */
+
+
+/*
+ * FUNCTION: PKIX_CertSelector_Create (see comments in pkix_certsel.h)
+ */
+PKIX_Error *
+PKIX_CertSelector_Create(
+        PKIX_CertSelector_MatchCallback callback,
+        PKIX_PL_Object *certSelectorContext,
+        PKIX_CertSelector **pSelector,
+        void *plContext)
+{
+        PKIX_CertSelector *selector = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Create");
+        PKIX_NULLCHECK_ONE(pSelector);
+
+        PKIX_CHECK(PKIX_PL_Object_Alloc
+                    (PKIX_CERTSELECTOR_TYPE,
+                    sizeof (PKIX_CertSelector),
+                    (PKIX_PL_Object **)&selector,
+                    plContext),
+                    PKIX_COULDNOTCREATECERTSELECTOROBJECT);
+
+        /*
+         * if user specified a particular match callback, we use that one.
+         * otherwise, we use the default match implementation which
+         * understands how to process PKIX_ComCertSelParams
+         */
+
+        if (callback){
+                selector->matchCallback = callback;
+        } else {
+                selector->matchCallback = pkix_CertSelector_DefaultMatch;
+        }
+
+        /* initialize other fields */
+        selector->params = NULL;
+
+        PKIX_INCREF(certSelectorContext);
+        selector->context = certSelectorContext;
+
+        *pSelector = selector;
+
+cleanup:
+
+        PKIX_RETURN(CERTSELECTOR);
+
+}
+
+/*
+ * FUNCTION: PKIX_CertSelector_GetMatchCallback
+ *      (see comments in pkix_certsel.h)
+ */
+PKIX_Error *
+PKIX_CertSelector_GetMatchCallback(
+        PKIX_CertSelector *selector,
+        PKIX_CertSelector_MatchCallback *pCallback,
+        void *plContext)
+{
+        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetMatchCallback");
+        PKIX_NULLCHECK_TWO(selector, pCallback);
+
+        *pCallback = selector->matchCallback;
+
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
+ *      (see comments in pkix_certsel.h)
+ */
+PKIX_Error *
+PKIX_CertSelector_GetCertSelectorContext(
+        PKIX_CertSelector *selector,
+        PKIX_PL_Object **pCertSelectorContext,
+        void *plContext)
+{
+        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetCertSelectorContext");
+        PKIX_NULLCHECK_TWO(selector, pCertSelectorContext);
+
+        PKIX_INCREF(selector->context);
+
+        *pCertSelectorContext = selector->context;
+
+cleanup:
+        PKIX_RETURN(CERTSELECTOR);
+}
+
+/*
+ * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
+ *      (see comments in pkix_certsel.h)
+ */
+PKIX_Error *
+PKIX_CertSelector_GetCommonCertSelectorParams(
+        PKIX_CertSelector *selector,
+        PKIX_ComCertSelParams **pParams,
+        void *plContext)
+{
+        PKIX_ENTER(CERTSELECTOR,
+                    "PKIX_CertSelector_GetCommonCertSelectorParams");
+
+        PKIX_NULLCHECK_TWO(selector, pParams);
+
+        PKIX_INCREF(selector->params);
+        *pParams = selector->params;
+
+cleanup:
+        PKIX_RETURN(CERTSELECTOR);
+
+}
+
+/*
+ * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
+ *      (see comments in pkix_certsel.h)
+ */
+PKIX_Error *
+PKIX_CertSelector_SetCommonCertSelectorParams(
+        PKIX_CertSelector *selector,
+        PKIX_ComCertSelParams *params,
+        void *plContext)
+{
+        PKIX_ENTER(CERTSELECTOR,
+                    "PKIX_CertSelector_SetCommonCertSelectorParams");
+
+        PKIX_NULLCHECK_ONE(selector);
+
+        PKIX_DECREF(selector->params);
+        PKIX_INCREF(params);
+        selector->params = params;
+
+        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
+                    ((PKIX_PL_Object *)selector, plContext),
+                    PKIX_OBJECTINVALIDATECACHEFAILED);
+
+cleanup:
+
+        PKIX_RETURN(CERTSELECTOR);
+
+}
+
+/*
+ * FUNCTION: pkix_CertSelector_Select
+ * DESCRIPTION:
+ *
+ *  This function applies the selector pointed to by "selector" to each Cert,
+ *  in turn, in the List pointed to by "before", and creates a List containing
+ *  all the Certs that matched, or passed the selection process, storing that
+ *  List at "pAfter". If no Certs match, an empty List is stored at "pAfter".
+ *
+ *  The List returned in "pAfter" is immutable.
+ *
+ * PARAMETERS:
+ *  "selector"
+ *      Address of CertSelelector to be applied to the List. Must be non-NULL.
+ *  "before"
+ *      Address of List that is to be filtered. Must be non-NULL.
+ *  "pAfter"
+ *      Address at which resulting List, possibly empty, is stored. Must be
+ *      non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CertSelector Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_CertSelector_Select(
+	PKIX_CertSelector *selector,
+	PKIX_List *before,
+	PKIX_List **pAfter,
+	void *plContext)
+{
+	PKIX_UInt32 numBefore = 0;
+	PKIX_UInt32 i = 0;
+	PKIX_List *filtered = NULL;
+	PKIX_PL_Cert *candidate = NULL;
+
+        PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Select");
+        PKIX_NULLCHECK_THREE(selector, before, pAfter);
+
+        PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
+                PKIX_LISTCREATEFAILED);
+
+        PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
+                PKIX_LISTGETLENGTHFAILED);
+
+        for (i = 0; i < numBefore; i++) {
+
+                PKIX_CHECK(PKIX_List_GetItem
+                        (before, i, (PKIX_PL_Object **)&candidate, plContext),
+                        PKIX_LISTGETITEMFAILED);
+
+                PKIX_CHECK_ONLY_FATAL(selector->matchCallback
+                        (selector, candidate, plContext),
+                        PKIX_CERTSELECTORMATCHCALLBACKFAILED);
+
+                if (!(PKIX_ERROR_RECEIVED)) {
+
+                        PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
+                                (filtered,
+                                (PKIX_PL_Object *)candidate,
+                                plContext),
+                                PKIX_LISTAPPENDITEMFAILED);
+                }
+
+                pkixTempErrorReceived = PKIX_FALSE;
+                PKIX_DECREF(candidate);
+        }
+
+        PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
+                PKIX_LISTSETIMMUTABLEFAILED);
+
+        /* Don't throw away the list if one Cert was bad! */
+        pkixTempErrorReceived = PKIX_FALSE;
+
+        *pAfter = filtered;
+        filtered = NULL;
+
+cleanup:
+
+        PKIX_DECREF(filtered);
+        PKIX_DECREF(candidate);
+
+        PKIX_RETURN(CERTSELECTOR);
+
+}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)