Change NewTempCertificate(), making the search for the cert and the

subsequent insertion of the cert into the DB into one atomic operation
by holding the certdb's lock around the pair of operations.  Bug 62286.
This commit is contained in:
nelsonb%netscape.com 2000-12-08 03:35:29 +00:00
parent f9ef364f27
commit b48c49ffe4

View File

@ -34,7 +34,7 @@
/* /*
* Permanent Certificate database handling code * Permanent Certificate database handling code
* *
* $Id: pcertdb.c,v 1.4 2000/10/02 23:23:50 wtc%netscape.com Exp $ * $Id: pcertdb.c,v 1.5 2000/12/08 03:35:29 nelsonb%netscape.com Exp $
*/ */
#include "prtime.h" #include "prtime.h"
@ -57,6 +57,10 @@
#include "cdbhdl.h" #include "cdbhdl.h"
/* forward declaration */
CERTCertificate *
CERT_FindCertByDERCertNoLocking(CERTCertDBHandle *handle, SECItem *derCert);
/* /*
* the following functions are wrappers for the db library that implement * the following functions are wrappers for the db library that implement
* a global lock to make the database thread safe. * a global lock to make the database thread safe.
@ -4967,19 +4971,19 @@ NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname,
SECItem keyitem; SECItem keyitem;
SECStatus rv; SECStatus rv;
if ( lockdb ) {
CERT_LockDB(handle);
}
if ( isperm == PR_FALSE ) { if ( isperm == PR_FALSE ) {
cert = CERT_FindCertByDERCert(handle, derCert); cert = CERT_FindCertByDERCertNoLocking(handle, derCert);
if ( cert ) { if ( cert ) {
return(cert); goto winner;
} }
nickname = NULL; nickname = NULL;
} }
if ( lockdb ) {
CERT_LockDB(handle);
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) { if ( arena == NULL ) {
goto loser; goto loser;
@ -5047,6 +5051,8 @@ NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname,
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
winner:
if ( lockdb ) { if ( lockdb ) {
CERT_UnlockDB(handle); CERT_UnlockDB(handle);
} }
@ -5475,6 +5481,37 @@ loser:
return(cert); return(cert);
} }
/*
* look for the given DER certificate in the database
*/
CERTCertificate *
CERT_FindCertByDERCertNoLocking(CERTCertDBHandle *handle, SECItem *derCert)
{
PRArenaPool *arena;
SECItem certKey;
SECStatus rv;
CERTCertificate *cert = NULL;
/* create a scratch arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
return(NULL);
}
/* extract the database key from the cert */
rv = CERT_KeyFromDERCert(arena, derCert, &certKey);
if ( rv != SECSuccess ) {
goto loser;
}
/* find the certificate */
cert = CERT_FindCertByKeyNoLocking(handle, &certKey);
loser:
PORT_FreeArena(arena, PR_FALSE);
return(cert);
}
/* /*
* The following is bunch of types and code to allow looking up a certificate * The following is bunch of types and code to allow looking up a certificate
* by a hash of its subject public key. Because the words "hash" and "key" * by a hash of its subject public key. Because the words "hash" and "key"