embed support for ASN1_STRING
authorDr. Stephen Henson <steve@openssl.org>
Wed, 7 Oct 2015 12:28:46 +0000 (13:28 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 11 Oct 2015 19:33:57 +0000 (20:33 +0100)
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/asn1/asn1_lib.c
crypto/asn1/tasn_new.c
include/openssl/asn1.h

index 3b366449a924ad1ec02eee5a2f013ae8395a3536..12248dbf780a83231e064fadfd1222a0cb1d72e9 100644 (file)
@@ -363,7 +363,8 @@ void ASN1_STRING_free(ASN1_STRING *a)
         return;
     if (!(a->flags & ASN1_STRING_FLAG_NDEF))
         OPENSSL_free(a->data);
-    OPENSSL_free(a);
+    if (!(a->flags & ASN1_STRING_FLAG_EMBED))
+        OPENSSL_free(a);
 }
 
 void ASN1_STRING_clear_free(ASN1_STRING *a)
index 13db8676fc876e7a1085cc3fbc0cf72f5d414897..33a8e97442ec19684d7d030a28d2af41105f79c0 100644 (file)
@@ -67,7 +67,8 @@
 
 static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
                                int embed);
-static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed);
 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
@@ -120,12 +121,12 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
         if (it->templates) {
             if (!asn1_template_new(pval, it->templates))
                 goto memerr;
-        } else if (!asn1_primitive_new(pval, it))
+        } else if (!asn1_primitive_new(pval, it, embed))
             goto memerr;
         break;
 
     case ASN1_ITYPE_MSTRING:
-        if (!asn1_primitive_new(pval, it))
+        if (!asn1_primitive_new(pval, it, embed))
             goto memerr;
         break;
 
@@ -305,7 +306,8 @@ static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
  * all the old functions.
  */
 
-static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed)
 {
     ASN1_TYPE *typ;
     ASN1_STRING *str;
@@ -347,10 +349,16 @@ static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
         break;
 
     default:
-        str = ASN1_STRING_type_new(utype);
+        if (embed) {
+            str = *(ASN1_STRING **)pval;
+            memset(str, 0, sizeof(*str));
+            str->flags = ASN1_STRING_FLAG_EMBED;
+        } else {
+            str = ASN1_STRING_type_new(utype);
+            *pval = (ASN1_VALUE *)str;
+        }
         if (it->itype == ASN1_ITYPE_MSTRING && str)
             str->flags |= ASN1_STRING_FLAG_MSTRING;
-        *pval = (ASN1_VALUE *)str;
         break;
     }
     if (*pval)
index 2405bd68d1d0af84909c23b21bbe10f75ef376e3..076886974f630f32d3707f7422fba1da36d4043a 100644 (file)
@@ -179,6 +179,8 @@ DECLARE_STACK_OF(X509_ALGOR)
  * type.
  */
 # define ASN1_STRING_FLAG_MSTRING 0x040
+/* String is embedded and only content should be freed */
+# define ASN1_STRING_FLAG_EMBED 0x080
 /* This is the base type that holds just about everything :-) */
 struct asn1_string_st {
     int length;