#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;
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;
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
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);
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;
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);
* 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;
}
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;
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;
}
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 */
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);
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,
* 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;
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);
}
/*
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;
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);
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:
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;
}
/*
* 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;
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;
}
*/
ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx,
- depth);
+ depth, libctx, propq);
if (!ret) {
errtt = seqtt;
goto err;
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;
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;
}
}
} 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;
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;
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));
/* 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;
} 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;
/* 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);
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;
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;
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;
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;
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;
#include <openssl/asn1.h>
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
I<x> can be used to optionally supply
a previously created I<it> 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<it>
-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<OSSL_LIB_CTX> supplied in
+the I<libctx> parameter, and use the property query string I<propq> See
+L<crypto(7)/ALGORITHM FETCHING> 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.
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);
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);
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);
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);
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);
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 {
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: