fix x509_PUBKEY propq so that it uses a copy
@@ -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);
