diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_mime.c')
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_mime.c | 104 |
1 files changed, 46 insertions, 58 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c index 927b88c3e7..17b68992f7 100644 --- a/src/lib/libcrypto/pkcs7/pk7_mime.c +++ b/src/lib/libcrypto/pkcs7/pk7_mime.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* pk7_mime.c */ | 1 | /* pk7_mime.c */ |
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL |
3 | * project 1999. | 3 | * project. |
4 | */ | 4 | */ |
5 | /* ==================================================================== | 5 | /* ==================================================================== |
6 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | 6 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. |
@@ -86,6 +86,7 @@ STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ | |||
86 | DECLARE_STACK_OF(MIME_HEADER) | 86 | DECLARE_STACK_OF(MIME_HEADER) |
87 | IMPLEMENT_STACK_OF(MIME_HEADER) | 87 | IMPLEMENT_STACK_OF(MIME_HEADER) |
88 | 88 | ||
89 | static int pkcs7_output_data(BIO *bio, BIO *data, PKCS7 *p7, int flags); | ||
89 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7); | 90 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7); |
90 | static PKCS7 *B64_read_PKCS7(BIO *bio); | 91 | static PKCS7 *B64_read_PKCS7(BIO *bio); |
91 | static char * strip_ends(char *name); | 92 | static char * strip_ends(char *name); |
@@ -109,9 +110,6 @@ static void mime_hdr_free(MIME_HEADER *hdr); | |||
109 | #define MAX_SMLEN 1024 | 110 | #define MAX_SMLEN 1024 |
110 | #define mime_debug(x) /* x */ | 111 | #define mime_debug(x) /* x */ |
111 | 112 | ||
112 | |||
113 | typedef void (*stkfree)(); | ||
114 | |||
115 | /* Base 64 read and write of PKCS#7 structure */ | 113 | /* Base 64 read and write of PKCS#7 structure */ |
116 | 114 | ||
117 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7) | 115 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7) |
@@ -123,7 +121,7 @@ static int B64_write_PKCS7(BIO *bio, PKCS7 *p7) | |||
123 | } | 121 | } |
124 | bio = BIO_push(b64, bio); | 122 | bio = BIO_push(b64, bio); |
125 | i2d_PKCS7_bio(bio, p7); | 123 | i2d_PKCS7_bio(bio, p7); |
126 | BIO_flush(bio); | 124 | (void)BIO_flush(bio); |
127 | bio = BIO_pop(bio); | 125 | bio = BIO_pop(bio); |
128 | BIO_free(b64); | 126 | BIO_free(b64); |
129 | return 1; | 127 | return 1; |
@@ -140,7 +138,7 @@ static PKCS7 *B64_read_PKCS7(BIO *bio) | |||
140 | bio = BIO_push(b64, bio); | 138 | bio = BIO_push(b64, bio); |
141 | if(!(p7 = d2i_PKCS7_bio(bio, NULL))) | 139 | if(!(p7 = d2i_PKCS7_bio(bio, NULL))) |
142 | PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR); | 140 | PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR); |
143 | BIO_flush(bio); | 141 | (void)BIO_flush(bio); |
144 | bio = BIO_pop(bio); | 142 | bio = BIO_pop(bio); |
145 | BIO_free(b64); | 143 | BIO_free(b64); |
146 | return p7; | 144 | return p7; |
@@ -182,7 +180,7 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) | |||
182 | mime_eol, mime_eol); | 180 | mime_eol, mime_eol); |
183 | /* Now write out the first part */ | 181 | /* Now write out the first part */ |
184 | BIO_printf(bio, "------%s%s", bound, mime_eol); | 182 | BIO_printf(bio, "------%s%s", bound, mime_eol); |
185 | SMIME_crlf_copy(data, bio, flags); | 183 | pkcs7_output_data(bio, data, p7, flags); |
186 | BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); | 184 | BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); |
187 | 185 | ||
188 | /* Headers for signature */ | 186 | /* Headers for signature */ |
@@ -196,7 +194,7 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) | |||
196 | mime_eol, mime_eol); | 194 | mime_eol, mime_eol); |
197 | B64_write_PKCS7(bio, p7); | 195 | B64_write_PKCS7(bio, p7); |
198 | BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound, | 196 | BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound, |
199 | mime_eol, mime_eol); | 197 | mime_eol, mime_eol); |
200 | return 1; | 198 | return 1; |
201 | } | 199 | } |
202 | 200 | ||
@@ -231,6 +229,46 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) | |||
231 | return 1; | 229 | return 1; |
232 | } | 230 | } |
233 | 231 | ||
232 | /* Handle output of PKCS#7 data */ | ||
233 | |||
234 | |||
235 | static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags) | ||
236 | { | ||
237 | BIO *tmpbio, *p7bio; | ||
238 | |||
239 | if (!(flags & PKCS7_STREAM)) | ||
240 | { | ||
241 | SMIME_crlf_copy(data, out, flags); | ||
242 | return 1; | ||
243 | } | ||
244 | |||
245 | /* Partial sign operation */ | ||
246 | |||
247 | /* Initialize sign operation */ | ||
248 | p7bio = PKCS7_dataInit(p7, out); | ||
249 | |||
250 | /* Copy data across, computing digests etc */ | ||
251 | SMIME_crlf_copy(data, p7bio, flags); | ||
252 | |||
253 | /* Must be detached */ | ||
254 | PKCS7_set_detached(p7, 1); | ||
255 | |||
256 | /* Finalize signatures */ | ||
257 | PKCS7_dataFinal(p7, p7bio); | ||
258 | |||
259 | /* Now remove any digests prepended to the BIO */ | ||
260 | |||
261 | while (p7bio != out) | ||
262 | { | ||
263 | tmpbio = BIO_pop(p7bio); | ||
264 | BIO_free(p7bio); | ||
265 | p7bio = tmpbio; | ||
266 | } | ||
267 | |||
268 | return 1; | ||
269 | |||
270 | } | ||
271 | |||
234 | /* SMIME reader: handle multipart/signed and opaque signing. | 272 | /* SMIME reader: handle multipart/signed and opaque signing. |
235 | * in multipart case the content is placed in a memory BIO | 273 | * in multipart case the content is placed in a memory BIO |
236 | * pointed to by "bcont". In opaque this is set to NULL | 274 | * pointed to by "bcont". In opaque this is set to NULL |
@@ -339,56 +377,6 @@ PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) | |||
339 | 377 | ||
340 | } | 378 | } |
341 | 379 | ||
342 | /* Copy text from one BIO to another making the output CRLF at EOL */ | ||
343 | int SMIME_crlf_copy(BIO *in, BIO *out, int flags) | ||
344 | { | ||
345 | char eol; | ||
346 | int len; | ||
347 | char linebuf[MAX_SMLEN]; | ||
348 | if(flags & PKCS7_BINARY) { | ||
349 | while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) | ||
350 | BIO_write(out, linebuf, len); | ||
351 | return 1; | ||
352 | } | ||
353 | if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); | ||
354 | while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { | ||
355 | eol = strip_eol(linebuf, &len); | ||
356 | if (len) | ||
357 | BIO_write(out, linebuf, len); | ||
358 | if(eol) BIO_write(out, "\r\n", 2); | ||
359 | } | ||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | /* Strip off headers if they are text/plain */ | ||
364 | int SMIME_text(BIO *in, BIO *out) | ||
365 | { | ||
366 | char iobuf[4096]; | ||
367 | int len; | ||
368 | STACK_OF(MIME_HEADER) *headers; | ||
369 | MIME_HEADER *hdr; | ||
370 | |||
371 | if (!(headers = mime_parse_hdr(in))) { | ||
372 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR); | ||
373 | return 0; | ||
374 | } | ||
375 | if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { | ||
376 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE); | ||
377 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
378 | return 0; | ||
379 | } | ||
380 | if (strcmp (hdr->value, "text/plain")) { | ||
381 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE); | ||
382 | ERR_add_error_data(2, "type: ", hdr->value); | ||
383 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
384 | return 0; | ||
385 | } | ||
386 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
387 | while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) | ||
388 | BIO_write(out, iobuf, len); | ||
389 | return 1; | ||
390 | } | ||
391 | |||
392 | /* Split a multipart/XXX message body into component parts: result is | 380 | /* Split a multipart/XXX message body into component parts: result is |
393 | * canonical parts in a STACK of bios | 381 | * canonical parts in a STACK of bios |
394 | */ | 382 | */ |