summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwchang0222%aol.com <devnull@localhost>2003-12-18 18:23:17 +0000
committerwchang0222%aol.com <devnull@localhost>2003-12-18 18:23:17 +0000
commitf3c4b6448941935f86de62a740654fdfa627eef7 (patch)
tree9ad0d449ff1457d0fa2fa24c76e49432725a86be
parent98520291a0e695ec891dfd8dc85de70688c19b9c (diff)
downloadnss-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.c36
-rw-r--r--security/nss/lib/pki/tdcache.c50
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;
}