summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/asn1/asn_mime.c')
-rw-r--r--Cryptlib/OpenSSL/crypto/asn1/asn_mime.c107
1 files changed, 88 insertions, 19 deletions
diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
index e7c5696b..96110c54 100644
--- a/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
+++ b/Cryptlib/OpenSSL/crypto/asn1/asn_mime.c
@@ -60,6 +60,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
@@ -88,6 +89,8 @@ typedef struct {
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);
@@ -109,6 +112,37 @@ static void mime_hdr_free(MIME_HEADER *hdr);
#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,
@@ -125,13 +159,25 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
* 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;
@@ -154,7 +200,8 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
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++) {
@@ -162,6 +209,19 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
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:
BIO_puts(out, "sha1");
@@ -183,6 +243,11 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
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;
@@ -195,16 +260,18 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
}
}
- return 1;
+ ret = 1;
+ err:
+
+ return ret;
}
/* SMIME sender */
-int 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)
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+ int ctype_nid, int econt_nid,
+ STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
{
char bound[33], c;
int i;
@@ -222,7 +289,8 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
if ((flags & SMIME_DETACHED) && data) {
/* We want multipart/signed */
/* Generate a random boundary */
- RAND_pseudo_bytes((unsigned char *)bound, 32);
+ if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+ return 0;
for (i = 0; i < 32; i++) {
c = bound[i] & 0xf;
if (c < 10)
@@ -243,7 +311,7 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
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);
@@ -291,8 +359,6 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
return 1;
}
-#if 0
-
/* Handle output of ASN1 data */
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
@@ -301,8 +367,13 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
BIO *tmpbio;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
+ int rv = 1;
- if (!(flags & SMIME_DETACHED)) {
+ /*
+ * If data is not deteched or resigning then the output BIO is already
+ * set up to finalise when it is written through.
+ */
+ if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
SMIME_crlf_copy(data, out, flags);
return 1;
}
@@ -326,7 +397,7 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
/* Finalize structure */
if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
- return 0;
+ rv = 0;
/* Now remove any digests prepended to the BIO */
@@ -336,12 +407,10 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
sarg.ndef_bio = tmpbio;
}
- return 1;
+ return rv;
}
-#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
@@ -737,7 +806,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if (!(tmpname = BUF_strdup(name)))
return NULL;
for (p = tmpname; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;
@@ -749,7 +818,7 @@ static MIME_HEADER *mime_hdr_new(char *name, char *value)
if (!(tmpval = BUF_strdup(value)))
return NULL;
for (p = tmpval; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;
@@ -777,7 +846,7 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
if (!tmpname)
return 0;
for (p = tmpname; *p; p++) {
- c = *p;
+ c = (unsigned char)*p;
if (isupper(c)) {
c = tolower(c);
*p = c;