From 30ca8928a0a6bd901105529fe664e989122ed6ae Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Tue, 2 Apr 2024 20:46:41 +0200
Subject: [PATCH v1] Remove support for OpenSSL 1.0.2 and 1.1.0

This sets the required version of OpenSSL at 1.1.1.
---
 configure                                |  40 +----
 configure.ac                             |  19 +--
 doc/src/sgml/installation.sgml           |   2 +-
 doc/src/sgml/libpq.sgml                  |   4 +-
 meson.build                              |  21 +--
 src/backend/libpq/be-secure-openssl.c    |  33 +---
 src/common/hmac_openssl.c                |  13 --
 src/include/pg_config.h.in               |  21 ---
 src/interfaces/libpq/fe-secure-openssl.c | 205 +----------------------
 src/interfaces/libpq/libpq-int.h         |   5 -
 10 files changed, 20 insertions(+), 343 deletions(-)

diff --git a/configure b/configure
index 36feeafbb2..16b7b1fef9 100755
--- a/configure
+++ b/configure
@@ -12327,9 +12327,10 @@ if test "$with_openssl" = yes ; then
 fi
 
 if test "$with_ssl" = openssl ; then
-    # Minimum required OpenSSL version is 1.0.2
+    # Minimum required OpenSSL version is 1.1.1, but we set 1.1.0 as he deprecation
+  # level since 1.1.1 wasn't defined as a deprecation point by OpenSSL
 
-$as_echo "#define OPENSSL_API_COMPAT 0x10002000L" >>confdefs.h
+$as_echo "#define OPENSSL_API_COMPAT 0x10100000L" >>confdefs.h
 
   if test "$PORTNAME" != "win32"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5
@@ -12556,36 +12557,8 @@ _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_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free
-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
+$as_echo "#define USE_OPENSSL 1" >>confdefs.h
 
   # Function introduced in OpenSSL 1.1.1.
   for ac_func in X509_get_signature_info
@@ -12596,12 +12569,11 @@ if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
 #define HAVE_X509_GET_SIGNATURE_INFO 1
 _ACEOF
 
+else
+  as_fn_error $? "OpenSSL, version 1.1.1 or newer, is required for SSL support" "$LINENO" 5
 fi
 done
 
-
-$as_echo "#define USE_OPENSSL 1" >>confdefs.h
-
 elif test "$with_ssl" != no ; then
   as_fn_error $? "--with-ssl must specify openssl" "$LINENO" 5
 fi
diff --git a/configure.ac b/configure.ac
index 57f734879e..9d9e976de5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1335,8 +1335,9 @@ fi
 
 if test "$with_ssl" = openssl ; then
   dnl Order matters!
-  # Minimum required OpenSSL version is 1.0.2
-  AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L],
+  # Minimum required OpenSSL version is 1.1.1, but we set 1.1.0 as he deprecation
+  # level since 1.1.1 wasn't defined as a deprecation point by OpenSSL
+  AC_DEFINE(OPENSSL_API_COMPAT, [0x10100000L],
             [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.])
   if test "$PORTNAME" != "win32"; then
      AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
@@ -1347,19 +1348,9 @@ if test "$with_ssl" = openssl ; then
   fi
   # Function introduced in OpenSSL 1.0.2, not in LibreSSL.
   AC_CHECK_FUNCS([SSL_CTX_set_cert_cb])
-  # 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 HMAC_CTX_new HMAC_CTX_free])
-  # 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])
-  # Function introduced in OpenSSL 1.1.1.
-  AC_CHECK_FUNCS([X509_get_signature_info])
   AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)])
+  # Function introduced in OpenSSL 1.1.1.
+  AC_CHECK_FUNCS([X509_get_signature_info], [], [AC_MSG_ERROR([OpenSSL, version 1.1.1 or newer, is required for SSL support])])
 elif test "$with_ssl" != no ; then
   AC_MSG_ERROR([--with-ssl must specify openssl])
 fi
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index a453f804cd..1d5578d935 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -293,7 +293,7 @@
       encrypted client connections.  <productname>OpenSSL</productname> is
       also required for random number generation on platforms that do not
       have <filename>/dev/urandom</filename> (except Windows).  The minimum
-      required version is 1.0.2.
+      required version is 1.1.1.
      </para>
     </listitem>
 
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index d3e87056f2..e718d355bb 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1741,9 +1741,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
 
        <para>
         SSL compression is nowadays considered insecure and its use is no
