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#24044)

(cherry picked from commit ddead09)
  • Loading branch information
mattcaswell authored and bernd-edlinger committed Apr 21, 2024
1 parent f4f6e21 commit a2f354f
Showing 1 changed file with 123 additions and 0 deletions.
123 changes: 123 additions & 0 deletions test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -6916,6 +6916,126 @@ 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)
return 1;
#endif
#ifdef OPENSSL_NO_TLS1_2
/* If no TLSv1.2 available then do nothing in this case */
if (idx % 2 == 1)
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 @@ -8130,6 +8250,9 @@ int setup_tests(void)
ADD_TEST(test_set_verify_cert_store_ssl_ctx);
ADD_TEST(test_set_verify_cert_store_ssl);
ADD_TEST(test_inherit_verify_param);
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
ADD_ALL_TESTS(test_session_cache_overflow, 4);
#endif
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_3)
ADD_ALL_TESTS(test_serverinfo_custom, 4);
#endif
Expand Down

0 comments on commit a2f354f

Please sign in to comment.