From 5c21ebe072d1c877d7fe8f676879b9a8af76eb1c Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Tue, 18 Jun 2024 14:50:39 +0200
Subject: [PATCH v1] Disable all TLS session tickets

OpenSSL supports two types of session tickets for TLSv1.3, stateless
and stateful. The option we've used only turns off stateless tickets
leaving stateful tickets active. Use the new API introduced in 1.1.1
to disable all types of tickets.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/20240617173803.6alnafnxpiqvlh3g@awork3.anarazel.de
---
 configure                             |  9 +++++----
 configure.ac                          |  2 +-
 meson.build                           |  1 +
 src/backend/libpq/be-secure-openssl.c | 14 +++++++++++++-
 src/include/pg_config.h.in            |  3 +++
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 7b03db56a6..519a2e5ce6 100755
--- a/configure
+++ b/configure
@@ -12591,12 +12591,13 @@ fi
 done
 
   # Function introduced in OpenSSL 1.1.1.
-  for ac_func in X509_get_signature_info
+  for ac_func in X509_get_signature_info SSL_CTX_set_num_tickets
 do :
-  ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info"
-if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_X509_GET_SIGNATURE_INFO 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
 fi
diff --git a/configure.ac b/configure.ac
index 63e7be3847..6e28c2d04c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1358,7 +1358,7 @@ if test "$with_ssl" = openssl ; then
   # function was removed.
   AC_CHECK_FUNCS([CRYPTO_lock])
   # Function introduced in OpenSSL 1.1.1.
-  AC_CHECK_FUNCS([X509_get_signature_info])
+  AC_CHECK_FUNCS([X509_get_signature_info SSL_CTX_set_num_tickets])
   AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)])
 elif test "$with_ssl" != no ; then
   AC_MSG_ERROR([--with-ssl must specify openssl])
diff --git a/meson.build b/meson.build
index 2767abd19e..e21f88b529 100644
--- a/meson.build
+++ b/meson.build
@@ -1293,6 +1293,7 @@ if sslopt in ['auto', 'openssl']
 
       # Function introduced in OpenSSL 1.1.1
       ['X509_get_signature_info'],
+      ['SSL_CTX_set_num_tickets'],
     ]
 
     are_openssl_funcs_complete = true
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 39b1a66236..d257b93104 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -258,8 +258,20 @@ be_tls_init(bool isServerStart)
 		}
 	}
 
-	/* disallow SSL session tickets */
+	/*
+	 * Disallow SSL session tickets. OpenSSL use both stateful and stateless
+	 * tickets for TLSv1.3, and stateless ticket for TLSv1.2. SSL_OP_NO_TICKET
+	 * is available since 1.0.0 but only turns off stateless tickets. In order
+	 * to turn off stateful tickets we also need SSL_CTX_set_num_tickets, which
+	 * is available since OpenSSL 1.1.1. LibreSSL 3.5.4 (from OpenBSD 7.1)
+	 * introduced this API for compatibility, but doesn't support session
+	 * tickets at all so it's a no-op there.
+	 */
+#ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
+	SSL_CTX_set_num_tickets(context, 0);
+#else
 	SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
+#endif
 
 	/* disallow SSL session caching, too */
 	SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f8d3e3b6b8..e2834912f8 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -510,6 +510,9 @@
 /* Define to 1 if you have the `X509_get_signature_info' function. */
 #undef HAVE_X509_GET_SIGNATURE_INFO
 
+/* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */
+#undef HAVE_SSL_CTX_SET_NUM_TICKETS
+
 /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */
 #undef HAVE_X86_64_POPCNTQ
 
-- 
2.39.3 (Apple Git-146)

