From 0bbb001513d07b47223b4dbd8950241c327ca731 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Wed, 24 May 2023 17:08:24 +0900
Subject: [PATCH v1 2/2] Remove support for OpenSSL 1.0.2

This allows the removal of the following flags:
HAVE_ASN1_STRING_GET0_DATA
HAVE_BIO_GET_DATA
HAVE_BIO_METH_NEW
HAVE_HMAC_CTX_FREE
HAVE_HMAC_CTX_NEW

OpenSSL 1.1.0 has removed CRYPTO_lock(), but LibreSSL requires it.  On
the contrary, OPENSSL_init_ssl() is not in OpenSSL.
---
 src/include/pg_config.h.in               | 15 ------------
 src/backend/libpq/be-secure-openssl.c    | 14 ------------
 src/common/hmac_openssl.c                | 17 --------------
 src/interfaces/libpq/fe-secure-openssl.c | 22 ------------------
 src/interfaces/libpq/libpq-int.h         |  5 +---
 doc/src/sgml/installation.sgml           |  2 +-
 configure                                | 29 +++++++-----------------
 configure.ac                             | 21 ++++++++---------
 meson.build                              | 20 ++++++----------
 src/tools/msvc/Solution.pm               | 18 +--------------
 10 files changed, 27 insertions(+), 136 deletions(-)

diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ca3a49c552..80b6ddec73 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -58,9 +58,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
 
@@ -70,12 +67,6 @@
 /* Define to 1 if you have the `backtrace_symbols' function. */
 #undef HAVE_BACKTRACE_SYMBOLS
 
-/* 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 your compiler handles computed gotos. */
 #undef HAVE_COMPUTED_GOTO
 
@@ -214,12 +205,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
 
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 658b09988d..61ad6b3476 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -833,11 +833,6 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
  */
 
-#ifndef HAVE_BIO_GET_DATA
-#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
@@ -887,7 +882,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();
@@ -910,14 +904,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;
 }
diff --git a/src/common/hmac_openssl.c b/src/common/hmac_openssl.c
index 12be542fa2..068b098da6 100644
--- a/src/common/hmac_openssl.c
+++ b/src/common/hmac_openssl.c
@@ -41,11 +41,7 @@
  * a failure status back to the caller.
  */
 #ifndef FRONTEND
-#ifdef HAVE_HMAC_CTX_NEW
 #define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size)
-#else
-#define ALLOC(size) palloc(size)
-#endif
 #define FREE(ptr) pfree(ptr)
 #else							/* FRONTEND */
 #define ALLOC(size) malloc(size)
@@ -113,14 +109,10 @@ pg_hmac_create(pg_cryptohash_type type)
 	 * previous runs.
 	 */
 	ERR_clear_error();
-#ifdef HAVE_HMAC_CTX_NEW
 #ifndef FRONTEND
 	ResourceOwnerEnlargeHMAC(CurrentResourceOwner);
 #endif
 	ctx->hmacctx = HMAC_CTX_new();
-#else
-	ctx->hmacctx = ALLOC(sizeof(HMAC_CTX));
-#endif
 
 	if (ctx->hmacctx == NULL)
 	{
@@ -134,14 +126,10 @@ pg_hmac_create(pg_cryptohash_type type)
 		return NULL;
 	}
 
-#ifdef HAVE_HMAC_CTX_NEW
 #ifndef FRONTEND
 	ctx->resowner = CurrentResourceOwner;
 	ResourceOwnerRememberHMAC(CurrentResourceOwner, PointerGetDatum(ctx));
 #endif
-#else
-	memset(ctx->hmacctx, 0, sizeof(HMAC_CTX));
-#endif							/* HAVE_HMAC_CTX_NEW */
 
 	return ctx;
 }
@@ -300,15 +288,10 @@ pg_hmac_free(pg_hmac_ctx *ctx)
 	if (ctx == NULL)
 		return;
 
-#ifdef HAVE_HMAC_CTX_FREE
 	HMAC_CTX_free(ctx->hmacctx);
 #ifndef FRONTEND
 	ResourceOwnerForgetHMAC(ctx->resowner, PointerGetDatum(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/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index bea71660ab..123ba4d04c 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -511,11 +511,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. */
@@ -546,11 +542,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);
@@ -1826,11 +1818,6 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
  */
 
-#ifndef HAVE_BIO_GET_DATA
-#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
@@ -1899,7 +1886,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();
@@ -1927,14 +1913,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;
 }
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 33bacd8e65..d3a86876e0 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -564,10 +564,7 @@ struct pg_conn
 								 * 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. */
+								 * been done for this connection */
 #endif							/* USE_OPENSSL */
 #endif							/* USE_SSL */
 
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index e9d797417a..f2dc53dcb5 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -275,7 +275,7 @@ documentation.  See standalone-profile.xsl for details.
       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.0.
      </para>
     </listitem>
 
diff --git a/configure b/configure
index dbb37f3b83..748977c3bb 100755
--- a/configure
+++ b/configure
@@ -12744,7 +12744,8 @@ 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.0.  API compatibility is kept at
+  # 1.0.2 for OpenSSL_add_all_algorithms().
 
 $as_echo "#define OPENSSL_API_COMPAT 0x10002000L" >>confdefs.h
 
@@ -12961,24 +12962,11 @@ else
 fi
 
   fi
-  # LibreSSL does not have SSL_CTX_set_cert_cb().
-  for ac_func in SSL_CTX_set_cert_cb
-do :
-  ac_fn_c_check_func "$LINENO" "SSL_CTX_set_cert_cb" "ac_cv_func_SSL_CTX_set_cert_cb"
-if test "x$ac_cv_func_SSL_CTX_set_cert_cb" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SSL_CTX_SET_CERT_CB 1
-_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 not in LibreSSL.  We used to check for OPENSSL_VERSION_NUMBER,
+  # but that didn't work with OpenSSL 1.1.0, because LibreSSL defines
+  # OPENSSL_VERSION_NUMBER to claim version 2.0.0. So check for individual
   # functions.
-  for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free
+  for ac_func in SSL_CTX_set_cert_cb OPENSSL_init_ssl
 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"
@@ -12990,9 +12978,8 @@ _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.
+  # Function included in LibreSSL, not in OpenSSL.  This is required for
+  # thread safety.
   for ac_func in CRYPTO_lock
 do :
   ac_fn_c_check_func "$LINENO" "CRYPTO_lock" "ac_cv_func_CRYPTO_lock"
diff --git a/configure.ac b/configure.ac
index 94ae1d33c2..7f723289dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1367,7 +1367,8 @@ fi
 
 if test "$with_ssl" = openssl ; then
   dnl Order matters!
-  # Minimum required OpenSSL version is 1.0.2
+  # Minimum required OpenSSL version is 1.1.0.  API compatibility is kept at
+  # 1.0.2 for OpenSSL_add_all_algorithms().
   AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L],
             [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.])
   if test "$PORTNAME" != "win32"; then
@@ -1377,18 +1378,14 @@ if test "$with_ssl" = openssl ; then
      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
-  # LibreSSL does not have SSL_CTX_set_cert_cb().
-  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 not in LibreSSL.  We used to check for OPENSSL_VERSION_NUMBER,
+  # but that didn't work with OpenSSL 1.1.0, because LibreSSL defines
+  # OPENSSL_VERSION_NUMBER to claim version 2.0.0. So check for individual
   # functions.
-  AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data 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])
+  AC_CHECK_FUNCS([SSL_CTX_set_cert_cb OPENSSL_init_ssl])
+  # Function included in LibreSSL, not in OpenSSL.  This is required for
+  # thread safety.
+  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)])
diff --git a/meson.build b/meson.build
index 5cf13e3b36..c176a0fbea 100644
--- a/meson.build
+++ b/meson.build
@@ -1271,21 +1271,15 @@ if sslopt in ['auto', 'openssl']
       # Function 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 not in LibreSSL. 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. So check for individual
       # functions.
       ['OPENSSL_init_ssl'],
-      ['BIO_get_data'],
-      ['BIO_meth_new'],
-      ['ASN1_STRING_get0_data'],
-      ['HMAC_CTX_new'],
-      ['HMAC_CTX_free'],
+      ['SSL_CTX_set_cert_cb'],
 
-      # 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.
+      # Function included in LibreSSL, not in OpenSSL.  This is required for
+      # thread-safety.
       ['CRYPTO_lock'],
 
       # Function introduced in OpenSSL 1.1.1
@@ -1311,7 +1305,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', '0x10001000L',
+      cdata.set('OPENSSL_API_COMPAT', '0x10002000L',
                 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/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index e6d8f9fedc..84e2209e74 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -221,12 +221,9 @@ sub GenerateFiles
 		ENABLE_NLS => $self->{options}->{nls} ? 1 : undef,
 		ENABLE_THREAD_SAFETY => 1,
 		HAVE_APPEND_HISTORY => undef,
-		HAVE_ASN1_STRING_GET0_DATA => undef,
 		HAVE_ATOMICS => 1,
 		HAVE_ATOMIC_H => undef,
 		HAVE_BACKTRACE_SYMBOLS => undef,
-		HAVE_BIO_GET_DATA => undef,
-		HAVE_BIO_METH_NEW => undef,
 		HAVE_COMPUTED_GOTO => undef,
 		HAVE_COPYFILE => undef,
 		HAVE_COPYFILE_H => undef,
@@ -266,8 +263,6 @@ sub GenerateFiles
 		HAVE_GSSAPI_GSSAPI_EXT_H => undef,
 		HAVE_GSSAPI_GSSAPI_H => undef,
 		HAVE_GSSAPI_H => undef,
-		HAVE_HMAC_CTX_FREE => undef,
-		HAVE_HMAC_CTX_NEW => undef,
 		HAVE_HISTORY_H => undef,
 		HAVE_HISTORY_TRUNCATE_FILE => undef,
 		HAVE_IFADDRS_H => undef,
@@ -488,6 +483,7 @@ sub GenerateFiles
 	{
 		$define{USE_OPENSSL} = 1;
 		$define{HAVE_SSL_CTX_SET_CERT_CB} = 1;
+		$define{HAVE_OPENSSL_INIT_SSL} = 1;
 
 		my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
 
@@ -497,18 +493,6 @@ sub GenerateFiles
 		{
 			$define{HAVE_X509_GET_SIGNATURE_INFO} = 1;
 		}
-
-		# Symbols needed with OpenSSL 1.1.0 and above.
-		if (   ($digit1 >= '3' && $digit2 >= '0' && $digit3 >= '0')
-			|| ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0'))
-		{
-			$define{HAVE_ASN1_STRING_GET0_DATA} = 1;
-			$define{HAVE_BIO_GET_DATA} = 1;
-			$define{HAVE_BIO_METH_NEW} = 1;
-			$define{HAVE_HMAC_CTX_FREE} = 1;
-			$define{HAVE_HMAC_CTX_NEW} = 1;
-			$define{HAVE_OPENSSL_INIT_SSL} = 1;
-		}
 	}
 
 	$self->GenerateConfigHeader('src/include/pg_config.h', \%define, 1);
-- 
2.40.1

