Bug 418544 – Pathological OCSP inefficiency with libPKIX. Part two. r=nelson
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -1971,49 +1971,63 @@ cleanup:
static PKIX_Error *
pkix_Build_GatherCerts(
PKIX_ForwardBuilderState *state,
PKIX_ComCertSelParams *certSelParams,
void **pNBIOContext,
void *plContext)
{
PKIX_Boolean certStoreIsCached = PKIX_FALSE;
- PKIX_Boolean certStoreCanBeUsed = PKIX_FALSE;
+ PKIX_Boolean certStoreIsLocal = PKIX_FALSE;
PKIX_Boolean foundInCache = PKIX_FALSE;
+ PKIX_Boolean listIsEmpty = PKIX_FALSE;
PKIX_CertStore *certStore = NULL;
PKIX_CertStore_CertCallback getCerts = NULL;
PKIX_List *certsFound = NULL;
PKIX_List *sorted = NULL;
void *nbioContext = NULL;
PKIX_ENTER(BUILD, "pkix_Build_GatherCerts");
PKIX_NULLCHECK_THREE(state, certSelParams, pNBIOContext);
nbioContext = *pNBIOContext;
*pNBIOContext = NULL;
+ PKIX_CHECK(
+ PKIX_List_IsEmpty(state->candidateCerts, &listIsEmpty, plContext),
+ PKIX_LISTISEMPTYFAILED);
+
+ /* The caller is responsible to make sure that the list is empty */
+#ifdef UNDEF
+ /* I suspect that the list will not be empty. Commenting the assertion
+ * out for now. More work needs to be done for bug 418544 to clean up
+ * code related to candidateCerts list */
+ PORT_Assert(listIsEmpty);
+#endif
+ if (!listIsEmpty) {
+ PKIX_DECREF(state->candidateCerts);
+ PKIX_CHECK(PKIX_List_Create(&state->candidateCerts, plContext),
+ PKIX_LISTCREATEFAILED);
+ }
+
while (state->certStoreIndex < state->buildConstants.numCertStores) {
/* Get the current CertStore */
PKIX_CHECK(PKIX_List_GetItem
(state->buildConstants.certStores,
state->certStoreIndex,
(PKIX_PL_Object **)&certStore,
plContext),
PKIX_LISTGETITEMFAILED);
- if ((state->useOnlyLocal) == PKIX_FALSE) {
- certStoreCanBeUsed = PKIX_TRUE;
- } else {
- PKIX_CHECK(PKIX_CertStore_GetLocalFlag
- (certStore, &certStoreCanBeUsed, plContext),
- PKIX_CERTSTOREGETLOCALFLAGFAILED);
- }
-
- if (certStoreCanBeUsed == PKIX_TRUE) {
+ PKIX_CHECK(PKIX_CertStore_GetLocalFlag
+ (certStore, &certStoreIsLocal, plContext),
+ PKIX_CERTSTOREGETLOCALFLAGFAILED);
+
+ if (state->useOnlyLocal == certStoreIsLocal) {
/* If GATHERPENDING, we've already checked the cache */
if (state->status == BUILD_GATHERPENDING) {
certStoreIsCached = PKIX_FALSE;
foundInCache = PKIX_FALSE;
} else {
PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
(certStore, &certStoreIsCached, plContext),
PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
@@ -3347,17 +3361,17 @@ cleanup:
state->canBeCached = canBeCached;
PKIX_DECREF(state->validityDate);
state->validityDate = validityDate;
validityDate = NULL;
}
if (!*pValResult && !verifyError) {
if (finalError) {
pkixErrorResult = finalError;
- pkixErrorCode = finalError->errCode;
+ pkixErrorCode = PKIX_BUILDFORWARDDEPTHFIRSTSEARCHFAILED;
finalError = NULL;
goto fatal;
}
pkixErrorCode = PKIX_SECERRORUNKNOWNISSUER;
pkixErrorReceived = PKIX_TRUE;
} else {
pkixErrorResult = verifyError;
verifyError = NULL;