From 49005bb8b3e134d5c8c5c8fc87aecb74d1437286 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 12 Apr 2017 11:48:12 +0200 Subject: [PATCH] ASN.1: extend the possibilities to embed data instead of pointers Also, when "allocating" or "deallocating" an embedded item, never call prim_new() or prim_free(). Call prim_clear() instead. Fixes #3191 Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/3199) --- crypto/asn1/tasn_fre.c | 7 ++++++- crypto/asn1/tasn_new.c | 8 +++++++- include/openssl/asn1t.h | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c index 3c98efb363..ae91461774 100644 --- a/crypto/asn1/tasn_fre.c +++ b/crypto/asn1/tasn_fre.c @@ -155,7 +155,12 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (it) { const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; - if (pf && pf->prim_free) { + if (embed) { + if (pf && pf->prim_clear) { + pf->prim_clear(pval, it); + return; + } + } else if (pf && pf->prim_free) { pf->prim_free(pval, it); return; } diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index e9b83773f1..f695e38da0 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -266,8 +266,14 @@ static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, if (it->funcs) { const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; - if (pf->prim_new) + if (embed) { + if (pf->prim_clear) { + pf->prim_clear(pval, it); + return 1; + } + } else if (pf->prim_new) { return pf->prim_new(pval, it); + } } if (it->itype == ASN1_ITYPE_MSTRING) diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h index a73d4a8e65..537ee2e519 100644 --- a/include/openssl/asn1t.h +++ b/include/openssl/asn1t.h @@ -346,17 +346,22 @@ extern "C" { /* OPTIONAL simple type */ # define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) +# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type) /* IMPLICIT tagged simple type */ # define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) +# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) /* IMPLICIT tagged OPTIONAL simple type */ # define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) /* Same as above but EXPLICIT */ # define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) # define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) /* SEQUENCE OF type */ # define ASN1_SEQUENCE_OF(stname, field, type) \ -- 2.25.1