| /* 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); |
| |
| } |