fix CVE-2024-2511
(cherry picked from commit b29f7652a28a277f2547bb81d86c508cb627a4b1)
This commit is contained in:
parent
fe3837c2cf
commit
128505e92d
132
backport-Add-a-test-for-session-cache-handling.patch
Normal file
132
backport-Add-a-test-for-session-cache-handling.patch
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
From 2af85c2b8fd6799924a56eb5907cc6110b450467 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matt Caswell <matt@openssl.org>
|
||||||
|
Date: Mon, 4 Mar 2024 13:45:23 +0000
|
||||||
|
Subject: [PATCH] Add a test for session cache handling
|
||||||
|
|
||||||
|
Repeatedly create sessions to be added to the cache and ensure we never
|
||||||
|
exceed the expected size.
|
||||||
|
|
||||||
|
Related to CVE-2024-2511
|
||||||
|
|
||||||
|
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||||
|
|
||||||
|
(cherry picked from commit 5f5b9e1ca1fad0215f623b8bd4955a2e8101f306)
|
||||||
|
---
|
||||||
|
test/sslapitest.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 92 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||||
|
index 231f498199..56229e51b9 100644
|
||||||
|
--- a/test/sslapitest.c
|
||||||
|
+++ b/test/sslapitest.c
|
||||||
|
@@ -10436,6 +10436,97 @@ end:
|
||||||
|
return testresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Test multiple resumptions and cache size handling
|
||||||
|
+ * Test 0: TLSv1.3 (max_early_data set)
|
||||||
|
+ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
|
||||||
|
+ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
|
||||||
|
+ * Test 3: TLSv1.2
|
||||||
|
+ */
|
||||||
|
+static int test_multi_resume(int idx)
|
||||||
|
+{
|
||||||
|
+ SSL_CTX *sctx = NULL, *cctx = NULL;
|
||||||
|
+ SSL *serverssl = NULL, *clientssl = NULL;
|
||||||
|
+ SSL_SESSION *sess = NULL;
|
||||||
|
+ int max_version = TLS1_3_VERSION;
|
||||||
|
+ int i, testresult = 0;
|
||||||
|
+
|
||||||
|
+ if (idx == 3)
|
||||||
|
+ max_version = TLS1_2_VERSION;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||||
|
+ TLS_client_method(), TLS1_VERSION,
|
||||||
|
+ max_version, &sctx, &cctx, cert,
|
||||||
|
+ privkey)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for
|
||||||
|
+ * replay protection), or if SSL_OP_NO_TICKET is in use
|
||||||
|
+ */
|
||||||
|
+ if (idx == 0 || idx == 2) {
|
||||||
|
+ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ if (idx == 1 || idx == 2)
|
||||||
|
+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
|
||||||
|
+
|
||||||
|
+ SSL_CTX_sess_set_cache_size(sctx, 5);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < 30; i++) {
|
||||||
|
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||||
|
+ NULL, NULL))
|
||||||
|
+ || !TEST_true(SSL_set_session(clientssl, sess)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Recreate a bug where dynamically changing the max_early_data value
|
||||||
|
+ * can cause sessions in the session cache which cannot be deleted.
|
||||||
|
+ */
|
||||||
|
+ if ((idx == 0 || idx == 2) && (i % 3) == 2)
|
||||||
|
+ SSL_set_max_early_data(serverssl, 0);
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (sess == NULL || (idx == 0 && (i % 3) == 2)) {
|
||||||
|
+ if (!TEST_false(SSL_session_reused(clientssl)))
|
||||||
|
+ goto end;
|
||||||
|
+ } else {
|
||||||
|
+ if (!TEST_true(SSL_session_reused(clientssl)))
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ SSL_SESSION_free(sess);
|
||||||
|
+
|
||||||
|
+ /* Do a full handshake, followed by two resumptions */
|
||||||
|
+ if ((i % 3) == 2) {
|
||||||
|
+ sess = NULL;
|
||||||
|
+ } else {
|
||||||
|
+ if (!TEST_ptr((sess = SSL_get1_session(clientssl))))
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SSL_shutdown(clientssl);
|
||||||
|
+ SSL_shutdown(serverssl);
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ serverssl = clientssl = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We should never exceed the session cache size limit */
|
||||||
|
+ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ testresult = 1;
|
||||||
|
+ end:
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ SSL_CTX_free(sctx);
|
||||||
|
+ SSL_CTX_free(cctx);
|
||||||
|
+ SSL_SESSION_free(sess);
|
||||||
|
+ return testresult;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
|
||||||
|
|
||||||
|
int setup_tests(void)
|
||||||
|
@@ -10708,6 +10799,7 @@ int setup_tests(void)
|
||||||
|
ADD_ALL_TESTS(test_pipelining, 6);
|
||||||
|
#endif
|
||||||
|
ADD_ALL_TESTS(test_handshake_retry, 16);
|
||||||
|
+ ADD_ALL_TESTS(test_multi_resume, 4);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
171
backport-Add-a-test-for-session-cache-overflow.patch
Normal file
171
backport-Add-a-test-for-session-cache-overflow.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
From ea821878c0cc04d292c1f8d1ff3c5e112da91f08 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matt Caswell <matt@openssl.org>
|
||||||
|
Date: Fri, 15 Jul 2022 13:26:33 +0100
|
||||||
|
Subject: [PATCH] Add a test for session cache overflow
|
||||||
|
|
||||||
|
Test sessions behave as we expect even in the case that an overflow
|
||||||
|
occurs when adding a new session into the session cache.
|
||||||
|
|
||||||
|
Related to CVE-2024-2511
|
||||||
|
|
||||||
|
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||||
|
|
||||||
|
(cherry picked from commit ddead0935d77ba9b771d632ace61b145d7153f18)
|
||||||
|
---
|
||||||
|
test/sslapitest.c | 124 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 123 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||||
|
index 24fb95e4b6..cb098a46f5 100644
|
||||||
|
--- a/test/sslapitest.c
|
||||||
|
+++ b/test/sslapitest.c
|
||||||
|
@@ -2402,7 +2402,6 @@ static int test_session_wo_ca_names(void)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
#ifndef OSSL_NO_USABLE_TLS1_3
|
||||||
|
static SSL_SESSION *sesscache[6];
|
||||||
|
static int do_cache;
|
||||||
|
@@ -8954,6 +8953,126 @@ static int test_session_timeout(int test)
|
||||||
|
return testresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Test that a session cache overflow works as expected
|
||||||
|
+ * Test 0: TLSv1.3, timeout on new session later than old session
|
||||||
|
+ * Test 1: TLSv1.2, timeout on new session later than old session
|
||||||
|
+ * Test 2: TLSv1.3, timeout on new session earlier than old session
|
||||||
|
+ * Test 3: TLSv1.2, timeout on new session earlier than old session
|
||||||
|
+ */
|
||||||
|
+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
|
||||||
|
+static int test_session_cache_overflow(int idx)
|
||||||
|
+{
|
||||||
|
+ SSL_CTX *sctx = NULL, *cctx = NULL;
|
||||||
|
+ SSL *serverssl = NULL, *clientssl = NULL;
|
||||||
|
+ int testresult = 0;
|
||||||
|
+ SSL_SESSION *sess = NULL;
|
||||||
|
+
|
||||||
|
+#ifdef OSSL_NO_USABLE_TLS1_3
|
||||||
|
+ /* If no TLSv1.3 available then do nothing in this case */
|
||||||
|
+ if (idx % 2 == 0)
|
||||||
|
+ return TEST_skip("No TLSv1.3 available");
|
||||||
|
+#endif
|
||||||
|
+#ifdef OPENSSL_NO_TLS1_2
|
||||||
|
+ /* If no TLSv1.2 available then do nothing in this case */
|
||||||
|
+ if (idx % 2 == 1)
|
||||||
|
+ return TEST_skip("No TLSv1.2 available");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||||
|
+ TLS_client_method(), TLS1_VERSION,
|
||||||
|
+ (idx % 2 == 0) ? TLS1_3_VERSION
|
||||||
|
+ : TLS1_2_VERSION,
|
||||||
|
+ &sctx, &cctx, cert, privkey))
|
||||||
|
+ || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ SSL_CTX_sess_set_get_cb(sctx, get_session_cb);
|
||||||
|
+ get_sess_val = NULL;
|
||||||
|
+
|
||||||
|
+ SSL_CTX_sess_set_cache_size(sctx, 1);
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||||
|
+ NULL, NULL)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (idx > 1) {
|
||||||
|
+ sess = SSL_get_session(serverssl);
|
||||||
|
+ if (!TEST_ptr(sess))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Cause this session to have a longer timeout than the next session to
|
||||||
|
+ * be added.
|
||||||
|
+ */
|
||||||
|
+ if (!TEST_true(SSL_SESSION_set_timeout(sess, LONG_MAX / 2))) {
|
||||||
|
+ sess = NULL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ sess = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SSL_shutdown(serverssl);
|
||||||
|
+ SSL_shutdown(clientssl);
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ serverssl = clientssl = NULL;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Session cache size is 1 and we already populated the cache with a session
|
||||||
|
+ * so the next connection should cause an overflow.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||||
|
+ NULL, NULL)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * The session we just negotiated may have been already removed from the
|
||||||
|
+ * internal cache - but we will return it anyway from our external cache.
|
||||||
|
+ */
|
||||||
|
+ get_sess_val = SSL_get_session(serverssl);
|
||||||
|
+ if (!TEST_ptr(get_sess_val))
|
||||||
|
+ goto end;
|
||||||
|
+ sess = SSL_get1_session(clientssl);
|
||||||
|
+ if (!TEST_ptr(sess))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ SSL_shutdown(serverssl);
|
||||||
|
+ SSL_shutdown(clientssl);
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ serverssl = clientssl = NULL;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||||
|
+ NULL, NULL)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(SSL_set_session(clientssl, sess)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ testresult = 1;
|
||||||
|
+
|
||||||
|
+ end:
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ SSL_CTX_free(sctx);
|
||||||
|
+ SSL_CTX_free(cctx);
|
||||||
|
+ SSL_SESSION_free(sess);
|
||||||
|
+
|
||||||
|
+ return testresult;
|
||||||
|
+}
|
||||||
|
+#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Test 0: Client sets servername and server acknowledges it (TLSv1.2)
|
||||||
|
* Test 1: Client sets servername and server does not acknowledge it (TLSv1.2)
|
||||||
|
@@ -10872,6 +10991,9 @@ int setup_tests(void)
|
||||||
|
ADD_TEST(test_set_verify_cert_store_ssl_ctx);
|
||||||
|
ADD_TEST(test_set_verify_cert_store_ssl);
|
||||||
|
ADD_ALL_TESTS(test_session_timeout, 1);
|
||||||
|
+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
|
||||||
|
+ ADD_ALL_TESTS(test_session_cache_overflow, 4);
|
||||||
|
+#endif
|
||||||
|
ADD_TEST(test_load_dhfile);
|
||||||
|
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3)
|
||||||
|
ADD_ALL_TESTS(test_serverinfo_custom, 4);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
From b52867a9f618bb955bed2a3ce3db4d4f97ed8e5d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matt Caswell <matt@openssl.org>
|
||||||
|
Date: Tue, 5 Mar 2024 15:43:53 +0000
|
||||||
|
Subject: [PATCH] Fix unconstrained session cache growth in TLSv1.3
|
||||||
|
|
||||||
|
In TLSv1.3 we create a new session object for each ticket that we send.
|
||||||
|
We do this by duplicating the original session. If SSL_OP_NO_TICKET is in
|
||||||
|
use then the new session will be added to the session cache. However, if
|
||||||
|
early data is not in use (and therefore anti-replay protection is being
|
||||||
|
used), then multiple threads could be resuming from the same session
|
||||||
|
simultaneously. If this happens and a problem occurs on one of the threads,
|
||||||
|
then the original session object could be marked as not_resumable. When we
|
||||||
|
duplicate the session object this not_resumable status gets copied into the
|
||||||
|
new session object. The new session object is then added to the session
|
||||||
|
cache even though it is not_resumable.
|
||||||
|
|
||||||
|
Subsequently, another bug means that the session_id_length is set to 0 for
|
||||||
|
sessions that are marked as not_resumable - even though that session is
|
||||||
|
still in the cache. Once this happens the session can never be removed from
|
||||||
|
the cache. When that object gets to be the session cache tail object the
|
||||||
|
cache never shrinks again and grows indefinitely.
|
||||||
|
|
||||||
|
CVE-2024-2511
|
||||||
|
|
||||||
|
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||||
|
|
||||||
|
(cherry picked from commit 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce)
|
||||||
|
---
|
||||||
|
ssl/ssl_lib.c | 5 +++--
|
||||||
|
ssl/ssl_sess.c | 28 ++++++++++++++++++++++------
|
||||||
|
ssl/statem/statem_srvr.c | 5 ++---
|
||||||
|
3 files changed, 27 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
|
||||||
|
index 2c8479eb5f..eed649c6fd 100644
|
||||||
|
--- a/ssl/ssl_lib.c
|
||||||
|
+++ b/ssl/ssl_lib.c
|
||||||
|
@@ -3736,9 +3736,10 @@ void ssl_update_cache(SSL *s, int mode)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the session_id_length is 0, we are not supposed to cache it, and it
|
||||||
|
- * would be rather hard to do anyway :-)
|
||||||
|
+ * would be rather hard to do anyway :-). Also if the session has already
|
||||||
|
+ * been marked as not_resumable we should not cache it for later reuse.
|
||||||
|
*/
|
||||||
|
- if (s->session->session_id_length == 0)
|
||||||
|
+ if (s->session->session_id_length == 0 || s->session->not_resumable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
|
||||||
|
index d836b33ed0..75adbd9e52 100644
|
||||||
|
--- a/ssl/ssl_sess.c
|
||||||
|
+++ b/ssl/ssl_sess.c
|
||||||
|
@@ -152,16 +152,11 @@ SSL_SESSION *SSL_SESSION_new(void)
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
-SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
|
||||||
|
-{
|
||||||
|
- return ssl_session_dup(src, 1);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Create a new SSL_SESSION and duplicate the contents of |src| into it. If
|
||||||
|
* ticket == 0 then no ticket information is duplicated, otherwise it is.
|
||||||
|
*/
|
||||||
|
-SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||||
|
+static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
|
||||||
|
{
|
||||||
|
SSL_SESSION *dest;
|
||||||
|
|
||||||
|
@@ -285,6 +280,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
|
||||||
|
+{
|
||||||
|
+ return ssl_session_dup_intern(src, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Used internally when duplicating a session which might be already shared.
|
||||||
|
+ * We will have resumed the original session. Subsequently we might have marked
|
||||||
|
+ * it as non-resumable (e.g. in another thread) - but this copy should be ok to
|
||||||
|
+ * resume from.
|
||||||
|
+ */
|
||||||
|
+SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||||
|
+{
|
||||||
|
+ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);
|
||||||
|
+
|
||||||
|
+ if (sess != NULL)
|
||||||
|
+ sess->not_resumable = 0;
|
||||||
|
+
|
||||||
|
+ return sess;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
|
||||||
|
{
|
||||||
|
if (len)
|
||||||
|
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
|
||||||
|
index a9e67f9d32..6c942e6bce 100644
|
||||||
|
--- a/ssl/statem/statem_srvr.c
|
||||||
|
+++ b/ssl/statem/statem_srvr.c
|
||||||
|
@@ -2338,9 +2338,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
|
||||||
|
* so the following won't overwrite an ID that we're supposed
|
||||||
|
* to send back.
|
||||||
|
*/
|
||||||
|
- if (s->session->not_resumable ||
|
||||||
|
- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
|
||||||
|
- && !s->hit))
|
||||||
|
+ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
|
||||||
|
+ && !s->hit)
|
||||||
|
s->session->session_id_length = 0;
|
||||||
|
|
||||||
|
if (usetls13) {
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,160 @@
|
|||||||
|
From c1e462ee4bd61867ee391fc13110ca41e4889535 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matt Caswell <matt@openssl.org>
|
||||||
|
Date: Tue, 5 Mar 2024 15:35:51 +0000
|
||||||
|
Subject: [PATCH] Extend the multi_resume test for simultaneous resumptions
|
||||||
|
|
||||||
|
Test what happens if the same session gets resumed multiple times at the
|
||||||
|
same time - and one of them gets marked as not_resumable.
|
||||||
|
|
||||||
|
Related to CVE-2024-2511
|
||||||
|
|
||||||
|
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||||
|
|
||||||
|
(cherry picked from commit 031b11a4054c972a5e2f07dfa81ce1842453253e)
|
||||||
|
---
|
||||||
|
test/sslapitest.c | 89 ++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 85 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||||
|
index 56229e51b9..24fb95e4b6 100644
|
||||||
|
--- a/test/sslapitest.c
|
||||||
|
+++ b/test/sslapitest.c
|
||||||
|
@@ -10436,12 +10436,63 @@ end:
|
||||||
|
return testresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct resume_servername_cb_data {
|
||||||
|
+ int i;
|
||||||
|
+ SSL_CTX *cctx;
|
||||||
|
+ SSL_CTX *sctx;
|
||||||
|
+ SSL_SESSION *sess;
|
||||||
|
+ int recurse;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Servername callback. We use it here to run another complete handshake using
|
||||||
|
+ * the same session - and mark the session as not_resuamble at the end
|
||||||
|
+ */
|
||||||
|
+static int resume_servername_cb(SSL *s, int *ad, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct resume_servername_cb_data *cbdata = arg;
|
||||||
|
+ SSL *serverssl = NULL, *clientssl = NULL;
|
||||||
|
+ int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
+
|
||||||
|
+ if (cbdata->recurse)
|
||||||
|
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
+
|
||||||
|
+ if ((cbdata->i % 3) != 1)
|
||||||
|
+ return SSL_TLSEXT_ERR_OK;
|
||||||
|
+
|
||||||
|
+ cbdata->recurse = 1;
|
||||||
|
+
|
||||||
|
+ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl,
|
||||||
|
+ &clientssl, NULL, NULL))
|
||||||
|
+ || !TEST_true(SSL_set_session(clientssl, cbdata->sess)))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ ERR_set_mark();
|
||||||
|
+ /*
|
||||||
|
+ * We expect this to fail - because the servername cb will fail. This will
|
||||||
|
+ * mark the session as not_resumable.
|
||||||
|
+ */
|
||||||
|
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
|
||||||
|
+ ERR_clear_last_mark();
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ ERR_pop_to_mark();
|
||||||
|
+
|
||||||
|
+ ret = SSL_TLSEXT_ERR_OK;
|
||||||
|
+ end:
|
||||||
|
+ SSL_free(serverssl);
|
||||||
|
+ SSL_free(clientssl);
|
||||||
|
+ cbdata->recurse = 0;
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Test multiple resumptions and cache size handling
|
||||||
|
* Test 0: TLSv1.3 (max_early_data set)
|
||||||
|
* Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
|
||||||
|
* Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
|
||||||
|
- * Test 3: TLSv1.2
|
||||||
|
+ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes)
|
||||||
|
+ * Test 4: TLSv1.2
|
||||||
|
*/
|
||||||
|
static int test_multi_resume(int idx)
|
||||||
|
{
|
||||||
|
@@ -10450,9 +10501,19 @@ static int test_multi_resume(int idx)
|
||||||
|
SSL_SESSION *sess = NULL;
|
||||||
|
int max_version = TLS1_3_VERSION;
|
||||||
|
int i, testresult = 0;
|
||||||
|
+ struct resume_servername_cb_data cbdata;
|
||||||
|
|
||||||
|
- if (idx == 3)
|
||||||
|
+#if defined(OPENSSL_NO_TLS1_2)
|
||||||
|
+ if (idx == 4)
|
||||||
|
+ return TEST_skip("TLSv1.2 is disabled in this build");
|
||||||
|
+#else
|
||||||
|
+ if (idx == 4)
|
||||||
|
max_version = TLS1_2_VERSION;
|
||||||
|
+#endif
|
||||||
|
+#if defined(OSSL_NO_USABLE_TLS1_3)
|
||||||
|
+ if (idx != 4)
|
||||||
|
+ return TEST_skip("No usable TLSv1.3 in this build");
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||||
|
TLS_client_method(), TLS1_VERSION,
|
||||||
|
@@ -10468,17 +10529,37 @@ static int test_multi_resume(int idx)
|
||||||
|
if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
- if (idx == 1 || idx == 2)
|
||||||
|
+ if (idx == 1 || idx == 2 || idx == 3)
|
||||||
|
SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
|
||||||
|
|
||||||
|
SSL_CTX_sess_set_cache_size(sctx, 5);
|
||||||
|
|
||||||
|
+ if (idx == 3) {
|
||||||
|
+ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb);
|
||||||
|
+ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata);
|
||||||
|
+ cbdata.cctx = cctx;
|
||||||
|
+ cbdata.sctx = sctx;
|
||||||
|
+ cbdata.recurse = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = 0; i < 30; i++) {
|
||||||
|
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||||
|
NULL, NULL))
|
||||||
|
|| !TEST_true(SSL_set_session(clientssl, sess)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Check simultaneous resumes. We pause the connection part way through
|
||||||
|
+ * the handshake by (mis)using the servername_cb. The pause occurs after
|
||||||
|
+ * session resumption has already occurred, but before any session
|
||||||
|
+ * tickets have been issued. While paused we run another complete
|
||||||
|
+ * handshake resuming the same session.
|
||||||
|
+ */
|
||||||
|
+ if (idx == 3) {
|
||||||
|
+ cbdata.i = i;
|
||||||
|
+ cbdata.sess = sess;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Recreate a bug where dynamically changing the max_early_data value
|
||||||
|
* can cause sessions in the session cache which cannot be deleted.
|
||||||
|
@@ -10799,7 +10880,7 @@ int setup_tests(void)
|
||||||
|
ADD_ALL_TESTS(test_pipelining, 6);
|
||||||
|
#endif
|
||||||
|
ADD_ALL_TESTS(test_handshake_retry, 16);
|
||||||
|
- ADD_ALL_TESTS(test_multi_resume, 4);
|
||||||
|
+ ADD_ALL_TESTS(test_multi_resume, 5);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
38
backport-Hardening-around-not_resumable-sessions.patch
Normal file
38
backport-Hardening-around-not_resumable-sessions.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From cc9ece9118eeacccc3571c2ee852f8ba067d0607 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matt Caswell <matt@openssl.org>
|
||||||
|
Date: Fri, 15 Mar 2024 17:58:42 +0000
|
||||||
|
Subject: [PATCH] Hardening around not_resumable sessions
|
||||||
|
|
||||||
|
Make sure we can't inadvertently use a not_resumable session
|
||||||
|
|
||||||
|
Related to CVE-2024-2511
|
||||||
|
|
||||||
|
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||||
|
|
||||||
|
(cherry picked from commit c342f4b8bd2d0b375b0e22337057c2eab47d9b96)
|
||||||
|
---
|
||||||
|
ssl/ssl_sess.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
|
||||||
|
index 75adbd9e52..d0b72b7880 100644
|
||||||
|
--- a/ssl/ssl_sess.c
|
||||||
|
+++ b/ssl/ssl_sess.c
|
||||||
|
@@ -531,6 +531,12 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
|
||||||
|
ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©);
|
||||||
|
|
||||||
|
if (ret != NULL) {
|
||||||
|
+ if (ret->not_resumable) {
|
||||||
|
+ /* If its not resumable then ignore this session */
|
||||||
|
+ if (!copy)
|
||||||
|
+ SSL_SESSION_free(ret);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
ssl_tsan_counter(s->session_ctx,
|
||||||
|
&s->session_ctx->stats.sess_cb_hit);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
10
openssl.spec
10
openssl.spec
@ -2,7 +2,7 @@
|
|||||||
Name: openssl
|
Name: openssl
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 3.0.12
|
Version: 3.0.12
|
||||||
Release: 3
|
Release: 4
|
||||||
Summary: Cryptography and SSL/TLS Toolkit
|
Summary: Cryptography and SSL/TLS Toolkit
|
||||||
License: OpenSSL and SSLeay
|
License: OpenSSL and SSLeay
|
||||||
URL: https://www.openssl.org/
|
URL: https://www.openssl.org/
|
||||||
@ -32,6 +32,11 @@ Patch20: Backport-Limit-the-execution-time-of-RSA-public-key-check.patch
|
|||||||
Patch21: Backport-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch
|
Patch21: Backport-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch
|
||||||
Patch22: Backport-Fix-SM4-XTS-aarch64-assembly-implementation-bug.patch
|
Patch22: Backport-Fix-SM4-XTS-aarch64-assembly-implementation-bug.patch
|
||||||
Patch23: fix-add-loongarch64-target.patch
|
Patch23: fix-add-loongarch64-target.patch
|
||||||
|
Patch24: backport-CVE-2024-2511-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch
|
||||||
|
Patch25: backport-Add-a-test-for-session-cache-handling.patch
|
||||||
|
Patch26: backport-Extend-the-multi_resume-test-for-simultaneous-resump.patch
|
||||||
|
Patch27: backport-Hardening-around-not_resumable-sessions.patch
|
||||||
|
Patch28: backport-Add-a-test-for-session-cache-overflow.patch
|
||||||
|
|
||||||
BuildRequires: gcc gcc-c++ perl make lksctp-tools-devel coreutils util-linux zlib-devel
|
BuildRequires: gcc gcc-c++ perl make lksctp-tools-devel coreutils util-linux zlib-devel
|
||||||
Requires: coreutils %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
|
Requires: coreutils %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
|
||||||
@ -232,6 +237,9 @@ make test || :
|
|||||||
%ldconfig_scriptlets libs
|
%ldconfig_scriptlets libs
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun Apr 28 2024 wangcheng <wangcheng156@huawei.com> - 1:3.0.12-4
|
||||||
|
- fix CVE-2024-2511
|
||||||
|
|
||||||
* Wed Mar 6 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 1:3.0.12-3
|
* Wed Mar 6 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 1:3.0.12-3
|
||||||
- Fix build error for loongarch64
|
- Fix build error for loongarch64
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user