diff options
author | nelsonb%netscape.com <devnull@localhost> | 2003-12-04 00:36:47 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2003-12-04 00:36:47 +0000 |
commit | 376ec1e3f2d393d69eb2c277ba23dd91d62afe26 (patch) | |
tree | c73ce4f66e5fd20aa0b4c09a4523f62ff5ec028d | |
parent | d4f785e2ac9034e575001fe202cce20230ad9f6a (diff) | |
download | nss-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.c | 45 |
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 || |