Give ASN.1 objects the ability to report their libctx/propq
authorMatt Caswell <matt@openssl.org>
Thu, 27 May 2021 09:56:02 +0000 (10:56 +0100)
committerPauli <pauli@openssl.org>
Sat, 5 Jun 2021 07:39:27 +0000 (17:39 +1000)
Some ASN.1 objects have an embedded libctx/propq. If they have one we
give the ASN.1 code the ability to find these values and use them where
needed. This is used for OSSL_CMP_MSG_dup() and X509_dup().

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/a_dup.c
crypto/cmp/cmp_asn.c
crypto/x509/x_x509.c
include/openssl/asn1t.h.in

index 2fa3ccd28a82e810f574accfdbb6f5e6fcf8550c..93e8b2aa8dab8a9a2ecd76ca5495385719be20d6 100644 (file)
@@ -56,6 +56,8 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
     const unsigned char *p;
     long i;
     ASN1_VALUE *ret;
+    OSSL_LIB_CTX *libctx = NULL;
+    const char *propq = NULL;
 
     if (x == NULL)
         return NULL;
@@ -67,9 +69,12 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
         asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
     }
 
-    if (asn1_cb != NULL
-        && !asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL))
-        goto auxerr;
+    if (asn1_cb != NULL) {
+        if (!asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL)
+                || !asn1_cb(ASN1_OP_GET0_LIBCTX, (ASN1_VALUE **)&x, it, &libctx)
+                || !asn1_cb(ASN1_OP_GET0_PROPQ, (ASN1_VALUE **)&x, it, &propq))
+            goto auxerr;
+    }
 
     i = ASN1_item_i2d(x, &b, it);
     if (b == NULL) {
@@ -77,7 +82,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
         return NULL;
     }
     p = b;
-    ret = ASN1_item_d2i(NULL, &p, i, it);
+    ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq);
     OPENSSL_free(b);
 
     if (asn1_cb != NULL
index 1d17f77bd6adc50808d9630e804ba63f1de3c8ff..31b67178d8c054c7de28c40245983300b6a6c57f 100644 (file)
@@ -211,21 +211,35 @@ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a)
 static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval,
                            const ASN1_ITEM *it, void *exarg)
 {
-    OSSL_CMP_MSG *ret = (OSSL_CMP_MSG *)*pval;
+    OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval;
 
     switch (operation) {
     case ASN1_OP_FREE_POST:
-        OPENSSL_free(ret->propq);
+        OPENSSL_free(msg->propq);
         break;
 
     case ASN1_OP_DUP_POST:
         {
             OSSL_CMP_MSG *old = exarg;
 
-            if (!ossl_cmp_msg_set0_libctx(ret, old->libctx, old->propq))
+            if (!ossl_cmp_msg_set0_libctx(msg, old->libctx, old->propq))
                 return 0;
         }
         break;
+    case ASN1_OP_GET0_LIBCTX:
+        {
+            OSSL_LIB_CTX **libctx = exarg;
+
+            *libctx = msg->libctx;
+        }
+        break;
+    case ASN1_OP_GET0_PROPQ:
+        {
+            const char **propq = exarg;
+
+            *propq = msg->propq;
+        }
+        break;
     default:
         break;
     }
index 6666058b4c1f269d58693f1aaede9707a323d437..260bfda6830d01ca2eb097f0da67cfcc9f8c5208 100644 (file)
@@ -123,6 +123,20 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
             }
         }
         break;
+    case ASN1_OP_GET0_LIBCTX:
+        {
+            OSSL_LIB_CTX **libctx = exarg;
+
+            *libctx = ret->libctx;
+        }
+        break;
+    case ASN1_OP_GET0_PROPQ:
+        {
+            const char **propq = exarg;
+
+            *propq = ret->propq;
+        }
+        break;
     default:
         break;
     }
index 7e0e41a011d5c3d58c7e3fcd14cad7de10a6b7a6..321f106e0362117e9d7690b2b85dba3e702a6f54 100644 (file)
@@ -756,6 +756,8 @@ typedef struct ASN1_STREAM_ARG_st {
 # define ASN1_OP_DETACHED_POST   13
 # define ASN1_OP_DUP_PRE         14
 # define ASN1_OP_DUP_POST        15
+# define ASN1_OP_GET0_LIBCTX     16
+# define ASN1_OP_GET0_PROPQ      17
 
 /* Macro to implement a primitive type */
 # define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)