Index: openssl/crypto/asn1/asn_mime.c |
=================================================================== |
--- openssl/crypto/asn1/asn_mime.c (revision 105093) |
+++ openssl/crypto/asn1/asn_mime.c (working copy) |
@@ -59,6 +59,7 @@ |
#include <openssl/x509.h> |
#include <openssl/asn1.h> |
#include <openssl/asn1t.h> |
+#include "asn1_locl.h" |
/* Generalised MIME like utilities for streaming ASN1. Although many |
* have a PKCS7/CMS like flavour others are more general purpose. |
@@ -86,6 +87,8 @@ |
DECLARE_STACK_OF(MIME_HEADER) |
IMPLEMENT_STACK_OF(MIME_HEADER) |
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, |
+ const ASN1_ITEM *it); |
static char * strip_ends(char *name); |
static char * strip_start(char *name); |
static char * strip_end(char *name); |
@@ -107,6 +110,39 @@ |
#define MAX_SMLEN 1024 |
#define mime_debug(x) /* x */ |
+/* Output an ASN1 structure in BER format streaming if necessary */ |
+ |
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, |
+ const ASN1_ITEM *it) |
+ { |
+ /* If streaming create stream BIO and copy all content through it */ |
+ if (flags & SMIME_STREAM) |
+ { |
+ BIO *bio, *tbio; |
+ bio = BIO_new_NDEF(out, val, it); |
+ if (!bio) |
+ { |
+ ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE); |
+ return 0; |
+ } |
+ SMIME_crlf_copy(in, bio, flags); |
+ (void)BIO_flush(bio); |
+ /* Free up successive BIOs until we hit the old output BIO */ |
+ do |
+ { |
+ tbio = BIO_pop(bio); |
+ BIO_free(bio); |
+ bio = tbio; |
+ } while (bio != out); |
+ } |
+ /* else just write out ASN1 structure which will have all content |
+ * stored internally |
+ */ |
+ else |
+ ASN1_item_i2d_bio(it, out, val); |
+ return 1; |
+ } |
+ |
/* Base 64 read and write of ASN1 structure */ |
static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, |
@@ -123,13 +159,26 @@ |
/* prepend the b64 BIO so all data is base64 encoded. |
*/ |
out = BIO_push(b64, out); |
- r = ASN1_item_i2d_bio(it, out, val); |
+ r = i2d_ASN1_bio_stream(out, val, in, flags, it); |
(void)BIO_flush(out); |
BIO_pop(out); |
BIO_free(b64); |
return r; |
} |
+/* Streaming ASN1 PEM write */ |
+ |
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, |
+ const char *hdr, |
+ const ASN1_ITEM *it) |
+ { |
+ int r; |
+ BIO_printf(out, "-----BEGIN %s-----\n", hdr); |
+ r = B64_write_ASN1(out, val, in, flags, it); |
+ BIO_printf(out, "-----END %s-----\n", hdr); |
+ return r; |
+ } |
+ |
static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) |
{ |
BIO *b64; |
@@ -152,7 +201,8 @@ |
static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) |
{ |
- int i, have_unknown = 0, write_comma, md_nid; |
+ const EVP_MD *md; |
+ int i, have_unknown = 0, write_comma, ret = 0, md_nid; |
have_unknown = 0; |
write_comma = 0; |
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) |
@@ -161,6 +211,21 @@ |
BIO_write(out, ",", 1); |
write_comma = 1; |
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); |
+ md = EVP_get_digestbynid(md_nid); |
+ if (md && md->md_ctrl) |
+ { |
+ int rv; |
+ char *micstr; |
+ rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); |
+ if (rv > 0) |
+ { |
+ BIO_puts(out, micstr); |
+ OPENSSL_free(micstr); |
+ continue; |
+ } |
+ if (rv != -2) |
+ goto err; |
+ } |
switch(md_nid) |
{ |
case NID_sha1: |
@@ -183,6 +248,11 @@ |
BIO_puts(out, "sha-512"); |
break; |
+ case NID_id_GostR3411_94: |
+ BIO_puts(out, "gostr3411-94"); |
+ goto err; |
+ break; |
+ |
default: |
if (have_unknown) |
write_comma = 0; |
@@ -196,16 +266,18 @@ |
} |
} |
- return 1; |
+ ret = 1; |
+ err: |
+ return ret; |
+ |
} |
/* SMIME sender */ |
-int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, |
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, |
int ctype_nid, int econt_nid, |
STACK_OF(X509_ALGOR) *mdalgs, |
- asn1_output_data_fn *data_fn, |
const ASN1_ITEM *it) |
{ |
char bound[33], c; |
@@ -243,7 +315,7 @@ |
mime_eol, mime_eol); |
/* Now write out the first part */ |
BIO_printf(bio, "------%s%s", bound, mime_eol); |
- if (!data_fn(bio, data, val, flags, it)) |
+ if (!asn1_output_data(bio, data, val, flags, it)) |
return 0; |
BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); |
@@ -296,8 +368,6 @@ |
return 1; |
} |
-#if 0 |
- |
/* Handle output of ASN1 data */ |
@@ -350,8 +420,6 @@ |
} |
-#endif |
- |
/* SMIME reader: handle multipart/signed and opaque signing. |
* in multipart case the content is placed in a memory BIO |
* pointed to by "bcont". In opaque this is set to NULL |