]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix compilation with OpenSSL 4
authorDaniel Gustafsson <dgustafsson@postgresql.org>
Fri, 12 Jun 2026 11:57:22 +0000 (13:57 +0200)
committerDaniel Gustafsson <dgustafsson@postgresql.org>
Fri, 12 Jun 2026 11:57:22 +0000 (13:57 +0200)
OpenSSL 4.0.0 changed some parameters and returnvalues to const, so
we need to update our declarations and subsequently cast away const-
ness from a few callsites to make libpq build without warnings. This
is tested with OpenSSL 1.1.1 through 4.0.0 as well as with LibreSSL.
No functional change is introduced, this commit only allows postgres
to be compiled against OpenSSL 4.0.0 without warnings.

There is also an errormessage change in OpenSSL 4.0.0 which needed
to be covered by our testharness.

This will be backpatched to all supported branches since they are
all equally likely to be built against OpenSSL 4.0.0 as it becomes
available in distributions.  Backpatching will be done once it has
been in master for a few days without issues.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/066B07BB-85FA-487C-BE8C-40F791CFC3C4@yesql.se
Backpatch-through: 14

contrib/sslinfo/sslinfo.c
src/backend/libpq/be-secure-openssl.c
src/interfaces/libpq/fe-secure-openssl.c
src/test/ssl/t/001_ssltests.pl

index 30cae0bb985ee46ea79ce7c9e53aadd5c6e96aef..4f8a118bc918a0680b107c60e611f01443421aee 100644 (file)
@@ -21,8 +21,8 @@
 
 PG_MODULE_MAGIC;
 
-static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
-static Datum ASN1_STRING_to_text(ASN1_STRING *str);
+static Datum X509_NAME_field_to_text(const X509_NAME *name, text *fieldName);
+static Datum ASN1_STRING_to_text(const ASN1_STRING *str);
 
 /*
  * Function context for data persisting over repeated calls.
@@ -145,7 +145,7 @@ ssl_client_serial(PG_FUNCTION_ARGS)
  * function.
  */
 static Datum
-ASN1_STRING_to_text(ASN1_STRING *str)
+ASN1_STRING_to_text(const ASN1_STRING *str)
 {
        BIO                *membuf;
        size_t          size;
@@ -160,7 +160,7 @@ ASN1_STRING_to_text(ASN1_STRING *str)
                                (errcode(ERRCODE_OUT_OF_MEMORY),
                                 errmsg("could not create OpenSSL BIO structure")));
        (void) BIO_set_close(membuf, BIO_CLOSE);
-       ASN1_STRING_print_ex(membuf, str,
+       ASN1_STRING_print_ex(membuf, unconstify(ASN1_STRING *, str),
                                                 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
                                                  | ASN1_STRFLGS_UTF8_CONVERT));
        /* ensure null termination of the BIO's content */
@@ -191,12 +191,12 @@ ASN1_STRING_to_text(ASN1_STRING *str)
  * part of name
  */
 static Datum
-X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
+X509_NAME_field_to_text(const X509_NAME *name, text *fieldName)
 {
        char       *string_fieldname;
        int                     nid,
                                index;
-       ASN1_STRING *data;
+       const ASN1_STRING *data;
 
        string_fieldname = text_to_cstring(fieldName);
        nid = OBJ_txt2nid(string_fieldname);
@@ -206,10 +206,10 @@ X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
                                 errmsg("invalid X.509 field name: \"%s\"",
                                                string_fieldname)));
        pfree(string_fieldname);
-       index = X509_NAME_get_index_by_NID(name, nid, -1);
+       index = X509_NAME_get_index_by_NID(unconstify(X509_NAME *, name), nid, -1);
        if (index < 0)
                return (Datum) 0;
-       data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, index));
+       data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(unconstify(X509_NAME *, name), index));
        return ASN1_STRING_to_text(data);
 }
 
@@ -418,8 +418,8 @@ ssl_extension_info(PG_FUNCTION_ARGS)
                HeapTuple       tuple;
                Datum           result;
                BIO                *membuf;
