|
|
1b6f66 |
diff --git a/lib/pki/tdcache.c b/lib/pki/tdcache.c
|
|
|
1b6f66 |
--- a/lib/pki/tdcache.c
|
|
|
1b6f66 |
+++ b/lib/pki/tdcache.c
|
|
|
1b6f66 |
@@ -379,23 +379,29 @@ nssTrustDomain_UnlockCertCache (
|
|
|
1b6f66 |
|
|
|
1b6f66 |
struct token_cert_dtor {
|
|
|
1b6f66 |
NSSToken *token;
|
|
|
1b6f66 |
nssTDCertificateCache *cache;
|
|
|
1b6f66 |
NSSCertificate **certs;
|
|
|
1b6f66 |
PRUint32 numCerts, arrSize;
|
|
|
1b6f66 |
};
|
|
|
1b6f66 |
|
|
|
1b6f66 |
+static void cert_iter(const void *k, void *v, void *a)
|
|
|
1b6f66 |
+{
|
|
|
1b6f66 |
+ nssList *certList = (nssList *)a;
|
|
|
1b6f66 |
+ NSSCertificate *c = (NSSCertificate *)k;
|
|
|
1b6f66 |
+ nssList_Add(certList, nssCertificate_AddRef(c));
|
|
|
1b6f66 |
+}
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
static void
|
|
|
1b6f66 |
-remove_token_certs(const void *k, void *v, void *a)
|
|
|
1b6f66 |
+remove_token_certs(NSSCertificate *c, struct token_cert_dtor *dtor)
|
|
|
1b6f66 |
{
|
|
|
1b6f66 |
- NSSCertificate *c = (NSSCertificate *)k;
|
|
|
1b6f66 |
nssPKIObject *object = &c->object;
|
|
|
1b6f66 |
- struct token_cert_dtor *dtor = a;
|
|
|
1b6f66 |
PRUint32 i;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
nssPKIObject_AddRef(object);
|
|
|
1b6f66 |
nssPKIObject_Lock(object);
|
|
|
1b6f66 |
for (i=0; i<object->numInstances; i++) {
|
|
|
1b6f66 |
if (object->instances[i]->token == dtor->token) {
|
|
|
1b6f66 |
nssCryptokiObject_Destroy(object->instances[i]);
|
|
|
1b6f66 |
object->instances[i] = object->instances[object->numInstances-1];
|
|
|
1b6f66 |
object->instances[object->numInstances-1] = NULL;
|
|
|
1b6f66 |
object->numInstances--;
|
|
|
1b6f66 |
@@ -422,45 +428,83 @@ NSS_IMPLEMENT PRStatus
|
|
|
1b6f66 |
nssTrustDomain_RemoveTokenCertsFromCache (
|
|
|
1b6f66 |
NSSTrustDomain *td,
|
|
|
1b6f66 |
NSSToken *token
|
|
|
1b6f66 |
)
|
|
|
1b6f66 |
{
|
|
|
1b6f66 |
NSSCertificate **certs;
|
|
|
1b6f66 |
PRUint32 i, arrSize = 10;
|
|
|
1b6f66 |
struct token_cert_dtor dtor;
|
|
|
1b6f66 |
+ nssList *certList;
|
|
|
1b6f66 |
+ PRStatus nspr_rv = PR_FAILURE;
|
|
|
1b6f66 |
+ nssListIterator *iter;
|
|
|
1b6f66 |
+ NSSCertificate *c;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
|
|
|
1b6f66 |
if (!certs) {
|
|
|
1b6f66 |
return PR_FAILURE;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
dtor.cache = td->cache;
|
|
|
1b6f66 |
dtor.token = token;
|
|
|
1b6f66 |
dtor.certs = certs;
|
|
|
1b6f66 |
dtor.numCerts = 0;
|
|
|
1b6f66 |
dtor.arrSize = arrSize;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ certList = nssList_Create(NULL, PR_FALSE);
|
|
|
1b6f66 |
+ if (!certList) {
|
|
|
1b6f66 |
+ goto loser;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ /* fetch the list of certs in the cache */
|
|
|
1b6f66 |
PZ_Lock(td->cache->lock);
|
|
|
1b6f66 |
- nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, &dtor);
|
|
|
1b6f66 |
+ nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList);
|
|
|
1b6f66 |
+ PZ_Unlock(td->cache->lock);
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ /* find the certs that match this token without olding the td cache lock */
|
|
|
1b6f66 |
+ iter=nssList_CreateIterator(certList);
|
|
|
1b6f66 |
+ if (!iter) {
|
|
|
1b6f66 |
+ goto loser;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ for (c = (NSSCertificate *)nssListIterator_Start(iter);
|
|
|
1b6f66 |
+ c != (NSSCertificate *)NULL;
|
|
|
1b6f66 |
+ c = (NSSCertificate *)nssListIterator_Next(iter)) {
|
|
|
1b6f66 |
+ remove_token_certs( c, &dtor);
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ nssListIterator_Finish(iter);
|
|
|
1b6f66 |
+ nssListIterator_Destroy(iter);
|
|
|
1b6f66 |
+ nssList_Destroy(certList);
|
|
|
1b6f66 |
+ certList = NULL;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ /* now remove theose certs attached to this token */
|
|
|
1b6f66 |
+ PZ_Lock(td->cache->lock);
|
|
|
1b6f66 |
for (i=0; i
|
|
|
1b6f66 |
if (dtor.certs[i]->object.numInstances == 0) {
|
|
|
1b6f66 |
nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]);
|
|
|
1b6f66 |
dtor.certs[i] = NULL; /* skip this cert in the second for loop */
|
|
|
1b6f66 |
} else {
|
|
|
1b6f66 |
/* make sure it doesn't disappear on us before we finish */
|
|
|
1b6f66 |
nssCertificate_AddRef(dtor.certs[i]);
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
PZ_Unlock(td->cache->lock);
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ /* clean up */
|
|
|
1b6f66 |
for (i=0; i
|
|
|
1b6f66 |
if (dtor.certs[i]) {
|
|
|
1b6f66 |
STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
|
|
|
1b6f66 |
nssCertificate_Destroy(dtor.certs[i]);
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ nspr_rv = PR_SUCCESS;
|
|
|
1b6f66 |
+loser:
|
|
|
1b6f66 |
+ if (certList) {
|
|
|
1b6f66 |
+ nssList_Destroy(certList);
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
nss_ZFreeIf(dtor.certs);
|
|
|
1b6f66 |
- return PR_SUCCESS;
|
|
|
1b6f66 |
+ return nspr_rv;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
NSS_IMPLEMENT PRStatus
|
|
|
1b6f66 |
nssTrustDomain_UpdateCachedTokenCerts (
|
|
|
1b6f66 |
NSSTrustDomain *td,
|
|
|
1b6f66 |
NSSToken *token
|
|
|
1b6f66 |
)
|
|
|
1b6f66 |
{
|
|
|
1b6f66 |
@@ -1073,23 +1117,16 @@ nssTrustDomain_GetCertByDERFromCache (
|
|
|
1b6f66 |
#endif
|
|
|
1b6f66 |
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
|
|
|
1b6f66 |
&issuer, &serial);
|
|
|
1b6f66 |
PORT_Free(issuer.data);
|
|
|
1b6f66 |
PORT_Free(serial.data);
|
|
|
1b6f66 |
return rvCert;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
-static void cert_iter(const void *k, void *v, void *a)
|
|
|
1b6f66 |
-{
|
|
|
1b6f66 |
- nssList *certList = (nssList *)a;
|
|
|
1b6f66 |
- NSSCertificate *c = (NSSCertificate *)k;
|
|
|
1b6f66 |
- nssList_Add(certList, nssCertificate_AddRef(c));
|
|
|
1b6f66 |
-}
|
|
|
1b6f66 |
-
|
|
|
1b6f66 |
NSS_EXTERN NSSCertificate **
|
|
|
1b6f66 |
nssTrustDomain_GetCertsFromCache (
|
|
|
1b6f66 |
NSSTrustDomain *td,
|
|
|
1b6f66 |
nssList *certListOpt
|
|
|
1b6f66 |
)
|
|
|
1b6f66 |
{
|
|
|
1b6f66 |
NSSCertificate **rvArray = NULL;
|
|
|
1b6f66 |
nssList *certList;
|