-        longer recommended.  <productname>OpenSSL</productname> 1.1.0 disables
+        longer recommended.  <productname>OpenSSL</productname> 1.1.0 disabled
         compression by default, and many operating system distributions
-        disable it in prior versions as well, so setting this parameter to on
+        disabled it in prior versions as well, so setting this parameter to on
         will not have any effect if the server does not accept compression.
         <productname>PostgreSQL</productname> 14 disables compression
         completely in the backend.
diff --git a/meson.build b/meson.build
index 18b5be842e..119f9c9405 100644
--- a/meson.build
+++ b/meson.build
@@ -1274,25 +1274,8 @@ if sslopt in ['auto', 'openssl']
 
       # Function introduced in OpenSSL 1.0.2, not in LibreSSL.
       ['SSL_CTX_set_cert_cb'],
-
-      # 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.
-      ['OPENSSL_init_ssl'],
-      ['BIO_meth_new'],
-      ['ASN1_STRING_get0_data'],
-      ['HMAC_CTX_new'],
-      ['HMAC_CTX_free'],
-
-      # 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.
-      ['CRYPTO_lock'],
-
       # Function introduced in OpenSSL 1.1.1
-      ['X509_get_signature_info'],
+      ['X509_get_signature_info', {'required': true}]
     ]
 
     are_openssl_funcs_complete = true
@@ -1314,7 +1297,7 @@ if sslopt in ['auto', 'openssl']
     if are_openssl_funcs_complete
       cdata.set('USE_OPENSSL', 1,
                 description: 'Define to 1 to build with OpenSSL support. (-Dssl=openssl)')
-      cdata.set('OPENSSL_API_COMPAT', '0x10002000L',
+      cdata.set('OPENSSL_API_COMPAT', '0x10100000L',
                 description: 'Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.')
       ssl_library = 'openssl'
     else
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 72e43af353..c0227f6239 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -98,13 +98,7 @@ be_tls_init(bool isServerStart)
 	/* This stuff need be done only once. */
 	if (!SSL_initialized)
 	{
-#ifdef HAVE_OPENSSL_INIT_SSL
 		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
-#else
-		OPENSSL_config(NULL);
-		SSL_library_init();
-		SSL_load_error_strings();
-#endif
 		SSL_initialized = true;
 	}
 
@@ -261,15 +255,11 @@ be_tls_init(bool isServerStart)
 	/* disallow SSL compression */
 	SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
 
-#ifdef SSL_OP_NO_RENEGOTIATION
-
 	/*
-	 * Disallow SSL renegotiation, option available since 1.1.0h.  This
-	 * concerns only TLSv1.2 and older protocol versions, as TLSv1.3 has no
-	 * support for renegotiation.
+	 * Disallow SSL renegotiation.  This concerns only TLSv1.2 and older
+	 * protocol versions, as TLSv1.3 has no support for renegotiation.
 	 */
 	SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
-#endif
 
 	/* set up ephemeral DH and ECDH keys */
 	if (!initialize_dh(context, isServerStart))
@@ -531,10 +521,8 @@ aloop:
 					case SSL_R_WRONG_SSL_VERSION:
 					case SSL_R_WRONG_VERSION_NUMBER:
 					case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
-#ifdef SSL_R_VERSION_TOO_HIGH
 					case SSL_R_VERSION_TOO_HIGH:
 					case SSL_R_VERSION_TOO_LOW:
-#endif
 						give_proto_hint = true;
 						break;
 					default:
@@ -898,7 +886,6 @@ 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();
@@ -921,14 +908,6 @@ my_BIO_s_socket(void)
 			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;
 }
@@ -1468,15 +1447,9 @@ be_tls_get_certificate_hash(Port *port, size_t *len)
 
 	/*
 	 * Get the signature algorithm of the certificate to determine the hash
-	 * algorithm to use for the result.  Prefer X509_get_signature_info(),
-	 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
+	 * algorithm to use for the result.
 	 */
-#if HAVE_X509_GET_SIGNATURE_INFO
 	if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
-#else
-	if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
-							 &algo_nid, NULL))
-#endif
 		elog(ERROR, "could not determine server certificate signature algorithm");
 
 	/*
diff --git a/src/common/hmac_openssl.c b/src/common/hmac_openssl.c
index d10f7e5af7..89d71a819e 100644
--- a/src/common/hmac_openssl.c
+++ b/src/common/hmac_openssl.c
@@ -138,14 +138,10 @@ pg_hmac_create(pg_cryptohash_type type)
 	 * previous runs.
 	 */
 	ERR_clear_error();
