Add suppot for ASCII with CRLF canonicalisation.

This commit is contained in:
Dr. Stephen Henson 2014-02-12 15:15:55 +00:00
parent 4dce704145
commit 847865d0f9
6 changed files with 47 additions and 5 deletions

View File

@ -258,6 +258,8 @@ int MAIN(int argc, char **argv)
flags |= CMS_DEBUG_DECRYPT;
else if (!strcmp (*args, "-text"))
flags |= CMS_TEXT;
else if (!strcmp (*args, "-asciicrlf"))
flags |= CMS_ASCIICRLF;
else if (!strcmp (*args, "-nointern"))
flags |= CMS_NOINTERN;
else if (!strcmp (*args, "-noverify")

View File

@ -102,7 +102,7 @@ static int mime_param_cmp(const MIME_PARAM * const *a,
static void mime_param_free(MIME_PARAM *param);
static int mime_bound_check(char *line, int linelen, char *bound, int blen);
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
static int strip_eol(char *linebuf, int *plen);
static int strip_eol(char *linebuf, int *plen, int flags);
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
static void mime_hdr_free(MIME_HEADER *hdr);
@ -554,14 +554,30 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
}
else
{
int eolcnt = 0;
if(flags & SMIME_TEXT)
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
{
eol = strip_eol(linebuf, &len);
eol = strip_eol(linebuf, &len, flags);
if (len)
{
/* Not EOF: write out all CRLF */
if (flags & SMIME_ASCIICRLF)
{
int i;
for(i = 0; i < eolcnt; i++)
BIO_write(out, "\r\n", 2);
eolcnt = 0;
}
BIO_write(out, linebuf, len);
if(eol) BIO_write(out, "\r\n", 2);
if(eol)
BIO_write(out, "\r\n", 2);
}
else if (flags & SMIME_ASCIICRLF)
eolcnt++;
else if(eol)
BIO_write(out, "\r\n", 2);
}
}
(void)BIO_flush(out);
@ -630,7 +646,7 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
return 1;
} else if(part) {
/* Strip CR+LF from linebuf */
next_eol = strip_eol(linebuf, &len);
next_eol = strip_eol(linebuf, &len, 0);
if(first) {
first = 0;
if(bpart) sk_BIO_push(parts, bpart);
@ -932,7 +948,7 @@ static int mime_bound_check(char *line, int linelen, char *bound, int blen)
return 0;
}
static int strip_eol(char *linebuf, int *plen)
static int strip_eol(char *linebuf, int *plen, int flags)
{
int len = *plen;
char *p, c;
@ -943,6 +959,8 @@ static int strip_eol(char *linebuf, int *plen)
c = *p;
if (c == '\n')
is_eol = 1;
else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
continue;
else if (c != '\r')
break;
}

View File

@ -117,6 +117,7 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
#define CMS_USE_KEYID 0x10000
#define CMS_DEBUG_DECRYPT 0x20000
#define CMS_KEY_PARAM 0x40000
#define CMS_ASCIICRLF 0x80000
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);

View File

@ -334,6 +334,12 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
if (!dcont && !check_content(cms))
return 0;
if (dcont && !(flags & CMS_BINARY))
{
const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
flags |= CMS_ASCIICRLF;
}
/* Attempt to find all signer certificates */
@ -519,6 +525,8 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
cms = CMS_ContentInfo_new();
if (!cms || !CMS_SignedData_init(cms))
goto merr;
if (flags & CMS_ASCIICRLF && !CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
goto err;
if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
{

View File

@ -276,6 +276,9 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
#define SMIME_BINARY PKCS7_BINARY
#define SMIME_NOATTR PKCS7_NOATTR
/* CRLF ASCII canonicalisation */
#define SMIME_ASCIICRLF 0x80000
DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,

View File

@ -43,6 +43,7 @@ B<openssl> B<cms>
[B<-noattr>]
[B<-nosmimecap>]
[B<-binary>]
[B<-asciicrlf>]
[B<-nodetach>]
[B<-certfile file>]
[B<-certsout file>]
@ -291,6 +292,15 @@ effectively using CR and LF as end of line: as required by the S/MIME
specification. When this option is present no translation occurs. This
is useful when handling binary data which may not be in MIME format.
=item B<-asciicrlf>
when signing use ASCII CRLF format canonicalisation. This strips trailing
whitespace from all lines, deletes trailing blank lines at EOF and sets
the encapsulated content type. This option is normally used with detached
content and an output signature format of DER. This option is not normally
needed when verifying as it is enabled automatically if the encapsulated
content format is detected.
=item B<-nodetach>
when signing a message use opaque signing: this form is more resistant