From e4252fb60fe790578018cbf1df474fff54dcc378 Mon Sep 17 00:00:00 2001 From: "nelsonb%netscape.com" Date: Thu, 31 Jul 2003 00:16:27 +0000 Subject: [PATCH] Fix bug 213084. Detect when cert in signature cannot be imported. Detect NULL pointer, don't crash. git-svn-id: svn://10.0.0.236/trunk@145407 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/certdb/certdb.c | 49 +++++++++++---------- mozilla/security/nss/lib/cryptohi/seckey.c | 26 +++++++---- mozilla/security/nss/lib/smime/cmssigdata.c | 9 ++-- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/mozilla/security/nss/lib/certdb/certdb.c b/mozilla/security/nss/lib/certdb/certdb.c index b241786105a..f8547841bd8 100644 --- a/mozilla/security/nss/lib/certdb/certdb.c +++ b/mozilla/security/nss/lib/certdb/certdb.c @@ -34,7 +34,7 @@ /* * Certificate handling code * - * $Id: certdb.c,v 1.53 2003-07-09 04:12:16 wtc%netscape.com Exp $ + * $Id: certdb.c,v 1.54 2003-07-31 00:16:23 nelsonb%netscape.com Exp $ */ #include "nssilock.h" @@ -1200,13 +1200,15 @@ loser: SECStatus CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) { - SECKEYPublicKey *key; - + if (!cert) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } /* choose between key agreement or key encipherment based on key * type in cert */ if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { - key = CERT_ExtractPublicKey(cert); + SECKEYPublicKey *key = CERT_ExtractPublicKey(cert); if (!key) return SECFailure; if ( ( key->keyType == keaKey ) || ( key->keyType == fortezzaKey ) || @@ -2573,10 +2575,7 @@ CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, unsigned int requiredKeyUsage; unsigned int requiredCertType; CERTCertListNode *node, *savenode; - PRBool bad; SECStatus rv; - unsigned int certType; - PRBool dummyret; if (certList == NULL) goto loser; @@ -2590,26 +2589,28 @@ CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, while ( !CERT_LIST_END(node, certList) ) { - bad = PR_FALSE; + PRBool bad = (PRBool)(!node->cert); - /* bad key usage */ - if ( CERT_CheckKeyUsage(node->cert, requiredKeyUsage ) - != SECSuccess ) { + /* bad key usage ? */ + if ( !bad && + CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess ) { bad = PR_TRUE; } - /* bad cert type */ - if ( ca ) { - /* This function returns a more comprehensive cert type that - * takes trust flags into consideration. Should probably - * fix the cert decoding code to do this. - */ - dummyret = CERT_IsCACert(node->cert, &certType); - } else { - certType = node->cert->nsCertType; - } - - if ( ! ( certType & requiredCertType ) ) { - bad = PR_TRUE; + /* bad cert type ? */ + if ( !bad ) { + unsigned int certType = 0; + if ( ca ) { + /* This function returns a more comprehensive cert type that + * takes trust flags into consideration. Should probably + * fix the cert decoding code to do this. + */ + PRBool dummyret = CERT_IsCACert(node->cert, &certType); + } else { + certType = node->cert->nsCertType; + } + if ( !( certType & requiredCertType ) ) { + bad = PR_TRUE; + } } if ( bad ) { diff --git a/mozilla/security/nss/lib/cryptohi/seckey.c b/mozilla/security/nss/lib/cryptohi/seckey.c index 0343760194c..b39ba988f09 100644 --- a/mozilla/security/nss/lib/cryptohi/seckey.c +++ b/mozilla/security/nss/lib/cryptohi/seckey.c @@ -430,7 +430,7 @@ done: * formats. The public key extraction code will deal with the different * formats at the time of extraction. */ -SECStatus +static SECStatus seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) { SECStatus rv, rvCompare; @@ -484,16 +484,16 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) /* check if the cert is self-signed */ rvCompare = (SECStatus)SECITEM_CompareItem(&subjectCert->derSubject, &subjectCert->derIssuer); - if (rvCompare == SECEqual) { - /* fail since cert is self-signed and has no pqg params. */ - return SECFailure; - } + if (rvCompare == SECEqual) { + /* fail since cert is self-signed and has no pqg params. */ + return SECFailure; + } /* get issuer cert */ issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA); - if ( ! issuerCert ) { - return SECFailure; - } + if ( ! issuerCert ) { + return SECFailure; + } /* if parent is not DSA or fortezza, return failure since we don't allow this case. */ @@ -552,7 +552,11 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) SECStatus SECKEY_UpdateCertPQG(CERTCertificate * subjectCert) { - return(seckey_UpdateCertPQGChain(subjectCert,0)); + if (!subjectCert) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + return seckey_UpdateCertPQGChain(subjectCert,0); } @@ -1148,6 +1152,10 @@ CERT_ExtractPublicKey(CERTCertificate *cert) { SECStatus rv; + if (!cert) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } rv = SECKEY_UpdateCertPQG(cert); if (rv != SECSuccess) return NULL; diff --git a/mozilla/security/nss/lib/smime/cmssigdata.c b/mozilla/security/nss/lib/smime/cmssigdata.c index f5dbd314357..6274890cb0e 100644 --- a/mozilla/security/nss/lib/smime/cmssigdata.c +++ b/mozilla/security/nss/lib/smime/cmssigdata.c @@ -34,7 +34,7 @@ /* * CMS signedData methods. * - * $Id: cmssigdata.c,v 1.17 2003-02-18 23:26:39 wtc%netscape.com Exp $ + * $Id: cmssigdata.c,v 1.18 2003-07-31 00:16:27 nelsonb%netscape.com Exp $ */ #include "cmslocal.h" @@ -488,8 +488,11 @@ NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, goto loser; } for (i=0; i < certcount; i++) { - CERTCertificate *cert = CERT_DupCertificate(certArray[i]); - CERT_AddCertToListTail(certList,cert); + CERTCertificate *cert = certArray[i]; + if (cert) + cert = CERT_DupCertificate(cert); + if (cert) + CERT_AddCertToListTail(certList,cert); } /* filter out the certs we don't want */