diff --git a/mozilla/security/nss/lib/certdb/certdb.c b/mozilla/security/nss/lib/certdb/certdb.c index faa89919d83..60864d9926d 100644 --- a/mozilla/security/nss/lib/certdb/certdb.c +++ b/mozilla/security/nss/lib/certdb/certdb.c @@ -34,7 +34,7 @@ /* * Certificate handling code * - * $Id: certdb.c,v 1.19 2001-11-21 18:00:08 relyea%netscape.com Exp $ + * $Id: certdb.c,v 1.20 2002-01-03 20:09:27 ian.mcgreer%sun.com Exp $ */ #include "nssilock.h" @@ -63,7 +63,7 @@ #ifndef NSS_3_4_CODE #define NSS_3_4_CODE #endif /* NSS_3_4_CODE */ -#include "pkit.h" +#include "pki.h" /* * Certificate database handling code @@ -1159,9 +1159,14 @@ CERTCertificate * CERT_DupCertificate(CERTCertificate *c) { if (c) { +#ifdef NSS_CLASSIC CERT_LockCertRefCount(c); ++c->referenceCount; CERT_UnlockCertRefCount(c); +#else + NSSCertificate *tmp = STAN_GetNSSCertificate(c); + nssCertificate_AddRef(tmp); +#endif } return c; } diff --git a/mozilla/security/nss/lib/certdb/stanpcertdb.c b/mozilla/security/nss/lib/certdb/stanpcertdb.c index 164e3ac9a7c..9ecd3ae1018 100644 --- a/mozilla/security/nss/lib/certdb/stanpcertdb.c +++ b/mozilla/security/nss/lib/certdb/stanpcertdb.c @@ -164,6 +164,7 @@ CERTCertificate * __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname, PRBool isperm, PRBool copyDER) { + PRStatus nssrv; NSSCertificate *c; NSSCryptoContext *context; NSSArena *arena; @@ -174,13 +175,14 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, } c = nss_ZNEW(arena, NSSCertificate); if (!c) { - goto loser; + nssArena_Destroy(arena); + return NULL; } NSSITEM_FROM_SECITEM(&c->encoding, derCert); - c->object.arena = arena; - c->object.refCount = 1; - c->object.instanceList = nssList_Create(arena, PR_TRUE); - c->object.instances = nssList_CreateIterator(c->object.instanceList); + nssrv = nssPKIObject_Initialize(&c->object, arena, NULL, NULL); + if (nssrv != PR_SUCCESS) { + goto loser; + } /* Forces a decoding of the cert in order to obtain the parts used * below */ @@ -204,11 +206,14 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, PORT_Strlen(cc->emailAddr)); } context = STAN_GetDefaultCryptoContext(); - NSSCryptoContext_ImportCertificate(context, c); + nssrv = NSSCryptoContext_ImportCertificate(context, c); + if (nssrv != PR_SUCCESS) { + goto loser; + } c->object.trustDomain = STAN_GetDefaultTrustDomain(); return cc; loser: - nssArena_Destroy(arena); + nssPKIObject_Destroy(&c->object); return NULL; } @@ -404,28 +409,50 @@ CERT_DestroyCertificate(CERTCertificate *cert) int refCount; CERTCertDBHandle *handle; if ( cert ) { + NSSCertificate *tmp = STAN_GetNSSCertificate(cert); handle = cert->dbhandle; +#ifdef NSS_CLASSIC CERT_LockCertRefCount(cert); PORT_Assert(cert->referenceCount > 0); refCount = --cert->referenceCount; CERT_UnlockCertRefCount(cert); - if ( ( refCount == 0 ) && !cert->keepSession ) { - PRArenaPool *arena = cert->arena; +#else + if (tmp) { /* delete the NSSCertificate */ NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSCertificate *tmp = STAN_GetNSSCertificate(cert); + refCount = (int)tmp->object.refCount; if (tmp) { - NSSCryptoContext *cc = tmp->object.cryptoContext; - nssTrustDomain_RemoveCertFromCache(td, tmp); - /* In 4.0, in context references of this cert would go - * away with the context. but here the context persists, - * so explicity remove the cert. + /* This is a hack. For 3.4, there are persistent references + * to 4.0 certificates during the lifetime of a cert. In the + * case of a temp cert, the persistent reference is in the + * cert store of the global crypto context. For a perm cert, + * the persistent reference is in the cache. Thus, the last + * external reference is really the penultimate NSS reference. + * When the count drops to two, it is really one, but the + * persistent reference must be explicitly deleted. In 4.0, + * this ugliness will not appear. Crypto contexts will remove + * their own cert references, and the cache will have its + * own management code also. */ - if (cc != NULL) { - nssCertificateStore_Remove(cc->certStore, tmp); + if (refCount == 2) { + NSSCryptoContext *cc = tmp->object.cryptoContext; + if (cc != NULL) { + nssCertificateStore_Remove(cc->certStore, tmp); + } else { + nssTrustDomain_RemoveCertFromCache(td, tmp); + } + refCount = (int)tmp->object.refCount; } NSSCertificate_Destroy(tmp); + /* another hack... the destroy *must* decrement the count */ + --refCount; } + } else { + refCount = 0; + } +#endif + if ( ( refCount == 0 ) && !cert->keepSession ) { + PRArenaPool *arena = cert->arena; /* zero cert before freeing. Any stale references to this cert * after this point will probably cause an exception. */ PORT_Memset(cert, 0, sizeof *cert); diff --git a/mozilla/security/nss/lib/dev/devobject.c b/mozilla/security/nss/lib/dev/devobject.c index da8219098d9..329f9cb88b4 100644 --- a/mozilla/security/nss/lib/dev/devobject.c +++ b/mozilla/security/nss/lib/dev/devobject.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.7 $ $Date: 2001-12-20 23:17:58 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.8 $ $Date: 2002-01-03 20:09:18 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef DEV_H @@ -316,7 +316,6 @@ get_token_cert ) { NSSCertificate *rvCert; - struct nssPKIObjectBaseStr *object; /* XXX needs to go */ NSSArena *arena; nssSession *session; PRStatus nssrv; @@ -339,25 +338,18 @@ get_token_cert } rvCert = nss_ZNEW(arena, NSSCertificate); if (!rvCert) { - goto loser; + NSSArena_Destroy(arena); + return NULL; } - object = &rvCert->object; - object->arena = arena; - object->refCount = 1; - object->instanceList = nssList_Create(arena, PR_TRUE); - /* XXX this is only valid if tokens are unique in trust domains... */ - object->trustDomain = token->trustDomain; - if (!object->instanceList) { - goto loser; - } - object->instances = nssList_CreateIterator(object->instanceList); - if (!object->instances) { + nssrv = nssPKIObject_Initialize(&rvCert->object, arena, + token->trustDomain, NULL); + if (nssrv != PR_SUCCESS) { goto loser; } nssrv = nssCKObject_GetAttributes(handle, cert_template, template_size, arena, session, token->slot); - if (nssrv) { + if (nssrv != PR_SUCCESS) { goto loser; } rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]); @@ -383,7 +375,7 @@ get_token_cert #endif return rvCert; loser: - nssArena_Destroy(arena); + nssPKIObject_Destroy(&rvCert->object); return (NSSCertificate *)NULL; } @@ -494,7 +486,9 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg) } nssList_Add(cert->object.instanceList, ci); } - return (*search->callback)(cert, search->cbarg); + nssrv = (*search->callback)(cert, search->cbarg); + NSSCertificate_Destroy(cert); + return nssrv; } /* traverse all certificates - this should only happen if the token @@ -889,7 +883,6 @@ nssToken_FindTrustForCert NSSTrust *rvTrust; nssSession *session; NSSArena *arena; - struct nssPKIObjectBaseStr *object; nssCryptokiInstance *instance; PRBool isTokenObject; CK_BBOOL isToken; @@ -926,31 +919,23 @@ nssToken_FindTrustForCert nssArena_Destroy(arena); return NULL; } - object = &rvTrust->object; - object->arena = arena; - object->refCount = 1; - /* XXX this is only valid if tokens are unique in trust domains... */ - object->trustDomain = token->trustDomain; - object->instanceList = nssList_Create(arena, PR_TRUE); - if (!object->instanceList) { - nssArena_Destroy(arena); - return NULL; - } - object->instances = nssList_CreateIterator(object->instanceList); - if (!object->instances) { - nssArena_Destroy(arena); - return NULL; + nssrv = nssPKIObject_Initialize(&rvTrust->object, arena, + token->trustDomain, NULL); + if (nssrv != PR_SUCCESS) { + goto loser; } isTokenObject = (isToken == CK_TRUE) ? PR_TRUE : PR_FALSE; instance = create_cryptoki_instance(arena, token, tobjID, isTokenObject); if (!instance) { - nssArena_Destroy(arena); - return NULL; + goto loser; } rvTrust->serverAuth = saTrust; rvTrust->clientAuth = caTrust; rvTrust->emailProtection = epTrust; rvTrust->codeSigning = csTrust; return rvTrust; +loser: + nssPKIObject_Destroy(&rvTrust->object); + return (NSSTrust *)NULL; } diff --git a/mozilla/security/nss/lib/pk11wrap/pk11cert.c b/mozilla/security/nss/lib/pk11wrap/pk11cert.c index e8f66972fb4..b9fefd733bd 100644 --- a/mozilla/security/nss/lib/pk11wrap/pk11cert.c +++ b/mozilla/security/nss/lib/pk11wrap/pk11cert.c @@ -76,8 +76,6 @@ struct nss3_cert_cbstr { /* Translate from NSSCertificate to CERTCertificate, then pass the latter * to a callback. - * Question: do all callers of PK11_ functions using a CERTCertificate - * callback understand that they must dup the cert to keep it alive? */ static PRStatus convert_cert(NSSCertificate *c, void *arg) { @@ -87,11 +85,18 @@ static PRStatus convert_cert(NSSCertificate *c, void *arg) nss3cert = STAN_GetCERTCertificate(c); if (!nss3cert) return PR_FAILURE; secrv = (*nss3cb->callback)(nss3cert, nss3cb->arg); - /* this destroy is dependent upon the question above */ - CERT_DestroyCertificate(nss3cert); return (secrv) ? PR_FAILURE : PR_SUCCESS; } +/* this is redeclared from trustdomain.c, but this code is just 3.4 glue + * anyway + */ +static void cert_destructor(void *el) +{ + NSSCertificate *c = (NSSCertificate *)el; + NSSCertificate_Destroy(c); +} + void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst) { @@ -1186,6 +1191,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { *delimit = '\0'; /* find token by name */ token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); + slot = PK11_ReferenceSlot(token->pk11slot); *delimit = ':'; } else { slot = PK11_GetInternalKeySlot(); @@ -1194,6 +1200,12 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { if (token) { nssTokenCertSearch search; nssList *certList; + if (!PK11_IsFriendly(slot)) { + if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { + PK11_FreeSlot(slot); + return NULL; + } + } certList = nssList_Create(NULL, PR_FALSE); (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, nickname, @@ -1207,6 +1219,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { nssToken_TraverseCertificatesByNickname(token, NULL, (NSSUTF8 *)nickname, &search); + nssList_Clear(certList, cert_destructor); nssList_Destroy(certList); if (!cert) { certList = nssList_Create(NULL, PR_FALSE); @@ -1217,9 +1230,11 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { nssToken_TraverseCertificatesByEmail(token, NULL, (NSSASCII7 *)nickname, &search); + nssList_Clear(certList, cert_destructor); nssList_Destroy(certList); } if (cert) { + (void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1); rvCert = STAN_GetCERTCertificate(cert); } } @@ -1272,43 +1287,51 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { int i; CERTCertList *certList = NULL; NSSCertificate **foundCerts = NULL; - NSSCertificate *c; NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); + NSSCertificate *c; + NSSToken *token; + PK11SlotInfo *slot; if ((delimit = PORT_Strchr(nickname,':')) != NULL) { - NSSToken *token; tokenName = nickname; nickname = delimit + 1; *delimit = '\0'; /* find token by name */ token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); - if (token) { - nssTokenCertSearch search; - PRUint32 count; - nssList *nameList; - nameList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, - nickname, - nameList); - /* set the search criteria */ - search.callback = collect_certs; - search.cbarg = nameList; - search.cached = nameList; - search.searchType = nssTokenSearchType_TokenOnly; - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - nickname, &search); - count = nssList_Count(nameList); - foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); - nssList_GetArray(nameList, (void **)foundCerts, count); - nssList_Destroy(nameList); - } + slot = PK11_ReferenceSlot(token->pk11slot); *delimit = ':'; } else { - foundCerts = NSSTrustDomain_FindCertificatesByNickname( - defaultTD, - (NSSUTF8 *)nickname, - NULL, - 0, - NULL); + slot = PK11_GetInternalKeySlot(); + token = PK11Slot_GetNSSToken(slot); + } + if (token) { + nssTokenCertSearch search; + PRUint32 count; + nssList *nameList; + if (!PK11_IsFriendly(slot)) { + if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { + PK11_FreeSlot(slot); + return NULL; + } + } + nameList = nssList_Create(NULL, PR_FALSE); + (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, + nickname, + nameList); + /* set the search criteria */ + search.callback = collect_certs; + search.cbarg = nameList; + search.cached = nameList; + search.searchType = nssTokenSearchType_TokenOnly; + nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, + nickname, &search); + count = nssList_Count(nameList); + foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); + nssList_GetArray(nameList, (void **)foundCerts, count); + nssList_Clear(nameList, cert_destructor); + nssList_Destroy(nameList); + } + if (slot) { + PK11_FreeSlot(slot); } if (foundCerts) { certList = CERT_NewCertList(); @@ -2340,6 +2363,7 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, token = PK11Slot_GetNSSToken(slot); nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, &subject, &search); + nssList_Clear(subjectList, cert_destructor); nssList_Destroy(subjectList); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; #endif @@ -2410,6 +2434,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, token = PK11Slot_GetNSSToken(slot); nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, nick, &search); + nssList_Clear(nameList, cert_destructor); nssList_Destroy(nameList); if (created) nss_ZFreeIf(nick); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; @@ -2466,6 +2491,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot, } else { nssrv = PR_FAILURE; } + nssList_Clear(certList, cert_destructor); nssList_Destroy(certList); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; #endif diff --git a/mozilla/security/nss/lib/pki/certdecode.c b/mozilla/security/nss/lib/pki/certdecode.c index 4668020c847..910fb6c30d3 100644 --- a/mozilla/security/nss/lib/pki/certdecode.c +++ b/mozilla/security/nss/lib/pki/certdecode.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.7 $ $Date: 2001-12-14 17:32:18 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.8 $ $Date: 2002-01-03 20:09:21 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef PKIT_H @@ -46,30 +46,71 @@ static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.7 $ $ /* XXX * move this to a more appropriate location */ -NSS_IMPLEMENT void -nssPKIObject_AddRef +NSS_IMPLEMENT PRStatus +nssPKIObject_Initialize ( - struct nssPKIObjectBaseStr *object + struct nssPKIObjectBaseStr *object, + NSSArena *arena, + NSSTrustDomain *td, + NSSCryptoContext *cc ) { - /* XXX of course this needs to be locked in 4.0! */ - object->refCount++; + object->arena = arena; + object->trustDomain = td; + object->cryptoContext = cc; + object->lock = PZ_NewLock(nssILockOther); + if (!object->lock) { + return PR_FAILURE; + } + object->instanceList = nssList_Create(arena, PR_TRUE); + if (!object->instanceList) { + PZ_DestroyLock(object->lock); + return PR_FAILURE; + } + object->instances = nssList_CreateIterator(object->instanceList); + if (!object->instances) { + nssList_Destroy(object->instanceList); + PZ_DestroyLock(object->lock); + return PR_FAILURE; + } + object->refCount = 1; + return PR_SUCCESS; } /* XXX * move this to a more appropriate location */ NSS_IMPLEMENT void +nssPKIObject_AddRef +( + struct nssPKIObjectBaseStr *object +) +{ + PZ_Lock(object->lock); + object->refCount++; + PZ_Unlock(object->lock); +} + +/* XXX + * move this to a more appropriate location + */ +NSS_IMPLEMENT PRBool nssPKIObject_Destroy ( struct nssPKIObjectBaseStr *object ) { - /* XXX of course this needs to be locked in 4.0! */ - if (--object->refCount == 0) { + PRUint32 refCount; + PZ_Lock(object->lock); + PORT_Assert(object->refCount > 0); + refCount = --object->refCount; + PZ_Unlock(object->lock); + if (refCount == 0) { nssList_Destroy(object->instanceList); nssArena_Destroy(object->arena); + return PR_TRUE; } + return PR_FALSE; } #ifdef NSS_3_4_CODE diff --git a/mozilla/security/nss/lib/pki/certificate.c b/mozilla/security/nss/lib/pki/certificate.c index 8c38d4297cd..0333f977224 100644 --- a/mozilla/security/nss/lib/pki/certificate.c +++ b/mozilla/security/nss/lib/pki/certificate.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.21 $ $Date: 2001-12-14 17:32:18 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.22 $ $Date: 2002-01-03 20:09:23 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -67,7 +67,9 @@ nssCertificate_AddRef NSSCertificate *c ) { - nssPKIObject_AddRef(&c->object); + if (c) { + nssPKIObject_AddRef(&c->object); + } return c; } @@ -77,7 +79,9 @@ NSSCertificate_Destroy NSSCertificate *c ) { - nssPKIObject_Destroy(&c->object); + if (c) { + nssPKIObject_Destroy(&c->object); + } return PR_SUCCESS; } @@ -679,6 +683,7 @@ nssSMIMEProfile_Create NSSItem *profileData ) { + PRStatus nssrv; NSSArena *arena; nssSMIMEProfile *rvProfile; arena = nssArena_Create(); @@ -687,18 +692,11 @@ nssSMIMEProfile_Create } rvProfile = nss_ZNEW(arena, nssSMIMEProfile); if (!rvProfile) { - goto loser; + nssArena_Destroy(arena); + return NULL; } - rvProfile->object.arena = arena; - rvProfile->object.refCount = 1; - rvProfile->object.instanceList = nssList_Create(arena, PR_TRUE); - if (!rvProfile->object.instanceList) { - goto loser; - } - rvProfile->object.instances = nssList_CreateIterator( - rvProfile->object.instanceList); - if (!rvProfile->object.instances) { - nssList_Destroy(rvProfile->object.instanceList); + nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL); + if (nssrv != PR_SUCCESS) { goto loser; } rvProfile->certificate = cert; @@ -712,7 +710,7 @@ nssSMIMEProfile_Create } return rvProfile; loser: - nssArena_Destroy(arena); + nssPKIObject_Destroy(&rvProfile->object); return NULL; } diff --git a/mozilla/security/nss/lib/pki/pki3hack.c b/mozilla/security/nss/lib/pki/pki3hack.c index 91845c1bc43..fb5fbc080de 100644 --- a/mozilla/security/nss/lib/pki/pki3hack.c +++ b/mozilla/security/nss/lib/pki/pki3hack.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.16 $ $Date: 2001-12-20 16:20:16 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.17 $ $Date: 2002-01-03 20:09:23 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ /* @@ -580,6 +580,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc) NSSCertificate *c; nssCryptokiInstance *instance; NSSArena *arena; + PRStatus nssrv; c = cc->nssCertificate; if (c) { return c; @@ -593,15 +594,15 @@ STAN_GetNSSCertificate(CERTCertificate *cc) } c = nss_ZNEW(arena, NSSCertificate); if (!c) { - goto loser; + nssArena_Destroy(arena); + return NULL; } NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; - c->object.arena = arena; - c->object.refCount = 1; - c->object.trustDomain = (NSSTrustDomain *)cc->dbhandle; - c->object.instanceList = nssList_Create(arena, PR_TRUE); - c->object.instances = nssList_CreateIterator(c->object.instanceList); + nssrv = nssPKIObject_Initialize(&c->object, arena, cc->dbhandle, NULL); + if (nssrv != PR_SUCCESS) { + nssPKIObject_Destroy(&c->object); + } nssItem_Create(arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(arena, @@ -637,9 +638,6 @@ STAN_GetNSSCertificate(CERTCertificate *cc) c->decoding = create_decoded_pkix_cert_from_nss3cert(arena, cc); cc->nssCertificate = c; return c; -loser: - nssArena_Destroy(arena); - return NULL; } NSS_EXTERN PRStatus @@ -665,17 +663,9 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) arena = nssArena_Create(); if (!arena) return PR_FAILURE; nssTrust = nss_ZNEW(arena, NSSTrust); - nssTrust->object.arena = arena; - nssTrust->object.refCount = 1; - nssTrust->object.instanceList = nssList_Create(arena, PR_FALSE); - if (!nssTrust->object.instanceList) { - nssArena_Destroy(arena); - return PR_FAILURE; - } - nssTrust->object.instances = nssList_CreateIterator( - nssTrust->object.instanceList); - if (!nssTrust->object.instances) { - nssArena_Destroy(arena); + nssrv = nssPKIObject_Initialize(&nssTrust->object, arena, NULL, NULL); + if (nssrv != PR_SUCCESS) { + nssPKIObject_Destroy(&nssTrust->object); return PR_FAILURE; } nssTrust->certificate = c; diff --git a/mozilla/security/nss/lib/pki/pkim.h b/mozilla/security/nss/lib/pki/pkim.h index 724cc1a0de5..9e8f8b16c83 100644 --- a/mozilla/security/nss/lib/pki/pkim.h +++ b/mozilla/security/nss/lib/pki/pkim.h @@ -35,7 +35,7 @@ #define PKIM_H #ifdef DEBUG -static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.12 $ $Date: 2001-12-14 17:32:20 $ $Name: not supported by cvs2svn $"; +static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.13 $ $Date: 2002-01-03 20:09:24 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef BASE_H @@ -281,13 +281,22 @@ nssBestCertificate_Callback void *arg ); +NSS_EXTERN PRStatus +nssPKIObject_Initialize +( + struct nssPKIObjectBaseStr *object, + NSSArena *arena, + NSSTrustDomain *td, + NSSCryptoContext *cc +); + NSS_EXTERN void nssPKIObject_AddRef ( struct nssPKIObjectBaseStr *object ); -NSS_EXTERN void +NSS_EXTERN PRBool nssPKIObject_Destroy ( struct nssPKIObjectBaseStr *object diff --git a/mozilla/security/nss/lib/pki/pkistore.c b/mozilla/security/nss/lib/pki/pkistore.c index 8208a174b00..0438d435167 100644 --- a/mozilla/security/nss/lib/pki/pkistore.c +++ b/mozilla/security/nss/lib/pki/pkistore.c @@ -32,16 +32,20 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.2 $ $Date: 2001-12-19 20:27:21 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.3 $ $Date: 2002-01-03 20:09:24 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef PKIM_H #include "pkim.h" #endif /* PKIM_H */ -#ifndef PKIT_H -#include "pkit.h" -#endif /* PKIT_H */ +#ifndef PKI_H +#include "pki.h" +#endif /* PKI_H */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ #ifndef BASE_H #include "base.h" @@ -58,9 +62,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.2 $ $Da * stay in until they are explicitly removed. It is only used by crypto * contexts at this time, but may be more generally useful... * - * TODO: - * 1) In the future (4.0), the cert entries are ref-counted. In 3.4, they - * are managed by the CERTCertificate pointer. */ struct nssCertificateStoreStr @@ -244,7 +245,9 @@ nssCertificateStore_Add nssrv = add_certificate_entry(store, cert); if (nssrv == PR_SUCCESS) { nssrv = add_subject_entry(store, cert); - if (nssrv != PR_SUCCESS) { + if (nssrv == PR_SUCCESS) { + nssCertificate_AddRef(cert); /* obtain a reference for the store */ + } else { remove_certificate_entry(store, cert); } } @@ -290,7 +293,6 @@ remove_subject_entry if (nssList_Count(subjectList) == 0) { nssHash_Remove(store->subject, &cert->subject); nssList_Destroy(subjectList); - /* XXX need to deref objects here in 4.0 */ } } } @@ -306,6 +308,7 @@ nssCertificateStore_Remove remove_certificate_entry(store, cert); remove_subject_entry(store, cert); PZ_Unlock(store->lock); + NSSCertificate_Destroy(cert); /* release the store's reference */ } NSS_IMPLEMENT NSSCertificate ** @@ -318,7 +321,7 @@ nssCertificateStore_FindCertificatesBySubject NSSArena *arenaOpt ) { - PRUint32 count; + PRUint32 i, count; NSSCertificate **rvArray = NULL; nssList *subjectList; PZ_Lock(store->lock); @@ -331,12 +334,14 @@ nssCertificateStore_FindCertificatesBySubject } if (rvOpt) { nssList_GetArray(subjectList, (void **)rvOpt, count); + for (i=0; iissuer_and_serial, &index); PZ_Unlock(store->lock); if (entry) { - return entry->cert; + return nssCertificate_AddRef(entry->cert); } return NULL; } @@ -548,7 +557,7 @@ nssCertificateStore_FindCertificateByEncodedCertificate PZ_Lock(store->lock); nssHash_Iterate(store->subject, match_encoding, &der); PZ_Unlock(store->lock); - return der.cert; + return nssCertificate_AddRef(der.cert); } NSS_EXTERN PRStatus diff --git a/mozilla/security/nss/lib/pki/tdcache.c b/mozilla/security/nss/lib/pki/tdcache.c index 325c86a598e..2226590cf48 100644 --- a/mozilla/security/nss/lib/pki/tdcache.c +++ b/mozilla/security/nss/lib/pki/tdcache.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.17 $ $Date: 2001-12-14 17:32:23 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.18 $ $Date: 2002-01-03 20:09:24 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef PKIM_H @@ -385,6 +385,7 @@ nssTrustDomain_RemoveCertFromCache nssHash_Remove(td->cache->subject, &cert->subject); } PZ_Unlock(td->cache->lock); + NSSCertificate_Destroy(cert); /* release the reference */ return; loser: /* if here, then the cache is inconsistent. For now, flush it. */ @@ -393,6 +394,7 @@ loser: PR_LOG(s_log, PR_LOG_DEBUG, ("remove cert failed, flushing")); #endif nssTrustDomain_FlushCache(td, -1.0); + NSSCertificate_Destroy(cert); /* release the reference */ } /* This is used to remove all certs below a certain threshold, where @@ -665,6 +667,7 @@ add_cert_to_cache #endif } PZ_Unlock(td->cache->lock); + nssCertificate_AddRef(cert); return nssrv; loser: /* Remove any handles that have been created */ @@ -730,13 +733,13 @@ collect_subject_certs { NSSCertificate *c; NSSCertificate **rvArray = NULL; - PRUint32 count; + PRUint32 i, count; if (rvCertListOpt) { nssListIterator *iter = nssList_CreateIterator(subjectList); for (c = (NSSCertificate *)nssListIterator_Start(iter); c != (NSSCertificate *)NULL; c = (NSSCertificate *)nssListIterator_Next(iter)) { - nssList_Add(rvCertListOpt, c); + nssList_Add(rvCertListOpt, nssCertificate_AddRef(c)); } nssListIterator_Finish(iter); nssListIterator_Destroy(iter); @@ -747,6 +750,7 @@ collect_subject_certs return (NSSCertificate **)NULL; } nssList_GetArray(subjectList, (void **)rvArray, count); + for (i=0; icache->lock); - return rvCert; + return nssCertificate_AddRef(rvCert); } #ifdef NSS_3_4_CODE @@ -963,14 +967,14 @@ nssTrustDomain_GetCertByDERFromCache PORT_Free(issuer.data); PORT_Free(serial.data); #endif - return rvCert; + return nssCertificate_AddRef(rvCert); } static void cert_iter(const void *k, void *v, void *a) { nssList *certList = (nssList *)a; - NSSCertificate *c = (NSSCertificate *)v; - nssList_Add(certList, c); + NSSCertificate *c = (NSSCertificate *)k; + nssList_Add(certList, nssCertificate_AddRef(c)); } NSS_EXTERN NSSCertificate ** @@ -994,6 +998,7 @@ nssTrustDomain_GetCertsFromCache PRUint32 count = nssList_Count(certList); rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count); nssList_GetArray(certList, (void **)rvArray, count); + /* array takes the references */ nssList_Destroy(certList); } return rvArray; diff --git a/mozilla/security/nss/lib/pki/trustdomain.c b/mozilla/security/nss/lib/pki/trustdomain.c index c711217d572..d638648e97c 100644 --- a/mozilla/security/nss/lib/pki/trustdomain.c +++ b/mozilla/security/nss/lib/pki/trustdomain.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.22 $ $Date: 2001-12-14 20:50:59 $ $Name: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.23 $ $Date: 2002-01-03 20:09:25 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -355,6 +355,12 @@ NSSTrustDomain_ImportEncodedPublicKey return NULL; } +static void cert_destructor(void *el) +{ + NSSCertificate *c = (NSSCertificate *)el; + NSSCertificate_Destroy(c); +} + struct collect_arg_str { nssList *list; PRUint32 maximum; @@ -411,6 +417,7 @@ NSSTrustDomain_FindBestCertificateByNickname name, &search); } nssListIterator_Finish(td->tokens); + nssList_Clear(nameList, cert_destructor); nssList_Destroy(nameList); if (best.cert) { nssTrustDomain_AddCertsToCache(td, &best.cert, 1); @@ -466,6 +473,7 @@ NSSTrustDomain_FindCertificatesByNickname } nssTrustDomain_AddCertsToCache(td, rvCerts, count); } + nssList_Clear(nameList, cert_destructor); nssList_Destroy(nameList); return rvCerts; } @@ -541,6 +549,7 @@ NSSTrustDomain_FindBestCertificateBySubject subject, &search); } nssListIterator_Finish(td->tokens); + nssList_Clear(subjectList, cert_destructor); nssList_Destroy(subjectList); if (best.cert) { nssTrustDomain_AddCertsToCache(td, &best.cert, 1); @@ -596,6 +605,7 @@ NSSTrustDomain_FindCertificatesBySubject } nssTrustDomain_AddCertsToCache(td, rvCerts, count); } + nssList_Clear(subjectList, cert_destructor); nssList_Destroy(subjectList); return rvCerts; } @@ -694,6 +704,7 @@ NSSTrustDomain_FindCertificateByEmail email, &search); } nssListIterator_Finish(td->tokens); + nssList_Clear(emailList, cert_destructor); nssList_Destroy(emailList); if (best.cert) { nssTrustDomain_AddCertsToCache(td, &best.cert, 1); @@ -848,6 +859,7 @@ NSSTrustDomain_TraverseCertificates nssrv = nssToken_TraverseCertificates(token, NULL, &search); } nssListIterator_Finish(td->tokens); + nssList_Clear(certList, cert_destructor); nssList_Destroy(certList); return NULL; }