/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the PKIX-C library. * * The Initial Developer of the Original Code is * Sun Microsystems, Inc. * Portions created by the Initial Developer are * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. * * Contributor(s): * Sun Microsystems, Inc. * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * 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; goto cleanup; } 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) { PKIX_CERTSELECTOR_DEBUG ("Certificate has no acceptable policies\n"); *pResult = PKIX_FALSE; goto cleanup; } } } 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: 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) { PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints (cert, nameConstraints, plContext), PKIX_CERTCHECKNAMECONSTRAINTSFAILED); } cleanup: 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) { PKIX_CERTSELECTOR_DEBUG("PathToName Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } } 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) { 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) { PKIX_CERTSELECTOR_DEBUG("SubjAltName Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { PKIX_CERTSELECTOR_DEBUG ("SubjAltName Match failed: Cert has no SubjAltName\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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) { PKIX_CERTSELECTOR_DEBUG ("Extended Key Usage Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } } 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: 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, 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) { PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)selSubjKeyId, (PKIX_PL_Object *)certSubjKeyId, &equals, plContext), PKIX_OBJECTEQUALSFAILED); if (equals != PKIX_TRUE) { PKIX_CERTSELECTOR_DEBUG("SubjKeyId Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { PKIX_CERTSELECTOR_DEBUG ("SubjKeyId Match failed: Cert has no SubjKeyId\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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) { PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)selAuthKeyId, (PKIX_PL_Object *)certAuthKeyId, &equals, plContext), PKIX_OBJECTEQUALSFAILED); if (equals != PKIX_TRUE) { PKIX_CERTSELECTOR_DEBUG("AuthKeyId Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { PKIX_CERTSELECTOR_DEBUG ("AuthKeyId Match failed: Cert has no AuthKeyId\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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) { PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)selPKAlgId, (PKIX_PL_Object *)certPKAlgId, &equals, plContext), PKIX_OBJECTEQUALSFAILED); if (equals != PKIX_TRUE) { PKIX_CERTSELECTOR_DEBUG ("SubjPKAlgId Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { PKIX_CERTSELECTOR_DEBUG ("SubjPKAlgId Match failed: Cert has no SubjPKAlgId\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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) { PKIX_CHECK(PKIX_PL_Object_Equals ((PKIX_PL_Object *)selPK, (PKIX_PL_Object *)certPK, &equals, plContext), PKIX_OBJECTEQUALSFAILED); if (equals != PKIX_TRUE) { PKIX_CERTSELECTOR_DEBUG ("Subject Public Key Match failed\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { PKIX_CERTSELECTOR_DEBUG ("SubjPubKey Match failed: Cert has no SubjPubKey\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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 satisfies the CertSelector's criteria, PKIX_TRUE * is stored at "pResult". If the Cert does not match the CertSelector's * criteria, PKIX_FALSE is stored at "pResult". * * 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. * "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_DefaultMatch( PKIX_CertSelector *selector, PKIX_PL_Cert *cert, PKIX_Boolean *pResult, 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 requiredKeyUsage = 0; PKIX_UInt32 selVersion = 0xFFFFFFFF; PKIX_UInt32 certVersion = 0; PKIX_Boolean result = 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_THREE(selector, cert, pResult); *pResult = PKIX_TRUE; PKIX_INCREF(selector->params); params = selector->params; 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_CERTSELECTOR_DEBUG("Version Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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_CERTSELECTOR_DEBUG ("Subject Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } else { /* cert has no subject */ PKIX_CERTSELECTOR_DEBUG("Subject Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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_CERTSELECTOR_DEBUG("Issuer Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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_CERTSELECTOR_DEBUG("Serial Number Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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_CERTSELECTOR_DEBUG("Certificate Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } } 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_ComCertSelParams_GetKeyUsage (params, &requiredKeyUsage, plContext), PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED); if (requiredKeyUsage != 0) { PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage (cert, requiredKeyUsage, plContext), PKIX_CERTVERIFYKEYUSAGEFAILED); } PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("BasicConstraint Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_Policies (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHPOLICIESFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("Policies Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_CertificateValid (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("CertificateValid Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_NameConstraints (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("NameConstraints Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_PathToNames (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHPATHTONAMESFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("PathToNames Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("SubjAltNames Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("ExtendedKeyUsage Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_KeyUsage (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHKEYUSAGEFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("KeyUsage Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("SubjKeyId Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("AuthKeyId Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("SubjPKAlgId Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey (params, cert, &result, plContext), PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED); if (result == PKIX_FALSE){ PKIX_CERTSELECTOR_DEBUG("SubjPubKey Match FAILED\n"); *pResult = PKIX_FALSE; goto cleanup; } /* 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_Boolean match = PKIX_FALSE; 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, &match, plContext), PKIX_CERTSELECTORMATCHCALLBACKFAILED); if ((!(PKIX_ERROR_RECEIVED)) && (match == PKIX_TRUE)) { 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); }