OpenSSL 1.1 breaks configure and more

Started by Christoph Bergover 9 years ago57 messages
#1Christoph Berg
myon@debian.org

Hi,

as reported by Debian's OpenSSL maintainers, PostgreSQL is failing to
build against a snapshot of the upcoming 1.1.0 version. The report was
for 9.5.3, but I can reproduce it in HEAD as well:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=828510

OpenSSL 1.1.0 is about to released. During a rebuild of all packages using
OpenSSL this package fail to build. A log of that build can be found at:
https://breakpoint.cc/openssl-1.1-rebuild-2016-05-29/Attempted/postgresql-9.5_9.5.3-1_amd64-20160529-1510

On https://wiki.openssl.org/index.php/1.1_API_Changes you can see various of the
reasons why it might fail. There are also updated man pages at
https://www.openssl.org/docs/manmaster/ that should contain useful information.

There is a libssl-dev package available in experimental that contains a recent
snapshot, I suggest you try building against that to see if everything works.

$ ./configure --with-openssl
checking for CRYPTO_new_ex_data in -lcrypto... yes
checking for SSL_library_init in -lssl... no
configure: error: library 'ssl' is required for OpenSSL

I can get one step further by tweaking configure.in and running
autoreconf, but then compilation fails further down:

-      AC_CHECK_LIB(ssl,    SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
+      AC_CHECK_LIB([ssl],  [SSL_library_init])

make -C common all
make[4]: Verzeichnis „/home/cbe/projects/postgresql/pg/master/src/backend/access/common“ wird betreten
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -I../../../../src/include -D_GNU_SOURCE -c -o printtup.o printtup.c
In file included from ../../../../src/include/libpq/libpq-be.h:25:0,
from ../../../../src/include/libpq/libpq.h:21,
from printtup.c:19:
/usr/include/openssl/ssl.h:1740:26: error: expected identifier or ‘(’ before numeric constant
__owur const COMP_METHOD *SSL_get_current_compression(SSL *s);
^

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christoph Berg (#1)
Re: OpenSSL 1.1 breaks configure and more

Christoph Berg <myon@debian.org> writes:

as reported by Debian's OpenSSL maintainers, PostgreSQL is failing to
build against a snapshot of the upcoming 1.1.0 version.

The errors you report make it sound like they broke API compatibility
wholesale. Was that really their intent? If so, where are the changes
documented?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Andreas Karlsson
andreas@proxel.se
In reply to: Tom Lane (#2)
Re: OpenSSL 1.1 breaks configure and more

On 06/27/2016 05:24 PM, Tom Lane wrote:

Christoph Berg <myon@debian.org> writes:

as reported by Debian's OpenSSL maintainers, PostgreSQL is failing to
build against a snapshot of the upcoming 1.1.0 version.

The errors you report make it sound like they broke API compatibility
wholesale. Was that really their intent? If so, where are the changes
documented?

I do not see that they have documented the removal of the
SSL_library_init symbol anywhere. They changed the function into a macro
in the following commit. I guess we have to check for some other symbol,
like SSL_new.

https://github.com/openssl/openssl/commit/7fa792d14d06cdaca18f225b1d2d8daf8ed24fd7

They have also, which is in the release notes, broken API compatibility
when they made the BIO and BIO_METHOD structs opaque. This will probably
require some ugly ugly #ifs or compatibility macros from us.

They also seem to have broken our OpenSSL thread safety callback when
they added their new threading API and removed the CRYPTO_LOCK define. I
have reported this in their issue tracker
(https://github.com/openssl/openssl/issues/1260).

In addition to this there are a couple of deprecated functions
(DH_generate_parameters() and OPENSSL_config()), but they look pretty
easy to handle.

I think much of the above is missing from the release notes I have
found. I hope they will be more complete at the time of the release. I
am working on a patch to handle these API changes.

- https://www.openssl.org/news/openssl-1.1.0-notes.html
- https://wiki.openssl.org/index.php/1.1_API_Changes

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Christoph Berg
myon@debian.org
In reply to: Andreas Karlsson (#3)
Re: OpenSSL 1.1 breaks configure and more

Re: Andreas Karlsson 2016-06-27 <8a0a5959-0b83-3dc8-d9e7-66ce8c1c5bc7@proxel.se>

The errors you report make it sound like they broke API compatibility
wholesale. Was that really their intent? If so, where are the changes
documented?

I do not see that they have documented the removal of the SSL_library_init
symbol anywhere. They changed the function into a macro in the following
commit. I guess we have to check for some other symbol, like SSL_new.

I'm not an autoconf expert, but as said in the original mail, I could
get the SSL_library_init check to work, even if that's a macro now:

-      AC_CHECK_LIB(ssl,    SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
+      AC_CHECK_LIB([ssl],  [SSL_library_init])

(I haven't investigated if that's due to the quoting, the removal of
the extra arguments, or simply because I reran autoreconf.)

I think much of the above is missing from the release notes I have found. I
hope they will be more complete at the time of the release. I am working on
a patch to handle these API changes.

- https://www.openssl.org/news/openssl-1.1.0-notes.html
- https://wiki.openssl.org/index.php/1.1_API_Changes

Nod, I was also disappointed when browsing the API changes document,
given it didn't mention any of the problems I was seeing.

Christoph

#5Andreas Karlsson
andreas@proxel.se
In reply to: Christoph Berg (#4)
Re: OpenSSL 1.1 breaks configure and more

On 06/27/2016 08:12 PM, Christoph Berg wrote:

Re: Andreas Karlsson 2016-06-27 <8a0a5959-0b83-3dc8-d9e7-66ce8c1c5bc7@proxel.se>

The errors you report make it sound like they broke API compatibility
wholesale. Was that really their intent? If so, where are the changes
documented?

I do not see that they have documented the removal of the SSL_library_init
symbol anywhere. They changed the function into a macro in the following
commit. I guess we have to check for some other symbol, like SSL_new.

I'm not an autoconf expert, but as said in the original mail, I could
get the SSL_library_init check to work, even if that's a macro now:

Yes, we could do that, but I do not think we should check for the
existence of a backwards compatibility macro. Actually I think we may
want to skip much of the OpenSSL initialization code when compiling
against OpenSSL 1.1 since they have now added automatic initialization
of the library. Instead I think we should check for something we
actually will use like SSL_CTX_new().

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Michael Paquier
michael.paquier@gmail.com
In reply to: Andreas Karlsson (#5)
Re: OpenSSL 1.1 breaks configure and more

On Tue, Jun 28, 2016 at 3:21 AM, Andreas Karlsson <andreas@proxel.se> wrote:

Yes, we could do that, but I do not think we should check for the existence
of a backwards compatibility macro. Actually I think we may want to skip
much of the OpenSSL initialization code when compiling against OpenSSL 1.1
since they have now added automatic initialization of the library. Instead I
think we should check for something we actually will use like SSL_CTX_new().

Agreed. Changing the routine being checked may be a good idea in this
case, and we surely want to check for something that is used in the
frontend and the backend. So why not something more generic like
SSL_read or SSL_write?
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Andreas Karlsson
andreas@proxel.se
In reply to: Andreas Karlsson (#3)
3 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

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

Attachments:

0001-Fixes-for-compiling-with-OpenSSL-1.1.patchtext/x-patch; name=0001-Fixes-for-compiling-with-OpenSSL-1.1.patchDownload
From 16bda89ea853d7ee160e049a300771b967f966ff Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@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

0002-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat.patchtext/x-patch; name=0002-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat.patchDownload
From 19755a1d04b8d31f98fc68226986bacda7651d0a Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@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

0003-Remove-OpenSSL-1.1-deprecation-warnings.patchtext/x-patch; name=0003-Remove-OpenSSL-1.1-deprecation-warnings.patchDownload
From 7de207025b11dacb9ec5f4946b31b332b85eef1f Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@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

#8Michael Paquier
michael.paquier@gmail.com
In reply to: Andreas Karlsson (#7)
Re: OpenSSL 1.1 breaks configure and more

On Fri, Jul 1, 2016 at 9:27 AM, Andreas Karlsson <andreas@proxel.se> wrote:

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.

Those patches are going to need a careful review by looking at the
areas they are changing, and a backpatch. On Arch there is no test
package available except in AUR. And that's the pre3 release, OpenSSL
folks are on pre5 now with their beta2. It would be annoying to
compile it manually, but if there is no other way... Is Debian up to
date with 1.1.0 beta2 in its snapshot packages?
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Magnus Hagander
magnus@hagander.net
In reply to: Michael Paquier (#8)
Re: OpenSSL 1.1 breaks configure and more

On Fri, Jul 1, 2016 at 4:08 AM, Michael Paquier <michael.paquier@gmail.com>
wrote:

On Fri, Jul 1, 2016 at 9:27 AM, Andreas Karlsson <andreas@proxel.se>
wrote:

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.

Those patches are going to need a careful review by looking at the
areas they are changing, and a backpatch. On Arch there is no test
package available except in AUR. And that's the pre3 release, OpenSSL
folks are on pre5 now with their beta2. It would be annoying to
compile it manually, but if there is no other way... Is Debian up to
date with 1.1.0 beta2 in its snapshot packages?

Debian testing is still on 1.0.2h.
Debian experimental is on 1.1.0pre5.

Not sure here beta2 enters the discussion, it's not mentioned anywhere on
their site?

--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/

#10Michael Paquier
michael.paquier@gmail.com
In reply to: Magnus Hagander (#9)
Re: OpenSSL 1.1 breaks configure and more

On Fri, Jul 1, 2016 at 5:02 PM, Magnus Hagander <magnus@hagander.net> wrote:

Debian testing is still on 1.0.2h.
Debian experimental is on 1.1.0pre5.

Not sure here beta2 enters the discussion, it's not mentioned anywhere on
their site?

Thanks. From the main page of openssl.org, pre5 is beta2.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Magnus Hagander
magnus@hagander.net
In reply to: Michael Paquier (#10)
Re: OpenSSL 1.1 breaks configure and more

On Fri, Jul 1, 2016 at 10:10 AM, Michael Paquier <michael.paquier@gmail.com>
wrote:

On Fri, Jul 1, 2016 at 5:02 PM, Magnus Hagander <magnus@hagander.net>
wrote:

Debian testing is still on 1.0.2h.
Debian experimental is on 1.1.0pre5.

Not sure here beta2 enters the discussion, it's not mentioned anywhere on
their site?

Thanks. From the main page of openssl.org, pre5 is beta2.

Hah. And it's not mentioned on their download page. I see they continue
down their path of confusing version numbering.

--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/

#12Christoph Berg
myon@debian.org
In reply to: Andreas Karlsson (#7)
Re: OpenSSL 1.1 breaks configure and more

Re: Andreas Karlsson 2016-07-01 <688a438c-ccc2-0431-7100-26e418fc3bca@proxel.se>

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).

Hi Andreas,

thanks for the patches. I applied all there patches on top of HEAD
(10c0558f). The server builds and passes "make check", pgcrypto still
needs work, though:

./configure --with-openssl
make world

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fpic -I. -I. -I../../src/include -D_GNU_SOURCE -c -o openssl.o openssl.c
openssl.c:205:13: error: field ‘ctx’ has incomplete type
EVP_MD_CTX ctx;
^
openssl.c: In function ‘digest_free’:
openssl.c:253:2: warning: implicit declaration of function ‘EVP_MD_CTX_cleanup’ [-Wimplicit-function-declaration]
EVP_MD_CTX_cleanup(&digest->ctx);
^
openssl.c: In function ‘init_openssl_rand’:
openssl.c:990:24: warning: implicit declaration of function ‘RAND_SSLeay’ [-Wimplicit-function-declaration]
RAND_set_rand_method(RAND_SSLeay());
^
openssl.c:990:24: warning: passing argument 1 of ‘RAND_set_rand_method’ makes pointer from integer without a cast [-Wint-conversion]
In file included from openssl.c:40:0:
/usr/include/openssl/rand.h:41:5: note: expected ‘const RAND_METHOD * {aka const struct rand_meth_st *}’ but argument is of type ‘int’
int RAND_set_rand_method(const RAND_METHOD *meth);
^
openssl.c: In function ‘px_get_pseudo_random_bytes’:
openssl.c:1017:2: warning: ‘RAND_pseudo_bytes’ is deprecated [-Wdeprecated-declarations]
res = RAND_pseudo_bytes(dst, count);
^
In file included from openssl.c:40:0:
/usr/include/openssl/rand.h:51:5: note: declared here
DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num))
^
openssl.c: In function ‘digest_block_size’:
openssl.c:222:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
openssl.c: In function ‘digest_result_size’:
openssl.c:214:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
<eingebaut>: die Regel für Ziel „openssl.o“ scheiterte
make[2]: *** [openssl.o] Fehler 1
make[2]: Verzeichnis „/home/cbe/projects/postgresql/pg/master/contrib/pgcrypto“ wird verlassen

ii libssl-dev:amd64 1.1.0~pre5-4 amd64 Secure Sockets Layer toolkit - development files
ii libssl1.0.0:amd64 1.0.2d-1 amd64 Secure Sockets Layer toolkit - shared libraries
ii libssl1.0.2:amd64 1.0.2h-1 amd64 Secure Sockets Layer toolkit - shared libraries
ii libssl1.1:amd64 1.1.0~pre5-4 amd64 Secure Sockets Layer toolkit - shared libraries
ii openssl 1.0.2h-1 amd64 Secure Sockets Layer toolkit - cryptographic utility

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Andreas Karlsson
andreas@proxel.se
In reply to: Christoph Berg (#12)
4 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 07/01/2016 11:41 AM, Christoph Berg wrote:

thanks for the patches. I applied all there patches on top of HEAD
(10c0558f). The server builds and passes "make check", pgcrypto still
needs work, though:

Thanks, I had forgotten pgcrypto.

When fixing pgcrypto I noticed that the OpenSSL team has deprecated
RAND_pseudo_bytes() and recommend using RAND_bytes() instead (see
302d38e3f73d5fd2ba2fd30bb7798778cb9f18dd).

As far as I can tell the only difference is that RAND_bytes() adds an
error to the error queue if there is not enough entropy for generating
secure data. And since we already always use strong random with the
Fortuna algorithm, why not just drop px_get_pseudo_random_bytes()? It
feels like a potential security problem with to me unclear benefit.

I also found that client CA loading is broken in OpenSSL 1.1-pre5
(reported as https://github.com/openssl/openssl/pull/1279). This might
be good to be aware of when testing my patches.

Attached a new set of patches:

0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch

The fixes necessary to build with OpenSSL 1.1. Mostly fixes surrounding
direct access to struct fields.

0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patch

Fix deprecation warnings. Mostly trusting OpenSSL 1.1 to handle
threading and initialization automatically.

0003-Remove-px_get_pseudo_random_bytes-v2.patch

Remove the px_get_pseudo_random_bytes() from pgcrypto. Also silcences
deprecation warning about RAND_pseudo_bytes().

0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patch

Useful if you want to play around with
0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch before they release a
new version where CRYPTO_LOCK is added back. See
https://github.com/openssl/openssl/issues/1260

Andreas

Attachments:

0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patchtext/x-patch; name=0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patchDownload
From 59cb028a38c18cb2f8fff077d355a8a26ecce641 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 05:55:03 +0200
Subject: [PATCH 1/4] Fixes for compiling with OpenSSL 1.1

- Check for SSL_new now that SSL_library_init is a macro
- Do not access struct members directly
- RAND_SSLeay was renamed to RAND_OpenSSL()
---
 configure                                | 44 ++++++++++++++++----------------
 configure.in                             |  4 +--
 contrib/pgcrypto/openssl.c               | 28 ++++++++++++--------
 contrib/sslinfo/sslinfo.c                | 14 ++--------
 src/backend/libpq/be-secure-openssl.c    | 39 +++++++++++++++++++---------
 src/interfaces/libpq/fe-secure-openssl.c | 39 +++++++++++++++++++---------
 6 files changed, 98 insertions(+), 70 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/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 976af70..a1db35d 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -196,13 +196,20 @@ compat_find_digest(const char *name, PX_MD **res)
 #endif
 
 /*
+ *  RAND_SSLeay() changed name to RAND_OpenSSL() in 1.1
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RAND_OpenSSL() RAND_SSLeay()
+#endif
+
+/*
  * Hashes
  */
 
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX	*ctx;
 } OSSLDigest;
 
 static unsigned
@@ -210,7 +217,7 @@ digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -218,7 +225,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -226,7 +233,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -234,7 +241,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -242,7 +249,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -250,7 +257,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
+	EVP_MD_CTX_destroy(digest->ctx);
 
 	px_free(digest);
 	px_free(h);
@@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res)
 	digest = px_alloc(sizeof(*digest));
 	digest->algo = md;
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	digest->ctx = EVP_MD_CTX_create();
+	EVP_MD_CTX_init(digest->ctx);
+	if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0)
 		return -1;
 
 	h = px_alloc(sizeof(*h));
@@ -987,7 +995,7 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
-		RAND_set_rand_method(RAND_SSLeay());
+		RAND_set_rand_method(RAND_OpenSSL());
 	openssl_random_init = 1;
 }
 
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 82a4c1b..a4b0f9b 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	SSLExtensionInfoContext *fctx;
 
-	STACK_OF(X509_EXTENSION) *ext_stack = NULL;
-
 	if (SRF_IS_FIRSTCALL())
 	{
 
@@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("function returning record called in context that cannot accept type record")));
 		fctx->tupdesc = BlessTupleDesc(tupdesc);
 
-		/* Get all extensions of certificate */
-		if (cert && cert->cert_info)
-			ext_stack = cert->cert_info->extensions;
-
 		/* Set max_calls as a count of extensions in certificate */
 		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
 
-		if (cert != NULL &&
-			ext_stack != NULL &&
-			max_calls > 0)
+		if (max_calls > 0)
 		{
 			/* got results, keep track of them */
 			funcctx->max_calls = max_calls;
@@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	max_calls = funcctx->max_calls;
 	fctx = funcctx->user_fctx;
 
-	ext_stack = cert->cert_info->extensions;
-
 	/* do while there are more left to send */
 	if (call_cntr < max_calls)
 	{
@@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("could not create OpenSSL BIO structure")));
 
 		/* Get the extension from the certificate */
-		ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
+		ext = X509_get_ext(cert, call_cntr);
 		obj = X509_EXTENSION_get_object(ext);
 
 		/* Get the extension name */
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

0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patchtext/x-patch; name=0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patchDownload
From 9d4e6c634bfb82ed07fb5b99ee4c838b9d2573a9 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 07:51:49 +0200
Subject: [PATCH 2/4] Remove OpenSSL 1.1 deprecation warnings

- Fix deprecation warning about DH_generate_parameters
- Fix warnigns resulting from the automatic initialization
- Fix warnigns resulting from the new thread support in OpenSSL
---
 src/backend/libpq/be-secure-openssl.c    | 23 ++++++++++++++++++++++-
 src/interfaces/libpq/fe-secure-openssl.c | 10 +++++++---
 2 files changed, 29 insertions(+), 4 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 520dcd7..aa80284 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -731,7 +731,7 @@ 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
  */
@@ -763,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
@@ -802,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)
 	{
 		/*
@@ -842,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
@@ -854,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
@@ -906,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

0003-Remove-px_get_pseudo_random_bytes-v2.patchtext/x-patch; name=0003-Remove-px_get_pseudo_random_bytes-v2.patchDownload
From 3ece4de28b6deea2281cd805dcbdb93851ddea50 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Fri, 1 Jul 2016 19:34:31 +0200
Subject: [PATCH 3/4] Remove px_get_pseudo_random_bytes

---
 contrib/pgcrypto/internal.c |  9 ---------
 contrib/pgcrypto/openssl.c  | 15 ---------------
 contrib/pgcrypto/pgcrypto.c |  2 +-
 contrib/pgcrypto/pgp-s2k.c  |  6 +++---
 contrib/pgcrypto/px-crypt.c |  2 +-
 contrib/pgcrypto/px.h       |  1 -
 6 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index a1db35d..d20dfdc 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -1015,21 +1015,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 9937d15..3551d44 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
 		case PGP_S2K_SIMPLE:
 			break;
 		case PGP_S2K_SALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case PGP_S2K_ISALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_s2k_iter(tmp, count);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 0f6bbd7..9174e13 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
-- 
2.8.1

0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patchtext/x-patch; name=0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patchDownload
From 34f75691e2454924392107940ab61773c09bd2ed Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 05:58:50 +0200
Subject: [PATCH 4/4] 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 aa80284..998eca4 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

#14Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andreas Karlsson (#13)
Re: OpenSSL 1.1 breaks configure and more

Thanks for this effort.

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

Generally, version number tests sprinkled all over the place are not
terribly nice. I think it would be better to get configure to define a
symbol like HAVE_BIO_METH_NEW. Not sure about the other hunks in this
patch; perhaps HAVE_BIO_SET_DATA, and #define both those macros if not.

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Andreas Karlsson
andreas@proxel.se
In reply to: Alvaro Herrera (#14)
Re: OpenSSL 1.1 breaks configure and more

On 07/02/2016 02:28 AM, Alvaro Herrera wrote:

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

Generally, version number tests sprinkled all over the place are not
terribly nice. I think it would be better to get configure to define a
symbol like HAVE_BIO_METH_NEW. Not sure about the other hunks in this
patch; perhaps HAVE_BIO_SET_DATA, and #define both those macros if not.

Agreed, that it is not nice. I followed what the previous code did, but
I do not like the inflation of this kind of #ifs with my OpenSSL 1.1
patches. I will try to see if I can figure out some good symbols.

Essentially the API changes which require ifdefs are:

- Opaque struts (we see an example above with the BIO struct)
- Renaming of RAND_SSLeay()
- Deprecation of DH_generate_parameters()
- Automatic initialization
- Automatic handling of threading

I do not like the idea of having a define per struct they have made
opaque in 1.1, but I think one define for all structs could be fine
(something like HAVE_OPENSSL_OPAQUE_STRUCTS). What do you think?

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Andreas Karlsson
andreas@proxel.se
In reply to: Andreas Karlsson (#15)
Re: OpenSSL 1.1 breaks configure and more

On 07/02/2016 02:45 AM, Andreas Karlsson wrote:

On 07/02/2016 02:28 AM, Alvaro Herrera wrote:

Generally, version number tests sprinkled all over the place are not
terribly nice. I think it would be better to get configure to define a
symbol like HAVE_BIO_METH_NEW. Not sure about the other hunks in this
patch; perhaps HAVE_BIO_SET_DATA, and #define both those macros if not.

Agreed, that it is not nice. I followed what the previous code did, but
I do not like the inflation of this kind of #ifs with my OpenSSL 1.1
patches. I will try to see if I can figure out some good symbols.

Essentially the API changes which require ifdefs are:

- Opaque struts (we see an example above with the BIO struct)
- Renaming of RAND_SSLeay()
- Deprecation of DH_generate_parameters()
- Automatic initialization
- Automatic handling of threading

I do not like the idea of having a define per struct they have made
opaque in 1.1, but I think one define for all structs could be fine
(something like HAVE_OPENSSL_OPAQUE_STRUCTS). What do you think?

Looking at my code again I noticed it is just the BIO and BIO_METHOD
structs which needed #ifs. The rest could be handled with changing the
code to work in both old and new versions. If it is just two structs it
might be fine to have two symbols, hm ..

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Christoph Berg
myon@debian.org
In reply to: Andreas Karlsson (#16)
Re: OpenSSL 1.1 breaks configure and more

Re: Andreas Karlsson 2016-07-02 <a5f4b79e-a9ea-200d-e17e-2da3ad187e5b@proxel.se>

On 07/01/2016 11:41 AM, Christoph Berg wrote:

thanks for the patches. I applied all there patches on top of HEAD
(10c0558f). The server builds and passes "make check", pgcrypto still
needs work, though:

Thanks, I had forgotten pgcrypto.

pgcrypto works now as well, thanks!

Re: Alvaro Herrera 2016-07-02 <20160702002846.GA376611@alvherre.pgsql>

Generally, version number tests sprinkled all over the place are not
terribly nice. I think it would be better to get configure to define a
symbol like HAVE_BIO_METH_NEW. Not sure about the other hunks in this
patch; perhaps HAVE_BIO_SET_DATA, and #define both those macros if not.

Otoh these symbols are strictly version-dependant on OpenSSL, it's not
like one of the symbols would appear or disappear for other reasons
(like different TLS implementation, or different operating system).

Once we decide (in 10 years?) that the minimum supported OpenSSL
version is >= 1.1, we can just drop the version checks. If these are
converted to feature tests now, it will be much harder to remember at
which point they can be dropped.

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Victor Wagner
vitus@wagner.pp.ru
In reply to: Andreas Karlsson (#7)
Re: OpenSSL 1.1 breaks configure and more

On Fri, 1 Jul 2016 02:27:03 +0200
Andreas Karlsson <andreas@proxel.se> wrote:

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.

This patch breaks feature, which exists in PostgreSQL since 8.2 -
support for SSL ciphers, provided by loadable modules such as Russian
national standard (GOST) algorithms, and support for cryptographic
hardware tokens (which are also supported by loadble modules called
engines in OpenSSL).

Call for OPENSSL_config was added to PostgreSQL for this purpose - it
loads default OpenSSL configuration file, where such things as crypto
hardware modules can be configured.

If we wish to keep this functionality, we need to explicitely call

OPENSSL_init_ssl(INIT_LOAD_CONFIG,NULL) instead of deprecated
OPENSSL_config in 1.1.0

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Andreas Karlsson
andreas@proxel.se
In reply to: Victor Wagner (#18)
3 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 07/05/2016 11:13 AM, Victor Wagner wrote:

On Fri, 1 Jul 2016 02:27:03 +0200
Andreas Karlsson <andreas@proxel.se> wrote:

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.

This patch breaks feature, which exists in PostgreSQL since 8.2 -
support for SSL ciphers, provided by loadable modules such as Russian
national standard (GOST) algorithms, and support for cryptographic
hardware tokens (which are also supported by loadble modules called
engines in OpenSSL).

Call for OPENSSL_config was added to PostgreSQL for this purpose - it
loads default OpenSSL configuration file, where such things as crypto
hardware modules can be configured.

If we wish to keep this functionality, we need to explicitely call

OPENSSL_init_ssl(INIT_LOAD_CONFIG,NULL) instead of deprecated
OPENSSL_config in 1.1.0

Thanks for testing the patches!

I have attached a new set of patches which this is fixed. I have also
skipped the last patch since OpenSSL has fixed the two issues I have
mentioned earlier in this thread.

Andreas

Attachments:

0001-Fixes-for-compiling-with-OpenSSL-1.1-v3.patchtext/x-patch; name=0001-Fixes-for-compiling-with-OpenSSL-1.1-v3.patchDownload
From 0e6d78ad199bde8c4e698952a3b5e4375371f072 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 05:55:03 +0200
Subject: [PATCH 1/3] Fixes for compiling with OpenSSL 1.1

- Check for SSL_new now that SSL_library_init is a macro
- Do not access struct members directly
- RAND_SSLeay was renamed to RAND_OpenSSL()
---
 configure                                | 44 ++++++++++++++++----------------
 configure.in                             |  4 +--
 contrib/pgcrypto/openssl.c               | 28 ++++++++++++--------
 contrib/sslinfo/sslinfo.c                | 14 ++--------
 src/backend/libpq/be-secure-openssl.c    | 39 +++++++++++++++++++---------
 src/interfaces/libpq/fe-secure-openssl.c | 39 +++++++++++++++++++---------
 6 files changed, 98 insertions(+), 70 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/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 976af70..a1db35d 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -196,13 +196,20 @@ compat_find_digest(const char *name, PX_MD **res)
 #endif
 
 /*
+ *  RAND_SSLeay() changed name to RAND_OpenSSL() in 1.1
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RAND_OpenSSL() RAND_SSLeay()
+#endif
+
+/*
  * Hashes
  */
 
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX	*ctx;
 } OSSLDigest;
 
 static unsigned
@@ -210,7 +217,7 @@ digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -218,7 +225,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -226,7 +233,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -234,7 +241,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -242,7 +249,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -250,7 +257,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
+	EVP_MD_CTX_destroy(digest->ctx);
 
 	px_free(digest);
 	px_free(h);
@@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res)
 	digest = px_alloc(sizeof(*digest));
 	digest->algo = md;
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	digest->ctx = EVP_MD_CTX_create();
+	EVP_MD_CTX_init(digest->ctx);
+	if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0)
 		return -1;
 
 	h = px_alloc(sizeof(*h));
@@ -987,7 +995,7 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
-		RAND_set_rand_method(RAND_SSLeay());
+		RAND_set_rand_method(RAND_OpenSSL());
 	openssl_random_init = 1;
 }
 
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 82a4c1b..a4b0f9b 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	SSLExtensionInfoContext *fctx;
 
-	STACK_OF(X509_EXTENSION) *ext_stack = NULL;
-
 	if (SRF_IS_FIRSTCALL())
 	{
 
@@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("function returning record called in context that cannot accept type record")));
 		fctx->tupdesc = BlessTupleDesc(tupdesc);
 
-		/* Get all extensions of certificate */
-		if (cert && cert->cert_info)
-			ext_stack = cert->cert_info->extensions;
-
 		/* Set max_calls as a count of extensions in certificate */
 		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
 
-		if (cert != NULL &&
-			ext_stack != NULL &&
-			max_calls > 0)
+		if (max_calls > 0)
 		{
 			/* got results, keep track of them */
 			funcctx->max_calls = max_calls;
@@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	max_calls = funcctx->max_calls;
 	fctx = funcctx->user_fctx;
 
-	ext_stack = cert->cert_info->extensions;
-
 	/* do while there are more left to send */
 	if (call_cntr < max_calls)
 	{
@@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("could not create OpenSSL BIO structure")));
 
 		/* Get the extension from the certificate */
-		ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
+		ext = X509_get_ext(cert, call_cntr);
 		obj = X509_EXTENSION_get_object(ext);
 
 		/* Get the extension name */
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

0002-Remove-OpenSSL-1.1-deprecation-warnings-v3.patchtext/x-patch; name=0002-Remove-OpenSSL-1.1-deprecation-warnings-v3.patchDownload
From d9b6b554e0580539605f74c83c5a9caaa9e2e6a0 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 07:51:49 +0200
Subject: [PATCH 2/3] Remove OpenSSL 1.1 deprecation warnings

- Fix deprecation warning about DH_generate_parameters
- Fix warnigns resulting from the automatic initialization
- Fix warnigns resulting from the new thread support in OpenSSL
- Use OPENSSL_init_ssl instead of deprecated OPENSSL_config
---
 src/backend/libpq/be-secure-openssl.c    | 25 ++++++++++++++++++++++++-
 src/interfaces/libpq/fe-secure-openssl.c | 12 +++++++++---
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 2fa2793..86ede00 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -166,11 +166,15 @@ be_tls_init(void)
 
 	if (!SSL_context)
 	{
+#if SSLEAY_VERSION_NUMBER >= 0x10100000L
+		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 #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 +858,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 +946,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 520dcd7..aaf27c5 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -731,7 +731,7 @@ 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
  */
@@ -763,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
@@ -802,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)
 	{
 		/*
@@ -842,17 +843,22 @@ pgtls_init(PGconn *conn)
 				CRYPTO_set_locking_callback(pq_lockingcallback);
 		}
 	}
+#endif
 #endif   /* ENABLE_THREAD_SAFETY */
 
 	if (!SSL_context)
 	{
 		if (pq_init_ssl_lib)
 		{
+#if SSLEAY_VERSION_NUMBER >= 0x10100000L
+			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 #if SSLEAY_VERSION_NUMBER >= 0x00907000L
 			OPENSSL_config(NULL);
 #endif
 			SSL_library_init();
 			SSL_load_error_strings();
+#endif
 		}
 
 		/*
@@ -906,7 +912,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

0003-Remove-px_get_pseudo_random_bytes-v3.patchtext/x-patch; name=0003-Remove-px_get_pseudo_random_bytes-v3.patchDownload
From abdd755c4625f12dda44721c5c26da35a26a61e1 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Fri, 1 Jul 2016 19:34:31 +0200
Subject: [PATCH 3/3] Remove px_get_pseudo_random_bytes

---
 contrib/pgcrypto/internal.c |  9 ---------
 contrib/pgcrypto/openssl.c  | 15 ---------------
 contrib/pgcrypto/pgcrypto.c |  2 +-
 contrib/pgcrypto/pgp-s2k.c  |  6 +++---
 contrib/pgcrypto/px-crypt.c |  2 +-
 contrib/pgcrypto/px.h       |  1 -
 6 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index a1db35d..d20dfdc 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -1015,21 +1015,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 9937d15..3551d44 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
 		case PGP_S2K_SIMPLE:
 			break;
 		case PGP_S2K_SALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case PGP_S2K_ISALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_s2k_iter(tmp, count);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 0f6bbd7..9174e13 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
-- 
2.8.1

#20Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Andreas Karlsson (#19)
Re: OpenSSL 1.1 breaks configure and more

On 07/05/2016 04:46 PM, Andreas Karlsson wrote:

@@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res)
digest = px_alloc(sizeof(*digest));
digest->algo = md;

-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	digest->ctx = EVP_MD_CTX_create();
+	EVP_MD_CTX_init(digest->ctx);
+	if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0)
return -1;

h = px_alloc(sizeof(*h));

Now that we're calling EVP_MD_CTX_create((), which allocates memory, are
we risking memory leaks? It has always been part of the contract that
you have to call px_md_free(), for any context returned by
px_find_digest(), but I wonder just how careful we have been about that.
Before this, you would probably get away with it without leaking, if the
digest implementation didn't allocate any extra memory or other resources.

At least pg_digest and try_unix_std functions call px_find_digest(), and
then do more palloc()s which could elog() if you run out of memory,
leaking th digest struct. Highly unlikely, but I think it would be
fairly straightforward to reorder those calls to eliminate the risk, so
we probably should.

@@ -854,6 +858,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
+}
+

I think now would be a good time to drop support for OpenSSL versions
older than 0.9.8. OpenSSL don't even support 0.9.8 anymore, although
there are probably distributions out there that still provide patches
for it. But OpenSSL 0.9.7 and older are really not interesting for
PostgreSQL 10 anymore, I think.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Heikki Linnakangas (#20)
Re: OpenSSL 1.1 breaks configure and more

On 8/26/16 5:31 AM, Heikki Linnakangas wrote:

I think now would be a good time to drop support for OpenSSL versions
older than 0.9.8. OpenSSL don't even support 0.9.8 anymore, although
there are probably distributions out there that still provide patches
for it. But OpenSSL 0.9.7 and older are really not interesting for
PostgreSQL 10 anymore, I think.

CentOS 5 currently ships 0.9.8e. That's usually the oldest OS we want
to support eagerly.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#22Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#21)
Re: OpenSSL 1.1 breaks configure and more

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 8/26/16 5:31 AM, Heikki Linnakangas wrote:

I think now would be a good time to drop support for OpenSSL versions
older than 0.9.8. OpenSSL don't even support 0.9.8 anymore, although
there are probably distributions out there that still provide patches
for it. But OpenSSL 0.9.7 and older are really not interesting for
PostgreSQL 10 anymore, I think.

CentOS 5 currently ships 0.9.8e. That's usually the oldest OS we want
to support eagerly.

Also, I get this on fully-up-to-date OS X (El Capitan):

$ openssl version
OpenSSL 0.9.8zh 14 Jan 2016

Worth noting though is that without -Wno-deprecated-declarations, you
find that Apple has sprinkled the entire OpenSSL API with deprecation
warnings. That suggests that their plan for the future is to drop it
rather than update it. Should we be thinking ahead to that?

regards, tom lane

PS: I still have 0.9.7 on some of my buildfarm critters. But I could
either update them, or stop using --with-openssl there.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#23Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Tom Lane (#22)
Re: OpenSSL 1.1 breaks configure and more

On 08/26/2016 07:44 PM, Tom Lane wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 8/26/16 5:31 AM, Heikki Linnakangas wrote:

I think now would be a good time to drop support for OpenSSL versions
older than 0.9.8. OpenSSL don't even support 0.9.8 anymore, although
there are probably distributions out there that still provide patches
for it. But OpenSSL 0.9.7 and older are really not interesting for
PostgreSQL 10 anymore, I think.

CentOS 5 currently ships 0.9.8e. That's usually the oldest OS we want
to support eagerly.

Also, I get this on fully-up-to-date OS X (El Capitan):

$ openssl version
OpenSSL 0.9.8zh 14 Jan 2016

Ok, sold, let's remove support for OpenSSL < 0.9.8.

Worth noting though is that without -Wno-deprecated-declarations, you
find that Apple has sprinkled the entire OpenSSL API with deprecation
warnings. That suggests that their plan for the future is to drop it
rather than update it. Should we be thinking ahead to that?

Yeah, they want people to move to their own SSL library [1]I couldn't find any official statement, but lots of blog posts saying the same thing.. I doubt
they will actually remove it any time soon, but who knows. It would be a
good project for someone with an OS X system and some spare time, to
write a patch to build with OS X's native SSL library instead of
OpenSSL. The code is structured nicely to enable that now.

[1]: I couldn't find any official statement, but lots of blog posts saying the same thing.
saying the same thing.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#24Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#23)
Re: OpenSSL 1.1 breaks configure and more

Heikki Linnakangas <hlinnaka@iki.fi> writes:

Yeah, they want people to move to their own SSL library [1].

[1] I couldn't find any official statement, but lots of blog posts
saying the same thing.

As I recall, the deprecation warning messages said that in so many words.
That probably counts as an official statement ...

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#25Andreas Karlsson
andreas@proxel.se
In reply to: Heikki Linnakangas (#23)
1 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 08/26/2016 07:04 PM, Heikki Linnakangas wrote:

On 08/26/2016 07:44 PM, Tom Lane wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 8/26/16 5:31 AM, Heikki Linnakangas wrote:

I think now would be a good time to drop support for OpenSSL versions
older than 0.9.8. OpenSSL don't even support 0.9.8 anymore, although
there are probably distributions out there that still provide patches
for it. But OpenSSL 0.9.7 and older are really not interesting for
PostgreSQL 10 anymore, I think.

CentOS 5 currently ships 0.9.8e. That's usually the oldest OS we want
to support eagerly.

Also, I get this on fully-up-to-date OS X (El Capitan):

$ openssl version
OpenSSL 0.9.8zh 14 Jan 2016

Ok, sold, let's remove support for OpenSSL < 0.9.8.

I have attached a patch which removes the < 0.9.8 compatibility code.
Should we also add a version check to configure? We do not have any such
check currently.

Andreas

Attachments:

remove-openssl-pre-0.9.8-v1.patchtext/x-patch; name=remove-openssl-pre-0.9.8-v1.patchDownload
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 976af70..ffab5d2 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -37,6 +37,7 @@
 #include <openssl/blowfish.h>
 #include <openssl/cast.h>
 #include <openssl/des.h>
+#include <openssl/aes.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
@@ -47,155 +48,6 @@
 #define MAX_IV		(128/8)
 
 /*
- * Compatibility with OpenSSL 0.9.6
- *
- * It needs AES and newer DES and digest API.
- */
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-
-/*
- * Nothing needed for OpenSSL 0.9.7+
- */
-
-#include <openssl/aes.h>
-#else							/* old OPENSSL */
-
-/*
- * Emulate OpenSSL AES.
- */
-
-#include "rijndael.c"
-
-#define AES_ENCRYPT 1
-#define AES_DECRYPT 0
-#define AES_KEY		rijndael_ctx
-
-static int
-AES_set_encrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
-{
-	aes_set_key(ctx, key, kbits, 1);
-	return 0;
-}
-
-static int
-AES_set_decrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
-{
-	aes_set_key(ctx, key, kbits, 0);
-	return 0;
-}
-
-static void
-AES_ecb_encrypt(const uint8 *src, uint8 *dst, AES_KEY *ctx, int enc)
-{
-	memcpy(dst, src, 16);
-	if (enc)
-		aes_ecb_encrypt(ctx, dst, 16);
-	else
-		aes_ecb_decrypt(ctx, dst, 16);
-}
-
-static void
-AES_cbc_encrypt(const uint8 *src, uint8 *dst, int len, AES_KEY *ctx, uint8 *iv, int enc)
-{
-	memcpy(dst, src, len);
-	if (enc)
-	{
-		aes_cbc_encrypt(ctx, iv, dst, len);
-		memcpy(iv, dst + len - 16, 16);
-	}
-	else
-	{
-		aes_cbc_decrypt(ctx, iv, dst, len);
-		memcpy(iv, src + len - 16, 16);
-	}
-}
-
-/*
- * Emulate DES_* API
- */
-
-#define DES_key_schedule des_key_schedule
-#define DES_cblock des_cblock
-#define DES_set_key(k, ks) \
-		des_set_key((k), *(ks))
-#define DES_ecb_encrypt(i, o, k, e) \
-		des_ecb_encrypt((i), (o), *(k), (e))
-#define DES_ncbc_encrypt(i, o, l, k, iv, e) \
-		des_ncbc_encrypt((i), (o), (l), *(k), (iv), (e))
-#define DES_ecb3_encrypt(i, o, k1, k2, k3, e) \
-		des_ecb3_encrypt((des_cblock *)(i), (des_cblock *)(o), \
-				*(k1), *(k2), *(k3), (e))
-#define DES_ede3_cbc_encrypt(i, o, l, k1, k2, k3, iv, e) \
-		des_ede3_cbc_encrypt((i), (o), \
-				(l), *(k1), *(k2), *(k3), (iv), (e))
-
-/*
- * Emulate newer digest API.
- */
-
-static void
-EVP_MD_CTX_init(EVP_MD_CTX *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-}
-
-static int
-EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
-{
-	px_memset(ctx, 0, sizeof(*ctx));
-	return 1;
-}
-
-static int
-EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
-{
-	EVP_DigestInit(ctx, md);
-	return 1;
-}
-
-static int
-EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
-{
-	EVP_DigestFinal(ctx, res, len);
-	return 1;
-}
-#endif   /* old OpenSSL */
-
-/*
- * Provide SHA2 for older OpenSSL < 0.9.8
- */
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
-
-#include "sha2.c"
-#include "internal-sha2.c"
-
-typedef void (*init_f) (PX_MD *md);
-
-static int
-compat_find_digest(const char *name, PX_MD **res)
-{
-	init_f		init = NULL;
-
-	if (pg_strcasecmp(name, "sha224") == 0)
-		init = init_sha224;
-	else if (pg_strcasecmp(name, "sha256") == 0)
-		init = init_sha256;
-	else if (pg_strcasecmp(name, "sha384") == 0)
-		init = init_sha384;
-	else if (pg_strcasecmp(name, "sha512") == 0)
-		init = init_sha512;
-	else
-		return PXE_NO_HASH;
-
-	*res = px_alloc(sizeof(PX_MD));
-	init(*res);
-	return 0;
-}
-#else
-#define compat_find_digest(name, res)  (PXE_NO_HASH)
-#endif
-
-/*
  * Hashes
  */
 
@@ -275,7 +127,7 @@ px_find_digest(const char *name, PX_MD **res)
 
 	md = EVP_get_digestbyname(name);
 	if (md == NULL)
-		return compat_find_digest(name, res);
+		return PXE_NO_HASH;
 
 	digest = px_alloc(sizeof(*digest));
 	digest->algo = md;
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index a996875..2420387 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -2827,30 +2827,6 @@ MANPATH=/usr/lib/scohelp/%L/man:/usr/dt/man:/usr/man:/usr/share/man:scohelp:/usr
    </sect3>
 
    <sect3>
-    <title>Problems with OpenSSL</title>
-
-    <para>
-     When you build PostgreSQL with OpenSSL support you might get
-     compilation errors in the following files:
-     <itemizedlist>
-      <listitem><para><filename>src/backend/libpq/crypt.c</filename></para></listitem>
-      <listitem><para><filename>src/backend/libpq/password.c</filename></para></listitem>
-      <listitem><para><filename>src/interfaces/libpq/fe-auth.c</filename></para></listitem>
-      <listitem><para><filename>src/interfaces/libpq/fe-connect.c</filename></para></listitem>
-     </itemizedlist>
-
-     This is because of a namespace conflict between the standard
-     <filename>/usr/include/crypt.h</filename> header and the header
-     files provided by OpenSSL.
-    </para>
-
-    <para>
-     Upgrading your OpenSSL installation to version 0.9.6a fixes this
-     problem.  Solaris 9 and above has a newer version of OpenSSL.
-    </para>
-   </sect3>
-
-   <sect3>
     <title>configure Complains About a Failed Test Program</title>
 
     <para>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2f9350b..4e34f00 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1238,8 +1238,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
       <listitem>
        <para>
         If set to 1 (default), data sent over SSL connections will be
-        compressed (this requires <productname>OpenSSL</> version
-        0.9.8 or later).
+        compressed.
         If set to 0, compression will be disabled (this requires
         <productname>OpenSSL</> 1.0.0 or later).
         This parameter is ignored if a connection without SSL is made,
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index c4cefde..af17f79 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1232,23 +1232,11 @@ gen_random_uuid() returns uuid
    <orderedlist>
     <listitem>
      <para>
-      SHA2 algorithms were added to OpenSSL in version 0.9.8.  For
-      older versions, <filename>pgcrypto</> will use built-in code.
-     </para>
-    </listitem>
-    <listitem>
-     <para>
       Any digest algorithm OpenSSL supports is automatically picked up.
       This is not possible with ciphers, which need to be supported
       explicitly.
      </para>
     </listitem>
-    <listitem>
-     <para>
-      AES is included in OpenSSL since version 0.9.7.  For
-      older versions, <filename>pgcrypto</> will use built-in code.
-     </para>
-    </listitem>
    </orderedlist>
   </sect3>
 
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index f6adb15..e5f434c 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -53,10 +53,8 @@
 
 #include <openssl/ssl.h>
 #include <openssl/dh.h>
-#if SSLEAY_VERSION_NUMBER >= 0x0907000L
 #include <openssl/conf.h>
-#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_ECDH)
+#ifndef OPENSSL_NO_ECDH
 #include <openssl/ec.h>
 #endif
 
@@ -166,9 +164,7 @@ be_tls_init(void)
 
 	if (!SSL_context)
 	{
-#if SSLEAY_VERSION_NUMBER >= 0x0907000L
 		OPENSSL_config(NULL);
-#endif
 		SSL_library_init();
 		SSL_load_error_strings();
 
@@ -978,7 +974,7 @@ info_cb(const SSL *ssl, int type, int args)
 static void
 initialize_ecdh(void)
 {
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_ECDH)
+#ifndef OPENSSL_NO_ECDH
 	EC_KEY	   *ecdh;
 	int			nid;
 
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index f6ce1c7..d871612 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -54,9 +54,7 @@
 #endif
 
 #include <openssl/ssl.h>
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
 #include <openssl/conf.h>
-#endif
 #ifdef USE_SSL_ENGINE
 #include <openssl/engine.h>
 #endif
@@ -848,9 +846,7 @@ pgtls_init(PGconn *conn)
 	{
 		if (pq_init_ssl_lib)
 		{
-#if SSLEAY_VERSION_NUMBER >= 0x00907000L
 			OPENSSL_config(NULL);
-#endif
 			SSL_library_init();
 			SSL_load_error_strings();
 		}
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 1183323..a94ead0 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -77,7 +77,7 @@ typedef struct
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
+#ifndef OPENSSL_NO_ENGINE
 #define USE_SSL_ENGINE
 #endif
 #endif   /* USE_OPENSSL */
#26Michael Paquier
michael.paquier@gmail.com
In reply to: Heikki Linnakangas (#23)
Re: OpenSSL 1.1 breaks configure and more

On Sat, Aug 27, 2016 at 2:04 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

On 08/26/2016 07:44 PM, Tom Lane wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
Also, I get this on fully-up-to-date OS X (El Capitan):

$ openssl version
OpenSSL 0.9.8zh 14 Jan 2016

Ok, sold, let's remove support for OpenSSL < 0.9.8.

Yes I think it's a wiser plan to not brush up newer versions than that.

Worth noting though is that without -Wno-deprecated-declarations, you
find that Apple has sprinkled the entire OpenSSL API with deprecation
warnings. That suggests that their plan for the future is to drop it
rather than update it. Should we be thinking ahead to that?

Yeah, they want people to move to their own SSL library [1]. I doubt they
will actually remove it any time soon, but who knows. It would be a good
project for someone with an OS X system and some spare time, to write a
patch to build with OS X's native SSL library instead of OpenSSL. The code
is structured nicely to enable that now.

[1] I couldn't find any official statement, but lots of blog posts saying
the same thing.

As well on El Capitan:
$ ssh -V
OpenSSH_6.9p1, LibreSSL 2.1.8

So could it be possible that it would be a switch from openssl to
libressl instead?
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#27Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Andreas Karlsson (#25)
Re: OpenSSL 1.1 breaks configure and more

On 8/26/16 9:26 PM, Andreas Karlsson wrote:

I have attached a patch which removes the < 0.9.8 compatibility code.
Should we also add a version check to configure? We do not have any such
check currently.

I think that is not necessary.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#28Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Peter Eisentraut (#27)
Re: OpenSSL 1.1 breaks configure and more

On 08/27/2016 05:15 PM, Peter Eisentraut wrote:

On 8/26/16 9:26 PM, Andreas Karlsson wrote:

I have attached a patch which removes the < 0.9.8 compatibility code.
Should we also add a version check to configure? We do not have any such
check currently.

I think that is not necessary.

I was going to change the configure test to check for a different
function that we use, that's only present in 0.9.8 and later. But the
only such functions were related to ECDH, and the use of those functions
is inside "#ifndef OPENSSL_NO_ECDH", so they're not suitable for the
autoconf test. So I gave up. If you try to build with 0.9.7, you'll get
compilation errors because of those ECDH symbols, and with 0.9.6,
probably on some other symbols.

Pushed with some small doc fixes, thanks Andreas! I'll continue
reviewing the rest of the patches.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#29Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Heikki Linnakangas (#28)
Re: OpenSSL 1.1 breaks configure and more

On 08/29/2016 08:22 PM, Heikki Linnakangas wrote:

On 08/27/2016 05:15 PM, Peter Eisentraut wrote:

On 8/26/16 9:26 PM, Andreas Karlsson wrote:

I have attached a patch which removes the < 0.9.8 compatibility code.
Should we also add a version check to configure? We do not have any such
check currently.

I think that is not necessary.

I was going to change the configure test to check for a different
function that we use, that's only present in 0.9.8 and later. But the
only such functions were related to ECDH, and the use of those functions
is inside "#ifndef OPENSSL_NO_ECDH", so they're not suitable for the
autoconf test. So I gave up. If you try to build with 0.9.7, you'll get
compilation errors because of those ECDH symbols, and with 0.9.6,
probably on some other symbols.

Pushed with some small doc fixes, thanks Andreas! I'll continue
reviewing the rest of the patches.

Buildfarm animals "locust" and "prairiedog" are not happy with this.
They seem to be using OpenSSL 0.9.7, as they failed with errors related
to those ECDH calls:

be-secure-openssl.c: In function 'initialize_ecdh':
be-secure-openssl.c:978: error: 'EC_KEY' undeclared (first use in this
function)
be-secure-openssl.c:978: error: (Each undeclared identifier is reported
only once
be-secure-openssl.c:978: error: for each function it appears in.)
be-secure-openssl.c:978: error: 'ecdh' undeclared (first use in this
function)
be-secure-openssl.c:979: warning: ISO C90 forbids mixed declarations and
code
be-secure-openssl.c:986: warning: implicit declaration of function
'EC_KEY_new_by_curve_name'
be-secure-openssl.c:991: error: 'SSL_OP_SINGLE_ECDH_USE' undeclared
(first use in this function)
be-secure-openssl.c:992: warning: implicit declaration of function
'SSL_CTX_set_tmp_ecdh'
be-secure-openssl.c:993: warning: implicit declaration of function
'EC_KEY_free'

I only now noticed that Tom said upthread that he still has a buildfarm
critter using 0.9.7 (that's prairiedog). Sorry for the breakage.

It would be easy to put the version check back to still support 0.9.7,
most of the changes in this commit was thanks to removing support for
0.9.6. But that'd complicate the upcoming 1.1.0 support patch slightly,
so let's stick to the plan and drop the support for <= 0.9.7

Tom, R�mi, can you fix locust and prairiedog, please, by updating
OpenSSL or removing --with-openssl?

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#30Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#29)
Re: OpenSSL 1.1 breaks configure and more

Heikki Linnakangas <hlinnaka@iki.fi> writes:

Buildfarm animals "locust" and "prairiedog" are not happy with this.
They seem to be using OpenSSL 0.9.7, as they failed with errors related
to those ECDH calls:

prairiedog definitely is, and since locust is also an ancient OS X
version, that's not too surprising also. (I imagine gaur/pademelon
will fall over too, next time I turn it on.)

Tom, R�mi, can you fix locust and prairiedog, please, by updating
OpenSSL or removing --with-openssl?

Roger, will do (probably just the latter for today).

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#31Rémi Zara
remi_zara@mac.com
In reply to: Heikki Linnakangas (#29)
Re: OpenSSL 1.1 breaks configure and more

Le 29 août 2016 à 19:46, Heikki Linnakangas <hlinnaka@iki.fi> a écrit :

Tom, Rémi, can you fix locust and prairiedog, please, by updating OpenSSL or removing --with-openssl?

Hi,

Should be OK for locust on next build.

Rémi

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#32Andreas Karlsson
andreas@proxel.se
In reply to: Heikki Linnakangas (#28)
Re: OpenSSL 1.1 breaks configure and more

On 08/29/2016 07:22 PM, Heikki Linnakangas wrote:

Pushed with some small doc fixes, thanks Andreas! I'll continue
reviewing the rest of the patches.

Thanks!

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#33Andreas Karlsson
andreas@proxel.se
In reply to: Heikki Linnakangas (#20)
3 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 08/26/2016 11:31 AM, Heikki Linnakangas wrote:

On 07/05/2016 04:46 PM, Andreas Karlsson wrote:

@@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res)
digest = px_alloc(sizeof(*digest));
digest->algo = md;

-    EVP_MD_CTX_init(&digest->ctx);
-    if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+    digest->ctx = EVP_MD_CTX_create();
+    EVP_MD_CTX_init(digest->ctx);
+    if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0)
return -1;

h = px_alloc(sizeof(*h));

Now that we're calling EVP_MD_CTX_create((), which allocates memory, are
we risking memory leaks? It has always been part of the contract that
you have to call px_md_free(), for any context returned by
px_find_digest(), but I wonder just how careful we have been about that.
Before this, you would probably get away with it without leaking, if the
digest implementation didn't allocate any extra memory or other resources.

At least pg_digest and try_unix_std functions call px_find_digest(), and
then do more palloc()s which could elog() if you run out of memory,
leaking th digest struct. Highly unlikely, but I think it would be
fairly straightforward to reorder those calls to eliminate the risk, so
we probably should.

Since px_find_digest() calls palloc() later in the function there is a
slim possibility of memory leaks. How do we generally handle that things
not allocated with palloc() may leak when something calls elog()?

I have attached new versions of the patches which are rebased on master,
with slightly improves error handling in px_find_digest(), and handles
the deprecation of ASN1_STRING_data().

Andreas

Attachments:

0002-Remove-OpenSSL-1.1-deprecation-warnings-v4.patchtext/x-patch; name=0002-Remove-OpenSSL-1.1-deprecation-warnings-v4.patchDownload
From 64ddce45b3de108303d2662a887585ae8bc77caa Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 07:51:49 +0200
Subject: [PATCH 2/3] Remove OpenSSL 1.1 deprecation warnings

- Fix deprecation warning about DH_generate_parameters
- Fix warnigns resulting from the automatic initialization
- Fix warnigns resulting from the new thread support in OpenSSL
- Use OPENSSL_init_ssl instead of deprecated OPENSSL_config
- Use ASN1_STRING_get0_data instead of ASN1_STRING_data

squash! Remove OpenSSL 1.1 deprecation warnings
---
 src/backend/libpq/be-secure-openssl.c    | 21 ++++++++++++++++++++-
 src/interfaces/libpq/fe-secure-openssl.c | 25 +++++++++++++++++--------
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 565e845..afe4694 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -164,9 +164,13 @@ be_tls_init(void)
 
 	if (!SSL_context)
 	{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 		OPENSSL_config(NULL);
 		SSL_library_init();
 		SSL_load_error_strings();
+#endif
 
 		/*
 		 * We use SSLv23_method() because it can negotiate use of the highest
@@ -850,6 +854,21 @@ load_dh_buffer(const char *buffer, size_t len)
 	return dh;
 }
 
+static DH  *
+generate_dh_params(int prime_len, int generator)
+{
+	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;
+}
+
 /*
  *	Generate an ephemeral DH key.  Because this can take a long
  *	time to compute, we can use precomputed parameters of the
@@ -919,7 +938,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 12cab74..388215f 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -506,6 +506,9 @@ wildcard_certificate_match(const char *pattern, const char *string)
 	return 1;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define ASN1_STRING_get0_data ASN1_STRING_data
+#endif
 
 /*
  * Check if a name from a server's certificate matches the peer's hostname.
@@ -520,10 +523,10 @@ static int
 verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 										  char **store_name)
 {
-	int			len;
-	char	   *name;
-	unsigned char *namedata;
-	int			result;
+	int						len;
+	char			  	   *name;
+	const unsigned char    *namedata;
+	int						result;
 
 	*store_name = NULL;
 
@@ -541,7 +544,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 	 * There is no guarantee the string returned from the certificate is
 	 * NULL-terminated, so make a copy that is.
 	 */
-	namedata = ASN1_STRING_data(name_entry);
+	namedata = ASN1_STRING_get0_data(name_entry);
 	len = ASN1_STRING_length(name_entry);
 	name = malloc(len + 1);
 	if (name == NULL)
@@ -729,7 +732,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
 	return found_match && !got_error;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 /*
  *	Callback functions for OpenSSL internal locking
  */
@@ -761,7 +764,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 && OPENSSL_VERSION_NUMBER < 0x10100000L */
 
 /*
  * Initialize SSL system, in particular creating the SSL_context object
@@ -800,6 +803,7 @@ pgtls_init(PGconn *conn)
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return -1;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	if (pq_init_crypto_lib)
 	{
 		/*
@@ -840,15 +844,20 @@ pgtls_init(PGconn *conn)
 				CRYPTO_set_locking_callback(pq_lockingcallback);
 		}
 	}
+#endif
 #endif   /* ENABLE_THREAD_SAFETY */
 
 	if (!SSL_context)
 	{
 		if (pq_init_ssl_lib)
 		{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 			OPENSSL_config(NULL);
 			SSL_library_init();
 			SSL_load_error_strings();
+#endif
 		}
 
 		/*
@@ -902,7 +911,7 @@ pgtls_init(PGconn *conn)
 static void
 destroy_ssl_system(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 	/* Mutex is created in initialize_ssl_system() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
-- 
2.9.3

0003-Remove-px_get_pseudo_random_bytes-v4.patchtext/x-patch; name=0003-Remove-px_get_pseudo_random_bytes-v4.patchDownload
From c3abf278c4bfe2b29d1c6d7168adb362242816a4 Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Fri, 1 Jul 2016 19:34:31 +0200
Subject: [PATCH 3/3] Remove px_get_pseudo_random_bytes

---
 contrib/pgcrypto/internal.c |  9 ---------
 contrib/pgcrypto/openssl.c  | 15 ---------------
 contrib/pgcrypto/pgcrypto.c |  2 +-
 contrib/pgcrypto/pgp-s2k.c  |  6 +++---
 contrib/pgcrypto/px-crypt.c |  2 +-
 contrib/pgcrypto/px.h       |  1 -
 6 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index c08e61b..6586d32 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -869,21 +869,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 9937d15..3551d44 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
 		case PGP_S2K_SIMPLE:
 			break;
 		case PGP_S2K_SALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case PGP_S2K_ISALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_s2k_iter(tmp, count);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 0f6bbd7..9174e13 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
-- 
2.9.3

0001-Fixes-for-compiling-with-OpenSSL-1.1-v4.patchtext/x-patch; name=0001-Fixes-for-compiling-with-OpenSSL-1.1-v4.patchDownload
From dea78efc9a4b68f2704dcf8cb089c0b45f3f385b Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Tue, 28 Jun 2016 05:55:03 +0200
Subject: [PATCH 1/3] Fixes for compiling with OpenSSL 1.1

- Check for SSL_new now that SSL_library_init is a macro
- Do not access struct members directly
- RAND_SSLeay was renamed to RAND_OpenSSL

squash! Fixes for compiling with OpenSSL 1.1
---
 configure                                | 44 ++++++++++++++++----------------
 configure.in                             |  4 +--
 contrib/pgcrypto/openssl.c               | 30 ++++++++++++++--------
 contrib/sslinfo/sslinfo.c                | 14 ++--------
 src/backend/libpq/be-secure-openssl.c    | 39 +++++++++++++++++++---------
 src/interfaces/libpq/fe-secure-openssl.c | 39 +++++++++++++++++++---------
 6 files changed, 100 insertions(+), 70 deletions(-)

diff --git a/configure b/configure
index 45c8eef..caf6f26 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 c878b4e..c426806 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/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index ffab5d2..c08e61b 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -54,7 +54,7 @@
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX	*ctx;
 } OSSLDigest;
 
 static unsigned
@@ -62,7 +62,7 @@ digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -70,7 +70,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -78,7 +78,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -86,7 +86,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -94,7 +94,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -102,7 +102,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
+	EVP_MD_CTX_destroy(digest->ctx);
 
 	px_free(digest);
 	px_free(h);
@@ -132,10 +132,16 @@ px_find_digest(const char *name, PX_MD **res)
 	digest = px_alloc(sizeof(*digest));
 	digest->algo = md;
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	digest->ctx = EVP_MD_CTX_create();
+	if (digest->ctx == NULL)
 		return -1;
 
+	EVP_MD_CTX_init(digest->ctx);
+	if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0) {
+		EVP_MD_CTX_destroy(digest->ctx);
+		return -1;
+	}
+
 	h = px_alloc(sizeof(*h));
 	h->result_size = digest_result_size;
 	h->block_size = digest_block_size;
@@ -831,6 +837,10 @@ px_find_cipher(const char *name, PX_Cipher **res)
 
 static int	openssl_random_init = 0;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RAND_OpenSSL RAND_SSLeay
+#endif
+
 /*
  * OpenSSL random should re-feeded occasionally. From /dev/urandom
  * preferably.
@@ -839,7 +849,7 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
-		RAND_set_rand_method(RAND_SSLeay());
+		RAND_set_rand_method(RAND_OpenSSL());
 	openssl_random_init = 1;
 }
 
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 82a4c1b..a4b0f9b 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	SSLExtensionInfoContext *fctx;
 
-	STACK_OF(X509_EXTENSION) *ext_stack = NULL;
-
 	if (SRF_IS_FIRSTCALL())
 	{
 
@@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("function returning record called in context that cannot accept type record")));
 		fctx->tupdesc = BlessTupleDesc(tupdesc);
 
-		/* Get all extensions of certificate */
-		if (cert && cert->cert_info)
-			ext_stack = cert->cert_info->extensions;
-
 		/* Set max_calls as a count of extensions in certificate */
 		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
 
-		if (cert != NULL &&
-			ext_stack != NULL &&
-			max_calls > 0)
+		if (max_calls > 0)
 		{
 			/* got results, keep track of them */
 			funcctx->max_calls = max_calls;
@@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	max_calls = funcctx->max_calls;
 	fctx = funcctx->user_fctx;
 
-	ext_stack = cert->cert_info->extensions;
-
 	/* do while there are more left to send */
 	if (call_cntr < max_calls)
 	{
@@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("could not create OpenSSL BIO structure")));
 
 		/* Get the extension from the certificate */
-		ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
+		ext = X509_get_ext(cert, call_cntr);
 		obj = X509_EXTENSION_get_object(ext);
 
 		/* Get the extension name */
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index e5f434c..565e845 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -669,8 +669,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 OPENSSL_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)
@@ -679,7 +683,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)
 		{
@@ -699,7 +703,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)
 	{
@@ -716,14 +720,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 OPENSSL_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 */
@@ -740,8 +756,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 d871612..12cab74 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1617,15 +1617,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 OPENSSL_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)
 	{
@@ -1655,7 +1659,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)
 	{
@@ -1683,14 +1687,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 OPENSSL_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 */
@@ -1706,8 +1722,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.9.3

#34Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Andreas Karlsson (#33)
Re: OpenSSL 1.1 breaks configure and more

On 08/30/2016 03:26 AM, Andreas Karlsson wrote:

On 08/26/2016 11:31 AM, Heikki Linnakangas wrote:

On 07/05/2016 04:46 PM, Andreas Karlsson wrote:

@@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res)
digest = px_alloc(sizeof(*digest));
digest->algo = md;

-    EVP_MD_CTX_init(&digest->ctx);
-    if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+    digest->ctx = EVP_MD_CTX_create();
+    EVP_MD_CTX_init(digest->ctx);
+    if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0)
return -1;

h = px_alloc(sizeof(*h));

Now that we're calling EVP_MD_CTX_create((), which allocates memory, are
we risking memory leaks? It has always been part of the contract that
you have to call px_md_free(), for any context returned by
px_find_digest(), but I wonder just how careful we have been about that.
Before this, you would probably get away with it without leaking, if the
digest implementation didn't allocate any extra memory or other resources.

At least pg_digest and try_unix_std functions call px_find_digest(), and
then do more palloc()s which could elog() if you run out of memory,
leaking th digest struct. Highly unlikely, but I think it would be
fairly straightforward to reorder those calls to eliminate the risk, so
we probably should.

Since px_find_digest() calls palloc() later in the function there is a
slim possibility of memory leaks.

Yep. That palloc() would be easy to move to before the EVP_MD_CTX_new()
call. And some of the calls to px_find_digest() could likewise be
rearranged. But there are some more complicated callers. pgp_encrypt(),
for example, builds a pipeline of multiple "mbuf" filters, and one of
those filters uses px_find_digest().

How do we generally handle that things
not allocated with palloc() may leak when something calls elog()?

There's the ResourceOwner mechanism, see src/backend/utils/resowner/.
That would be the proper way to do this. Call
RegisterResourceReleaseCallback() when the context is allocated, and
have the callback free it. One pitfall to watch out for is that
RegisterResourceReleaseCallback() itself calls palloc(), and can error
out, so you have to do things in such an order that you don't leak in
that case either.

Want to take a stab at that?

Another approach is put each allocated context in a list or array in a
global variable, and to register a callback to be called at
end-of-(sub)transaction, which closes all the contexts. But the resource
owner mechanism is probably easier.

There's also PG_TRY-CATCH, that you could maybe use in the callers of
px_find_digest(), to make sure they call px_free_digest() even on error.
But that also seems difficult to use with the pgp_encrypt() pipeline.

I have attached new versions of the patches which are rebased on master,
with slightly improves error handling in px_find_digest(), and handles
the deprecation of ASN1_STRING_data().

Thanks!

PS. I just remembered that I've wanted to refactor the pgcrypto calls
for symmetric encryption to use the newer EVP API for some time, and
even posted a patch for that
(/messages/by-id/561274F1.1030000@iki.fi). I
dropped the ball back then, but I think I'll go ahead and do that now,
once we get these other OpenSSL changes in.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#35Andreas Karlsson
andreas@proxel.se
In reply to: Heikki Linnakangas (#34)
1 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 08/30/2016 08:42 AM, Heikki Linnakangas wrote:

There's the ResourceOwner mechanism, see src/backend/utils/resowner/.
That would be the proper way to do this. Call
RegisterResourceReleaseCallback() when the context is allocated, and
have the callback free it. One pitfall to watch out for is that
RegisterResourceReleaseCallback() itself calls palloc(), and can error
out, so you have to do things in such an order that you don't leak in
that case either.

Want to take a stab at that?

Another approach is put each allocated context in a list or array in a
global variable, and to register a callback to be called at
end-of-(sub)transaction, which closes all the contexts. But the resource
owner mechanism is probably easier.

There's also PG_TRY-CATCH, that you could maybe use in the callers of
px_find_digest(), to make sure they call px_free_digest() even on error.
But that also seems difficult to use with the pgp_encrypt() pipeline.

Sure, I have attached a patch where I try to use it.

PS. I just remembered that I've wanted to refactor the pgcrypto calls
for symmetric encryption to use the newer EVP API for some time, and
even posted a patch for that
(/messages/by-id/561274F1.1030000@iki.fi). I
dropped the ball back then, but I think I'll go ahead and do that now,
once we get these other OpenSSL changes in.

Nice!

Andreas

Attachments:

0004-Add-callback-for-always-freeing-digest-context-v4.patchtext/x-patch; name=0004-Add-callback-for-always-freeing-digest-context-v4.patchDownload
From 0afeb5e075028339f28c2c2d7b407c1bcc85c4be Mon Sep 17 00:00:00 2001
From: Andreas Karlsson <andreas@proxel.se>
Date: Sun, 4 Sep 2016 18:44:49 +0200
Subject: [PATCH] Add callback for always freeing digest context

---
 contrib/pgcrypto/openssl.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 6586d32..68a6956 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -32,6 +32,7 @@
 #include "postgres.h"
 
 #include "px.h"
+#include "utils/resowner.h"
 
 #include <openssl/evp.h>
 #include <openssl/blowfish.h>
@@ -98,16 +99,30 @@ digest_finish(PX_MD *h, uint8 *dst)
 }
 
 static void
+digest_ctx_free_callback(ResourceReleasePhase phase,
+						 bool isCommit,
+						 bool isTopLevel,
+						 void *arg)
+{
+	OSSLDigest *digest = arg;
+
+	EVP_MD_CTX_destroy(digest->ctx);
+	UnregisterResourceReleaseCallback(digest_ctx_free_callback, digest);
+}
+
+static void
 digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
 	EVP_MD_CTX_destroy(digest->ctx);
+	UnregisterResourceReleaseCallback(digest_ctx_free_callback, digest);
 
 	px_free(digest);
 	px_free(h);
 }
 
+
 static int	px_openssl_initialized = 0;
 
 /* PUBLIC functions */
@@ -131,6 +146,9 @@ px_find_digest(const char *name, PX_MD **res)
 
 	digest = px_alloc(sizeof(*digest));
 	digest->algo = md;
+	digest->ctx = NULL;
+
+	RegisterResourceReleaseCallback(digest_ctx_free_callback, digest);
 
 	digest->ctx = EVP_MD_CTX_create();
 	if (digest->ctx == NULL)
@@ -139,6 +157,7 @@ px_find_digest(const char *name, PX_MD **res)
 	EVP_MD_CTX_init(digest->ctx);
 	if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0) {
 		EVP_MD_CTX_destroy(digest->ctx);
+		UnregisterResourceReleaseCallback(digest_ctx_free_callback, digest);
 		return -1;
 	}
 
-- 
2.9.3

#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andreas Karlsson (#35)
Re: OpenSSL 1.1 breaks configure and more

Andreas Karlsson <andreas@proxel.se> writes:

On 08/30/2016 08:42 AM, Heikki Linnakangas wrote:

PS. I just remembered that I've wanted to refactor the pgcrypto calls
for symmetric encryption to use the newer EVP API for some time, and
even posted a patch for that
(/messages/by-id/561274F1.1030000@iki.fi). I
dropped the ball back then, but I think I'll go ahead and do that now,
once we get these other OpenSSL changes in.

Nice!

Judging by the number of people who have popped up recently with their
own OpenSSL 1.1 patches, I think there is going to be a lot of demand for
back-patching some sort of 1.1 support into our back branches. All this
talk of refactoring does not sound very back-patchable. Should we be
thinking of what we can extract that is back-patchable?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#37Andreas Karlsson
andreas@proxel.se
In reply to: Tom Lane (#36)
Re: OpenSSL 1.1 breaks configure and more

On 09/05/2016 02:23 AM, Tom Lane wrote:

Judging by the number of people who have popped up recently with their
own OpenSSL 1.1 patches, I think there is going to be a lot of demand for
back-patching some sort of 1.1 support into our back branches. All this
talk of refactoring does not sound very back-patchable. Should we be
thinking of what we can extract that is back-patchable?

My idea is that the first of my four patches contains the minimum
changes needed to add support for 1.1 and tries to do as little
refactoring as possible while the other patches refactor things. I am
not sure about if anything of the other patches should be backpatched.

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#38Michael Paquier
michael.paquier@gmail.com
In reply to: Andreas Karlsson (#37)
Re: OpenSSL 1.1 breaks configure and more

On Mon, Sep 5, 2016 at 9:32 AM, Andreas Karlsson <andreas@proxel.se> wrote:

On 09/05/2016 02:23 AM, Tom Lane wrote:

Judging by the number of people who have popped up recently with their
own OpenSSL 1.1 patches, I think there is going to be a lot of demand for
back-patching some sort of 1.1 support into our back branches. All this
talk of refactoring does not sound very back-patchable. Should we be
thinking of what we can extract that is back-patchable?

My idea is that the first of my four patches contains the minimum changes
needed to add support for 1.1 and tries to do as little refactoring as
possible while the other patches refactor things. I am not sure about if
anything of the other patches should be backpatched.

From what I can see of the 4 patches proposed, those are not that much
invasive, so a backpatch of those is really doable. But yes let's keep
the refactoring only for HEAD. That's definitely the safest approach.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#39Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Andreas Karlsson (#35)
2 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 09/05/2016 03:12 AM, Andreas Karlsson wrote:

On 08/30/2016 08:42 AM, Heikki Linnakangas wrote:

There's the ResourceOwner mechanism, see src/backend/utils/resowner/.
That would be the proper way to do this. Call
RegisterResourceReleaseCallback() when the context is allocated, and
have the callback free it. One pitfall to watch out for is that
RegisterResourceReleaseCallback() itself calls palloc(), and can error
out, so you have to do things in such an order that you don't leak in
that case either.

Want to take a stab at that?

Another approach is put each allocated context in a list or array in a
global variable, and to register a callback to be called at
end-of-(sub)transaction, which closes all the contexts. But the resource
owner mechanism is probably easier.

There's also PG_TRY-CATCH, that you could maybe use in the callers of
px_find_digest(), to make sure they call px_free_digest() even on error.
But that also seems difficult to use with the pgp_encrypt() pipeline.

Sure, I have attached a patch where I try to use it.

Thanks! Unfortunately the callback mechanism is a bit more complicated
to use than that. The list of registered callbacks is global, so the
callback gets called for every ResourceOwner that's closed, not just the
one that was active when you registered it. Also, unregistering the
callback from within the callback is not safe. I fixed those things in
the (first) attached patch.

On 09/05/2016 03:23 AM, Tom Lane wrote:

Judging by the number of people who have popped up recently with their
own OpenSSL 1.1 patches, I think there is going to be a lot of demand for
back-patching some sort of 1.1 support into our back branches. All this
talk of refactoring does not sound very back-patchable. Should we be
thinking of what we can extract that is back-patchable?

Yes, I think you're right.

The minimum set of changes is the first of the attached patches. It
includes Andreas' first patch, with the configure changes and other
changes needed to compile, and a working version of the resourceowner
callback mechanism to make sure we don't leak OpenSSL handles in pgcrypto.

Maybe we could get away without the resourceowner mechanism, and just
accept the minor memory leaks on the rare error case (out-of-memory
might be the only situation where that happen). Or #ifdef it so that we
keep the old embed-in-palloced-struct approach for OpenSSL versions
older than 1.1. But on the whole, I'd prefer to keep the code the same
in all branches.

The second patch attached here includes Andreas' second and third
patches, to silence deprecation warnings. That's not strictly required,
but seems safe enough that I think we should back-patch that too. It
needs one additional #ifdef version check in generate_dh_params(), if we
want it to still work with OpenSSL 0.9.7, but that's easy. I'm assuming
we want to still support it in back-branches, even though we just
dropped it from master.

- Heikki

Attachments:

0001-Fix-compilation-with-OpenSSL-1.1.patchapplication/x-patch; name=0001-Fix-compilation-with-OpenSSL-1.1.patchDownload
From 4534d01a0471d7378100cddebb5641800950e6c6 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 5 Sep 2016 13:46:15 +0300
Subject: [PATCH 1/2] Fix compilation with OpenSSL 1.1.

- Check for SSL_new in configure, now that SSL_library_init is a macro.
- Do not access struct members directly. This includes some new code in
  pgcrypto, to use the resource owner mechanism to ensure that we don't
  leak OpenSSL handles, now that we don't palloc them as part of other
  structs anymore.
- RAND_SSLeay was renamed to RAND_OpenSSL

Andreas Karlsson, with some changes by me.
---
 configure                                |  44 ++++++------
 configure.in                             |   4 +-
 contrib/pgcrypto/openssl.c               | 115 +++++++++++++++++++++++++++----
 contrib/sslinfo/sslinfo.c                |  14 +---
 src/backend/libpq/be-secure-openssl.c    |  39 +++++++----
 src/interfaces/libpq/fe-secure-openssl.c |  39 +++++++----
 6 files changed, 181 insertions(+), 74 deletions(-)

diff --git a/configure b/configure
index 45c8eef..caf6f26 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 c878b4e..c426806 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/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index ffab5d2..0247ebb 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -41,6 +41,9 @@
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
+#include "utils/memutils.h"
+#include "utils/resowner.h"
+
 /*
  * Max lengths we might want to handle.
  */
@@ -51,18 +54,73 @@
  * Hashes
  */
 
+/*
+ * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
+ * objects in a linked list, allocated in TopMemoryContext. We use the
+ * ResourceOwner mechanism to free them on abort.
+ */
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX *ctx;
+
+	ResourceOwner owner;
+	struct OSSLDigest *next;
+	struct OSSLDigest *prev;
 } OSSLDigest;
 
+static OSSLDigest *open_digests = NULL;
+static bool		resowner_callback_registered = false;
+
+static void
+free_openssldigest(OSSLDigest *digest)
+{
+	EVP_MD_CTX_destroy(digest->ctx);
+	if (digest->prev)
+		digest->prev->next = digest->next;
+	else
+		open_digests = digest->next;
+	if (digest->next)
+		digest->next->prev = digest->prev;
+	pfree(digest);
+}
+
+/*
+ * Close any open OpenSSL handles on abort.
+ */
+static void
+digest_free_callback(ResourceReleasePhase phase,
+					 bool isCommit,
+					 bool isTopLevel,
+					 void *arg)
+{
+	OSSLDigest *curr;
+	OSSLDigest *next;
+
+	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
+		return;
+
+	next = open_digests;
+	while (next)
+	{
+		curr = next;
+		next = curr->next;
+
+		if (curr->owner == CurrentResourceOwner)
+		{
+			if (isCommit)
+				elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
+			free_openssldigest(curr);
+		}
+	}
+}
+
 static unsigned
 digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -70,7 +128,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -78,7 +136,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -86,7 +144,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -94,7 +152,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -102,9 +160,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
-
-	px_free(digest);
+	free_openssldigest(digest);
 	px_free(h);
 }
 
@@ -116,6 +172,7 @@ int
 px_find_digest(const char *name, PX_MD **res)
 {
 	const EVP_MD *md;
+	EVP_MD_CTX *ctx;
 	PX_MD	   *h;
 	OSSLDigest *digest;
 
@@ -125,17 +182,43 @@ px_find_digest(const char *name, PX_MD **res)
 		OpenSSL_add_all_algorithms();
 	}
 
+	if (!resowner_callback_registered)
+	{
+		RegisterResourceReleaseCallback(digest_free_callback, NULL);
+		resowner_callback_registered = true;
+	}
+
 	md = EVP_get_digestbyname(name);
 	if (md == NULL)
 		return PXE_NO_HASH;
 
-	digest = px_alloc(sizeof(*digest));
-	digest->algo = md;
+	/*
+	 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
+	 * The order is crucial, to make sure we don't leak anything on out-of-memory
+	 * or other error.
+	 */
+	digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	ctx = EVP_MD_CTX_create();
+	if (!ctx)
+	{
+		pfree(digest);
+		return -1;
+	}
+	if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
+	{
+		pfree(digest);
 		return -1;
+	}
+
+	digest->algo = md;
+	digest->ctx = ctx;
+	digest->owner = CurrentResourceOwner;
+	digest->next = open_digests;
+	digest->prev = NULL;
+	open_digests = digest;
 
+	/* The PX_MD object is allocated in the current memory context. */
 	h = px_alloc(sizeof(*h));
 	h->result_size = digest_result_size;
 	h->block_size = digest_block_size;
@@ -831,6 +914,10 @@ px_find_cipher(const char *name, PX_Cipher **res)
 
 static int	openssl_random_init = 0;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RAND_OpenSSL RAND_SSLeay
+#endif
+
 /*
  * OpenSSL random should re-feeded occasionally. From /dev/urandom
  * preferably.
@@ -839,7 +926,7 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
-		RAND_set_rand_method(RAND_SSLeay());
+		RAND_set_rand_method(RAND_OpenSSL());
 	openssl_random_init = 1;
 }
 
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 82a4c1b..a4b0f9b 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	SSLExtensionInfoContext *fctx;
 
-	STACK_OF(X509_EXTENSION) *ext_stack = NULL;
-
 	if (SRF_IS_FIRSTCALL())
 	{
 
@@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("function returning record called in context that cannot accept type record")));
 		fctx->tupdesc = BlessTupleDesc(tupdesc);
 
-		/* Get all extensions of certificate */
-		if (cert && cert->cert_info)
-			ext_stack = cert->cert_info->extensions;
-
 		/* Set max_calls as a count of extensions in certificate */
 		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
 
-		if (cert != NULL &&
-			ext_stack != NULL &&
-			max_calls > 0)
+		if (max_calls > 0)
 		{
 			/* got results, keep track of them */
 			funcctx->max_calls = max_calls;
@@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	max_calls = funcctx->max_calls;
 	fctx = funcctx->user_fctx;
 
-	ext_stack = cert->cert_info->extensions;
-
 	/* do while there are more left to send */
 	if (call_cntr < max_calls)
 	{
@@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("could not create OpenSSL BIO structure")));
 
 		/* Get the extension from the certificate */
-		ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
+		ext = X509_get_ext(cert, call_cntr);
 		obj = X509_EXTENSION_get_object(ext);
 
 		/* Get the extension name */
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index bb0d2d9..f4aaf40 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -667,8 +667,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 OPENSSL_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)
@@ -677,7 +681,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)
 		{
@@ -697,7 +701,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)
 	{
@@ -714,14 +718,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 OPENSSL_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 */
@@ -738,8 +754,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 d871612..12cab74 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1617,15 +1617,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 OPENSSL_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)
 	{
@@ -1655,7 +1659,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)
 	{
@@ -1683,14 +1687,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 OPENSSL_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 */
@@ -1706,8 +1722,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.9.3

0002-Silence-deprecation-warnings-with-OpenSSL-1.1.patchapplication/x-patch; name=0002-Silence-deprecation-warnings-with-OpenSSL-1.1.patchDownload
From 3117137786c7eb927950d2b5d2b2d113e9a9faec Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 5 Sep 2016 14:40:38 +0300
Subject: [PATCH 2/2] Silence deprecation warnings with OpenSSL 1.1.

Andreas Karlsson
---
 contrib/pgcrypto/internal.c              |  9 ---------
 contrib/pgcrypto/openssl.c               | 15 ---------------
 contrib/pgcrypto/pgcrypto.c              |  2 +-
 contrib/pgcrypto/pgp-s2k.c               |  6 +++---
 contrib/pgcrypto/px-crypt.c              |  2 +-
 contrib/pgcrypto/px.h                    |  1 -
 src/backend/libpq/be-secure-openssl.c    | 21 ++++++++++++++++++++-
 src/interfaces/libpq/fe-secure-openssl.c | 25 +++++++++++++++++--------
 8 files changed, 42 insertions(+), 39 deletions(-)

diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 0247ebb..ecb74c1 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -946,21 +946,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 9937d15..3551d44 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
 		case PGP_S2K_SIMPLE:
 			break;
 		case PGP_S2K_SALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case PGP_S2K_ISALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_s2k_iter(tmp, count);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 0f6bbd7..9174e13 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index f4aaf40..16cf86e 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -164,9 +164,13 @@ be_tls_init(void)
 
 	if (!SSL_context)
 	{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 		OPENSSL_config(NULL);
 		SSL_library_init();
 		SSL_load_error_strings();
+#endif
 
 		/*
 		 * We use SSLv23_method() because it can negotiate use of the highest
@@ -848,6 +852,21 @@ load_dh_buffer(const char *buffer, size_t len)
 	return dh;
 }
 
+static DH  *
+generate_dh_params(int prime_len, int generator)
+{
+	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;
+}
+
 /*
  *	Generate an ephemeral DH key.  Because this can take a long
  *	time to compute, we can use precomputed parameters of the
@@ -917,7 +936,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 12cab74..388215f 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -506,6 +506,9 @@ wildcard_certificate_match(const char *pattern, const char *string)
 	return 1;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define ASN1_STRING_get0_data ASN1_STRING_data
+#endif
 
 /*
  * Check if a name from a server's certificate matches the peer's hostname.
@@ -520,10 +523,10 @@ static int
 verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 										  char **store_name)
 {
-	int			len;
-	char	   *name;
-	unsigned char *namedata;
-	int			result;
+	int						len;
+	char			  	   *name;
+	const unsigned char    *namedata;
+	int						result;
 
 	*store_name = NULL;
 
@@ -541,7 +544,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 	 * There is no guarantee the string returned from the certificate is
 	 * NULL-terminated, so make a copy that is.
 	 */
-	namedata = ASN1_STRING_data(name_entry);
+	namedata = ASN1_STRING_get0_data(name_entry);
 	len = ASN1_STRING_length(name_entry);
 	name = malloc(len + 1);
 	if (name == NULL)
@@ -729,7 +732,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
 	return found_match && !got_error;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 /*
  *	Callback functions for OpenSSL internal locking
  */
@@ -761,7 +764,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 && OPENSSL_VERSION_NUMBER < 0x10100000L */
 
 /*
  * Initialize SSL system, in particular creating the SSL_context object
@@ -800,6 +803,7 @@ pgtls_init(PGconn *conn)
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return -1;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	if (pq_init_crypto_lib)
 	{
 		/*
@@ -840,15 +844,20 @@ pgtls_init(PGconn *conn)
 				CRYPTO_set_locking_callback(pq_lockingcallback);
 		}
 	}
+#endif
 #endif   /* ENABLE_THREAD_SAFETY */
 
 	if (!SSL_context)
 	{
 		if (pq_init_ssl_lib)
 		{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 			OPENSSL_config(NULL);
 			SSL_library_init();
 			SSL_load_error_strings();
+#endif
 		}
 
 		/*
@@ -902,7 +911,7 @@ pgtls_init(PGconn *conn)
 static void
 destroy_ssl_system(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 	/* Mutex is created in initialize_ssl_system() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
-- 
2.9.3

#40Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Heikki Linnakangas (#39)
1 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 09/05/2016 02:52 PM, Heikki Linnakangas wrote:

On 09/05/2016 03:23 AM, Tom Lane wrote:

Judging by the number of people who have popped up recently with their
own OpenSSL 1.1 patches, I think there is going to be a lot of demand for
back-patching some sort of 1.1 support into our back branches. All this
talk of refactoring does not sound very back-patchable. Should we be
thinking of what we can extract that is back-patchable?

Yes, I think you're right.

I planned to commit this today, but while reading through it and
testing, I ended up doing a bunch more changes, so this deserves another
round of review.

Changes since last version:

* Added more error checks to the my_BIO_s_socket() function. Check for
NULL result from malloc(). Check the return code of BIO_meth_set_*()
functions; looking at OpenSSL sources, they always succeed, but all the
test/example programs that come with OpenSSL do check them.

* Use BIO_get_new_index() to get the index number for the wrapper BIO.

* Also call BIO_meth_set_puts(). It was missing in previous patch versions.

* Fixed src/test/ssl test suite to also work with OpenSSL 1.1.0.

* Changed all references (in existing code) to SSLEAY_VERSION_NUMBER
into OPENSSL_VERSION_NUMBER, for consistency.

* Squashed all into one patch.

I intend to apply this to all supported branches, so please have a look!
This is now against REL9_6_STABLE, but there should be little difference
between branches in the code that this touches.

- Heikki

Attachments:

0001-Support-OpenSSL-1.1.0.patchtext/x-diff; name=0001-Support-OpenSSL-1.1.0.patchDownload
From d535c3941c66600f2e1716dfbdc1f1fff7eebbe0 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 12 Sep 2016 19:48:48 +0300
Subject: [PATCH 1/1] Support OpenSSL 1.1.0.

Changes needed to build at all:

- Check for SSL_new in configure, now that SSL_library_init is a macro.
- Do not access struct members directly. This includes some new code in
  pgcrypto, to use the resource owner mechanism to ensure that we don't
  leak OpenSSL handles, now that we can't embed them in other structs
  anymore.
- RAND_SSLeay() -> RAND_OpenSSL()

Changes that were needed to silence deprecation warnings, but were not
strictly necessary:

- RAND_pseudo_bytes() -> RAND_bytes().
- SSL_library_init() and OpenSSL_config() -> OPENSSL_init_ssl()
- ASN1_STRING_data() -> ASN1_STRING_get0_data()
- DH_generate_parameters() -> DH_generate_parameters()
- Locking callbacks are not needed with OpenSSL 1.1.0 anymore. (Good
  riddance!)

Also change references to SSLEAY_VERSION_NUMBER with OPENSSL_VERSION_NUMBER,
for the sake of consistency. OPENSSL_VERSION_NUMBER has existed since time
immemorial.

Fix SSL test suite to work with OpenSSL 1.1.0. CA certificates must have
the "CA:true" basic constraint extension now, or OpenSSL will refuse them.
Regenerate the test certificates with that. The "openssl" binary, used to
generate the certificates, is also now more picky, and throws an error
if an X509 extension is specified in "req_extensions", but that section
is empty.

Backpatch to all supported branches, per popular demand. In back-branches,
we still support OpenSSL 0.9.7 and above. OpenSSL 0.9.6 should still work
too, but I didn't test it. In master, we only support 0.9.8 and above.

Patch by Andreas Karlsson, with additional changes by me.

Discussion: <20160627151604.GD1051@msg.df7cb.de>
---
 configure                                      |  44 ++++-----
 configure.in                                   |   4 +-
 contrib/pgcrypto/internal.c                    |   9 --
 contrib/pgcrypto/openssl.c                     | 130 +++++++++++++++++++------
 contrib/pgcrypto/pgcrypto.c                    |   2 +-
 contrib/pgcrypto/pgp-s2k.c                     |   6 +-
 contrib/pgcrypto/px-crypt.c                    |   2 +-
 contrib/pgcrypto/px.h                          |   1 -
 contrib/sslinfo/sslinfo.c                      |  14 +--
 src/backend/libpq/be-secure-openssl.c          | 101 +++++++++++++++----
 src/interfaces/libpq/fe-secure-openssl.c       |  96 +++++++++++++-----
 src/interfaces/libpq/libpq-int.h               |   2 +-
 src/test/ssl/Makefile                          |   5 +-
 src/test/ssl/cas.config                        |   7 +-
 src/test/ssl/root_ca.config                    |   4 +
 src/test/ssl/server-cn-only.config             |   1 -
 src/test/ssl/server-no-names.config            |   1 -
 src/test/ssl/server-revoked.config             |   1 -
 src/test/ssl/ssl/both-cas-1.crt                |  67 ++++++-------
 src/test/ssl/ssl/both-cas-2.crt                |  67 ++++++-------
 src/test/ssl/ssl/client-revoked.crt            |  16 +--
 src/test/ssl/ssl/client-revoked.key            |  26 ++---
 src/test/ssl/ssl/client.crl                    |  12 +--
 src/test/ssl/ssl/client.crt                    |  16 +--
 src/test/ssl/ssl/client.key                    |  26 ++---
 src/test/ssl/ssl/client_ca.crt                 |  22 ++---
 src/test/ssl/ssl/client_ca.key                 |  26 ++---
 src/test/ssl/ssl/root+client.crl               |  22 ++---
 src/test/ssl/ssl/root+client_ca.crt            |  45 ++++-----
 src/test/ssl/ssl/root+server.crl               |  22 ++---
 src/test/ssl/ssl/root+server_ca.crt            |  45 ++++-----
 src/test/ssl/ssl/root.crl                      |  10 +-
 src/test/ssl/ssl/root_ca.crt                   |  23 ++---
 src/test/ssl/ssl/root_ca.key                   |  26 ++---
 src/test/ssl/ssl/server-cn-and-alt-names.crt   |  18 ++--
 src/test/ssl/ssl/server-cn-and-alt-names.key   |  26 ++---
 src/test/ssl/ssl/server-cn-only.crt            |  16 +--
 src/test/ssl/ssl/server-cn-only.key            |  26 ++---
 src/test/ssl/ssl/server-multiple-alt-names.crt |  16 +--
 src/test/ssl/ssl/server-multiple-alt-names.key |  26 ++---
 src/test/ssl/ssl/server-no-names.crt           |  14 +--
 src/test/ssl/ssl/server-no-names.key           |  26 ++---
 src/test/ssl/ssl/server-revoked.crt            |  16 +--
 src/test/ssl/ssl/server-revoked.key            |  26 ++---
 src/test/ssl/ssl/server-single-alt-name.crt    |  14 +--
 src/test/ssl/ssl/server-single-alt-name.key    |  26 ++---
 src/test/ssl/ssl/server-ss.crt                 |  16 +--
 src/test/ssl/ssl/server-ss.key                 |  26 ++---
 src/test/ssl/ssl/server.crl                    |  12 +--
 src/test/ssl/ssl/server_ca.crt                 |  22 ++---
 src/test/ssl/ssl/server_ca.key                 |  26 ++---
 51 files changed, 714 insertions(+), 539 deletions(-)

diff --git a/configure b/configure
index 9f09e48..778bbf0 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 f5deb5d..09ba479 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/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 976af70..cee2afe 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -40,6 +40,9 @@
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
+#include "utils/memutils.h"
+#include "utils/resowner.h"
+
 /*
  * Max lengths we might want to handle.
  */
@@ -199,18 +202,73 @@ compat_find_digest(const char *name, PX_MD **res)
  * Hashes
  */
 
+/*
+ * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
+ * objects in a linked list, allocated in TopMemoryContext. We use the
+ * ResourceOwner mechanism to free them on abort.
+ */
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX *ctx;
+
+	ResourceOwner owner;
+	struct OSSLDigest *next;
+	struct OSSLDigest *prev;
 } OSSLDigest;
 
+static OSSLDigest *open_digests = NULL;
+static bool resowner_callback_registered = false;
+
+static void
+free_openssldigest(OSSLDigest *digest)
+{
+	EVP_MD_CTX_destroy(digest->ctx);
+	if (digest->prev)
+		digest->prev->next = digest->next;
+	else
+		open_digests = digest->next;
+	if (digest->next)
+		digest->next->prev = digest->prev;
+	pfree(digest);
+}
+
+/*
+ * Close any open OpenSSL handles on abort.
+ */
+static void
+digest_free_callback(ResourceReleasePhase phase,
+					 bool isCommit,
+					 bool isTopLevel,
+					 void *arg)
+{
+	OSSLDigest *curr;
+	OSSLDigest *next;
+
+	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
+		return;
+
+	next = open_digests;
+	while (next)
+	{
+		curr = next;
+		next = curr->next;
+
+		if (curr->owner == CurrentResourceOwner)
+		{
+			if (isCommit)
+				elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
+			free_openssldigest(curr);
+		}
+	}
+}
+
 static unsigned
 digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -218,7 +276,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -226,7 +284,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -234,7 +292,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -242,7 +300,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -250,9 +308,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
-
-	px_free(digest);
+	free_openssldigest(digest);
 	px_free(h);
 }
 
@@ -264,6 +320,7 @@ int
 px_find_digest(const char *name, PX_MD **res)
 {
 	const EVP_MD *md;
+	EVP_MD_CTX *ctx;
 	PX_MD	   *h;
 	OSSLDigest *digest;
 
@@ -273,17 +330,43 @@ px_find_digest(const char *name, PX_MD **res)
 		OpenSSL_add_all_algorithms();
 	}
 
+	if (!resowner_callback_registered)
+	{
+		RegisterResourceReleaseCallback(digest_free_callback, NULL);
+		resowner_callback_registered = true;
+	}
+
 	md = EVP_get_digestbyname(name);
 	if (md == NULL)
 		return compat_find_digest(name, res);
 
-	digest = px_alloc(sizeof(*digest));
-	digest->algo = md;
+	/*
+	 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
+	 * The order is crucial, to make sure we don't leak anything on
+	 * out-of-memory or other error.
+	 */
+	digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	ctx = EVP_MD_CTX_create();
+	if (!ctx)
+	{
+		pfree(digest);
 		return -1;
+	}
+	if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
+	{
+		pfree(digest);
+		return -1;
+	}
+
+	digest->algo = md;
+	digest->ctx = ctx;
+	digest->owner = CurrentResourceOwner;
+	digest->next = open_digests;
+	digest->prev = NULL;
+	open_digests = digest;
 
+	/* The PX_MD object is allocated in the current memory context. */
 	h = px_alloc(sizeof(*h));
 	h->result_size = digest_result_size;
 	h->block_size = digest_block_size;
@@ -979,6 +1062,10 @@ px_find_cipher(const char *name, PX_Cipher **res)
 
 static int	openssl_random_init = 0;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RAND_OpenSSL RAND_SSLeay
+#endif
+
 /*
  * OpenSSL random should re-feeded occasionally. From /dev/urandom
  * preferably.
@@ -987,7 +1074,7 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
-		RAND_set_rand_method(RAND_SSLeay());
+		RAND_set_rand_method(RAND_OpenSSL());
 	openssl_random_init = 1;
 }
 
@@ -1007,21 +1094,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 9937d15..3551d44 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
 		case PGP_S2K_SIMPLE:
 			break;
 		case PGP_S2K_SALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case PGP_S2K_ISALTED:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_s2k_iter(tmp, count);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 0f6bbd7..9174e13 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c
index 82a4c1b..a4b0f9b 100644
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	MemoryContext oldcontext;
 	SSLExtensionInfoContext *fctx;
 
-	STACK_OF(X509_EXTENSION) *ext_stack = NULL;
-
 	if (SRF_IS_FIRSTCALL())
 	{
 
@@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("function returning record called in context that cannot accept type record")));
 		fctx->tupdesc = BlessTupleDesc(tupdesc);
 
-		/* Get all extensions of certificate */
-		if (cert && cert->cert_info)
-			ext_stack = cert->cert_info->extensions;
-
 		/* Set max_calls as a count of extensions in certificate */
 		max_calls = cert != NULL ? X509_get_ext_count(cert) : 0;
 
-		if (cert != NULL &&
-			ext_stack != NULL &&
-			max_calls > 0)
+		if (max_calls > 0)
 		{
 			/* got results, keep track of them */
 			funcctx->max_calls = max_calls;
@@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 	max_calls = funcctx->max_calls;
 	fctx = funcctx->user_fctx;
 
-	ext_stack = cert->cert_info->extensions;
-
 	/* do while there are more left to send */
 	if (call_cntr < max_calls)
 	{
@@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS)
 					 errmsg("could not create OpenSSL BIO structure")));
 
 		/* Get the extension from the certificate */
-		ext = sk_X509_EXTENSION_value(ext_stack, call_cntr);
+		ext = X509_get_ext(cert, call_cntr);
 		obj = X509_EXTENSION_get_object(ext);
 
 		/* Get the extension name */
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index f6adb15..9ffb5af 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -53,7 +53,7 @@
 
 #include <openssl/ssl.h>
 #include <openssl/dh.h>
-#if SSLEAY_VERSION_NUMBER >= 0x0907000L
+#if OPENSSL_VERSION_NUMBER >= 0x0907000L
 #include <openssl/conf.h>
 #endif
 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_ECDH)
@@ -74,6 +74,7 @@ static int	my_SSL_set_fd(Port *port, int fd);
 
 static DH  *load_dh_file(int keylength);
 static DH  *load_dh_buffer(const char *, size_t);
+static DH  *generate_dh_parameters(int prime_len, int generator);
 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
 static int	verify_cb(int, X509_STORE_CTX *);
 static void info_cb(const SSL *ssl, int type, int args);
@@ -166,11 +167,15 @@ be_tls_init(void)
 
 	if (!SSL_context)
 	{
-#if SSLEAY_VERSION_NUMBER >= 0x0907000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
+#if OPENSSL_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
@@ -673,8 +678,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 OPENSSL_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 +692,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 +712,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 +729,41 @@ 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 OPENSSL_VERSION_NUMBER >= 0x10100000L
+		int			my_bio_index;
+
+		my_bio_index = BIO_get_new_index();
+		if (my_bio_index == -1)
+			return NULL;
+		my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
+		if (!my_bio_methods)
+			return NULL;
+		if (!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_puts(my_bio_methods, BIO_meth_get_puts(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)))
+		{
+			BIO_meth_free(my_bio_methods);
+			my_bio_methods = NULL;
+			return NULL;
+		}
+#else
+		my_bio_methods = malloc(sizeof(BIO_METHOD));
+		if (!my_bio_methods)
+			return NULL;
+		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 */
@@ -735,17 +771,23 @@ static int
 my_SSL_set_fd(Port *port, int fd)
 {
 	int			ret = 0;
-	BIO		   *bio = NULL;
+	BIO		   *bio;
+	BIO_METHOD *bio_method;
 
-	bio = BIO_new(my_BIO_s_socket());
+	bio_method = my_BIO_s_socket();
+	if (bio_method == NULL)
+	{
+		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+		goto err;
+	}
+	bio = BIO_new(bio_method);
 
 	if (bio == NULL)
 	{
 		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);
@@ -840,6 +882,31 @@ load_dh_buffer(const char *buffer, size_t len)
 }
 
 /*
+ *	Generate DH parameters.
+ *
+ *	Last resort if we can't load precomputed nor hardcoded
+ *	parameters.
+ */
+static DH  *
+generate_dh_parameters(int prime_len, int generator)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+	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
  *	common key sizes.
@@ -908,7 +975,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_parameters(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 f6ce1c7..5f279ac 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -54,7 +54,7 @@
 #endif
 
 #include <openssl/ssl.h>
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
 #include <openssl/conf.h>
 #endif
 #ifdef USE_SSL_ENGINE
@@ -508,6 +508,9 @@ wildcard_certificate_match(const char *pattern, const char *string)
 	return 1;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define ASN1_STRING_get0_data ASN1_STRING_data
+#endif
 
 /*
  * Check if a name from a server's certificate matches the peer's hostname.
@@ -524,7 +527,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 {
 	int			len;
 	char	   *name;
-	unsigned char *namedata;
+	const unsigned char *namedata;
 	int			result;
 
 	*store_name = NULL;
@@ -543,7 +546,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
 	 * There is no guarantee the string returned from the certificate is
 	 * NULL-terminated, so make a copy that is.
 	 */
-	namedata = ASN1_STRING_data(name_entry);
+	namedata = ASN1_STRING_get0_data(name_entry);
 	len = ASN1_STRING_length(name_entry);
 	name = malloc(len + 1);
 	if (name == NULL)
@@ -731,9 +734,10 @@ verify_peer_name_matches_certificate(PGconn *conn)
 	return found_match && !got_error;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 /*
- *	Callback functions for OpenSSL internal locking
+ *	Callback functions for OpenSSL internal locking. (OpenSSL 1.1.0
+ *	does its own locking, and doesn't need these anymore.)
  */
 
 static unsigned long
@@ -763,7 +767,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 && OPENSSL_VERSION_NUMBER < 0x10100000L */
 
 /*
  * Initialize SSL system, in particular creating the SSL_context object
@@ -802,6 +806,7 @@ pgtls_init(PGconn *conn)
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return -1;
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	if (pq_init_crypto_lib)
 	{
 		/*
@@ -842,13 +847,16 @@ pgtls_init(PGconn *conn)
 				CRYPTO_set_locking_callback(pq_lockingcallback);
 		}
 	}
+#endif   /* OPENSSL_VERSION_NUMBER < 0x10100000L */
 #endif   /* ENABLE_THREAD_SAFETY */
 
 	if (!SSL_context)
 	{
 		if (pq_init_ssl_lib)
 		{
-#if SSLEAY_VERSION_NUMBER >= 0x00907000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#elif OPENSSL_VERSION_NUMBER >= 0x00907000L
 			OPENSSL_config(NULL);
 #endif
 			SSL_library_init();
@@ -901,12 +909,13 @@ pgtls_init(PGconn *conn)
  *	if we had any.)
  *
  *	Callbacks are only set when we're compiled in threadsafe mode, so
- *	we only need to remove them in this case.
+ *	we only need to remove them in this case. They are also not needed
+ *	with OpenSSL 1.1.0 anymore.
  */
 static void
 destroy_ssl_system(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L
 	/* Mutex is created in initialize_ssl_system() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
@@ -1621,15 +1630,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 OPENSSL_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 +1672,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 +1700,45 @@ 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 OPENSSL_VERSION_NUMBER >= 0x10100000L
+		int			my_bio_index;
+
+		my_bio_index = BIO_get_new_index();
+		if (my_bio_index == -1)
+			return NULL;
+		my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
+		if (!my_bio_methods)
+			return NULL;
+		/*
+		 * As of this writing, these functions never fail. But check anyway, like
+		 * OpenSSL's own examples do.
+		 */
+		if (!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_puts(my_bio_methods, BIO_meth_get_puts(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)))
+		{
+			BIO_meth_free(my_bio_methods);
+			my_bio_methods = NULL;
+			return NULL;
+		}
+#else
+		my_bio_methods = malloc(sizeof(BIO_METHOD));
+		if (!my_bio_methods)
+			return NULL;
+		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 */
@@ -1702,16 +1746,22 @@ static int
 my_SSL_set_fd(PGconn *conn, int fd)
 {
 	int			ret = 0;
-	BIO		   *bio = NULL;
+	BIO		   *bio;
+	BIO_METHOD *bio_method;
 
-	bio = BIO_new(my_BIO_s_socket());
+	bio_method = my_BIO_s_socket();
+	if (bio_method == NULL)
+	{
+		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+		goto err;
+	}
+	bio = BIO_new(bio_method);
 	if (bio == NULL)
 	{
 		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);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 1183323..df5e62d 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -77,7 +77,7 @@ typedef struct
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 #define USE_SSL_ENGINE
 #endif
 #endif   /* USE_OPENSSL */
diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile
index d8c4741..3d992ba 100644
--- a/src/test/ssl/Makefile
+++ b/src/test/ssl/Makefile
@@ -41,15 +41,16 @@ ssl/%.key:
 # Root CA certificate
 ssl/root_ca.crt: ssl/root_ca.key cas.config
 	touch ssl/root_ca-certindex
-	openssl req -new -out ssl/root_ca.crt -x509 -config cas.config -config root_ca.config -key ssl/root_ca.key -days 10000
+	openssl req -new -out ssl/root_ca.crt -x509 -config cas.config -config root_ca.config -key ssl/root_ca.key -days 10000 -extensions v3_ca
 	echo "01" > ssl/root_ca.srl
 
 # Client and server CAs
 ssl/%_ca.crt: ssl/%_ca.key %_ca.config ssl/root_ca.crt ssl/new_certs_dir
 	touch ssl/$*_ca-certindex
+	echo "unique_subject=no" > ssl/$*_ca-certindex.attr
 	openssl req -new -out ssl/temp_ca.crt -config cas.config -config $*_ca.config -key ssl/$*_ca.key
 # Sign the certificate with the root CA
-	openssl ca -name root_ca -batch -config cas.config -in ssl/temp_ca.crt -out ssl/temp_ca_signed.crt
+	openssl ca -name root_ca -batch -config cas.config -in ssl/temp_ca.crt -out ssl/temp_ca_signed.crt -extensions v3_ca
 	openssl x509 -in ssl/temp_ca_signed.crt -out ssl/$*_ca.crt # to keep just the PEM cert
 	rm ssl/temp_ca.crt ssl/temp_ca_signed.crt
 	echo "01" > ssl/$*_ca.srl
diff --git a/src/test/ssl/cas.config b/src/test/ssl/cas.config
index 9c6cbb9..013ceba 100644
--- a/src/test/ssl/cas.config
+++ b/src/test/ssl/cas.config
@@ -2,11 +2,10 @@
 
 [ req ]
 prompt                 = no
-req_extensions         = v3_req
 
-# For Subject Alternative Names
-[ v3_req ]
-subjectAltName = @alt_names
+# Extensions for CA certs
+[ v3_ca ]
+basicConstraints = CA:true
 
 # Root CA, used to sign the certificates of the intermediary server and
 # client CAs.
diff --git a/src/test/ssl/root_ca.config b/src/test/ssl/root_ca.config
index 72484d0..187a9b8 100644
--- a/src/test/ssl/root_ca.config
+++ b/src/test/ssl/root_ca.config
@@ -7,3 +7,7 @@ prompt                 = no
 
 [ req_distinguished_name ]
 CN                     = Test root CA for PostgreSQL SSL regression test suite
+
+# Extensions for CA certs
+[ v3_ca ]
+basicConstraints = CA:true
diff --git a/src/test/ssl/server-cn-only.config b/src/test/ssl/server-cn-only.config
index 7849d09..1e5d582 100644
--- a/src/test/ssl/server-cn-only.config
+++ b/src/test/ssl/server-cn-only.config
@@ -3,7 +3,6 @@
 
 [ req ]
 distinguished_name     = req_distinguished_name
-req_extensions         = v3_req
 prompt                 = no
 
 [ req_distinguished_name ]
diff --git a/src/test/ssl/server-no-names.config b/src/test/ssl/server-no-names.config
index 92cf779..2a71125 100644
--- a/src/test/ssl/server-no-names.config
+++ b/src/test/ssl/server-no-names.config
@@ -5,7 +5,6 @@
 
 [ req ]
 distinguished_name     = req_distinguished_name
-req_extensions         = v3_req
 prompt                 = no
 
 [ req_distinguished_name ]
diff --git a/src/test/ssl/server-revoked.config b/src/test/ssl/server-revoked.config
index 9924af8..47ef646 100644
--- a/src/test/ssl/server-revoked.config
+++ b/src/test/ssl/server-revoked.config
@@ -5,7 +5,6 @@
 
 [ req ]
 distinguished_name     = req_distinguished_name
-req_extensions         = v3_req
 prompt                 = no
 
 [ req_distinguished_name ]
diff --git a/src/test/ssl/ssl/both-cas-1.crt b/src/test/ssl/ssl/both-cas-1.crt
index abf4612..0e2a10a 100644
--- a/src/test/ssl/ssl/both-cas-1.crt
+++ b/src/test/ssl/ssl/both-cas-1.crt
@@ -1,39 +1,40 @@
 -----BEGIN CERTIFICATE-----
-MIIB9zCCAWACCQDrgvp38CAy8DANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVU
-ZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBz
-dWl0ZTAeFw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMEAxPjA8BgNVBAMM
-NVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0
-IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyTfGMPAjAylLr3G7c
-/QToCA3da5YZzdhd3TiQGugrJjWI4TzVB7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZl
-FLW9dMpa/8SY2TETvMTuXR5MOxyw6FMEKb3buolsIksCCQ1btEIrDZ+gv9SJXcdL
-ylU+VI1lKmn2fLNWWATzWrIUawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAF2T84iG
-zWKXu+3PysuPOn7RuRpMgYQKouQktErNJ8hM7Yqj3vu879zUkX1rP0HGnx7xQC3d
-nBkoJ7yNDR0MwQpWo1Dj1HLKNEY6ojKJgPd0+m8nG+02yUmmOjo0oMYzJx2DQy0u
-Y4qecEd6aDbqXTo+qOJ7Qm/U+U4kD9MTT6GD
+MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV
+BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0
+ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG
+A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u
+IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5
+qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8
+sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B
+MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE
+TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE
+TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1
+K5Y=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQIwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8wIYcmeePSXVufP/Hn/6ICEog
-IUXqSNls5QIJR7Sate4iKGGTDEsRTxI4oDgkOYtcQNuEeXMf6k3xo+PRR08IEQNk
-XKy1zUWds6UBFboD72SyuTE2lxJBg+xOAWgl7JSNA+g8e0Y+wfhfxGZgRuqVxVNP
-9sAsfCEzGKna1l46dQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD20Bmina/uXTLXO
-oPWgpMmKwQu7Q6DPXxItCUdWgK1k1D82brRjH+usrkrmCW5BQNXOC/0zJS22ioC1
-CJbhAujH3iPaV0C3xsVSf+bvTL6OMkwV/9x9OdDN+LI2auEt4S+fP5ZTVsTXt4wA
-A9cQIl2Qy88enZZAFKxrScFFlstp
+MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+
+19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd
+JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x
+6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI
+TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM
+ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQEwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDAYtajRx8vM6IB0SLZsAhTD0Y
-VHM+/+t0a4m3JXolJBbo9/B2/WAN0IH1E2zmlalLc3JBmGsH1a8U5ZlRow3p2ODL
-rFra9FbOl0wekmRFvZeaRln/99dpI5itVpL97QPHO8QMMK1IsyurFA5GfuPOBx9P
-i0MvzsT0tYsRvR929QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAJw4ngOYElfyMYkS
-K6bOgMosrBoX8ns6jQgdXEzf7QOIa110bs6nD+XeJeKmzUAZ3wumXBTalPaiqkEz
-bq4nlsEs1phvj0Coy5eehjV3DB8bDLEneOlV5N9y4Z4VO1BrhX61bLiPXBRp1MZR
-I0sCdxhswSrq02/OuFGe6mqrSBBI
+MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c
+vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1
+37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w
+mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB
+paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO
+cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/both-cas-2.crt b/src/test/ssl/ssl/both-cas-2.crt
index b0bc3f5..e857f80 100644
--- a/src/test/ssl/ssl/both-cas-2.crt
+++ b/src/test/ssl/ssl/both-cas-2.crt
@@ -1,39 +1,40 @@
 -----BEGIN CERTIFICATE-----
-MIIB9zCCAWACCQDrgvp38CAy8DANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVU
-ZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBz
-dWl0ZTAeFw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMEAxPjA8BgNVBAMM
-NVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0
-IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyTfGMPAjAylLr3G7c
-/QToCA3da5YZzdhd3TiQGugrJjWI4TzVB7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZl
-FLW9dMpa/8SY2TETvMTuXR5MOxyw6FMEKb3buolsIksCCQ1btEIrDZ+gv9SJXcdL
-ylU+VI1lKmn2fLNWWATzWrIUawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAF2T84iG
-zWKXu+3PysuPOn7RuRpMgYQKouQktErNJ8hM7Yqj3vu879zUkX1rP0HGnx7xQC3d
-nBkoJ7yNDR0MwQpWo1Dj1HLKNEY6ojKJgPd0+m8nG+02yUmmOjo0oMYzJx2DQy0u
-Y4qecEd6aDbqXTo+qOJ7Qm/U+U4kD9MTT6GD
+MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV
+BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0
+ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG
+A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u
+IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5
+qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8
+sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B
+MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE
+TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE
+TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1
+K5Y=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQEwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDAYtajRx8vM6IB0SLZsAhTD0Y
-VHM+/+t0a4m3JXolJBbo9/B2/WAN0IH1E2zmlalLc3JBmGsH1a8U5ZlRow3p2ODL
-rFra9FbOl0wekmRFvZeaRln/99dpI5itVpL97QPHO8QMMK1IsyurFA5GfuPOBx9P
-i0MvzsT0tYsRvR929QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAJw4ngOYElfyMYkS
-K6bOgMosrBoX8ns6jQgdXEzf7QOIa110bs6nD+XeJeKmzUAZ3wumXBTalPaiqkEz
-bq4nlsEs1phvj0Coy5eehjV3DB8bDLEneOlV5N9y4Z4VO1BrhX61bLiPXBRp1MZR
-I0sCdxhswSrq02/OuFGe6mqrSBBI
+MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c
+vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1
+37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w
+mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB
+paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO
+cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQIwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8wIYcmeePSXVufP/Hn/6ICEog
-IUXqSNls5QIJR7Sate4iKGGTDEsRTxI4oDgkOYtcQNuEeXMf6k3xo+PRR08IEQNk
-XKy1zUWds6UBFboD72SyuTE2lxJBg+xOAWgl7JSNA+g8e0Y+wfhfxGZgRuqVxVNP
-9sAsfCEzGKna1l46dQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD20Bmina/uXTLXO
-oPWgpMmKwQu7Q6DPXxItCUdWgK1k1D82brRjH+usrkrmCW5BQNXOC/0zJS22ioC1
-CJbhAujH3iPaV0C3xsVSf+bvTL6OMkwV/9x9OdDN+LI2auEt4S+fP5ZTVsTXt4wA
-A9cQIl2Qy88enZZAFKxrScFFlstp
+MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+
+19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd
+JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x
+6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI
+TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM
+ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client-revoked.crt b/src/test/ssl/ssl/client-revoked.crt
index c38229f..8448e96 100644
--- a/src/test/ssl/ssl/client-revoked.crt
+++ b/src/test/ssl/ssl/client-revoked.crt
@@ -1,12 +1,12 @@
 -----BEGIN CERTIFICATE-----
 MIIBxzCCATACAQIwDQYJKoZIhvcNAQEFBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm
 b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe
-Fw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBYxFDASBgNVBAMMC3NzbHRl
-c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmApiFBFLZi/hgQOMz
-iAHXBbY7A5hNMitQZMSTUB+/fLnzofkUjf/7GiRCLmdTCa4w1wvQp5VbrEhIbSGW
-sFSam6GuE0IBfSRJA0IouBtxdk8bCY4HDpXsh/6eC9XtV4k9YDp4JlkUNxOVu8Pb
-Z86OEQf3Ww/EZP5AfwORXLYgVQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAEarnPO1
-Rc88mDYZWM8H/I18L0omdib21+lJczkm4sgv2hVp2nR4Wfb51DojYruLxNJ0k/A5
-T0nEZghQDtNQQpMko9e8jn8gmEAs83zQIsVsmosfTYg0Zr2pSkT0ILSfR6BupHFJ
-I96I+qcRKc4rotOirgMrcgo/VpUcWnz8VPEo
+Fw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBYxFDASBgNVBAMMC3NzbHRl
+c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKeycg+E5SBlaTxcus
+Fps4yZnGVB78Kt/HQAZcmgiwWZxN0th9SsJVMw2VkwMPPm4o8idEF/PZvbz15DHk
+MrNWSOMB8qsXlt3P8VMhKhWG025TbWpfXbNHKKqQqAc55i1SvQJvllrAYKOlpu/K
+YQsIK/ZpjeTywcVi19B3aPE82wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAE3vuzMF
+C5Ut6X981NjsuSlDptqDd8aQqO1HK7McEcH7Tjw6DU9ZPqw9Ktpz/wAJc2DvsmBM
+QqlM+OtSkEncAdWx/xOzN46oHUNxrR2cXD1N/0HgVHJEUfq8p+oJHYXKVWtsjO7S
+2/fZnMMO9Gv6e7eTiYE55R0IZrQENwtmIJ8y
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client-revoked.key b/src/test/ssl/ssl/client-revoked.key
index b272f70..b2321ca 100644
--- a/src/test/ssl/ssl/client-revoked.key
+++ b/src/test/ssl/ssl/client-revoked.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDmApiFBFLZi/hgQOMziAHXBbY7A5hNMitQZMSTUB+/fLnzofkU
-jf/7GiRCLmdTCa4w1wvQp5VbrEhIbSGWsFSam6GuE0IBfSRJA0IouBtxdk8bCY4H
-DpXsh/6eC9XtV4k9YDp4JlkUNxOVu8PbZ86OEQf3Ww/EZP5AfwORXLYgVQIDAQAB
-AoGBAOV1iXqJya1Fuc8sbHyoHk3IYPeWqoW4mwVkwcbElCeP4mJvH/Glh82VUr7D
-VEi+y4vlvN+3j4UY5jN6y5ts5bhDam4RjdHzhLT+ddlztoH4LNcgPDokQtPDtfOd
-UbbMcM6Pim7+ynBLncAj7dTin4/pVL2tYUIrKWvLhCU2zISxAkEA+CyHJZs49vOs
-hx8xEXGStdLq3k9vUk8G4BISicswixDWPQmJ3YN053FAZ+moHjqNpU5dMn7cVIcA
-HEW6LLS7IwJBAO1DbyWtCNQJZBKXzvBKxx9nOBb+5ovQZWs92bpvxkATPn4TUbQx
-nEe7eOPX+R2szP9+/3ApmZA1gV1mpVKsyicCQQCcUmf6jzCtlUXKgyJES5bPAwFA
-cSa84NyCzb9xnlSAdGWOYvC9YC2GD3czPSHRkK5iPt9DjFc6wyKVrHId8OWjAkBh
-8Yp6dRnF3jKPclec3mGg1w1SgNtPMDINuTSeP/IJFWigxvzdc/Vdr0hSVh+iXmkp
-t5VfCe04mL3UfsEUhfvVAkEA5Y05DCgaT+rOZbl6hMXlIqT5eT+xTatmDZzv6FUJ
-eAaYYhja/FrWa5JFXFUpFTamWGMTkfd6zsDS1bI6hwg/5Q==
+MIICXQIBAAKBgQDKeycg+E5SBlaTxcusFps4yZnGVB78Kt/HQAZcmgiwWZxN0th9
+SsJVMw2VkwMPPm4o8idEF/PZvbz15DHkMrNWSOMB8qsXlt3P8VMhKhWG025TbWpf
+XbNHKKqQqAc55i1SvQJvllrAYKOlpu/KYQsIK/ZpjeTywcVi19B3aPE82wIDAQAB
+AoGAKXV79pFBICRyF8HZSTw7vi3xUZ2p1oJE3bxrUQytGMbQbVLtxwHGtsFEV8sJ
+RlbHIZUrmxK4eG4UQdjeqlYDSBsV4x/g4sqpgQAoE1J6TQ9D3at6LqnvUa6ObjQW
+W/GczCkrQRkRTxwa35PSE2CcgNcoyUXRkF0DHhugPcOVjRkCQQD1jUQYgLoUKDbZ
+mZ1odm2adDu4BMFTd3pyQBVZmetlPrLVr8iU6bHJGUWpaFkpv/jbOJfNgijqQ3i6
+vZRhyHgHAkEA0xi6XZITkzmLP7qEQsho9JX02Pqqpd4ZQOp6CZDY6TH45oOBK0Bn
++xsfGENexiqU2EFtIChesScVpzTuvq2XjQJBALB82HTEEPpr7QB5aKmsdRqOcF3T
+DSDwvxFe/flop8gdSGxN690cGqxvfaJFXdCkKjlmc7VB2CaIWD3gBMZDUAECQQC8
+oUIXTurTCf6WSdLZ4j93H3CVWxiV8uraCSxX0+kgKBlj0mrf/UNtLQUSJ1FO/snW
+nFApBinnXyeILFKSbIgZAkB74ahj70+NmAFfEcgN3FjcHOy81rsvN9tO4rC0/0nt
+iYBz1jc4KBZdyQY1rgk2om9m+EC+mlJsxtgFNK3k/kRJ
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/client.crl b/src/test/ssl/ssl/client.crl
index cb86d82..72ed9e6 100644
--- a/src/test/ssl/ssl/client.crl
+++ b/src/test/ssl/ssl/client.crl
@@ -1,9 +1,9 @@
 -----BEGIN X509 CRL-----
 MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ
-b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNTAy
-MTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBQwEgIBAhcNMTUwMjE2MjAwNjIzWjAN
-BgkqhkiG9w0BAQUFAAOBgQAsrnXoVeyU8vmxPOVQrHvoMXkEvF9dOnSHIQD0ZnAW
-pxbj98hCMSIW+DPIXXFebMQ6GIPp4S/w5kVpngY51paT4iztRMlV+YeyuZQuZX9a
-EVgpj4t+i6hhtBHk5p9DeknERoAIsl4m2maQ58lT5UyeN4fdz4eNP6y3mQRfSTUn
-bQ==
+b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNjA5
+MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBAhcNMTYwOTEyMTYzMDAxWjAN
+BgkqhkiG9w0BAQUFAAOBgQAyiU3V6ci5JR5oAZjlG7yFBhVO2TFLga5FynwHK5Wd
+ML0BA/0TtTXFiPoul+zvOdqwpX8GC3IuxqgJzlxWOxl5mZzyKEtheT9RBwvBmjAe
+ZjT7bFttKo/WKpztNE/2ZEDYyN87Xlpcm5UBFNhcYUjQkxuWIEvH4VOPm0iFjzm4
+tA==
 -----END X509 CRL-----
diff --git a/src/test/ssl/ssl/client.crt b/src/test/ssl/ssl/client.crt
index 0c397c0..33d57ce 100644
--- a/src/test/ssl/ssl/client.crt
+++ b/src/test/ssl/ssl/client.crt
@@ -1,12 +1,12 @@
 -----BEGIN CERTIFICATE-----
 MIIBxzCCATACAQEwDQYJKoZIhvcNAQEFBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm
 b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe
-Fw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBYxFDASBgNVBAMMC3NzbHRl
-c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDay1hT3/0Nj5ndv2TJ
-DxJZWQTOZD+/0ktqW9qyiRY9o0nf7PCQZE9OCh3ylaaPPfpL7iITZi1KASmSIn7M
-E4w1ibmBqFiogDE0Bq0DgJaoeUgLHMERDUtcxBJgwyCGjfI9Om4jy74kwMXb8I5i
-jVwZLUTSWzRSgany3WRqMb6CwwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALfP/i7o
-ZVYsIZWksIb/uxr/AlghyNQjLPVJTAOjrm9PP9rwKR2alI/zjkDrHVH57n4MfcmD
-Xn247DRv/MJFJ1xWCSh4PCy0vyTCFAerNDcqniSTqp2+Yusdr0mH/gHa+34ASYu/
-MXXB4UBMjTnZ/KhaVTmAv3cPeiMAQODRud65
+Fw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBYxFDASBgNVBAMMC3NzbHRl
+c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDN3RFl8VWMEBN1Qas0
+w1CFcXdDEbKVNSPsqWHzHIEPoGJv+eUIBK2lQ/Ce8nRCdelO50RsmlbcXBIrjVl6
+BN0RmEeEVclgCdiamYN53LBdc5KWKpKCKn45lCtlZodWt0hNNx1pAmh85jDKpoO9
+ErbCnSU1wODPqnOzdkLU7jBu5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABUz+vnu
+dD1Q1N/Ezs5DzJeQDtiJb9PNzBHAUPQoXeLvuITcDdyYWc18Yi4fX7gwyD42q2iu
+1I0hmm2bNJfujsGbvGYFLuQ4hC2ucAAj2Gm681GhhaNYtfsfHYm9R8GRZFvp40oj
+qXpkDkYsPdyVxUyoxJ+M0Ub5VC/k1pQNtIaq
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client.key b/src/test/ssl/ssl/client.key
index 6cb6655..4400c8e 100644
--- a/src/test/ssl/ssl/client.key
+++ b/src/test/ssl/ssl/client.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDay1hT3/0Nj5ndv2TJDxJZWQTOZD+/0ktqW9qyiRY9o0nf7PCQ
-ZE9OCh3ylaaPPfpL7iITZi1KASmSIn7ME4w1ibmBqFiogDE0Bq0DgJaoeUgLHMER
-DUtcxBJgwyCGjfI9Om4jy74kwMXb8I5ijVwZLUTSWzRSgany3WRqMb6CwwIDAQAB
-AoGAJAMiR7Pvb+L5/XC6QwmzCHfJfbssbwNLHHd/+LDtszmEOFJEik+oafzqTvpo
-ztzxrLvGahEAVVT5pa791dNF2V//AKCDj3mOSVfrh6aYeA5naMT91JjnuRVgpdlc
-1b7p1FpbnwmzppqSbAfVQxmTlFxvVevukTqkAzP03uuQZ+kCQQD8XMpgCYXFuAl9
-n59OjS9Fi4oISI2lxFFxUK4KjGW4fOzS9/PdHepc4YBJQXSrDdELkH/un5AZQ7tr
-67R5YkB1AkEA3fKwaV0dPlXg78rVImUEXwNRM9SgxHquE6itzuT7RYg47bEnDHDm
-EGzN5QVs7TrxApk8KCxPUzlv/3vSWszPVwJBAMN+2mN1XQTi4a9IhW+jnZghVce+
-9MQShgjjOEABrRcy538zB94mO5TCN9AH/eo45NUxlnlzcHyx5LHgwUk7HLUCQQCP
-RhT/Ty6LiOCVqvf/Jfq2YuvOa5oEe7VX13Grt0FFV3R4a/1rGI5LWBFpoCD62yut
-o8GjpUbn0JIt+H6IQuItAkAqnLiP2ZJMhDoey8+btgwiAEoUnkDfa3bNA9wncJhO
-M3G4BM/bZhX5cuIaU7kPUHUS5fQeLLUfveWtbVSu1cRn
+MIICXAIBAAKBgQDN3RFl8VWMEBN1Qas0w1CFcXdDEbKVNSPsqWHzHIEPoGJv+eUI
+BK2lQ/Ce8nRCdelO50RsmlbcXBIrjVl6BN0RmEeEVclgCdiamYN53LBdc5KWKpKC
+Kn45lCtlZodWt0hNNx1pAmh85jDKpoO9ErbCnSU1wODPqnOzdkLU7jBu5QIDAQAB
+AoGBAMFEdSwGuTCoewwPXcNIRpUxJC1ENStdW1+42atarFPWV/QWYI35jmhkc0dW
+Cg3HEwUvm452C2wPyEM5DbK/VCacUkcvcA1taPnNjaw4qUjxRnsVCMhIZp0sCKEW
+N1LZhBcc9ThGyOvirRZfk3URqtW58nDqTKZeKZQr/d4DkNz1AkEA7QrHDZUdtdQw
+znG+8gsby7hK6+4h3F7ICD+RfUVAHEdSC2L59YsEH03d/kr62t1YOxdlMmCYK9sO
+7bthNibwhwJBAN5T8BDD1eRukPPGu602uAPRCfOgx6uoUGL78jTXUYGOiVG/fxkt
+EIr3m4G7KKj7LKipX8eowsCVC+Fj/3+SXDMCQAnzPN3OF5wtVwsjbS991eHcT5DN
+wzAb7muiN3o5sPI+8Cu4MOPkvPyPaTUmcpdDWVPJrJ7LvTeCD4NdLTx3r/sCQEsV
+g+zVhoX4BUIe6sELyseXMEo0EVrapBNZzSmlUiRz89JE3vKssnqMNttwTsIK2cE4
+Ol2ek+8gJvv+nooB7tsCQCu8ZYH75hVZGONfviwHk1RD5DegNZ6pT1Or4g9N23cj
+YbP58Lvi4tiQqG6zKMCosWFoDsiKKIH9qQkrygSCn3o=
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/client_ca.crt b/src/test/ssl/ssl/client_ca.crt
index 003baed..6507bc5 100644
--- a/src/test/ssl/ssl/client_ca.crt
+++ b/src/test/ssl/ssl/client_ca.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQIwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8wIYcmeePSXVufP/Hn/6ICEog
-IUXqSNls5QIJR7Sate4iKGGTDEsRTxI4oDgkOYtcQNuEeXMf6k3xo+PRR08IEQNk
-XKy1zUWds6UBFboD72SyuTE2lxJBg+xOAWgl7JSNA+g8e0Y+wfhfxGZgRuqVxVNP
-9sAsfCEzGKna1l46dQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD20Bmina/uXTLXO
-oPWgpMmKwQu7Q6DPXxItCUdWgK1k1D82brRjH+usrkrmCW5BQNXOC/0zJS22ioC1
-CJbhAujH3iPaV0C3xsVSf+bvTL6OMkwV/9x9OdDN+LI2auEt4S+fP5ZTVsTXt4wA
-A9cQIl2Qy88enZZAFKxrScFFlstp
+MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+
+19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd
+JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x
+6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI
+TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM
+ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/client_ca.key b/src/test/ssl/ssl/client_ca.key
index 1d636ec..0e6c464 100644
--- a/src/test/ssl/ssl/client_ca.key
+++ b/src/test/ssl/ssl/client_ca.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQC8wIYcmeePSXVufP/Hn/6ICEogIUXqSNls5QIJR7Sate4iKGGT
-DEsRTxI4oDgkOYtcQNuEeXMf6k3xo+PRR08IEQNkXKy1zUWds6UBFboD72SyuTE2
-lxJBg+xOAWgl7JSNA+g8e0Y+wfhfxGZgRuqVxVNP9sAsfCEzGKna1l46dQIDAQAB
-AoGAMAXDmU9G7NvBtuSypvV76txBD7+nbB4ww1XYmMfXmW0kMyiW+rSr/LFjb2jE
-H+NMI6KUtzW3Jq2UOyB5e+tqnbDjqZlQjnBYFnWKRa8SxsuamSAvGNLPIzur8rxm
-qxOWkxlHpS+I6OXn263sWzG38ptQ3X4zK6ADcTpg7FkkYJkCQQDhCJH630aXQyia
-90QM+BaKp7rhr+DHW+vVU/5pg3FrPIuvRlLo+E8iJItY3Ae+AJylK6kP6/5AJzOz
-s1tXjZezAkEA1rnW4YIlWRlaJE4hXMNvF4VJO5MBtS60F4/z1kR0uVO5+JAgTZT0
-GE7ghZQ3VwdyRiWc59zXr2qkA75qtMFRNwJBAK0x82iqP6Jbxfy/Ilj4+CBvR547
-xzyourHNm5mJ2Nk4GCombdlwgzc7+SPC9RJ/VhCpsczXTTAC+//qovqXt5ECQEtF
-rlwzQWBwkLb1ZKCeKg12vetSZ2DaVGuGHRZZvQlSnnjSHWDU/JSg4fgxswyhIaAR
-g2WMd1eY7JIbaFChDBUCQQC46CikUDq2kfIPOkj/dsa4wLkUETrcgBx+eaZbOCgx
-JU7GqsoSXxTgKcjZPm/5O/rWWtwB9XhtTuvS/NYi3aSs
+MIICXQIBAAKBgQDCNjF1km/E2Zwi1TWCftfW+J6MUZmkdVts1MZeGkzH4j7fXCtO
+pTWN/RDwX45m+4Y8Q++sPHy6Ff2mdIDoHSVxUWbyIO0sjO0FRZmtACQCGWsnrPm2
+taHRJgRIt+/INJi64wi6mbQVR37ycS/+sev35UkwJ//tPb7RC77y1gXj2QIDAQAB
+AoGALo7NVpEvaDJ+wr74H/uGhMt/PsZFHe7gZvuvPlnxtC1hwywWWbkzWIGlcOqH
+edqseIAU0eaCRB4He8MMMBjko5WZcPRrE6mR0ZqtcTSIsg2dRkXJeSbY0A8ZPLjU
+xw0RiNPRwcr0zgImzMCR5dVuKOgnAGDRZiDwWefF0g6pRYECQQDwXJyT/E5EKOBY
+U4tioFMVypbYlyLXjvhKIFL6wdNAVIOa0LQ+X6cPBZRIM6q+eUjodHWnjf9uFX1i
+4mjegCwJAkEAztjruKRIoHAk6zQtSEv2vJhObeXg0gAHWRuCmivS/9NtqrEyGGpl
+V0YCe3T257Mrw7A0TgBf7lojkrSnOT+NUQJBAM4Fs7gstTE7EEDlKz4YSd8NzQpN
+UXIOe8eduUJyTI6BYmSaq0QjXOBFWfohPyMQdmu5FvfNgLls9hKCGn1Mw3ECQCMQ
+tvU4NG+uUzPkRoDpD8zs7O7Id5JiGtzKQxurrjtcNk0neNyWvNNMtQME0w54W0Tz
+TAqlGZ4ofbtTEL4tveECQQCFl7OS+Emv0kvUCUm4QQ/xR9bjZ80lRdRn0AwXPiPz
+zzYjV0OILDlMip+WrleC99v6R2M6BJrSPQr08oxeIUzy
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/root+client.crl b/src/test/ssl/ssl/root+client.crl
index 017f16b..e90d4b9 100644
--- a/src/test/ssl/ssl/root+client.crl
+++ b/src/test/ssl/ssl/root+client.crl
@@ -1,17 +1,17 @@
 -----BEGIN X509 CRL-----
 MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm
-b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNTAyMTYy
-MDA2MjNaFw00MjA3MDQyMDA2MjNaMA0GCSqGSIb3DQEBBQUAA4GBACEwQiR8BKoD
-eGuJKMy73AGLzNu3m7jUPWBPntGpNrUMZXNQXgtfm1t3twXbklQq4pao+9SKgT5X
-guXpfoa/mPLs//gsTEx0EQV/YzsXm2xFBUtaRq46GbJK3XTfRJLw7OOzBFij1o3i
-GaeVMn7IXwQBNkxQT0AAAiCUz5yz/Wvx
+b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx
+NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG
+0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk
++4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F
+yaKadxocukmCcbxXdiDZePFpf7TfuoIm
 -----END X509 CRL-----
 -----BEGIN X509 CRL-----
 MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ
-b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNTAy
-MTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBQwEgIBAhcNMTUwMjE2MjAwNjIzWjAN
-BgkqhkiG9w0BAQUFAAOBgQAsrnXoVeyU8vmxPOVQrHvoMXkEvF9dOnSHIQD0ZnAW
-pxbj98hCMSIW+DPIXXFebMQ6GIPp4S/w5kVpngY51paT4iztRMlV+YeyuZQuZX9a
-EVgpj4t+i6hhtBHk5p9DeknERoAIsl4m2maQ58lT5UyeN4fdz4eNP6y3mQRfSTUn
-bQ==
+b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNjA5
+MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBAhcNMTYwOTEyMTYzMDAxWjAN
+BgkqhkiG9w0BAQUFAAOBgQAyiU3V6ci5JR5oAZjlG7yFBhVO2TFLga5FynwHK5Wd
+ML0BA/0TtTXFiPoul+zvOdqwpX8GC3IuxqgJzlxWOxl5mZzyKEtheT9RBwvBmjAe
+ZjT7bFttKo/WKpztNE/2ZEDYyN87Xlpcm5UBFNhcYUjQkxuWIEvH4VOPm0iFjzm4
+tA==
 -----END X509 CRL-----
diff --git a/src/test/ssl/ssl/root+client_ca.crt b/src/test/ssl/ssl/root+client_ca.crt
index 227ab72..35dfac2 100644
--- a/src/test/ssl/ssl/root+client_ca.crt
+++ b/src/test/ssl/ssl/root+client_ca.crt
@@ -1,26 +1,27 @@
 -----BEGIN CERTIFICATE-----
-MIIB9zCCAWACCQDrgvp38CAy8DANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVU
-ZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBz
-dWl0ZTAeFw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMEAxPjA8BgNVBAMM
-NVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0
-IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyTfGMPAjAylLr3G7c
-/QToCA3da5YZzdhd3TiQGugrJjWI4TzVB7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZl
-FLW9dMpa/8SY2TETvMTuXR5MOxyw6FMEKb3buolsIksCCQ1btEIrDZ+gv9SJXcdL
-ylU+VI1lKmn2fLNWWATzWrIUawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAF2T84iG
-zWKXu+3PysuPOn7RuRpMgYQKouQktErNJ8hM7Yqj3vu879zUkX1rP0HGnx7xQC3d
-nBkoJ7yNDR0MwQpWo1Dj1HLKNEY6ojKJgPd0+m8nG+02yUmmOjo0oMYzJx2DQy0u
-Y4qecEd6aDbqXTo+qOJ7Qm/U+U4kD9MTT6GD
+MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV
+BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0
+ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG
+A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u
+IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5
+qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8
+sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B
+MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE
+TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE
+TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1
+K5Y=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQIwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8wIYcmeePSXVufP/Hn/6ICEog
-IUXqSNls5QIJR7Sate4iKGGTDEsRTxI4oDgkOYtcQNuEeXMf6k3xo+PRR08IEQNk
-XKy1zUWds6UBFboD72SyuTE2lxJBg+xOAWgl7JSNA+g8e0Y+wfhfxGZgRuqVxVNP
-9sAsfCEzGKna1l46dQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAD20Bmina/uXTLXO
-oPWgpMmKwQu7Q6DPXxItCUdWgK1k1D82brRjH+usrkrmCW5BQNXOC/0zJS22ioC1
-CJbhAujH3iPaV0C3xsVSf+bvTL6OMkwV/9x9OdDN+LI2auEt4S+fP5ZTVsTXt4wA
-A9cQIl2Qy88enZZAFKxrScFFlstp
+MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+
+19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd
+JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x
+6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI
+TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM
+ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/root+server.crl b/src/test/ssl/ssl/root+server.crl
index ac31888..096b48c 100644
--- a/src/test/ssl/ssl/root+server.crl
+++ b/src/test/ssl/ssl/root+server.crl
@@ -1,17 +1,17 @@
 -----BEGIN X509 CRL-----
 MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm
-b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNTAyMTYy
-MDA2MjNaFw00MjA3MDQyMDA2MjNaMA0GCSqGSIb3DQEBBQUAA4GBACEwQiR8BKoD
-eGuJKMy73AGLzNu3m7jUPWBPntGpNrUMZXNQXgtfm1t3twXbklQq4pao+9SKgT5X
-guXpfoa/mPLs//gsTEx0EQV/YzsXm2xFBUtaRq46GbJK3XTfRJLw7OOzBFij1o3i
-GaeVMn7IXwQBNkxQT0AAAiCUz5yz/Wvx
+b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx
+NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG
+0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk
++4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F
+yaKadxocukmCcbxXdiDZePFpf7TfuoIm
 -----END X509 CRL-----
 -----BEGIN X509 CRL-----
 MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ
-b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNTAy
-MTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBQwEgIBBhcNMTUwMjE2MjAwNjIzWjAN
-BgkqhkiG9w0BAQUFAAOBgQB1c54zLMueMtLiSmBT6kfXJe9o3Krd2n774g7kzNlR
-DeLpCHeUvyLF0m8YK09vbLv2W0r6VQnbjyQGr9xyweRLLtOXc0FIDsTO8g/jvMSq
-Q9zITuqWiCHRbNhi2B3HPo2NsrfA+tQEAZvMUgnynlerNvGkLWQZeC2UsxrrSs4t
-9Q==
+b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNjA5
+MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBBhcNMTYwOTEyMTYzMDAxWjAN
+BgkqhkiG9w0BAQUFAAOBgQAm5J6912hKDUWXyu3yCEk1j3KICE2J42ZjFRvxBNdO
+Zhv/iBjyFI6TmCVJqoe4GJbNG78xmNEl3/2ZUavG/aD0Z3xGu2xm0p+3Uh2zhfDQ
+VEdlgFNKNItS0AtKvoduoZUXKnz3Ft09yLmz9yHLu6EslIsYryi+wnZ5DwUBj5Ec
+WA==
 -----END X509 CRL-----
diff --git a/src/test/ssl/ssl/root+server_ca.crt b/src/test/ssl/ssl/root+server_ca.crt
index 4a33f77..8b548b4 100644
--- a/src/test/ssl/ssl/root+server_ca.crt
+++ b/src/test/ssl/ssl/root+server_ca.crt
@@ -1,26 +1,27 @@
 -----BEGIN CERTIFICATE-----
-MIIB9zCCAWACCQDrgvp38CAy8DANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVU
-ZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBz
-dWl0ZTAeFw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMEAxPjA8BgNVBAMM
-NVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0
-IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyTfGMPAjAylLr3G7c
-/QToCA3da5YZzdhd3TiQGugrJjWI4TzVB7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZl
-FLW9dMpa/8SY2TETvMTuXR5MOxyw6FMEKb3buolsIksCCQ1btEIrDZ+gv9SJXcdL
-ylU+VI1lKmn2fLNWWATzWrIUawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAF2T84iG
-zWKXu+3PysuPOn7RuRpMgYQKouQktErNJ8hM7Yqj3vu879zUkX1rP0HGnx7xQC3d
-nBkoJ7yNDR0MwQpWo1Dj1HLKNEY6ojKJgPd0+m8nG+02yUmmOjo0oMYzJx2DQy0u
-Y4qecEd6aDbqXTo+qOJ7Qm/U+U4kD9MTT6GD
+MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV
+BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0
+ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG
+A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u
+IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5
+qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8
+sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B
+MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE
+TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE
+TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1
+K5Y=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQEwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDAYtajRx8vM6IB0SLZsAhTD0Y
-VHM+/+t0a4m3JXolJBbo9/B2/WAN0IH1E2zmlalLc3JBmGsH1a8U5ZlRow3p2ODL
-rFra9FbOl0wekmRFvZeaRln/99dpI5itVpL97QPHO8QMMK1IsyurFA5GfuPOBx9P
-i0MvzsT0tYsRvR929QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAJw4ngOYElfyMYkS
-K6bOgMosrBoX8ns6jQgdXEzf7QOIa110bs6nD+XeJeKmzUAZ3wumXBTalPaiqkEz
-bq4nlsEs1phvj0Coy5eehjV3DB8bDLEneOlV5N9y4Z4VO1BrhX61bLiPXBRp1MZR
-I0sCdxhswSrq02/OuFGe6mqrSBBI
+MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c
+vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1
+37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w
+mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB
+paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO
+cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/root.crl b/src/test/ssl/ssl/root.crl
index 65e470c..2158728 100644
--- a/src/test/ssl/ssl/root.crl
+++ b/src/test/ssl/ssl/root.crl
@@ -1,8 +1,8 @@
 -----BEGIN X509 CRL-----
 MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm
-b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNTAyMTYy
-MDA2MjNaFw00MjA3MDQyMDA2MjNaMA0GCSqGSIb3DQEBBQUAA4GBACEwQiR8BKoD
-eGuJKMy73AGLzNu3m7jUPWBPntGpNrUMZXNQXgtfm1t3twXbklQq4pao+9SKgT5X
-guXpfoa/mPLs//gsTEx0EQV/YzsXm2xFBUtaRq46GbJK3XTfRJLw7OOzBFij1o3i
-GaeVMn7IXwQBNkxQT0AAAiCUz5yz/Wvx
+b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx
+NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG
+0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk
++4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F
+yaKadxocukmCcbxXdiDZePFpf7TfuoIm
 -----END X509 CRL-----
diff --git a/src/test/ssl/ssl/root_ca.crt b/src/test/ssl/ssl/root_ca.crt
index e491d73..fab7a68 100644
--- a/src/test/ssl/ssl/root_ca.crt
+++ b/src/test/ssl/ssl/root_ca.crt
@@ -1,13 +1,14 @@
 -----BEGIN CERTIFICATE-----
-MIIB9zCCAWACCQDrgvp38CAy8DANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVU
-ZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBz
-dWl0ZTAeFw0xNTAyMTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMEAxPjA8BgNVBAMM
-NVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0
-IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyTfGMPAjAylLr3G7c
-/QToCA3da5YZzdhd3TiQGugrJjWI4TzVB7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZl
-FLW9dMpa/8SY2TETvMTuXR5MOxyw6FMEKb3buolsIksCCQ1btEIrDZ+gv9SJXcdL
-ylU+VI1lKmn2fLNWWATzWrIUawIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAF2T84iG
-zWKXu+3PysuPOn7RuRpMgYQKouQktErNJ8hM7Yqj3vu879zUkX1rP0HGnx7xQC3d
-nBkoJ7yNDR0MwQpWo1Dj1HLKNEY6ojKJgPd0+m8nG+02yUmmOjo0oMYzJx2DQy0u
-Y4qecEd6aDbqXTo+qOJ7Qm/U+U4kD9MTT6GD
+MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV
+BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0
+ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG
+A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u
+IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5
+qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8
+sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B
+MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE
+TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE
+TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1
+K5Y=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/root_ca.key b/src/test/ssl/ssl/root_ca.key
index e5cddee..b79f4b0 100644
--- a/src/test/ssl/ssl/root_ca.key
+++ b/src/test/ssl/ssl/root_ca.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCyTfGMPAjAylLr3G7c/QToCA3da5YZzdhd3TiQGugrJjWI4TzV
-B7pQ8IwDYk/jZf5TzVdEtz0B4TeIeUZlFLW9dMpa/8SY2TETvMTuXR5MOxyw6FME
-Kb3buolsIksCCQ1btEIrDZ+gv9SJXcdLylU+VI1lKmn2fLNWWATzWrIUawIDAQAB
-AoGAQ8TmMuO6e/QqUiUlKe8tBzfQdUDn+wTG4N4tGnBvn77VCCJ7qYhXY14aCUs7
-i/V/FcDtE1wF3woHvmJBxDd731TILBhuqn3UIWJafoiezlhqwR2uvTfnWh62N15w
-xlmGDuPwXMtQCazbcD6I9hgbADBbMmsyym8cuwN+hxU7bKECQQDfzkAN0RNI/m31
-7GVjOvWrd3+brwf19jXtxhzJCRThjyVyCMYfG9ELP/u76aNCMs2otn2K49Vd0s5A
-rG6uN4Z7AkEAy/QXExktz0YxaTMHYHafwSkraoygKVUIoxWm2AHhNXdSY1M8AqkL
-6VqGpNgcwiEE0QJHG0MFjB0tZAe9/kq+0QJAWqc+htozR5PXko+ImeMd87BZvgPt
-45ExUvi2XDAThzHmZwRqy9sGl9n466q9eGj/qOEShRm4KWLkLIor4uGW1QJAbj2h
-u1EA0ei/DH3ontt/vojiTtV0POMZqA0sAdYCRUQZ5FY5ObbmGVw1KyUlZkkysUbp
-6HJxrSqYPllw+OKuAQJBAN54Aep6BvzI+arJrOm2Un5l27jfPbuKmvJWjus1mU+e
-HkaXYUF31/LIN4gNeu0ULbCSKpvk00UaBfjbwvfLmAk=
+MIICXQIBAAKBgQDOL1A4pRLAeaiPXBlk7YQCI5b69p4BSah5jHjoE4OCUENuDEHn
+YdK9tpwzcJvNK+EQ/UQo5cP5PLEvnIUcEHJSaqROhFeuUyB9CYTihhacfz8/8q67
+uUMBA5GHB5dUHCt8RVCm0sYvwTAquE2X+tx5COv1UWPtUsChdmuKY1iGgwIDAQAB
+AoGAE+iNnmqR/PPCStVhvlUQwgQdt+3II+ew1MuzgPUhZZvKZv3X/zd62cagHndp
+E86A1NsfkbNd0NsDYM2ELMmJwC8cTKFw2WyB9t3v0GTtVG8e338QdrrTOvawO3F4
+f4tCESvBgY4qmJMuvicMqLey9fAXc8ul+wocRRYx4r1Gc4ECQQDpgATrxdy7vkf0
+KFxO6htUnKB/V5Q56qvlMzXKHSiwnCMKRYPY7NAxLVNVTmH3ACaBFCvg1f7++Yn7
+r5zEEcuLAkEA4g17NFfFZmBz37C9Cu1W6cX0ps0MgI9w38bEYy8LOk0liUGd+Qit
+AKpu8KNOb3v5FQ5TL25EaX1VhM78OE9v6QJBAIFHZPIZGY5E2te+pOT4Tut40I/Q
+sHukh0meIdDmdgnaWLguJsKq0tX3b2USwcCcr7TVszmHoegPxyq3X0dbRuMCQQDW
+7OhyWO1XrGcfjKQAyq4zMMKvARBc/4TbTtoUT3tGYGlK+jdfuw76LhGy/CIsP1wQ
+2ADhfN7QyZjQ4BfQ1j5ZAkBggAL3a/4+KjsPesTxWjlufmoL9QG8Bgaj1tWBYDzX
+5CQCWYRPVE7aV+Jh1NDHgToQsziZtvRL16l+GivYEnTX
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-cn-and-alt-names.crt b/src/test/ssl/ssl/server-cn-and-alt-names.crt
index 04f9b58..ef7fd66 100644
--- a/src/test/ssl/ssl/server-cn-and-alt-names.crt
+++ b/src/test/ssl/ssl/server-cn-and-alt-names.crt
@@ -1,15 +1,15 @@
 -----BEGIN CERTIFICATE-----
 MIICSTCCAbKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owRjEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z
-c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMH7OtRvW0qP
-gYDMInkd0mgKnqhexEUnTf90mGihzd4sw91J0bJBnC/wfLmpP9a1wOwvAma1GSJ2
-1lLFrSC8bXkT+6nIiqXlFK4HqW5w3PktbO1InujFS1PoxXOdlSwdcIzQ+VDk3Kv3
-IVnCq9w8rcchthnSb+3kYx5QjA0Gb1vhAgMBAAGjSzBJMEcGA1UdEQRAMD6CHWRu
+c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsIeqZ7pHER
+w0nqVgePeSDdr7/fXMNtF/yFk4ZYUXGLuyzterEUaxeSYB5jmNAeY7ANRjbMb5N9
+mvoHHUsz0AzVNFihcSvP5nB9xIAEypMUF7qoXNVgXbG33gFKLbfNWqbuLUqaiWCb
++B7ahLVPTbm16Kwaw0sEMcSALED/lsMfAgMBAAGjSzBJMEcGA1UdEQRAMD6CHWRu
 czEuYWx0LW5hbWUucGctc3NsdGVzdC50ZXN0gh1kbnMyLmFsdC1uYW1lLnBnLXNz
-bHRlc3QudGVzdDANBgkqhkiG9w0BAQUFAAOBgQCBBVEMkprc18bqWcZ8P93JGc1r
-lJoSARfIkBuAkJODyQHJ6kp6fq1kuR8seax35VPNXIvBlPqXoS9zvXYVmF/qOJEk
-TtW8YAACZywn02dM5CQRS7T9HCcBJeFUHxbGcBCY+AqzbhM+tGii6UnogjvqdKje
-ApVvu0m4MsSn+WWQlw==
+bHRlc3QudGVzdDANBgkqhkiG9w0BAQUFAAOBgQAcbbxoyusUuTKq+hz7wLiJfEis
+UHrq8BwakaOP0zTln8XBT3uvNeumjQQGciqMNsV8QQ0xT3XadO7R9ix5V5IzTxnC
+q4s1xKxSJsmVcPf9Ql43ev3S+lRnyw1ws4lfe9hOdKfOopjHpa+D2VW8/iRfhNj2
+PO7iYMyUZKXB0ynKTw==
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-cn-and-alt-names.key b/src/test/ssl/ssl/server-cn-and-alt-names.key
index 7577e6f..a1ca8f4 100644
--- a/src/test/ssl/ssl/server-cn-and-alt-names.key
+++ b/src/test/ssl/ssl/server-cn-and-alt-names.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDB+zrUb1tKj4GAzCJ5HdJoCp6oXsRFJ03/dJhooc3eLMPdSdGy
-QZwv8Hy5qT/WtcDsLwJmtRkidtZSxa0gvG15E/upyIql5RSuB6lucNz5LWztSJ7o
-xUtT6MVznZUsHXCM0PlQ5Nyr9yFZwqvcPK3HIbYZ0m/t5GMeUIwNBm9b4QIDAQAB
-AoGAVOp2gWJR81zI0yoJeT2dyt/DPm9lueQP1+EhisQyC61K/IcBHehsx+udneTC
-RmqADqQxh+aFHzoobkmMlUUHInIF8gQe/brw6s27BemUSrT2M47BrZINnOKTvhVa
-6xnqcD46DkdYE3z4dF2DsZ+uzgw/bO4sksw/yus2C+2tLlUCQQD8dy5+Ivw7AUVW
-H5VNR0joFlR8xeJA8FA460+UhNle/oDtqEjq/YDotHdOnd8EePpR24/c3cMVfXj3
-uqTnKyo7AkEAxLJx8D55ZiDQYprL9DWONVuEk5WZJZIgCNRX+hlymf00Hfm67cue
-aD0Y8G1DA5vNywNVpUihdm9wDFPz/PSUkwJAevnG4NRDzq4QyyG5RRpLDhoKb3io
-e/9S5FbivbJ0e4w22wzU7/opt7BoSRgnUPNo40Sy79/precfbHQy7ROejwJASovu
-zsR+sgwhrh1Iywc5HFPRDTYXUrvs1CvWI/1dB6uFAw9QnysaoBr3xrdCPK3h8t0S
-qo+6Ue6uIp32zJnNbQJBALLb34EY6Au69ztILcUpYgzTE8wmXtBTt4RBQDMIw+F1
-ZBw3e3tZjKmOPJySq5v8jyNF5L3s5gd/GRtPRCTkOfo=
+MIICXQIBAAKBgQC7CHqme6RxEcNJ6lYHj3kg3a+/31zDbRf8hZOGWFFxi7ss7Xqx
+FGsXkmAeY5jQHmOwDUY2zG+TfZr6Bx1LM9AM1TRYoXErz+ZwfcSABMqTFBe6qFzV
+YF2xt94BSi23zVqm7i1Kmolgm/ge2oS1T025teisGsNLBDHEgCxA/5bDHwIDAQAB
+AoGAB0Hh+HnNvLFywXh9VBfGHHddrXVOVSrzhlHskob0yhIg9jJU03A2Y5jDcApv
+UIwNVDR/p/qwzalPDSqfgV6GURgqzS/If+qKN7aPiTZPwTB1I9zNVLf07EaZjS08
+IppwpVbFnrJww1WP/P5VRZxnkbhZ0ClZWm3Bo/V6Axi5O8kCQQDitdVoEerONTq3
+a3n6lzPm473l0P+gZdqbSeqRO59c0uMvE3aIged6cPQZ7WIAivID7Wh7AP0zHetz
+NQOCw1fNAkEA0zJfIDyNtkcuPzm9Eg5gQzdgusZ455Eij3VoSRJTX5fLDaBf/lo+
+z6bsGqmnGK8JVtKkpvSPV0L9R47KDCUCmwJBAKlWmKi7eV+9crY+mUYMWsBDrDxU
++Bue+MK1W3hPyKFVBEzNhORB490ZMbuMDH/LSSqV0kzOWFIuLwhGuPCbaKECQEeU
+VvFSFKWm0mHTa+VmwfGGH16uTeQOKKx+mm3JrEBF7igcJuzKIWe3p2YSAfQ3vu6S
+TgPX940Xw0gxeQFMuekCQQDHuGhGdj3faCSkW8/dIkAX37/VkOxSvaZGpmDxclZL
+g21KLL9Ng6wI56wvMo61TCK5gEPnpmDB8H5l3VULt9Yn
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-cn-only.crt b/src/test/ssl/ssl/server-cn-only.crt
index edf0bb8..9891072 100644
--- a/src/test/ssl/ssl/server-cn-only.crt
+++ b/src/test/ssl/ssl/server-cn-only.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
 MIIB/DCCAWWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owRjEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z
-c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOqxI3Umy7P+
-FqPSenj/4SgwJgKMM73Q0tJvaDNXb1ipfAUHbvnKCNUs693YjRdZwTAVXsYq8btC
-ja/4L24FLCNktLzQfxmVuueMgi7HuYevxVbhOXhxuy8cbTeC6FZj3F6vU7Obg5rM
-L6FNzVljbtx/YA2lM4H/lWafTp0mXnmFAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA
-DLLwuxmM5ReGFO6L95kxK++vFa7oXNBw8JxagzqfnF85N2leNbpQxxsDS9U/Bavu
-D0okKJR1ezdWlT0AwJcOtnt/X/qoxVFo35rIEjDZv4rWveiPwe3BeYm2tWLRHgKI
-6NrPD+kXXqGFPHobbXBPvE2MrW4p+ojD0DTeO8ZXjj4=
+c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALkR7DNyRnAE
+D7ZxnsfOPQ55QB0nM2onJmVZkG4EeqQJ6GZHJym7pHHwbww+dgXvlNzkv2SOvA+Y
+q8TXgYvSiKhZ4N4ReSWWZ71P+RqJXpSrj6K2mVKOw0Rno9kMt0370bQOnkvSQY9B
+WxJbxji2ks3oj4wma+1zje3i46IlwoYHAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA
+G2ZMgJnCz3/kDv30Uun3YzVktMW4O1y9AbFR1YrbHM8xvVGFLpp9z2PVYOKwKeND
+oS3UjW/wJynAT3xPwY3Zg6GbTqx2Fu8BG9bb73RK2af1IT8sB1Pxj8t4kZr0egaO
+m8TIbipkZNVakwG9idiVYjn4CusqYthFsOKW+OHiM3I=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-cn-only.key b/src/test/ssl/ssl/server-cn-only.key
index 9037a9b..f58af68 100644
--- a/src/test/ssl/ssl/server-cn-only.key
+++ b/src/test/ssl/ssl/server-cn-only.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDqsSN1Jsuz/haj0np4/+EoMCYCjDO90NLSb2gzV29YqXwFB275
-ygjVLOvd2I0XWcEwFV7GKvG7Qo2v+C9uBSwjZLS80H8ZlbrnjIIux7mHr8VW4Tl4
-cbsvHG03guhWY9xer1Ozm4OazC+hTc1ZY27cf2ANpTOB/5Vmn06dJl55hQIDAQAB
-AoGBAN1Vp9oBd5VNqS5g/y4EK+VJ218FuHpoaZsahEv/Rrx4QsU/aHLdDg11qxBy
-/UUrWZ2uWc5Mi+ON9bAiQSDicec0ybYD5+Nn3Yv6v82J4Lr6Nlg6lsMSXxr0tfh7
-1Jh4EZWkIvMilSyo2ft2bP5o/rBCiIKXPzLDOmaoYUurNwPVAkEA+uR8icow3Ig4
-DXatPDIVaCr66cfndBSmbXe9M0eY23ic/8VNqjyuo3CNLOqBupl5teZTv6dTLXY4
-9RD5U3x70wJBAO94OTptH8Mp5aJX5PX6x2eggydTBnSNUyZZp1FquFpE5GRhyd5O
-RO7V4f0fcZCyuJcZI9xNvkqLIC8WzyZ8FkcCQQCwJk2d/HxzyZv5L/KPCebnvQ1v
-p+/EG1+CCgingUQ8CyHHngJaXMKMc9Ba0ccFeQ3v/WedbuBCUffJcAJtcEALAkA7
-fIn60ZDKUmYQ5fSihiFyxJTP9/fqjBDTvgGqX/BbvDFgHkqfRqIpEkiJMH5ti3f/
-UOdvmoBi1Byyld/vl3ORAkEAzruQTKAG5HeD+XPijO1qtaNXAiyxLr49FkJsm/Yx
-sgM/ZMbLmYZwu6JHt3+Tvo1++scUuwrsYCUmTP1+Ca37Uw==
+MIICXQIBAAKBgQC5EewzckZwBA+2cZ7Hzj0OeUAdJzNqJyZlWZBuBHqkCehmRycp
+u6Rx8G8MPnYF75Tc5L9kjrwPmKvE14GL0oioWeDeEXkllme9T/kaiV6Uq4+itplS
+jsNEZ6PZDLdN+9G0Dp5L0kGPQVsSW8Y4tpLN6I+MJmvtc43t4uOiJcKGBwIDAQAB
+AoGBAJzj6r86UyhG6SMbcyWjWvNYKtgMEXQeOFiW8u+xcF57375E95hTcHb/AsT4
+dolVr3cLnI0cy6TVIli+8R2dnybVxgdV/NSWLk69HDb+YPh2cEA7TxAb3vSfMdyJ
+T4uC6ibyjAaWdmEDYhuhP45ALf8MKYHEdtmpdGVU0TtrcZThAkEA8oERu+OPXEVO
+OG6yJh6JKwrGOv5jEVK9G2v9ns0LiJDhnDc/wTv5/zq6GIQlWDViV7dmtYPedOAr
+Zk3e4HNUHwJBAMNemFSkwMew7jI0yQKuHLN3/kKQXi70ZGXHr6i6hzlcxgoa68zq
+Ayx9/4m3D4ucwzSTQo/84p7PA+JXTGLu0RkCQF07WgIOXtNuob/4bu1Q2BOANO4B
+Vz0VvjaIsh0XX9PFP7e7VfuIf3isr1c1ltXu0DxA+m/WnvP4KzdNwN4x+KkCQCrP
+mr/Jjnjzu26DBJ0yvBVTsQKzEgBmC24GMObfYOxf+QGT3qH7kZB5V7q8w4pLYrct
+ocNdnedA49AAYzu2q1kCQQDR5DJ+L/kM02pV4LLhbQ6U6nhBKDPXY26nob/TAtwq
+eODDcDiceMGKThwwnGEjEeO2w4uZEM124v5sJgZtlByD
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-multiple-alt-names.crt b/src/test/ssl/ssl/server-multiple-alt-names.crt
index d15c911..c330d4d 100644
--- a/src/test/ssl/ssl/server-multiple-alt-names.crt
+++ b/src/test/ssl/ssl/server-multiple-alt-names.crt
@@ -1,15 +1,15 @@
 -----BEGIN CERTIFICATE-----
 MIICPzCCAaigAwIBAgIBBDANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owIDEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQC0Bkarg2DSU/0+vFG5dgmxV38SSC006t69zkFmrkUMIEg0iuj4I44qlOf/6EP4
-++RfDwQpiUNRTQmTNwDmjmc1bsXysIvVPzIDKEgpvqI82T1sLpF14PogoNlAzdpu
-CnpnU+QTUS3Ic5dhxK8YHyVtsG5nfF/3u1S15p5UaPGiOwIDAQABo2cwZTBjBgNV
+gQC3KEGfUWKDHb5tzwJ58o5GaFwUctjQxOg4Wtf6TvBRnuAd7VYAVFRtdPLnH9k5
+dHDUpMw1bHx4nUmbnphtLJDS8VVowLyjKGAU/uOuQidUk0nCSllHPaE8soBZPV8x
+BwG7TQ47GO7Jg4dmcTLF+E4m3YbzHglOmoN5+vrwWSJnLQIDAQABo2cwZTBjBgNV
 HREEXDBagh1kbnMxLmFsdC1uYW1lLnBnLXNzbHRlc3QudGVzdIIdZG5zMi5hbHQt
 bmFtZS5wZy1zc2x0ZXN0LnRlc3SCGioud2lsZGNhcmQucGctc3NsdGVzdC50ZXN0
-MA0GCSqGSIb3DQEBBQUAA4GBAASEAOEwDFE4qCPXJPpEzma7+vRqVFedWPXFXoW0
-R3HCGlvYJKwnlgxf41ipWHWmJPHLdg+KVJtlfRQ5U2SIIn7yjr3Wk+apcvWMvDpQ
-lkIVTwCmSINnj8GjQqgJsHD6I75edRaMQk3PlurzdBWJp6oz+UWbYvGDRDC4pHWu
-nLhZ
+MA0GCSqGSIb3DQEBBQUAA4GBAANowuGrcHzwfVLHa1PC4W0obG2it61VaA+OFHwv
+OAloZTbbNslSh/RGyrD2ZafRZpZNhjNB3JRIt7bv5Y0j5YP7CQkp2ucD90V580Pe
+vuoP+jZ/f5ZIC2ffiG9ofPxQdJEHy63GWHSH668rWQBc12GhHqgwZXNoWRMJxVrj
+EZqd
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-multiple-alt-names.key b/src/test/ssl/ssl/server-multiple-alt-names.key
index 64266e3..5969b9b 100644
--- a/src/test/ssl/ssl/server-multiple-alt-names.key
+++ b/src/test/ssl/ssl/server-multiple-alt-names.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQC0Bkarg2DSU/0+vFG5dgmxV38SSC006t69zkFmrkUMIEg0iuj4
-I44qlOf/6EP4++RfDwQpiUNRTQmTNwDmjmc1bsXysIvVPzIDKEgpvqI82T1sLpF1
-4PogoNlAzdpuCnpnU+QTUS3Ic5dhxK8YHyVtsG5nfF/3u1S15p5UaPGiOwIDAQAB
-AoGAPa3gzKbIp4drPvFatsZAb+hgey0LgBPwmOtv8PRIZ+0vkAD/7PSRovk9u6oi
-j84N4pvMe0ayL8rLOwsfXd7wcQTxDPxy+RkkMW7RRFzusPjeTMgS753/l4IqehCX
-2SLPBkE9e3/UMRR0vds8T7btgTrv3R8pcgntli7W6RPrmLECQQDgZDjxx9X9O36v
-SR29RhMUQdz0PQpHYwhtmBLECmr1Lpecu5Zr0JOaabWvd5Lzx1cV2hmldZFQP/gO
-fEdzhsfHAkEAzWIjB0y/NH61U4Bj4fML1dGnMEzO0wm0MVEMKjcmPJUbtktvZ6jD
-MedYw5VLcWbjXMAJt70UFjcxxAJPmZXZ7QJBAMKEnwiZX1uCc7OoAmvNj0SEQ/JF
-598ybl/y8HGZRlb86NkplKAp04qMEL/nPDCvoUKEKq9QV4PlsDd+bMItGIkCQFml
-omCHUVZakE84VWDEs7/K2U0t2YEoVSzJkaPDmr8K3qO9XY1Djp/zuTz1p46COG+9
-qwA2WdQwl1pVH+WMESkCQQC1UPYLBYIDj0JaJokSgBPh71Ui8/iBP0J1cvhvKOsS
-LrEO4JUq2HBFVcxb7QahHPC22dWI8HlIJgzlUi9BEJPv
+MIICXAIBAAKBgQC3KEGfUWKDHb5tzwJ58o5GaFwUctjQxOg4Wtf6TvBRnuAd7VYA
+VFRtdPLnH9k5dHDUpMw1bHx4nUmbnphtLJDS8VVowLyjKGAU/uOuQidUk0nCSllH
+PaE8soBZPV8xBwG7TQ47GO7Jg4dmcTLF+E4m3YbzHglOmoN5+vrwWSJnLQIDAQAB
+AoGAPUp4Y0MNz0il0ANFFd/oYoFLxwADtCEggLNNsRK3cujSoNEqRWPy+Mn4+wT6
+YTKpC0+2km4iXQ5tcmkpIueV8qAitks7n8Ed7qP9Le4MXePnzgn4lL0qY1zExESX
+ibAQy/ThPdRuWvelpAXpEOMZclZsix6ksFaAMdC7o8+KwdUCQQDcrd0/X4N+wlSa
+LBUcnTmhFI9gcPcvckZoxISHWV2B/QaDVvGA2gYMNJa3lEcuH07LfQh0rraEzAP3
+AhG8BRPnAkEA1Hj2+qKf7aBqcjyQ5yHdxsyw/wFF3ivH5dW7mShi/C6fo+qj6WSU
+JNLPN3nhJ++5IH3DuuCTop1qNwk9jEOJywJAQED3bJ5Y4S2gCIvRUdWNlBMyc/gw
+YMY7LgIaPHaOvWx42wETrFrO6/rb73PjDdDb1m//aEn+psfoV6FonIA1/QJBAK1D
+c4xRf39k2EkN8NA6wsKx+wgIPrR9GUboc1HjKE0jrBUca8wQs+oPauF/Z0eM6nd/
+d1R2fI4YNhxpUaKHFN8CQEpJAGi5/CfFQWdGuDbJwbXwNA8zKlyGohE/lGfjZx55
+LnL3KE/rQXKRaCmLyk5Ce6oZQkDiN7GVEwEz2wMJlys=
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-no-names.crt b/src/test/ssl/ssl/server-no-names.crt
index 378050c..e130527 100644
--- a/src/test/ssl/ssl/server-no-names.crt
+++ b/src/test/ssl/ssl/server-no-names.crt
@@ -1,12 +1,12 @@
 -----BEGIN CERTIFICATE-----
 MIIB1jCCAT+gAwIBAgIBBTANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owIDEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDE2mzybnsgbq7owCPC0m+igNt5pBk5hDpzFAhpbAZ6hZ85AzHnLbpCDTH5w0Zm
-HeevCRkNcDgjqfoDo4DruXYpI8jH+QwuKvUwTt3GGm6C4lb3SBtfNdzJsk5kRE3o
-ziMG/OxtiApxFu14nbCnqMuDs3meykD1jHheK0CsHCKq2wIDAQABMA0GCSqGSIb3
-DQEBBQUAA4GBAFNfiKDTLJ2V7kgIWDEOcyKQY8T4cAzgz6jcpN9CePgATB2Yrb9P
-x7kkKW68h9SbEk6qtS4YQZjSXWKUqrjjIW22+DJSQAXMZoyADZTnZOASHjNXIzLE
-y6B1RX+c7CjolHHSYkbki3RqKGhTQr1hnwkq3N8Fl9bftT5zFuezwnjD
+gQC6VU212xAM+d99liOE5ROUG7qwuHhELgNbqGxUgNu8S/nKBrZSsGzWnqA4//iG
+DXTZLHszRctXVrkhq2VXFCmRZLajk8uw4GtGCwb/HdvANrDM3rwiU23yjX3Q5Dvh
+vHgkG+0PBf2Ghr+/XEbDkAwB0xi8QhO33F+1uQEH4XJM4QIDAQABMA0GCSqGSIb3
+DQEBBQUAA4GBAFBH5fx/I61acluRFTP5RJ8aymi8ez37+MoQ+Aftj1BXwcGSRe2E
+57c0VjWUooJGKy/gs/y9F09JngEhFRz0pUCMAKQMaciEJh17ai+QOuSo6/NsGA50
+dw+w4UrYbxJK1RxhgKIYY3sojJ/6G+VbprPlWtSPSEcukRGjj31XRIfp
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-no-names.key b/src/test/ssl/ssl/server-no-names.key
index 01a0915..da86d1e 100644
--- a/src/test/ssl/ssl/server-no-names.key
+++ b/src/test/ssl/ssl/server-no-names.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDE2mzybnsgbq7owCPC0m+igNt5pBk5hDpzFAhpbAZ6hZ85AzHn
-LbpCDTH5w0ZmHeevCRkNcDgjqfoDo4DruXYpI8jH+QwuKvUwTt3GGm6C4lb3SBtf
-NdzJsk5kRE3oziMG/OxtiApxFu14nbCnqMuDs3meykD1jHheK0CsHCKq2wIDAQAB
-AoGATKkLWHXx+TVhZD6/LnWpB83KqtpfAGkgIgShKfzpoPk8goVd/7ttF5/v4GZN
-miL3QND4MqWLF0hwls4rvKDjBH7q4zw+AR55pnfwoQMsfqMvAn7wZi5HKTah1xbj
-yf2J1N62pNW4ZdFnlcXmAPLVDxKyCYaZqdeqgr4VkLvgIVECQQD05OYFasP/5be1
-wSj7zxd5vPK2/EJ6CFN+gwXXYOZWWR7m90g3CXxMWeH7RPIlrfcPC8o8r6xna2BS
-E+BKzTYXAkEAzcfLpwZUHcCPrCipMsoC35FQhNCpecuZjVYx0oGsfiE6gu87ddLX
-H3YL7+EEmtPdps4fF/9WK87MSpj1IRFv3QJAJIEOTJZqmvV6GeyuGEL5Y9snbuFR
-Y3FkSMJtF3rJOuvT8GfB6vpN/e+UAOl5EubIogSG497n2w6lb/aog13thwJADtel
-WcO8F3VHJ5y7L32gnW2GyD2gq7dCuQ4Jg+x0e5h79uu4dzQg7hT+oWuygFRdvWVK
-mtmA5qIA3DSSIbN3RQJAd97xYxEPMF2NU+vdsLBxrkdH9tCHrqOlzEVTdhBCJrx/
-L/lJQvtxkpWEiFtQdd5OhAurNZ6iWoIdA7fhNHPCqg==
+MIICXQIBAAKBgQC6VU212xAM+d99liOE5ROUG7qwuHhELgNbqGxUgNu8S/nKBrZS
+sGzWnqA4//iGDXTZLHszRctXVrkhq2VXFCmRZLajk8uw4GtGCwb/HdvANrDM3rwi
+U23yjX3Q5DvhvHgkG+0PBf2Ghr+/XEbDkAwB0xi8QhO33F+1uQEH4XJM4QIDAQAB
+AoGBAJrFaDr5rqdYlc6W+wHT1SNctQE8+IiJP7jOeMzoC5yn7t9kG+UrLfxG3gb6
+ds/CNaB+VgcMng35tuTEnPRrhuoWh3d0jWZ/QqMklPMyrLO5s0wEOuW47D/KI4MR
+wKoucQW44LrTdQgKsa4ZJbILKMScanY1oQXXjq4tueZaxajBAkEA4w8gO1rby9zQ
+fIp2C4Mfi9Pe46c1/bM+AD+9hXRO9oYCE+aoi0ww4/qvE5fMYQluSmSd8Yhbvuzk
+nifMF2l5xQJBANIVTdPudQvviCoXXtexl71b4KVdX9EjuWTNTCx64YB2ISg30YNw
+xvlPvDQy/EvVj/3wSGAy5M/7ZVpkXCQe5G0CQC/Jgi4bzECWo6Zieb+ohB4opDNj
+gMB5VeY1hAyvUuMdhxhrJjPTAEMrAmfsPc56bqTnkjpASZbgQqlqlNCkmUUCQHlV
+epTLpWhWWMNOqiVTWbsxBGcdrchhpKLWe4c5FWKXV4Ed8/DBQvodFirjw5mc58QX
+cgW1fzesD5aMXjcybGUCQQCZwYJir3OQC+CJCrsvACSPr3SQm28hiuO4P41dC7eT
+JWluvXOGmWnZwskW/+6imEe7pGYnY81pKThnsV+CXfN9
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-revoked.crt b/src/test/ssl/ssl/server-revoked.crt
index 0197116..08a5e01 100644
--- a/src/test/ssl/ssl/server-revoked.crt
+++ b/src/test/ssl/ssl/server-revoked.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
 MIIB/DCCAWWgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owRjEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z
-c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMGFtZgJN+Lt
-w1Bu6MmAB6h9IUrSFEVxUrrxwz5RG3UDiBkr8StZCM2hXLdSB9tSjBLIWILmuPCR
-ydyf70XFTTO8L0Mc6F38I+4GVthNp8h1VJIrl1wRQIfVqFbbKYKiyCQYITzezVuC
-UjHjo6xklmMewdInRrcNbWxNVkWH91zLAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA
-m9bRiYypdOrU/1hCzo6bj3Ly39/zUZp+T5xBkLJQpgVLTU8GSEdP35kc3CWzEu77
-39610RY3X0A5fNTLs74t7w2dCViYPvNu/suu87AVtlioHMkwL3QEOUnWM/l23XUR
-mj33SwQfmLOV94cNLVTd8IZ9PIT0ARn/YrS1Prx1zeg=
+c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOmX1G+61akp
+XA8zveTsQOtipWN8UzF0TbtxFO6LndM4RMlMFPrS/18KAbOFcfSjQvw9dfMXfOIk
+zuwIYtAPD2qVyWAGRvk0Xl5qEz8aaVBbayUN5uRMByF2vgbOMz4IEywNRTWZRS2x
+kAFO4/FCb/LRxD+82yck8zcZoL+SdbZZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA
+LryjYf+t8X5j4DeeRN0uh3OWUpzFo7FaVcakjDQSgZIdlgA9RofL81yzJZAoSqk1
+zT8jqo0HKOAwunbNJxhIH54gAIpsEE9624IUAoLMo8OUF2WdMWLXJJTljfbXx/Tb
+4ccuQvMLs+Um70Ogc7Mqm0+BM5N61lBdJOgMlDP511E=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-revoked.key b/src/test/ssl/ssl/server-revoked.key
index b12071a..3300417 100644
--- a/src/test/ssl/ssl/server-revoked.key
+++ b/src/test/ssl/ssl/server-revoked.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDBhbWYCTfi7cNQbujJgAeofSFK0hRFcVK68cM+URt1A4gZK/Er
-WQjNoVy3UgfbUowSyFiC5rjwkcncn+9FxU0zvC9DHOhd/CPuBlbYTafIdVSSK5dc
-EUCH1ahW2ymCosgkGCE83s1bglIx46OsZJZjHsHSJ0a3DW1sTVZFh/dcywIDAQAB
-AoGADWTrxLIepB5AvnhutEOgRBElFMCllojZaQcCtHV4qQititB3yMBI07KvcCDF
-WnDEMSict7KwajYs+pA3R2T4itVLCoz5iXYJ2CIf6XOJK+NYcf7XulSm5IqukbqT
-3KlofUY2GY/5DN9tgUUnAsZ7wh6iMaq/H+BPBcblZg2kyYECQQDpYRAjwepzpr0P
-gfohKYlfKJwQ9WWTRkMasn6q4DY6txeXNk5nMC9C3FHeiTgpfRr8GZBvk61lb6pV
-pFWADR2TAkEA1EepQ95Mums8BxU6/PAOhXKLlyYvldaIXcajv/+/PclVuEL8ko5z
-jspEGk7U/jqonwcN98R/h4ui7nxhoxIG6QJAFydgGIwWnJ7ARxeYH04lqOE4ip4u
-E6x23+Exm/ZeqvibSI9EvAwVxEZjgPaQMd2NndFTeR5np5aqiZCiQvAKLQJAfRs+
-xqDc14Ebf5Ejkq5n4H4BhrMamFQ3Sg0ntKAlNWTTACV6dWU+9Yh/WoHbRXmMpyyh
-LsS/5EKHY8YqRND7AQJAd+qIgqFUI0RAwvbmLxW/iR5JIKM5kZ4xJ13/O4x55XEI
-4H+8YS/nYPnjMpaEWrFppNfv2UEXD2L1OkJVuYx1Sg==
+MIICXAIBAAKBgQDpl9RvutWpKVwPM73k7EDrYqVjfFMxdE27cRTui53TOETJTBT6
+0v9fCgGzhXH0o0L8PXXzF3ziJM7sCGLQDw9qlclgBkb5NF5eahM/GmlQW2slDebk
+TAchdr4GzjM+CBMsDUU1mUUtsZABTuPxQm/y0cQ/vNsnJPM3GaC/knW2WQIDAQAB
+AoGATDyWQ6TZiK0L85Yyep00jt4SFkcEK9bGa897QmNkrgPmR0BCdJ4aZF0ysvFx
+gKMsAIDaluzqgC/9LIGMJlVT9RisKWQks2cPIs5gERmYg7uNzfYegbn4N2liRG5z
+d7aWevi82Dtie1xch2DdUW/mxGdvR4duyXOlSYUhbDmK8oECQQD4MylmccYxz8Ry
+7APVKXPMhSCmD86y4KGfWGtKuLo4vF4Ifaze7sVtEBznNQLIAn2U4M5XD4to/VQN
+2nT1ESHJAkEA8O8nDKC4vWtCXzMD2/DdHrJjxhCPbDJFp24PRFUia1yUOAgqcnfv
+UzXkdcxSv/zUBB/WejLEvvrQ6Ib48Lq4EQJAZ8ashsMHhYhDsXFxYM1GN7tqHUT6
+vdwid8e2hLWcV2CbSJ2TjFr1fVaBX0LQ+OPhskAUxl4fgjR50pkG0fjp0QJAJvB/
+/yp6sSKEt54nIYTsN+nc9kX26CW33DeNgB3CUlfEHMo1EgsQQwKSyfcb6KuUGJaM
+s3NBGRywZuRpl36WAQJBAKgyfmq15Ggoe4rQOyO774e1mfUQW6/fWVX8dE09ZxXz
+28Sy4/K16UDUzIzzuaW3L7WjzCKql82vy2PpmWX28OM=
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-single-alt-name.crt b/src/test/ssl/ssl/server-single-alt-name.crt
index 349792f..832aa05 100644
--- a/src/test/ssl/ssl/server-single-alt-name.crt
+++ b/src/test/ssl/ssl/server-single-alt-name.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
 MIICBjCCAW+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0
 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl
-cnRzMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1owIDEeMBwGA1UECwwV
+cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV
 UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDnDMJShFXba5o4o1ubyRmV9AyJLVM+8nZaC1iJzqeIPObXYpbcp3bhXtowAwvk
-d3IGI/fBm/2/NKvYnyagTS9DUNRTnykHxlCKsMitx38+sU1EerkDltK0OId+obvZ
-eVD+h3j7pVfA0NPKXkpcP3xoihQU9I5kOPKQEIQPNAUfdwIDAQABoy4wLDAqBgNV
+gQD8lRO7m7xRlUJCKdkHdPnLKu/pbHLBgIYJk33nr22CQaM0UCgfCzr0LPaPCtlF
+r5D/WS/MIlyzaXHHJMnzbFB1bx3T9BQijobeO1LKS7s3ZyPEaiNVJoih6ZXlXMQ/
+sPp887EChn+COh9BWgnWbSV0Zq2m9bggDg83J34bIeWOmwIDAQABoy4wLDAqBgNV
 HREEIzAhgh9zaW5nbGUuYWx0LW5hbWUucGctc3NsdGVzdC50ZXN0MA0GCSqGSIb3
-DQEBBQUAA4GBAHDkKwNT8p+/sv0Q2dIo0jdFxtBdS/fnsHzjr5ZJNa9SXEer5m3v
-lMllzYW8lfTdR9PgBZ3y2lFZixD63ZF3nkIEYcD5njLp4ui7g2OVqxRfmt+rHefh
-HiKm5v5GLs72lhR4GQT13AsjGVS1WWZtYhO4LwTjN+nbjnRIpXIhrSC/
+DQEBBQUAA4GBAIIcaM6MHSbH9t8cQhgWKXhjqlph/oRsNwTTalSamLR6JeT9BWxp
+IZXrsgzIJsVlTSHj8JRZnv++6TVDe/1N2MtwNfJUqnblIFwaf83kulv18Vhwoh4l
+dqPNaBZqdk9+EWJwPSzolK2VRKZcea+E2sMZBTYAV3pijy1k/oC8OX1V
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-single-alt-name.key b/src/test/ssl/ssl/server-single-alt-name.key
index 71fd85c..90b6bc4 100644
--- a/src/test/ssl/ssl/server-single-alt-name.key
+++ b/src/test/ssl/ssl/server-single-alt-name.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDnDMJShFXba5o4o1ubyRmV9AyJLVM+8nZaC1iJzqeIPObXYpbc
-p3bhXtowAwvkd3IGI/fBm/2/NKvYnyagTS9DUNRTnykHxlCKsMitx38+sU1EerkD
-ltK0OId+obvZeVD+h3j7pVfA0NPKXkpcP3xoihQU9I5kOPKQEIQPNAUfdwIDAQAB
-AoGBAOP42uPAX1aY3Rp1VLZpvi0PGC9h4XmCkvRVrY6LsRHjxYFPbbtaIRpOFMq6
-tsk+cetNIfCOkdhPiB+9KMeSYMYShiyCrHfFxuS0FIP4rQhBB89wzcjffw2CYLGD
-Umx65+XVv6RBW85p6v4s1+LQMVUtf41yxm9JXT0TVDjEcgRBAkEA+/FKxv9DuZNZ
-Abjak3MeaULpnPl+Fxp+jg1M4wK12MFYCm2eBUx0X+cqVORErwLJ3gdXQBT7fJQz
-bNwxjUKuTQJBAOrFVKF2dtuPAeFBlKG4sy5azGfgzS6cAJQ4LPp4uGX7ve9C8OzI
-oZU21LT4cm3nuFSeMjcCKHmur85gFQrETtMCQQDKWu1yk8gzn1OX/H8iew3sAaBd
-Qk6yA8euFKSymJSyOeiax5xqKRQ3ixYHBSjdYGH/AOplP/UWBHqhbuIl0W7pAkAr
-f9qZfCizr8CqawtOF7njeeFr0eRSoYcd73auBhYsl0NvBJk9VkNSMXGiAnK5WHj3
-/MPTG2xCd5KNi5H6h7sPAkEApf8JUvEA5ZPkFAA6x+OXLmEL+nXOnJnhKjSUIVJx
-Pgp7FTy6eKg+/iUEyhRHw5So7QjwHqH61+CIBNS41vGPuA==
+MIICXwIBAAKBgQD8lRO7m7xRlUJCKdkHdPnLKu/pbHLBgIYJk33nr22CQaM0UCgf
+Czr0LPaPCtlFr5D/WS/MIlyzaXHHJMnzbFB1bx3T9BQijobeO1LKS7s3ZyPEaiNV
+Joih6ZXlXMQ/sPp887EChn+COh9BWgnWbSV0Zq2m9bggDg83J34bIeWOmwIDAQAB
+AoGBAOkekmraLvJBRzkXtJZcUVxBkdIn5LZRb+SQu2jFkdXhzMawoIceb1gD08Br
+6+KUSshSQXov0M1KKdf6TWYc9xfGg0+XgqPLw0CIJjdO8TZkIaaHZU803snWtM0e
+9PlhUm2T/RDdx0cG7HD4WR8x5ij1Fc+W5QsDOi5oCke0XC0xAkEA/+rmRUaOSOaI
+CohIH+oHlLTLfr0acAP2cjQHJkf5OUBVnyirfCcsFsxmnhvARuuIdftwd9p73Gw9
+MIGVV6TDIwJBAPyp5xByHy7sicsi2ynSTpS9JhuVvR9cdKBLGmbPQtS0Fb0rannR
+wyybfFIN1trfZJ6QmNKAPSPfUFhre3b4WikCQQDVOZYaairquojmnZ3aWVdvoyNZ
+uZ1pbyPLC2ZZkuYnuV6deXlHvCuT40Iswdp2PJA6HQEcG0HP6a8h1xXjLDgZAkEA
+wMKirTJTxgnh6l9SUyrGlsVjoGHx4k44D96catkvBHXLrAHGft/ghlStWTCDvYH3
+Et4AKYB6pLaHZp3BmPdKWQJBAMI65XkJC5+XESMUP26lC71eo6tMcJ9fBKOa7PEW
+M9I04AeId/3nbA2eKCebfUzrZOizeHHOjhH3Dubz3df8Ww8=
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server-ss.crt b/src/test/ssl/ssl/server-ss.crt
index d0c9b83..9b4f4d1 100644
--- a/src/test/ssl/ssl/server-ss.crt
+++ b/src/test/ssl/ssl/server-ss.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
-MIICCDCCAXGgAwIBAgIJAJyw4sQKTY2UMA0GCSqGSIb3DQEBCwUAMEYxJDAiBgNV
+MIICCDCCAXGgAwIBAgIJAJ5i7OAq01pyMA0GCSqGSIb3DQEBCwUAMEYxJDAiBgNV
 BAMMG2NvbW1vbi1uYW1lLnBnLXNzbHRlc3QudGVzdDEeMBwGA1UECwwVUG9zdGdy
-ZVNRTCB0ZXN0IHN1aXRlMB4XDTE1MDIxNjIwMDYyM1oXDTQyMDcwNDIwMDYyM1ow
+ZVNRTCB0ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVow
 RjEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVzdC50ZXN0MR4wHAYDVQQL
 DBVQb3N0Z3JlU1FMIHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
-AoGBAOqxI3Umy7P+FqPSenj/4SgwJgKMM73Q0tJvaDNXb1ipfAUHbvnKCNUs693Y
-jRdZwTAVXsYq8btCja/4L24FLCNktLzQfxmVuueMgi7HuYevxVbhOXhxuy8cbTeC
-6FZj3F6vU7Obg5rML6FNzVljbtx/YA2lM4H/lWafTp0mXnmFAgMBAAEwDQYJKoZI
-hvcNAQELBQADgYEAGweDmEYzoEWb3WNn7Mc58ToPnl5DbRZdVmRjsyC6J5oZRu2E
-e/GZZ/1MSNPgccoyhdcPmSqTzUzbQnvYsqcHfuncA/oNJR3wvMV/wSy0QepklX1b
-ixjZg9c+mhQ/JTSjYnRK5iSTPNX4F3zkpvP79POuQYl/7Oihqxl0Mmkezuc=
+AoGBALkR7DNyRnAED7ZxnsfOPQ55QB0nM2onJmVZkG4EeqQJ6GZHJym7pHHwbww+
+dgXvlNzkv2SOvA+Yq8TXgYvSiKhZ4N4ReSWWZ71P+RqJXpSrj6K2mVKOw0Rno9kM
+t0370bQOnkvSQY9BWxJbxji2ks3oj4wma+1zje3i46IlwoYHAgMBAAEwDQYJKoZI
+hvcNAQELBQADgYEAZtnJALcQmbqBAm16RE/Smu75lBkniqlB0MwOJyGpDg5DkXtA
+YnZP139cRWKCjbWiYj4hgK0eGGRoBuubF6zRrRlYLV9iyZyRx1cBYyUbQBW+AfER
+jWiL4IBJWn7RNej6Uc0Th8Di5eEZapDt0DFkdALFhpFNaWJIcCUKpqEJHUA=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server-ss.key b/src/test/ssl/ssl/server-ss.key
index 39cf3e3..69bc907 100644
--- a/src/test/ssl/ssl/server-ss.key
+++ b/src/test/ssl/ssl/server-ss.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQC6FTHDuNKbYQChNtxAFLKzJESIKOZh8WpgCN91HFtnXX4hp3rS
-bkEDIABlQdqfcXLk7PmlR/rboOIqwuIAaIa12BxEJ5KW2vtcSAFd17anhG/a9n8w
-cQnoEUvLLAp7V2xGJ8Cu8mtyv9Qsmd5bS+SFchmbIcMZUb4znZfIr7AWWQIDAQAB
-AoGAJvVzAtA6P8+ySw5qVHxA4aKxOnSdr1nU9KBG8ITsWhrH4pHm9BGjSN01V/3O
-oN0mueknZ0RHsB3h3CQLHxzDPwmsah7apU8W/1AVyZ9LDEMuoZQef3+JfegmuNMj
-YYtBR8xozTviOH0UH6t3VOW8Y2TLtZo5kMz3XwjWBS+cCYECQQDlPEfH1x9QGXNW
-Eo37QK4UkL6/2czIXWitvb5+79KiG70XYIxrQR9NhpZHSGjBlS+TqJ4tnQa/fv95
-v4I7Q5NpAkEAz88ax91FeHr8y41s01MmJ6Gs6EOrFEpoHGboDdbwJ50pME5XnVJu
-xjHPklHgwiWFf4dQURjv6hCPUMVpe1w9cQJAZocPk9Ijry+y5kxmNHo5YflbV3OS
-pAsjRpIXIa8iBl9hs5L7Ov1lgscvb7JzKCIRpXlFRiF1YzDqEwoUtW0EAQJAH+/c
-VcsT2ihMoZvilbe5rW2TfT6pFD07MuI916Ko1e25Xssre+onTB5roDklKbFKiwbo
-uQ30ESzqWad9RpAugQJBANmRD25BmlHbdBDg+Zfd+4jDPAjXN8OesslEs5dMvs8C
-vqGrozvmtpLRcLiIitTiT4TzuUPowgZQtCjC0X6jSGY=
+MIICXgIBAAKBgQC3ekl7kd5dbcgs5UDu2im/oNSranNRqfqe4USVtiD9NPEWIc43
+wJhkp7w5BOf4xwWukrhOkpTzPLJwYH5HsQL6gBFZi095VExrdRopmpk268l41rSD
+q+y0eWM+DoapoiU8tZ106RtMVSinDfXpXz6Nh9+WQ7/Q4EHWbREvf/SIeQIDAQAB
+AoGAWbacqaRIk2xznag3WNMp6L5OXsa9Pmgb2IYTkBSvCsBRRd4fxFkS6tythz/j
+4VwHZjXtktXPqSO7qIE2Hf3qkxfBpZ72qrvEDpHLXzEFXUamJMPRDZIBHrkfa/sl
+pq+z0siCwO/ozoiInQFxArHeZs8MoGd/FYtECwbuvQd9LuUCQQDkYhlrELE7MB47
+Ot+vgkodp84p2LHlY48cLfn0Es+3aDzusWZbNDENmY9tOubIygh3qo0G2NtSEGVK
+NZzm73GHAkEAzaoUKK3YCD95OKyj3FZ9P/32K1y7JqCH/9ux9dXBQLegdd0hWLk9
+USLlaPgC4FOVrSSbiQHbZ8lUewwtNeK1/wJBALf0nGy0wUzfcTpcLZh85Z4Fb/Yc
+6Q3Pp5IXJmIGVPFyMMJCeiO0Yl6F9hURgJrywOdCpN2DBwWO10dy77LD4zkCQQCP
+EJHnXk8aJbVYpFd0TcHhAvP8ZAxYKXGRnS0lWqWNNG9trf6lbm5mA4VcSLIPhHVp
+NT7wxpbukpGu6uCETInXAkEAhF7m+XeHvJ0vrdpI3OSOVTW8o9QZSqUffsGB6eRb
+v/dJvKgaz3JOzpvRS87lRUd62QfjfmiDXjyhllRn8OPMuw==
 -----END RSA PRIVATE KEY-----
diff --git a/src/test/ssl/ssl/server.crl b/src/test/ssl/ssl/server.crl
index d36ce7f..e481d01 100644
--- a/src/test/ssl/ssl/server.crl
+++ b/src/test/ssl/ssl/server.crl
@@ -1,9 +1,9 @@
 -----BEGIN X509 CRL-----
 MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ
-b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNTAy
-MTYyMDA2MjNaFw00MjA3MDQyMDA2MjNaMBQwEgIBBhcNMTUwMjE2MjAwNjIzWjAN
-BgkqhkiG9w0BAQUFAAOBgQB1c54zLMueMtLiSmBT6kfXJe9o3Krd2n774g7kzNlR
-DeLpCHeUvyLF0m8YK09vbLv2W0r6VQnbjyQGr9xyweRLLtOXc0FIDsTO8g/jvMSq
-Q9zITuqWiCHRbNhi2B3HPo2NsrfA+tQEAZvMUgnynlerNvGkLWQZeC2UsxrrSs4t
-9Q==
+b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNjA5
+MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBBhcNMTYwOTEyMTYzMDAxWjAN
+BgkqhkiG9w0BAQUFAAOBgQAm5J6912hKDUWXyu3yCEk1j3KICE2J42ZjFRvxBNdO
+Zhv/iBjyFI6TmCVJqoe4GJbNG78xmNEl3/2ZUavG/aD0Z3xGu2xm0p+3Uh2zhfDQ
+VEdlgFNKNItS0AtKvoduoZUXKnz3Ft09yLmz9yHLu6EslIsYryi+wnZ5DwUBj5Ec
+WA==
 -----END X509 CRL-----
diff --git a/src/test/ssl/ssl/server_ca.crt b/src/test/ssl/ssl/server_ca.crt
index 517a30a..2bbb8c9 100644
--- a/src/test/ssl/ssl/server_ca.crt
+++ b/src/test/ssl/ssl/server_ca.crt
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
-MIIB8TCCAVoCAQEwDQYJKoZIhvcNAQEFBQAwQDE+MDwGA1UEAww1VGVzdCByb290
-IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcN
-MTUwMjE2MjAwNjIzWhcNNDIwNzA0MjAwNjIzWjBCMUAwPgYDVQQDDDdUZXN0IENB
-IGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRz
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDAYtajRx8vM6IB0SLZsAhTD0Y
-VHM+/+t0a4m3JXolJBbo9/B2/WAN0IH1E2zmlalLc3JBmGsH1a8U5ZlRow3p2ODL
-rFra9FbOl0wekmRFvZeaRln/99dpI5itVpL97QPHO8QMMK1IsyurFA5GfuPOBx9P
-i0MvzsT0tYsRvR929QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAJw4ngOYElfyMYkS
-K6bOgMosrBoX8ns6jQgdXEzf7QOIa110bs6nD+XeJeKmzUAZ3wumXBTalPaiqkEz
-bq4nlsEs1phvj0Coy5eehjV3DB8bDLEneOlV5N9y4Z4VO1BrhX61bLiPXBRp1MZR
-I0sCdxhswSrq02/OuFGe6mqrSBBI
+MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0
+IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0
+ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl
+c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg
+Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c
+vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1
+37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w
+mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB
+paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO
+cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y=
 -----END CERTIFICATE-----
diff --git a/src/test/ssl/ssl/server_ca.key b/src/test/ssl/ssl/server_ca.key
index ac4e76f..668c37b 100644
--- a/src/test/ssl/ssl/server_ca.key
+++ b/src/test/ssl/ssl/server_ca.key
@@ -1,15 +1,15 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDDAYtajRx8vM6IB0SLZsAhTD0YVHM+/+t0a4m3JXolJBbo9/B2
-/WAN0IH1E2zmlalLc3JBmGsH1a8U5ZlRow3p2ODLrFra9FbOl0wekmRFvZeaRln/
-99dpI5itVpL97QPHO8QMMK1IsyurFA5GfuPOBx9Pi0MvzsT0tYsRvR929QIDAQAB
-AoGAcq9i1INvAJFN6cRUdKOeVTbwK3HnQWLjh9mC6bpZxqQd8S94NZK4Pgelloux
-HT9hjGU+CgPo1ne+e0y4ycFaeWf6SFyMJ3KmGFKCliE6A5zd/g+rIp8oja0Y7eLZ
-PUdx984qynfvFMxgB+VJk22cLui9az65WCY+akdWbnwfR4ECQQD4GH6S71bZya9G
-/DDS2YYi3Cvke6wsGSXTMyfDaW42M3mtJOrmoczrx1sAzTmO4rwhuzFFQRs662IS
-/c9nmXOhAkEAyTgK9BNbkb5n2KN0Ebpx+x9cCh7fJ6qY54DOk+svp2jOhBcV9Aqd
-fYPHzPI0v358buPjozXgALNl7FGrO6sC1QJBAPKrwuMmiOVuiav9ciRL8RCYG7bZ
-4Ycg8garuvFBZzRNFW9u9PWyvibCURlvpCVHUo4L9B2xmVkAdGXvLbhAOQECQQDD
-9zKjtl6NuFRGphmaUmxDV605pgtLBFhZzhZh9MC6V9YYyqr0u4nZ/YeOz6wTe0oQ
-bRz7jLKVvCHdX0RWnhvpAkEAhY+plw7q6fyXSBBOVUcHUO2Wtmdm8clvKbs64Wdl
-bjryhvBhq3gPii7jnLGwS2v5jwqCcKpK1tszO/8+gj2T+A==
+MIICXAIBAAKBgQCqZBASGXsZt2GfeEQPnL1ERKry4BAnx5T/QW5F8khTxlnAD7f9
+LklutnlUt1BXAfdPN1uMP7opS++T1wx1dd+38qvuixwmBOU4p81a+RAgLUDKSM5S
+pALgD6t5k2tX5JcE/zAs/zyhgJY7NqPecJjchCcE3ITkOdn2YxXsUYmqzQIDAQAB
+AoGATaLcI7MSgOwqggPFVyu+nS2AiruHAOkSPZ/tg9daFznISRegaK6/bL+d1vjT
+lWFi8ugxQV0EEK710XHpzldQAH0YQ9YA86s7P/a4SjETdRChFYt+CV+aZ4feyNPV
+OZcKuoE82MUFU03jaJsWJJ4jybPPTcZ0Rr25oFpkR2fnPMECQQDXrRWviHuLkmrV
+WqZQLXiPt6bCrTowpnKo62Un5yrA7dehfL9b12J7/9tgfy0ZHXZtBXSHlELZ4LeA
+wpYfsq59AkEAyj99EE++kU2QbkCqYKJ5xBQxNc2ntZ/EfiBXMuQNwncj4m86xFLj
+coFHyOrRjo1GZAFxsZsNbf74xgMLDxIOkQJAHzKiWGndtSrQ2Vvrgt2Q+vkN3ktA
+h5kMLPMgBs2hmZbOAkYRSC+3x0gTa7n5xBBG+S441QPVR78BzFZZcOxf4QJBAIVk
+lH8iqYU6jE07l2Q/JWK/Eqny529yXe32NK0bHzwoymE5jaAZL2zBefA5eFe2NDwX
+e75xjs0Cw2AOd8fL2BECQBqAafyDcER1SasqV5hkjyFQQu8FqzLUyppwbTKTRZji
+s+xxGwP9jT9LaKC6w9nuzFmaGi0OO3ciE+I+X89YiKc=
 -----END RSA PRIVATE KEY-----
-- 
2.9.3

#41Michael Paquier
michael.paquier@gmail.com
In reply to: Heikki Linnakangas (#40)
Re: OpenSSL 1.1 breaks configure and more

On Tue, Sep 13, 2016 at 1:51 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

I planned to commit this today, but while reading through it and testing, I
ended up doing a bunch more changes, so this deserves another round of
review.

OK, I am giving it a try. Note to people using OSX: at least for brew
there is the formula openssl@1.1 that you can use with the following
flags:
CFLAGS="-I/usr/local/opt/openssl@1.1/include"
LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
Postgres is not the only broken thing, so they kept the formula
openssl to 1.0.2.

Changes since last version:

* Added more error checks to the my_BIO_s_socket() function. Check for NULL
result from malloc(). Check the return code of BIO_meth_set_*() functions;
looking at OpenSSL sources, they always succeed, but all the test/example
programs that come with OpenSSL do check them.

* Use BIO_get_new_index() to get the index number for the wrapper BIO.

* Also call BIO_meth_set_puts(). It was missing in previous patch versions.

* Fixed src/test/ssl test suite to also work with OpenSSL 1.1.0.

* Changed all references (in existing code) to SSLEAY_VERSION_NUMBER into
OPENSSL_VERSION_NUMBER, for consistency.

* Squashed all into one patch.

I intend to apply this to all supported branches, so please have a look!
This is now against REL9_6_STABLE, but there should be little difference
between branches in the code that this touches.

I just took a look at this patch, testing it on the way with 1.1.0 and
1.0.2. And it looks in pretty good shape.

+ ResourceOwner owner;
+ struct OSSLDigest *next;
+ struct OSSLDigest *prev;
This could be done as well with a list of pg_list, the cost being a
couple of extra calls to switch memory contexts, but it would simplify
free_openssldigest when cleaning up an entry. I guessed you already
thought about that but discarded it?
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#42Andreas Karlsson
andreas@proxel.se
In reply to: Heikki Linnakangas (#40)
Re: OpenSSL 1.1 breaks configure and more

On 09/12/2016 06:51 PM, Heikki Linnakangas wrote:

Changes since last version:

* Added more error checks to the my_BIO_s_socket() function. Check for
NULL result from malloc(). Check the return code of BIO_meth_set_*()
functions; looking at OpenSSL sources, they always succeed, but all the
test/example programs that come with OpenSSL do check them.

* Use BIO_get_new_index() to get the index number for the wrapper BIO.

* Also call BIO_meth_set_puts(). It was missing in previous patch versions.

* Fixed src/test/ssl test suite to also work with OpenSSL 1.1.0.

* Changed all references (in existing code) to SSLEAY_VERSION_NUMBER
into OPENSSL_VERSION_NUMBER, for consistency.

* Squashed all into one patch.

I intend to apply this to all supported branches, so please have a look!
This is now against REL9_6_STABLE, but there should be little difference
between branches in the code that this touches.

This patch no longer seems to apply to head after the removed support of
0.9.6. Is that intentional?

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#43Andreas Karlsson
andreas@proxel.se
In reply to: Andreas Karlsson (#42)
Re: OpenSSL 1.1 breaks configure and more

On 09/15/2016 02:03 AM, Andreas Karlsson wrote:

On 09/12/2016 06:51 PM, Heikki Linnakangas wrote:

Changes since last version:

* Added more error checks to the my_BIO_s_socket() function. Check for
NULL result from malloc(). Check the return code of BIO_meth_set_*()
functions; looking at OpenSSL sources, they always succeed, but all the
test/example programs that come with OpenSSL do check them.

* Use BIO_get_new_index() to get the index number for the wrapper BIO.

* Also call BIO_meth_set_puts(). It was missing in previous patch
versions.

* Fixed src/test/ssl test suite to also work with OpenSSL 1.1.0.

* Changed all references (in existing code) to SSLEAY_VERSION_NUMBER
into OPENSSL_VERSION_NUMBER, for consistency.

* Squashed all into one patch.

I intend to apply this to all supported branches, so please have a look!
This is now against REL9_6_STABLE, but there should be little difference
between branches in the code that this touches.

This patch no longer seems to apply to head after the removed support of
0.9.6. Is that intentional?

Never mind. I just failed at reading.

Now for a review:

It looks generally good but I think I saw one error. In
fe-secure-openssl.c your code still calls SSL_library_init() in OpenSSL
1.1. I think it should be enough to just call
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) like you do in be-secure.

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#44Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Andreas Karlsson (#43)
Re: OpenSSL 1.1 breaks configure and more

On 09/15/2016 03:16 AM, Andreas Karlsson wrote:

Now for a review:

It looks generally good but I think I saw one error. In
fe-secure-openssl.c your code still calls SSL_library_init() in OpenSSL
1.1. I think it should be enough to just call
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) like you do in be-secure.

Ok, fixed that, and committed. Thanks everyone!

I backpatched this to 9.5, but not further than that. The functions this
modified were moved around in 9.5, so the patch wouldn't apply as is. It
wouldn't be difficult to back-patch further if there's demand, but I'm
not eager to do that until someone complains.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#45Michael Paquier
michael.paquier@gmail.com
In reply to: Heikki Linnakangas (#44)
Re: OpenSSL 1.1 breaks configure and more

On Thu, Sep 15, 2016 at 8:57 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

I backpatched this to 9.5, but not further than that. The functions this
modified were moved around in 9.5, so the patch wouldn't apply as is. It
wouldn't be difficult to back-patch further if there's demand, but I'm not
eager to do that until someone complains.

Not going older than 9.5 may be fine:
https://www.openssl.org/blog/blog/2014/12/23/the-new-release-strategy/
https://wiki.freebsd.org/OpenSSL
As far as I can see 1.0.2 would be supported until Dec 2019, so that
would just overlap with 9.4's EOL.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#46Christoph Berg
myon@debian.org
In reply to: Michael Paquier (#45)
Re: OpenSSL 1.1 breaks configure and more

Re: Michael Paquier 2016-09-15 <CAB7nPqQu1GpMzkB4S6XO0_+1cAUx==RDVF70vCmDytuA=nCHiQ@mail.gmail.com>

On Thu, Sep 15, 2016 at 8:57 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

I backpatched this to 9.5, but not further than that. The functions this
modified were moved around in 9.5, so the patch wouldn't apply as is. It
wouldn't be difficult to back-patch further if there's demand, but I'm not
eager to do that until someone complains.

Not going older than 9.5 may be fine:
https://www.openssl.org/blog/blog/2014/12/23/the-new-release-strategy/
https://wiki.freebsd.org/OpenSSL
As far as I can see 1.0.2 would be supported until Dec 2019, so that
would just overlap with 9.4's EOL.

I'm afraid it's not that easy - Debian 9 (stretch) will release at the
beginning of next year, and apt.postgresql.org will want to build
9.2/9.3/9.4 for that distribution. I guess yum.postgresql.org will
have the same problem with the next Fedora release.

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#47Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Christoph Berg (#46)
Re: OpenSSL 1.1 breaks configure and more

Christoph Berg wrote:

Re: Michael Paquier 2016-09-15 <CAB7nPqQu1GpMzkB4S6XO0_+1cAUx==RDVF70vCmDytuA=nCHiQ@mail.gmail.com>

On Thu, Sep 15, 2016 at 8:57 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

I backpatched this to 9.5, but not further than that. The functions this
modified were moved around in 9.5, so the patch wouldn't apply as is. It
wouldn't be difficult to back-patch further if there's demand, but I'm not
eager to do that until someone complains.

Not going older than 9.5 may be fine:
https://www.openssl.org/blog/blog/2014/12/23/the-new-release-strategy/
https://wiki.freebsd.org/OpenSSL
As far as I can see 1.0.2 would be supported until Dec 2019, so that
would just overlap with 9.4's EOL.

I'm afraid it's not that easy - Debian 9 (stretch) will release at the
beginning of next year, and apt.postgresql.org will want to build
9.2/9.3/9.4 for that distribution. I guess yum.postgresql.org will
have the same problem with the next Fedora release.

I suppose some interested party could grab the patch that Heikki
committed to the new branches and produce a back-patch that can be
applied to the older branches.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#48Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Christoph Berg (#46)
Re: OpenSSL 1.1 breaks configure and more

On 09/15/2016 05:33 PM, Christoph Berg wrote:

Re: Michael Paquier 2016-09-15 <CAB7nPqQu1GpMzkB4S6XO0_+1cAUx==RDVF70vCmDytuA=nCHiQ@mail.gmail.com>

On Thu, Sep 15, 2016 at 8:57 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

I backpatched this to 9.5, but not further than that. The functions this
modified were moved around in 9.5, so the patch wouldn't apply as is. It
wouldn't be difficult to back-patch further if there's demand, but I'm not
eager to do that until someone complains.

Not going older than 9.5 may be fine:
https://www.openssl.org/blog/blog/2014/12/23/the-new-release-strategy/
https://wiki.freebsd.org/OpenSSL
As far as I can see 1.0.2 would be supported until Dec 2019, so that
would just overlap with 9.4's EOL.

I'm afraid it's not that easy - Debian 9 (stretch) will release at the
beginning of next year, and apt.postgresql.org will want to build
9.2/9.3/9.4 for that distribution. I guess yum.postgresql.org will
have the same problem with the next Fedora release.

Can you elaborate? Are you saying that Debian 9 (strect) will not ship
OpenSSL 1.0.2 anymore, and will require using OpenSSL 1.1.0?

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#49Christoph Berg
myon@debian.org
In reply to: Heikki Linnakangas (#48)
Re: OpenSSL 1.1 breaks configure and more

Re: Heikki Linnakangas 2016-09-15 <7e4991a9-410f-5e1f-2a3a-e918e4a4bbbb@iki.fi>

I'm afraid it's not that easy - Debian 9 (stretch) will release at the
beginning of next year, and apt.postgresql.org will want to build
9.2/9.3/9.4 for that distribution. I guess yum.postgresql.org will
have the same problem with the next Fedora release.

Can you elaborate? Are you saying that Debian 9 (strect) will not ship
OpenSSL 1.0.2 anymore, and will require using OpenSSL 1.1.0?

I thought that was the plan, but upon asking on #debian-devel, it
seems it's not set yet. I'll ask the maintainers directly and report
back.

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#50Andreas Karlsson
andreas@proxel.se
In reply to: Alvaro Herrera (#47)
1 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

On 09/15/2016 05:38 PM, Alvaro Herrera wrote:

I suppose some interested party could grab the patch that Heikki
committed to the new branches and produce a back-patch that can be
applied to the older branches.

Here is the result of backporting the sum of the two patches on top of
REL9_4_STABLE. Not sure if we need this, but if we do we can apply this
patch.

Andreas

Attachments:

openssl-1.1-backport-9.4-v1.patchtext/x-diff; name=openssl-1.1-backport-9.4-v1.patchDownload
diff --git a/configure b/configure
index 6c6c08d..9470ed1 100755
--- a/configure
+++ b/configure
@@ -8621,9 +8621,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
@@ -8637,27 +8637,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
@@ -8727,9 +8727,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
@@ -8742,11 +8742,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;
 }
@@ -8759,25 +8759,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"
 
@@ -8797,6 +8797,37 @@ _ACEOF
 fi
 done
 
+  # Functions introduced in OpenSSL 1.1.0. We used to check for
+  # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+  # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+  # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+  # functions.
+  for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+  # OpenSSL versions before 1.1.0 required setting callback functions, for
+  # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+  # function was removed.
+  for ac_func in CRYPTO_lock
+do :
+  ac_fn_c_check_func "$LINENO" "CRYPTO_lock" "ac_cv_func_CRYPTO_lock"
+if test "x$ac_cv_func_CRYPTO_lock" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CRYPTO_LOCK 1
+_ACEOF
+
+fi
+done
+
 fi
 
 if test "$with_pam" = yes ; then
diff --git a/configure.in b/configure.in
index 4ed4950..39398b4 100644
--- a/configure.in
+++ b/configure.in
@@ -976,12 +976,22 @@ 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])
+  # Functions introduced in OpenSSL 1.1.0. We used to check for
+  # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+  # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+  # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+  # functions.
+  AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL])
+  # OpenSSL versions before 1.1.0 required setting callback functions, for
+  # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+  # function was removed.
+  AC_CHECK_FUNCS([CRYPTO_lock])
 fi
 
 if test "$with_pam" = yes ; then
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
  * Randomness provider
  */
 
-/*
- * Use always strong randomness.
- */
-int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	return px_get_random_bytes(dst, count);
-}
-
 static time_t seed_time = 0;
 static time_t check_time = 0;
 
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 976af70..682683c 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -40,6 +40,9 @@
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
+#include "utils/memutils.h"
+#include "utils/resowner.h"
+
 /*
  * Max lengths we might want to handle.
  */
@@ -199,18 +202,73 @@ compat_find_digest(const char *name, PX_MD **res)
  * Hashes
  */
 
+/*
+ * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
+ * objects in a linked list, allocated in TopMemoryContext. We use the
+ * ResourceOwner mechanism to free them on abort.
+ */
 typedef struct OSSLDigest
 {
 	const EVP_MD *algo;
-	EVP_MD_CTX	ctx;
+	EVP_MD_CTX *ctx;
+
+	ResourceOwner owner;
+	struct OSSLDigest *next;
+	struct OSSLDigest *prev;
 } OSSLDigest;
 
+static OSSLDigest *open_digests = NULL;
+static bool resowner_callback_registered = false;
+
+static void
+free_openssldigest(OSSLDigest *digest)
+{
+	EVP_MD_CTX_destroy(digest->ctx);
+	if (digest->prev)
+		digest->prev->next = digest->next;
+	else
+		open_digests = digest->next;
+	if (digest->next)
+		digest->next->prev = digest->prev;
+	pfree(digest);
+}
+
+/*
+ * Close any open OpenSSL handles on abort.
+ */
+static void
+digest_free_callback(ResourceReleasePhase phase,
+					 bool isCommit,
+					 bool isTopLevel,
+					 void *arg)
+{
+	OSSLDigest *curr;
+	OSSLDigest *next;
+
+	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
+		return;
+
+	next = open_digests;
+	while (next)
+	{
+		curr = next;
+		next = curr->next;
+
+		if (curr->owner == CurrentResourceOwner)
+		{
+			if (isCommit)
+				elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
+			free_openssldigest(curr);
+		}
+	}
+}
+
 static unsigned
 digest_result_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_size(&digest->ctx);
+	return EVP_MD_CTX_size(digest->ctx);
 }
 
 static unsigned
@@ -218,7 +276,7 @@ digest_block_size(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	return EVP_MD_CTX_block_size(&digest->ctx);
+	return EVP_MD_CTX_block_size(digest->ctx);
 }
 
 static void
@@ -226,7 +284,7 @@ digest_reset(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
 }
 
 static void
@@ -234,7 +292,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestUpdate(&digest->ctx, data, dlen);
+	EVP_DigestUpdate(digest->ctx, data, dlen);
 }
 
 static void
@@ -242,7 +300,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
 }
 
 static void
@@ -250,9 +308,7 @@ digest_free(PX_MD *h)
 {
 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
 
-	EVP_MD_CTX_cleanup(&digest->ctx);
-
-	px_free(digest);
+	free_openssldigest(digest);
 	px_free(h);
 }
 
@@ -264,6 +320,7 @@ int
 px_find_digest(const char *name, PX_MD **res)
 {
 	const EVP_MD *md;
+	EVP_MD_CTX *ctx;
 	PX_MD	   *h;
 	OSSLDigest *digest;
 
@@ -273,17 +330,43 @@ px_find_digest(const char *name, PX_MD **res)
 		OpenSSL_add_all_algorithms();
 	}
 
+	if (!resowner_callback_registered)
+	{
+		RegisterResourceReleaseCallback(digest_free_callback, NULL);
+		resowner_callback_registered = true;
+	}
+
 	md = EVP_get_digestbyname(name);
 	if (md == NULL)
 		return compat_find_digest(name, res);
 
-	digest = px_alloc(sizeof(*digest));
-	digest->algo = md;
+	/*
+	 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
+	 * The order is crucial, to make sure we don't leak anything on
+	 * out-of-memory or other error.
+	 */
+	digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
 
-	EVP_MD_CTX_init(&digest->ctx);
-	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+	ctx = EVP_MD_CTX_create();
+	if (!ctx)
+	{
+		pfree(digest);
+		return -1;
+	}
+	if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
+	{
+		pfree(digest);
 		return -1;
+	}
+
+	digest->algo = md;
+	digest->ctx = ctx;
+	digest->owner = CurrentResourceOwner;
+	digest->next = open_digests;
+	digest->prev = NULL;
+	open_digests = digest;
 
+	/* The PX_MD object is allocated in the current memory context. */
 	h = px_alloc(sizeof(*h));
 	h->result_size = digest_result_size;
 	h->block_size = digest_block_size;
@@ -987,7 +1070,13 @@ static void
 init_openssl_rand(void)
 {
 	if (RAND_get_rand_method() == NULL)
+	{
+#ifdef HAVE_RAND_OPENSSL
+		RAND_set_rand_method(RAND_OpenSSL());
+#else
 		RAND_set_rand_method(RAND_SSLeay());
+#endif
+	}
 	openssl_random_init = 1;
 }
 
@@ -1007,21 +1096,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
 }
 
 int
-px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
-{
-	int			res;
-
-	if (!openssl_random_init)
-		init_openssl_rand();
-
-	res = RAND_pseudo_bytes(dst, count);
-	if (res == 0 || res == 1)
-		return count;
-
-	return PXE_OSSL_RAND_ERROR;
-}
-
-int
 px_add_entropy(const uint8 *data, unsigned count)
 {
 	/*
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 2d446d8..27b96c7 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
 	int			err;
 
 	/* generate random bits */
-	err = px_get_pseudo_random_bytes(buf, UUID_LEN);
+	err = px_get_random_bytes(buf, UUID_LEN);
 	if (err < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 193dd95..0bcb95a 100644
--- a/contrib/pgcrypto/pgp-s2k.c
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -222,13 +222,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
 		case 0:
 			break;
 		case 1:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			break;
 		case 3:
-			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
 			if (res < 0)
 				break;
-			res = px_get_pseudo_random_bytes(&tmp, 1);
+			res = px_get_random_bytes(&tmp, 1);
 			if (res < 0)
 				break;
 			s2k->iter = decide_count(tmp);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 			return PXE_BAD_SALT_ROUNDS;
 	}
 
-	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
 	if (res < 0)
 		return res;
 
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index d237d97..fa889eb 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -190,7 +190,6 @@ int			px_find_cipher(const char *name, PX_Cipher **res);
 int			px_find_combo(const char *name, PX_Combo **res);
 
 int			px_get_random_bytes(uint8 *dst, unsigned count);
-int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
 int			px_add_entropy(const uint8 *data, unsigned count);
 
 unsigned	px_acquire_system_randomness(uint8 *dst);
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 3169ec3..8a435e2 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -66,7 +66,7 @@
 #ifdef USE_SSL
 #include <openssl/ssl.h>
 #include <openssl/dh.h>
-#if SSLEAY_VERSION_NUMBER >= 0x0907000L
+#if OPENSSL_VERSION_NUMBER >= 0x0907000L
 #include <openssl/conf.h>
 #endif
 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_ECDH)
@@ -83,6 +83,7 @@
 
 static DH  *load_dh_file(int keylength);
 static DH  *load_dh_buffer(const char *, size_t);
+static DH  *generate_dh_parameters(int prime_len, int generator);
 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
 static int	verify_cb(int, X509_STORE_CTX *);
 static void info_cb(const SSL *ssl, int type, int args);
@@ -485,8 +486,7 @@ wloop:
  * to retry; do we need to adopt their logic for that?
  */
 
-static bool my_bio_initialized = false;
-static BIO_METHOD my_bio_methods;
+static BIO_METHOD *my_bio_methods = NULL;
 
 static int
 my_sock_read(BIO *h, char *buf, int size)
@@ -497,7 +497,7 @@ my_sock_read(BIO *h, char *buf, int size)
 
 	if (buf != NULL)
 	{
-		res = recv(h->num, buf, size, 0);
+		res = recv(BIO_get_fd(h, NULL), buf, size, 0);
 		BIO_clear_retry_flags(h);
 		if (res <= 0)
 		{
@@ -519,7 +519,7 @@ my_sock_write(BIO *h, const char *buf, int size)
 {
 	int			res = 0;
 
-	res = send(h->num, buf, size, 0);
+	res = send(BIO_get_fd(h, NULL), buf, size, 0);
 	BIO_clear_retry_flags(h);
 	if (res <= 0)
 	{
@@ -535,14 +535,41 @@ 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();
+#ifdef HAVE_BIO_METH_NEW
+		int			my_bio_index;
+
+		my_bio_index = BIO_get_new_index();
+		if (my_bio_index == -1)
+			return NULL;
+		my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
+		if (!my_bio_methods)
+			return NULL;
+		if (!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_puts(my_bio_methods, BIO_meth_get_puts(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)))
+		{
+			BIO_meth_free(my_bio_methods);
+			my_bio_methods = NULL;
+			return NULL;
+		}
+#else
+		my_bio_methods = malloc(sizeof(BIO_METHOD));
+		if (!my_bio_methods)
+			return NULL;
+		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 */
@@ -550,9 +577,16 @@ static int
 my_SSL_set_fd(SSL *s, int fd)
 {
 	int			ret = 0;
-	BIO		   *bio = NULL;
+	BIO		   *bio;
+	BIO_METHOD *bio_method;
 
-	bio = BIO_new(my_BIO_s_socket());
+	bio_method = my_BIO_s_socket();
+	if (bio_method == NULL)
+	{
+		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+		goto err;
+	}
+	bio = BIO_new(bio_method);
 
 	if (bio == NULL)
 	{
@@ -652,6 +686,31 @@ load_dh_buffer(const char *buffer, size_t len)
 }
 
 /*
+ *	Generate DH parameters.
+ *
+ *	Last resort if we can't load precomputed nor hardcoded
+ *	parameters.
+ */
+static DH  *
+generate_dh_parameters(int prime_len, int generator)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+	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
  *	common key sizes.
@@ -720,7 +779,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_parameters(keylength, DH_GENERATOR_2);
 	}
 
 	return r;
@@ -824,11 +883,15 @@ initialize_SSL(void)
 
 	if (!SSL_context)
 	{
+#ifdef HAVE_OPENSSL_INIT_SSL
+		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
 #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
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 946af63..9909aa4 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -87,6 +87,15 @@
 /* Define to 1 if you have the `append_history' function. */
 #undef HAVE_APPEND_HISTORY
 
+/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
+#undef HAVE_ASN1_STRING_GET0_DATA
+
+/* Define to 1 if you have the `BIO_get_data' function. */
+#undef HAVE_BIO_GET_DATA
+
+/* Define to 1 if you have the `BIO_meth_new' function. */
+#undef HAVE_BIO_METH_NEW
+
 /* Define to 1 if you have the `cbrt' function. */
 #undef HAVE_CBRT
 
@@ -99,6 +108,9 @@
 /* Define to 1 if you have the `crypt' function. */
 #undef HAVE_CRYPT
 
+/* Define to 1 if you have the `CRYPTO_lock' function. */
+#undef HAVE_CRYPTO_LOCK
+
 /* Define to 1 if you have the <crypt.h> header file. */
 #undef HAVE_CRYPT_H
 
@@ -342,6 +354,9 @@
 /* Define to 1 if you have the <net/if.h> header file. */
 #undef HAVE_NET_IF_H
 
+/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
+#undef HAVE_OPENSSL_INIT_SSL
+
 /* Define to 1 if you have the <ossp/uuid.h> header file. */
 #undef HAVE_OSSP_UUID_H
 
@@ -381,6 +396,9 @@
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
+/* Define to 1 if you have the `RAND_OpenSSL' function. */
+#undef HAVE_RAND_OPENSSL
+
 /* Define to 1 if you have the <readline.h> header file. */
 #undef HAVE_READLINE_H
 
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 97e275b..f85d09b 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -58,7 +58,7 @@
 #ifdef USE_SSL
 
 #include <openssl/ssl.h>
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
 #include <openssl/conf.h>
 #endif
 #ifdef USE_SSL_ENGINE
@@ -873,9 +873,13 @@ verify_peer_name_matches_certificate(PGconn *conn)
 	return result;
 }
 
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
 /*
- *	Callback functions for OpenSSL internal locking
+ *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
+ *	does its own locking, and doesn't need these anymore.  The
+ *	CRYPTO_lock() function was removed in 1.1.0, when the callbacks
+ *	were made obsolete, so we assume that if CRYPTO_lock() exists,
+ *	the callbacks are still required.)
  */
 
 static unsigned long
@@ -905,7 +909,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 && HAVE_CRYPTO_LOCK */
 
 /*
  * Initialize SSL system, in particular creating the SSL_context object
@@ -944,6 +948,7 @@ init_ssl_system(PGconn *conn)
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return -1;
 
+#ifdef HAVE_CRYPTO_LOCK
 	if (pq_init_crypto_lib)
 	{
 		/*
@@ -979,17 +984,22 @@ init_ssl_system(PGconn *conn)
 			CRYPTO_set_locking_callback(pq_lockingcallback);
 		}
 	}
+#endif   /* HAVE_CRYPTO_LOCK */
 #endif   /* ENABLE_THREAD_SAFETY */
 
 	if (!SSL_context)
 	{
 		if (pq_init_ssl_lib)
 		{
-#if SSLEAY_VERSION_NUMBER >= 0x00907000L
+#ifdef HAVE_OPENSSL_INIT_SSL
+			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
 			OPENSSL_config(NULL);
 #endif
 			SSL_library_init();
 			SSL_load_error_strings();
+#endif
 		}
 
 		/*
@@ -1038,12 +1048,13 @@ init_ssl_system(PGconn *conn)
  *	if we had any.)
  *
  *	Callbacks are only set when we're compiled in threadsafe mode, so
- *	we only need to remove them in this case.
+ *	we only need to remove them in this case. They are also not needed
+ *	with OpenSSL 1.1.0 anymore.
  */
 static void
 destroy_ssl_system(void)
 {
-#ifdef ENABLE_THREAD_SAFETY
+#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
 	/* Mutex is created in initialize_ssl_system() */
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return;
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index e048081..f0b8e37 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -77,7 +77,7 @@ typedef struct
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
-#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 #define USE_SSL_ENGINE
 #endif
 #endif   /* USE_SSL */
#51Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andreas Karlsson (#50)
Re: OpenSSL 1.1 breaks configure and more

Andreas Karlsson <andreas@proxel.se> writes:

On 09/15/2016 05:38 PM, Alvaro Herrera wrote:

I suppose some interested party could grab the patch that Heikki
committed to the new branches and produce a back-patch that can be
applied to the older branches.

Here is the result of backporting the sum of the two patches on top of
REL9_4_STABLE. Not sure if we need this, but if we do we can apply this
patch.

If someone's done the legwork, I think we would be well advised to
back-patch. Maybe not bother with 9.1 though.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#52Christoph Berg
myon@debian.org
In reply to: Tom Lane (#51)
Re: OpenSSL 1.1 breaks configure and more

Re: To Heikki Linnakangas 2016-09-15 <20160915213406.2mjlhcg7px3saynq@msg.df7cb.de>

Can you elaborate? Are you saying that Debian 9 (strect) will not ship
OpenSSL 1.0.2 anymore, and will require using OpenSSL 1.1.0?

I thought that was the plan, but upon asking on #debian-devel, it
seems it's not set yet. I'll ask the maintainers directly and report
back.

The plan is to ship only OpenSSL 1.1 in Stretch. (The list of packages
not yet ported is enormous, though, so I'm not yet sure it will really
happen.)

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=827061

Re: Tom Lane 2016-09-16 <17025.1473977329@sss.pgh.pa.us>

Here is the result of backporting the sum of the two patches on top of
REL9_4_STABLE. Not sure if we need this, but if we do we can apply this
patch.

If someone's done the legwork, I think we would be well advised to
back-patch. Maybe not bother with 9.1 though.

Thanks for the patch!

I just tried to apply it to 9.2. There was a conflict in configure.in which was
trivial to resolve.

Another conflict in contrib/pgcrypto/pgcrypto.c was not applicable
because the code doesn't seem to exist (didn't try very hard though).

Ignoring the contrib conflict, it still didn't compile:

/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c: In function ‘secure_write’:
/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c:342:17: error: dereferencing pointer to incomplete type ‘SSL {aka struct ssl_st}’
if (port->ssl->state != SSL_ST_OK)
^~
/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c:342:28: error: ‘SSL_ST_OK’ undeclared (first use in this function)
if (port->ssl->state != SSL_ST_OK)
^~~~~~~~~

Christoph

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#53Andreas Karlsson
andreas@proxel.se
In reply to: Christoph Berg (#52)
Re: OpenSSL 1.1 breaks configure and more

On 09/16/2016 04:11 PM, Christoph Berg wrote:

Thanks for the patch!

I just tried to apply it to 9.2. There was a conflict in configure.in which was
trivial to resolve.

Another conflict in contrib/pgcrypto/pgcrypto.c was not applicable
because the code doesn't seem to exist (didn't try very hard though).

Ignoring the contrib conflict, it still didn't compile:

/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c: In function ‘secure_write’:
/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c:342:17: error: dereferencing pointer to incomplete type ‘SSL {aka struct ssl_st}’
if (port->ssl->state != SSL_ST_OK)
^~
/home/cbe/projects/postgresql/debian/9.2/build/../src/backend/libpq/be-secure.c:342:28: error: ‘SSL_ST_OK’ undeclared (first use in this function)
if (port->ssl->state != SSL_ST_OK)
^~~~~~~~~

This is related to the renegotiation which was first fixed and later
removed in the 9.4 cycle, but intentionally not backported. It seems
like OpenSSL refactored the state machine in 1.1 which is why the code
above breaks.

I am not entirely sure I follow what the old code in 9.3 and 9.2 is
strying to do and why it messes directly with the state of the statemachine.

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#54Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andreas Karlsson (#50)
1 attachment(s)
Re: OpenSSL 1.1 breaks configure and more

Andreas Karlsson <andreas@proxel.se> writes:

On 09/15/2016 05:38 PM, Alvaro Herrera wrote:

I suppose some interested party could grab the patch that Heikki
committed to the new branches and produce a back-patch that can be
applied to the older branches.

Here is the result of backporting the sum of the two patches on top of
REL9_4_STABLE. Not sure if we need this, but if we do we can apply this
patch.

I've pushed this into 9.4 with trivial corrections (fix merge failure
against a later patch, and sync the autoconf output files with the
actual contents of configure.in). I've tested it locally against
openssl 1.0.1e and 1.1.0e, but not anything older. What I did to test
was to copy the 9.5-branch src/test/ssl/ stuff into 9.4 and run it.
I saw failures on the tests for Subject Alternative Name, which is
unsurprising since we added that support as a feature in 9.5, but
everything else passed. Unless the buildfarm turns up problems,
I think we're ok there.

I tried to push the code into 9.3, and saw the same problems Christoph
mentioned for 9.2: it compiles fine against 1.0.1e, but the references
to port->ssl->state don't work with 1.1. The reason that's OK in 9.4
is not that we removed SSL negotiation; that didn't happen until 9.5.
Rather, it's because this 9.4 commit got rid of the bogus code:

Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
Branch: master Release: REL9_4_BR [31cf1a1a4] 2013-10-10 23:45:20 -0300

Rework SSL renegotiation code

If we want to go any further back with 1.1 support, we have a range
of options:

1. Back-patch that patch, probably also including the followup adjustments
in 86029b31e and 36a3be654.

2. Add #if's to use 31cf1a1a4's coding with OpenSSL >= 1.1, while keeping
the older code for use when built against older OpenSSLs.

3. Conditionally disable renegotiation altogether with OpenSSL >= 1.1,
thus adopting 9.5 not 9.4 behavior when using newer OpenSSL.

I think #3 would be fairly weird unless we also changed 9.4 similarly.
But there's some argument for doing that: we don't really have any field
experience with using renegotiation with OpenSSL 1.1, so we don't know
that what is in the 9.4 branch right now actually works with 1.1.
On the other hand, it would also be the most work of these options,
since we'd have to do things like adding conditional behavior in guc.c.

Thoughts?

For the archives' sake, attached is the 9.3-adapted version of the
patch so far.

regards, tom lane

Attachments:

openssl-1.1-backport-9.3-v1.patchtext/x-diff; charset=us-ascii; name=openssl-1.1-backport-9.3-v1.patchDownload
diff --git a/configure b/configure
index 0702667..e548722 100755
*** a/configure
--- b/configure
*************** $as_echo "$as_me: error: library 'crypto
*** 9524,9532 ****
  fi
  
  
! { $as_echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
! $as_echo_n "checking for SSL_library_init in -lssl... " >&6; }
! if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then
    $as_echo_n "(cached) " >&6
  else
    ac_check_lib_save_LIBS=$LIBS
--- 9524,9532 ----
  fi
  
  
! { $as_echo "$as_me:$LINENO: checking for SSL_new in -lssl" >&5
! $as_echo_n "checking for SSL_new in -lssl... " >&6; }
! if test "${ac_cv_lib_ssl_SSL_new+set}" = set; then
    $as_echo_n "(cached) " >&6
  else
    ac_check_lib_save_LIBS=$LIBS
*************** cat >>conftest.$ac_ext <<_ACEOF
*** 9544,9554 ****
  #ifdef __cplusplus
  extern "C"
  #endif
! char SSL_library_init ();
  int
  main ()
  {
! return SSL_library_init ();
    ;
    return 0;
  }
--- 9544,9554 ----
  #ifdef __cplusplus
  extern "C"
  #endif
! char SSL_new ();
  int
  main ()
  {
! return SSL_new ();
    ;
    return 0;
  }
*************** $as_echo "$ac_try_echo") >&5
*** 9574,9585 ****
  	 test "$cross_compiling" = yes ||
  	 $as_test_x conftest$ac_exeext
         }; then
!   ac_cv_lib_ssl_SSL_library_init=yes
  else
    $as_echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! 	ac_cv_lib_ssl_SSL_library_init=no
  fi
  
  rm -rf conftest.dSYM
--- 9574,9585 ----
  	 test "$cross_compiling" = yes ||
  	 $as_test_x conftest$ac_exeext
         }; then
!   ac_cv_lib_ssl_SSL_new=yes
  else
    $as_echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
  
! 	ac_cv_lib_ssl_SSL_new=no
  fi
  
  rm -rf conftest.dSYM
*************** rm -f core conftest.err conftest.$ac_obj
*** 9587,9595 ****
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! { $as_echo "$as_me:$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" = x""yes; then
    cat >>confdefs.h <<_ACEOF
  #define HAVE_LIBSSL 1
  _ACEOF
--- 9587,9595 ----
        conftest$ac_exeext conftest.$ac_ext
  LIBS=$ac_check_lib_save_LIBS
  fi
! { $as_echo "$as_me:$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" = x""yes; then
    cat >>confdefs.h <<_ACEOF
  #define HAVE_LIBSSL 1
  _ACEOF
*************** $as_echo "$as_me: error: library 'eay32'
*** 9694,9702 ****
     { (exit 1); exit 1; }; }
  fi
  
!      { $as_echo "$as_me:$LINENO: checking for library containing SSL_library_init" >&5
! $as_echo_n "checking for library containing SSL_library_init... " >&6; }
! if test "${ac_cv_search_SSL_library_init+set}" = set; then
    $as_echo_n "(cached) " >&6
  else
    ac_func_search_save_LIBS=$LIBS
--- 9694,9702 ----
     { (exit 1); exit 1; }; }
  fi
  
!      { $as_echo "$as_me:$LINENO: checking for library containing SSL_new" >&5
! $as_echo_n "checking for library containing SSL_new... " >&6; }
! if test "${ac_cv_search_SSL_new+set}" = set; then
    $as_echo_n "(cached) " >&6
  else
    ac_func_search_save_LIBS=$LIBS
*************** cat >>conftest.$ac_ext <<_ACEOF
*** 9713,9723 ****
  #ifdef __cplusplus
  extern "C"
  #endif
! char SSL_library_init ();
  int
  main ()
  {
! return SSL_library_init ();
    ;
    return 0;
  }
--- 9713,9723 ----
  #ifdef __cplusplus
  extern "C"
  #endif
! char SSL_new ();
  int
  main ()
  {
! return SSL_new ();
    ;
    return 0;
  }
*************** $as_echo "$ac_try_echo") >&5
*** 9750,9756 ****
  	 test "$cross_compiling" = yes ||
  	 $as_test_x conftest$ac_exeext
         }; then
!   ac_cv_search_SSL_library_init=$ac_res
  else
    $as_echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
--- 9750,9756 ----
  	 test "$cross_compiling" = yes ||
  	 $as_test_x conftest$ac_exeext
         }; then
!   ac_cv_search_SSL_new=$ac_res
  else
    $as_echo "$as_me: failed program was:" >&5
  sed 's/^/| /' conftest.$ac_ext >&5
*************** fi
*** 9761,9781 ****
  rm -rf conftest.dSYM
  rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
        conftest$ac_exeext
!   if test "${ac_cv_search_SSL_library_init+set}" = set; then
    break
  fi
  done
! if test "${ac_cv_search_SSL_library_init+set}" = set; then
    :
  else
!   ac_cv_search_SSL_library_init=no
  fi
  rm conftest.$ac_ext
  LIBS=$ac_func_search_save_LIBS
  fi
! { $as_echo "$as_me:$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
  if test "$ac_res" != no; then
    test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
  
--- 9761,9781 ----
  rm -rf conftest.dSYM
  rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
        conftest$ac_exeext
!   if test "${ac_cv_search_SSL_new+set}" = set; then
    break
  fi
  done
! if test "${ac_cv_search_SSL_new+set}" = set; then
    :
  else
!   ac_cv_search_SSL_new=no
  fi
  rm conftest.$ac_ext
  LIBS=$ac_func_search_save_LIBS
  fi
! { $as_echo "$as_me:$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"
  
*************** $as_echo "$as_me: error: library 'ssleay
*** 9786,9791 ****
--- 9786,10004 ----
  fi
  
    fi
+   # Functions introduced in OpenSSL 1.1.0. We used to check for
+   # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+   # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+   # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+   # functions.
+ 
+ 
+ 
+ 
+ for ac_func in OPENSSL_init_ssl BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL
+ do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+ $as_echo_n "checking for $ac_func... " >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+   $as_echo_n "(cached) " >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $ac_func innocuous_$ac_func
+ 
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ 
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ 
+ #undef $ac_func
+ 
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char $ac_func ();
+ /* The GNU C library defines this for functions which it implements
+     to always fail with ENOSYS.  Some functions are actually named
+     something starting with __ and the normal name is an alias.  */
+ #if defined __stub_$ac_func || defined __stub___$ac_func
+ choke me
+ #endif
+ 
+ int
+ main ()
+ {
+ return $ac_func ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+ $as_echo "$ac_try_echo") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+ 	 test -z "$ac_c_werror_flag" ||
+ 	 test ! -s conftest.err
+        } && test -s conftest$ac_exeext && {
+ 	 test "$cross_compiling" = yes ||
+ 	 $as_test_x conftest$ac_exeext
+        }; then
+   eval "$as_ac_var=yes"
+ else
+   $as_echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ 	eval "$as_ac_var=no"
+ fi
+ 
+ rm -rf conftest.dSYM
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ fi
+ ac_res=`eval 'as_val=${'$as_ac_var'}
+ 		 $as_echo "$as_val"'`
+ 	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+ $as_echo "$ac_res" >&6; }
+ as_val=`eval 'as_val=${'$as_ac_var'}
+ 		 $as_echo "$as_val"'`
+    if test "x$as_val" = x""yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+ 
+ fi
+ done
+ 
+   # OpenSSL versions before 1.1.0 required setting callback functions, for
+   # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+   # function was removed.
+ 
+ for ac_func in CRYPTO_lock
+ do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+ $as_echo_n "checking for $ac_func... " >&6; }
+ if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+   $as_echo_n "(cached) " >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ /* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+ #define $ac_func innocuous_$ac_func
+ 
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.
+     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+     <limits.h> exists even on freestanding compilers.  */
+ 
+ #ifdef __STDC__
+ # include <limits.h>
+ #else
+ # include <assert.h>
+ #endif
+ 
+ #undef $ac_func
+ 
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char $ac_func ();
+ /* The GNU C library defines this for functions which it implements
+     to always fail with ENOSYS.  Some functions are actually named
+     something starting with __ and the normal name is an alias.  */
+ #if defined __stub_$ac_func || defined __stub___$ac_func
+ choke me
+ #endif
+ 
+ int
+ main ()
+ {
+ return $ac_func ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+ $as_echo "$ac_try_echo") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+ 	 test -z "$ac_c_werror_flag" ||
+ 	 test ! -s conftest.err
+        } && test -s conftest$ac_exeext && {
+ 	 test "$cross_compiling" = yes ||
+ 	 $as_test_x conftest$ac_exeext
+        }; then
+   eval "$as_ac_var=yes"
+ else
+   $as_echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ 	eval "$as_ac_var=no"
+ fi
+ 
+ rm -rf conftest.dSYM
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext conftest.$ac_ext
+ fi
+ ac_res=`eval 'as_val=${'$as_ac_var'}
+ 		 $as_echo "$as_val"'`
+ 	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+ $as_echo "$ac_res" >&6; }
+ as_val=`eval 'as_val=${'$as_ac_var'}
+ 		 $as_echo "$as_val"'`
+    if test "x$as_val" = x""yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+ 
+ fi
+ done
+ 
  fi
  
  if test "$with_pam" = yes ; then