-#ifdef HAVE_HMAC_CTX_NEW
 #ifndef FRONTEND
 	ResourceOwnerEnlarge(CurrentResourceOwner);
 #endif
 	ctx->hmacctx = HMAC_CTX_new();
-#else
-	ctx->hmacctx = ALLOC(sizeof(HMAC_CTX));
-#endif
 
 	if (ctx->hmacctx == NULL)
 	{
@@ -159,14 +155,10 @@ pg_hmac_create(pg_cryptohash_type type)
 		return NULL;
 	}
 
-#ifdef HAVE_HMAC_CTX_NEW
 #ifndef FRONTEND
 	ctx->resowner = CurrentResourceOwner;
 	ResourceOwnerRememberHMAC(CurrentResourceOwner, ctx);
 #endif
-#else
-	memset(ctx->hmacctx, 0, sizeof(HMAC_CTX));
-#endif							/* HAVE_HMAC_CTX_NEW */
 
 	return ctx;
 }
@@ -325,16 +317,11 @@ pg_hmac_free(pg_hmac_ctx *ctx)
 	if (ctx == NULL)
 		return;
 
-#ifdef HAVE_HMAC_CTX_FREE
 	HMAC_CTX_free(ctx->hmacctx);
 #ifndef FRONTEND
 	if (ctx->resowner)
 		ResourceOwnerForgetHMAC(ctx->resowner, ctx);
 #endif
-#else
-	explicit_bzero(ctx->hmacctx, sizeof(HMAC_CTX));
-	FREE(ctx->hmacctx);
-#endif
 
 	explicit_bzero(ctx, sizeof(pg_hmac_ctx));
 	FREE(ctx);
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 591e1ca3df..d2286e0b44 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -54,9 +54,6 @@
 /* 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 want to use atomics if available. */
 #undef HAVE_ATOMICS
 
@@ -66,9 +63,6 @@
 /* Define to 1 if you have the `backtrace_symbols' function. */
 #undef HAVE_BACKTRACE_SYMBOLS
 
-/* Define to 1 if you have the `BIO_meth_new' function. */
-#undef HAVE_BIO_METH_NEW
-
 /* Define to 1 if your compiler handles computed gotos. */
 #undef HAVE_COMPUTED_GOTO
 
@@ -84,9 +78,6 @@
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
-/* Define to 1 if you have the `CRYPTO_lock' function. */
-#undef HAVE_CRYPTO_LOCK
-
 /* Define to 1 if you have the declaration of `fdatasync', and to 0 if you
    don't. */
 #undef HAVE_DECL_FDATASYNC
@@ -198,12 +189,6 @@
 /* Define to 1 if you have the `history_truncate_file' function. */
 #undef HAVE_HISTORY_TRUNCATE_FILE
 
-/* Define to 1 if you have the `HMAC_CTX_free' function. */
-#undef HAVE_HMAC_CTX_FREE
-
-/* Define to 1 if you have the `HMAC_CTX_new' function. */
-#undef HAVE_HMAC_CTX_NEW
-
 /* Define to 1 if you have the <ifaddrs.h> header file. */
 #undef HAVE_IFADDRS_H
 
@@ -303,9 +288,6 @@
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP
 
-/* 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
 
@@ -507,9 +489,6 @@
 /* Define to 1 if you have the `wcstombs_l' function. */
 #undef HAVE_WCSTOMBS_L
 
-/* Define to 1 if you have the `X509_get_signature_info' function. */
-#undef HAVE_X509_GET_SIGNATURE_INFO
-
 /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */
 #undef HAVE_X86_64_POPCNTQ
 
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 0c8c9f8dcb..dd9dfe963c 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -71,7 +71,6 @@ static int	openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
 static int	openssl_verify_peer_name_matches_certificate_ip(PGconn *conn,
 															ASN1_OCTET_STRING *addr_entry,
 															char **store_name);
-static void destroy_ssl_system(void);
 static int	initialize_SSL(PGconn *conn);
 static PostgresPollingStatusType open_client_SSL(PGconn *conn);
 static char *SSLerrmessage(unsigned long ecode);
@@ -377,15 +376,9 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 
 	/*
 	 * Get the signature algorithm of the certificate to determine the hash
-	 * algorithm to use for the result.  Prefer X509_get_signature_info(),
-	 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
+	 * algorithm to use for the result.
 	 */
