summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2017-04-12 11:48:12 +0200
committerRichard Levitte <levitte@openssl.org>2017-04-13 10:23:31 +0200
commit49005bb8b3e134d5c8c5c8fc87aecb74d1437286 (patch)
treecc82c8245ba3381b01c4b2bb7b94bd9cd0ae5a8c
parent8edefd7bb323f84abfbc381e4ba13c02925673b9 (diff)
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 <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3199)
-rw-r--r--crypto/asn1/tasn_fre.c7
-rw-r--r--crypto/asn1/tasn_new.c8
-rw-r--r--include/openssl/asn1t.h5
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) \