diff --git a/src/dtls13.c b/src/dtls13.c index 375c00af0..a07f8d3df 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -905,7 +905,7 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs, /* the other peer may have retransmitted because an ACK for a flight that needs explicit ACK was lost.*/ if (ssl->dtls13Rtx.seenRecords != NULL) - ssl->dtls13Rtx.sendAcks = (byte)ssl->options.dtls13SendMoreAcks; + ssl->dtls13Rtx.sendAcks = 1; } if (ssl->keys.dtls_peer_handshake_number == diff --git a/src/ssl.c b/src/ssl.c index ecaa07b8c..16acfda1c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12817,6 +12817,13 @@ cleanup: if (ssl == NULL) return 0; +#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_CLIENT) + if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls + && IsAtLeastTLSv1_3(ssl->version)) { + return ssl->options.serverState == SERVER_FINISHED_ACKED; + } +#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT */ + /* Can't use ssl->options.connectState and ssl->options.acceptState * because they differ in meaning for TLS <=1.2 and 1.3 */ if (ssl->options.handShakeState == HANDSHAKE_DONE) @@ -26762,4 +26769,3 @@ void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data) #endif /* !WOLFCRYPT_ONLY */ - diff --git a/tests/api.c b/tests/api.c index 7c8e89e3e..8cadb6af8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -66090,8 +66090,7 @@ static int test_dtls13_missing_finished_server(void) ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); /* Let's clear the output */ test_memio_clear_buffer(&test_ctx, 0); - /* We should signal that the handshake is done */ - ExpectTrue(wolfSSL_is_init_finished(ssl_c)); + ExpectFalse(wolfSSL_is_init_finished(ssl_c)); /* Let's send some app data */ ExpectIntEQ(wolfSSL_write(ssl_c, test_str, sizeof(test_str)), sizeof(test_str)); @@ -68496,6 +68495,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_dtls_cid_parse), TEST_DECL(test_dtls13_epochs), TEST_DECL(test_dtls_rtx_across_epoch_change), + TEST_DECL(test_dtls_drop_client_ack), 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 d6a106b39..75f495533 100644 --- a/tests/api/test_dtls.c +++ b/tests/api/test_dtls.c @@ -1383,3 +1383,82 @@ int test_dtls_rtx_across_epoch_change(void) defined(WOLFSSL_DTLS13) */ return EXPECT_RESULT(); } +int test_dtls_drop_client_ack(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_DTLS13) && defined(WOLFSSL_DTLS) + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + char data[32]; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + /* Setup DTLS contexts */ + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), + 0); + + /* disable new session ticket to simplify testing */ + ExpectIntEQ(wolfSSL_no_ticket_TLSv13(ssl_s), 0); + + /* CH0 */ + wolfSSL_SetLoggingPrefix("client:"); + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + + /* HRR */ + wolfSSL_SetLoggingPrefix("server:"); + ExpectIntEQ(wolfSSL_accept(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + + /* CH1 */ + wolfSSL_SetLoggingPrefix("client:"); + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + + /* SH ... FINISHED */ + wolfSSL_SetLoggingPrefix("server:"); + ExpectIntEQ(wolfSSL_accept(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + + /* ... FINISHED */ + wolfSSL_SetLoggingPrefix("client:"); + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + + /* init is finished should return false at this point */ + ExpectFalse(wolfSSL_is_init_finished(ssl_c)); + + /* ACK */ + ExpectIntEQ(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS); + /* Drop the ack */ + test_memio_clear_buffer(&test_ctx, 1); + + /* trigger client timeout, finished should be rtx */ + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS); + /* this should have triggered a rtx */ + ExpectIntGT(test_ctx.s_msg_count, 0); + + /* this should re-send the ack immediately */ + ExpectIntEQ(wolfSSL_read(ssl_s, data, 32), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(test_ctx.c_msg_count, 1); + + /* This should advance the connection on the client */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), WOLFSSL_SUCCESS); + + /* Test communication works correctly */ + ExpectIntEQ(test_dtls_communication(ssl_s, ssl_c), TEST_SUCCESS); + + /* Cleanup */ + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); +#endif /* defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_DTLS13) */ + return EXPECT_RESULT(); +} diff --git a/tests/api/test_dtls.h b/tests/api/test_dtls.h index 18ace27b6..e5801d084 100644 --- a/tests/api/test_dtls.h +++ b/tests/api/test_dtls.h @@ -37,4 +37,5 @@ int test_dtls13_short_read(void); 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); #endif /* TESTS_API_DTLS_H */