Skip to content

Commit

Permalink
Merge pull request #7590 from julek-wolfssl/expose-alerts
Browse files Browse the repository at this point in the history
Allow user to send a user_canceled alert
  • Loading branch information
JacobBarthelmeh authored Jun 5, 2024
2 parents 592a452 + ede8cde commit 8d63fb5
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -24894,6 +24894,11 @@ static int SendAlert_ex(WOLFSSL* ssl, int severity, int type)
#endif /* WOLFSSL_DTLS13 */
{
AddRecordHeader(output, ALERT_SIZE, alert, ssl, CUR_ORDER);
#ifdef WOLFSSL_DTLS
/* AddRecordHeader doesn't increment the seq number */
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
}

output += RECORD_HEADER_SZ;
Expand Down
19 changes: 19 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3973,6 +3973,25 @@ int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
}
#endif

int wolfSSL_SendUserCanceled(WOLFSSL* ssl)
{
int ret = WOLFSSL_FAILURE;
WOLFSSL_ENTER("wolfSSL_recv");

if (ssl != NULL) {
ssl->error = SendAlert(ssl, alert_warning, user_canceled);
if (ssl->error < 0) {
WOLFSSL_ERROR(ssl->error);
}
else {
ret = wolfSSL_shutdown(ssl);
}
}

WOLFSSL_LEAVE("wolfSSL_SendUserCanceled", ret);

return ret;
}

/* WOLFSSL_SUCCESS on ok */
WOLFSSL_ABI
Expand Down
72 changes: 72 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -72660,6 +72660,77 @@ static int test_tls_cert_store_unchanged(void)
return EXPECT_RESULT();
}

static int test_wolfSSL_SendUserCanceled(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* tls_version;
} params[] = {
#if defined(WOLFSSL_TLS13)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS)
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
};

for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;

printf("Testing %s\n", params[i].tls_version);

XMEMSET(&h, 0, sizeof(h));
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
params[i].client_meth, params[i].server_meth), 0);

/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

ExpectIntEQ(wolfSSL_SendUserCanceled(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);

/* Alert closed connection */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_ZERO_RETURN);

/* Last alert will be close notify because user_canceled should be
* followed by a close_notify */
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_rx.code, close_notify);
ExpectIntEQ(h.last_rx.level, alert_warning);

wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
}
#endif
return EXPECT_RESULT();
}

/*----------------------------------------------------------------------------*
| Main
*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -73989,6 +74060,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_read_write_hs),
TEST_DECL(test_get_signature_nid),
TEST_DECL(test_tls_cert_store_unchanged),
TEST_DECL(test_wolfSSL_SendUserCanceled),
/* This test needs to stay at the end to clean up any caches allocated. */
TEST_DECL(test_wolfSSL_Cleanup)
};
Expand Down
4 changes: 3 additions & 1 deletion wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,7 @@ WOLFSSL_API unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSIO
WOLFSSL_ABI WOLFSSL_API void wolfSSL_CTX_free(WOLFSSL_CTX* ctx);
WOLFSSL_ABI WOLFSSL_API void wolfSSL_free(WOLFSSL* ssl);
WOLFSSL_ABI WOLFSSL_API int wolfSSL_shutdown(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_SendUserCanceled(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags);
WOLFSSL_API int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags);

Expand Down Expand Up @@ -2576,7 +2577,8 @@ enum { /* ssl Constants */
WOLFSSL_FAILURE = 0, /* for some functions */
WOLFSSL_SUCCESS = 1,

/* WOLFSSL_SHUTDOWN_NOT_DONE is returned by wolfSSL_shutdown when the other end
/* WOLFSSL_SHUTDOWN_NOT_DONE is returned by wolfSSL_shutdown and
* wolfSSL_SendUserCanceled when the other end
* of the connection has yet to send its close notify alert as part of the
* bidirectional shutdown. To complete the shutdown, either keep calling
* wolfSSL_shutdown until it returns WOLFSSL_SUCCESS or call wolfSSL_read until
Expand Down

0 comments on commit 8d63fb5

Please sign in to comment.