mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
Merge pull request #11708 from padelsbach/shutdown-loop
Fail wolfSSL_shutdown when the peer's record cannot be processed
This commit is contained in:
@@ -1023,11 +1023,10 @@ static int wolfssl_shutdown_recv_close_notify(WOLFSSL* ssl)
|
||||
ssl->error = WOLFSSL_ERROR_NONE;
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
else if (ret == WC_NO_ERR_TRACE(WANT_READ)) {
|
||||
else if ((ret < 0) && (ret != WC_NO_ERR_TRACE(APP_DATA_READY))) {
|
||||
/* Retry would process the same bad record again, error out. */
|
||||
ssl->error = ret;
|
||||
WOLFSSL_ERROR(ret);
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
else if (ssl->error == WOLFSSL_ERROR_NONE) {
|
||||
|
||||
@@ -1498,6 +1498,106 @@ int test_wolfSSL_shutdown_no_notify(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_TLS) && \
|
||||
(!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13))
|
||||
/* Shut a connection down when the peer's next record cannot be processed.
|
||||
*
|
||||
* @param [in] method_c Client method.
|
||||
* @param [in] method_s Server method.
|
||||
* @param [in] peerAlert 0 to corrupt a record from the server, 1 to have the
|
||||
* server send a fatal alert instead.
|
||||
* @return TEST_SUCCESS on success.
|
||||
*/
|
||||
static int test_ssl_rw_shutdown_bad_record(method_provider method_c,
|
||||
method_provider method_s, int peerAlert)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX* ctx_c = NULL;
|
||||
WOLFSSL_CTX* ctx_s = NULL;
|
||||
WOLFSSL* ssl_c = NULL;
|
||||
WOLFSSL* ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
char buf[16];
|
||||
int sentLen = 0;
|
||||
int retryRet = WOLFSSL_FATAL_ERROR;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
method_c, method_s), 0);
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
/* Read any session tickets so the next record is the bad one. */
|
||||
ExpectIntEQ(wolfSSL_read(ssl_c, buf, (int)sizeof(buf)),
|
||||
WOLFSSL_FATAL_ERROR);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
|
||||
if (peerAlert) {
|
||||
/* An unknown record type gets a fatal alert with any cipher. */
|
||||
ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), 5);
|
||||
ExpectIntEQ(test_ctx.s_buff[0], application_data);
|
||||
if (EXPECT_SUCCESS()) {
|
||||
test_ctx.s_buff[0] = no_type;
|
||||
}
|
||||
ExpectIntEQ(wolfSSL_read(ssl_s, buf, (int)sizeof(buf)),
|
||||
WOLFSSL_FATAL_ERROR);
|
||||
ExpectIntGT(test_ctx.c_len, 0);
|
||||
}
|
||||
else {
|
||||
ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), 5);
|
||||
if (EXPECT_SUCCESS()) {
|
||||
test_ctx.c_buff[test_ctx.c_len - 1] ^= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
|
||||
/* The record cannot be processed, so the shutdown fails. */
|
||||
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_FATAL_ERROR);
|
||||
ExpectIntLT(ssl_c->error, 0);
|
||||
ExpectIntNE(ssl_c->error, WC_NO_ERR_TRACE(WANT_READ));
|
||||
sentLen = test_ctx.s_len;
|
||||
#ifdef WOLFSSL_SHUTDOWNONCE
|
||||
if ((ssl_c != NULL) &&
|
||||
(ssl_c->options.isClosed || ssl_c->options.connReset)) {
|
||||
retryRet = WC_NO_ERR_TRACE(SSL_SHUTDOWN_ALREADY_DONE_E);
|
||||
}
|
||||
#endif
|
||||
/* Trying again still fails and sends nothing more. */
|
||||
ExpectIntEQ(wolfSSL_shutdown(ssl_c), retryRet);
|
||||
ExpectIntLT(ssl_c->error, 0);
|
||||
ExpectIntEQ(test_ctx.s_len, sentLen);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test that a shutdown fails when the peer's next record is bad.
|
||||
*
|
||||
* @return TEST_SUCCESS on success.
|
||||
*/
|
||||
int test_wolfSSL_shutdown_bad_record(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_TLS)
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
ExpectIntEQ(test_ssl_rw_shutdown_bad_record(wolfTLSv1_2_client_method,
|
||||
wolfTLSv1_2_server_method, 0), TEST_SUCCESS);
|
||||
ExpectIntEQ(test_ssl_rw_shutdown_bad_record(wolfTLSv1_2_client_method,
|
||||
wolfTLSv1_2_server_method, 1), TEST_SUCCESS);
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13
|
||||
ExpectIntEQ(test_ssl_rw_shutdown_bad_record(wolfTLSv1_3_client_method,
|
||||
wolfTLSv1_3_server_method, 0), TEST_SUCCESS);
|
||||
ExpectIntEQ(test_ssl_rw_shutdown_bad_record(wolfTLSv1_3_client_method,
|
||||
wolfTLSv1_3_server_method, 1), TEST_SUCCESS);
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Test the paths wolfSSL_SendUserCanceled() takes once the alert is sent.
|
||||
*
|
||||
* The NULL case is covered by test_wolfSSL_rw_bad_args(). This drives the
|
||||
|
||||
@@ -39,6 +39,7 @@ int test_wolfSSL_rehandshake_app_data_pending(void);
|
||||
int test_wolfSSL_rehandshake_app_data_partial_record(void);
|
||||
int test_wolfSSL_accept_early_data_pending(void);
|
||||
int test_wolfSSL_shutdown_no_notify(void);
|
||||
int test_wolfSSL_shutdown_bad_record(void);
|
||||
int test_wolfSSL_shutdown_repeat_after_done(void);
|
||||
int test_wolfSSL_shutdown_flush_no_notify(void);
|
||||
int test_wolfSSL_shutdown_quic_alert_refused(void);
|
||||
@@ -69,6 +70,7 @@ int test_wolfSSL_write_dup_max_fragment(void);
|
||||
test_wolfSSL_rehandshake_app_data_partial_record), \
|
||||
TEST_DECL_GROUP("ssl_rw", test_wolfSSL_accept_early_data_pending), \
|
||||
TEST_DECL_GROUP("ssl_rw", test_wolfSSL_shutdown_no_notify), \
|
||||
TEST_DECL_GROUP("ssl_rw", test_wolfSSL_shutdown_bad_record), \
|
||||
TEST_DECL_GROUP("ssl_rw", \
|
||||
test_wolfSSL_shutdown_repeat_after_done), \
|
||||
TEST_DECL_GROUP("ssl_rw", test_wolfSSL_shutdown_flush_no_notify), \
|
||||
|
||||
Reference in New Issue
Block a user