diff options
author | Matt Caswell <matt@openssl.org> | 2021-05-25 17:16:18 +0100 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-06-05 17:39:10 +1000 |
commit | dea2878fac8bde549fa0dd3b8e895703b174391b (patch) | |
tree | 8e0b77927b65d77397e6294086b2aabe5b851e7f /crypto/asn1 | |
parent | c8a9af97c928118ae4626d793d0b73552648b7ea (diff) |
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 <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15591)
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/a_d2i_fp.c | 20 | ||||
-rw-r--r-- | crypto/asn1/asn1_local.h | 3 | ||||
-rw-r--r-- | crypto/asn1/asn_mime.c | 16 | ||||
-rw-r--r-- | crypto/asn1/tasn_dec.c | 100 | ||||
-rw-r--r-- | crypto/asn1/tasn_new.c | 7 |
5 files changed, 101 insertions, 45 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); |