diff -up evolution-data-server-2.22.3/camel/camel-smime-context.c.CVE-2009-0547 evolution-data-server-2.22.3/camel/camel-smime-context.c --- evolution-data-server-2.22.3/camel/camel-smime-context.c.CVE-2009-0547 2008-04-04 05:01:59.000000000 -0400 +++ evolution-data-server-2.22.3/camel/camel-smime-context.c 2009-03-17 14:04:17.000000000 -0400 @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -534,6 +535,7 @@ sm_verify_cmsg(CamelCipherContext *conte for (i = 0; i < count; i++) { NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(cmsg, i); SECOidTag typetag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); + int which_digest; switch (typetag) { case SEC_OID_PKCS7_SIGNED_DATA: @@ -543,45 +545,50 @@ sm_verify_cmsg(CamelCipherContext *conte goto fail; } - /* need to build digests of the content */ - if (!NSS_CMSSignedData_HasDigests(sigd)) { - if (extstream == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Digests missing from enveloped data")); - goto fail; - } + if (extstream == NULL) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Digests missing from enveloped data")); + goto fail; + } - if ((poolp = PORT_NewArena(1024)) == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, g_strerror (ENOMEM)); - goto fail; - } + if ((poolp = PORT_NewArena(1024)) == NULL) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, g_strerror (ENOMEM)); + goto fail; + } - digestalgs = NSS_CMSSignedData_GetDigestAlgs(sigd); + digestalgs = NSS_CMSSignedData_GetDigestAlgs(sigd); + + digcx = NSS_CMSDigestContext_StartMultiple(digestalgs); + if (digcx == NULL) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests")); + goto fail; + } - digcx = NSS_CMSDigestContext_StartMultiple(digestalgs); - if (digcx == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests")); - goto fail; - } + mem = (CamelStreamMem *)camel_stream_mem_new(); + camel_stream_write_to_stream(extstream, (CamelStream *)mem); + NSS_CMSDigestContext_Update(digcx, mem->buffer->data, mem->buffer->len); + camel_object_unref(mem); - mem = (CamelStreamMem *)camel_stream_mem_new(); - camel_stream_write_to_stream(extstream, (CamelStream *)mem); - NSS_CMSDigestContext_Update(digcx, mem->buffer->data, mem->buffer->len); - camel_object_unref(mem); + if (NSS_CMSDigestContext_FinishMultiple(digcx, poolp, &digests) != SECSuccess) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests")); + goto fail; + } - if (NSS_CMSDigestContext_FinishMultiple(digcx, poolp, &digests) != SECSuccess) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot calculate digests")); + for (which_digest = 0; digests[which_digest] != NULL; which_digest++) { + SECOidData *digest_alg = SECOID_FindOID(&digestalgs[which_digest]->algorithm); + if (digest_alg == NULL) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot set message digests")); goto fail; } - - if (NSS_CMSSignedData_SetDigests(sigd, digestalgs, digests) != SECSuccess) { + if (NSS_CMSSignedData_SetDigestValue(sigd, digest_alg->offset, digests[which_digest]) != SECSuccess) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot set message digests")); goto fail; } - - PORT_FreeArena(poolp, PR_FALSE); - poolp = NULL; } + PORT_FreeArena(poolp, PR_FALSE); + poolp = NULL; + + /* import all certificates present */ if (NSS_CMSSignedData_ImportCerts(sigd, p->certdb, certUsageEmailSigner, PR_TRUE) != SECSuccess) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Certificate import failed"));