From 7c03c8e5ce2a895850e75857eb4aa44dcc5f787c Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 21 Sep 2020 15:21:18 +0200
Subject: [PATCH] Fix OpenSSL 3 support in pgcrypto v3

---
 contrib/pgcrypto/openssl.c | 19 ++++++++++++++++++-
 doc/src/sgml/pgcrypto.sgml |  6 ++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 90951a8ae7..7ae843bd7d 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -31,6 +31,9 @@
 
 #include "postgres.h"
 
+#ifndef HAVE_OPENSSL_INIT_SSL
+#include <openssl/conf.h>
+#endif
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
@@ -173,8 +176,18 @@ px_find_digest(const char *name, PX_MD **res)
 
 	if (!px_openssl_initialized)
 	{
-		px_openssl_initialized = 1;
+		/*
+		 * OpenSSL_add_all_algorithms is deprecated in OpenSSL 1.1.0 and no
+		 * longer required in 1.1.0 and later versions, as initialization is
+		 * performed automatically. We don't have macros for OpenSSL versions
+		 * since they collide with LibreSSL, OPENSSL_init_ssl was introduced
+		 * in 1.1.0 so we can use the corresponding HAVE_ macro.
+		 */
+#ifndef HAVE_OPENSSL_INIT_SSL
+		OPENSSL_config(NULL);
 		OpenSSL_add_all_algorithms();
+#endif
+		px_openssl_initialized = 1;
 	}
 
 	if (!digest_resowner_callback_registered)
@@ -367,6 +380,8 @@ gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
 	{
 		if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
 			return PXE_CIPHER_INIT;
+		if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+			return PXE_CIPHER_INIT;
 		if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
 			return PXE_CIPHER_INIT;
 		if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
@@ -391,6 +406,8 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
 	{
 		if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
 			return PXE_CIPHER_INIT;
+		if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
+			return PXE_CIPHER_INIT;
 		if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
 			return PXE_CIPHER_INIT;
 		if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index 8748c64e2d..3c1e16e0f9 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1233,6 +1233,12 @@ gen_random_uuid() returns uuid
     </tgroup>
    </table>
 
+   <para>
+    When compiled against <productname>OpenSSL</productname> 3.0.0, the legacy
+    provider must be activated in the <filename>openssl.cnf</filename> file
+    in order to use older ciphers like MD5.
+   </para>
+
    <para>
     Notes:
    </para>
-- 
2.21.1 (Apple Git-122.3)

