]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Make X509_up_ref and X509_free take const X509 *
authorBob Beck <beck@openssl.org>
Mon, 2 Mar 2026 18:46:39 +0000 (11:46 -0700)
committerTomas Mraz <tomas@openssl.org>
Wed, 4 Mar 2026 16:43:26 +0000 (17:43 +0100)
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Wed Mar  4 16:43:39 2026
(Merged from https://github.com/openssl/openssl/pull/30235)

crypto/x509/x509_set.c
crypto/x509/x_x509.c
doc/man3/X509_new.pod
doc/man7/ossl-guide-migration.pod
include/openssl/asn1t.h.in
include/openssl/safestack.h.in
include/openssl/x509.h.in
util/libcrypto.num
util/perl/OpenSSL/stackhash.pm

index cd196ff4caa3de59424963025df5a1b1e0153cd9..3551fb65144abf1923e570a863461c4453dec5e8 100644 (file)
@@ -113,11 +113,11 @@ int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
     return 1;
 }
 
-int X509_up_ref(X509 *x)
+int X509_up_ref(const X509 *x)
 {
     int i;
 
-    if (CRYPTO_UP_REF(&x->references, &i) <= 0)
+    if (CRYPTO_UP_REF(&((X509 *)x)->references, &i) <= 0)
         return 0;
 
     REF_PRINT_COUNT("X509", i, x);
index 08435a4517446f12feb44327fdf3d7e7e456a204..701937b4c67a645c365afd6afc1cf8c4bf077595 100644 (file)
@@ -129,7 +129,7 @@ ASN1_SEQUENCE_ref(X509, x509_cb) = {
     ASN1_EMBED(X509, signature, ASN1_BIT_STRING)
 } ASN1_SEQUENCE_END_ref(X509, X509)
 
-IMPLEMENT_ASN1_FUNCTIONS(X509)
+IMPLEMENT_ASN1_FUNCTIONS_CONSTFREE(X509)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509)
 
 /*
index 264767e83414daad0baf39c62a0216417dfa0af1..d8dd1179cc190d9eeae1dd4b85efdd331bdaae92 100644 (file)
@@ -14,8 +14,8 @@ OSSL_STACK_OF_X509_free
 
  X509 *X509_new(void);
  X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
- void X509_free(X509 *a);
- int X509_up_ref(X509 *a);
+ void X509_free(const X509 *a);
+ int X509_up_ref(const X509 *a);
  STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *x);
  void OSSL_STACK_OF_X509_free(STACK_OF(X509) *certs);
 
index 37d5d4c187bec3ad59e072300bad129cc7de8f17..8fc148f9be8eb5bd9422e7cbaaaf121ed036324b 100644 (file)
@@ -169,6 +169,8 @@ X509_to_X509_REQ
 X509_TRUST_add
 X509v3_addr_validate_resource_set
 X509v3_asid_validate_resource_set
+X509_up_ref
+X509_free
 
 The following two functions we "un-constified" As they were documented as returning
 an explicitly mutable pointer from within an B<X509> object:
index ca8bbc2517daf3af7088e86149a99f597377ebf9..aff58e0577b0313e862a2db2ac81d1053c801d1b 100644 (file)
@@ -775,6 +775,8 @@ typedef struct ASN1_STREAM_ARG_st {
 
 #define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
 
+#define IMPLEMENT_ASN1_FUNCTIONS_CONSTFREE(stname) IMPLEMENT_ASN1_FUNCTIONS_fname_constfree(stname, stname, stname)
+
 #define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
 
 #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
@@ -806,10 +808,24 @@ typedef struct ASN1_STREAM_ARG_st {
         ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname));    \
     }
 
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname_constfree(stname, itname, fname) \
+    stname *fname##_new(void)                                                 \
+    {                                                                         \
+        return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname));               \
+    }                                                                         \
+    void fname##_free(const stname *a)                                        \
+    {                                                                         \
+        ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname));              \
+    }
+
 #define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname)    \
     IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
     IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
 
+#define IMPLEMENT_ASN1_FUNCTIONS_fname_constfree(stname, itname, fname) \
+    IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname)        \
+    IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname_constfree(stname, itname, fname)
+
 #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname)                       \
     stname *d2i_##fname(stname **a, const unsigned char **in, long len)                    \
     {                                                                                      \
index 42c3ec95ff5af865fdd48649f6876d0cb4043986..f81dd5888895702899db930b804459d00818c04a 100644 (file)
@@ -35,50 +35,6 @@ extern "C" {
 
 #define STACK_OF(type) struct stack_st_##type
 
-/* Helper macro for internal use */
-#define SKM_DEFINE_STACK_OF_INTERNAL(t1, t2, t3)                                                                         \
-    STACK_OF(t1);                                                                                                        \
-    typedef int (*sk_##t1##_compfunc)(const t3 *const *a, const t3 *const *b);                                           \
-    typedef void (*sk_##t1##_freefunc)(t3 * a);                                                                          \
-    typedef t3 *(*sk_##t1##_copyfunc)(const t3 *a);                                                                      \
-    static ossl_inline void sk_##t1##_freefunc_thunk(OPENSSL_sk_freefunc freefunc_arg, void *ptr)                        \
-    {                                                                                                                    \
-        sk_##t1##_freefunc freefunc = (sk_##t1##_freefunc)freefunc_arg;                                                  \
-        freefunc((t3 *)ptr);                                                                                             \
-    }                                                                                                                    \
-    static ossl_inline int sk_##t1##_cmpfunc_thunk(int (*cmp)(const void *, const void *), const void *a, const void *b) \
-    {                                                                                                                    \
-        int (*realcmp)(const t3 *const *a, const t3 *const *b) = (int (*)(const t3 *const *a, const t3 *const *b))(cmp); \
-        const t3 *const *at = (const t3 *const *)a;                                                                      \
-        const t3 *const *bt = (const t3 *const *)b;                                                                      \
-                                                                                                                         \
-        return realcmp(at, bt);                                                                                          \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline t2 *ossl_check_##t1##_type(t2 *ptr)                                                   \
-    {                                                                                                                    \
-        return ptr;                                                                                                      \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline const OPENSSL_STACK *ossl_check_const_##t1##_sk_type(const STACK_OF(t1) *sk)          \
-    {                                                                                                                    \
-        return (const OPENSSL_STACK *)sk;                                                                                \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline OPENSSL_STACK *ossl_check_##t1##_sk_type(STACK_OF(t1) *sk)                            \
-    {                                                                                                                    \
-        return (OPENSSL_STACK *)sk;                                                                                      \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline OPENSSL_sk_compfunc ossl_check_##t1##_compfunc_type(sk_##t1##_compfunc cmp)           \
-    {                                                                                                                    \
-        return (OPENSSL_sk_compfunc)cmp;                                                                                 \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline OPENSSL_sk_copyfunc ossl_check_##t1##_copyfunc_type(sk_##t1##_copyfunc cpy)           \
-    {                                                                                                                    \
-        return (OPENSSL_sk_copyfunc)cpy;                                                                                 \
-    }                                                                                                                    \
-    static ossl_unused ossl_inline OPENSSL_sk_freefunc ossl_check_##t1##_freefunc_type(sk_##t1##_freefunc fr)            \
-    {                                                                                                                    \
-        return (OPENSSL_sk_freefunc)fr;                                                                                  \
-    }
-
 #define SKM_DEFINE_STACK_OF(t1, t2, t3)                                                                                    \
     STACK_OF(t1);                                                                                                          \
     typedef int (*sk_##t1##_compfunc)(const t3 *const *a, const t3 *const *b);                                             \
index b5a104a3aa5dcd89c334acac550c6db12e0ea246..84d65269cc847ab9a07ef67827e842228943e8f3 100644 (file)
@@ -571,7 +571,11 @@ DECLARE_ASN1_FUNCTIONS(X509_NAME)
 int X509_NAME_set(X509_NAME **xn, const X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(X509_CINF)
-DECLARE_ASN1_FUNCTIONS(X509)
+X509 *X509_new(void);
+void X509_free(const X509 *a);
+X509 *d2i_X509(X509 **a, const unsigned char **in, long len);
+int i2d_X509(const X509 *a, unsigned char **out);
+const ASN1_ITEM *X509_it(void);
 X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
 DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
 
@@ -672,7 +676,7 @@ int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm);
 const ASN1_TIME *X509_get0_notAfter(const X509 *x);
 ASN1_TIME *X509_getm_notAfter(X509 *x);
 int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm);
-int X509_up_ref(X509 *x);
+int X509_up_ref(const X509 *x);
 int X509_get_signature_type(const X509 *x);
 
 #ifndef OPENSSL_NO_DEPRECATED_1_1_0
index 6b83d53b620acd2e03b5178e3f2f7d71bc2ed09b..b694a335c5b7a5e004b669a2cbe4afa1ed115129 100644 (file)
@@ -4495,11 +4495,6 @@ i2d_X509_CINF                           ?        4_0_0   EXIST::FUNCTION:
 X509_CINF_free                          ?      4_0_0   EXIST::FUNCTION:
 X509_CINF_new                           ?      4_0_0   EXIST::FUNCTION:
 X509_CINF_it                            ?      4_0_0   EXIST::FUNCTION:
-d2i_X509                                ?      4_0_0   EXIST::FUNCTION:
-i2d_X509                                ?      4_0_0   EXIST::FUNCTION:
-X509_free                               ?      4_0_0   EXIST::FUNCTION:
-X509_new                                ?      4_0_0   EXIST::FUNCTION:
-X509_it                                 ?      4_0_0   EXIST::FUNCTION:
 X509_new_ex                             ?      4_0_0   EXIST::FUNCTION:
 d2i_X509_CERT_AUX                       ?      4_0_0   EXIST::FUNCTION:
 i2d_X509_CERT_AUX                       ?      4_0_0   EXIST::FUNCTION:
@@ -5714,3 +5709,8 @@ OSSL_ENCODER_CTX_ctrl_string            ? 4_0_0   EXIST::FUNCTION:
 OPENSSL_sk_set_cmp_thunks               ?      4_0_0   EXIST::FUNCTION:
 ASN1_BIT_STRING_set1                    ?      4_0_0   EXIST::FUNCTION:
 OSSL_ESS_check_signing_certs_ex         ?      4_0_0   EXIST::FUNCTION:
+X509_new                                ?      4_0_0   EXIST::FUNCTION:
+X509_free                               ?      4_0_0   EXIST::FUNCTION:
+d2i_X509                                ?      4_0_0   EXIST::FUNCTION:
+i2d_X509                                ?      4_0_0   EXIST::FUNCTION:
+X509_it                                 ?      4_0_0   EXIST::FUNCTION:
index 0c7c1297057a76860eaa1affdeda6c44fc6aa0f7..9ef5a338af51aaa9b6a165a24a51550e69b503e4 100644 (file)
@@ -10,7 +10,6 @@ package OpenSSL::stackhash;
 
 use strict;
 use warnings;
-
 require Exporter;
 our @ISA = qw(Exporter);
 our @EXPORT_OK = qw(generate_stack_macros generate_const_stack_macros
@@ -23,9 +22,51 @@ sub generate_stack_macros_int {
     my $nametype = shift;
     my $realtype = shift;
     my $plaintype = shift;
-
+    my $const_free = "";
+    if ($nametype eq "X509") {
+       $const_free = "const ";
+    }
     my $macros = <<END_MACROS;
-SKM_DEFINE_STACK_OF_INTERNAL(${nametype}, ${realtype}, ${plaintype})
+STACK_OF(${nametype});
+typedef int (*sk_${nametype}_compfunc)(const ${plaintype} *const *a, const ${plaintype} *const *b);
+typedef void (*sk_${nametype}_freefunc)(${const_free}${plaintype} *a);
+typedef ${plaintype} *(*sk_${nametype}_copyfunc)(const ${plaintype} *a);
+static ossl_inline void sk_${nametype}_freefunc_thunk(OPENSSL_sk_freefunc freefunc_arg, void *ptr)
+{
+    sk_${nametype}_freefunc freefunc = (sk_${nametype}_freefunc)freefunc_arg;
+    freefunc((${const_free}${plaintype} *)ptr);
+}
+static ossl_inline int sk_${nametype}_cmpfunc_thunk(int (*cmp)(const void *, const void *), const void *a, const void *b)
+{
+    int (*realcmp)(const ${plaintype} *const *a, const ${plaintype} *const *b) = (int (*)(const ${plaintype} *const *a, const ${plaintype} *const *b))(cmp);
+    const ${plaintype} *const *at = (const ${plaintype} *const *)a;
+    const ${plaintype} *const *bt = (const ${plaintype} *const *)b;
+    return realcmp(at, bt);
+}
+static ossl_unused ossl_inline ${realtype} *ossl_check_${nametype}_type(${realtype} *ptr)
+{
+    return ptr;
+}
+static ossl_unused ossl_inline const OPENSSL_STACK *ossl_check_const_${nametype}_sk_type(const STACK_OF(${nametype}) *sk)
+{
+    return (const OPENSSL_STACK *)sk;
+}
+static ossl_unused ossl_inline OPENSSL_STACK *ossl_check_${nametype}_sk_type(STACK_OF(${nametype}) *sk)
+{
+    return (OPENSSL_STACK *)sk;
+}
+static ossl_unused ossl_inline OPENSSL_sk_compfunc ossl_check_${nametype}_compfunc_type(sk_${nametype}_compfunc cmp)
+{
+    return (OPENSSL_sk_compfunc)cmp;
+}
+static ossl_unused ossl_inline OPENSSL_sk_copyfunc ossl_check_${nametype}_copyfunc_type(sk_${nametype}_copyfunc cpy)
+{
+    return (OPENSSL_sk_copyfunc)cpy;
+}
+static ossl_unused ossl_inline OPENSSL_sk_freefunc ossl_check_${nametype}_freefunc_type(sk_${nametype}_freefunc fr)
+{
+    return (OPENSSL_sk_freefunc)fr;
+}
 #define sk_${nametype}_num(sk) OPENSSL_sk_num(ossl_check_const_${nametype}_sk_type(sk))
 #define sk_${nametype}_value(sk, idx) ((${realtype} *)OPENSSL_sk_value(ossl_check_const_${nametype}_sk_type(sk), (idx)))
 #define sk_${nametype}_new(cmp) ((STACK_OF(${nametype}) *)OPENSSL_sk_set_cmp_thunks(OPENSSL_sk_new(ossl_check_${nametype}_compfunc_type(cmp)), sk_${nametype}_cmpfunc_thunk))