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 */
