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")
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);
}
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);
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);
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;
c = *p;
if (c == '\n')
is_eol = 1;
+ else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
+ continue;
else if (c != '\r')
break;
}
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 */
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))
{
[B<-noattr>]
[B<-nosmimecap>]
[B<-binary>]
+[B<-asciicrlf>]
[B<-nodetach>]
[B<-certfile file>]
[B<-certsout file>]
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