From da0c193b1e1476fc994864aa23173964932be0ef Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 3 Jul 2024 17:50:25 +0200 Subject: [PATCH v3 2/2] Support TLSv1.3 cipher suites --- doc/src/sgml/config.sgml | 37 +++++++++++++++---- src/backend/libpq/be-secure-openssl.c | 25 +++++++++++-- src/backend/libpq/be-secure.c | 1 + src/backend/utils/misc/guc_tables.c | 15 +++++++- src/backend/utils/misc/postgresql.conf.sample | 3 +- src/include/libpq/libpq.h | 1 + src/test/ssl/t/SSL/Server.pm | 3 +- 7 files changed, 70 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 67a5e3ea3d..0ca01580b8 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1340,6 +1340,29 @@ include_dir 'conf.d' + + ssl_cipher_suites (string) + + ssl_cipher_suites configuration parameter + + + + + Specifies a list of SSL cipher suites that are + allowed by connections using TLS version 1.3. Multiple cipher suites + can be specified by using a colon separated list. If left blank, the + default set of cipher suites in OpenSSL + will be used. + + + + This parameter can only be set in the + postgresql.conf file or on the server command + line. + + + + ssl_ciphers (string) @@ -1348,15 +1371,13 @@ include_dir 'conf.d' - Specifies a list of SSL cipher suites that are - allowed to be used by SSL connections. See the - ciphers + Specifies a list of SSL ciphers that are allowed by + connections using TLS version 1.2 and lower, see + for TLS version 1.3 connections. See + the ciphers manual page in the OpenSSL package for the - syntax of this setting and a list of supported values. Only - connections using TLS version 1.2 and lower are affected. There is - currently no setting that controls the cipher choices used by TLS - version 1.3 connections. The default value is - HIGH:MEDIUM:+3DES:!aNULL. The default is usually a + syntax of this setting and a list of supported values. The default value + is HIGH:MEDIUM:+3DES:!aNULL. The default is usually a reasonable choice unless you have specific security requirements. diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 55faf5df38..0dfd5fa9b8 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -100,6 +100,7 @@ be_tls_init(bool isServerStart) SSL_CTX *context; int ssl_ver_min = -1; int ssl_ver_max = -1; + int status; /* This stuff need be done only once. */ if (!SSL_initialized) @@ -288,12 +289,30 @@ be_tls_init(bool isServerStart) if (!initialize_ecdh(context, isServerStart)) goto error; - /* set up the allowed cipher list */ - if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1) + /* set up the allowed cipher list for TLSv1.2 and below */ + if (SSL_CTX_set_cipher_list(context, SSLCipherLists) != 1) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("could not set the cipher list (no valid ciphers available)"))); + errmsg("could not set the TLSv1.2 cipher list (no valid ciphers available)"))); + goto error; + } + + /* + * Set up the allowed cipher suites for TLSv1.3. If the GUC is an empty + * string we set the allowed suites to the OpenSSL default value. + */ + if (SSLCipherSuites[0]) + status = SSL_CTX_set_ciphersuites(context, SSLCipherSuites); + else + status = SSL_CTX_set_ciphersuites(context, TLS_DEFAULT_CIPHERSUITES); + + /* set up the allowed cipher suites */ + if (status != 1) + { + ereport(isServerStart ? FATAL : LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not set the TLSv1.3 cipher suites (no valid ciphers available)"))); goto error; } diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index 1663f36b6b..aba0498d39 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -48,6 +48,7 @@ bool ssl_loaded_verify_locations = false; /* GUC variable controlling SSL cipher list */ char *SSLCipherSuites = NULL; +char *SSLCipherLists = NULL; /* GUC variable for default ECHD curve. */ char *SSLECDHCurve; diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index adf94381fd..4b702fd9f7 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -4576,12 +4576,23 @@ struct config_string ConfigureNamesString[] = }, { - {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the list of allowed SSL ciphers."), + {"ssl_cipher_suites", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the list of allowed TLSv1.3 cipher suites (leave blank for default)."), NULL, GUC_SUPERUSER_ONLY }, &SSLCipherSuites, + "", + NULL, NULL, NULL + }, + + { + {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the list of allowed TLSv1.2 (and lower) ciphers."), + NULL, + GUC_SUPERUSER_ONLY + }, + &SSLCipherLists, #ifdef USE_OPENSSL "HIGH:MEDIUM:+3DES:!aNULL", #else diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 9ec9f97e92..e8e17c8fc2 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -110,7 +110,8 @@ #ssl_crl_file = '' #ssl_crl_dir = '' #ssl_key_file = 'server.key' -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed TLSv1.2 ciphers +#ssl_cipher_suites = '' # allowed TLSv1.3 cipher suites, blank for default #ssl_prefer_server_ciphers = on #ssl_ecdh_curve = 'prime256v1' #ssl_min_protocol_version = 'TLSv1.2' diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 142c98462e..5e0d796972 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -118,6 +118,7 @@ extern ssize_t secure_open_gssapi(Port *port); /* GUCs */ extern PGDLLIMPORT char *SSLCipherSuites; +extern PGDLLIMPORT char *SSLCipherLists; extern PGDLLIMPORT char *SSLECDHCurve; extern PGDLLIMPORT bool SSLPreferServerCiphers; extern PGDLLIMPORT int ssl_min_protocol_version; diff --git a/src/test/ssl/t/SSL/Server.pm b/src/test/ssl/t/SSL/Server.pm index abc695c6a3..3dc2a6ab23 100644 --- a/src/test/ssl/t/SSL/Server.pm +++ b/src/test/ssl/t/SSL/Server.pm @@ -198,8 +198,9 @@ sub configure_test_server_for_ssl print $conf "listen_addresses='$serverhost'\n"; print $conf "log_statement=all\n"; - # use lists of ECDH curves for syntax testing + # use lists of ECDH curves and cipher suites for syntax testing print $conf "ssl_ecdh_curve=prime256v1:secp521r1\n"; + print $conf "ssl_cipher_suites=TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256\n"; # enable SSL and set up server key print $conf "include 'sslconfig.conf'\n"; -- 2.39.3 (Apple Git-146)