Skip to content

Commit

Permalink
Canonicalise input in CMS_verify.
Browse files Browse the repository at this point in the history
If content is detached and not binary mode translate the input to
CRLF format. Before this change the input was verified verbatim
which lead to a discrepancy between sign and verify.
  • Loading branch information
snhenson committed Dec 22, 2013
1 parent 20b82b5 commit cd30f03
Showing 1 changed file with 73 additions and 21 deletions.
94 changes: 73 additions & 21 deletions crypto/cms/cms_smime.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,28 @@
#include "cms_lcl.h"
#include "asn1_locl.h"

static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
{
unsigned char buf[4096];
int r = 0, i;
BIO *tmpout = NULL;

BIO *rbio;
if (out == NULL)
tmpout = BIO_new(BIO_s_null());
rbio = BIO_new(BIO_s_null());
else if (flags & CMS_TEXT)
{
tmpout = BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(tmpout, 0);
rbio = BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(rbio, 0);
}
else
tmpout = out;
rbio = out;
return rbio;
}

static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
{
unsigned char buf[4096];
int r = 0, i;
BIO *tmpout;

tmpout = cms_get_text_bio(out, flags);

if(!tmpout)
{
Expand Down Expand Up @@ -142,7 +149,7 @@ static void do_free_upto(BIO *f, BIO *upto)
BIO_free(f);
f = tbio;
}
while (f != upto);
while (f && f != upto);
}
else
BIO_free_all(f);
Expand Down Expand Up @@ -323,7 +330,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
STACK_OF(X509_CRL) *crls = NULL;
X509 *signer;
int i, scount = 0, ret = 0;
BIO *cmsbio = NULL, *tmpin = NULL;
BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;

if (!dcont && !check_content(cms))
return 0;
Expand Down Expand Up @@ -406,15 +413,48 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
}
else
tmpin = dcont;

/* If not binary mode and detached generate digests by *writing*
* through the BIO. That makes it possible to canonicalise the
* input.
*/
if (!(flags & SMIME_BINARY) && dcont)
{
/* Create output BIO so we can either handle text or to
* ensure included content doesn't override detached content.
*/
tmpout = cms_get_text_bio(out, flags);
if(!tmpout)
{
CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
}
cmsbio = CMS_dataInit(cms, tmpout);
if (!cmsbio)
goto err;
/* Don't use SMIME_TEXT for verify: it adds headers and
* we want to remove them.
*/
SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT);

cmsbio=CMS_dataInit(cms, tmpin);
if (!cmsbio)
goto err;
if(flags & CMS_TEXT)
{
if (!SMIME_text(tmpout, out))
{
CMSerr(CMS_F_CMS_VERIFY,CMS_R_SMIME_TEXT_ERROR);
goto err;
}
}
}
else
{
cmsbio=CMS_dataInit(cms, tmpin);
if (!cmsbio)
goto err;

if (!cms_copy_content(out, cmsbio, flags))
goto err;
if (!cms_copy_content(out, cmsbio, flags))
goto err;

}
if (!(flags & CMS_NO_CONTENT_VERIFY))
{
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
Expand All @@ -432,11 +472,23 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
ret = 1;

err:

if (dcont && (tmpin == dcont))
do_free_upto(cmsbio, dcont);
if (!(flags & SMIME_BINARY) && dcont)
{
do_free_upto(cmsbio, tmpout);
if (tmpin != dcont)
BIO_free(tmpin);
}
else
BIO_free_all(cmsbio);
{

if (dcont && (tmpin == dcont))
do_free_upto(cmsbio, dcont);
else
BIO_free_all(cmsbio);
}

if (tmpout && out != tmpout)
BIO_free_all(tmpout);

if (cms_certs)
sk_X509_pop_free(cms_certs, X509_free);
Expand Down

0 comments on commit cd30f03

Please sign in to comment.