diff options
author | ian.mcgreer%sun.com <devnull@localhost> | 2002-02-02 20:01:22 +0000 |
---|---|---|
committer | ian.mcgreer%sun.com <devnull@localhost> | 2002-02-02 20:01:22 +0000 |
commit | 8fffebcd84eb23926d3c36984e0c656169fa71f7 (patch) | |
tree | 55564d56e354b4e98efb1b709318f519192d9b02 | |
parent | f6f38395c29665c7f7b9e1cfd79e4a1584375b36 (diff) | |
download | nss-hg-8fffebcd84eb23926d3c36984e0c656169fa71f7.tar.gz |
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.
-rw-r--r-- | security/nss/lib/certhigh/certhigh.c | 21 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certvfy.c | 7 | ||||
-rw-r--r-- | security/nss/lib/pki/certificate.c | 2 |
3 files changed, 23 insertions, 7 deletions
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index c11e66152..261ac9755 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -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 } diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 61667bc4c..42d6d86ee 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -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); diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 1bfe1d7c8..868c08eaa 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -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)) { |