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: