/* * FUNCTION: pkix_pl_LdapCertStore_GetCertContinue * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h) */ PKIX_Error * pkix_pl_LdapCertStore_GetCertContinue( PKIX_CertStore *store, PKIX_CertSelector *selector, PKIX_VerifyNode *verifyNode, void **pNBIOContext, PKIX_List **pCertList, void *plContext) { PKIX_Boolean cacheFlag = PKIX_FALSE; PKIX_PL_LdapCertStoreContext *lcs = NULL; void *pollDesc = NULL; PKIX_List *responses = NULL; PKIX_List *unfilteredCerts = NULL; PKIX_List *filteredCerts = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCertContinue"); PKIX_NULLCHECK_THREE(store, selector, pCertList); PKIX_CHECK(PKIX_CertStore_GetCertStoreContext (store, (PKIX_PL_Object **)&lcs, plContext), PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest ((PKIX_PL_LdapClient *)lcs, &pollDesc, &responses, plContext), PKIX_LDAPCLIENTRESUMEREQUESTFAILED); if (pollDesc != NULL) { /* client is waiting for non-blocking I/O to complete */ *pNBIOContext = (void *)pollDesc; *pCertList = NULL; goto cleanup; } /* LdapClient has given us a response! */ if (responses) { PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag (store, &cacheFlag, plContext), PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList (responses, &unfilteredCerts, plContext), PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED); PKIX_CHECK(pkix_CertSelector_Select (selector, unfilteredCerts, &filteredCerts, plContext), PKIX_CERTSELECTORSELECTFAILED); } *pNBIOContext = NULL; *pCertList = filteredCerts; cleanup: PKIX_DECREF(responses); PKIX_DECREF(unfilteredCerts); PKIX_DECREF(lcs); PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_pl_LdapCertStore_GetCert * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h) */ PKIX_Error * pkix_pl_LdapCertStore_GetCert( PKIX_CertStore *store, PKIX_CertSelector *selector, PKIX_VerifyNode *verifyNode, void **pNBIOContext, PKIX_List **pCertList, void *plContext) { PRArenaPool *requestArena = NULL; LDAPRequestParams requestParams; void *pollDesc = NULL; PKIX_Int32 minPathLen = 0; PKIX_Boolean cacheFlag = PKIX_FALSE; PKIX_ComCertSelParams *params = NULL; PKIX_PL_LdapCertStoreContext *lcs = NULL; PKIX_List *responses = NULL; PKIX_List *unfilteredCerts = NULL; PKIX_List *filteredCerts = NULL; PKIX_PL_X500Name *subjectName = 0; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCert"); PKIX_NULLCHECK_THREE(store, selector, pCertList); requestParams.baseObject = "c=US"; requestParams.scope = WHOLE_SUBTREE; requestParams.derefAliases = NEVER_DEREF; requestParams.sizeLimit = 0; requestParams.timeLimit = 0; /* Prepare elements for request filter */ /* * Get a short-lived arena. We'll be done with this space once * the request is encoded. */ requestArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!requestArena) { PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY); } PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams (selector, ¶ms, plContext), PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED); /* * If we have the subject name for the desired subject, * ask the server for Certs with that subject. */ PKIX_CHECK(PKIX_ComCertSelParams_GetSubject (params, &subjectName, plContext), PKIX_COMCERTSELPARAMSGETSUBJECTFAILED); PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints (params, &minPathLen, plContext), PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED); if (subjectName) { PKIX_CHECK(pkix_pl_LdapCertStore_MakeNameAVAList (requestArena, subjectName, &(requestParams.nc), plContext), PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED); if (*requestParams.nc == NULL) { /* * The subjectName may not include any components * that we know how to encode. We do not return * an error, because the caller did not necessarily * do anything wrong, but we return an empty List. */ PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (requestArena, PR_FALSE)); PKIX_CHECK(PKIX_List_Create(&filteredCerts, plContext), PKIX_LISTCREATEFAILED); PKIX_CHECK(PKIX_List_SetImmutable (filteredCerts, plContext), PKIX_LISTSETIMMUTABLEFAILED); *pNBIOContext = NULL; *pCertList = filteredCerts; filteredCerts = NULL; goto cleanup; } } else { PKIX_ERROR(PKIX_INSUFFICIENTCRITERIAFORCERTQUERY); } /* Prepare attribute field of request */ requestParams.attributes = 0; if (minPathLen < 0) { requestParams.attributes |= LDAPATTR_USERCERT; } if (minPathLen > -2) { requestParams.attributes |= LDAPATTR_CACERT | LDAPATTR_CROSSPAIRCERT; } /* All request fields are done */ PKIX_CHECK(PKIX_CertStore_GetCertStoreContext (store, (PKIX_PL_Object **)&lcs, plContext), PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED); PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest ((PKIX_PL_LdapClient *)lcs, &requestParams, &pollDesc, &responses, plContext), PKIX_LDAPCLIENTINITIATEREQUESTFAILED); PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList (requestParams.nc, plContext), PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED); if (requestArena) { PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (requestArena, PR_FALSE)); requestArena = NULL; } if (pollDesc != NULL) { /* client is waiting for non-blocking I/O to complete */ *pNBIOContext = (void *)pollDesc; *pCertList = NULL; goto cleanup; } /* LdapClient has given us a response! */ if (responses) { PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag (store, &cacheFlag, plContext), PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList (responses, &unfilteredCerts, plContext), PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED); PKIX_CHECK(pkix_CertSelector_Select (selector, unfilteredCerts, &filteredCerts, plContext), PKIX_CERTSELECTORSELECTFAILED); } *pNBIOContext = NULL; *pCertList = filteredCerts; filteredCerts = NULL; cleanup: PKIX_DECREF(params); PKIX_DECREF(subjectName); PKIX_DECREF(responses); PKIX_DECREF(unfilteredCerts); PKIX_DECREF(filteredCerts); PKIX_DECREF(lcs); PKIX_RETURN(CERTSTORE); }
/* * FUNCTION: pkix_DefaultCRLChecker_Check_Store * * DESCRIPTION: * Checks the certStore pointed to by "certStore" for a CRL that may determine * whether the Cert pointed to by "cert" has been revoked. * * PARAMETERS * "checker" * Address of CertChainChecker which has the state data. * Must be non-NULL. * "cert" * Address of Certificate that is to be validated. Must be non-NULL. * "prevPublicKey" * Address of previous public key in the backward chain. May be NULL. * "state" * Address of DefaultCrlCheckerState. Must be non-NULL. * "unresolvedCriticalExtensions" * A List OIDs. Not **yet** used in this checker function. * "certStore" * Address of the CertStore to be queried for a relevant CRL. Must be * non-NULL. * "pNBIOContext" * Address at which platform-dependent information is stored if processing * is suspended for non-blocking I/O. 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 DefaultCrlCheckerState Error if the function fails in a * non-fatal way. * Returns a Fatal Error */ static PKIX_Error * pkix_DefaultCRLChecker_Check_Store( PKIX_CertChainChecker *checker, PKIX_PL_Cert *cert, PKIX_PL_PublicKey *prevPublicKey, pkix_DefaultCRLCheckerState *state, PKIX_List *unresolvedCriticalExtensions, PKIX_CertStore *certStore, void **pNBIOContext, void *plContext) { PKIX_Boolean cacheFlag = PKIX_FALSE; PKIX_Boolean cacheHit = PKIX_FALSE; PKIX_UInt32 numEntries = 0; PKIX_UInt32 i = 0; PKIX_Int32 reasonCode = 0; PKIX_UInt32 allReasonCodes = 0; PKIX_List *crlList = NULL; PKIX_List *crlEntryList = NULL; PKIX_PL_CRLEntry *crlEntry = NULL; PKIX_Error *checkCrlFail = NULL; PKIX_CertStore_CRLCallback getCrls = NULL; void *nbioContext = NULL; PKIX_ENTER(CERTCHAINCHECKER, "pkix_DefaultCRLChecker_Check_Store"); PKIX_NULLCHECK_TWO(checker, cert); PKIX_NULLCHECK_THREE(state, certStore, pNBIOContext); nbioContext = *pNBIOContext; *pNBIOContext = NULL; /* Are this CertStore's entries in cache? */ PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag (certStore, &cacheFlag, plContext), PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED); if (cacheFlag) { PKIX_CHECK(pkix_CacheCrlEntry_Lookup (certStore, state->certIssuer, state->certSerialNumber, &cacheHit, &crlEntryList, plContext), PKIX_CACHECRLENTRYLOOKUPFAILED); } if (cacheHit) { /* Use cached data */ PKIX_CHECK(PKIX_List_GetLength (crlEntryList, &numEntries, plContext), PKIX_LISTGETLENGTHFAILED); for (i = 0; i < numEntries; i++) { PKIX_CHECK(PKIX_List_GetItem (crlEntryList, i, (PKIX_PL_Object **)&crlEntry, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode (crlEntry, &reasonCode, plContext), PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED); if (reasonCode >= 0) { if (reasonCode >= numReasonCodes) reasonCode = 0; allReasonCodes |= (1 << reasonCode); PKIX_DEFAULTCRLCHECKERSTATE_DEBUG_ARG ("CRL revocation Reason: %s\n ", reasonCodeMsgString[reasonCode]); } PKIX_DECREF(crlEntry); } state->reasonCodeMask |= allReasonCodes; if (allReasonCodes != 0) { PKIX_ERROR(PKIX_CERTIFICATEREVOKEDBYCRL); } PKIX_DECREF(crlEntryList); } else { if (nbioContext == NULL) { PKIX_CHECK(PKIX_CertStore_GetCRLCallback (certStore, &getCrls, plContext), PKIX_CERTSTOREGETCRLCALLBACKFAILED); PKIX_CHECK(getCrls (certStore, state->crlSelector, &nbioContext, &crlList, plContext), PKIX_GETCRLSFAILED); } else { PKIX_CHECK(PKIX_CertStore_CrlContinue (certStore, state->crlSelector, &nbioContext, &crlList, plContext), PKIX_CERTSTORECRLCONTINUEFAILED); } /* * Verify Certificate validity: if one CertStore provides * reason code, we stop here. Instead of exhausting all * CertStores to get all possible reason codes associated * with the Cert. May be expanded if desire otherwise. */ if (crlList == NULL) { *pNBIOContext = nbioContext; } else { *pNBIOContext = NULL; checkCrlFail = pkix_DefaultCRLChecker_CheckCRLs (cert, state->certIssuer, state->certSerialNumber, prevPublicKey, crlList, state, &crlEntryList, plContext); if (checkCrlFail) { if (crlEntryList != NULL) { /* Add to cache */ PKIX_CHECK(pkix_CacheCrlEntry_Add (certStore, state->certIssuer, state->certSerialNumber, crlEntryList, plContext), PKIX_CACHECRLENTRYADDFAILED); } PKIX_ERROR(PKIX_CERTIFICATEREVOKEDBYCRL); } } PKIX_DECREF(crlList); } cleanup: PKIX_DECREF(crlEntryList); PKIX_DECREF(crlEntry); PKIX_DECREF(crlList); PKIX_DECREF(checkCrlFail); PKIX_RETURN(CERTCHAINCHECKER); }