diff --git a/configure.in b/configure.in
index e00adc9..aad7598 100644
*** a/configure.in
--- b/configure.in
*************** if test "$with_openssl" = yes ; then
*** 951,961 ****
    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])])
    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])])
    fi
  fi
  
  if test "$with_pam" = yes ; then
--- 951,971 ----
    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_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_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
    fi
+   # Functions introduced in OpenSSL 1.1.0. We used to check for
+   # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
+   # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
+   # doesn't have these OpenSSL 1.1.0 functions. So check for individual
+   # functions.
+   AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL])
+   # OpenSSL versions before 1.1.0 required setting callback functions, for
+   # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
+   # function was removed.
+   AC_CHECK_FUNCS([CRYPTO_lock])
  fi
  
  if test "$with_pam" = yes ; then
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index cb8ba26..02ff976 100644
*** a/contrib/pgcrypto/internal.c
--- b/contrib/pgcrypto/internal.c
*************** px_find_cipher(const char *name, PX_Ciph
*** 620,634 ****
   * Randomness provider
   */
  
- /*
-  * Use always strong randomness.
-  */
- int
- px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
- {
- 	return px_get_random_bytes(dst, count);
- }
- 
  static time_t seed_time = 0;
  static time_t check_time = 0;
  
--- 620,625 ----
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index e49dbaf..9ae45b2 100644
*** a/contrib/pgcrypto/openssl.c
--- b/contrib/pgcrypto/openssl.c
***************
*** 40,45 ****
--- 40,48 ----
  #include <openssl/rand.h>
  #include <openssl/err.h>
  
+ #include "utils/memutils.h"
+ #include "utils/resowner.h"
+ 
  /*
   * Max lengths we might want to handle.
   */
*************** compat_find_digest(const char *name, PX_
*** 199,216 ****
   * Hashes
   */
  
  typedef struct OSSLDigest
  {
  	const EVP_MD *algo;
! 	EVP_MD_CTX	ctx;
  } OSSLDigest;
  
  static unsigned
  digest_result_size(PX_MD *h)
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	return EVP_MD_CTX_size(&digest->ctx);
  }
  
  static unsigned
--- 202,274 ----
   * Hashes
   */
  
+ /*
+  * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
+  * objects in a linked list, allocated in TopMemoryContext. We use the
+  * ResourceOwner mechanism to free them on abort.
+  */
  typedef struct OSSLDigest
  {
  	const EVP_MD *algo;
! 	EVP_MD_CTX *ctx;
! 
! 	ResourceOwner owner;
! 	struct OSSLDigest *next;
! 	struct OSSLDigest *prev;
  } OSSLDigest;
  
+ static OSSLDigest *open_digests = NULL;
+ static bool resowner_callback_registered = false;
+ 
+ static void
+ free_openssldigest(OSSLDigest *digest)
+ {
+ 	EVP_MD_CTX_destroy(digest->ctx);
+ 	if (digest->prev)
+ 		digest->prev->next = digest->next;
+ 	else
+ 		open_digests = digest->next;
+ 	if (digest->next)
+ 		digest->next->prev = digest->prev;
+ 	pfree(digest);
+ }
+ 
+ /*
+  * Close any open OpenSSL handles on abort.
+  */
+ static void
+ digest_free_callback(ResourceReleasePhase phase,
+ 					 bool isCommit,
+ 					 bool isTopLevel,
+ 					 void *arg)
+ {
+ 	OSSLDigest *curr;
+ 	OSSLDigest *next;
+ 
+ 	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
+ 		return;
+ 
+ 	next = open_digests;
+ 	while (next)
+ 	{
+ 		curr = next;
+ 		next = curr->next;
+ 
+ 		if (curr->owner == CurrentResourceOwner)
+ 		{
+ 			if (isCommit)
+ 				elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
+ 			free_openssldigest(curr);
+ 		}
+ 	}
+ }
+ 
  static unsigned
  digest_result_size(PX_MD *h)
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	return EVP_MD_CTX_size(digest->ctx);
  }
  
  static unsigned
