Recover when the client sends a 0-length session ID when using tickets

Fixes ZD16477
This commit is contained in:
Juliusz Sosinowicz
2023-07-28 17:51:47 +02:00
parent fbc6ed4fe4
commit bfe7bc0fcc
2 changed files with 88 additions and 9 deletions

View File

@ -16114,15 +16114,15 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
case certificate_request:
case server_hello_done:
if (ssl->options.resuming) {
#ifdef WOLFSSL_WPAS
/* This can occur when ssl->sessionSecretCb is set. EAP-FAST
* (RFC 4851) allows for detecting server session resumption
* based on the msg received after the ServerHello. */
WOLFSSL_MSG("Not resuming as thought");
ssl->options.resuming = 0;
/* No longer resuming, reset peer authentication state. */
ssl->options.peerAuthGood = 0;
#else
/* https://www.rfc-editor.org/rfc/rfc5077.html#section-3.4
* Alternatively, the client MAY include an empty Session ID
* in the ClientHello. In this case, the client ignores the
* Session ID sent in the ServerHello and determines if the
* server is resuming a session by the subsequent handshake
* messages.
*/
if (ssl->session->sessionIDSz != 0) {
#ifndef WOLFSSL_WPAS
/* Fatal error. Only try to send an alert. RFC 5246 does not
* allow for reverting back to a full handshake after the
* server has indicated the intention to do a resumption. */
@ -16131,6 +16131,14 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return OUT_OF_ORDER_E;
#endif
}
/* This can occur when ssl->sessionSecretCb is set. EAP-FAST
* (RFC 4851) allows for detecting server session resumption
* based on the msg received after the ServerHello. */
WOLFSSL_MSG("Not resuming as thought");
ssl->options.resuming = 0;
/* No longer resuming, reset peer authentication state. */
ssl->options.peerAuthGood = 0;
}
}
}

View File

@ -63172,6 +63172,76 @@ static int test_dtls_1_0_hvr_downgrade(void)
}
#endif
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_SESSION_TICKET)
static WOLFSSL_SESSION* test_session_ticket_no_id_session = NULL;
static void test_session_ticket_no_id_on_result(WOLFSSL* ssl)
{
test_session_ticket_no_id_session = wolfSSL_get1_session(ssl);
AssertNotNull(test_session_ticket_no_id_session);
}
static void test_session_ticket_no_id_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
}
static void test_session_ticket_no_id_ssl_ready(WOLFSSL* ssl)
{
test_session_ticket_no_id_session->sessionIDSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_set_session(ssl, test_session_ticket_no_id_session));
}
static int test_session_ticket_no_id(void)
{
/* We are testing an expired (invalid crypto context in out case since the
* ctx changes) session ticket being sent with the session ID being 0
* length. */
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
func_cb_client.on_result = test_session_ticket_no_id_on_result;
func_cb_server.method = wolfTLSv1_2_server_method;
func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
func_cb_client.ssl_ready = test_session_ticket_no_id_ssl_ready;
func_cb_server.method = wolfTLSv1_2_server_method;
func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
wolfSSL_SESSION_free(test_session_ticket_no_id_session);
return EXPECT_RESULT();
}
#else
static int test_session_ticket_no_id(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
/*----------------------------------------------------------------------------*
| Main
*----------------------------------------------------------------------------*/
@ -64425,6 +64495,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_dtls_no_extensions),
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
TEST_DECL(test_dtls_1_0_hvr_downgrade),
TEST_DECL(test_session_ticket_no_id),
/* This test needs to stay at the end to clean up any caches allocated. */
TEST_DECL(test_wolfSSL_Cleanup)
};