From dea2878fac8bde549fa0dd3b8e895703b174391b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 25 May 2021 17:16:18 +0100 Subject: Teach more of the ASN.1 code about libctx/propq Make sure we pass libctx/propq down to all the layers so that objects that are created during parsing have the right values. Then use this new capability for PKCS7. Reviewed-by: Shane Lontis Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15591) --- crypto/asn1/a_d2i_fp.c | 20 +++++++-- crypto/asn1/asn1_local.h | 3 ++ crypto/asn1/asn_mime.c | 16 ++++--- crypto/asn1/tasn_dec.c | 100 ++++++++++++++++++++++++++++--------------- crypto/asn1/tasn_new.c | 7 +++ crypto/pkcs7/pk7_asn1.c | 13 +++++- crypto/pkcs7/pk7_mime.c | 9 +++- crypto/x509/x_all.c | 19 +++++++- doc/man3/SMIME_read_ASN1.pod | 8 +++- include/openssl/asn1.h.in | 12 +++++- include/openssl/asn1t.h.in | 5 +++ util/libcrypto.num | 3 ++ 12 files changed, 161 insertions(+), 54 deletions(-) diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c index f1e96b2eaf..e8602053f9 100644 --- a/crypto/asn1/a_d2i_fp.c +++ b/crypto/asn1/a_d2i_fp.c @@ -55,7 +55,8 @@ void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) #endif -void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +void *ASN1_item_d2i_bio_ex(const ASN1_ITEM *it, BIO *in, void *x, + OSSL_LIB_CTX *libctx, const char *propq) { BUF_MEM *b = NULL; const unsigned char *p; @@ -69,14 +70,20 @@ void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) goto err; p = (const unsigned char *)b->data; - ret = ASN1_item_d2i(x, &p, len, it); + ret = ASN1_item_d2i_ex(x, &p, len, it, libctx, propq); err: BUF_MEM_free(b); return ret; } +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + return ASN1_item_d2i_bio_ex(it, in, x, NULL, NULL); +} + #ifndef OPENSSL_NO_STDIO -void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +void *ASN1_item_d2i_fp_ex(const ASN1_ITEM *it, FILE *in, void *x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; char *ret; @@ -86,10 +93,15 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) return NULL; } BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_item_d2i_bio(it, b, x); + ret = ASN1_item_d2i_bio_ex(it, b, x, libctx, propq); BIO_free(b); return ret; } + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + return ASN1_item_d2i_fp_ex(it, in, x, NULL, NULL); +} #endif #define HEADER_SIZE 8 diff --git a/crypto/asn1/asn1_local.h b/crypto/asn1/asn1_local.h index 15843ac689..f73bd8fc6a 100644 --- a/crypto/asn1/asn1_local.h +++ b/crypto/asn1/asn1_local.h @@ -89,3 +89,6 @@ int ossl_c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, int ossl_i2c_uint64_int(unsigned char *p, uint64_t r, int neg); ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type); + +int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index 1c1f72f800..1b8ac34106 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -130,7 +130,8 @@ int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, return r; } -static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x) +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *b64; ASN1_VALUE *val; @@ -140,7 +141,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x) return 0; } bio = BIO_push(b64, bio); - val = ASN1_item_d2i_bio(it, bio, x); + val = ASN1_item_d2i_bio_ex(it, bio, x, libctx, propq); if (!val) ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR); (void)BIO_flush(bio); @@ -388,8 +389,9 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, * opaque this is set to NULL */ -ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, const ASN1_ITEM *it, - ASN1_VALUE **x) +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, + const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *asnin; STACK_OF(MIME_HEADER) *headers = NULL; @@ -461,7 +463,7 @@ ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, const ASN1_ITEM } sk_MIME_HEADER_pop_free(headers, mime_hdr_free); /* Read in ASN1 */ - if ((val = b64_read_asn1(asnin, it, x)) == NULL) { + if ((val = b64_read_asn1(asnin, it, x, libctx, propq)) == NULL) { ERR_raise(ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); sk_BIO_pop_free(parts, BIO_vfree); return NULL; @@ -489,7 +491,7 @@ ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, const ASN1_ITEM sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - if ((val = b64_read_asn1(bio, it, x)) == NULL) { + if ((val = b64_read_asn1(bio, it, x, libctx, propq)) == NULL) { ERR_raise(ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR); return NULL; } @@ -498,7 +500,7 @@ ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, const ASN1_ITEM ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) { - return SMIME_read_ASN1_ex(bio, 0, bcont, it, NULL); + return SMIME_read_ASN1_ex(bio, 0, bcont, it, NULL, NULL, NULL); } /* Copy text from one BIO to another making the output CRLF at EOL */ diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index aaf3de7e19..eff67d87fc 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -28,7 +28,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, - int depth); + int depth, OSSL_LIB_CTX *libctx, + const char *propq); static int asn1_check_eoc(const unsigned char **in, long len); static int asn1_find_end(const unsigned char **in, long len, char inf); @@ -46,11 +47,13 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); + ASN1_TLC *ctx, int depth, OSSL_LIB_CTX *libctx, + const char *propq); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, @@ -101,9 +104,36 @@ unsigned long ASN1_tag2bit(int tag) * this will simply be a special case. */ -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it) +static int asn1_item_ex_d2i_intern(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, + int aclass, char opt, ASN1_TLC *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int rv; + + if (pval == NULL || it == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0, + libctx, propq); + if (rv <= 0) + ASN1_item_ex_free(pval, it); + return rv; +} + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + return asn1_item_ex_d2i_intern(pval, in, len, it, tag, aclass, opt, ctx, + NULL, NULL); +} + +ASN1_VALUE *ASN1_item_d2i_ex(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, + const char *propq) { ASN1_TLC c; ASN1_VALUE *ptmpval = NULL; @@ -111,25 +141,17 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, if (pval == NULL) pval = &ptmpval; asn1_tlc_clear_nc(&c); - if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + if (asn1_item_ex_d2i_intern(pval, in, len, it, -1, 0, 0, &c, libctx, + propq) > 0) return *pval; return NULL; } -int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it) { - int rv; - - if (pval == NULL || it == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); - if (rv <= 0) - ASN1_item_ex_free(pval, it); - return rv; + return ASN1_item_d2i_ex(pval, in, len, it, NULL, NULL); } /* @@ -140,7 +162,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, - int depth) + int depth, OSSL_LIB_CTX *libctx, + const char *propq) { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_EXTERN_FUNCS *ef; @@ -188,8 +211,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; } - return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx, depth); + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx, + depth, libctx, propq); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); @@ -235,6 +258,9 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, case ASN1_ITYPE_EXTERN: /* Use new style d2i */ ef = it->funcs; + if (ef->asn1_ex_d2i_ex != NULL) + return ef->asn1_ex_d2i_ex(pval, in, len, it, tag, aclass, opt, ctx, + libctx, propq); return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); case ASN1_ITYPE_CHOICE: @@ -258,7 +284,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, ossl_asn1_template_free(pchptr, tt); ossl_asn1_set_choice_selector(pval, -1, it); } - } else if (!ASN1_item_ex_new(pval, it)) { + } else if (!ossl_asn1_item_ex_new_intern(pval, it, libctx, propq)) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -269,7 +295,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* * We mark field as OPTIONAL so its absence can be recognised. */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth, + libctx, propq); /* If field not present, try the next one */ if (ret == -1) continue; @@ -335,7 +362,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, goto err; } - if (*pval == NULL && !ASN1_item_ex_new(pval, it)) { + if (*pval == NULL + && !ossl_asn1_item_ex_new_intern(pval, it, libctx, propq)) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -392,7 +420,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, */ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, - depth); + depth, libctx, propq); if (!ret) { errtt = seqtt; goto err; @@ -468,7 +496,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq) { int flags, aclass; int ret; @@ -502,7 +531,8 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, return 0; } /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth, libctx, + propq); if (!ret) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; @@ -525,7 +555,8 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, } } } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth, + libctx, propq); *in = p; return 1; @@ -537,7 +568,8 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq) { int flags, aclass; int ret; @@ -618,7 +650,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, skfield = NULL; if (!asn1_item_embed_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx, - depth)) { + depth, libctx, propq)) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); /* |skfield| may be partially allocated despite failure. */ ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); @@ -639,7 +671,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, /* IMPLICIT tagging */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, - ctx, depth); + ctx, depth, libctx, propq); if (!ret) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; @@ -648,7 +680,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } else { /* Nothing special */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, opt, ctx, depth); + -1, 0, opt, ctx, depth, libctx, propq); if (!ret) { ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index f3562251f2..4b624bbdd4 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -45,6 +45,13 @@ ASN1_VALUE *ASN1_item_new_ex(const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, /* Allocate an ASN1 structure */ + +int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return asn1_item_embed_new(pval, it, 0, libctx, propq); +} + int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { return asn1_item_embed_new(pval, it, 0, NULL, NULL); diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c index 60ad5b1e76..1cd867721e 100644 --- a/crypto/pkcs7/pk7_asn1.c +++ b/crypto/pkcs7/pk7_asn1.c @@ -66,8 +66,16 @@ ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) { PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; - ret = (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (PKCS7_it())); + if (a != NULL && *a != NULL) { + libctx = (*a)->ctx.libctx; + propq = (*a)->ctx.propq; + } + + ret = (PKCS7 *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, (PKCS7_it()), + libctx, propq); if (ret != NULL) ossl_pkcs7_resolve_libctx(ret); return ret; @@ -85,7 +93,8 @@ PKCS7 *PKCS7_new(void) PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { - PKCS7 *pkcs7 = PKCS7_new(); + PKCS7 *pkcs7 = (PKCS7 *)ASN1_item_new_ex(ASN1_ITEM_rptr(PKCS7), libctx, + propq); if (pkcs7 != NULL) { pkcs7->ctx.libctx = libctx; diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c index b446423384..49a0da5f81 100644 --- a/crypto/pkcs7/pk7_mime.c +++ b/crypto/pkcs7/pk7_mime.c @@ -49,9 +49,16 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7) { PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } ret = (PKCS7 *)SMIME_read_ASN1_ex(bio, 0, bcont, ASN1_ITEM_rptr(PKCS7), - (ASN1_VALUE **)p7); + (ASN1_VALUE **)p7, libctx, propq); if (ret != NULL) ossl_pkcs7_resolve_libctx(ret); return ret; diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index ba400d1103..92b659d009 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -182,8 +182,15 @@ int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl) PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) { PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; - ret = ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } + + ret = ASN1_item_d2i_fp_ex(ASN1_ITEM_rptr(PKCS7), fp, p7, libctx, propq); if (ret != NULL) ossl_pkcs7_resolve_libctx(ret); return ret; @@ -198,8 +205,16 @@ int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7) PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) { PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } + - ret = ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + ret = ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(PKCS7), bp, p7, libctx, propq); if (ret != NULL) ossl_pkcs7_resolve_libctx(ret); return ret; diff --git a/doc/man3/SMIME_read_ASN1.pod b/doc/man3/SMIME_read_ASN1.pod index 56d1e67dcd..a90d9a4004 100644 --- a/doc/man3/SMIME_read_ASN1.pod +++ b/doc/man3/SMIME_read_ASN1.pod @@ -10,7 +10,8 @@ SMIME_read_ASN1_ex, SMIME_read_ASN1 #include ASN1_VALUE *SMIME_read_ASN1_ex(BIO *in, int flags, BIO **bcont, - const ASN1_ITEM *it, ASN1_VALUE **x); + const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq); ASN1_VALUE *SMIME_read_ASN1(BIO *in, BIO **bcont, const ASN1_ITEM *it); =head1 DESCRIPTION @@ -25,7 +26,10 @@ to be followed by B and B characters, else only by an B character. I can be used to optionally supply a previously created I ASN1_VALUE object (such as CMS_ContentInfo or PKCS7), it can be set to NULL. Valid values that can be used by ASN.1 structure I -are ASN1_ITEM_rptr(PKCS7) or ASN1_ITEM_rptr(CMS_ContentInfo). +are ASN1_ITEM_rptr(PKCS7) or ASN1_ITEM_rptr(CMS_ContentInfo). Any algorithm +fetches that occur during the operation will use the B supplied in +the I parameter, and use the property query string I See +L for further details about algorithm fetching. If cleartext signing is used then the content is saved in a memory bio which is written to I<*bcont>, otherwise I<*bcont> is set to NULL. diff --git a/include/openssl/asn1.h.in b/include/openssl/asn1.h.in index c995693080..40b43a227a 100644 --- a/include/openssl/asn1.h.in +++ b/include/openssl/asn1.h.in @@ -762,6 +762,8 @@ void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); in, \ CHECKED_PPTR_OF(type, x))) +void *ASN1_item_d2i_fp_ex(const ASN1_ITEM *it, FILE *in, void *x, + OSSL_LIB_CTX *libctx, const char *propq); void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x); @@ -784,6 +786,8 @@ void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); in, \ CHECKED_PPTR_OF(type, x))) +void *ASN1_item_d2i_bio_ex(const ASN1_ITEM *it, BIO *in, void *pval, + OSSL_LIB_CTX *libctx, const char *propq); void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *pval); int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x); @@ -846,6 +850,9 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); ASN1_VALUE *ASN1_item_new_ex(const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, const char *propq); void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i_ex(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it); int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); @@ -921,8 +928,9 @@ int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, const char *propq); ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); -ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, const ASN1_ITEM *it, - ASN1_VALUE **x); +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, + const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq); int SMIME_crlf_copy(BIO *in, BIO *out, int flags); int SMIME_text(BIO *in, BIO *out); diff --git a/include/openssl/asn1t.h.in b/include/openssl/asn1t.h.in index 6314dc41cb..7e0e41a011 100644 --- a/include/openssl/asn1t.h.in +++ b/include/openssl/asn1t.h.in @@ -631,6 +631,10 @@ typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); +typedef int ASN1_ex_d2i_ex(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx, OSSL_LIB_CTX *libctx, + const char *propq); typedef int ASN1_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); @@ -660,6 +664,7 @@ typedef struct ASN1_EXTERN_FUNCS_st { ASN1_ex_i2d *asn1_ex_i2d; ASN1_ex_print_func *asn1_ex_print; ASN1_ex_new_ex_func *asn1_ex_new_ex; + ASN1_ex_d2i_ex *asn1_ex_d2i_ex; } ASN1_EXTERN_FUNCS; typedef struct ASN1_PRIMITIVE_FUNCS_st { diff --git a/util/libcrypto.num b/util/libcrypto.num index 0f011b71b3..5c36c4d44a 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5409,3 +5409,6 @@ NCONF_get0_libctx ? 3_0_0 EXIST::FUNCTION: NCONF_get_section_names ? 3_0_0 EXIST::FUNCTION: X509_PUBKEY_new_ex ? 3_0_0 EXIST::FUNCTION: ASN1_item_new_ex ? 3_0_0 EXIST::FUNCTION: +ASN1_item_d2i_fp_ex ? 3_0_0 EXIST::FUNCTION:STDIO +ASN1_item_d2i_bio_ex ? 3_0_0 EXIST::FUNCTION: +ASN1_item_d2i_ex ? 3_0_0 EXIST::FUNCTION: -- cgit v1.2.3