More performance improvements for PK11ListCerts/ CERT_GetUserCertByUsage().
git-svn-id: svn://10.0.0.236/trunk@123953 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
caa7c66928
commit
aa413cb2ba
@ -34,7 +34,7 @@
|
||||
/*
|
||||
* Certificate handling code
|
||||
*
|
||||
* $Id: lowcert.c,v 1.8 2002-06-21 20:25:49 relyea%netscape.com Exp $
|
||||
* $Id: lowcert.c,v 1.9 2002-06-24 21:54:39 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
@ -378,14 +378,21 @@ static SECStatus
|
||||
nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
|
||||
SECItem *key)
|
||||
{
|
||||
unsigned int len = sn->len + issuer->len;
|
||||
|
||||
key->len = sn->len + issuer->len;
|
||||
|
||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
|
||||
if (arena) {
|
||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
|
||||
} else {
|
||||
if (len > key->len) {
|
||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
|
||||
}
|
||||
}
|
||||
if ( !key->data ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
key->len = len;
|
||||
/* copy the serialNumber */
|
||||
PORT_Memcpy(key->data, sn->data, sn->len);
|
||||
|
||||
@ -404,60 +411,39 @@ loser:
|
||||
* take a DER certificate and decode it into a certificate structure
|
||||
*/
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
|
||||
char *nickname)
|
||||
nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
|
||||
{
|
||||
NSSLOWCERTCertificate *cert;
|
||||
PRArenaPool *arena;
|
||||
void *data;
|
||||
int rv;
|
||||
int len;
|
||||
|
||||
/* make a new arena */
|
||||
arena = PORT_NewArena(SOFT_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if ( !arena ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate the certificate structure */
|
||||
cert = (NSSLOWCERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWCERTCertificate));
|
||||
cert = nsslowcert_CreateCert();
|
||||
|
||||
if ( !cert ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
cert->arena = arena;
|
||||
|
||||
if ( copyDER ) {
|
||||
/* copy the DER data for the cert into this arena */
|
||||
data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
|
||||
if ( !data ) {
|
||||
goto loser;
|
||||
}
|
||||
cert->derCert.data = (unsigned char *)data;
|
||||
cert->derCert.len = derSignedCert->len;
|
||||
PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
|
||||
} else {
|
||||
/* point to passed in DER data */
|
||||
cert->derCert = *derSignedCert;
|
||||
}
|
||||
cert->derCert = *derSignedCert;
|
||||
cert->nickname = NULL;
|
||||
cert->certKey.data = NULL;
|
||||
cert->referenceCount = 1;
|
||||
|
||||
/* decode the certificate info */
|
||||
rv = nsslowcert_GetCertFields(cert->derCert.data, cert->derCert.len,
|
||||
&cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject,
|
||||
&cert->validity, &cert->derSubjKeyInfo);
|
||||
|
||||
/*rv = SEC_ASN1DecodeItem(arena, cert, nsslowcert_SignedCertificateTemplate,
|
||||
&cert->derCert); */
|
||||
|
||||
/* cert->subjectKeyID; x509v3 subject key identifier */
|
||||
cert->subjectKeyID.data = NULL;
|
||||
cert->subjectKeyID.len = 0;
|
||||
cert->dbEntry = NULL;
|
||||
cert ->trust = NULL;
|
||||
|
||||
/* generate and save the database key for the cert */
|
||||
/*rv = nsslowcert_KeyFromDERCert(arena, &cert->derCert, &cert->certKey); */
|
||||
rv = nsslowcert_KeyFromIssuerAndSN(arena, &cert->derIssuer,
|
||||
cert->certKey.data = cert->certKeySpace;
|
||||
cert->certKey.len = sizeof(cert->certKeySpace);
|
||||
rv = nsslowcert_KeyFromIssuerAndSN(NULL, &cert->derIssuer,
|
||||
&cert->serialNumber, &cert->certKey);
|
||||
if ( rv ) {
|
||||
goto loser;
|
||||
@ -468,13 +454,8 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
|
||||
cert->nickname = NULL;
|
||||
} else {
|
||||
/* copy and install the nickname */
|
||||
len = PORT_Strlen(nickname) + 1;
|
||||
cert->nickname = (char*)PORT_ArenaAlloc(arena, len);
|
||||
if ( cert->nickname == NULL ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memcpy(cert->nickname, nickname, len);
|
||||
cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
|
||||
sizeof(cert->nicknameSpace));
|
||||
}
|
||||
|
||||
#ifdef FIXME
|
||||
@ -494,9 +475,8 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
|
||||
return(cert);
|
||||
|
||||
loser:
|
||||
|
||||
if ( arena ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
if (cert) {
|
||||
nsslowcert_DestroyCertificate(cert);
|
||||
}
|
||||
|
||||
return(0);
|
||||
@ -538,10 +518,10 @@ nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key)
|
||||
int rv;
|
||||
NSSLOWCERTCertKey certkey;
|
||||
|
||||
PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
|
||||
PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
|
||||
|
||||
rv = nsslowcert_GetCertFields(derCert->data, derCert->len,
|
||||
&certkey.derIssuer, &certkey.serialNumber, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
||||
if ( rv ) {
|
||||
goto loser;
|
||||
@ -556,7 +536,7 @@ loser:
|
||||
NSSLOWKEYPublicKey *
|
||||
nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
|
||||
{
|
||||
NSSLOWCERTSubjectPublicKeyInfo *spki = cert->subjectPublicKeyInfo;
|
||||
NSSLOWCERTSubjectPublicKeyInfo spki;
|
||||
NSSLOWKEYPublicKey *pubk;
|
||||
SECItem os;
|
||||
SECStatus rv;
|
||||
@ -575,29 +555,21 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
|
||||
}
|
||||
|
||||
pubk->arena = arena;
|
||||
PORT_Memset(&spki,0,sizeof(spki));
|
||||
|
||||
/* we haven't bothered decoding the spki struct yet, do it now */
|
||||
if (spki == NULL) {
|
||||
spki = (NSSLOWCERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(cert->arena,
|
||||
sizeof(NSSLOWCERTSubjectPublicKeyInfo));
|
||||
if (spki == NULL) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
rv = SEC_ASN1DecodeItem(cert->arena, spki,
|
||||
rv = SEC_ASN1DecodeItem(arena, &spki,
|
||||
nsslowcert_SubjectPublicKeyInfoTemplate, &cert->derSubjKeyInfo);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
cert->subjectPublicKeyInfo = spki;
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert bit string length from bits to bytes */
|
||||
os = spki->subjectPublicKey;
|
||||
os = spki.subjectPublicKey;
|
||||
DER_ConvertBitString (&os);
|
||||
|
||||
tag = SECOID_GetAlgorithmTag(&spki->algorithm);
|
||||
tag = SECOID_GetAlgorithmTag(&spki.algorithm);
|
||||
switch ( tag ) {
|
||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
|
||||
@ -147,7 +147,7 @@ char *nsslowcert_FixupEmailAddr(char *emailAddr);
|
||||
** then a temporary nickname is generated.
|
||||
*/
|
||||
extern NSSLOWCERTCertificate *
|
||||
nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname);
|
||||
nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, char *nickname);
|
||||
|
||||
SECStatus
|
||||
nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
|
||||
@ -215,6 +215,20 @@ nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust);
|
||||
void
|
||||
nsslowcert_DestroyGlobalLocks(void);
|
||||
|
||||
void
|
||||
pkcs11_freeNickname(char *nickname, char *space);
|
||||
|
||||
char *
|
||||
pkcs11_copyNickname(char *nickname, char *space, int spaceLen);
|
||||
|
||||
void
|
||||
pkcs11_freeStaticData(unsigned char *data, unsigned char *space);
|
||||
|
||||
unsigned char *
|
||||
pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
|
||||
int spaceLen);
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_CreateCert(void);
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _PCERTDB_H_ */
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
/*
|
||||
* Permanent Certificate database handling code
|
||||
*
|
||||
* $Id: pcertdb.c,v 1.22 2002-06-20 18:46:46 relyea%netscape.com Exp $
|
||||
* $Id: pcertdb.c,v 1.23 2002-06-24 21:54:39 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "prtime.h"
|
||||
|
||||
@ -62,6 +62,17 @@
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
|
||||
|
||||
|
||||
static NSSLOWCERTCertificate *certListHead = NULL;
|
||||
static NSSLOWCERTTrust *trustListHead = NULL;
|
||||
static certDBEntryCert *entryListHead = NULL;
|
||||
static int certListCount = 0;
|
||||
static int trustListCount = 0;
|
||||
static int entryListCount = 0;
|
||||
#define MAX_CERT_LIST_COUNT 10
|
||||
#define MAX_TRUST_LIST_COUNT 10
|
||||
#define MAX_ENTRY_LIST_COUNT 10
|
||||
|
||||
/*
|
||||
* the following functions are wrappers for the db library that implement
|
||||
* a global lock to make the database thread safe.
|
||||
@ -183,6 +194,43 @@ nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
|
||||
return;
|
||||
}
|
||||
|
||||
static PZLock *freeListLock = NULL;
|
||||
|
||||
/*
|
||||
* Acquire the cert reference count lock
|
||||
* There is currently one global lock for all certs, but I'm putting a cert
|
||||
* arg here so that it will be easy to make it per-cert in the future if
|
||||
* that turns out to be necessary.
|
||||
*/
|
||||
static void
|
||||
nsslowcert_LockFreeList(void)
|
||||
{
|
||||
if ( freeListLock == NULL ) {
|
||||
nss_InitLock(&freeListLock, nssILockRefLock);
|
||||
PORT_Assert(freeListLock != NULL);
|
||||
}
|
||||
|
||||
PZ_Lock(freeListLock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the cert reference count lock
|
||||
*/
|
||||
static void
|
||||
nsslowcert_UnlockFreeList(void)
|
||||
{
|
||||
PRStatus prstat;
|
||||
|
||||
PORT_Assert(freeListLock != NULL);
|
||||
|
||||
prstat = PZ_Unlock(freeListLock);
|
||||
|
||||
PORT_Assert(prstat == PR_SUCCESS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_DupCertificate(NSSLOWCERTCertificate *c)
|
||||
{
|
||||
@ -295,6 +343,98 @@ certdb_Close(DB *db)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
pkcs11_freeNickname(char *nickname, char *space)
|
||||
{
|
||||
if (nickname && nickname != space) {
|
||||
PORT_Free(nickname);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
pkcs11_copyNickname(char *nickname,char *space, int spaceLen)
|
||||
{
|
||||
int len;
|
||||
char *copy = NULL;
|
||||
|
||||
len = PORT_Strlen(nickname)+1;
|
||||
if (len <= spaceLen) {
|
||||
copy = space;
|
||||
PORT_Memcpy(copy,nickname,len);
|
||||
} else {
|
||||
copy = PORT_Strdup(nickname);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void
|
||||
pkcs11_freeStaticData (unsigned char *data, unsigned char *space)
|
||||
{
|
||||
if (data && data != space) {
|
||||
PORT_Free(data);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
pkcs11_copyStaticData(unsigned char *data, int len,
|
||||
unsigned char *space, int spaceLen)
|
||||
{
|
||||
unsigned char *copy = NULL;
|
||||
|
||||
if (len <= spaceLen) {
|
||||
copy = space;
|
||||
} else {
|
||||
copy = (unsigned char *) PORT_Alloc(len);
|
||||
}
|
||||
if (copy) {
|
||||
PORT_Memcpy(copy,data,len);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy a database entry
|
||||
*/
|
||||
static void
|
||||
DestroyDBEntry(certDBEntry *entry)
|
||||
{
|
||||
PRArenaPool *arena = entry->common.arena;
|
||||
|
||||
/* must be one of our certDBEntry from the free list */
|
||||
if (arena == NULL) {
|
||||
certDBEntryCert *certEntry;
|
||||
if ( entry->common.type != certDBEntryTypeCert) {
|
||||
return;
|
||||
}
|
||||
certEntry = (certDBEntryCert *)entry;
|
||||
|
||||
pkcs11_freeStaticData(certEntry->derCert.data, certEntry->derCertSpace);
|
||||
pkcs11_freeNickname(certEntry->nickname, certEntry->nicknameSpace);
|
||||
|
||||
nsslowcert_LockFreeList();
|
||||
if (entryListCount > MAX_ENTRY_LIST_COUNT) {
|
||||
PORT_Free(certEntry);
|
||||
} else {
|
||||
entryListCount++;
|
||||
PORT_Memset(certEntry, 0, sizeof( *certEntry));
|
||||
certEntry->next = entryListHead;
|
||||
entryListHead = certEntry;
|
||||
}
|
||||
nsslowcert_UnlockFreeList();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Zero out the entry struct, so that any further attempts to use it
|
||||
* will cause an exception (e.g. null pointer reference). */
|
||||
PORT_Memset(&entry->common, 0, sizeof entry->common);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* forward references */
|
||||
static void nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert);
|
||||
|
||||
@ -507,7 +647,7 @@ EncodeDBCertKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey)
|
||||
dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
|
||||
} else {
|
||||
if (dbkey->len < len) {
|
||||
dbkey->data = (unsigned char *)PORT_Alloc(dbkey->len);
|
||||
dbkey->data = (unsigned char *)PORT_Alloc(len);
|
||||
}
|
||||
}
|
||||
dbkey->len = len;
|
||||
@ -603,26 +743,23 @@ DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
|
||||
}
|
||||
|
||||
/* copy the dercert */
|
||||
entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
|
||||
entry->derCert.len);
|
||||
|
||||
entry->derCert.data = pkcs11_copyStaticData(&dbentry->data[headerlen],
|
||||
entry->derCert.len,entry->derCertSpace,sizeof(entry->derCertSpace));
|
||||
if ( entry->derCert.data == NULL ) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(entry->derCert.data, &dbentry->data[headerlen],
|
||||
entry->derCert.len);
|
||||
|
||||
/* copy the nickname */
|
||||
if ( nnlen > 1 ) {
|
||||
entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
|
||||
entry->nickname = (char *)pkcs11_copyStaticData(
|
||||
&dbentry->data[headerlen+entry->derCert.len], nnlen,
|
||||
entry->nicknameSpace, sizeof(entry->nicknameSpace));
|
||||
if ( entry->nickname == NULL ) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(entry->nickname,
|
||||
&dbentry->data[headerlen +
|
||||
entry->derCert.len],
|
||||
nnlen);
|
||||
} else {
|
||||
entry->nickname = NULL;
|
||||
}
|
||||
@ -876,6 +1013,25 @@ loser:
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
static certDBEntryCert *
|
||||
CreateCertEntry(void)
|
||||
{
|
||||
certDBEntryCert *entry;
|
||||
|
||||
nsslowcert_LockFreeList();
|
||||
entry = entryListHead;
|
||||
if (entry) {
|
||||
entryListCount--;
|
||||
entryListHead = entry->next;
|
||||
}
|
||||
nsslowcert_UnlockFreeList();
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
return PORT_ZAlloc(sizeof(certDBEntryCert));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a certificate entry
|
||||
*/
|
||||
@ -891,19 +1047,13 @@ ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
|
||||
|
||||
dbkey.data = buf;
|
||||
dbkey.len = sizeof(buf);
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if ( arena == NULL ) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
|
||||
entry = CreateCertEntry();
|
||||
if ( entry == NULL ) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
entry->common.arena = arena;
|
||||
entry->common.arena = NULL;
|
||||
entry->common.type = certDBEntryTypeCert;
|
||||
|
||||
rv = EncodeDBCertKey(certKey, NULL, &dbkey);
|
||||
@ -920,19 +1070,18 @@ ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (dbkey.data && dbkey.data != buf) {
|
||||
PORT_Free(dbkey.data);
|
||||
}
|
||||
|
||||
pkcs11_freeStaticData(dbkey.data,buf);
|
||||
dbkey.data = NULL;
|
||||
return(entry);
|
||||
|
||||
loser:
|
||||
if (dbkey.data && dbkey.data != buf) {
|
||||
PORT_Free(dbkey.data);
|
||||
}
|
||||
if ( arena ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
pkcs11_freeStaticData(dbkey.data,buf);
|
||||
dbkey.data = NULL;
|
||||
if ( entry ) {
|
||||
|
||||
}
|
||||
DestroyDBEntry((certDBEntry *)entry);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
@ -1242,22 +1391,6 @@ loser:
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy a database entry
|
||||
*/
|
||||
static void
|
||||
DestroyDBEntry(certDBEntry *entry)
|
||||
{
|
||||
PRArenaPool *arena = entry->common.arena;
|
||||
|
||||
/* Zero out the entry struct, so that any further attempts to use it
|
||||
* will cause an exception (e.g. null pointer reference). */
|
||||
PORT_Memset(&entry->common, 0, sizeof entry->common);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
nsslowcert_DestroyDBEntry(certDBEntry *entry)
|
||||
{
|
||||
@ -2992,14 +3125,21 @@ AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
|
||||
goto loser;
|
||||
}
|
||||
|
||||
entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
|
||||
pkcs11_freeNickname(entry->nickname,entry->nicknameSpace);
|
||||
entry->nickname = NULL;
|
||||
entry->nickname = pkcs11_copyNickname(nickname,entry->nicknameSpace,
|
||||
sizeof(entry->nicknameSpace));
|
||||
|
||||
rv = WriteDBCertEntry(dbhandle, entry);
|
||||
if ( rv ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
|
||||
pkcs11_freeNickname(cert->nickname,cert->nicknameSpace);
|
||||
cert->nickname = NULL;
|
||||
cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
|
||||
sizeof(cert->nicknameSpace));
|
||||
|
||||
return(SECSuccess);
|
||||
|
||||
loser:
|
||||
@ -3458,7 +3598,7 @@ UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
|
||||
derSubject.data = NULL;
|
||||
|
||||
if ( entry ) {
|
||||
cert = nsslowcert_DecodeDERCertificate(&entry->derCert, PR_TRUE,
|
||||
cert = nsslowcert_DecodeDERCertificate(&entry->derCert,
|
||||
entry->nickname);
|
||||
|
||||
if ( cert != NULL ) {
|
||||
@ -3866,8 +4006,7 @@ DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
|
||||
{
|
||||
NSSLOWCERTCertificate *cert = NULL;
|
||||
|
||||
cert = nsslowcert_DecodeDERCertificate(&entry->derCert, PR_TRUE,
|
||||
entry->nickname );
|
||||
cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname );
|
||||
|
||||
if ( cert == NULL ) {
|
||||
goto loser;
|
||||
@ -3883,15 +4022,38 @@ loser:
|
||||
return(0);
|
||||
}
|
||||
|
||||
static NSSLOWCERTTrust *
|
||||
CreateTrust(void)
|
||||
{
|
||||
NSSLOWCERTTrust *trust = NULL;
|
||||
|
||||
nsslowcert_LockFreeList();
|
||||
trust = trustListHead;
|
||||
if (trust) {
|
||||
trustListCount--;
|
||||
trustListHead = trust->next;
|
||||
}
|
||||
nsslowcert_UnlockFreeList();
|
||||
if (trust) {
|
||||
return trust;
|
||||
}
|
||||
|
||||
return PORT_ZAlloc(sizeof(NSSLOWCERTTrust));
|
||||
}
|
||||
|
||||
|
||||
static NSSLOWCERTTrust *
|
||||
DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry, SECItem *dbKey)
|
||||
{
|
||||
NSSLOWCERTTrust *trust = PORT_Alloc(sizeof(NSSLOWCERTTrust));
|
||||
NSSLOWCERTTrust *trust = CreateTrust();
|
||||
if (trust == NULL) {
|
||||
return trust;
|
||||
}
|
||||
trust->dbhandle = handle;
|
||||
trust->dbEntry = entry;
|
||||
trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len,
|
||||
trust->dbKeySpace, sizeof(trust->dbKeySpace));
|
||||
trust->dbKey.len = dbKey->len;
|
||||
SECITEM_CopyItem(NULL, &trust->dbKey , dbKey);
|
||||
trust->trust = &entry->trust;
|
||||
trust->derCert = &entry->derCert;
|
||||
@ -4120,8 +4282,11 @@ nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
|
||||
ret = SECFailure;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pkcs11_freeNickname(oldnn,cert->nicknameSpace);
|
||||
|
||||
cert->nickname = (entry->nickname) ? PORT_ArenaStrdup(cert->arena,entry->nickname) : NULL;
|
||||
cert->nickname = (entry->nickname) ? pkcs11_copyNickname(entry->nickname,
|
||||
cert->nicknameSpace, sizeof(cert->nicknameSpace)) : NULL;
|
||||
cert->trust = &entry->trust;
|
||||
cert->dbEntry = entry;
|
||||
|
||||
@ -4169,7 +4334,6 @@ loser:
|
||||
static NSSLOWCERTCertificate *
|
||||
FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey, PRBool lockdb)
|
||||
{
|
||||
SECStatus rv;
|
||||
NSSLOWCERTCertificate *cert = NULL;
|
||||
PRArenaPool *arena = NULL;
|
||||
certDBEntryCert *entry;
|
||||
@ -4210,7 +4374,6 @@ loser:
|
||||
static NSSLOWCERTTrust *
|
||||
FindTrustByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey, PRBool lockdb)
|
||||
{
|
||||
SECStatus rv;
|
||||
NSSLOWCERTTrust *trust = NULL;
|
||||
PRArenaPool *arena = NULL;
|
||||
certDBEntryCert *entry;
|
||||
@ -4314,6 +4477,7 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
|
||||
}
|
||||
}
|
||||
|
||||
certKey.type = 0;
|
||||
certKey.data = (unsigned char*)PORT_Alloc(sn->len + issuer->len);
|
||||
certKey.len = data_len + issuer->len;
|
||||
|
||||
@ -4397,6 +4561,7 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
|
||||
}
|
||||
}
|
||||
|
||||
certKey.type = 0;
|
||||
certKey.data = (unsigned char*)PORT_Alloc(sn->len + issuer->len);
|
||||
certKey.len = data_len + issuer->len;
|
||||
|
||||
@ -4493,20 +4658,32 @@ DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
|
||||
|
||||
if ( ( refCount == 0 ) ) {
|
||||
certDBEntryCert *entry = cert->dbEntry;
|
||||
PRArenaPool * arena = cert->arena;
|
||||
|
||||
if ( entry ) {
|
||||
DestroyDBEntry((certDBEntry *)entry);
|
||||
}
|
||||
|
||||
pkcs11_freeNickname(cert->nickname,cert->nicknameSpace);
|
||||
pkcs11_freeStaticData(cert->certKey.data,cert->certKeySpace);
|
||||
cert->certKey.data = NULL;
|
||||
cert->nickname = NULL;
|
||||
|
||||
/* zero cert before freeing. Any stale references to this cert
|
||||
* after this point will probably cause an exception. */
|
||||
PORT_Memset(cert, 0, sizeof *cert);
|
||||
|
||||
/* use reflock to protect the free list */
|
||||
nsslowcert_LockFreeList();
|
||||
if (certListCount > MAX_CERT_LIST_COUNT) {
|
||||
PORT_Free(cert);
|
||||
} else {
|
||||
certListCount++;
|
||||
cert->next = certListHead;
|
||||
certListHead = cert;
|
||||
}
|
||||
nsslowcert_UnlockFreeList();
|
||||
|
||||
cert = NULL;
|
||||
|
||||
/* free the arena that contains the cert. */
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
if ( lockdb && handle ) {
|
||||
nsslowcert_UnlockDB(handle);
|
||||
@ -4516,6 +4693,24 @@ DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
|
||||
return;
|
||||
}
|
||||
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_CreateCert(void)
|
||||
{
|
||||
NSSLOWCERTCertificate *cert;
|
||||
nsslowcert_LockFreeList();
|
||||
cert = certListHead;
|
||||
if (cert) {
|
||||
certListHead = cert->next;
|
||||
certListCount--;
|
||||
}
|
||||
nsslowcert_UnlockFreeList();
|
||||
|
||||
if (cert) {
|
||||
return cert;
|
||||
}
|
||||
return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate));
|
||||
}
|
||||
|
||||
void
|
||||
nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
|
||||
{
|
||||
@ -4524,10 +4719,18 @@ nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
|
||||
if ( entry ) {
|
||||
DestroyDBEntry((certDBEntry *)entry);
|
||||
}
|
||||
if (trust->dbKey.data) {
|
||||
PORT_Free(trust->dbKey.data);
|
||||
pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace);
|
||||
PORT_Memset(trust, 0, sizeof(*trust));
|
||||
|
||||
nsslowcert_LockFreeList();
|
||||
if (trustListCount > MAX_TRUST_LIST_COUNT) {
|
||||
PORT_Free(trust);
|
||||
} else {
|
||||
trustListCount++;
|
||||
trust->next = trustListHead;
|
||||
trustListHead = trust;
|
||||
}
|
||||
PORT_Free(trust);
|
||||
nsslowcert_UnlockFreeList();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
/*
|
||||
* certt.h - public data structures for the certificate library
|
||||
*
|
||||
* $Id: pcertt.h,v 1.5 2002-06-20 18:46:46 relyea%netscape.com Exp $
|
||||
* $Id: pcertt.h,v 1.6 2002-06-24 21:54:40 relyea%netscape.com Exp $
|
||||
*/
|
||||
#ifndef _PCERTT_H_
|
||||
#define _PCERTT_H_
|
||||
@ -111,11 +111,13 @@ struct NSSLOWCERTCertTrustStr {
|
||||
** PKCS11 Trust representation
|
||||
*/
|
||||
struct NSSLOWCERTTrustStr {
|
||||
NSSLOWCERTTrust *next;
|
||||
NSSLOWCERTCertDBHandle *dbhandle;
|
||||
SECItem dbKey; /* database key for this cert */
|
||||
certDBEntryCert *dbEntry; /* database entry struct */
|
||||
NSSLOWCERTCertTrust *trust;
|
||||
SECItem *derCert; /* original DER for the cert */
|
||||
unsigned char dbKeySpace[512];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -128,7 +130,7 @@ struct NSSLOWCERTCertificateStr {
|
||||
* cert is decoded, destroyed, and at some times when it changes
|
||||
* state
|
||||
*/
|
||||
PRArenaPool *arena;
|
||||
NSSLOWCERTCertificate *next;
|
||||
NSSLOWCERTCertDBHandle *dbhandle;
|
||||
|
||||
SECItem derCert; /* original DER for the cert */
|
||||
@ -150,7 +152,11 @@ struct NSSLOWCERTCertificateStr {
|
||||
* or destroys a certificate
|
||||
*/
|
||||
int referenceCount;
|
||||
|
||||
char nicknameSpace[200];
|
||||
char certKeySpace[512];
|
||||
};
|
||||
|
||||
#define SEC_CERTIFICATE_VERSION_1 0 /* default created */
|
||||
#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */
|
||||
#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */
|
||||
@ -253,9 +259,12 @@ typedef struct {
|
||||
*/
|
||||
struct _certDBEntryCert {
|
||||
certDBEntryCommon common;
|
||||
certDBEntryCert *next;
|
||||
NSSLOWCERTCertTrust trust;
|
||||
SECItem derCert;
|
||||
char *nickname;
|
||||
char nicknameSpace[200];
|
||||
unsigned char derCertSpace[2048];
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -618,6 +618,7 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
|
||||
attribute = pk11_FindAttribute(object,CKA_VALUE);
|
||||
PORT_Assert(attribute);
|
||||
|
||||
derCert.type = 0;
|
||||
derCert.data = (unsigned char *)attribute->attrib.pValue;
|
||||
derCert.len = attribute->attrib.ulValueLen ;
|
||||
|
||||
@ -625,7 +626,7 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
|
||||
|
||||
cert = nsslowcert_FindCertByDERCert(slot->certDB, &derCert);
|
||||
if (cert == NULL) {
|
||||
cert = nsslowcert_DecodeDERCertificate(&derCert,PR_FALSE,label);
|
||||
cert = nsslowcert_DecodeDERCertificate(&derCert, label);
|
||||
inDB = PR_FALSE;
|
||||
}
|
||||
if (cert == NULL) {
|
||||
@ -738,7 +739,7 @@ pk11_handleTrustObject(PK11Session *session,PK11Object *object)
|
||||
CK_TRUST clientTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
|
||||
CK_TRUST emailTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
|
||||
CK_TRUST signTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
|
||||
NSSLOWCERTCertTrust dbTrust = { 0 } ;
|
||||
NSSLOWCERTCertTrust dbTrust = { 0 };
|
||||
SECStatus rv;
|
||||
|
||||
|
||||
|
||||
@ -1054,7 +1054,7 @@ pk11_FindCertAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
|
||||
if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
|
||||
((cert->trust->emailFlags & CERTDB_USER) == 0) &&
|
||||
((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
|
||||
return (PK11Attribute *)&pk11_StaticNullAttr;
|
||||
return NULL;
|
||||
}
|
||||
pubKey = nsslowcert_ExtractPublicKey(cert);
|
||||
if (pubKey == NULL) break;
|
||||
@ -1744,10 +1744,10 @@ pk11_deleteTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle)
|
||||
PRBool rem;
|
||||
|
||||
item = (SECItem *)PL_HashTableLookup(slot->tokenHashTable, (void *)handle);
|
||||
if (item) {
|
||||
rem = PL_HashTableRemove(slot->tokenHashTable,(void *)handle) ;
|
||||
if (rem && item) {
|
||||
SECITEM_FreeItem(item,PR_TRUE);
|
||||
}
|
||||
rem = PL_HashTableRemove(slot->tokenHashTable,(void *)handle) ;
|
||||
return rem ? SECSuccess : SECFailure;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user