*************** digest_block_size(PX_MD *h)
*** 218,224 ****
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	return EVP_MD_CTX_block_size(&digest->ctx);
  }
  
  static void
--- 276,282 ----
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	return EVP_MD_CTX_block_size(digest->ctx);
  }
  
  static void
*************** digest_reset(PX_MD *h)
*** 226,232 ****
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
  }
  
  static void
--- 284,290 ----
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
  }
  
  static void
*************** digest_update(PX_MD *h, const uint8 *dat
*** 234,240 ****
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestUpdate(&digest->ctx, data, dlen);
  }
  
  static void
--- 292,298 ----
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestUpdate(digest->ctx, data, dlen);
  }
  
  static void
*************** digest_finish(PX_MD *h, uint8 *dst)
*** 242,248 ****
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
  }
  
  static void
--- 300,306 ----
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_DigestFinal_ex(digest->ctx, dst, NULL);
  }
  
  static void
*************** digest_free(PX_MD *h)
*** 250,258 ****
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	EVP_MD_CTX_cleanup(&digest->ctx);
! 
! 	px_free(digest);
  	px_free(h);
  }
  
--- 308,314 ----
  {
  	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
  
! 	free_openssldigest(digest);
  	px_free(h);
  }
  
*************** int
*** 264,269 ****
--- 320,326 ----
  px_find_digest(const char *name, PX_MD **res)
  {
  	const EVP_MD *md;
+ 	EVP_MD_CTX *ctx;
  	PX_MD	   *h;
  	OSSLDigest *digest;
  
*************** px_find_digest(const char *name, PX_MD *
*** 273,289 ****
  		OpenSSL_add_all_algorithms();
  	}
  
  	md = EVP_get_digestbyname(name);
  	if (md == NULL)
  		return compat_find_digest(name, res);
  
! 	digest = px_alloc(sizeof(*digest));
! 	digest->algo = md;
  
! 	EVP_MD_CTX_init(&digest->ctx);
! 	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
  		return -1;
  
  	h = px_alloc(sizeof(*h));
  	h->result_size = digest_result_size;
  	h->block_size = digest_block_size;
--- 330,372 ----
  		OpenSSL_add_all_algorithms();
  	}
  
