Skip to content

Commit

Permalink
Extend the multi_resume test for simultaneous resumptions
Browse files Browse the repository at this point in the history
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 #24044)
  • Loading branch information
mattcaswell authored and t8m committed Apr 8, 2024
1 parent 5f5b9e1 commit 031b11a
Showing 1 changed file with 85 additions and 4 deletions.
89 changes: 85 additions & 4 deletions test/sslapitest.c
Expand Up @@ -10630,12 +10630,63 @@ static int test_handshake_retry(int idx)
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)
{
Expand All @@ -10644,9 +10695,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,
Expand All @@ -10662,17 +10723,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.
Expand Down Expand Up @@ -11018,7 +11099,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_pipelining, 7);
#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:
Expand Down

0 comments on commit 031b11a

Please sign in to comment.