Move OpenSSL routines for min/max protocol setting to src/common/

Two routines have been added in OpenSSL 1.1.0 to set the protocol bounds
allowed within a given SSL context:
- SSL_CTX_set_min_proto_version
- SSL_CTX_set_max_proto_version

As Postgres supports OpenSSL down to 1.0.1 (as of HEAD), equivalent
replacements exist in the tree, which are only available for the
backend.  A follow-up patch is planned to add control of the SSL
protocol bounds for libpq, so move those routines to src/common/ so as
libpq can use them.

Author: Daniel Gustafsson
Discussion: https://postgr.es/m/4F246AE3-A7AE-471E-BD3D-C799D3748E03@yesql.se
This commit is contained in:
Michael Paquier 2020-01-17 10:06:17 +09:00
parent 5afaa2e426
commit f7cd5896a6
5 changed files with 150 additions and 99 deletions

View File

@ -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 */

View File

@ -75,7 +75,9 @@ OBJS_COMMON = \
wchar.o
ifeq ($(with_openssl),yes)
OBJS_COMMON += sha2_openssl.o
OBJS_COMMON += \
protocol_openssl.o \
sha2_openssl.o
else
OBJS_COMMON += sha2.o
endif

View File

@ -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 "common/openssl.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 */

View File

@ -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 */

View File

@ -130,6 +130,7 @@ sub mkvcbuild
if ($solution->{options}->{openssl})
{
push(@pgcommonallfiles, 'sha2_openssl.c');
push(@pgcommonallfiles, 'protocol_openssl.c');
}
else
{