153 lines
4.8 KiB
Diff
153 lines
4.8 KiB
Diff
From cf1f5d212c9d30d2a1996b7426cf8483205e8491 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)
|
|
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
|
|
---
|
|
test/sslapitest.c | 87 ++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 84 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
|
index 2992356fdf..472b1224ca 100644
|
|
--- a/test/sslapitest.c
|
|
+++ b/test/sslapitest.c
|
|
@@ -7288,12 +7288,63 @@ static int test_inherit_verify_param(void)
|
|
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)
|
|
{
|
|
@@ -7302,9 +7353,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(TLS_server_method(),
|
|
TLS_client_method(), TLS1_VERSION,
|
|
@@ -7320,17 +7381,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.
|
|
--
|
|
2.33.0
|
|
|