c70942
diff -up nss/lib/pki/tdcache.c.fix_deadlock nss/lib/pki/tdcache.c
c70942
--- nss/lib/pki/tdcache.c.fix_deadlock	2017-01-13 17:10:36.055530248 +0100
c70942
+++ nss/lib/pki/tdcache.c	2017-01-13 17:14:04.015338438 +0100
c70942
@@ -374,13 +374,19 @@ struct token_cert_dtor {
c70942
     PRUint32 numCerts, arrSize;
c70942
 };
c70942
 
c70942
-static void
c70942
-remove_token_certs(const void *k, void *v, void *a)
c70942
+static void cert_iter(const void *k, void *v, void *a)
c70942
 {
c70942
+    nssList *certList = (nssList *)a;
c70942
     NSSCertificate *c = (NSSCertificate *)k;
c70942
+    nssList_Add(certList, nssCertificate_AddRef(c));
c70942
+}
c70942
+
c70942
+static void
c70942
+remove_token_certs(NSSCertificate *c, struct token_cert_dtor *dtor) 
c70942
+{
c70942
     nssPKIObject *object = &c->object;
c70942
-    struct token_cert_dtor *dtor = a;
c70942
     PRUint32 i;
c70942
+
c70942
     nssPKIObject_AddRef(object);
c70942
     nssPKIObject_Lock(object);
c70942
     for (i = 0; i < object->numInstances; i++) {
c70942
@@ -416,6 +422,11 @@ nssTrustDomain_RemoveTokenCertsFromCache
c70942
     NSSCertificate **certs;
c70942
     PRUint32 i, arrSize = 10;
c70942
     struct token_cert_dtor dtor;
c70942
+    nssList *certList;
c70942
+    PRStatus nspr_rv = PR_FAILURE;
c70942
+    nssListIterator *iter;
c70942
+    NSSCertificate *c;
c70942
+
c70942
     certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
c70942
     if (!certs) {
c70942
         return PR_FAILURE;
c70942
@@ -425,8 +436,33 @@ nssTrustDomain_RemoveTokenCertsFromCache
c70942
     dtor.certs = certs;
c70942
     dtor.numCerts = 0;
c70942
     dtor.arrSize = arrSize;
c70942
+
c70942
+    certList = nssList_Create(NULL, PR_FALSE);
c70942
+    if (!certList) {
c70942
+	goto loser;
c70942
+    }
c70942
+    /* fetch the list of certs in the cache */
c70942
+    PZ_Lock(td->cache->lock);
c70942
+    nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList);
c70942
+    PZ_Unlock(td->cache->lock);
c70942
+
c70942
+    /* find the certs that match this token without olding the td cache lock */
c70942
+    iter=nssList_CreateIterator(certList);
c70942
+    if (!iter) {
c70942
+	goto loser;
c70942
+    }
c70942
+    for (c  = (NSSCertificate *)nssListIterator_Start(iter);
c70942
+	 c != (NSSCertificate *)NULL;
c70942
+	 c  = (NSSCertificate *)nssListIterator_Next(iter)) {
c70942
+	remove_token_certs( c, &dtor);
c70942
+    }
c70942
+    nssListIterator_Finish(iter);
c70942
+    nssListIterator_Destroy(iter);
c70942
+    nssList_Destroy(certList);
c70942
+    certList = NULL;
c70942
+
c70942
+    /* now remove theose certs attached to this token */
c70942
     PZ_Lock(td->cache->lock);
c70942
-    nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, &dtor);
c70942
     for (i = 0; i < dtor.numCerts; i++) {
c70942
         if (dtor.certs[i]->object.numInstances == 0) {
c70942
             nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]);
c70942
@@ -437,14 +473,22 @@ nssTrustDomain_RemoveTokenCertsFromCache
c70942
         }
c70942
     }
c70942
     PZ_Unlock(td->cache->lock);
c70942
+
c70942
+    /* clean up */
c70942
     for (i = 0; i < dtor.numCerts; i++) {
c70942
         if (dtor.certs[i]) {
c70942
             STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
c70942
             nssCertificate_Destroy(dtor.certs[i]);
c70942
         }
c70942
     }
c70942
+
c70942
+    nspr_rv = PR_SUCCESS;
c70942
+loser:
c70942
+    if (certList) {
c70942
+	nssList_Destroy(certList);
c70942
+    }
c70942
     nss_ZFreeIf(dtor.certs);
c70942
-    return PR_SUCCESS;
c70942
+    return nspr_rv;
c70942
 }
c70942
 
c70942
 NSS_IMPLEMENT PRStatus
c70942
@@ -1058,14 +1102,6 @@ nssTrustDomain_GetCertByDERFromCache(
c70942
     return rvCert;
c70942
 }
c70942
 
c70942
-static void
c70942
-cert_iter(const void *k, void *v, void *a)
c70942
-{
c70942
-    nssList *certList = (nssList *)a;
c70942
-    NSSCertificate *c = (NSSCertificate *)k;
c70942
-    nssList_Add(certList, nssCertificate_AddRef(c));
c70942
-}
c70942
-
c70942
 NSS_EXTERN NSSCertificate **
c70942
 nssTrustDomain_GetCertsFromCache(
c70942
     NSSTrustDomain *td,