From 0d532cc3f22cabb25abcc2066d9c95d6add21283 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 7 Aug 2025 14:12:42 +0200 Subject: [PATCH] Test DTLS replay protection --- tests/api.c | 1 + tests/api/test_dtls.c | 53 +++++++++++++++++++++++++++++++++++++++++++ tests/api/test_dtls.h | 1 + tests/utils.c | 32 ++++++++++++++++++++++++++ tests/utils.h | 2 ++ 5 files changed, 89 insertions(+) diff --git a/tests/api.c b/tests/api.c index 754597961..b615eb0b4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -53212,6 +53212,7 @@ TEST_DECL(test_wc_RsaPSS_DigitalSignVerify), TEST_DECL(test_dtls13_epochs), TEST_DECL(test_dtls_rtx_across_epoch_change), TEST_DECL(test_dtls_drop_client_ack), + TEST_DECL(test_dtls_replay), TEST_DECL(test_dtls13_ack_order), TEST_DECL(test_dtls_version_checking), TEST_DECL(test_ocsp_status_callback), diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c index cc0c1a254..9458874dc 100644 --- a/tests/api/test_dtls.c +++ b/tests/api/test_dtls.c @@ -1393,6 +1393,7 @@ int test_dtls_rtx_across_epoch_change(void) defined(WOLFSSL_DTLS13) */ return EXPECT_RESULT(); } + int test_dtls_drop_client_ack(void) { EXPECT_DECLS; @@ -1472,3 +1473,55 @@ int test_dtls_drop_client_ack(void) defined(WOLFSSL_DTLS13) */ return EXPECT_RESULT(); } + +int test_dtls_replay(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) + size_t i; + struct { + method_provider client_meth; + method_provider server_meth; + const char* tls_version; + } params[] = { +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DTLS13) + { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" }, +#endif +#if !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_DTLS) + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" }, +#endif +#if !defined(NO_OLD_TLS) && defined(WOLFSSL_DTLS) + { wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" }, +#endif + }; + for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) { + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + + char msg_buf[256]; + int msg_len = sizeof(msg_buf); + byte app_data[8]; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + /* Setup DTLS contexts */ + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + params[i].client_meth, params[i].server_meth), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + ExpectIntEQ(wolfSSL_write(ssl_c, "test", 4), 4); + ExpectIntEQ(test_memio_copy_message(&test_ctx, 0, msg_buf, &msg_len, 0), 0); + ExpectIntEQ(wolfSSL_read(ssl_s, app_data, sizeof(app_data)), 4); + ExpectIntEQ(test_memio_inject_message(&test_ctx, 0, msg_buf, msg_len), 0); + ExpectIntEQ(wolfSSL_read(ssl_s, app_data, sizeof(app_data)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + } +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_dtls.h b/tests/api/test_dtls.h index 199518790..9c717826a 100644 --- a/tests/api/test_dtls.h +++ b/tests/api/test_dtls.h @@ -38,4 +38,5 @@ int test_records_span_network_boundaries(void); int test_dtls_record_cross_boundaries(void); int test_dtls_rtx_across_epoch_change(void); int test_dtls_drop_client_ack(void); +int test_dtls_replay(void); #endif /* TESTS_API_DTLS_H */ diff --git a/tests/utils.c b/tests/utils.c index 7d42428d2..fb37eada9 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -405,6 +405,38 @@ int test_memio_inject_message(struct test_memio_ctx* ctx, int client, return 0; } +int test_memio_copy_message(const struct test_memio_ctx *ctx, int client, + char *out, int *out_sz, int msg_pos) +{ + int msg_count; + const int* msg_sizes; + int i; + const byte* buff; + + if (client) { + buff = ctx->c_buff; + msg_count = ctx->c_msg_count; + msg_sizes = ctx->c_msg_sizes; + } + else { + buff = ctx->s_buff; + msg_count = ctx->s_msg_count; + msg_sizes = ctx->s_msg_sizes; + } + if (msg_pos < 0 || msg_pos >= msg_count) { + return -1; + } + if (*out_sz < msg_sizes[msg_pos]) { + return -1; + } + for (i = 0; i < msg_pos; i++) { + buff += msg_sizes[i]; + } + XMEMCPY(out, buff, (size_t)msg_sizes[msg_pos]); + *out_sz = msg_sizes[msg_pos]; + return 0; +} + int test_memio_drop_message(struct test_memio_ctx *ctx, int client, int msg_pos) { int *len; diff --git a/tests/utils.h b/tests/utils.h index bfedf4451..8d44172e1 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -66,6 +66,8 @@ int test_memio_setup_ex(struct test_memio_ctx *ctx, byte *serverKey, int serverKeySz); void test_memio_clear_buffer(struct test_memio_ctx *ctx, int is_client); int test_memio_inject_message(struct test_memio_ctx *ctx, int client, const char *data, int sz); +int test_memio_copy_message(const struct test_memio_ctx *ctx, int client, + char *out, int *out_sz, int msg_pos); int test_memio_drop_message(struct test_memio_ctx *ctx, int client, int msg_pos); int test_memio_modify_message_len(struct test_memio_ctx *ctx, int client, int msg_pos, int new_len); int test_memio_remove_from_buffer(struct test_memio_ctx *ctx, int client, int off, int sz);