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.

This commit is contained in:
ian.mcgreer%sun.com 2002-01-03 20:09:30 +00:00
Родитель 3c7d0ffdc4
Коммит 82b1f2de39
11 изменённых файлов: 260 добавлений и 153 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.8 $ $Date: 2002/01/03 20:09:18 $ $Name: $";
#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;
}

Просмотреть файл

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

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.8 $ $Date: 2002/01/03 20:09:21 $ $Name: $";
#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

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.22 $ $Date: 2002/01/03 20:09:23 $ $Name: $";
#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;
}

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.17 $ $Date: 2002/01/03 20:09:23 $ $Name: $";
#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;

Просмотреть файл

@ -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: $";
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.13 $ $Date: 2002/01/03 20:09:24 $ $Name: $";
#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

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.3 $ $Date: 2002/01/03 20:09:24 $ $Name: $";
#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

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.18 $ $Date: 2002/01/03 20:09:24 $ $Name: $";
#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;

Просмотреть файл

@ -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: $";
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.23 $ $Date: 2002/01/03 20:09:25 $ $Name: $";
#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;
}