diff options
author | wchang0222%aol.com <devnull@localhost> | 2003-12-18 18:23:17 +0000 |
---|---|---|
committer | wchang0222%aol.com <devnull@localhost> | 2003-12-18 18:23:17 +0000 |
commit | f3c4b6448941935f86de62a740654fdfa627eef7 (patch) | |
tree | 9ad0d449ff1457d0fa2fa24c76e49432725a86be | |
parent | 98520291a0e695ec891dfd8dc85de70688c19b9c (diff) | |
download | nss-hg-f3c4b6448941935f86de62a740654fdfa627eef7.tar.gz |
Bugzilla bug 228624: made PK11_ListCertsInSlot reach into the Stan layer
to obtain the correct nicknames of the cert instances (pk11cert.c). Fixed
the bug that if a cert we want to add the the cache is already in the
cache, we should merge the instances of the cert before destroying the
duplicate cert (tdcache.c). r=jpierre,relyea.
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 36 | ||||
-rw-r--r-- | security/nss/lib/pki/tdcache.c | 50 |
2 files changed, 81 insertions, 5 deletions
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index d2b2cd578..a100caca3 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -3525,17 +3525,40 @@ PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey) return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID); } +/* argument type for listCertsCallback */ +typedef struct { + CERTCertList *list; + PK11SlotInfo *slot; +} ListCertsArg; + static SECStatus listCertsCallback(CERTCertificate* cert, void*arg) { - CERTCertList *list = (CERTCertList*)arg; + ListCertsArg *cdata = (ListCertsArg*)arg; char *nickname = NULL; + nssCryptokiObject *instance, **ci; + nssCryptokiObject **instances; + NSSCertificate *c = STAN_GetNSSCertificate(cert); - if (cert->nickname) { - nickname = PORT_ArenaStrdup(list->arena,cert->nickname); + instances = nssPKIObject_GetInstances(&c->object); + instance = NULL; + for (ci = instances; *ci; ci++) { + if ((*ci)->token->pk11slot == cdata->slot) { + instance = *ci; + break; + } + } + PORT_Assert(instance != NULL); + if (!instance) { + nssCryptokiObjectArray_Destroy(instances); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } + nickname = STAN_GetCERTCertificateNameForInstance(cdata->list->arena, + c, instance); + nssCryptokiObjectArray_Destroy(instances); - return CERT_AddCertToListTailWithData(list, + return CERT_AddCertToListTailWithData(cdata->list, CERT_DupCertificate(cert),nickname); } @@ -3544,12 +3567,15 @@ PK11_ListCertsInSlot(PK11SlotInfo *slot) { SECStatus status; CERTCertList *certs; + ListCertsArg cdata; certs = CERT_NewCertList(); if(certs == NULL) return NULL; + cdata.list = certs; + cdata.slot = slot; status = PK11_TraverseCertsInSlot(slot, listCertsCallback, - (void*)certs); + &cdata); if( status != SECSuccess ) { CERT_DestroyCertList(certs); diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index c9fd8012f..2428de046 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -715,6 +715,50 @@ add_email_entry ( extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; +static void +remove_object_instances ( + nssPKIObject *object, + nssCryptokiObject **instances, + int numInstances +) +{ + int i; + + for (i = 0; i < numInstances; i++) { + nssPKIObject_RemoveInstanceForToken(object, instances[i]->token); + } +} + +static SECStatus +merge_object_instances ( + nssPKIObject *to, + nssPKIObject *from +) +{ + nssCryptokiObject **instances, **ci; + int i; + SECStatus rv = SECSuccess; + + instances = nssPKIObject_GetInstances(from); + if (instances == NULL) { + return SECFailure; + } + for (ci = instances, i = 0; *ci; ci++, i++) { + nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci); + if (instance) { + if (nssPKIObject_AddInstance(to, instance) == SECSuccess) { + continue; + } + nssCryptokiObject_Destroy(instance); + } + remove_object_instances(to, instances, i); + rv = SECFailure; + break; + } + nssCryptokiObjectArray_Destroy(instances); + return rv; +} + static NSSCertificate * add_cert_to_cache ( NSSTrustDomain *td, @@ -743,6 +787,12 @@ add_cert_to_cache ( /* collision - somebody else already added the cert * to the cache before this thread got around to it. */ + /* merge the instances of the cert */ + if (merge_object_instances(&rvCert->object, &cert->object) + != SECSuccess) { + nssCertificate_Destroy(rvCert); + return NULL; + } nssCertificate_Destroy(cert); return rvCert; } |