Commit a19ddb558b for openssl.org

commit a19ddb558b848d32d787da51d9be50351fe691e3
Author: Daniel Kubec <kubec@openssl.foundation>
Date:   Mon Sep 14 14:47:00 2026 +0200

    Deprecate X509_OBJECT_up_ref_count()

    Despite its name, X509_OBJECT_up_ref_count() does not reference count the
    X509_OBJECT itself. With X509_OBJECT being opaque there is nothing useful an
    application can do with it.

    Assisted-by: Claude:claude-fable-5-1

    Fixes #21121

    Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Merge-date: Fri Oct  2 08:09:09 2026
    Merged-from: https://github.com/openssl/openssl/pull/32823

diff --git a/CHANGES.md b/CHANGES.md
index 80a2067692..5015ab5378 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -33,6 +33,14 @@ OpenSSL 4.2

 ### Changes between 4.1 and 4.2 [xx XXX xxxx]

+ * `X509_OBJECT_up_ref_count()` has been deprecated. Despite its name,
+   X509_OBJECT_up_ref_count() does not reference count the X509_OBJECT itself.
+   With X509_OBJECT being opaque there is nothing useful an application can do
+   with it.
+   <!-- https://github.com/openssl/openssl/pull/32823 -->
+
+   *Daniel Kubec*
+
  * Changed the OpenSSL FIPS provider so that every algorithm advertised with
    `fips=yes` explicitly exposes the `fips-indicator` as a gettable context
    parameter and returns 1 for an approved operation.  The absence of an
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 5be50c2195..e166110c9b 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -427,6 +427,23 @@ static int obj_ht_foreach_certs(HT_VALUE *v, void *arg)
     return 1;
 }

+/*
+ * Increment the reference count of the object contained in |a|, if any.
+ * The X509_OBJECT itself is not reference counted.
+ */
+static int x509_object_up_ref_count(X509_OBJECT *a)
+{
+    switch (a->type) {
+    case X509_LU_NONE:
+        break;
+    case X509_LU_X509:
+        return X509_up_ref(a->data.x509);
+    case X509_LU_CRL:
+        return X509_CRL_up_ref(a->data.crl);
+    }
+    return 1;
+}
+
 /*
  * May be called with |ret| == NULL just for the side effect of
  * caching all certs matching the given subject DN in |ctx->store->objs|.
@@ -479,7 +496,7 @@ int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx, X509_LOOKUP_TY
     }

     if (ret != NULL) {
-        if (!X509_OBJECT_up_ref_count(tmp))
+        if (!x509_object_up_ref_count(tmp))
             return -1;
         ret->type = tmp->type;
         ret->data = tmp->data;
@@ -511,7 +528,7 @@ static int x509_store_add_obj(X509_STORE *store, X509_OBJECT *obj)
         return 0;
     }

-    if (!X509_OBJECT_up_ref_count(obj)) {
+    if (!x509_object_up_ref_count(obj)) {
         obj->type = X509_LU_NONE;
         X509_OBJECT_free(obj);
         return 0;
@@ -600,18 +617,12 @@ int X509_STORE_add_crl(X509_STORE *xs, X509_CRL *x)
     return 1;
 }

+#ifndef OPENSSL_NO_DEPRECATED_4_2
 int X509_OBJECT_up_ref_count(X509_OBJECT *a)
 {
-    switch (a->type) {
-    case X509_LU_NONE:
-        break;
-    case X509_LU_X509:
-        return X509_up_ref(a->data.x509);
-    case X509_LU_CRL:
-        return X509_CRL_up_ref(a->data.crl);
-    }
-    return 1;
+    return x509_object_up_ref_count(a);
 }
+#endif

 X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
 {
@@ -742,7 +753,7 @@ static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj)
     ret->type = obj->type;
     ret->data = obj->data;

-    if (!X509_OBJECT_up_ref_count(ret)) {
+    if (!x509_object_up_ref_count(ret)) {
         OPENSSL_free(ret);
         return NULL;
     }
diff --git a/doc/man7/ossl-guide-migration.pod b/doc/man7/ossl-guide-migration.pod
index 6bd27323ee..02f594e0ca 100644
--- a/doc/man7/ossl-guide-migration.pod
+++ b/doc/man7/ossl-guide-migration.pod
@@ -18,6 +18,23 @@ L<https://github.com/openssl/openssl/blob/master/CHANGES.md>.
 For an overview of some of the key concepts introduced since OpenSSL 3.0, see
 L<crypto(7)>.

+=head1 OPENSSL 4.2
+
+=head2 Main Changes from OpenSSL 4.1
+
+=head3 Deprecation of X509_OBJECT_up_ref_count()
+
+This function has been deprecated in OpenSSL 4.2.  Despite its name, it does
+not increment a reference count on the B<X509_OBJECT> itself, which is not
+reference counted, but on the certificate or CRL it contains, and it does not
+return that object.  Since B<X509_OBJECT> is opaque there is nothing useful an
+application can do with it; the library maintains the reference counts of the
+contained objects internally.
+
+Applications that need their own reference to the contained object should
+retrieve it with X509_OBJECT_get0_X509() or X509_OBJECT_get0_X509_CRL() and
+call L<X509_up_ref(3)> or X509_CRL_up_ref() on the result.
+
 =head1 OPENSSL 4.1

 =head2 Main Changes from OpenSSL 4.0
diff --git a/include/openssl/x509_vfy.h.in b/include/openssl/x509_vfy.h.in
index 1d20703a76..7d89857e52 100644
--- a/include/openssl/x509_vfy.h.in
+++ b/include/openssl/x509_vfy.h.in
@@ -414,7 +414,10 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
     const X509_NAME *name);
 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
     X509_OBJECT *x);
+#ifndef OPENSSL_NO_DEPRECATED_4_2
+OSSL_DEPRECATEDIN_4_2_FOR("use X509_up_ref() or X509_CRL_up_ref() on the contained object")
 int X509_OBJECT_up_ref_count(X509_OBJECT *a);
+#endif
 X509_OBJECT *X509_OBJECT_new(void);
 void X509_OBJECT_free(X509_OBJECT *a);
 X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index eebc52128d..25c24cd96d 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4963,7 +4963,7 @@ X509_STORE_CTX_set_depth                4960	4_0_0	EXIST::FUNCTION:
 X509_OBJECT_idx_by_subject              4961	4_0_0	EXIST::FUNCTION:
 X509_OBJECT_retrieve_by_subject         4962	4_0_0	EXIST::FUNCTION:
 X509_OBJECT_retrieve_match              4963	4_0_0	EXIST::FUNCTION:
-X509_OBJECT_up_ref_count                4964	4_0_0	EXIST::FUNCTION:
+X509_OBJECT_up_ref_count                4964	4_0_0	EXIST::FUNCTION:DEPRECATEDIN_4_2
 X509_OBJECT_new                         4965	4_0_0	EXIST::FUNCTION:
 X509_OBJECT_free                        4966	4_0_0	EXIST::FUNCTION:
 X509_OBJECT_get_type                    4967	4_0_0	EXIST::FUNCTION: