Fix for bug 311164 . Initialize stan cert store object early to fix a race condition. r=nelson

This commit is contained in:
julien.pierre.bugs%sun.com 2006-04-07 05:49:04 +00:00
parent 02eed06ed8
commit 7ceb91038f
6 changed files with 107 additions and 27 deletions

View File

@ -155,6 +155,9 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
NSSCryptoContext *context;
nssCryptokiObject *permInstance;
NSSCertificate *c = STAN_GetNSSCertificate(cert);
nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
context = c->object.cryptoContext;
if (!context) {
PORT_SetError(SEC_ERROR_ADDING_CERT);
@ -170,9 +173,10 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena);
}
/* Delete the temp instance */
nssCertificateStore_Lock(context->certStore);
nssCertificateStore_Lock(context->certStore, &lockTrace);
nssCertificateStore_RemoveCertLOCKED(context->certStore, c);
nssCertificateStore_Unlock(context->certStore);
nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace);
nssCertificateStore_Check(&lockTrace, &unlockTrace);
c->object.cryptoContext = NULL;
/* Import the perm instance onto the internal token */
slot = PK11_GetInternalKeySlot();

View File

@ -796,6 +796,8 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
NSSToken *token = PK11Slot_GetNSSToken(slot);
SECItem *keyID = pk11_mkcertKeyID(cert);
char *emailAddr = NULL;
nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
if (keyID == NULL) {
goto loser;
@ -815,9 +817,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
if (c->object.cryptoContext) {
/* Delete the temp instance */
NSSCryptoContext *cc = c->object.cryptoContext;
nssCertificateStore_Lock(cc->certStore);
nssCertificateStore_Lock(cc->certStore, &lockTrace);
nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
nssCertificateStore_Unlock(cc->certStore);
nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace);
nssCertificateStore_Check(&lockTrace, &unlockTrace);
c->object.cryptoContext = NULL;
cert->istemp = PR_FALSE;
cert->isperm = PR_TRUE;

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.56 $ $Date: 2005/07/08 17:06:15 $";
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.57 $ $Date: 2006/04/07 05:49:04 $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -120,6 +120,10 @@ nssCertificate_Destroy (
NSSCertificate *c
)
{
nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
PRBool locked = PR_FALSE;
if (c) {
PRUint32 i;
nssDecodedCert *dc = c->decoding;
@ -130,7 +134,8 @@ nssCertificate_Destroy (
/* --- LOCK storage --- */
if (cc) {
nssCertificateStore_Lock(cc->certStore);
nssCertificateStore_Lock(cc->certStore, &lockTrace);
locked = PR_TRUE;
} else {
nssTrustDomain_LockCertCache(td);
}
@ -138,7 +143,10 @@ nssCertificate_Destroy (
/* --- remove cert and UNLOCK storage --- */
if (cc) {
nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
nssCertificateStore_Unlock(cc->certStore);
nssCertificateStore_Unlock(cc->certStore, &lockTrace,
&unlockTrace);
nssCertificateStore_Check(&lockTrace, &unlockTrace);
} else {
nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
nssTrustDomain_UnlockCertCache(td);
@ -153,12 +161,18 @@ nssCertificate_Destroy (
} else {
/* --- UNLOCK storage --- */
if (cc) {
nssCertificateStore_Unlock(cc->certStore);
nssCertificateStore_Unlock(cc->certStore,
&lockTrace,
&unlockTrace);
nssCertificateStore_Check(&lockTrace, &unlockTrace);
} else {
nssTrustDomain_UnlockCertCache(td);
}
}
}
if (locked) {
nssCertificateStore_Check(&lockTrace, &unlockTrace);
}
return PR_SUCCESS;
}

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.14 $ $Date: 2005/01/20 02:25:49 $";
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.15 $ $Date: 2006/04/07 05:49:04 $";
#endif /* DEBUG */
#ifndef DEV_H
@ -84,6 +84,12 @@ nssCryptoContext_Create (
}
rvCC->td = td;
rvCC->arena = arena;
rvCC->certStore = nssCertificateStore_Create(rvCC->arena);
if (!rvCC->certStore) {
nssArena_Destroy(arena);
return NULL;
}
return rvCC;
}
@ -93,11 +99,14 @@ NSSCryptoContext_Destroy (
)
{
PRStatus status = PR_SUCCESS;
PORT_Assert(cc->certStore);
if (cc->certStore) {
status = nssCertificateStore_Destroy(cc->certStore);
if (status == PR_FAILURE) {
return status;
}
} else {
status = PR_FAILURE;
}
nssArena_Destroy(cc->arena);
return status;
@ -140,11 +149,9 @@ NSSCryptoContext_ImportCertificate (
)
{
PRStatus nssrv;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
cc->certStore = nssCertificateStore_Create(cc->arena);
if (!cc->certStore) {
return PR_FAILURE;
}
return PR_FAILURE;
}
nssrv = nssCertificateStore_Add(cc->certStore, c);
if (nssrv == PR_SUCCESS) {
@ -190,11 +197,9 @@ nssCryptoContext_ImportTrust (
)
{
PRStatus nssrv;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
cc->certStore = nssCertificateStore_Create(cc->arena);
if (!cc->certStore) {
return PR_FAILURE;
}
return PR_FAILURE;
}
nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
#if 0
@ -212,11 +217,9 @@ nssCryptoContext_ImportSMIMEProfile (
)
{
PRStatus nssrv;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
cc->certStore = nssCertificateStore_Create(cc->arena);
if (!cc->certStore) {
return PR_FAILURE;
}
return PR_FAILURE;
}
nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
#if 0
@ -238,6 +241,7 @@ NSSCryptoContext_FindBestCertificateByNickname (
{
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -264,6 +268,7 @@ NSSCryptoContext_FindCertificatesByNickname (
)
{
NSSCertificate **rvCerts;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -282,6 +287,7 @@ NSSCryptoContext_FindCertificateByIssuerAndSerialNumber (
NSSDER *serialNumber
)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -302,6 +308,7 @@ NSSCryptoContext_FindBestCertificateBySubject (
{
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -328,6 +335,7 @@ nssCryptoContext_FindCertificatesBySubject (
)
{
NSSCertificate **rvCerts;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -385,6 +393,7 @@ NSSCryptoContext_FindCertificateByEncodedCertificate (
NSSBER *encodedCertificate
)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -404,6 +413,8 @@ NSSCryptoContext_FindBestCertificateByEmail (
{
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -430,6 +441,7 @@ NSSCryptoContext_FindCertificatesByEmail (
)
{
NSSCertificate **rvCerts;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -546,6 +558,7 @@ nssCryptoContext_FindTrustForCertificate (
NSSCertificate *cert
)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}
@ -558,6 +571,7 @@ nssCryptoContext_FindSMIMEProfileForCertificate (
NSSCertificate *cert
)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
return NULL;
}

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.26 $ $Date: 2005/06/27 21:50:06 $";
static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.27 $ $Date: 2006/04/07 05:49:04 $";
#endif /* DEBUG */
#ifndef PKIM_H
@ -313,18 +313,41 @@ nssCertificateStore_RemoveCertLOCKED (
NSS_IMPLEMENT void
nssCertificateStore_Lock (
nssCertificateStore *store
nssCertificateStore *store, nssCertificateStoreTrace* out
)
{
#ifdef DEBUG
PORT_Assert(out);
out->store = store;
out->lock = store->lock;
out->locked = PR_TRUE;
PZ_Lock(out->lock);
#else
PZ_Lock(store->lock);
#endif
}
NSS_IMPLEMENT void
nssCertificateStore_Unlock (
nssCertificateStore *store
nssCertificateStore *store, nssCertificateStoreTrace* in,
nssCertificateStoreTrace* out
)
{
#ifdef DEBUG
PORT_Assert(in);
PORT_Assert(out);
out->store = store;
out->lock = store->lock;
out->unlocked = PR_TRUE;
PORT_Assert(in->store == out->store);
PORT_Assert(in->lock == out->lock);
PORT_Assert(in->locked);
PZ_Unlock(out->lock);
#else
PZ_Unlock(store->lock);
#endif
}
static NSSCertificate **

View File

@ -38,7 +38,7 @@
#define PKISTORE_H
#ifdef DEBUG
static const char PKISTORE_CVS_ID[] = "@(#) $RCSfile: pkistore.h,v $ $Revision: 1.7 $ $Date: 2005/01/20 02:25:49 $";
static const char PKISTORE_CVS_ID[] = "@(#) $RCSfile: pkistore.h,v $ $Revision: 1.8 $ $Date: 2006/04/07 05:49:04 $";
#endif /* DEBUG */
#ifndef NSSPKIT_H
@ -95,14 +95,36 @@ nssCertificateStore_RemoveCertLOCKED
NSSCertificate *cert
);
struct nssCertificateStoreTraceStr {
nssCertificateStore* store;
PZLock* lock;
PRBool locked;
PRBool unlocked;
};
typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace;
static void nssCertificateStore_Check(nssCertificateStoreTrace* a,
nssCertificateStoreTrace* b) {
PORT_Assert(a->locked);
PORT_Assert(b->unlocked);
PORT_Assert(!a->unlocked);
PORT_Assert(!b->locked);
PORT_Assert(a->lock == b->lock);
PORT_Assert(a->store == b->store);
};
NSS_EXTERN void
nssCertificateStore_Lock (
nssCertificateStore *store
nssCertificateStore *store, nssCertificateStoreTrace* out
);
NSS_EXTERN void
nssCertificateStore_Unlock (
nssCertificateStore *store
nssCertificateStore *store, nssCertificateStoreTrace* in,
nssCertificateStoreTrace* out
);
NSS_EXTERN NSSCertificate **