diff --git a/lib/pki/pki3hack.c b/lib/pki/pki3hack.c
--- a/lib/pki/pki3hack.c
+++ b/lib/pki/pki3hack.c
@@ -849,18 +849,21 @@ fill_CERTCertificateFields(NSSCertificat
}
static CERTCertificate *
stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
{
nssDecodedCert *dc = NULL;
CERTCertificate *cc = NULL;
CERTCertTrust certTrust;
+ nssPKIObject *object = &c->object;
- nssPKIObject_Lock(&c->object);
+ /* make sure object does not go away until we finish */
+ nssPKIObject_AddRef(object);
+ nssPKIObject_Lock(object);
dc = c->decoding;
if (!dc) {
dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
if (!dc) {
goto loser;
}
cc = (CERTCertificate *)dc->data;
@@ -898,17 +901,18 @@ stan_GetCERTCertificate(NSSCertificate *
trust = nssTrust_GetCERTCertTrustForCert(c, cc);
CERT_LockCertTrust(cc);
cc->trust = trust;
CERT_UnlockCertTrust(cc);
}
loser:
- nssPKIObject_Unlock(&c->object);
+ nssPKIObject_Unlock(object);
+ nssPKIObject_Destroy(object);
return cc;
}
NSS_IMPLEMENT CERTCertificate *
STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
{
if (c->decoding) {
return stan_GetCERTCertificate(c, PR_TRUE);
@@ -1265,16 +1269,17 @@ done:
*/
static PRStatus
DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject)
{
int numNotDestroyed = 0; /* the ones skipped plus the failures */
int failureCount = 0; /* actual deletion failures by devices */
int index;
+ nssPKIObject_AddRef(tObject);
nssPKIObject_Lock(tObject);
/* Keep going even if a module fails to delete. */
for (index = 0; index < tObject->numInstances; index++) {
nssCryptokiObject *instance = tObject->instances[index];
if (!instance) {
continue;
}
@@ -1298,16 +1303,17 @@ DeleteCertTrustMatchingSlot(PK11SlotInfo
if (numNotDestroyed == 0) {
nss_ZFreeIf(tObject->instances);
tObject->numInstances = 0;
} else {
tObject->numInstances = numNotDestroyed;
}
nssPKIObject_Unlock(tObject);
+ nssPKIObject_Destroy(tObject);
return failureCount == 0 ? PR_SUCCESS : PR_FAILURE;
}
/*
** Delete trust objects matching the slot of the given certificate.
** Returns an error if any device fails to delete.
*/
@@ -1324,30 +1330,32 @@ STAN_DeleteCertTrustMatchingSlot(NSSCert
int i;
/* Iterate through the cert and trust object instances looking for
* those with matching pk11 slots to delete. Even if some device
* can't delete we keep going. Keeping a status variable for the
* loop so that once it's failed the other gets set.
*/
NSSRWLock_LockRead(td->tokensLock);
+ nssPKIObject_AddRef(cobject);
nssPKIObject_Lock(cobject);
for (i = 0; i < cobject->numInstances; i++) {
nssCryptokiObject *cInstance = cobject->instances[i];
if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) {
PRStatus status;
if (!tobject->numInstances || !tobject->instances) continue;
status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject);
if (status == PR_FAILURE) {
/* set the outer one but keep going */
nssrv = PR_FAILURE;
}
}
}
nssPKIObject_Unlock(cobject);
+ nssPKIObject_Destroy(cobject);
NSSRWLock_UnlockRead(td->tokensLock);
return nssrv;
}
/* CERT_TraversePermCertsForSubject */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificatesBySubject (
NSSTrustDomain *td,
diff --git a/lib/pki/tdcache.c b/lib/pki/tdcache.c
--- a/lib/pki/tdcache.c
+++ b/lib/pki/tdcache.c
@@ -386,16 +386,17 @@ struct token_cert_dtor {
static void
remove_token_certs(const void *k, void *v, void *a)
{
NSSCertificate *c = (NSSCertificate *)k;
nssPKIObject *object = &c->object;
struct token_cert_dtor *dtor = a;
PRUint32 i;
+ nssPKIObject_AddRef(object);
nssPKIObject_Lock(object);
for (i=0; i<object->numInstances; i++) {
if (object->instances[i]->token == dtor->token) {
nssCryptokiObject_Destroy(object->instances[i]);
object->instances[i] = object->instances[object->numInstances-1];
object->instances[object->numInstances-1] = NULL;
object->numInstances--;
dtor->certs[dtor->numCerts++] = c;
@@ -404,16 +405,17 @@ remove_token_certs(const void *k, void *
dtor->certs = nss_ZREALLOCARRAY(dtor->certs,
NSSCertificate *,
dtor->arrSize);
}
break;
}
}
nssPKIObject_Unlock(object);
+ nssPKIObject_Destroy(object);
return;
}
/*
* Remove all certs for the given token from the cache. This is
* needed if the token is removed.
*/
NSS_IMPLEMENT PRStatus