X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_smime/lib/cmssigdata.c?ds=sidebyside diff --git a/OSX/libsecurity_smime/lib/cmssigdata.c b/OSX/libsecurity_smime/lib/cmssigdata.c index c072d3a9..3d4dc41a 100644 --- a/OSX/libsecurity_smime/lib/cmssigdata.c +++ b/OSX/libsecurity_smime/lib/cmssigdata.c @@ -223,7 +223,7 @@ SecCmsSignedDataEncodeBeforeData(SecCmsSignedDataRef sigd) extern const SecAsn1Template kSecAsn1TSATSTInfoTemplate; -OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, +OSStatus createTSAMessageImprint(SecCmsSignerInfoRef signerInfo, SECAlgorithmID *digestAlg, CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint) { // Calculate hash of encDigest and put in messageImprint.hashedMessage @@ -231,21 +231,17 @@ OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR e OSStatus status = SECFailure; - require(signedData && messageImprint, xit); - - SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData); - require(digestAlgorithms, xit); + require(signerInfo && digestAlg && messageImprint, xit); - SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms); + SecCmsDigestContextRef digcx = SecCmsDigestContextStartSingle(digestAlg); require(digcx, xit); require(encDigest, xit); - SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(signedData, 0); // NB - assume 1 signer only! - messageImprint->hashAlgorithm = signerinfo->digestAlg; + messageImprint->hashAlgorithm = *digestAlg; SecCmsDigestContextUpdate(digcx, encDigest->Data, encDigest->Length); - require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signedData->cmsg->poolp, + require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signerInfo->cmsg->poolp, &messageImprint->hashedMessage), xit); status = SECSuccess; @@ -354,7 +350,8 @@ static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinf The code for this is essentially the same code taht is done during a timestamp verify, except that we also need to check the nonce. */ - require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, NULL, expectedNonce), xit); + CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo); + require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, encDigest, expectedNonce), xit); status = SecCmsSignerInfoAddTimeStamp(signerinfo, &respDER.timeStampTokenDER); @@ -440,9 +437,9 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd) /* did we have digest calculation going on? */ if (cinfo->digcx) { rv = SecCmsDigestContextFinishMultiple(cinfo->digcx, (SecArenaPoolRef)poolp, &(sigd->digests)); + cinfo->digcx = NULL; if (rv != SECSuccess) goto loser; /* error has been set by SecCmsDigestContextFinishMultiple */ - cinfo->digcx = NULL; } signerinfos = sigd->signerInfos; @@ -500,7 +497,7 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd) // Calculate hash of encDigest and put in messageImprint.hashedMessage SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(sigd, 0); // NB - assume 1 signer only! CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo); - require_noerr(createTSAMessageImprint(sigd, encDigest, &messageImprint), tsxit); + require_noerr(createTSAMessageImprint(signerinfo, &signerinfo->digestAlg, encDigest, &messageImprint), tsxit); // Callback to fire up XPC service to talk to TimeStamping server, etc. require_noerr(rv =(*sigd->cmsg->tsaCallback)(sigd->cmsg->tsaContext, &messageImprint, @@ -617,8 +614,10 @@ SecCmsSignedDataDecodeAfterData(SecCmsSignedDataRef sigd) { /* did we have digest calculation going on? */ if (sigd->contentInfo.digcx) { - if (SecCmsDigestContextFinishMultiple(sigd->contentInfo.digcx, (SecArenaPoolRef)sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess) + if (SecCmsDigestContextFinishMultiple(sigd->contentInfo.digcx, (SecArenaPoolRef)sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess) { + sigd->contentInfo.digcx = NULL; return SECFailure; /* error has been set by SecCmsDigestContextFinishMultiple */ + } sigd->contentInfo.digcx = NULL; } return SECSuccess; @@ -634,6 +633,10 @@ SecCmsSignedDataDecodeAfterEnd(SecCmsSignedDataRef sigd) SecCmsSignerInfoRef *signerinfos; int i; + if (!sigd) { + return SECFailure; + } + signerinfos = sigd->signerInfos; /* set cmsg and sigd backpointers for all the signerinfos */ @@ -746,8 +749,11 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i, CSSM_DATA_PTR contentType, digest; OSStatus status, status2; - cinfo = &(sigd->contentInfo); + if (sigd == NULL || sigd->signerInfos == NULL || i >= SecCmsSignedDataSignerInfoCount(sigd)) { + return errSecParam; + } + cinfo = &(sigd->contentInfo); signerinfo = sigd->signerInfos[i]; /* Signature or digest level verificationStatus errors should supercede @@ -756,32 +762,23 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i, /* Find digest and contentType for signerinfo */ algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo); if (algiddata == NULL) { - return errSecInternalError; // shouldn't have happened, this is likely due to corrupted data + return errSecInvalidDigestAlgorithm; } digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset); - if(digest == NULL) { - /* - * No digests; this probably had detached content the caller has to - * deal with. - * FIXME: need some error return for this (as well as many - * other places in this library). - */ - return errSecDataNotAvailable; - } + if(digest == NULL) { + /* + * No digests; this probably had detached content the caller has to + * deal with. + * FIXME: need some error return for this (as well as many + * other places in this library). + */ + return errSecDataNotAvailable; + } contentType = SecCmsContentInfoGetContentTypeOID(cinfo); /* verify signature */ -#if SECTRUST_OSX -#warning STU: - // timestamp policy is currently unsupported; use codesign policy only - #if !NDEBUG - syslog(LOG_ERR, "SecCmsSignedDataVerifySignerInfo: using codesign policy without timestamp verification"); - #endif - CFTypeRef timeStampPolicies=SecPolicyCreateWithProperties(kSecPolicyAppleCodeSigning, NULL); -#else CFTypeRef timeStampPolicies=SecPolicyCreateAppleTimeStampingAndRevocationPolicies(policies); -#endif status = SecCmsSignerInfoVerifyWithPolicy(signerinfo, timeStampPolicies, digest, contentType); CFReleaseSafe(timeStampPolicies); @@ -961,11 +958,11 @@ SecCmsSignedDataGetDigestByAlgTag(SecCmsSignedDataRef sigd, SECOidTag algtag) { int idx; - if(sigd->digests == NULL) { - return NULL; - } + if(sigd == NULL || sigd->digests == NULL) { + return NULL; + } idx = SecCmsAlgArrayGetIndexByAlgTag(sigd->digestAlgorithms, algtag); - return sigd->digests[idx]; + return (idx >= 0) ? sigd->digests[idx] : NULL; } /* @@ -981,7 +978,8 @@ SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd, { int cnt, i, idx; - if (sigd->digestAlgorithms == NULL) { + /* Check input structure and items in structure */ + if (sigd == NULL || sigd->digestAlgorithms == NULL || sigd->cmsg == NULL || sigd->cmsg->poolp == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; }