summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7/pk7_mime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_mime.c')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c105
1 files changed, 67 insertions, 38 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
index 086d394270..5d2a97839d 100644
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_mime.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -101,7 +101,7 @@ static int mime_param_cmp(const MIME_PARAM * const *a,
101static void mime_param_free(MIME_PARAM *param); 101static void mime_param_free(MIME_PARAM *param);
102static int mime_bound_check(char *line, int linelen, char *bound, int blen); 102static int mime_bound_check(char *line, int linelen, char *bound, int blen);
103static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); 103static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
104static int iscrlf(char c); 104static int strip_eol(char *linebuf, int *plen);
105static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); 105static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
106static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); 106static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
107static void mime_hdr_free(MIME_HEADER *hdr); 107static void mime_hdr_free(MIME_HEADER *hdr);
@@ -150,9 +150,17 @@ static PKCS7 *B64_read_PKCS7(BIO *bio)
150 150
151int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) 151int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
152{ 152{
153 char linebuf[MAX_SMLEN];
154 char bound[33], c; 153 char bound[33], c;
155 int i; 154 int i;
155 char *mime_prefix, *mime_eol;
156 if (flags & PKCS7_NOOLDMIMETYPE)
157 mime_prefix = "application/pkcs7-";
158 else
159 mime_prefix = "application/x-pkcs7-";
160 if (flags & PKCS7_CRLFEOL)
161 mime_eol = "\r\n";
162 else
163 mime_eol = "\n";
156 if((flags & PKCS7_DETACHED) && data) { 164 if((flags & PKCS7_DETACHED) && data) {
157 /* We want multipart/signed */ 165 /* We want multipart/signed */
158 /* Generate a random boundary */ 166 /* Generate a random boundary */
@@ -164,34 +172,42 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
164 bound[i] = c; 172 bound[i] = c;
165 } 173 }
166 bound[32] = 0; 174 bound[32] = 0;
167 BIO_printf(bio, "MIME-Version: 1.0\n"); 175 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
168 BIO_printf(bio, "Content-Type: multipart/signed;"); 176 BIO_printf(bio, "Content-Type: multipart/signed;");
169 BIO_printf(bio, " protocol=\"application/x-pkcs7-signature\";"); 177 BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
170 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"\n\n", bound); 178 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
171 BIO_printf(bio, "This is an S/MIME signed message\n\n"); 179 bound, mime_eol, mime_eol);
180 BIO_printf(bio, "This is an S/MIME signed message%s%s",
181 mime_eol, mime_eol);
172 /* Now write out the first part */ 182 /* Now write out the first part */
173 BIO_printf(bio, "------%s\n", bound); 183 BIO_printf(bio, "------%s%s", bound, mime_eol);
174 if(flags & PKCS7_TEXT) BIO_printf(bio, "Content-Type: text/plain\n\n"); 184 SMIME_crlf_copy(data, bio, flags);
175 while((i = BIO_read(data, linebuf, MAX_SMLEN)) > 0) 185 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
176 BIO_write(bio, linebuf, i);
177 BIO_printf(bio, "\n------%s\n", bound);
178 186
179 /* Headers for signature */ 187 /* Headers for signature */
180 188
181 BIO_printf(bio, "Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\n"); 189 BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
182 BIO_printf(bio, "Content-Transfer-Encoding: base64\n"); 190 BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
183 BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7s\"\n\n"); 191 BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
192 mime_eol);
193 BIO_printf(bio, "Content-Disposition: attachment;");
194 BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
195 mime_eol, mime_eol);
184 B64_write_PKCS7(bio, p7); 196 B64_write_PKCS7(bio, p7);
185 BIO_printf(bio,"\n------%s--\n\n", bound); 197 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
198 mime_eol, mime_eol);
186 return 1; 199 return 1;
187 } 200 }
188 /* MIME headers */ 201 /* MIME headers */
189 BIO_printf(bio, "MIME-Version: 1.0\n"); 202 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
190 BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7m\"\n"); 203 BIO_printf(bio, "Content-Disposition: attachment;");
191 BIO_printf(bio, "Content-Type: application/x-pkcs7-mime; name=\"smime.p7m\"\n"); 204 BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
192 BIO_printf(bio, "Content-Transfer-Encoding: base64\n\n"); 205 BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
206 BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
207 BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
208 mime_eol, mime_eol);
193 B64_write_PKCS7(bio, p7); 209 B64_write_PKCS7(bio, p7);
194 BIO_printf(bio, "\n"); 210 BIO_printf(bio, "%s", mime_eol);
195 return 1; 211 return 1;
196} 212}
197 213
@@ -316,12 +332,9 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
316 } 332 }
317 if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); 333 if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
318 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { 334 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
319 eol = 0; 335 eol = strip_eol(linebuf, &len);
320 while(iscrlf(linebuf[len - 1])) { 336 if (len)
321 len--; 337 BIO_write(out, linebuf, len);
322 eol = 1;
323 }
324 BIO_write(out, linebuf, len);
325 if(eol) BIO_write(out, "\r\n", 2); 338 if(eol) BIO_write(out, "\r\n", 2);
326 } 339 }
327 return 1; 340 return 1;
@@ -364,6 +377,7 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
364{ 377{
365 char linebuf[MAX_SMLEN]; 378 char linebuf[MAX_SMLEN];
366 int len, blen; 379 int len, blen;
380 int eol = 0, next_eol = 0;
367 BIO *bpart = NULL; 381 BIO *bpart = NULL;
368 STACK_OF(BIO) *parts; 382 STACK_OF(BIO) *parts;
369 char state, part, first; 383 char state, part, first;
@@ -383,26 +397,23 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
383 sk_BIO_push(parts, bpart); 397 sk_BIO_push(parts, bpart);
384 return 1; 398 return 1;
385 } else if(part) { 399 } else if(part) {
400 /* Strip CR+LF from linebuf */
401 next_eol = strip_eol(linebuf, &len);
386 if(first) { 402 if(first) {
387 first = 0; 403 first = 0;
388 if(bpart) sk_BIO_push(parts, bpart); 404 if(bpart) sk_BIO_push(parts, bpart);
389 bpart = BIO_new(BIO_s_mem()); 405 bpart = BIO_new(BIO_s_mem());
390 406 BIO_set_mem_eof_return(bpart, 0);
391 } else BIO_write(bpart, "\r\n", 2); 407 } else if (eol)
392 /* Strip CR+LF from linebuf */ 408 BIO_write(bpart, "\r\n", 2);
393 while(iscrlf(linebuf[len - 1])) len--; 409 eol = next_eol;
394 BIO_write(bpart, linebuf, len); 410 if (len)
411 BIO_write(bpart, linebuf, len);
395 } 412 }
396 } 413 }
397 return 0; 414 return 0;
398} 415}
399 416
400static int iscrlf(char c)
401{
402 if(c == '\r' || c == '\n') return 1;
403 return 0;
404}
405
406/* This is the big one: parse MIME header lines up to message body */ 417/* This is the big one: parse MIME header lines up to message body */
407 418
408#define MIME_INVALID 0 419#define MIME_INVALID 0
@@ -683,3 +694,21 @@ static int mime_bound_check(char *line, int linelen, char *bound, int blen)
683 } 694 }
684 return 0; 695 return 0;
685} 696}
697
698static int strip_eol(char *linebuf, int *plen)
699 {
700 int len = *plen;
701 char *p, c;
702 int is_eol = 0;
703 p = linebuf + len - 1;
704 for (p = linebuf + len - 1; len > 0; len--, p--)
705 {
706 c = *p;
707 if (c == '\n')
708 is_eol = 1;
709 else if (c != '\r')
710 break;
711 }
712 *plen = len;
713 return is_eol;
714 }