fix x509_PUBKEY propq so that it uses a copy
authorShane Lontis <shane.lontis@oracle.com>
Wed, 2 Dec 2020 10:52:32 +0000 (20:52 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Thu, 3 Dec 2020 22:22:24 +0000 (08:22 +1000)
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12700)

crypto/x509/x_pubkey.c

index 9f5b5d3c3db571855f2aa2433b8eba3cef9cc4ee..f2caa0b834df6843aa9a20fb7ecad0c8b4ea567a 100644 (file)
@@ -32,11 +32,27 @@ struct X509_pubkey_st {
 
     /* extra data for the callback, used by d2i_PUBKEY_ex */
     OSSL_LIB_CTX *libctx;
-    const char *propq;
+    char *propq;
 };
 
 static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key);
 
+static int x509_pubkey_set0_libctx(X509_PUBKEY *x, OSSL_LIB_CTX *libctx,
+                                   const char *propq)
+{
+    if (x != NULL) {
+        x->libctx = libctx;
+        OPENSSL_free(x->propq);
+        x->propq = NULL;
+        if (propq != NULL) {
+            x->propq = OPENSSL_strdup(propq);
+            if (x->propq == NULL)
+                return 0;
+        }
+    }
+    return 1;
+}
+
 /* Minor tweak to operation: free up EVP_PKEY */
 static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                      void *exarg)
@@ -44,6 +60,7 @@ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
     X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
 
     if (operation == ASN1_OP_FREE_POST) {
+        OPENSSL_free(pubkey->propq);
         EVP_PKEY_free(pubkey->pkey);
     } else if (operation == ASN1_OP_D2I_POST) {
         /* Attempt to decode public key and cache in pubkey structure. */
@@ -60,6 +77,11 @@ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
             return 0;
         }
         ERR_pop_to_mark();
+    } else if (operation == ASN1_OP_DUP_POST) {
+        X509_PUBKEY *old = exarg;
+
+        if (!x509_pubkey_set0_libctx(pubkey, old->libctx, old->propq))
+            return 0;
     }
     return 1;
 }
@@ -257,8 +279,8 @@ EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
             ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
             return NULL;
         }
-        xpk2->libctx = libctx;
-        xpk2->propq = propq;
+        if (!x509_pubkey_set0_libctx(xpk2, libctx, propq))
+            goto end;
         pxpk = &xpk2;
     }
     xpk = d2i_X509_PUBKEY(pxpk, &q, length);