/*
 * 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;
}
Ejemplo n.º 2
0
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;
}