Skip to content

Commit

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

(cherry picked from commit ddead0935d77ba9b771d632ace61b145d7153f18)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
Signed-off-by: hhhFun <fanghaojie@huawei.com>
  • Loading branch information
mattcaswell authored and hhhFun committed Apr 13, 2024
1 parent 2351649 commit 319a698
Showing 1 changed file with 130 additions and 4 deletions.
134 changes: 130 additions & 4 deletions test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -6457,6 +6457,128 @@ static int test_ca_names(int tst)
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(OPENSSL_NO_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 OPENSSL_NO_TLS1_3
/* If no TLSv1.3 available then do nothing in this case */
if (idx % 2 == 0)
TEST_info("No TLSv1.3 available");
return 1;
#endif
#ifdef OPENSSL_NO_TLS1_2
/* If no TLSv1.2 available then do nothing in this case */
if (idx % 2 == 1)
TEST_info("No TLSv1.2 available");
return 1;
#endif

if (!TEST_true(create_ssl_ctx_pair(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(OPENSSL_NO_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)
Expand Down Expand Up @@ -6917,14 +7039,16 @@ static int test_multi_resume(int idx)

#if defined(OPENSSL_NO_TLS1_2)
if (idx == 4)
return TEST_skip("TLSv1.2 is disabled in this build");
TEST_info("TLSv1.2 is disabled in this build");
return 1;
#else
if (idx == 4)
max_version = TLS1_2_VERSION;
#endif
#if defined(OSSL_NO_USABLE_TLS1_3)
#if defined(OPENSSL_NO_TLS1_3)
if (idx != 4)
return TEST_skip("No usable TLSv1.3 in this build");
TEST_info("No usable TLSv1.3 in this build");
return 1;
#endif

if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
Expand Down Expand Up @@ -7148,7 +7272,9 @@ int setup_tests(void)
#endif
ADD_TEST(test_set_alpn);
ADD_TEST(test_inherit_verify_param);
ADD_ALL_TESTS(test_multi_resume, 5);
#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
ADD_ALL_TESTS(test_session_cache_overflow, 4);
#endif
return 1;
}

Expand Down

0 comments on commit 319a698

Please sign in to comment.