Fix cert leaks when building a chain. There are several client auth bugs filed, this may not be for any one in particular, but was found with tstclnt.
git-svn-id: svn://10.0.0.236/trunk@113532 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1084,21 +1084,23 @@ loser:
|
||||
|
||||
arena = PORT_NewArena(4096);
|
||||
if (arena == NULL) {
|
||||
/* XXX destroy certs in chain */
|
||||
nss_ZFreeIf(stanChain);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
chain = (CERTCertificateList *)PORT_ArenaAlloc(arena,
|
||||
sizeof(CERTCertificateList));
|
||||
if (!chain) goto loser;
|
||||
chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
|
||||
if (!chain->certs) goto loser;
|
||||
i = 0;
|
||||
stanCert = stanChain[i];
|
||||
while (stanCert) {
|
||||
SECItem derCert;
|
||||
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
|
||||
derCert.len = (unsigned int)stanCert->encoding.size;
|
||||
derCert.data = (unsigned char *)stanCert->encoding.data;
|
||||
SECITEM_CopyItem(arena, &chain->certs[i], &derCert);
|
||||
/* XXX CERT_DestroyCertificate(node->cert); */
|
||||
CERT_DestroyCertificate(cCert);
|
||||
stanCert = stanChain[++i];
|
||||
}
|
||||
if ( !includeRoot && len > 1) {
|
||||
@@ -1110,6 +1112,19 @@ loser:
|
||||
chain->arena = arena;
|
||||
nss_ZFreeIf(stanChain);
|
||||
return chain;
|
||||
loser:
|
||||
i = 0;
|
||||
stanCert = stanChain[i];
|
||||
while (stanCert) {
|
||||
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
|
||||
CERT_DestroyCertificate(cCert);
|
||||
stanCert = stanChain[++i];
|
||||
}
|
||||
nss_ZFreeIf(stanChain);
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -422,10 +422,11 @@ loser:
|
||||
if (status == PR_SUCCESS) {
|
||||
/* if it's a root, the chain will only have one cert */
|
||||
if (!chain[1]) {
|
||||
/* need to dupe since caller expects new cert */
|
||||
return CERT_DupCertificate(cert);
|
||||
/* already has a reference from the call to BuildChain */
|
||||
return cert;
|
||||
} else {
|
||||
return STAN_GetCERTCertificate(chain[1]);
|
||||
CERT_DestroyCertificate(cert); /* the first cert in the chain */
|
||||
return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */
|
||||
}
|
||||
} else {
|
||||
PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.28 $ $Date: 2002-02-01 17:25:15 $ $Name: not supported by cvs2svn $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.29 $ $Date: 2002-02-02 20:01:18 $ $Name: not supported by cvs2svn $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
@@ -313,7 +313,7 @@ NSSCertificate_BuildChain
|
||||
}
|
||||
#endif
|
||||
chain = nssList_Create(NULL, PR_FALSE);
|
||||
nssList_Add(chain, c);
|
||||
nssList_Add(chain, nssCertificate_AddRef(c));
|
||||
if (statusOpt) *statusOpt = PR_SUCCESS;
|
||||
if (rvLimit == 1) goto finish;
|
||||
while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) {
|
||||
|
||||
Reference in New Issue
Block a user