Hi,
Here is an initial set of patches related to OpenSSL 1.1. Everything
should still build fine on older OpenSSL versions (and did when I tested
with 1.0.2h).
0001-Fixes-for-compiling-with-OpenSSL-1.1.patch
This patch fixes the code so it builds with OpenSSL 1.1 (except the
CRYPTO_LOCK issue I have reported to the OpenSSL team).
- Makes our configure script check for SSL_new instead
- Uses functions instead of direct access to struct members
0002-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat.patch
Fix for the removal of the CRYPTO_LOCK define. I am trying to convince
them to add the define back. :)
0003-Remove-OpenSSL-1.1-deprecation-warnings.patch
Silence all warnings. This commit changes more things and is not
necessary for getting PostgreSQL to build against 1.1.
- Silences deprecation other warnings related to that OpenSSL 1.1 now
1) automatically initializes the library and 2) no longer uses the
locking callback.
- Silences deprecation warning when generating DH parameters.
Andreas
>From 16bda89ea853d7ee160e049a300771b967f966ff Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andr...@proxel.se>
Date: Tue, 28 Jun 2016 05:55:03 +0200
Subject: [PATCH 1/3] Fixes for compiling with OpenSSL 1.1
---
configure | 44 ++++++++++++++++----------------
configure.in | 4 +--
src/backend/libpq/be-secure-openssl.c | 39 +++++++++++++++++++---------
src/interfaces/libpq/fe-secure-openssl.c | 39 +++++++++++++++++++---------
4 files changed, 78 insertions(+), 48 deletions(-)
diff --git a/configure b/configure
index 1f42c8a..ca83738 100755
--- a/configure
+++ b/configure
@@ -9538,9 +9538,9 @@ else
as_fn_error $? "library 'crypto' is required for OpenSSL" "$LINENO" 5
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_library_init in -lssl" >&5
-$as_echo_n "checking for SSL_library_init in -lssl... " >&6; }
-if ${ac_cv_lib_ssl_SSL_library_init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5
+$as_echo_n "checking for SSL_new in -lssl... " >&6; }
+if ${ac_cv_lib_ssl_SSL_new+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -9554,27 +9554,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char SSL_library_init ();
+char SSL_new ();
int
main ()
{
-return SSL_library_init ();
+return SSL_new ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ssl_SSL_library_init=yes
+ ac_cv_lib_ssl_SSL_new=yes
else
- ac_cv_lib_ssl_SSL_library_init=no
+ ac_cv_lib_ssl_SSL_new=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_library_init" >&5
-$as_echo "$ac_cv_lib_ssl_SSL_library_init" >&6; }
-if test "x$ac_cv_lib_ssl_SSL_library_init" = xyes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5
+$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; }
+if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBSSL 1
_ACEOF
@@ -9644,9 +9644,9 @@ else
as_fn_error $? "library 'eay32' or 'crypto' is required for OpenSSL" "$LINENO" 5
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5
-$as_echo_n "checking for library containing SSL_library_init... " >&6; }
-if ${ac_cv_search_SSL_library_init+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_new" >&5
+$as_echo_n "checking for library containing SSL_new... " >&6; }
+if ${ac_cv_search_SSL_new+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
@@ -9659,11 +9659,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char SSL_library_init ();
+char SSL_new ();
int
main ()
{
-return SSL_library_init ();
+return SSL_new ();
;
return 0;
}
@@ -9676,25 +9676,25 @@ for ac_lib in '' ssleay32 ssl; do
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_SSL_library_init=$ac_res
+ ac_cv_search_SSL_new=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
- if ${ac_cv_search_SSL_library_init+:} false; then :
+ if ${ac_cv_search_SSL_new+:} false; then :
break
fi
done
-if ${ac_cv_search_SSL_library_init+:} false; then :
+if ${ac_cv_search_SSL_new+:} false; then :
else
- ac_cv_search_SSL_library_init=no
+ ac_cv_search_SSL_new=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_library_init" >&5
-$as_echo "$ac_cv_search_SSL_library_init" >&6; }
-ac_res=$ac_cv_search_SSL_library_init
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_new" >&5
+$as_echo "$ac_cv_search_SSL_new" >&6; }
+ac_res=$ac_cv_search_SSL_new
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
diff --git a/configure.in b/configure.in
index c07904e..34bc5ab 100644
--- a/configure.in
+++ b/configure.in
@@ -1112,10 +1112,10 @@ if test "$with_openssl" = yes ; then
dnl Order matters!
if test "$PORTNAME" != "win32"; then
AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
- AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
+ AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
else
AC_SEARCH_LIBS(CRYPTO_new_ex_data, eay32 crypto, [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])])
- AC_SEARCH_LIBS(SSL_library_init, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
+ AC_SEARCH_LIBS(SSL_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
fi
AC_CHECK_FUNCS([SSL_get_current_compression])
fi
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index f6adb15..2fa2793 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -673,8 +673,12 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
* to retry; do we need to adopt their logic for that?
*/
-static bool my_bio_initialized = false;
-static BIO_METHOD my_bio_methods;
+#if SSLEAY_VERSION_NUMBER < 0x10100000L
+#define BIO_get_data(bio) (bio->ptr)
+#define BIO_set_data(bio, data) (bio->ptr = data)
+#endif
+
+static BIO_METHOD *my_bio_methods = NULL;
static int
my_sock_read(BIO *h, char *buf, int size)
@@ -683,7 +687,7 @@ my_sock_read(BIO *h, char *buf, int size)
if (buf != NULL)
{
- res = secure_raw_read(((Port *) h->ptr), buf, size);
+ res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
BIO_clear_retry_flags(h);
if (res <= 0)
{
@@ -703,7 +707,7 @@ my_sock_write(BIO *h, const char *buf, int size)
{
int res = 0;
- res = secure_raw_write(((Port *) h->ptr), buf, size);
+ res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
BIO_clear_retry_flags(h);
if (res <= 0)
{
@@ -720,14 +724,26 @@ my_sock_write(BIO *h, const char *buf, int size)
static BIO_METHOD *
my_BIO_s_socket(void)
{
- if (!my_bio_initialized)
+ if (!my_bio_methods)
{
- memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
- my_bio_methods.bread = my_sock_read;
- my_bio_methods.bwrite = my_sock_write;
- my_bio_initialized = true;
+ BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
+#if SSLEAY_VERSION_NUMBER >= 0x10100000L
+ my_bio_methods = BIO_meth_new(BIO_TYPE_SOCKET, "pgsocket");
+ BIO_meth_set_write(my_bio_methods, my_sock_write);
+ BIO_meth_set_read(my_bio_methods, my_sock_read);
+ BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom));
+ BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom));
+ BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom));
+ BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom));
+ BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom));
+#else
+ my_bio_methods = malloc(sizeof(BIO_METHOD));
+ memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
+ my_bio_methods->bread = my_sock_read;
+ my_bio_methods->bwrite = my_sock_write;
+#endif
}
- return &my_bio_methods;
+ return my_bio_methods;
}
/* This should exactly match openssl's SSL_set_fd except for using my BIO */
@@ -744,8 +760,7 @@ my_SSL_set_fd(Port *port, int fd)
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
goto err;
}
- /* Use 'ptr' to store pointer to PGconn */
- bio->ptr = port;
+ BIO_set_data(bio, port);
BIO_set_fd(bio, fd, BIO_NOCLOSE);
SSL_set_bio(port->ssl, bio, bio);
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index f6ce1c7..520dcd7 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1621,15 +1621,19 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
* to retry; do we need to adopt their logic for that?
*/
-static bool my_bio_initialized = false;
-static BIO_METHOD my_bio_methods;
+#if SSLEAY_VERSION_NUMBER < 0x10100000L
+#define BIO_get_data(bio) (bio->ptr)
+#define BIO_set_data(bio, data) (bio->ptr = data)
+#endif
+
+static BIO_METHOD *my_bio_methods;
static int
my_sock_read(BIO *h, char *buf, int size)
{
int res;
- res = pqsecure_raw_read((PGconn *) h->ptr, buf, size);
+ res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res < 0)
{
@@ -1659,7 +1663,7 @@ my_sock_write(BIO *h, const char *buf, int size)
{
int res;
- res = pqsecure_raw_write((PGconn *) h->ptr, buf, size);
+ res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res <= 0)
{
@@ -1687,14 +1691,26 @@ my_sock_write(BIO *h, const char *buf, int size)
static BIO_METHOD *
my_BIO_s_socket(void)
{
- if (!my_bio_initialized)
+ if (!my_bio_methods)
{
- memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
- my_bio_methods.bread = my_sock_read;
- my_bio_methods.bwrite = my_sock_write;
- my_bio_initialized = true;
+ BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
+#if SSLEAY_VERSION_NUMBER >= 0x10100000L
+ my_bio_methods = BIO_meth_new(BIO_TYPE_SOCKET, "pgsocket");
+ BIO_meth_set_write(my_bio_methods, my_sock_write);
+ BIO_meth_set_read(my_bio_methods, my_sock_read);
+ BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom));
+ BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom));
+ BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom));
+ BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom));
+ BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom));
+#else
+ my_bio_methods = malloc(sizeof(BIO_METHOD));
+ memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
+ my_bio_methods->bread = my_sock_read;
+ my_bio_methods->bwrite = my_sock_write;
+#endif
}
- return &my_bio_methods;
+ return my_bio_methods;
}
/* This should exactly match openssl's SSL_set_fd except for using my BIO */
@@ -1710,8 +1726,7 @@ my_SSL_set_fd(PGconn *conn, int fd)
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
goto err;
}
- /* Use 'ptr' to store pointer to PGconn */
- bio->ptr = conn;
+ BIO_set_data(bio, conn);
SSL_set_bio(conn->ssl, bio, bio);
BIO_set_fd(bio, fd, BIO_NOCLOSE);
--
2.8.1
>From 19755a1d04b8d31f98fc68226986bacda7651d0a Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andr...@proxel.se>
Date: Tue, 28 Jun 2016 05:58:50 +0200
Subject: [PATCH 2/3] Define CRYPTO_LOCK for OpenSSL 1.1 compat
---
src/interfaces/libpq/fe-secure-openssl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 520dcd7..56bc279 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -736,6 +736,11 @@ verify_peer_name_matches_certificate(PGconn *conn)
* Callback functions for OpenSSL internal locking
*/
+/* OpenSSL 1.1 no longer defines CRYPTO_LOCK */
+#ifndef CRYPTO_LOCK
+#define CRYPTO_LOCK 1
+#endif
+
static unsigned long
pq_threadidcallback(void)
{
--
2.8.1
>From 7de207025b11dacb9ec5f4946b31b332b85eef1f Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andr...@proxel.se>
Date: Tue, 28 Jun 2016 07:51:49 +0200
Subject: [PATCH 3/3] Remove OpenSSL 1.1 deprecation warnings
---
src/backend/libpq/be-secure-openssl.c | 23 ++++++++++++++++++++++-
src/interfaces/libpq/fe-secure-openssl.c | 15 +++++++--------
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 2fa2793..926dbf2 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -166,11 +166,13 @@ be_tls_init(void)
if (!SSL_context)
{
+#if SSLEAY_VERSION_NUMBER < 0x10100000L
#if SSLEAY_VERSION_NUMBER >= 0x0907000L
OPENSSL_config(NULL);
#endif
SSL_library_init();
SSL_load_error_strings();
+#endif
/*
* We use SSLv23_method() because it can negotiate use of the highest
@@ -854,6 +856,25 @@ load_dh_buffer(const char *buffer, size_t len)
return dh;
}
+static DH *
+generate_dh_params(int prime_len, int generator)
+{
+#if SSLEAY_VERSION_NUMBER >= 0x00908000L
+ DH *dh;
+
+ if ((dh = DH_new()) == NULL)
+ return NULL;
+
+ if (DH_generate_parameters_ex(dh, prime_len, generator, NULL))
+ return dh;
+
+ DH_free(dh);
+ return NULL;
+#else
+ return DH_generate_parameters(prime_len, generator, NULL, NULL);
+#endif
+}
+
/*
* Generate an ephemeral DH key. Because this can take a long
* time to compute, we can use precomputed parameters of the
@@ -923,7 +944,7 @@ tmp_dh_cb(SSL *s, int is_export, int keylength)
ereport(DEBUG2,
(errmsg_internal("DH: generating parameters (%d bits)",
keylength)));
- r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
+ r = generate_dh_params(keylength, DH_GENERATOR_2);
}
return r;
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 56bc279..aa80284 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -731,16 +731,11 @@ verify_peer_name_matches_certificate(PGconn *conn)
return found_match && !got_error;
}
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && SSLEAY_VERSION_NUMBER < 0x10100000L
/*
* Callback functions for OpenSSL internal locking
*/
-/* OpenSSL 1.1 no longer defines CRYPTO_LOCK */
-#ifndef CRYPTO_LOCK
-#define CRYPTO_LOCK 1
-#endif
-
static unsigned long
pq_threadidcallback(void)
{
@@ -768,7 +763,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
PGTHREAD_ERROR("failed to unlock mutex");
}
}
-#endif /* ENABLE_THREAD_SAFETY */
+#endif /* ENABLE_THREAD_SAFETY && && SSLEAY_VERSION_NUMBER < 0x10100000L */
/*
* Initialize SSL system, in particular creating the SSL_context object
@@ -807,6 +802,7 @@ pgtls_init(PGconn *conn)
if (pthread_mutex_lock(&ssl_config_mutex))
return -1;
+#if SSLEAY_VERSION_NUMBER < 0x10100000L
if (pq_init_crypto_lib)
{
/*
@@ -847,10 +843,12 @@ pgtls_init(PGconn *conn)
CRYPTO_set_locking_callback(pq_lockingcallback);
}
}
+#endif
#endif /* ENABLE_THREAD_SAFETY */
if (!SSL_context)
{
+#if SSLEAY_VERSION_NUMBER < 0x10100000L
if (pq_init_ssl_lib)
{
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
@@ -859,6 +857,7 @@ pgtls_init(PGconn *conn)
SSL_library_init();
SSL_load_error_strings();
}
+#endif
/*
* We use SSLv23_method() because it can negotiate use of the highest
@@ -911,7 +910,7 @@ pgtls_init(PGconn *conn)
static void
destroy_ssl_system(void)
{
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && SSLEAY_VERSION_NUMBER < 0x10100000L
/* Mutex is created in initialize_ssl_system() */
if (pthread_mutex_lock(&ssl_config_mutex))
return;
--
2.8.1
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers