Skip to content

Commit

Permalink
Add a test for session cache handling
Browse files Browse the repository at this point in the history
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 openssl/openssl#24044)

(cherry picked from commit 5f5b9e1ca1fad0215f623b8bd4955a2e8101f306)
Signed-off-by: hhhFun <fanghaojie@huawei.com>
  • Loading branch information
mattcaswell authored and hhhFun committed Apr 12, 2024
1 parent 6ac84aa commit e76f85e
Showing 1 changed file with 92 additions and 0 deletions.
92 changes: 92 additions & 0 deletions test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -10303,6 +10303,97 @@ static int test_pipelining(int idx)
}
#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */

/*
* 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)
Expand Down Expand Up @@ -10574,6 +10665,7 @@ int setup_tests(void)
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
ADD_ALL_TESTS(test_pipelining, 6);
#endif
ADD_ALL_TESTS(test_multi_resume, 4);
return 1;

err:
Expand Down

0 comments on commit e76f85e

Please sign in to comment.