ASN.1: extend the possibilities to embed data instead of pointers
authorRichard Levitte <levitte@openssl.org>
Wed, 12 Apr 2017 09:48:12 +0000 (11:48 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 13 Apr 2017 08:23:31 +0000 (10:23 +0200)
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)

crypto/asn1/tasn_fre.c
crypto/asn1/tasn_new.c
include/openssl/asn1t.h

index 3c98efb..ae91461 100644 (file)
@@ -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;
         }
index e9b8377..f695e38 100644 (file)
@@ -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)
index a73d4a8..537ee2e 100644 (file)
@@ -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) \