-               X509_EXTENSION *ext;
-               ASN1_OBJECT *obj;
+               const X509_EXTENSION *ext;
+               const ASN1_OBJECT *obj;
                int                     nid;
                int                     len;
 
@@ -432,7 +432,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 
                /* Get the extension from the certificate */
                ext = X509_get_ext(cert, call_cntr);
-               obj = X509_EXTENSION_get_object(ext);
+               obj = X509_EXTENSION_get_object(unconstify(X509_EXTENSION *, ext));
 
                /* Get the extension name */
                nid = OBJ_obj2nid(obj);
@@ -445,7 +445,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
                nulls[0] = false;
 
                /* Get the extension value */
-               if (X509V3_EXT_print(membuf, ext, 0, 0) <= 0)
+               if (X509V3_EXT_print(membuf, unconstify(X509_EXTENSION *, ext), 0, 0) <= 0)
                        ereport(ERROR,
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("could not print extension value in certificate at position %d",
index 8df8ed3c90ae425b5c47a8711ffba1295c85bd36..8fa4963ceddc8ff91c801b926de42979d6116487 100644 (file)
@@ -64,7 +64,7 @@ static bool initialize_dh(SSL_CTX *context, bool isServerStart);
 static bool initialize_ecdh(SSL_CTX *context, bool isServerStart);
 static const char *SSLerrmessage(unsigned long ecode);
 
-static char *X509_NAME_to_cstring(X509_NAME *name);
+static char *X509_NAME_to_cstring(const X509_NAME *name);
 
 static SSL_CTX *SSL_context = NULL;
 static bool SSL_initialized = false;
@@ -580,18 +580,18 @@ aloop:
        if (port->peer != NULL)
        {
                int                     len;
-               X509_NAME  *x509name = X509_get_subject_name(port->peer);
+               const X509_NAME *x509name = X509_get_subject_name(port->peer);
                char       *peer_dn;
                BIO                *bio = NULL;
                BUF_MEM    *bio_buf = NULL;
 
-               len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0);
+               len = X509_NAME_get_text_by_NID(unconstify(X509_NAME *, x509name), NID_commonName, NULL, 0);
                if (len != -1)
                {
                        char       *peer_cn;
 
                        peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
-                       r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn,
+                       r = X509_NAME_get_text_by_NID(unconstify(X509_NAME *, x509name), NID_commonName, peer_cn,
                                                                                  len + 1);
                        peer_cn[len] = '\0';
                        if (r != len)
@@ -632,7 +632,7 @@ aloop:
                 * which make regular expression matching a bit easier. Also note that
                 * it prints the Subject fields in reverse order.
                 */
-               X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253);
+               X509_NAME_print_ex(bio, unconstify(X509_NAME *, x509name), 0, XN_FLAG_RFC2253);
                if (BIO_get_mem_ptr(bio, &bio_buf) <= 0)
                {
                        BIO_free(bio);
@@ -1406,14 +1406,14 @@ be_tls_get_certificate_hash(Port *port, size_t *len)
  *
  */
 static char *
-X509_NAME_to_cstring(X509_NAME *name)
+X509_NAME_to_cstring(const X509_NAME *name)
 {
        BIO                *membuf = BIO_new(BIO_s_mem());
        int                     i,
                                nid,
-                               count = X509_NAME_entry_count(name);
-       X509_NAME_ENTRY *e;
-       ASN1_STRING *v;
+                               count = X509_NAME_entry_count(unconstify(X509_NAME *, name));
+       const X509_NAME_ENTRY *e;
+       const ASN1_STRING *v;
        const char *field_name;
        size_t          size;
        char            nullterm;
@@ -1429,13 +1429,13 @@ X509_NAME_to_cstring(X509_NAME *name)
        (void) BIO_set_close(membuf, BIO_CLOSE);
        for (i = 0; i < count; i++)
        {
-               e = X509_NAME_get_entry(name, i);
-               nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
+               e = X509_NAME_get_entry(unconstify(X509_NAME *, name), i);
+               nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(unconstify(X509_NAME_ENTRY *, e)));
                if (nid == NID_undef)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                         errmsg("could not get NID for ASN1_OBJECT object")));
-               v = X509_NAME_ENTRY_get_data(e);
+               v = X509_NAME_ENTRY_get_data(unconstify(X509_NAME_ENTRY *, e));
                field_name = OBJ_nid2sn(nid);
                if (field_name == NULL)
                        field_name = OBJ_nid2ln(nid);
@@ -1444,7 +1444,7 @@ X509_NAME_to_cstring(X509_NAME *name)
                                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                         errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
                BIO_printf(membuf, "/%s=", field_name);
-               ASN1_STRING_print_ex(membuf, v,
+               ASN1_STRING_print_ex(membuf, unconstify(ASN1_STRING *, v),
                                                         ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
                                                          | ASN1_STRFLGS_UTF8_CONVERT));
        }
index 5f340494b7f46c6373b7d041d7db49b4e8bb1961..915a23cf20acca30859cdd2ae51f4ee08731c803 100644 (file)
@@ -64,7 +64,7 @@
 
 static int     verify_cb(int ok, X509_STORE_CTX *ctx);
 static int     openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
-                                                                                                                         ASN1_STRING *name,
+                                                                                                                         const ASN1_STRING *name,
                                                                                                                          char **store_name);
 static void destroy_ssl_system(void);
 static int     initialize_SSL(PGconn *conn);
