diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_mime.c')
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_mime.c | 105 |
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, | |||
101 | static void mime_param_free(MIME_PARAM *param); | 101 | static void mime_param_free(MIME_PARAM *param); |
102 | static int mime_bound_check(char *line, int linelen, char *bound, int blen); | 102 | static int mime_bound_check(char *line, int linelen, char *bound, int blen); |
103 | static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); | 103 | static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); |
104 | static int iscrlf(char c); | 104 | static int strip_eol(char *linebuf, int *plen); |
105 | static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); | 105 | static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); |
106 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); | 106 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); |
107 | static void mime_hdr_free(MIME_HEADER *hdr); | 107 | static void mime_hdr_free(MIME_HEADER *hdr); |
@@ -150,9 +150,17 @@ static PKCS7 *B64_read_PKCS7(BIO *bio) | |||
150 | 150 | ||
151 | int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) | 151 | int 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 | ||
400 | static 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 | |||
698 | static 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 | } | ||