summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2003-12-04 00:36:47 +0000
committernelsonb%netscape.com <devnull@localhost>2003-12-04 00:36:47 +0000
commit376ec1e3f2d393d69eb2c277ba23dd91d62afe26 (patch)
treec73ce4f66e5fd20aa0b4c09a4523f62ff5ec028d
parentd4f785e2ac9034e575001fe202cce20230ad9f6a (diff)
downloadnss-hg-376ec1e3f2d393d69eb2c277ba23dd91d62afe26.tar.gz
In functions NSS_CMSSignedData_Encode_AfterData and
NSS_CMSSignedData_Decode_AfterData - These functions call NSS_CMSDigestContext_FinishMultiple, which always destroys the digest context, regardless of whether it returns SECSUccess or SECFailure. So, change these functions to always NULL out the context pointer regardless of the returned value. NSS_CMSSignedData_VerifySignerInfo() - Always call NSS_CMSSignerInfo_Verify() to set the verification status in the signerinfo object, even if some of the other arguments are NULL, or other failures have occurred, but avoid NULL pointer dereferences along the way. Notice that this change is dependent on changes to NSS_CMSSignerInfo_Verify() (see below.) NSS_CMSSignedData_SetDigests() - skip over missing digests. Don't fail the function, and don't crash, if digest pointers are NULL. Bugscape bug 54208, r=relyea
-rw-r--r--security/nss/lib/smime/cmssigdata.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c
index b9ae45ea6..4548d5deb 100644
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -260,10 +260,12 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd)
/* did we have digest calculation going on? */
if (cinfo->digcx) {
- rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, &(sigd->digests));
- if (rv != SECSuccess)
- goto loser; /* error has been set by NSS_CMSDigestContext_FinishMultiple */
+ rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp,
+ &(sigd->digests));
+ /* error has been set by NSS_CMSDigestContext_FinishMultiple */
cinfo->digcx = NULL;
+ if (rv != SECSuccess)
+ goto loser;
}
signerinfos = sigd->signerInfos;
@@ -398,24 +400,28 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
}
/*
- * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a SignedData
- * after all the encapsulated data was passed through the decoder.
+ * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a
+ * SignedData after all the encapsulated data was passed through the decoder.
*/
SECStatus
NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd)
{
+ SECStatus rv = SECSuccess;
+
PORT_Assert(sigd);
if (!sigd) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
+
/* did we have digest calculation going on? */
if (sigd->contentInfo.digcx) {
- if (NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx, sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess)
- return SECFailure; /* error has been set by NSS_CMSDigestContext_FinishMultiple */
+ rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx,
+ sigd->cmsg->poolp, &(sigd->digests));
+ /* error set by NSS_CMSDigestContext_FinishMultiple */
sigd->contentInfo.digcx = NULL;
}
- return SECSuccess;
+ return rv;
}
/*
@@ -659,6 +665,7 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
NSSCMSContentInfo *cinfo;
SECOidData *algiddata;
SECItem *contentType, *digest;
+ SECOidTag oidTag;
SECStatus rv;
PORT_Assert(sigd);
@@ -678,18 +685,11 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
/* find digest and contentType for signerinfo */
algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
- if (!algiddata)
- return SECFailure; /* error code is set */
- digest = NSS_CMSSignedData_GetDigestValue(sigd, algiddata->offset);
- if (!digest) {
- PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
- return SECFailure;
- }
+ oidTag = algiddata ? algiddata->offset : SEC_OID_UNKNOWN;
+ digest = NSS_CMSSignedData_GetDigestValue(sigd, oidTag);
+ /* NULL digest is acceptable. */
contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo);
- if (!contentType) {
- PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
- return SECFailure;
- }
+ /* NULL contentType is acceptable. */
/* now verify signature */
rv = NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType);
@@ -926,6 +926,13 @@ NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
return SECFailure;
}
+ if (!digests[idx]) {
+ /* We have no digest for this algorithm, probably because it is
+ ** unrecognized or unsupported. We'll ignore this here. If this
+ ** digest is needed later, an error will be be generated then.
+ */
+ continue;
+ }
/* found it - now set it */
if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL ||