michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * pkix_crlselector.c michael@0: * michael@0: * CRLSelector Function Definitions michael@0: * michael@0: */ michael@0: michael@0: #include "pkix_crlselector.h" michael@0: michael@0: /* --CRLSelector Private-Functions-------------------------------------- */ michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_Destroy michael@0: * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_Destroy( michael@0: PKIX_PL_Object *object, michael@0: void *plContext) michael@0: { michael@0: PKIX_CRLSelector *selector = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Destroy"); michael@0: PKIX_NULLCHECK_ONE(object); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext), michael@0: PKIX_OBJECTNOTCRLSELECTOR); michael@0: michael@0: selector = (PKIX_CRLSelector *)object; michael@0: michael@0: selector->matchCallback = NULL; michael@0: michael@0: PKIX_DECREF(selector->params); michael@0: PKIX_DECREF(selector->context); michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_ToString_Helper michael@0: * michael@0: * DESCRIPTION: michael@0: * Helper function that creates a string representation of CRLSelector michael@0: * pointed to by "crlParams" and stores its address in the object pointed to michael@0: * by "pString". michael@0: * michael@0: * PARAMETERS michael@0: * "list" michael@0: * Address of CRLSelector whose string representation is desired. michael@0: * Must be non-NULL. michael@0: * "pString" michael@0: * Address of object pointer's destination. Must be non-NULL. michael@0: * "plContext" - Platform-specific context pointer. michael@0: * michael@0: * THREAD SAFETY: michael@0: * Conditionally Thread Safe michael@0: * (see Thread Safety Definitions in Programmer's Guide) michael@0: * michael@0: * RETURNS: michael@0: * Returns NULL if the function succeeds. michael@0: * Returns a CRLSelector Error if the function fails in a non-fatal way. michael@0: * Returns a Fatal Error if the function fails in an unrecoverable way. michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_ToString_Helper( michael@0: PKIX_CRLSelector *crlSelector, michael@0: PKIX_PL_String **pString, michael@0: void *plContext) michael@0: { michael@0: PKIX_PL_String *crlSelectorString = NULL; michael@0: PKIX_PL_String *formatString = NULL; michael@0: PKIX_PL_String *crlParamsString = NULL; michael@0: PKIX_PL_String *crlContextString = NULL; michael@0: char *asciiFormat = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_ToString_Helper"); michael@0: PKIX_NULLCHECK_TWO(crlSelector, pString); michael@0: PKIX_NULLCHECK_ONE(crlSelector->params); michael@0: michael@0: asciiFormat = michael@0: "\n\t[\n" michael@0: "\tMatchCallback: 0x%x\n" michael@0: "\tParams: %s\n" michael@0: "\tContext: %s\n" michael@0: "\t]\n"; michael@0: michael@0: PKIX_CHECK(PKIX_PL_String_Create michael@0: (PKIX_ESCASCII, michael@0: asciiFormat, michael@0: 0, michael@0: &formatString, michael@0: plContext), michael@0: PKIX_STRINGCREATEFAILED); michael@0: michael@0: /* Params */ michael@0: PKIX_TOSTRING michael@0: ((PKIX_PL_Object *)crlSelector->params, michael@0: &crlParamsString, michael@0: plContext, michael@0: PKIX_COMCRLSELPARAMSTOSTRINGFAILED); michael@0: michael@0: /* Context */ michael@0: PKIX_TOSTRING(crlSelector->context, &crlContextString, plContext, michael@0: PKIX_LISTTOSTRINGFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Sprintf michael@0: (&crlSelectorString, michael@0: plContext, michael@0: formatString, michael@0: crlSelector->matchCallback, michael@0: crlParamsString, michael@0: crlContextString), michael@0: PKIX_SPRINTFFAILED); michael@0: michael@0: *pString = crlSelectorString; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(crlParamsString); michael@0: PKIX_DECREF(crlContextString); michael@0: PKIX_DECREF(formatString); michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_ToString michael@0: * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_ToString( michael@0: PKIX_PL_Object *object, michael@0: PKIX_PL_String **pString, michael@0: void *plContext) michael@0: { michael@0: PKIX_PL_String *crlSelectorString = NULL; michael@0: PKIX_CRLSelector *crlSelector = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_ToString"); michael@0: PKIX_NULLCHECK_TWO(object, pString); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext), michael@0: PKIX_OBJECTNOTCRLSELECTOR); michael@0: michael@0: crlSelector = (PKIX_CRLSelector *) object; michael@0: michael@0: PKIX_CHECK(pkix_CRLSelector_ToString_Helper michael@0: (crlSelector, &crlSelectorString, plContext), michael@0: PKIX_CRLSELECTORTOSTRINGHELPERFAILED); michael@0: michael@0: *pString = crlSelectorString; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_Hashcode michael@0: * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_Hashcode( michael@0: PKIX_PL_Object *object, michael@0: PKIX_UInt32 *pHashcode, michael@0: void *plContext) michael@0: { michael@0: PKIX_UInt32 paramsHash = 0; michael@0: PKIX_UInt32 contextHash = 0; michael@0: PKIX_UInt32 hash = 0; michael@0: michael@0: PKIX_CRLSelector *crlSelector = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Hashcode"); michael@0: PKIX_NULLCHECK_TWO(object, pHashcode); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext), michael@0: PKIX_OBJECTNOTCRLSELECTOR); michael@0: michael@0: crlSelector = (PKIX_CRLSelector *)object; michael@0: michael@0: PKIX_HASHCODE(crlSelector->params, ¶msHash, plContext, michael@0: PKIX_OBJECTHASHCODEFAILED); michael@0: michael@0: PKIX_HASHCODE(crlSelector->context, &contextHash, plContext, michael@0: PKIX_OBJECTHASHCODEFAILED); michael@0: michael@0: hash = 31 * ((PKIX_UInt32)crlSelector->matchCallback + michael@0: (contextHash << 3)) + paramsHash; michael@0: michael@0: *pHashcode = hash; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_Equals michael@0: * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_Equals( michael@0: PKIX_PL_Object *firstObject, michael@0: PKIX_PL_Object *secondObject, michael@0: PKIX_Boolean *pResult, michael@0: void *plContext) michael@0: { michael@0: PKIX_CRLSelector *firstCrlSelector = NULL; michael@0: PKIX_CRLSelector *secondCrlSelector = NULL; michael@0: PKIX_UInt32 secondType; michael@0: PKIX_Boolean cmpResult = PKIX_FALSE; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Equals"); michael@0: PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); michael@0: michael@0: /* test that firstObject is a CRLSelector */ michael@0: PKIX_CHECK(pkix_CheckType michael@0: (firstObject, PKIX_CRLSELECTOR_TYPE, plContext), michael@0: PKIX_FIRSTOBJECTNOTCRLSELECTOR); michael@0: michael@0: firstCrlSelector = (PKIX_CRLSelector *)firstObject; michael@0: secondCrlSelector = (PKIX_CRLSelector *)secondObject; michael@0: michael@0: /* michael@0: * Since we know firstObject is a CRLSelector, if both references are michael@0: * identical, they must be equal michael@0: */ michael@0: if (firstCrlSelector == secondCrlSelector){ michael@0: *pResult = PKIX_TRUE; michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* michael@0: * If secondCRLSelector isn't a CRLSelector, we don't throw an error. michael@0: * We simply return a Boolean result of FALSE michael@0: */ michael@0: *pResult = PKIX_FALSE; michael@0: PKIX_CHECK(PKIX_PL_Object_GetType michael@0: ((PKIX_PL_Object *)secondCrlSelector, michael@0: &secondType, michael@0: plContext), michael@0: PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); michael@0: michael@0: if (secondType != PKIX_CRLSELECTOR_TYPE) { michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* Compare MatchCallback address */ michael@0: cmpResult = (firstCrlSelector->matchCallback == michael@0: secondCrlSelector->matchCallback); michael@0: michael@0: if (cmpResult == PKIX_FALSE) { michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* Compare Common CRL Selector Params */ michael@0: PKIX_EQUALS michael@0: (firstCrlSelector->params, michael@0: secondCrlSelector->params, michael@0: &cmpResult, michael@0: plContext, michael@0: PKIX_COMCRLSELPARAMSEQUALSFAILED); michael@0: michael@0: michael@0: if (cmpResult == PKIX_FALSE) { michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* Compare Context */ michael@0: PKIX_EQUALS michael@0: (firstCrlSelector->context, michael@0: secondCrlSelector->context, michael@0: &cmpResult, michael@0: plContext, michael@0: PKIX_COMCRLSELPARAMSEQUALSFAILED); michael@0: michael@0: *pResult = cmpResult; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_Duplicate michael@0: * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_Duplicate( michael@0: PKIX_PL_Object *object, michael@0: PKIX_PL_Object **pNewObject, michael@0: void *plContext) michael@0: { michael@0: PKIX_CRLSelector *old; michael@0: PKIX_CRLSelector *new = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Duplicate"); michael@0: PKIX_NULLCHECK_TWO(object, pNewObject); michael@0: michael@0: PKIX_CHECK(pkix_CheckType michael@0: (object, PKIX_CRLSELECTOR_TYPE, plContext), michael@0: PKIX_OBJECTNOTCRLSELECTOR); michael@0: michael@0: old = (PKIX_CRLSelector *)object; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Alloc michael@0: (PKIX_CRLSELECTOR_TYPE, michael@0: (PKIX_UInt32)(sizeof (PKIX_CRLSelector)), michael@0: (PKIX_PL_Object **)&new, michael@0: plContext), michael@0: PKIX_CREATECRLSELECTORDUPLICATEOBJECTFAILED); michael@0: michael@0: new->matchCallback = old->matchCallback; michael@0: michael@0: PKIX_DUPLICATE(old->params, &new->params, plContext, michael@0: PKIX_OBJECTDUPLICATEPARAMSFAILED); michael@0: michael@0: PKIX_DUPLICATE(old->context, &new->context, plContext, michael@0: PKIX_OBJECTDUPLICATECONTEXTFAILED); michael@0: michael@0: *pNewObject = (PKIX_PL_Object *)new; michael@0: michael@0: cleanup: michael@0: michael@0: if (PKIX_ERROR_RECEIVED){ michael@0: PKIX_DECREF(new); michael@0: } michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_DefaultMatch michael@0: * michael@0: * DESCRIPTION: michael@0: * This function compares the parameter values (Issuer, date, and CRL number) michael@0: * set in the ComCRLSelParams of the CRLSelector pointed to by "selector" with michael@0: * the corresponding values in the CRL pointed to by "crl". When all the michael@0: * criteria set in the parameter values match the values in "crl", PKIX_TRUE is michael@0: * stored at "pMatch". If the CRL does not match the CRLSelector's criteria, michael@0: * PKIX_FALSE is stored at "pMatch". michael@0: * michael@0: * PARAMETERS michael@0: * "selector" michael@0: * Address of CRLSelector which is verified for a match michael@0: * Must be non-NULL. michael@0: * "crl" michael@0: * Address of the CRL object to be verified. Must be non-NULL. michael@0: * "pMatch" michael@0: * Address at which Boolean result is stored. Must be non-NULL. michael@0: * "plContext" michael@0: * Platform-specific context pointer. michael@0: * michael@0: * THREAD SAFETY: michael@0: * Conditionally Thread Safe michael@0: * (see Thread Safety Definitions in Programmer's Guide) michael@0: * michael@0: * RETURNS: michael@0: * Returns NULL if the function succeeds. michael@0: * Returns a CRLSelector Error if the function fails in a non-fatal way. michael@0: * Returns a Fatal Error if the function fails in an unrecoverable way. michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_CRLSelector_DefaultMatch( michael@0: PKIX_CRLSelector *selector, michael@0: PKIX_PL_CRL *crl, michael@0: PKIX_Boolean *pMatch, michael@0: void *plContext) michael@0: { michael@0: PKIX_ComCRLSelParams *params = NULL; michael@0: PKIX_PL_X500Name *crlIssuerName = NULL; michael@0: PKIX_PL_X500Name *issuerName = NULL; michael@0: PKIX_List *selIssuerNames = NULL; michael@0: PKIX_PL_Date *selDate = NULL; michael@0: PKIX_Boolean result = PKIX_TRUE; michael@0: PKIX_UInt32 numIssuers = 0; michael@0: PKIX_UInt32 i; michael@0: PKIX_PL_BigInt *minCRLNumber = NULL; michael@0: PKIX_PL_BigInt *maxCRLNumber = NULL; michael@0: PKIX_PL_BigInt *crlNumber = NULL; michael@0: PKIX_Boolean nistPolicyEnabled = PKIX_FALSE; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_DefaultMatch"); michael@0: PKIX_NULLCHECK_TWO(selector, crl); michael@0: michael@0: *pMatch = PKIX_TRUE; michael@0: params = selector->params; michael@0: michael@0: /* No matching parameter provided, just a match */ michael@0: if (params == NULL) { michael@0: goto cleanup; michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames michael@0: (params, &selIssuerNames, plContext), michael@0: PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED); michael@0: michael@0: /* Check for Issuers */ michael@0: if (selIssuerNames != NULL){ michael@0: michael@0: result = PKIX_FALSE; michael@0: michael@0: PKIX_CHECK(PKIX_PL_CRL_GetIssuer michael@0: (crl, &crlIssuerName, plContext), michael@0: PKIX_CRLGETISSUERFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_List_GetLength michael@0: (selIssuerNames, &numIssuers, plContext), michael@0: PKIX_LISTGETLENGTHFAILED); michael@0: michael@0: for (i = 0; i < numIssuers; i++){ michael@0: michael@0: PKIX_CHECK(PKIX_List_GetItem michael@0: (selIssuerNames, michael@0: i, michael@0: (PKIX_PL_Object **)&issuerName, michael@0: plContext), michael@0: PKIX_LISTGETITEMFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_X500Name_Match michael@0: (crlIssuerName, michael@0: issuerName, michael@0: &result, michael@0: plContext), michael@0: PKIX_X500NAMEMATCHFAILED); michael@0: michael@0: PKIX_DECREF(issuerName); michael@0: michael@0: if (result == PKIX_TRUE) { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (result == PKIX_FALSE) { michael@0: PKIX_CRLSELECTOR_DEBUG("Issuer Match Failed\N"); michael@0: *pMatch = PKIX_FALSE; michael@0: goto cleanup; michael@0: } michael@0: michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_ComCRLSelParams_GetDateAndTime michael@0: (params, &selDate, plContext), michael@0: PKIX_COMCRLSELPARAMSGETDATEANDTIMEFAILED); michael@0: michael@0: /* Check for Date */ michael@0: if (selDate != NULL){ michael@0: michael@0: PKIX_CHECK(PKIX_ComCRLSelParams_GetNISTPolicyEnabled michael@0: (params, &nistPolicyEnabled, plContext), michael@0: PKIX_COMCRLSELPARAMSGETNISTPOLICYENABLEDFAILED); michael@0: michael@0: /* check crl dates only for if NIST policies enforced */ michael@0: if (nistPolicyEnabled) { michael@0: result = PKIX_FALSE; michael@0: michael@0: PKIX_CHECK(PKIX_PL_CRL_VerifyUpdateTime michael@0: (crl, selDate, &result, plContext), michael@0: PKIX_CRLVERIFYUPDATETIMEFAILED); michael@0: michael@0: if (result == PKIX_FALSE) { michael@0: *pMatch = PKIX_FALSE; michael@0: goto cleanup; michael@0: } michael@0: } michael@0: michael@0: } michael@0: michael@0: /* Check for CRL number in range */ michael@0: PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber(crl, &crlNumber, plContext), michael@0: PKIX_CRLGETCRLNUMBERFAILED); michael@0: michael@0: if (crlNumber != NULL) { michael@0: result = PKIX_FALSE; michael@0: michael@0: PKIX_CHECK(PKIX_ComCRLSelParams_GetMinCRLNumber michael@0: (params, &minCRLNumber, plContext), michael@0: PKIX_COMCRLSELPARAMSGETMINCRLNUMBERFAILED); michael@0: michael@0: if (minCRLNumber != NULL) { michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Compare michael@0: ((PKIX_PL_Object *)minCRLNumber, michael@0: (PKIX_PL_Object *)crlNumber, michael@0: &result, michael@0: plContext), michael@0: PKIX_OBJECTCOMPARATORFAILED); michael@0: michael@0: if (result == 1) { michael@0: PKIX_CRLSELECTOR_DEBUG michael@0: ("CRL MinNumber Range Match Failed\n"); michael@0: *pMatch = PKIX_FALSE; michael@0: goto cleanup; michael@0: } michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_ComCRLSelParams_GetMaxCRLNumber michael@0: (params, &maxCRLNumber, plContext), michael@0: PKIX_COMCRLSELPARAMSGETMAXCRLNUMBERFAILED); michael@0: michael@0: if (maxCRLNumber != NULL) { michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Compare michael@0: ((PKIX_PL_Object *)crlNumber, michael@0: (PKIX_PL_Object *)maxCRLNumber, michael@0: &result, michael@0: plContext), michael@0: PKIX_OBJECTCOMPARATORFAILED); michael@0: michael@0: if (result == 1) { michael@0: PKIX_CRLSELECTOR_DEBUG michael@0: (PKIX_CRLMAXNUMBERRANGEMATCHFAILED); michael@0: *pMatch = PKIX_FALSE; michael@0: goto cleanup; michael@0: } michael@0: } michael@0: } michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(selIssuerNames); michael@0: PKIX_DECREF(selDate); michael@0: PKIX_DECREF(crlIssuerName); michael@0: PKIX_DECREF(issuerName); michael@0: PKIX_DECREF(crlNumber); michael@0: PKIX_DECREF(minCRLNumber); michael@0: PKIX_DECREF(maxCRLNumber); michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_RegisterSelf michael@0: * DESCRIPTION: michael@0: * Registers PKIX_CRLSELECTOR_TYPE and its related functions with michael@0: * systemClasses[] michael@0: * THREAD SAFETY: michael@0: * Not Thread Safe - for performance and complexity reasons michael@0: * michael@0: * Since this function is only called by PKIX_PL_Initialize, which should michael@0: * only be called once, it is acceptable that this function is not michael@0: * thread-safe. michael@0: */ michael@0: PKIX_Error * michael@0: pkix_CRLSelector_RegisterSelf(void *plContext) michael@0: { michael@0: extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; michael@0: pkix_ClassTable_Entry entry; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_RegisterSelf"); michael@0: michael@0: entry.description = "CRLSelector"; michael@0: entry.objCounter = 0; michael@0: entry.typeObjectSize = sizeof(PKIX_CRLSelector); michael@0: entry.destructor = pkix_CRLSelector_Destroy; michael@0: entry.equalsFunction = pkix_CRLSelector_Equals; michael@0: entry.hashcodeFunction = pkix_CRLSelector_Hashcode; michael@0: entry.toStringFunction = pkix_CRLSelector_ToString; michael@0: entry.comparator = NULL; michael@0: entry.duplicateFunction = pkix_CRLSelector_Duplicate; michael@0: michael@0: systemClasses[PKIX_CRLSELECTOR_TYPE] = entry; michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* --CRLSelector-Public-Functions---------------------------------------- */ michael@0: PKIX_Error * michael@0: pkix_CRLSelector_Create( michael@0: PKIX_CRLSelector_MatchCallback callback, michael@0: PKIX_PL_Object *crlSelectorContext, michael@0: PKIX_CRLSelector **pSelector, michael@0: void *plContext) michael@0: { michael@0: PKIX_CRLSelector *selector = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_Create"); michael@0: PKIX_NULLCHECK_ONE(pSelector); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Alloc michael@0: (PKIX_CRLSELECTOR_TYPE, michael@0: sizeof (PKIX_CRLSelector), michael@0: (PKIX_PL_Object **)&selector, michael@0: plContext), michael@0: PKIX_COULDNOTCREATECRLSELECTOROBJECT); michael@0: michael@0: /* michael@0: * if user specified a particular match callback, we use that one. michael@0: * otherwise, we use the default match provided. michael@0: */ michael@0: michael@0: if (callback != NULL){ michael@0: selector->matchCallback = callback; michael@0: } else { michael@0: selector->matchCallback = pkix_CRLSelector_DefaultMatch; michael@0: } michael@0: michael@0: /* initialize other fields */ michael@0: selector->params = NULL; michael@0: michael@0: PKIX_INCREF(crlSelectorContext); michael@0: selector->context = crlSelectorContext; michael@0: michael@0: *pSelector = selector; michael@0: selector = NULL; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(selector); michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_CRLSelector_Create (see comments in pkix_crlsel.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_CRLSelector_Create( michael@0: PKIX_PL_Cert *issuer, michael@0: PKIX_List *crldpList, michael@0: PKIX_PL_Date *date, michael@0: PKIX_CRLSelector **pCrlSelector, michael@0: void *plContext) michael@0: { michael@0: PKIX_PL_X500Name *issuerName = NULL; michael@0: PKIX_PL_Date *nowDate = NULL; michael@0: PKIX_ComCRLSelParams *comCrlSelParams = NULL; michael@0: PKIX_CRLSelector *crlSelector = NULL; michael@0: michael@0: PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CrlSelector_Create"); michael@0: PKIX_NULLCHECK_ONE(issuer); michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_PL_Cert_GetSubject(issuer, &issuerName, plContext), michael@0: PKIX_CERTGETISSUERFAILED); michael@0: michael@0: if (date != NULL) { michael@0: PKIX_INCREF(date); michael@0: nowDate = date; michael@0: } else { michael@0: PKIX_CHECK( michael@0: PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext), michael@0: PKIX_DATECREATEUTCTIMEFAILED); michael@0: } michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_ComCRLSelParams_Create(&comCrlSelParams, plContext), michael@0: PKIX_COMCRLSELPARAMSCREATEFAILED); michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_ComCRLSelParams_AddIssuerName(comCrlSelParams, issuerName, michael@0: plContext), michael@0: PKIX_COMCRLSELPARAMSADDISSUERNAMEFAILED); michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_ComCRLSelParams_SetCrlDp(comCrlSelParams, crldpList, michael@0: plContext), michael@0: PKIX_COMCRLSELPARAMSSETCERTFAILED); michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_ComCRLSelParams_SetDateAndTime(comCrlSelParams, nowDate, michael@0: plContext), michael@0: PKIX_COMCRLSELPARAMSSETDATEANDTIMEFAILED); michael@0: michael@0: PKIX_CHECK( michael@0: pkix_CRLSelector_Create(NULL, NULL, &crlSelector, plContext), michael@0: PKIX_CRLSELECTORCREATEFAILED); michael@0: michael@0: PKIX_CHECK( michael@0: PKIX_CRLSelector_SetCommonCRLSelectorParams(crlSelector, michael@0: comCrlSelParams, michael@0: plContext), michael@0: PKIX_CRLSELECTORSETCOMMONCRLSELECTORPARAMSFAILED); michael@0: michael@0: *pCrlSelector = crlSelector; michael@0: crlSelector = NULL; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(issuerName); michael@0: PKIX_DECREF(nowDate); michael@0: PKIX_DECREF(comCrlSelParams); michael@0: PKIX_DECREF(crlSelector); michael@0: michael@0: PKIX_RETURN(CERTCHAINCHECKER); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_CRLSelector_GetMatchCallback (see comments in pkix_crlsel.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_CRLSelector_GetMatchCallback( michael@0: PKIX_CRLSelector *selector, michael@0: PKIX_CRLSelector_MatchCallback *pCallback, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetMatchCallback"); michael@0: PKIX_NULLCHECK_TWO(selector, pCallback); michael@0: michael@0: *pCallback = selector->matchCallback; michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_CRLSelector_GetCRLSelectorContext michael@0: * (see comments in pkix_crlsel.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_CRLSelector_GetCRLSelectorContext( michael@0: PKIX_CRLSelector *selector, michael@0: void **pCrlSelectorContext, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetCRLSelectorContext"); michael@0: PKIX_NULLCHECK_TWO(selector, pCrlSelectorContext); michael@0: michael@0: PKIX_INCREF(selector->context); michael@0: michael@0: *pCrlSelectorContext = selector->context; michael@0: michael@0: cleanup: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_CRLSelector_GetCommonCRLSelectorParams michael@0: * (see comments in pkix_crlsel.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_CRLSelector_GetCommonCRLSelectorParams( michael@0: PKIX_CRLSelector *selector, michael@0: PKIX_ComCRLSelParams **pParams, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetCommonCRLSelectorParams"); michael@0: PKIX_NULLCHECK_TWO(selector, pParams); michael@0: michael@0: PKIX_INCREF(selector->params); michael@0: michael@0: *pParams = selector->params; michael@0: michael@0: cleanup: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_CRLSelector_SetCommonCRLSelectorParams michael@0: * (see comments in pkix_crlsel.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_CRLSelector_SetCommonCRLSelectorParams( michael@0: PKIX_CRLSelector *selector, michael@0: PKIX_ComCRLSelParams *params, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_SetCommonCRLSelectorParams"); michael@0: PKIX_NULLCHECK_TWO(selector, params); michael@0: michael@0: PKIX_DECREF(selector->params); michael@0: michael@0: PKIX_INCREF(params); michael@0: selector->params = params; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_InvalidateCache michael@0: ((PKIX_PL_Object *)selector, plContext), michael@0: PKIX_OBJECTINVALIDATECACHEFAILED); michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_CRLSelector_Select michael@0: * DESCRIPTION: michael@0: * michael@0: * This function applies the selector pointed to by "selector" to each CRL, michael@0: * in turn, in the List pointed to by "before", and creates a List containing michael@0: * all the CRLs that matched, or passed the selection process, storing that michael@0: * List at "pAfter". If no CRLs match, an empty List is stored at "pAfter". michael@0: * michael@0: * The List returned in "pAfter" is immutable. michael@0: * michael@0: * PARAMETERS: michael@0: * "selector" michael@0: * Address of CRLSelelector to be applied to the List. Must be non-NULL. michael@0: * "before" michael@0: * Address of List that is to be filtered. Must be non-NULL. michael@0: * "pAfter" michael@0: * Address at which resulting List, possibly empty, is stored. Must be michael@0: * non-NULL. michael@0: * "plContext" michael@0: * Platform-specific context pointer. michael@0: * THREAD SAFETY: michael@0: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) michael@0: * RETURNS: michael@0: * Returns NULL if the function succeeds. michael@0: * Returns a CRLSelector Error if the function fails in a non-fatal way. michael@0: * Returns a Fatal Error if the function fails in an unrecoverable way. michael@0: */ michael@0: PKIX_Error * michael@0: pkix_CRLSelector_Select( michael@0: PKIX_CRLSelector *selector, michael@0: PKIX_List *before, michael@0: PKIX_List **pAfter, michael@0: void *plContext) michael@0: { michael@0: PKIX_Boolean match = PKIX_FALSE; michael@0: PKIX_UInt32 numBefore = 0; michael@0: PKIX_UInt32 i = 0; michael@0: PKIX_List *filtered = NULL; michael@0: PKIX_PL_CRL *candidate = NULL; michael@0: michael@0: PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_Select"); michael@0: PKIX_NULLCHECK_THREE(selector, before, pAfter); michael@0: michael@0: PKIX_CHECK(PKIX_List_Create(&filtered, plContext), michael@0: PKIX_LISTCREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext), michael@0: PKIX_LISTGETLENGTHFAILED); michael@0: michael@0: for (i = 0; i < numBefore; i++) { michael@0: michael@0: PKIX_CHECK(PKIX_List_GetItem michael@0: (before, i, (PKIX_PL_Object **)&candidate, plContext), michael@0: PKIX_LISTGETITEMFAILED); michael@0: michael@0: PKIX_CHECK_ONLY_FATAL(selector->matchCallback michael@0: (selector, candidate, &match, plContext), michael@0: PKIX_CRLSELECTORMATCHCALLBACKFAILED); michael@0: michael@0: if (!(PKIX_ERROR_RECEIVED) && match == PKIX_TRUE) { michael@0: michael@0: PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem michael@0: (filtered, michael@0: (PKIX_PL_Object *)candidate, michael@0: plContext), michael@0: PKIX_LISTAPPENDITEMFAILED); michael@0: } michael@0: michael@0: pkixTempErrorReceived = PKIX_FALSE; michael@0: PKIX_DECREF(candidate); michael@0: } michael@0: michael@0: PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext), michael@0: PKIX_LISTSETIMMUTABLEFAILED); michael@0: michael@0: /* Don't throw away the list if one CRL was bad! */ michael@0: pkixTempErrorReceived = PKIX_FALSE; michael@0: michael@0: *pAfter = filtered; michael@0: filtered = NULL; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(filtered); michael@0: PKIX_DECREF(candidate); michael@0: michael@0: PKIX_RETURN(CRLSELECTOR); michael@0: michael@0: }