On Wed, Jan 15, 2020 at 02:58:09PM +0900, Michael Paquier wrote: > On Tue, Jan 14, 2020 at 11:01:00PM +0100, Daniel Gustafsson wrote: >> Files renamed to match existing naming convention, the rest of the patch left >> unchanged. > > [previous review]
One thing I remembered after sleeping on it is that we can split the patch into two parts: the refactoring pieces and the addition of the options for libpq. The previous review mostly impacts the libpq part, and the split is straight-forward, so attached is a patch for only the refactoring pieces with some fixes and tweaks. I have tested it with and without OpenSSL, using 1.0.2 and 1.1.0 on Linux and Windows (MSVC). Those tests have allowed me to find an error in the previous patch that I missed: the new files openssl.h and protocol_openssl.c still declared SSL_CTX_set_min/max_proto_version as static functions, so compilation was broken when trying to use OpenSSL <= 1.0.2. If that looks fine, I would like to get that part committed first. Daniel, any thoughts? -- Michael
diff --git a/src/include/common/openssl.h b/src/include/common/openssl.h new file mode 100644 index 0000000000..47fa129994 --- /dev/null +++ b/src/include/common/openssl.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * openssl.h + * OpenSSL supporting functionality shared between frontend and backend + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/common/openssl.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMMON_OPENSSL_H +#define COMMON_OPENSSL_H + +#ifdef USE_OPENSSL +#include <openssl/ssl.h> + +/* src/common/protocol_openssl.c */ +#ifndef SSL_CTX_set_min_proto_version +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 + +#endif + +#endif /* COMMON_OPENSSL_H */ diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 62f1fcab2b..0cc59f1be1 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -36,6 +36,7 @@ #include <openssl/ec.h> #endif +#include "common/openssl.h" #include "libpq/libpq.h" #include "miscadmin.h" #include "pgstat.h" @@ -69,11 +70,6 @@ static bool ssl_is_server_start; static int ssl_protocol_version_to_openssl(int v, const char *guc_name, int loglevel); -#ifndef SSL_CTX_set_min_proto_version -static int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version); -static int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); -#endif - /* ------------------------------------------------------------ */ /* Public interface */ @@ -1314,96 +1310,3 @@ ssl_protocol_version_to_openssl(int v, const char *guc_name, int loglevel) GetConfigOption(guc_name, false, false)))); return -1; } - -/* - * Replacements for APIs present in newer versions of OpenSSL - */ -#ifndef SSL_CTX_set_min_proto_version - -/* - * OpenSSL versions that support TLS 1.3 shouldn't get here because they - * already have these functions. So we don't have to keep updating the below - * code for every new TLS version, and eventually it can go away. But let's - * just check this to make sure ... - */ -#ifdef TLS1_3_VERSION -#error OpenSSL version mismatch -#endif - -static int -SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) -{ - int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; - - if (version > TLS1_VERSION) - ssl_options |= SSL_OP_NO_TLSv1; - /* - * Some OpenSSL versions define TLS*_VERSION macros but not the - * corresponding SSL_OP_NO_* macro, so in those cases we have to return - * unsuccessfully here. - */ -#ifdef TLS1_1_VERSION - if (version > TLS1_1_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_1 - ssl_options |= SSL_OP_NO_TLSv1_1; -#else - return 0; -#endif - } -#endif -#ifdef TLS1_2_VERSION - if (version > TLS1_2_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_2 - ssl_options |= SSL_OP_NO_TLSv1_2; -#else - return 0; -#endif - } -#endif - - SSL_CTX_set_options(ctx, ssl_options); - - return 1; /* success */ -} - -static int -SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) -{ - int ssl_options = 0; - - AssertArg(version != 0); - - /* - * Some OpenSSL versions define TLS*_VERSION macros but not the - * corresponding SSL_OP_NO_* macro, so in those cases we have to return - * unsuccessfully here. - */ -#ifdef TLS1_1_VERSION - if (version < TLS1_1_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_1 - ssl_options |= SSL_OP_NO_TLSv1_1; -#else - return 0; -#endif - } -#endif -#ifdef TLS1_2_VERSION - if (version < TLS1_2_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_2 - ssl_options |= SSL_OP_NO_TLSv1_2; -#else - return 0; -#endif - } -#endif - - SSL_CTX_set_options(ctx, ssl_options); - - return 1; /* success */ -} - -#endif /* !SSL_CTX_set_min_proto_version */ diff --git a/src/common/Makefile b/src/common/Makefile index ffb0f6edff..55161f05a2 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -73,7 +73,9 @@ OBJS_COMMON = \ wait_error.o ifeq ($(with_openssl),yes) -OBJS_COMMON += sha2_openssl.o +OBJS_COMMON += \ + protocol_openssl.o \ + sha2_openssl.o else OBJS_COMMON += sha2.o endif diff --git a/src/common/protocol_openssl.c b/src/common/protocol_openssl.c new file mode 100644 index 0000000000..253b611ea2 --- /dev/null +++ b/src/common/protocol_openssl.c @@ -0,0 +1,117 @@ +/*------------------------------------------------------------------------- + * + * protocol_openssl.c + * OpenSSL 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/protocol_openssl.c + * + *------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include <openssl/ssl.h> + +/* + * Replacements for APIs introduced in OpenSSL 1.1.0. + */ +#ifndef SSL_CTX_set_min_proto_version + +/* + * OpenSSL versions that support TLS 1.3 shouldn't get here because they + * already have these functions. So we don't have to keep updating the below + * code for every new TLS version, and eventually it can go away. But let's + * just check this to make sure ... + */ +#ifdef TLS1_3_VERSION +#error OpenSSL version mismatch +#endif + +int +SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) +{ + int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + + if (version > TLS1_VERSION) + ssl_options |= SSL_OP_NO_TLSv1; + + /* + * Some OpenSSL versions define TLS*_VERSION macros but not the + * corresponding SSL_OP_NO_* macro, so in those cases we have to return + * unsuccessfully here. + */ +#ifdef TLS1_1_VERSION + if (version > TLS1_1_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_1 + ssl_options |= SSL_OP_NO_TLSv1_1; +#else + return 0; +#endif + } +#endif +#ifdef TLS1_2_VERSION + if (version > TLS1_2_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_2 + ssl_options |= SSL_OP_NO_TLSv1_2; +#else + return 0; +#endif + } +#endif + + SSL_CTX_set_options(ctx, ssl_options); + + return 1; /* success */ +} + +int +SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) +{ + int ssl_options = 0; + + AssertArg(version != 0); + + /* + * Some OpenSSL versions define TLS*_VERSION macros but not the + * corresponding SSL_OP_NO_* macro, so in those cases we have to return + * unsuccessfully here. + */ +#ifdef TLS1_1_VERSION + if (version < TLS1_1_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_1 + ssl_options |= SSL_OP_NO_TLSv1_1; +#else + return 0; +#endif + } +#endif +#ifdef TLS1_2_VERSION + if (version < TLS1_2_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_2 + ssl_options |= SSL_OP_NO_TLSv1_2; +#else + return 0; +#endif + } +#endif + + SSL_CTX_set_options(ctx, ssl_options); + + return 1; /* success */ +} + +#endif /* !SSL_CTX_set_min_proto_version */ diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index f6ab0d528b..e4f27a692a 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -129,6 +129,7 @@ sub mkvcbuild if ($solution->{options}->{openssl}) { push(@pgcommonallfiles, 'sha2_openssl.c'); + push(@pgcommonallfiles, 'protocol_openssl.c'); } else {
signature.asc
Description: PGP signature