+ 	if (!resowner_callback_registered)
+ 	{
+ 		RegisterResourceReleaseCallback(digest_free_callback, NULL);
+ 		resowner_callback_registered = true;
+ 	}
+ 
  	md = EVP_get_digestbyname(name);
  	if (md == NULL)
  		return compat_find_digest(name, res);
  
! 	/*
! 	 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
! 	 * The order is crucial, to make sure we don't leak anything on
! 	 * out-of-memory or other error.
! 	 */
! 	digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
  
! 	ctx = EVP_MD_CTX_create();
! 	if (!ctx)
! 	{
! 		pfree(digest);
  		return -1;
+ 	}
+ 	if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
+ 	{
+ 		pfree(digest);
+ 		return -1;
+ 	}
+ 
+ 	digest->algo = md;
+ 	digest->ctx = ctx;
+ 	digest->owner = CurrentResourceOwner;
+ 	digest->next = open_digests;
+ 	digest->prev = NULL;
+ 	open_digests = digest;
  
+ 	/* The PX_MD object is allocated in the current memory context. */
  	h = px_alloc(sizeof(*h));
  	h->result_size = digest_result_size;
  	h->block_size = digest_block_size;
*************** static void
*** 987,993 ****
--- 1070,1082 ----
  init_openssl_rand(void)
  {
  	if (RAND_get_rand_method() == NULL)
+ 	{
+ #ifdef HAVE_RAND_OPENSSL
+ 		RAND_set_rand_method(RAND_OpenSSL());
+ #else
  		RAND_set_rand_method(RAND_SSLeay());
+ #endif
+ 	}
  	openssl_random_init = 1;
  }
  
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 1007,1027 ****
  }
  
  int
