Teach the ASN.1 code how to create embedded objects with libctx/propq
authorMatt Caswell <matt@openssl.org>
Fri, 21 May 2021 16:25:05 +0000 (17:25 +0100)
committerPauli <pauli@openssl.org>
Sat, 5 Jun 2021 07:39:10 +0000 (17:39 +1000)
An ASN.1 object such as an X509 may have embedded objects in it such as
an X509_PUBKEY. If there is a libctx/propq in use then we need to make sure
we pass these down to the constructors of these embedded objects.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15591)

crypto/asn1/tasn_new.c
crypto/x509/x_pubkey.c
crypto/x509/x_x509.c
include/openssl/asn1.h.in
include/openssl/asn1t.h.in
util/libcrypto.num

index 2ac9ab3e034024e657a0a5857eb6007c0cea388d..f3562251f2e749813cd5761a9df62228dd35f6bd 100644 (file)
 #include "asn1_local.h"
 
 static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-                               int embed);
+                               int embed, OSSL_LIB_CTX *libctx,
+                               const char *propq);
 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 int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                             OSSL_LIB_CTX *libctx, const char *propq);
 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
@@ -32,14 +34,24 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
     return NULL;
 }
 
+ASN1_VALUE *ASN1_item_new_ex(const ASN1_ITEM *it, OSSL_LIB_CTX *libctx,
+                             const char *propq)
+{
+    ASN1_VALUE *ret = NULL;
+    if (asn1_item_embed_new(&ret, it, 0, libctx, propq) > 0)
+        return ret;
+    return NULL;
+}
+
 /* Allocate an ASN1 structure */
 
 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
-    return asn1_item_embed_new(pval, it, 0);
+    return asn1_item_embed_new(pval, it, 0, NULL, NULL);
 }
 
-int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed,
+                        OSSL_LIB_CTX *libctx, const char *propq)
 {
     const ASN1_TEMPLATE *tt = NULL;
     const ASN1_EXTERN_FUNCS *ef;
@@ -56,15 +68,20 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
 
     case ASN1_ITYPE_EXTERN:
         ef = it->funcs;
-        if (ef && ef->asn1_ex_new) {
-            if (!ef->asn1_ex_new(pval, it))
-                goto memerr;
+        if (ef != NULL) {
+            if (ef->asn1_ex_new_ex != NULL) {
+                if (!ef->asn1_ex_new_ex(pval, it, libctx, propq))
+                    goto memerr;
+            } else if (ef->asn1_ex_new != NULL) {
+                if (!ef->asn1_ex_new(pval, it))
+                    goto memerr;
+            }
         }
         break;
 
     case ASN1_ITYPE_PRIMITIVE:
         if (it->templates) {
-            if (!asn1_template_new(pval, it->templates))
+            if (!asn1_template_new(pval, it->templates, libctx, propq))
                 goto memerr;
         } else if (!asn1_primitive_new(pval, it, embed))
             goto memerr;
@@ -124,7 +141,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
         ossl_asn1_enc_init(pval, it);
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             pseqval = ossl_asn1_get_field_ptr(pval, tt);
-            if (!asn1_template_new(pseqval, tt))
+            if (!asn1_template_new(pseqval, tt, libctx, propq))
                 goto memerr2;
         }
         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
@@ -180,7 +197,8 @@ 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 int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                             OSSL_LIB_CTX *libctx, const char *propq)
 {
     const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
     int embed = tt->flags & ASN1_TFLG_EMBED;
@@ -214,7 +232,7 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
         goto done;
     }
     /* Otherwise pass it back to the item routine */
-    ret = asn1_item_embed_new(pval, it, embed);
+    ret = asn1_item_embed_new(pval, it, embed, libctx, propq);
  done:
     return ret;
 }
index 502caaa9a8944db923ac8f537aba26a8d1fc30ad..d83e5c59e027545e54f85972e18a490f2ef51490 100644 (file)
@@ -71,6 +71,7 @@ static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     X509_ALGOR_free(pubkey->algor);
     ASN1_BIT_STRING_free(pubkey->public_key);
     EVP_PKEY_free(pubkey->pkey);
+    OPENSSL_free(pubkey->propq);
     OPENSSL_free(pubkey);
     *pval = NULL;
 }
@@ -85,12 +86,15 @@ static int x509_pubkey_ex_populate(ASN1_VALUE **pval, const ASN1_ITEM *it)
             || (pubkey->public_key = ASN1_BIT_STRING_new()) != NULL);
 }
 
-static int x509_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+
+static int x509_pubkey_ex_new_ex(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                 OSSL_LIB_CTX *libctx, const char *propq)
 {
     X509_PUBKEY *ret;
 
     if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL
-        || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL)) {
+        || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL)
+        || !x509_pubkey_set0_libctx(ret, libctx, propq)) {
         x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL);
         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
     } else {
@@ -110,7 +114,7 @@ static int x509_pubkey_ex_d2i(ASN1_VALUE **pval,
     int ret;
     OSSL_DECODER_CTX *dctx = NULL;
 
-    if (*pval == NULL && !x509_pubkey_ex_new(pval, it))
+    if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, NULL, NULL))
         return 0;
     if (!x509_pubkey_ex_populate(pval, NULL)) {
         ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
@@ -190,12 +194,13 @@ static int x509_pubkey_ex_print(BIO *out, const ASN1_VALUE **pval, int indent,
 
 static const ASN1_EXTERN_FUNCS x509_pubkey_ff = {
     NULL,
-    x509_pubkey_ex_new,
+    NULL,
     x509_pubkey_ex_free,
     0,                          /* Default clear behaviour is OK */
     x509_pubkey_ex_d2i,
     x509_pubkey_ex_i2d,
-    x509_pubkey_ex_print
+    x509_pubkey_ex_print,
+    x509_pubkey_ex_new_ex,
 };
 
 IMPLEMENT_EXTERN_ASN1(X509_PUBKEY, V_ASN1_SEQUENCE, x509_pubkey_ff)
@@ -205,7 +210,7 @@ X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
 {
     X509_PUBKEY *pubkey = NULL;
 
-    pubkey = (X509_PUBKEY *)ASN1_item_new((X509_PUBKEY_it()));
+    pubkey = (X509_PUBKEY *)ASN1_item_new_ex(X509_PUBKEY_it(), libctx, propq);
     if (!x509_pubkey_set0_libctx(pubkey, libctx, propq)) {
         X509_PUBKEY_free(pubkey);
         pubkey = NULL;
index 7959ee223f73dba0a14aaaf8d4f07d659c86de6e..a45b89cbeb97b760755b852afe4a33d9bf51c7ef 100644 (file)
@@ -169,7 +169,7 @@ X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
 {
     X509 *cert = NULL;
 
-    cert = (X509 *)ASN1_item_new((X509_it()));
+    cert = (X509 *)ASN1_item_new_ex(X509_it(), libctx, propq);
     if (!ossl_x509_set0_libctx(cert, libctx, propq)) {
         X509_free(cert);
         cert = NULL;
index e2b2b25cf391a3e3563250aca80591f7bc6afd4e..c995693080a86ee04a6c01d3e0ecc26bd8a41e35 100644 (file)
@@ -843,6 +843,8 @@ void ASN1_STRING_TABLE_cleanup(void);
 
 /* Old API compatible functions */
 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+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(ASN1_VALUE **val, const unsigned char **in,
                           long len, const ASN1_ITEM *it);
index 2f40d1ca159794d3296ba83956031d6d37db3133..6314dc41cb926aae62268c601c2a0b66b51d5e3c 100644 (file)
@@ -634,6 +634,8 @@ typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
 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);
+typedef int ASN1_ex_new_ex_func(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                OSSL_LIB_CTX *libctx, const char *propq);
 typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 typedef int ASN1_ex_print_func(BIO *out, const ASN1_VALUE **pval,
@@ -657,6 +659,7 @@ typedef struct ASN1_EXTERN_FUNCS_st {
     ASN1_ex_d2i *asn1_ex_d2i;
     ASN1_ex_i2d *asn1_ex_i2d;
     ASN1_ex_print_func *asn1_ex_print;
+    ASN1_ex_new_ex_func *asn1_ex_new_ex;
 } ASN1_EXTERN_FUNCS;
 
 typedef struct ASN1_PRIMITIVE_FUNCS_st {
index 42211e4caa9c9a5ec14b5fc5fa00271729a7eea1..0f011b71b3e39e1f6eedc0ccd2f1e541068b789b 100644 (file)
@@ -5408,3 +5408,4 @@ i2b_PVK_bio_ex                          ? 3_0_0   EXIST::FUNCTION:
 NCONF_get0_libctx                       ?      3_0_0   EXIST::FUNCTION:
 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: