/* * Given detached content and a valid (decoded) SignedData, digest the detached * content. This occurs at the later of {CMSDecoderFinalizeMessage() finding a * SignedData when already have detachedContent, or CMSDecoderSetDetachedContent() * when we already have a SignedData). */ static OSStatus cmsDigestDetachedContent( CMSDecoderRef cmsDecoder) { ASSERT((cmsDecoder->signedData != NULL) && (cmsDecoder->detachedContent != NULL)); SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(cmsDecoder->signedData); if(digestAlgorithms == NULL) { return errSecUnknownFormat; } SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms); if(digcx == NULL) { return errSecAllocate; } CSSM_DATA **digests = NULL; SecCmsDigestContextUpdate(digcx, CFDataGetBytePtr(cmsDecoder->detachedContent), CFDataGetLength(cmsDecoder->detachedContent)); /* note this frees the digest content regardless */ OSStatus ortn = SecCmsDigestContextFinishMultiple(digcx, cmsDecoder->arena, &digests); if(ortn) { ortn = cmsRtnToOSStatus(ortn); CSSM_PERROR("SecCmsDigestContextFinishMultiple", ortn); return ortn; } ortn = SecCmsSignedDataSetDigests(cmsDecoder->signedData, digestAlgorithms, digests); if(ortn) { ortn = cmsRtnToOSStatus(ortn); CSSM_PERROR("SecCmsSignedDataSetDigests", ortn); } return ortn; }
OSStatus createTSAMessageImprint(SecCmsSignedDataRef signedData, CSSM_DATA_PTR encDigest, SecAsn1TSAMessageImprint *messageImprint) { // Calculate hash of encDigest and put in messageImprint.hashedMessage // We pass in encDigest, since in the verification case, it comes from a different signedData OSStatus status = SECFailure; require(signedData && messageImprint, xit); SECAlgorithmID **digestAlgorithms = SecCmsSignedDataGetDigestAlgs(signedData); require(digestAlgorithms, xit); SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestAlgorithms); require(digcx, xit); require(encDigest, xit); SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(signedData, 0); // NB - assume 1 signer only! messageImprint->hashAlgorithm = signerinfo->digestAlg; SecCmsDigestContextUpdate(digcx, encDigest->Data, encDigest->Length); require_noerr(SecCmsDigestContextFinishSingle(digcx, (SecArenaPoolRef)signedData->cmsg->poolp, &messageImprint->hashedMessage), xit); status = SECSuccess; xit: return status; }