92 static
char * strip_ends(
char *name);
93 static
char * strip_start(
char *name);
94 static
char * strip_end(
char *name);
95 static
MIME_HEADER *mime_hdr_new(
char *name,
char *value);
96 static
int mime_hdr_addparam(
MIME_HEADER *mhdr,
char *name,
char *value);
100 static
int mime_param_cmp(const
MIME_PARAM * const *a,
102 static
void mime_param_free(
MIME_PARAM *param);
103 static
int mime_bound_check(
char *line,
int linelen,
char *bound,
int blen);
104 static
int multi_split(
BIO *bio,
char *bound,
STACK_OF(
BIO) **ret);
105 static
int strip_eol(
char *linebuf,
int *plen);
110 #define MAX_SMLEN 1024
111 #define mime_debug(x)
136 }
while (bio != out);
177 r = B64_write_ASN1(out, val, in, flags, it);
205 int i, have_unknown = 0, write_comma, ret = 0, md_nid;
279 int ctype_nid,
int econt_nid,
285 const char *mime_prefix, *mime_eol, *cname =
"smime.p7m";
286 const char *msg_type=NULL;
288 mime_prefix =
"application/x-pkcs7-";
290 mime_prefix =
"application/pkcs7-";
300 for(i = 0; i < 32; i++) {
307 BIO_printf(bio,
"MIME-Version: 1.0%s", mime_eol);
308 BIO_printf(bio,
"Content-Type: multipart/signed;");
309 BIO_printf(bio,
" protocol=\"%ssignature\";", mime_prefix);
311 asn1_write_micalg(bio, mdalgs);
312 BIO_printf(bio,
"\"; boundary=\"----%s\"%s%s",
313 bound, mime_eol, mime_eol);
314 BIO_printf(bio,
"This is an S/MIME signed message%s%s",
317 BIO_printf(bio,
"------%s%s", bound, mime_eol);
318 if (!asn1_output_data(bio, data, val, flags, it))
320 BIO_printf(bio,
"%s------%s%s", mime_eol, bound, mime_eol);
324 BIO_printf(bio,
"Content-Type: %ssignature;", mime_prefix);
325 BIO_printf(bio,
" name=\"smime.p7s\"%s", mime_eol);
326 BIO_printf(bio,
"Content-Transfer-Encoding: base64%s",
328 BIO_printf(bio,
"Content-Disposition: attachment;");
329 BIO_printf(bio,
" filename=\"smime.p7s\"%s%s",
331 B64_write_ASN1(bio, val, NULL, 0, it);
332 BIO_printf(bio,
"%s------%s--%s%s", mime_eol, bound,
340 msg_type =
"enveloped-data";
344 msg_type =
"signed-receipt";
346 msg_type =
"signed-data";
348 msg_type =
"certs-only";
352 msg_type =
"compressed-data";
356 BIO_printf(bio,
"MIME-Version: 1.0%s", mime_eol);
357 BIO_printf(bio,
"Content-Disposition: attachment;");
358 BIO_printf(bio,
" filename=\"%s\"%s", cname, mime_eol);
359 BIO_printf(bio,
"Content-Type: %smime;", mime_prefix);
362 BIO_printf(bio,
" name=\"%s\"%s", cname, mime_eol);
363 BIO_printf(bio,
"Content-Transfer-Encoding: base64%s%s",
365 if (!B64_write_ASN1(bio, val, data, flags, it))
374 static int asn1_output_data(
BIO *out,
BIO *data,
ASN1_VALUE *val,
int flags,
442 if(bcont) *bcont = NULL;
444 if (!(headers = mime_parse_hdr(bio))) {
449 if(!(hdr = mime_hdr_find(headers,
"content-type")) || !hdr->
value) {
457 if(!strcmp(hdr->
value,
"multipart/signed")) {
459 prm = mime_param_find(hdr,
"boundary");
476 if (!(headers = mime_parse_hdr(asnin))) {
484 if(!(hdr = mime_hdr_find(headers,
"content-type")) ||
491 if(strcmp(hdr->
value,
"application/x-pkcs7-signature") &&
492 strcmp(hdr->
value,
"application/pkcs7-signature")) {
501 if(!(val = b64_read_asn1(asnin, it))) {
517 if (strcmp (hdr->
value,
"application/x-pkcs7-mime") &&
518 strcmp (hdr->
value,
"application/pkcs7-mime")) {
527 if(!(val = b64_read_asn1(bio, it))) {
558 BIO_printf(out,
"Content-Type: text/plain\r\n\r\n");
561 eol = strip_eol(linebuf, &len);
581 if (!(headers = mime_parse_hdr(in))) {
585 if(!(hdr = mime_hdr_find(headers,
"content-type")) || !hdr->
value) {
590 if (strcmp (hdr->
value,
"text/plain")) {
597 while ((len =
BIO_read(in, iobuf,
sizeof(iobuf))) > 0)
608 static int multi_split(
BIO *bio,
char *bound,
STACK_OF(
BIO) **ret)
612 int eol = 0, next_eol = 0;
615 char state, part, first;
617 blen = strlen(bound);
623 while ((len =
BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
624 state = mime_bound_check(linebuf, len, bound, blen);
628 }
else if(state == 2) {
633 next_eol = strip_eol(linebuf, &len);
651 #define MIME_INVALID 0
657 #define MIME_COMMENT 6
667 int len, state, save_state = 0;
672 if(mhdr && isspace((
unsigned char)linebuf[0])) state =
MIME_NAME;
676 for(p = linebuf, q = linebuf; (c = *
p) && (c!=
'\r') && (c!=
'\n'); p++) {
687 ntmp = strip_ends(q);
696 mhdr = mime_hdr_new(ntmp, strip_ends(q));
701 }
else if(c ==
'(') {
717 ntmp = strip_ends(q);
726 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
729 }
else if (c ==
'"') {
732 }
else if(c ==
'(') {
748 mhdr = mime_hdr_new(ntmp, strip_ends(q));
751 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
752 if(p == linebuf)
break;
759 static char *strip_ends(
char *name)
761 return strip_end(strip_start(name));
765 static char *strip_start(
char *name)
769 for(p = name; (c = *
p) ;p++) {
772 if(p[1])
return p + 1;
776 if(!isspace((
unsigned char)c))
return p;
782 static char *strip_end(
char *name)
785 if(!name)
return NULL;
787 for(p = name + strlen(name) - 1; p >= name ;p--) {
790 if(p - 1 == name)
return NULL;
794 if(isspace((
unsigned char)c)) *p = 0;
800 static MIME_HEADER *mime_hdr_new(
char *name,
char *value)
803 char *tmpname, *tmpval, *
p;
806 if(!(tmpname =
BUF_strdup(name)))
return NULL;
807 for(p = tmpname ; *
p; p++) {
808 c = (
unsigned char)*p;
814 }
else tmpname = NULL;
816 if(!(tmpval =
BUF_strdup(value)))
return NULL;
817 for(p = tmpval ; *
p; p++) {
818 c = (
unsigned char)*p;
824 }
else tmpval = NULL;
826 if(!mhdr)
return NULL;
827 mhdr->
name = tmpname;
828 mhdr->
value = tmpval;
833 static int mime_hdr_addparam(
MIME_HEADER *mhdr,
char *name,
char *value)
835 char *tmpname, *tmpval, *
p;
840 if(!tmpname)
return 0;
841 for(p = tmpname ; *
p; p++) {
842 c = (
unsigned char)*p;
848 }
else tmpname = NULL;
851 if(!tmpval)
return 0;
852 }
else tmpval = NULL;
855 if(!mparam)
return 0;
862 static int mime_hdr_cmp(
const MIME_HEADER *
const *a,
865 if (!(*a)->name || !(*b)->name)
866 return !!(*a)->name - !!(*b)->name;
868 return(strcmp((*a)->name, (*b)->name));
871 static int mime_param_cmp(
const MIME_PARAM *
const *a,
874 if (!(*a)->param_name || !(*b)->param_name)
875 return !!(*a)->param_name - !!(*b)->param_name;
876 return(strcmp((*a)->param_name, (*b)->param_name));
887 if(idx < 0)
return NULL;
897 if(idx < 0)
return NULL;
909 static void mime_param_free(
MIME_PARAM *param)
921 static int mime_bound_check(
char *line,
int linelen,
char *bound,
int blen)
923 if(linelen == -1) linelen = strlen(line);
924 if(blen == -1) blen = strlen(bound);
926 if(blen + 2 > linelen)
return 0;
928 if(!strncmp(line,
"--", 2) && !strncmp(line + 2, bound, blen)) {
929 if(!strncmp(line + blen + 2,
"--", 2))
return 2;
935 static int strip_eol(
char *linebuf,
int *plen)
940 p = linebuf + len - 1;
941 for (p = linebuf + len - 1; len > 0; len--, p--)