Commit 96a1334659 for openssl.org
commit 96a13346596da18a8c005b110e648e9451647f58
Author: Richard Levitte <levitte@openssl.foundation>
Date: Sat Nov 7 09:54:31 2026 +0100
Make CRYPTO_new_ex_data_ex() public
Provider modules that carry their own copy of an algorithm's core
create objects whose ex_data must be constructed against the
provider's library context. So far, the libctx-aware constructor
has been internal to libcrypto; a separately linked module needing
it would have to statically duplicate libcrypto's libctx / ex_data /
thread machinery, ending up with split copies of the library-context
lifecycle.
The name drops the OSSL_ prefix that promoted ossl_ functions
usually get, following the existing CRYPTO_new_ex_data() family.
Assisted-by: Pi:moonshotai/kimi-k3
Signed-off-by: Richard Levitte <levitte@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Tue Nov 10 14:29:35 2026
Merged-from: https://github.com/openssl/openssl/pull/33591
diff --git a/CHANGES.md b/CHANGES.md
index 09ffde8bca..712f17e8bd 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -33,6 +33,11 @@ OpenSSL 4.2
### Changes between 4.1 and 4.2 [xx XXX xxxx]
+ * Added `CRYPTO_new_ex_data_ex()`, an `OSSL_LIB_CTX`-aware variant of
+ `CRYPTO_new_ex_data()`.
+
+ *Richard Levitte*
+
* Deprecated `SSL_copy_session_id()` and `BIO_ssl_copy_session_id()`.
Use `SSL_set_session()` to resume a session on a new connection, or
`SSL_dup()` to copy an SSL object.
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index 5936b84098..49e81b2073 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -144,7 +144,7 @@ static DSA *dsa_new_intern(OSSL_LIB_CTX *libctx)
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
#ifndef FIPS_MODULE
- if (!ossl_crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret,
+ if (!CRYPTO_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret,
&ret->ex_data))
goto err;
#endif
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index cd443bd4b9..80f0e3769a 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -215,7 +215,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
* in the lock, then using them outside the lock. Note this only applies
* to the global "ex_data" state (ie. class definitions), not 'ad' itself.
*/
-int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
+int CRYPTO_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
CRYPTO_EX_DATA *ad)
{
int mx, i;
@@ -262,7 +262,7 @@ int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
{
- return ossl_crypto_new_ex_data_ex(NULL, class_index, obj, ad);
+ return CRYPTO_new_ex_data_ex(NULL, class_index, obj, ad);
}
/*
diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod
index b0c68cbd5c..a94e57ea83 100644
--- a/doc/man3/CRYPTO_get_ex_new_index.pod
+++ b/doc/man3/CRYPTO_get_ex_new_index.pod
@@ -5,7 +5,7 @@
CRYPTO_EX_new, CRYPTO_EX_free, CRYPTO_EX_dup,
CRYPTO_free_ex_index, CRYPTO_get_ex_new_index,
CRYPTO_alloc_ex_data, CRYPTO_set_ex_data, CRYPTO_get_ex_data,
-CRYPTO_free_ex_data, CRYPTO_new_ex_data
+CRYPTO_free_ex_data, CRYPTO_new_ex_data, CRYPTO_new_ex_data_ex
- functions supporting application-specific data
=head1 SYNOPSIS
@@ -26,6 +26,8 @@ CRYPTO_free_ex_data, CRYPTO_new_ex_data
void **from_d, int idx, long argl, void *argp);
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+ int CRYPTO_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
+ CRYPTO_EX_DATA *ad);
int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
int idx);
@@ -70,8 +72,10 @@ structures. Since the application data can be anything at all it is passed
and retrieved as a B<void *> type.
The B<CRYPTO_EX_DATA> type is opaque. To initialize the exdata part of
-a structure, call CRYPTO_new_ex_data(). This is only necessary for
-B<CRYPTO_EX_INDEX_APP> objects.
+a structure, call CRYPTO_new_ex_data_ex() with the library context I<ctx>.
+This is only necessary for B<CRYPTO_EX_INDEX_APP> objects.
+CRYPTO_new_ex_data() does the same with I<ctx> set to NULL, i.e. the
+default library context.
Exdata types are identified by an B<index>, an integer guaranteed to be
unique within structures for the lifetime of the program. Applications
@@ -160,6 +164,8 @@ dup_func() should return 0 for failure and 1 for success.
=head1 HISTORY
+CRYPTO_new_ex_data_ex() was added in OpenSSL 4.2.
+
CRYPTO_alloc_ex_data() was added in OpenSSL 3.0.
The signature of the dup_func() callback was changed in OpenSSL 3.0 to use the
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index f09d4dddc1..82ea21c5d5 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -137,8 +137,6 @@ OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx);
const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx);
-int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
- CRYPTO_EX_DATA *ad);
int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index,
long argl, void *argp,
CRYPTO_EX_new *new_func,
diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in
index a9ade25b15..fc23da0761 100644
--- a/include/openssl/crypto.h.in
+++ b/include/openssl/crypto.h.in
@@ -268,6 +268,13 @@ int CRYPTO_free_ex_index(int class_index, int idx);
* given class (invokes whatever per-class callbacks are applicable)
*/
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/**
+ * @brief Initialize the exdata part of a structure, associated with the
+ * given library context.
+ * @see CRYPTO_new_ex_data_ex(3)
+ */
+int CRYPTO_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
+ CRYPTO_EX_DATA *ad);
int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
const CRYPTO_EX_DATA *from);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index c20bf4717d..f51053c5c7 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5749,3 +5749,4 @@ PKCS12_PARSE_CTX_set_ca ? 4_2_0 EXIST::FUNCTION:
PKCS12_PARSE_CTX_set_skeys ? 4_2_0 EXIST::FUNCTION:
PKCS12_parse_ex ? 4_2_0 EXIST::FUNCTION:
PKCS12_check_version ? 4_2_0 EXIST::FUNCTION:
+CRYPTO_new_ex_data_ex ? 4_2_0 EXIST::FUNCTION: