Index: mozilla/security/nss/lib/pki/trustdomain.c =================================================================== RCS file: /cvsroot/mozilla/security/nss/lib/pki/trustdomain.c,v retrieving revision 1.57 retrieving revision 1.58 diff -u -p -5 -r1.57 -r1.58 --- mozilla/security/nss/lib/pki/trustdomain.c 27 Apr 2008 02:13:47 -0000 1.57 +++ mozilla/security/nss/lib/pki/trustdomain.c 26 Jul 2008 02:52:03 -0000 1.58 @@ -436,19 +436,21 @@ nssTrustDomain_FindCertificatesByNicknam NSSCertificate *rvOpt[], PRUint32 maximumOpt, /* 0 for no max */ NSSArena *arenaOpt ) { - PRStatus status; - PRUint32 numRemaining; NSSToken *token = NULL; NSSSlot **slots = NULL; NSSSlot **slotp; NSSCertificate **rvCerts = NULL; nssPKIObjectCollection *collection = NULL; nssUpdateLevel updateLevel; nssList *nameList; + PRUint32 numRemaining = maximumOpt; + PRUint32 collectionCount = 0; + PRUint32 errors = 0; + /* First, grab from the cache */ nameList = nssList_Create(NULL, PR_FALSE); if (!nameList) { return NULL; } @@ -467,48 +469,51 @@ nssTrustDomain_FindCertificatesByNicknam slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); if (!slots) { goto loser; } /* iterate over the slots */ - numRemaining = maximumOpt; for (slotp = slots; *slotp; slotp++) { token = nssSlot_GetToken(*slotp); if (token) { nssSession *session; - nssCryptokiObject **instances; + nssCryptokiObject **instances = NULL; nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + PRStatus status = PR_FAILURE; + session = nssTrustDomain_GetSessionForToken(td, token); - if (!session) { - nssToken_Destroy(token); - goto loser; + if (session) { + instances = nssToken_FindCertificatesByNickname(token, + session, + name, + tokenOnly, + numRemaining, + &status); } - instances = nssToken_FindCertificatesByNickname(token, - session, - name, - tokenOnly, - numRemaining, - &status); nssToken_Destroy(token); if (status != PR_SUCCESS) { - goto loser; + errors++; + continue; } if (instances) { status = nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); if (status != PR_SUCCESS) { - goto loser; + errors++; + continue; } + collectionCount = nssPKIObjectCollection_Count(collection); if (maximumOpt > 0) { - PRUint32 count; - count = nssPKIObjectCollection_Count(collection); - numRemaining = maximumOpt - count; - if (numRemaining == 0) break; + if (collectionCount >= maximumOpt) + break; + numRemaining = maximumOpt - collectionCount; } } } } + if (!collectionCount && errors) + goto loser; /* Grab the certs collected in the search. */ rvCerts = nssPKIObjectCollection_GetCertificates(collection, rvOpt, maximumOpt, arenaOpt); /* clean up */ @@ -585,23 +590,25 @@ NSSTrustDomain_FindBestCertificateByNick NSS_IMPLEMENT NSSCertificate ** nssTrustDomain_FindCertificatesBySubject ( NSSTrustDomain *td, NSSDER *subject, NSSCertificate *rvOpt[], - PRUint32 maximumOpt, + PRUint32 maximumOpt, /* 0 for no max */ NSSArena *arenaOpt ) { - PRStatus status; - PRUint32 numRemaining; NSSToken *token = NULL; NSSSlot **slots = NULL; NSSSlot **slotp; NSSCertificate **rvCerts = NULL; nssPKIObjectCollection *collection = NULL; nssUpdateLevel updateLevel; nssList *subjectList; + PRUint32 numRemaining = maximumOpt; + PRUint32 collectionCount = 0; + PRUint32 errors = 0; + /* look in cache */ subjectList = nssList_Create(NULL, PR_FALSE); if (!subjectList) { return NULL; } @@ -615,48 +622,51 @@ nssTrustDomain_FindCertificatesBySubject } slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); if (!slots) { goto loser; } - numRemaining = maximumOpt; for (slotp = slots; *slotp; slotp++) { token = nssSlot_GetToken(*slotp); if (token) { nssSession *session; - nssCryptokiObject **instances; + nssCryptokiObject **instances = NULL; nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + PRStatus status = PR_FAILURE; + session = nssTrustDomain_GetSessionForToken(td, token); - if (!session) { - nssToken_Destroy(token); - goto loser; + if (session) { + instances = nssToken_FindCertificatesBySubject(token, + session, + subject, + tokenOnly, + numRemaining, + &status); } - instances = nssToken_FindCertificatesBySubject(token, - session, - subject, - tokenOnly, - numRemaining, - &status); nssToken_Destroy(token); if (status != PR_SUCCESS) { - goto loser; + errors++; + continue; } if (instances) { status = nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); if (status != PR_SUCCESS) { - goto loser; + errors++; + continue; } + collectionCount = nssPKIObjectCollection_Count(collection); if (maximumOpt > 0) { - PRUint32 count; - count = nssPKIObjectCollection_Count(collection); - numRemaining = maximumOpt - count; - if (numRemaining == 0) break; + if (collectionCount >= maximumOpt) + break; + numRemaining = maximumOpt - collectionCount; } } } } + if (!collectionCount && errors) + goto loser; rvCerts = nssPKIObjectCollection_GetCertificates(collection, rvOpt, maximumOpt, arenaOpt); nssPKIObjectCollection_Destroy(collection); nssSlotArray_Destroy(slots);