@@ -481,7 +481,8 @@ verify_cb(int ok, X509_STORE_CTX *ctx)
  * into a plain C string.
  */
 static int
-openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
+openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
+                                                                                                 const ASN1_STRING *name_entry,
                                                                                                  char **store_name)
 {
        int                     len;
@@ -501,7 +502,7 @@ openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *nam
 #ifdef HAVE_ASN1_STRING_GET0_DATA
        namedata = ASN1_STRING_get0_data(name_entry);
 #else
-       namedata = ASN1_STRING_data(name_entry);
+       namedata = ASN1_STRING_data(unconstify(ASN1_STRING *, name_entry));
 #endif
        len = ASN1_STRING_length(name_entry);
 
@@ -570,20 +571,20 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
         */
        if (*names_examined == 0)
        {
-               X509_NAME  *subject_name;
+               const X509_NAME *subject_name;
 
                subject_name = X509_get_subject_name(conn->peer);
                if (subject_name != NULL)
                {
                        int                     cn_index;
 
-                       cn_index = X509_NAME_get_index_by_NID(subject_name,
+                       cn_index = X509_NAME_get_index_by_NID(unconstify(X509_NAME *, subject_name),
                                                                                                  NID_commonName, -1);
                        if (cn_index >= 0)
                        {
                                (*names_examined)++;
                                rc = openssl_verify_peer_name_matches_certificate_name(conn,
-                                                                                                                                          X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
+                                                                                                                                          X509_NAME_ENTRY_get_data(X509_NAME_get_entry(unconstify(X509_NAME *, subject_name), cn_index)),
                                                                                                                                           first_name);
                        }
                }
index cc7bd98c83c99e59cdf157b88627fe011549992a..f6b20186f1f01ff9e7903a0693651bfe2b779c5e 100644 (file)
@@ -538,7 +538,7 @@ $node->connect_fails(
 $node->connect_fails(
        "$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked_tmp.key",
        "certificate authorization fails with revoked client cert",
-       expected_stderr => qr|SSL error: ssl[a-z0-9/]* alert certificate revoked|,
+       expected_stderr => qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!,
        # revoked certificates should not authenticate the user
        log_unlike => [qr/connection authenticated:/],);
 
@@ -591,7 +591,7 @@ switch_server_cert($node, 'server-cn-only', undef, undef,
 $node->connect_fails(
        "$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked_tmp.key",
        "certificate authorization fails with revoked client cert with server-side CRL directory",
-       expected_stderr => qr|SSL error: ssl[a-z0-9/]* alert certificate revoked|);
+       expected_stderr => qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!);
 
 # clean up
 foreach my $key (@keys)