move handling of certificate reference counting into Stan. NSS 3.4 needs to maintain persistent references of both temp and perm certs in order to replicate the old temp database.

git-svn-id: svn://10.0.0.236/trunk@111308 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
ian.mcgreer%sun.com
2002-01-03 20:09:30 +00:00
parent 77a48bf25c
commit f85961a3de
11 changed files with 260 additions and 153 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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; i<count; i++) nssCertificate_AddRef(rvOpt[i]);
} else {
rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
if (!rvArray) {
return (NSSCertificate **)NULL;
}
nssList_GetArray(subjectList, (void **)rvArray, count);
for (i=0; i<count; i++) nssCertificate_AddRef(rvArray[i]);
}
}
return rvArray;
@@ -386,7 +391,7 @@ nssCertificateStore_FindCertificatesByNickname
NSSArena *arenaOpt
)
{
PRUint32 count;
PRUint32 i, count;
NSSCertificate **rvArray = NULL;
struct nickname_template_str nt;
nt.nickname = nickname;
@@ -401,12 +406,14 @@ nssCertificateStore_FindCertificatesByNickname
}
if (rvOpt) {
nssList_GetArray(nt.subjectList, (void **)rvOpt, count);
for (i=0; i<count; i++) nssCertificate_AddRef(rvOpt[i]);
} else {
rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
if (!rvArray) {
return (NSSCertificate **)NULL;
}
nssList_GetArray(nt.subjectList, (void **)rvArray, count);
for (i=0; i<count; i++) nssCertificate_AddRef(rvArray[i]);
}
}
return rvArray;
@@ -455,7 +462,7 @@ nssCertificateStore_FindCertificatesByEmail
NSSArena *arenaOpt
)
{
PRUint32 count;
PRUint32 i, count;
NSSCertificate **rvArray = NULL;
struct email_template_str et;
et.email = email;
@@ -473,12 +480,14 @@ nssCertificateStore_FindCertificatesByEmail
}
if (rvOpt) {
nssList_GetArray(et.emailList, (void **)rvOpt, count);
for (i=0; i<count; i++) nssCertificate_AddRef(rvOpt[i]);
} else {
rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
if (!rvArray) {
return (NSSCertificate **)NULL;
}
nssList_GetArray(et.emailList, (void **)rvArray, count);
for (i=0; i<count; i++) nssCertificate_AddRef(rvArray[i]);
}
}
return rvArray;
@@ -501,7 +510,7 @@ nssCertificateStore_FindCertificateByIssuerAndSerialNumber
nssHash_Lookup(store->issuer_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

View File

@@ -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; i<count; i++) nssCertificate_AddRef(rvArray[i]);
}
return rvArray;
}
@@ -903,7 +907,7 @@ nssTrustDomain_GetCertForIssuerAndSNFromCache
#endif
}
PZ_Unlock(td->cache->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;

View File

@@ -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;
}