summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/asn_mime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/asn_mime.c')
-rw-r--r--src/lib/libcrypto/asn1/asn_mime.c186
1 files changed, 93 insertions, 93 deletions
diff --git a/src/lib/libcrypto/asn1/asn_mime.c b/src/lib/libcrypto/asn1/asn_mime.c
index 2b600ab411..011b97ff92 100644
--- a/src/lib/libcrypto/asn1/asn_mime.c
+++ b/src/lib/libcrypto/asn1/asn_mime.c
@@ -114,48 +114,48 @@ static void mime_hdr_free(MIME_HEADER *hdr);
114 114
115int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, 115int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
116 const ASN1_ITEM *it) 116 const ASN1_ITEM *it)
117 { 117{
118 /* If streaming create stream BIO and copy all content through it */ 118 /* If streaming create stream BIO and copy all content through it */
119 if (flags & SMIME_STREAM) 119 if (flags & SMIME_STREAM)
120 { 120 {
121 BIO *bio, *tbio; 121 BIO *bio, *tbio;
122 bio = BIO_new_NDEF(out, val, it); 122 bio = BIO_new_NDEF(out, val, it);
123 if (!bio) 123 if (!bio)
124 { 124 {
125 ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE); 125 ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
126 return 0; 126 return 0;
127 } 127 }
128 SMIME_crlf_copy(in, bio, flags); 128 SMIME_crlf_copy(in, bio, flags);
129 (void)BIO_flush(bio); 129 (void)BIO_flush(bio);
130 /* Free up successive BIOs until we hit the old output BIO */ 130 /* Free up successive BIOs until we hit the old output BIO */
131 do 131 do
132 { 132 {
133 tbio = BIO_pop(bio); 133 tbio = BIO_pop(bio);
134 BIO_free(bio); 134 BIO_free(bio);
135 bio = tbio; 135 bio = tbio;
136 } while (bio != out); 136 } while (bio != out);
137 } 137 }
138 /* else just write out ASN1 structure which will have all content 138 /* else just write out ASN1 structure which will have all content
139 * stored internally 139 * stored internally
140 */ 140 */
141 else 141 else
142 ASN1_item_i2d_bio(it, out, val); 142 ASN1_item_i2d_bio(it, out, val);
143 return 1; 143 return 1;
144 } 144}
145 145
146/* Base 64 read and write of ASN1 structure */ 146/* Base 64 read and write of ASN1 structure */
147 147
148static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, 148static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
149 const ASN1_ITEM *it) 149 const ASN1_ITEM *it)
150 { 150{
151 BIO *b64; 151 BIO *b64;
152 int r; 152 int r;
153 b64 = BIO_new(BIO_f_base64()); 153 b64 = BIO_new(BIO_f_base64());
154 if(!b64) 154 if(!b64)
155 { 155 {
156 ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE); 156 ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
157 return 0; 157 return 0;
158 } 158 }
159 /* prepend the b64 BIO so all data is base64 encoded. 159 /* prepend the b64 BIO so all data is base64 encoded.
160 */ 160 */
161 out = BIO_push(b64, out); 161 out = BIO_push(b64, out);
@@ -164,20 +164,20 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
164 BIO_pop(out); 164 BIO_pop(out);
165 BIO_free(b64); 165 BIO_free(b64);
166 return r; 166 return r;
167 } 167}
168 168
169/* Streaming ASN1 PEM write */ 169/* Streaming ASN1 PEM write */
170 170
171int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, 171int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
172 const char *hdr, 172 const char *hdr,
173 const ASN1_ITEM *it) 173 const ASN1_ITEM *it)
174 { 174{
175 int r; 175 int r;
176 BIO_printf(out, "-----BEGIN %s-----\n", hdr); 176 BIO_printf(out, "-----BEGIN %s-----\n", hdr);
177 r = B64_write_ASN1(out, val, in, flags, it); 177 r = B64_write_ASN1(out, val, in, flags, it);
178 BIO_printf(out, "-----END %s-----\n", hdr); 178 BIO_printf(out, "-----END %s-----\n", hdr);
179 return r; 179 return r;
180 } 180}
181 181
182static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) 182static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
183{ 183{
@@ -186,7 +186,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
186 if(!(b64 = BIO_new(BIO_f_base64()))) { 186 if(!(b64 = BIO_new(BIO_f_base64()))) {
187 ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE); 187 ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
188 return 0; 188 return 0;
189 } 189}
190 bio = BIO_push(b64, bio); 190 bio = BIO_push(b64, bio);
191 val = ASN1_item_d2i_bio(it, bio, NULL); 191 val = ASN1_item_d2i_bio(it, bio, NULL);
192 if(!val) 192 if(!val)
@@ -200,34 +200,34 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
200/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */ 200/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
201 201
202static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) 202static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
203 { 203{
204 const EVP_MD *md; 204 const EVP_MD *md;
205 int i, have_unknown = 0, write_comma, ret = 0, md_nid; 205 int i, have_unknown = 0, write_comma, ret = 0, md_nid;
206 have_unknown = 0; 206 have_unknown = 0;
207 write_comma = 0; 207 write_comma = 0;
208 for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) 208 for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
209 { 209 {
210 if (write_comma) 210 if (write_comma)
211 BIO_write(out, ",", 1); 211 BIO_write(out, ",", 1);
212 write_comma = 1; 212 write_comma = 1;
213 md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); 213 md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
214 md = EVP_get_digestbynid(md_nid); 214 md = EVP_get_digestbynid(md_nid);
215 if (md && md->md_ctrl) 215 if (md && md->md_ctrl)
216 { 216 {
217 int rv; 217 int rv;
218 char *micstr; 218 char *micstr;
219 rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); 219 rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
220 if (rv > 0) 220 if (rv > 0)
221 { 221 {
222 BIO_puts(out, micstr); 222 BIO_puts(out, micstr);
223 free(micstr); 223 free(micstr);
224 continue; 224 continue;
225 } 225 }
226 if (rv != -2) 226 if (rv != -2)
227 goto err; 227 goto err;
228 } 228 }
229 switch(md_nid) 229 switch(md_nid)
230 { 230 {
231 case NID_sha1: 231 case NID_sha1:
232 BIO_puts(out, "sha1"); 232 BIO_puts(out, "sha1");
233 break; 233 break;
@@ -257,21 +257,21 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
257 if (have_unknown) 257 if (have_unknown)
258 write_comma = 0; 258 write_comma = 0;
259 else 259 else
260 { 260 {
261 BIO_puts(out, "unknown"); 261 BIO_puts(out, "unknown");
262 have_unknown = 1; 262 have_unknown = 1;
263 } 263 }
264 break; 264 break;
265 265
266 }
267 } 266 }
267 }
268 268
269 ret = 1; 269 ret = 1;
270 err: 270 err:
271 271
272 return ret; 272 return ret;
273 273
274 } 274}
275 275
276/* SMIME sender */ 276/* SMIME sender */
277 277
@@ -302,7 +302,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
302 if(c < 10) c += '0'; 302 if(c < 10) c += '0';
303 else c += 'A' - 10; 303 else c += 'A' - 10;
304 bound[i] = c; 304 bound[i] = c;
305 } 305 }
306 bound[32] = 0; 306 bound[32] = 0;
307 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); 307 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
308 BIO_printf(bio, "Content-Type: multipart/signed;"); 308 BIO_printf(bio, "Content-Type: multipart/signed;");
@@ -332,26 +332,26 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
332 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound, 332 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
333 mime_eol, mime_eol); 333 mime_eol, mime_eol);
334 return 1; 334 return 1;
335 } 335}
336 336
337 /* Determine smime-type header */ 337 /* Determine smime-type header */
338 338
339 if (ctype_nid == NID_pkcs7_enveloped) 339 if (ctype_nid == NID_pkcs7_enveloped)
340 msg_type = "enveloped-data"; 340 msg_type = "enveloped-data";
341 else if (ctype_nid == NID_pkcs7_signed) 341 else if (ctype_nid == NID_pkcs7_signed)
342 { 342 {
343 if (econt_nid == NID_id_smime_ct_receipt) 343 if (econt_nid == NID_id_smime_ct_receipt)
344 msg_type = "signed-receipt"; 344 msg_type = "signed-receipt";
345 else if (sk_X509_ALGOR_num(mdalgs) >= 0) 345 else if (sk_X509_ALGOR_num(mdalgs) >= 0)
346 msg_type = "signed-data"; 346 msg_type = "signed-data";
347 else 347 else
348 msg_type = "certs-only"; 348 msg_type = "certs-only";
349 } 349 }
350 else if (ctype_nid == NID_id_smime_ct_compressedData) 350 else if (ctype_nid == NID_id_smime_ct_compressedData)
351 { 351 {
352 msg_type = "compressed-data"; 352 msg_type = "compressed-data";
353 cname = "smime.p7z"; 353 cname = "smime.p7z";
354 } 354 }
355 /* MIME headers */ 355 /* MIME headers */
356 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); 356 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
357 BIO_printf(bio, "Content-Disposition: attachment;"); 357 BIO_printf(bio, "Content-Disposition: attachment;");
@@ -373,7 +373,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
373 373
374static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, 374static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
375 const ASN1_ITEM *it) 375 const ASN1_ITEM *it)
376 { 376{
377 BIO *tmpbio; 377 BIO *tmpbio;
378 const ASN1_AUX *aux = it->funcs; 378 const ASN1_AUX *aux = it->funcs;
379 ASN1_STREAM_ARG sarg; 379 ASN1_STREAM_ARG sarg;
@@ -383,17 +383,17 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
383 * already set up to finalise when it is written through. 383 * already set up to finalise when it is written through.
384 */ 384 */
385 if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) 385 if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
386 { 386 {
387 SMIME_crlf_copy(data, out, flags); 387 SMIME_crlf_copy(data, out, flags);
388 return 1; 388 return 1;
389 } 389 }
390 390
391 if (!aux || !aux->asn1_cb) 391 if (!aux || !aux->asn1_cb)
392 { 392 {
393 ASN1err(ASN1_F_ASN1_OUTPUT_DATA, 393 ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
394 ASN1_R_STREAMING_NOT_SUPPORTED); 394 ASN1_R_STREAMING_NOT_SUPPORTED);
395 return 0; 395 return 0;
396 } 396 }
397 397
398 sarg.out = out; 398 sarg.out = out;
399 sarg.ndef_bio = NULL; 399 sarg.ndef_bio = NULL;
@@ -414,15 +414,15 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
414 /* Now remove any digests prepended to the BIO */ 414 /* Now remove any digests prepended to the BIO */
415 415
416 while (sarg.ndef_bio != out) 416 while (sarg.ndef_bio != out)
417 { 417 {
418 tmpbio = BIO_pop(sarg.ndef_bio); 418 tmpbio = BIO_pop(sarg.ndef_bio);
419 BIO_free(sarg.ndef_bio); 419 BIO_free(sarg.ndef_bio);
420 sarg.ndef_bio = tmpbio; 420 sarg.ndef_bio = tmpbio;
421 } 421 }
422 422
423 return rv; 423 return rv;
424 424
425 } 425}
426 426
427/* SMIME reader: handle multipart/signed and opaque signing. 427/* SMIME reader: handle multipart/signed and opaque signing.
428 * in multipart case the content is placed in a memory BIO 428 * in multipart case the content is placed in a memory BIO
@@ -444,13 +444,13 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
444 if (!(headers = mime_parse_hdr(bio))) { 444 if (!(headers = mime_parse_hdr(bio))) {
445 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR); 445 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
446 return NULL; 446 return NULL;
447 } 447}
448 448
449 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { 449 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
450 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 450 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
451 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); 451 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
452 return NULL; 452 return NULL;
453 } 453}
454 454
455 /* Handle multipart/signed */ 455 /* Handle multipart/signed */
456 456
@@ -461,14 +461,14 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
461 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 461 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
462 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); 462 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
463 return NULL; 463 return NULL;
464 } 464 }
465 ret = multi_split(bio, prm->param_value, &parts); 465 ret = multi_split(bio, prm->param_value, &parts);
466 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 466 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
467 if(!ret || (sk_BIO_num(parts) != 2) ) { 467 if(!ret || (sk_BIO_num(parts) != 2) ) {
468 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); 468 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
469 sk_BIO_pop_free(parts, BIO_vfree); 469 sk_BIO_pop_free(parts, BIO_vfree);
470 return NULL; 470 return NULL;
471 } 471 }
472 472
473 /* Parse the signature piece */ 473 /* Parse the signature piece */
474 asnin = sk_BIO_value(parts, 1); 474 asnin = sk_BIO_value(parts, 1);
@@ -477,7 +477,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
477 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR); 477 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
478 sk_BIO_pop_free(parts, BIO_vfree); 478 sk_BIO_pop_free(parts, BIO_vfree);
479 return NULL; 479 return NULL;
480 } 480 }
481 481
482 /* Get content type */ 482 /* Get content type */
483 483
@@ -486,7 +486,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
486 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 486 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
487 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); 487 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
488 return NULL; 488 return NULL;
489 } 489 }
490 490
491 if(strcmp(hdr->value, "application/x-pkcs7-signature") && 491 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
492 strcmp(hdr->value, "application/pkcs7-signature")) { 492 strcmp(hdr->value, "application/pkcs7-signature")) {
@@ -495,22 +495,22 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
495 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 495 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
496 sk_BIO_pop_free(parts, BIO_vfree); 496 sk_BIO_pop_free(parts, BIO_vfree);
497 return NULL; 497 return NULL;
498 } 498 }
499 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 499 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
500 /* Read in ASN1 */ 500 /* Read in ASN1 */
501 if(!(val = b64_read_asn1(asnin, it))) { 501 if(!(val = b64_read_asn1(asnin, it))) {
502 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR); 502 ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
503 sk_BIO_pop_free(parts, BIO_vfree); 503 sk_BIO_pop_free(parts, BIO_vfree);
504 return NULL; 504 return NULL;
505 } 505 }
506 506
507 if(bcont) { 507 if(bcont) {
508 *bcont = sk_BIO_value(parts, 0); 508 *bcont = sk_BIO_value(parts, 0);
509 BIO_free(asnin); 509 BIO_free(asnin);
510 sk_BIO_free(parts); 510 sk_BIO_free(parts);
511 } else sk_BIO_pop_free(parts, BIO_vfree); 511 } else sk_BIO_pop_free(parts, BIO_vfree);
512 return val; 512 return val;
513 } 513}
514 514
515 /* OK, if not multipart/signed try opaque signature */ 515 /* OK, if not multipart/signed try opaque signature */
516 516
@@ -520,14 +520,14 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
520 ERR_add_error_data(2, "type: ", hdr->value); 520 ERR_add_error_data(2, "type: ", hdr->value);
521 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 521 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
522 return NULL; 522 return NULL;
523 } 523}
524 524
525 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 525 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
526 526
527 if(!(val = b64_read_asn1(bio, it))) { 527 if(!(val = b64_read_asn1(bio, it))) {
528 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); 528 ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
529 return NULL; 529 return NULL;
530 } 530}
531 return val; 531 return val;
532 532
533} 533}
@@ -548,22 +548,22 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
548 return 0; 548 return 0;
549 out = BIO_push(bf, out); 549 out = BIO_push(bf, out);
550 if(flags & SMIME_BINARY) 550 if(flags & SMIME_BINARY)
551 { 551 {
552 while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) 552 while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
553 BIO_write(out, linebuf, len); 553 BIO_write(out, linebuf, len);
554 } 554 }
555 else 555 else
556 { 556 {
557 if(flags & SMIME_TEXT) 557 if(flags & SMIME_TEXT)
558 BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); 558 BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
559 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) 559 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
560 { 560 {
561 eol = strip_eol(linebuf, &len); 561 eol = strip_eol(linebuf, &len);
562 if (len) 562 if (len)
563 BIO_write(out, linebuf, len); 563 BIO_write(out, linebuf, len);
564 if(eol) BIO_write(out, "\r\n", 2); 564 if(eol) BIO_write(out, "\r\n", 2);
565 }
566 } 565 }
566 }
567 (void)BIO_flush(out); 567 (void)BIO_flush(out);
568 BIO_pop(out); 568 BIO_pop(out);
569 BIO_free(bf); 569 BIO_free(bf);
@@ -581,18 +581,18 @@ int SMIME_text(BIO *in, BIO *out)
581 if (!(headers = mime_parse_hdr(in))) { 581 if (!(headers = mime_parse_hdr(in))) {
582 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR); 582 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
583 return 0; 583 return 0;
584 } 584}
585 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { 585 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
586 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE); 586 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
587 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 587 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
588 return 0; 588 return 0;
589 } 589}
590 if (strcmp (hdr->value, "text/plain")) { 590 if (strcmp (hdr->value, "text/plain")) {
591 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE); 591 ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
592 ERR_add_error_data(2, "type: ", hdr->value); 592 ERR_add_error_data(2, "type: ", hdr->value);
593 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 593 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
594 return 0; 594 return 0;
595 } 595}
596 sk_MIME_HEADER_pop_free(headers, mime_hdr_free); 596 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
597 while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) 597 while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
598 BIO_write(out, iobuf, len); 598 BIO_write(out, iobuf, len);
@@ -625,10 +625,10 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
625 if(state == 1) { 625 if(state == 1) {
626 first = 1; 626 first = 1;
627 part++; 627 part++;
628 } else if(state == 2) { 628 } else if(state == 2) {
629 sk_BIO_push(parts, bpart); 629 sk_BIO_push(parts, bpart);
630 return 1; 630 return 1;
631 } else if(part) { 631 } else if(part) {
632 /* Strip CR+LF from linebuf */ 632 /* Strip CR+LF from linebuf */
633 next_eol = strip_eol(linebuf, &len); 633 next_eol = strip_eol(linebuf, &len);
634 if(first) { 634 if(first) {
@@ -636,13 +636,13 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
636 if(bpart) sk_BIO_push(parts, bpart); 636 if(bpart) sk_BIO_push(parts, bpart);
637 bpart = BIO_new(BIO_s_mem()); 637 bpart = BIO_new(BIO_s_mem());
638 BIO_set_mem_eof_return(bpart, 0); 638 BIO_set_mem_eof_return(bpart, 0);
639 } else if (eol) 639 } else if (eol)
640 BIO_write(bpart, "\r\n", 2); 640 BIO_write(bpart, "\r\n", 2);
641 eol = next_eol; 641 eol = next_eol;
642 if (len) 642 if (len)
643 BIO_write(bpart, linebuf, len); 643 BIO_write(bpart, linebuf, len);
644 }
645 } 644 }
645}
646 return 0; 646 return 0;
647} 647}
648 648
@@ -686,7 +686,7 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
686 *p = 0; 686 *p = 0;
687 ntmp = strip_ends(q); 687 ntmp = strip_ends(q);
688 q = p + 1; 688 q = p + 1;
689 } 689 }
690 break; 690 break;
691 691
692 case MIME_TYPE: 692 case MIME_TYPE:
@@ -698,16 +698,16 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
698 ntmp = NULL; 698 ntmp = NULL;
699 q = p + 1; 699 q = p + 1;
700 state = MIME_NAME; 700 state = MIME_NAME;
701 } else if(c == '(') { 701 } else if(c == '(') {
702 save_state = state; 702 save_state = state;
703 state = MIME_COMMENT; 703 state = MIME_COMMENT;
704 } 704 }
705 break; 705 break;
706 706
707 case MIME_COMMENT: 707 case MIME_COMMENT:
708 if(c == ')') { 708 if(c == ')') {
709 state = save_state; 709 state = save_state;
710 } 710 }
711 break; 711 break;
712 712
713 case MIME_NAME: 713 case MIME_NAME:
@@ -716,7 +716,7 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
716 *p = 0; 716 *p = 0;
717 ntmp = strip_ends(q); 717 ntmp = strip_ends(q);
718 q = p + 1; 718 q = p + 1;
719 } 719 }
720 break ; 720 break ;
721 721
722 case MIME_VALUE: 722 case MIME_VALUE:
@@ -726,28 +726,28 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
726 mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); 726 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
727 ntmp = NULL; 727 ntmp = NULL;
728 q = p + 1; 728 q = p + 1;
729 } else if (c == '"') { 729 } else if (c == '"') {
730 mime_debug("Found Quote\n"); 730 mime_debug("Found Quote\n");
731 state = MIME_QUOTE; 731 state = MIME_QUOTE;
732 } else if(c == '(') { 732 } else if(c == '(') {
733 save_state = state; 733 save_state = state;
734 state = MIME_COMMENT; 734 state = MIME_COMMENT;
735 } 735 }
736 break; 736 break;
737 737
738 case MIME_QUOTE: 738 case MIME_QUOTE:
739 if(c == '"') { 739 if(c == '"') {
740 mime_debug("Found Match Quote\n"); 740 mime_debug("Found Match Quote\n");
741 state = MIME_VALUE; 741 state = MIME_VALUE;
742 }
743 break;
744 } 742 }
743 break;
745 } 744 }
745}
746 746
747 if(state == MIME_TYPE) { 747 if(state == MIME_TYPE) {
748 mhdr = mime_hdr_new(ntmp, strip_ends(q)); 748 mhdr = mime_hdr_new(ntmp, strip_ends(q));
749 sk_MIME_HEADER_push(headers, mhdr); 749 sk_MIME_HEADER_push(headers, mhdr);
750 } else if(state == MIME_VALUE) 750} else if(state == MIME_VALUE)
751 mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); 751 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
752 if(p == linebuf) break; /* Blank line means end of headers */ 752 if(p == linebuf) break; /* Blank line means end of headers */
753} 753}
@@ -772,9 +772,9 @@ static char *strip_start(char *name)
772 if(p[1]) return p + 1; 772 if(p[1]) return p + 1;
773 /* Else null string */ 773 /* Else null string */
774 return NULL; 774 return NULL;
775 }
776 if(!isspace((unsigned char)c)) return p;
777 } 775 }
776 if(!isspace((unsigned char)c)) return p;
777}
778 return NULL; 778 return NULL;
779} 779}
780 780
@@ -790,10 +790,10 @@ static char *strip_end(char *name)
790 if(p - 1 == name) return NULL; 790 if(p - 1 == name) return NULL;
791 *p = 0; 791 *p = 0;
792 return name; 792 return name;
793 } 793 }
794 if(isspace((unsigned char)c)) *p = 0; 794 if(isspace((unsigned char)c)) *p = 0;
795 else return name; 795 else return name;
796 } 796}
797 return NULL; 797 return NULL;
798} 798}
799 799
@@ -809,9 +809,9 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
809 if(isupper(c)) { 809 if(isupper(c)) {
810 c = tolower(c); 810 c = tolower(c);
811 *p = c; 811 *p = c;
812 }
813 } 812 }
814 } else tmpname = NULL; 813 }
814} else tmpname = NULL;
815 if(value) { 815 if(value) {
816 if(!(tmpval = BUF_strdup(value))) return NULL; 816 if(!(tmpval = BUF_strdup(value))) return NULL;
817 for(p = tmpval ; *p; p++) { 817 for(p = tmpval ; *p; p++) {
@@ -819,20 +819,20 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
819 if(isupper(c)) { 819 if(isupper(c)) {
820 c = tolower(c); 820 c = tolower(c);
821 *p = c; 821 *p = c;
822 }
823 } 822 }
824 } else tmpval = NULL; 823 }
824} else tmpval = NULL;
825 mhdr = (MIME_HEADER *) malloc(sizeof(MIME_HEADER)); 825 mhdr = (MIME_HEADER *) malloc(sizeof(MIME_HEADER));
826 if (!mhdr) { 826 if (!mhdr) {
827 OPENSSL_free(tmpname); 827 OPENSSL_free(tmpname);
828 return NULL; 828 return NULL;
829 } 829}
830 mhdr->name = tmpname; 830 mhdr->name = tmpname;
831 mhdr->value = tmpval; 831 mhdr->value = tmpval;
832 if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) { 832 if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) {
833 free(mhdr); 833 free(mhdr);
834 return NULL; 834 return NULL;
835 } 835}
836 return mhdr; 836 return mhdr;
837} 837}
838 838
@@ -849,13 +849,13 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
849 if(isupper(c)) { 849 if(isupper(c)) {
850 c = tolower(c); 850 c = tolower(c);
851 *p = c; 851 *p = c;
852 }
853 } 852 }
854 } else tmpname = NULL; 853 }
854} else tmpname = NULL;
855 if(value) { 855 if(value) {
856 tmpval = BUF_strdup(value); 856 tmpval = BUF_strdup(value);
857 if(!tmpval) return 0; 857 if(!tmpval) return 0;
858 } else tmpval = NULL; 858} else tmpval = NULL;
859 /* Parameter values are case sensitive so leave as is */ 859 /* Parameter values are case sensitive so leave as is */
860 mparam = (MIME_PARAM *) malloc(sizeof(MIME_PARAM)); 860 mparam = (MIME_PARAM *) malloc(sizeof(MIME_PARAM));
861 if(!mparam) return 0; 861 if(!mparam) return 0;
@@ -934,24 +934,24 @@ static int mime_bound_check(char *line, int linelen, char *bound, int blen)
934 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { 934 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
935 if(!strncmp(line + blen + 2, "--", 2)) return 2; 935 if(!strncmp(line + blen + 2, "--", 2)) return 2;
936 else return 1; 936 else return 1;
937 } 937}
938 return 0; 938 return 0;
939} 939}
940 940
941static int strip_eol(char *linebuf, int *plen) 941static int strip_eol(char *linebuf, int *plen)
942 { 942{
943 int len = *plen; 943 int len = *plen;
944 char *p, c; 944 char *p, c;
945 int is_eol = 0; 945 int is_eol = 0;
946 p = linebuf + len - 1; 946 p = linebuf + len - 1;
947 for (p = linebuf + len - 1; len > 0; len--, p--) 947 for (p = linebuf + len - 1; len > 0; len--, p--)
948 { 948 {
949 c = *p; 949 c = *p;
950 if (c == '\n') 950 if (c == '\n')
951 is_eol = 1; 951 is_eol = 1;
952 else if (c != '\r') 952 else if (c != '\r')
953 break; 953 break;
954 } 954 }
955 *plen = len; 955 *plen = len;
956 return is_eol; 956 return is_eol;
957 } 957}