-#if HAVE_X509_GET_SIGNATURE_INFO
 	if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
-#else
-	if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
-							 &algo_nid, NULL))
-#endif
 	{
 		libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
 		return NULL;
@@ -505,11 +498,7 @@ openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *nam
 	/*
 	 * GEN_DNS can be only IA5String, equivalent to US ASCII.
 	 */
-#ifdef HAVE_ASN1_STRING_GET0_DATA
 	namedata = ASN1_STRING_get0_data(name_entry);
-#else
-	namedata = ASN1_STRING_data(name_entry);
-#endif
 	len = ASN1_STRING_length(name_entry);
 
 	/* OK to cast from unsigned to plain char, since it's all ASCII. */
@@ -540,11 +529,7 @@ openssl_verify_peer_name_matches_certificate_ip(PGconn *conn,
 	 * GEN_IPADD is an OCTET STRING containing an IP address in network byte
 	 * order.
 	 */
-#ifdef HAVE_ASN1_STRING_GET0_DATA
 	addrdata = ASN1_STRING_get0_data(addr_entry);
-#else
-	addrdata = ASN1_STRING_data(addr_entry);
-#endif
 	len = ASN1_STRING_length(addr_entry);
 
 	return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name);
@@ -712,49 +697,6 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
 	return rc;
 }
 
-#if 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_threadidcallback(void)
-{
-	/*
-	 * This is not standards-compliant.  pthread_self() returns pthread_t, and
-	 * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
-	 * it, so we have to do it.
-	 */
-	return (unsigned long) pthread_self();
-}
-
-static pthread_mutex_t *pq_lockarray;
-
-static void
-pq_lockingcallback(int mode, int n, const char *file, int line)
-{
-	/*
-	 * There's no way to report a mutex-primitive failure, so we just Assert
-	 * in development builds, and ignore any errors otherwise.  Fortunately
-	 * this is all obsolete in modern OpenSSL.
-	 */
-	if (mode & CRYPTO_LOCK)
-	{
-		if (pthread_mutex_lock(&pq_lockarray[n]))
-			Assert(false);
-	}
-	else
-	{
-		if (pthread_mutex_unlock(&pq_lockarray[n]))
-			Assert(false);
-	}
-}
-#endif							/* HAVE_CRYPTO_LOCK */
-
 /*
  * Initialize SSL library.
  *
@@ -771,67 +713,10 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 	if (pthread_mutex_lock(&ssl_config_mutex))
 		return -1;
 
-#ifdef HAVE_CRYPTO_LOCK
-	if (pq_init_crypto_lib)
-	{
-		/*
-		 * If necessary, set up an array to hold locks for libcrypto.
-		 * libcrypto will tell us how big to make this array.
-		 */
-		if (pq_lockarray == NULL)
-		{
-			int			i;
-
-			pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
-			if (!pq_lockarray)
-			{
-				pthread_mutex_unlock(&ssl_config_mutex);
-				return -1;
-			}
-			for (i = 0; i < CRYPTO_num_locks(); i++)
-			{
-				if (pthread_mutex_init(&pq_lockarray[i], NULL))
-				{
-					free(pq_lockarray);
-					pq_lockarray = NULL;
-					pthread_mutex_unlock(&ssl_config_mutex);
-					return -1;
-				}
-			}
-		}
-
-		if (do_crypto && !conn->crypto_loaded)
-		{
-			if (crypto_open_connections++ == 0)
-			{
-				/*
-				 * These are only required for threaded libcrypto
-				 * applications, but make sure we don't stomp on them if
-				 * they're already set.
-				 */
-				if (CRYPTO_get_id_callback() == NULL)
-					CRYPTO_set_id_callback(pq_threadidcallback);
-				if (CRYPTO_get_locking_callback() == NULL)
-					CRYPTO_set_locking_callback(pq_lockingcallback);
-			}
-
-			conn->crypto_loaded = true;
-		}
-	}
-#endif							/* HAVE_CRYPTO_LOCK */
-
 	if (!ssl_lib_initialized && do_ssl)
 	{
 		if (pq_init_ssl_lib)
-		{
-#ifdef HAVE_OPENSSL_INIT_SSL
 			OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
-#else
-			OPENSSL_config(NULL);
-			SSL_library_init();
-			SSL_load_error_strings();
-#endif
-		}
 		ssl_lib_initialized = true;
 	}
 