- px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
- {
- 	int			res;
- 
- 	if (!openssl_random_init)
- 		init_openssl_rand();
- 
- 	res = RAND_pseudo_bytes(dst, count);
- 	if (res == 0 || res == 1)
- 		return count;
- 
- 	return PXE_OSSL_RAND_ERROR;
- }
- 
- int
  px_add_entropy(const uint8 *data, unsigned count)
  {
  	/*
--- 1096,1101 ----
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
index 5f47e79..fb651fc 100644
*** a/contrib/pgcrypto/pgp-s2k.c
--- b/contrib/pgcrypto/pgp-s2k.c
*************** pgp_s2k_fill(PGP_S2K *s2k, int mode, int
*** 223,235 ****
  		case 0:
  			break;
  		case 1:
! 			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
  			break;
  		case 3:
! 			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
  			if (res < 0)
  				break;
! 			res = px_get_pseudo_random_bytes(&tmp, 1);
  			if (res < 0)
  				break;
  			s2k->iter = decide_count(tmp);
--- 223,235 ----
  		case 0:
  			break;
  		case 1:
! 			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
  			break;
  		case 3:
! 			res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
  			if (res < 0)
  				break;
! 			res = px_get_random_bytes(&tmp, 1);
  			if (res < 0)
  				break;
  			s2k->iter = decide_count(tmp);
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index e3246fc..3d42393 100644
*** a/contrib/pgcrypto/px-crypt.c
--- b/contrib/pgcrypto/px-crypt.c
*************** px_gen_salt(const char *salt_type, char 
*** 153,159 ****
  			return PXE_BAD_SALT_ROUNDS;
  	}
  
! 	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
  	if (res < 0)
  		return res;
  
--- 153,159 ----
  			return PXE_BAD_SALT_ROUNDS;
  	}
  
! 	res = px_get_random_bytes((uint8 *) rbuf, g->input_len);
  	if (res < 0)
  		return res;
  
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index d237d97..fa889eb 100644
*** a/contrib/pgcrypto/px.h
--- b/contrib/pgcrypto/px.h
*************** int			px_find_cipher(const char *name, P
*** 190,196 ****
  int			px_find_combo(const char *name, PX_Combo **res);
  
  int			px_get_random_bytes(uint8 *dst, unsigned count);
- int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
  int			px_add_entropy(const uint8 *data, unsigned count);
  
  unsigned	px_acquire_system_randomness(uint8 *dst);
--- 190,195 ----
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 82a608d..0122b0d 100644
*** a/src/backend/libpq/be-secure.c
--- b/src/backend/libpq/be-secure.c
***************
*** 66,72 ****
  #ifdef USE_SSL
  #include <openssl/ssl.h>
  #include <openssl/dh.h>
! #if SSLEAY_VERSION_NUMBER >= 0x0907000L
  #include <openssl/conf.h>
  #endif
  #endif   /* USE_SSL */
--- 66,72 ----
  #ifdef USE_SSL
  #include <openssl/ssl.h>
  #include <openssl/dh.h>
! #if OPENSSL_VERSION_NUMBER >= 0x0907000L
  #include <openssl/conf.h>
  #endif
  #endif   /* USE_SSL */
***************
*** 80,85 ****
--- 80,86 ----
  
  static DH  *load_dh_file(int keylength);
  static DH  *load_dh_buffer(const char *, size_t);
+ static DH  *generate_dh_parameters(int prime_len, int generator);
  static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
  static int	verify_cb(int, X509_STORE_CTX *);
  static void info_cb(const SSL *ssl, int type, int args);
*************** wloop:
*** 423,430 ****
   * to retry; do we need to adopt their logic for that?
   */
  
! static bool my_bio_initialized = false;
! static BIO_METHOD my_bio_methods;
  
  static int
  my_sock_read(BIO *h, char *buf, int size)
--- 424,430 ----
   * to retry; do we need to adopt their logic for that?
   */
  
! static BIO_METHOD *my_bio_methods = NULL;
  
  static int
  my_sock_read(BIO *h, char *buf, int size)
*************** my_sock_read(BIO *h, char *buf, int size
*** 435,441 ****
  
  	if (buf != NULL)
  	{
! 		res = recv(h->num, buf, size, 0);
  		BIO_clear_retry_flags(h);
  		if (res <= 0)
  		{
--- 435,441 ----
  
  	if (buf != NULL)
  	{
! 		res = recv(BIO_get_fd(h, NULL), buf, size, 0);
  		BIO_clear_retry_flags(h);
  		if (res <= 0)
  		{
*************** my_sock_write(BIO *h, const char *buf, i
*** 457,463 ****
  {
  	int			res = 0;
  
! 	res = send(h->num, buf, size, 0);
  	BIO_clear_retry_flags(h);
  	if (res <= 0)
  	{
--- 457,463 ----
  {
  	int			res = 0;
  
! 	res = send(BIO_get_fd(h, NULL), buf, size, 0);
  	BIO_clear_retry_flags(h);
  	if (res <= 0)
  	{
*************** my_sock_write(BIO *h, const char *buf, i
*** 473,486 ****
  static BIO_METHOD *
  my_BIO_s_socket(void)
  {
! 	if (!my_bio_initialized)
  	{
! 		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;
  	}
! 	return &my_bio_methods;
  }
  
  /* This should exactly match openssl's SSL_set_fd except for using my BIO */
--- 473,513 ----
  static BIO_METHOD *
  my_BIO_s_socket(void)
  {
! 	if (!my_bio_methods)
  	{
! 		BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
! #ifdef HAVE_BIO_METH_NEW
! 		int			my_bio_index;
! 
! 		my_bio_index = BIO_get_new_index();
! 		if (my_bio_index == -1)
! 			return NULL;
! 		my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
! 		if (!my_bio_methods)
! 			return NULL;
! 		if (!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_puts(my_bio_methods, BIO_meth_get_puts(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)))
! 		{
! 			BIO_meth_free(my_bio_methods);
! 			my_bio_methods = NULL;
! 			return NULL;
! 		}
! #else
! 		my_bio_methods = malloc(sizeof(BIO_METHOD));
! 		if (!my_bio_methods)
! 			return NULL;
! 		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;
  }
  
  /* This should exactly match openssl's SSL_set_fd except for using my BIO */
*************** static int
*** 488,496 ****
  my_SSL_set_fd(SSL *s, int fd)
  {
  	int			ret = 0;
! 	BIO		   *bio = NULL;
  
! 	bio = BIO_new(my_BIO_s_socket());
  
  	if (bio == NULL)
  	{
--- 515,530 ----
  my_SSL_set_fd(SSL *s, int fd)
  {
  	int			ret = 0;
! 	BIO		   *bio;
! 	BIO_METHOD *bio_method;
  
! 	bio_method = my_BIO_s_socket();
! 	if (bio_method == NULL)
! 	{
! 		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
! 		goto err;
! 	}
! 	bio = BIO_new(bio_method);
  
  	if (bio == NULL)
  	{
*************** load_dh_buffer(const char *buffer, size_
*** 590,595 ****
--- 624,654 ----
  }
  
  /*
+  *	Generate DH parameters.
+  *
+  *	Last resort if we can't load precomputed nor hardcoded
+  *	parameters.
+  */
+ static DH  *
+ generate_dh_parameters(int prime_len, int generator)
+ {
+ #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+ 	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
   *	common key sizes.
*************** tmp_dh_cb(SSL *s, int is_export, int key
*** 658,664 ****
  		ereport(DEBUG2,
  				(errmsg_internal("DH: generating parameters (%d bits)",
  								 keylength)));
! 		r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
  	}
  
  	return r;
--- 717,723 ----
  		ereport(DEBUG2,
  				(errmsg_internal("DH: generating parameters (%d bits)",
  								 keylength)));
! 		r = generate_dh_parameters(keylength, DH_GENERATOR_2);
  	}
  
  	return r;
*************** initialize_SSL(void)
*** 737,747 ****
--- 796,810 ----
  
  	if (!SSL_context)
  	{
+ #ifdef HAVE_OPENSSL_INIT_SSL
+ 		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
+ #else
  #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
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 985e5a7..872d39f 100644
*** a/src/include/pg_config.h.in
--- b/src/include/pg_config.h.in
***************
*** 87,92 ****
--- 87,98 ----
  /* Define to 1 if you have the `append_history' function. */
  #undef HAVE_APPEND_HISTORY
  
+ /* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
+ #undef HAVE_ASN1_STRING_GET0_DATA
+ 
+ /* Define to 1 if you have the `BIO_meth_new' function. */
+ #undef HAVE_BIO_METH_NEW
+ 
  /* Define to 1 if you have the `cbrt' function. */
  #undef HAVE_CBRT
  
***************
*** 99,104 ****
--- 105,113 ----
  /* Define to 1 if you have the `crypt' function. */
  #undef HAVE_CRYPT
  
+ /* Define to 1 if you have the `CRYPTO_lock' function. */
+ #undef HAVE_CRYPTO_LOCK
+ 
  /* Define to 1 if you have the <crypt.h> header file. */
  #undef HAVE_CRYPT_H
  
***************
*** 357,362 ****
--- 366,374 ----
  /* Define to 1 if you have the <net/if.h> header file. */
  #undef HAVE_NET_IF_H
  
+ /* Define to 1 if you have the `OPENSSL_init_ssl' function. */
+ #undef HAVE_OPENSSL_INIT_SSL
+ 
  /* Define to 1 if you have the <ossp/uuid.h> header file. */
  #undef HAVE_OSSP_UUID_H
  
***************
*** 396,401 ****
--- 408,416 ----
  /* Define to 1 if you have the `random' function. */
  #undef HAVE_RANDOM
  
+ /* Define to 1 if you have the `RAND_OpenSSL' function. */
+ #undef HAVE_RAND_OPENSSL
+ 
  /* Define to 1 if you have the <readline.h> header file. */
  #undef HAVE_READLINE_H
  
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 9e7ae47..a52a206 100644
*** a/src/interfaces/libpq/fe-secure.c
--- b/src/interfaces/libpq/fe-secure.c
***************
*** 58,64 ****
  #ifdef USE_SSL
  
  #include <openssl/ssl.h>
! #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
  #include <openssl/conf.h>
  #endif
  #ifdef USE_SSL_ENGINE
--- 58,64 ----
  #ifdef USE_SSL
  
  #include <openssl/ssl.h>
! #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
  #include <openssl/conf.h>
  #endif
  #ifdef USE_SSL_ENGINE
*************** verify_peer_name_matches_certificate(PGc
*** 835,843 ****
  	return result;
  }
  
! #ifdef ENABLE_THREAD_SAFETY
  /*
!  *	Callback functions for OpenSSL internal locking
   */
  
  static unsigned long
--- 835,847 ----
  	return result;
  }
  
! #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
  /*
!  *	Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
!  *	does its own locking, and doesn't need these anymore.  The
!  *	CRYPTO_lock() function was removed in 1.1.0, when the callbacks
!  *	were made obsolete, so we assume that if CRYPTO_lock() exists,
!  *	the callbacks are still required.)
   */
  
  static unsigned long
*************** pq_lockingcallback(int mode, int n, cons
*** 867,873 ****
  			PGTHREAD_ERROR("failed to unlock mutex");
  	}
  }
! #endif   /* ENABLE_THREAD_SAFETY */
  
  /*
   * Initialize SSL library.
--- 871,877 ----
  			PGTHREAD_ERROR("failed to unlock mutex");
  	}
  }
! #endif   /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
  
  /*
   * Initialize SSL library.
*************** init_ssl_system(PGconn *conn)
*** 905,910 ****
--- 909,915 ----
  	if (pthread_mutex_lock(&ssl_config_mutex))
  		return -1;
  
+ #ifdef HAVE_CRYPTO_LOCK
  	if (pq_init_crypto_lib)
  	{
  		/*
*************** init_ssl_system(PGconn *conn)
*** 940,956 ****
  			CRYPTO_set_locking_callback(pq_lockingcallback);
  		}
  	}
  #endif   /* ENABLE_THREAD_SAFETY */
  
  	if (!ssl_lib_initialized)
  	{
  		if (pq_init_ssl_lib)
  		{
! #if SSLEAY_VERSION_NUMBER >= 0x00907000L
  			OPENSSL_config(NULL);
  #endif
  			SSL_library_init();
  			SSL_load_error_strings();
  		}
  		ssl_lib_initialized = true;
  	}
--- 945,966 ----
  			CRYPTO_set_locking_callback(pq_lockingcallback);
  		}
  	}
+ #endif   /* HAVE_CRYPTO_LOCK */
  #endif   /* ENABLE_THREAD_SAFETY */
  
  	if (!ssl_lib_initialized)
  	{
  		if (pq_init_ssl_lib)
  		{
! #ifdef HAVE_OPENSSL_INIT_SSL
! 			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
! #else
! #if OPENSSL_VERSION_NUMBER >= 0x00907000L
  			OPENSSL_config(NULL);
  #endif
  			SSL_library_init();
  			SSL_load_error_strings();
+ #endif
  		}
  		ssl_lib_initialized = true;
  	}
*************** init_ssl_system(PGconn *conn)
*** 970,981 ****
   *	if we had any.)
   *
   *	Callbacks are only set when we're compiled in threadsafe mode, so
!  *	we only need to remove them in this case.
   */
  static void
  destroy_ssl_system(void)
  {
! #ifdef ENABLE_THREAD_SAFETY
  	/* Mutex is created in initialize_ssl_system() */
  	if (pthread_mutex_lock(&ssl_config_mutex))
  		return;
--- 980,992 ----
   *	if we had any.)
   *
   *	Callbacks are only set when we're compiled in threadsafe mode, so
!  *	we only need to remove them in this case. They are also not needed
!  *	with OpenSSL 1.1.0 anymore.
   */
  static void
  destroy_ssl_system(void)
  {
! #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
  	/* Mutex is created in initialize_ssl_system() */
  	if (pthread_mutex_lock(&ssl_config_mutex))
  		return;
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index f14cf2b..ba1bfac 100644
*** a/src/interfaces/libpq/libpq-int.h
--- b/src/interfaces/libpq/libpq-int.h
*************** typedef struct
*** 77,83 ****
  #include <openssl/ssl.h>
  #include <openssl/err.h>
  
! #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
  #define USE_SSL_ENGINE
  #endif
  #endif   /* USE_SSL */
--- 77,83 ----
  #include <openssl/ssl.h>
  #include <openssl/err.h>
  
! #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
  #define USE_SSL_ENGINE
  #endif
  #endif   /* USE_SSL */
#55Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#54)
Re: OpenSSL 1.1 breaks configure and more

I wrote:

If we want to go any further back with 1.1 support, we have a range
of options:
1. Back-patch that patch, probably also including the followup adjustments
in 86029b31e and 36a3be654.
2. Add #if's to use 31cf1a1a4's coding with OpenSSL >= 1.1, while keeping
the older code for use when built against older OpenSSLs.
3. Conditionally disable renegotiation altogether with OpenSSL >= 1.1,
thus adopting 9.5 not 9.4 behavior when using newer OpenSSL.

I think #3 would be fairly weird unless we also changed 9.4 similarly.
But there's some argument for doing that: we don't really have any field
experience with using renegotiation with OpenSSL 1.1, so we don't know
that what is in the 9.4 branch right now actually works with 1.1.
On the other hand, it would also be the most work of these options,
since we'd have to do things like adding conditional behavior in guc.c.

I did some simple testing and can say that at least the successful path
in the 9.4 code seems to be fine with 1.1; in particular I see no sign
of the misbehavior discussed in
/messages/by-id/20150126101405.GA31719@awork2.anarazel.de
Given Heikki's opinion that that was an OpenSSL bug, perhaps they
fixed the bug. Certainly we don't seem to have committed any of
the workaround patches discussed in that thread.

At this point I'd be inclined to reject option #3: aside from being
more work, it'd be a pain to document, and confusing for users.
I have a slight preference for #1 over #2 --- we'd intended to back-patch
Alvaro's fixes once they had survived some field use, and I know of no
evidence that 9.4 is worse than the older branches.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#56Andreas Karlsson
andreas@proxel.se
In reply to: Tom Lane (#54)
Re: OpenSSL 1.1 breaks configure and more

On 04/16/2017 03:14 AM, Tom Lane wrote:

1. Back-patch that patch, probably also including the followup adjustments
in 86029b31e and 36a3be654.

2. Add #if's to use 31cf1a1a4's coding with OpenSSL >= 1.1, while keeping
the older code for use when built against older OpenSSLs.

3. Conditionally disable renegotiation altogether with OpenSSL >= 1.1,
thus adopting 9.5 not 9.4 behavior when using newer OpenSSL.

[...]

Thoughts?

Given that I cannot recall seeing any complaints about the behavior of
9.4 compared to 9.3 I am leaning towards #1. That way there are fewer
different versions of our OpenSSL code.

Andreas

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#57Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andreas Karlsson (#56)
Re: OpenSSL 1.1 breaks configure and more

Andreas Karlsson <andreas@proxel.se> writes:

On 04/16/2017 03:14 AM, Tom Lane wrote:

1. Back-patch that patch, probably also including the followup adjustments
in 86029b31e and 36a3be654.

Given that I cannot recall seeing any complaints about the behavior of
9.4 compared to 9.3 I am leaning towards #1. That way there are fewer
different versions of our OpenSSL code.

Yeah, I was thinking about that point too. Barring objections I'll
do #1 and then move forward with the openssl 1.1 backport.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers