0001-Compatibility-with-OpenSSL-3.0.0.patch
application/octet-stream
Filename: 0001-Compatibility-with-OpenSSL-3.0.0.patch
Type: application/octet-stream
Part: 1
Message:
OpenSSL 3.0.0 compatibility
Patch
Format: format-patch
Series: patch 0001
Subject: Compatibility with OpenSSL 3.0.0
| File | + | − |
|---|---|---|
| src/backend/libpq/be-secure-openssl.c | 58 | 23 |
| src/common/cert_openssl.c | 42 | 0 |
| src/common/Makefile | 2 | 1 |
| src/include/common/openssl.h | 6 | 0 |
| src/interfaces/libpq/fe-secure-openssl.c | 2 | 2 |
From 28ed04b053247ecbcb1f14045cd16f98864f2488 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 26 May 2020 20:21:30 +0200
Subject: [PATCH 1/2] Compatibility with OpenSSL 3.0.0
OpenSSL 3.0.0 deprecates a set of functions used in libpq:
SSL_CTX_load_verify_locations and X509_STORE_load_locations were
replaced with individual calls for file and directory, so replace
with the appropriate call since we only have configuration options
for files.
Usage of DH_check has been discouraged for a long time, and it was
finally deprecated with no direct replacement. Instead implement a
version using the EVP api which is the recommended alternative.
u
---
src/backend/libpq/be-secure-openssl.c | 81 +++++++++++++++++-------
src/common/Makefile | 3 +-
src/common/cert_openssl.c | 42 ++++++++++++
src/include/common/openssl.h | 6 ++
src/interfaces/libpq/fe-secure-openssl.c | 4 +-
5 files changed, 110 insertions(+), 26 deletions(-)
create mode 100644 src/common/cert_openssl.c
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 78a865d23b..32bdca30a1 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -266,7 +266,7 @@ be_tls_init(bool isServerStart)
*/
if (ssl_ca_file[0])
{
- if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
+ if (SSL_CTX_load_verify_file(context, ssl_ca_file) != 1 ||
(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
{
ereport(isServerStart ? FATAL : LOG,
@@ -289,7 +289,7 @@ be_tls_init(bool isServerStart)
if (cvstore)
{
/* Set the flags to check against the complete CRL chain */
- if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
+ if (X509_STORE_load_file(cvstore, ssl_crl_file) == 1)
{
X509_STORE_set_flags(cvstore,
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
@@ -817,7 +817,6 @@ load_dh_file(char *filename, bool isServerStart)
{
FILE *fp;
DH *dh = NULL;
- int codes;
/* attempt to open file. It's not an error if it doesn't exist. */
if ((fp = AllocateFile(filename, "r")) == NULL)
@@ -841,30 +840,66 @@ load_dh_file(char *filename, bool isServerStart)
return NULL;
}
- /* make sure the DH parameters are usable */
- if (DH_check(dh, &codes) == 0)
+#if OPENSSL_VERSION_MAJOR < 3
{
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: %s",
- SSLerrmessage(ERR_get_error()))));
- return NULL;
- }
- if (codes & DH_CHECK_P_NOT_PRIME)
- {
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: p is not prime")));
- return NULL;
+ int codes;
+
+ /* make sure the DH parameters are usable */
+ if (DH_check(dh, &codes) == 0)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: %s",
+ SSLerrmessage(ERR_get_error()))));
+ return NULL;
+ }
+ if (codes & DH_CHECK_P_NOT_PRIME)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: p is not prime")));
+ return NULL;
+ }
+ if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
+ (codes & DH_CHECK_P_NOT_SAFE_PRIME))
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: neither suitable generator or safe prime")));
+ return NULL;
+ }
}
- if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
- (codes & DH_CHECK_P_NOT_SAFE_PRIME))
+#else
{
- ereport(isServerStart ? FATAL : LOG,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("invalid DH parameters: neither suitable generator or safe prime")));
- return NULL;
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pkey_ctx = NULL;
+ unsigned long err = 0;
+
+ pkey = EVP_PKEY_new();
+
+ if (!EVP_PKEY_set1_DH(pkey, dh))
+ err = ERR_get_error();
+ else
+ {
+ pkey_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+
+ if (!EVP_PKEY_param_check(pkey_ctx))
+ err = ERR_get_error();
+ }
+
+ EVP_PKEY_CTX_free(pkey_ctx);
+ EVP_PKEY_free(pkey);
+
+ if (err)
+ {
+ ereport(isServerStart ? FATAL : LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("invalid DH parameters: %s",
+ SSLerrmessage(err))));
+ return NULL;
+ }
}
+#endif
return dh;
}
diff --git a/src/common/Makefile b/src/common/Makefile
index d0be882cca..482561f63e 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -80,7 +80,8 @@ OBJS_COMMON = \
ifeq ($(with_openssl),yes)
OBJS_COMMON += \
protocol_openssl.o \
- sha2_openssl.o
+ sha2_openssl.o \
+ cert_openssl.o
else
OBJS_COMMON += sha2.o
endif
diff --git a/src/common/cert_openssl.c b/src/common/cert_openssl.c
new file mode 100644
index 0000000000..2149e7eb36
--- /dev/null
+++ b/src/common/cert_openssl.c
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------
+ *
+ * protocol_openssl.c
+ * OpenSSL certificate functionality shared between frontend and backend
+ *
+ * This should only be used if code is compiled with OpenSSL support.
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/common/cert_openssl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/openssl.h"
+
+/*
+ * SSL_CTX_load_verify_locations and X509_STORE_load_locations were deprecated
+ * in OpenSSL 3.0.0 and replaced by their new _file counterparts. Provide
+ * implementations of the replacement for OpenSSL versions 1.0.1 through 1.1.1
+ * where they are missing.
+ */
+#if OPENSSL_VERSION_MAJOR < 3
+int
+SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile)
+{
+ return SSL_CTX_load_verify_locations(ctx, CAfile, NULL);
+}
+int
+X509_STORE_load_file(X509_STORE *ctx, const char *file)
+{
+ return X509_STORE_load_locations(ctx, file, NULL);
+}
+#endif
diff --git a/src/include/common/openssl.h b/src/include/common/openssl.h
index 47fa129994..d5dc2910bf 100644
--- a/src/include/common/openssl.h
+++ b/src/include/common/openssl.h
@@ -23,6 +23,12 @@ extern int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
extern int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
#endif
+/* src/common/cert_openssl.c */
+#if OPENSSL_VERSION_MAJOR < 3
+extern int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile);
+int X509_STORE_load_file(X509_STORE *ctx, const char *file);
+#endif
+
#endif
#endif /* COMMON_OPENSSL_H */
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 2d813ef5f9..a1ad181976 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -922,7 +922,7 @@ initialize_SSL(PGconn *conn)
{
X509_STORE *cvstore;
- if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
+ if (SSL_CTX_load_verify_file(SSL_context, fnbuf) != 1)
{
char *err = SSLerrmessage(ERR_get_error());
@@ -945,7 +945,7 @@ initialize_SSL(PGconn *conn)
/* Set the flags to check against the complete CRL chain */
if (fnbuf[0] != '\0' &&
- X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1)
+ X509_STORE_load_file(cvstore, fnbuf) == 1)
{
X509_STORE_set_flags(cvstore,
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
--
2.21.1 (Apple Git-122.3)