@@ -839,52 +724,6 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
 	return 0;
 }
 
-/*
- *	This function is needed because if the libpq library is unloaded
- *	from the application, the callback functions will no longer exist when
- *	libcrypto is used by other parts of the system.  For this reason,
- *	we unregister the callback functions when the last libpq
- *	connection is closed.  (The same would apply for OpenSSL callbacks
- *	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(HAVE_CRYPTO_LOCK)
-	if (pthread_mutex_lock(&ssl_config_mutex))
-		return;
-
-	if (pq_init_crypto_lib && crypto_open_connections > 0)
-		--crypto_open_connections;
-
-	if (pq_init_crypto_lib && crypto_open_connections == 0)
-	{
-		/*
-		 * No connections left, unregister libcrypto callbacks, if no one
-		 * registered different ones in the meantime.
-		 */
-		if (CRYPTO_get_locking_callback() == pq_lockingcallback)
-			CRYPTO_set_locking_callback(NULL);
-		if (CRYPTO_get_id_callback() == pq_threadidcallback)
-			CRYPTO_set_id_callback(NULL);
-
-		/*
-		 * We don't free the lock array. If we get another connection in this
-		 * process, we will just re-use them with the existing mutexes.
-		 *
-		 * This means we leak a little memory on repeated load/unload of the
-		 * library.
-		 */
-	}
-
-	pthread_mutex_unlock(&ssl_config_mutex);
-#endif
-}
-
 /*
  *	Create per-connection SSL object, and load the client certificate,
  *	private key, and trusted CA certs.
@@ -1596,8 +1435,6 @@ open_client_SSL(PGconn *conn)
 void
 pgtls_close(PGconn *conn)
 {
-	bool		destroy_needed = false;
-
 	if (conn->ssl_in_use)
 	{
 		if (conn->ssl)
@@ -1612,8 +1449,6 @@ pgtls_close(PGconn *conn)
 			SSL_free(conn->ssl);
 			conn->ssl = NULL;
 			conn->ssl_in_use = false;
-
-			destroy_needed = true;
 		}
 
 		if (conn->peer)
@@ -1631,30 +1466,6 @@ pgtls_close(PGconn *conn)
 		}
 #endif
 	}
-	else
-	{
-		/*
-		 * In the non-SSL case, just remove the crypto callbacks if the
-		 * connection has then loaded.  This code path has no dependency on
-		 * any pending SSL calls.
-		 */
-		if (conn->crypto_loaded)
-			destroy_needed = true;
-	}
-
-	/*
-	 * This will remove our crypto locking hooks if this is the last
-	 * connection using libcrypto which means we must wait to call it until
-	 * after all the potential SSL calls have been made, otherwise we can end
-	 * up with a race condition and possible deadlocks.
-	 *
-	 * See comments above destroy_ssl_system().
-	 */
-	if (destroy_needed)
-	{
-		destroy_ssl_system();
-		conn->crypto_loaded = false;
-	}
 }
 
 
@@ -1895,7 +1706,6 @@ 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();
@@ -1921,14 +1731,6 @@ my_BIO_s_socket(void)
 		{
 			goto err;
 		}
-#else
-		res = malloc(sizeof(BIO_METHOD));
-		if (!res)
-			goto err;
-		memcpy(res, biom, sizeof(BIO_METHOD));
-		res->bread = my_sock_read;
-		res->bwrite = my_sock_write;
-#endif
 	}
 
 	my_bio_methods = res;
@@ -1936,13 +1738,8 @@ my_BIO_s_socket(void)
 	return res;
 
 err:
-#ifdef HAVE_BIO_METH_NEW
 	if (res)
 		BIO_meth_free(res);
-#else
-	if (res)
-		free(res);
-#endif
 	pthread_mutex_unlock(&ssl_config_mutex);
 	return NULL;
 }
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 9c05f11a6e..d049087301 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -565,11 +565,6 @@ struct pg_conn
 	void	   *engine;			/* dummy field to keep struct the same if
 								 * OpenSSL version changes */
 #endif
-	bool		crypto_loaded;	/* Track if libcrypto locking callbacks have
-								 * been done for this connection. This can be
-								 * removed once support for OpenSSL 1.0.2 is
-								 * removed as this locking is handled
-								 * internally in OpenSSL >= 1.1.0. */
 #endif							/* USE_OPENSSL */
 #endif							/* USE_SSL */
 
-- 
2.32.1 (Apple Git-133)

