Bug 329002. fix cert reference leak. r=alexei.volkov,rrelyea

This commit is contained in:
nelson%bolyard.com 2006-03-09 23:38:57 +00:00
Родитель d0d0625c18
Коммит 19a46702bf
1 изменённых файлов: 37 добавлений и 60 удалений

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

@ -37,7 +37,7 @@
/*
* Permanent Certificate database handling code
*
* $Id: pcertdb.c,v 1.56 2006/01/21 02:23:42 nelsonb%netscape.com Exp $
* $Id: pcertdb.c,v 1.57 2006/03/09 23:38:57 nelson%bolyard.com Exp $
*/
#include "prtime.h"
@ -3023,10 +3023,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
SECItem *newCertKeys, *newKeyIDs;
unsigned int i, new_i;
SECStatus rv;
NSSLOWCERTCertificate *cmpcert;
unsigned int nnlen;
unsigned int ncerts;
PRBool added = PR_FALSE;
PORT_Assert(entry);
ncerts = entry->ncerts;
@ -3038,25 +3035,24 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) {
/* copy nickname into the entry */
nnlen = PORT_Strlen(nickname) + 1;
entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,nnlen);
entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
if ( entry->nickname == NULL ) {
return(SECFailure);
}
PORT_Memcpy(entry->nickname, nickname, nnlen);
}
/* a DB entry already exists, so add this cert */
newCertKeys = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
sizeof(SECItem) * ( ncerts + 1 ) );
newKeyIDs = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
sizeof(SECItem) * ( ncerts + 1 ) );
newCertKeys = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
newKeyIDs = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) {
return(SECFailure);
}
/* Step 1: copy certs older than "cert" into new entry. */
for ( i = 0, new_i=0; i < ncerts; i++ ) {
NSSLOWCERTCertificate *cmpcert;
PRBool isNewer;
cmpcert = nsslowcert_FindCertByKey(cert->dbhandle,
&entry->certKeys[i]);
/* The entry has been corrupted, remove it from the list */
@ -3064,61 +3060,42 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
continue;
}
if ( nsslowcert_IsNewer(cert, cmpcert) ) {
/* insert before cmpcert */
rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
&cert->certKey);
if ( rv != SECSuccess ) {
return(SECFailure);
}
rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
&cert->subjectKeyID);
if ( rv != SECSuccess ) {
return(SECFailure);
}
new_i++;
/* copy the rest of the entry */
for ( ; i < ncerts; i++ ,new_i++) {
newCertKeys[new_i] = entry->certKeys[i];
newKeyIDs[new_i] = entry->keyIDs[i];
}
/* update certKeys and keyIDs */
entry->certKeys = newCertKeys;
entry->keyIDs = newKeyIDs;
/* set new count value */
entry->ncerts = new_i;
added = PR_TRUE;
isNewer = nsslowcert_IsNewer(cert, cmpcert);
nsslowcert_DestroyCertificate(cmpcert);
if ( isNewer )
break;
}
/* copy this cert entry */
newCertKeys[new_i] = entry->certKeys[i];
newKeyIDs[new_i] = entry->keyIDs[i];
new_i++; /* only increment if we copied the entries */
newKeyIDs[new_i] = entry->keyIDs[i];
new_i++;
}
if ( !added ) {
/* insert new one at end */
rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
&cert->certKey);
if ( rv != SECSuccess ) {
return(SECFailure);
}
rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
&cert->subjectKeyID);
if ( rv != SECSuccess ) {
return(SECFailure);
}
new_i++;
/* update certKeys and keyIDs */
entry->certKeys = newCertKeys;
entry->keyIDs = newKeyIDs;
/* increment count */
entry->ncerts = new_i;
/* Step 2: Add "cert" to the entry. */
rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
&cert->certKey);
if ( rv != SECSuccess ) {
return(SECFailure);
}
rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
&cert->subjectKeyID);
if ( rv != SECSuccess ) {
return(SECFailure);
}
new_i++;
/* Step 3: copy remaining certs (if any) from old entry to new. */
for ( ; i < ncerts; i++ ,new_i++) {
newCertKeys[new_i] = entry->certKeys[i];
newKeyIDs[new_i] = entry->keyIDs[i];
}
/* update certKeys and keyIDs */
entry->certKeys = newCertKeys;
entry->keyIDs = newKeyIDs;
/* set new count value */
entry->ncerts = new_i;
DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
rv = WriteDBSubjectEntry(cert->dbhandle, entry);
return(rv);