diff options
author | Daniel Gustafsson | 2024-10-24 13:20:32 +0000 |
---|---|---|
committer | Daniel Gustafsson | 2024-10-24 13:20:32 +0000 |
commit | 45188c2ea2391b7b24039e1632c726e2fc6b8008 (patch) | |
tree | e85052c98e0775dd4932789e0fe603909a36bccf | |
parent | 3d1ef3a15c3eb68dae44b94e89d04c422b26fc16 (diff) |
Support configuring TLSv1.3 cipher suites
The ssl_ciphers GUC can only set cipher suites for TLSv1.2, and lower,
connections. For TLSv1.3 connections a different OpenSSL API must be
used. This adds a new GUC, ssl_tls13_ciphers, which can be used to
configure a colon separated list of cipher suites to support when
performing a TLSv1.3 handshake.
Original patch by Erica Zhang with additional hacking by me.
Author: Erica Zhang <[email protected]>
Author: Daniel Gustafsson <[email protected]>
Reviewed-by: Jacob Champion <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Peter Eisentraut <[email protected]>
Reviewed-by: Jelte Fennema-Nio <[email protected]>
Discussion: https://postgr.es/m/[email protected]
-rw-r--r-- | doc/src/sgml/config.sgml | 36 | ||||
-rw-r--r-- | src/backend/libpq/be-secure-openssl.c | 22 | ||||
-rw-r--r-- | src/backend/libpq/be-secure.c | 1 | ||||
-rw-r--r-- | src/backend/utils/misc/guc_tables.c | 15 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 3 | ||||
-rw-r--r-- | src/include/libpq/libpq.h | 1 | ||||
-rw-r--r-- | src/test/ssl/t/SSL/Server.pm | 3 |
7 files changed, 66 insertions, 15 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index f8d862a6ce4..dc401087dc6 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1340,6 +1340,28 @@ include_dir 'conf.d' </listitem> </varlistentry> + <varlistentry id="guc-ssl-tls13-ciphers" xreflabel="ssl_tls13_ciphers"> + <term><varname>ssl_tls13_ciphers</varname> (<type>string</type>) + <indexterm> + <primary><varname>ssl_tls13_ciphers</varname> configuration parameter</primary> + </indexterm> + </term> + <listitem> + <para> + Specifies a list of cipher suites that are allowed by connections using + <acronym>TLS</acronym> 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 <productname>OpenSSL</productname> will be used. + </para> + + <para> + This parameter can only be set in the + <filename>postgresql.conf</filename> file or on the server command + line. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers"> <term><varname>ssl_ciphers</varname> (<type>string</type>) <indexterm> @@ -1348,15 +1370,13 @@ include_dir 'conf.d' </term> <listitem> <para> - Specifies a list of <acronym>SSL</acronym> cipher suites that are - allowed to be used by SSL connections. See the - <citerefentry><refentrytitle>ciphers</refentrytitle></citerefentry> + Specifies a list of <acronym>SSL</acronym> ciphers that are allowed by + connections using TLS version 1.2 and lower, see + <xref linkend="guc-ssl-tls13-ciphers"/> for TLS version 1.3 connections. See + the <citerefentry><refentrytitle>ciphers</refentrytitle></citerefentry> manual page in the <productname>OpenSSL</productname> 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 - <literal>HIGH:MEDIUM:+3DES:!aNULL</literal>. The default is usually a + syntax of this setting and a list of supported values. The default value + is <literal>HIGH:MEDIUM:+3DES:!aNULL</literal>. The default is usually a reasonable choice unless you have specific security requirements. </para> diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index c8cd81d8537..469be36e764 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -288,15 +288,31 @@ 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, SSLCipherList) != 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 leave the allowed suites to be the OpenSSL default value. + */ + if (SSLCipherSuites[0]) + { + /* set up the allowed cipher suites */ + if (SSL_CTX_set_ciphersuites(context, SSLCipherSuites) != 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; + } + } + /* Let server choose order */ if (SSLPreferServerCiphers) SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE); diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index ef20ea755b7..2139f81f241 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -49,6 +49,7 @@ bool ssl_loaded_verify_locations = false; /* GUC variable controlling SSL cipher list */ char *SSLCipherSuites = NULL; +char *SSLCipherList = 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 859e6658e77..8a67f01200c 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -4641,12 +4641,23 @@ struct config_string ConfigureNamesString[] = }, { - {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the list of allowed SSL ciphers."), + {"ssl_tls13_ciphers", 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 + }, + &SSLCipherList, #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 204eab5f1a7..39a3ac23127 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_tls13_ciphers = '' # allowed TLSv1.3 cipher suites, blank for default #ssl_prefer_server_ciphers = on #ssl_groups = 'prime256v1' #ssl_min_protocol_version = 'TLSv1.2' diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 142c98462ed..d825b4c7b6c 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 *SSLCipherList; 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 c1b25a4ebf6..b8d268e616c 100644 --- a/src/test/ssl/t/SSL/Server.pm +++ b/src/test/ssl/t/SSL/Server.pm @@ -300,8 +300,9 @@ sub switch_server_cert ok(unlink($node->data_dir . '/sslconfig.conf')); $node->append_conf('sslconfig.conf', "ssl=on"); $node->append_conf('sslconfig.conf', $backend->set_server_cert(\%params)); - # use lists of ECDH curves for syntax testing + # use lists of ECDH curves and cipher suites for syntax testing $node->append_conf('sslconfig.conf', 'ssl_groups=prime256v1:secp521r1'); + $node->append_conf('sslconfig.conf', 'ssl_tls13_ciphers=TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256'); $node->append_conf('sslconfig.conf', "ssl_passphrase_command='" . $params{passphrase_cmd} . "'") |