diff --git a/src/internal.c b/src/internal.c index 1af47563f..978f89543 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10421,16 +10421,19 @@ static int GetDtlsRecordHeader(WOLFSSL* ssl, word32* inOutIdx, ENUM_LEN + VERSION_SZ); *inOutIdx += ENUM_LEN + VERSION_SZ; ato16(ssl->buffers.inputBuffer.buffer + *inOutIdx, &ssl->keys.curEpoch); + #ifdef WOLFSSL_DTLS13 /* only non protected message can use the DTLSPlaintext record header */ - if (ssl->options.tls1_3 && ssl->keys.curEpoch != 0) + if (IsAtLeastTLSv1_3(ssl->version)) { + if (ssl->keys.curEpoch != 0) return SEQUENCE_ERROR; - w64Zero(&ssl->keys.curEpoch64); - if (!w64IsZero(ssl->dtls13DecryptEpoch->epochNumber)) - Dtls13SetEpochKeys(ssl, ssl->keys.curEpoch64, DECRYPT_SIDE_ONLY); - + w64Zero(&ssl->keys.curEpoch64); + if (!w64IsZero(ssl->dtls13DecryptEpoch->epochNumber)) + Dtls13SetEpochKeys(ssl, ssl->keys.curEpoch64, DECRYPT_SIDE_ONLY); + } #endif /* WOLFSSL_DTLS13 */ + *inOutIdx += OPAQUE16_LEN; if (ssl->options.haveMcast) { #ifdef WOLFSSL_MULTICAST diff --git a/tests/api.c b/tests/api.c index 5ccee2321..d9958a5a3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -65778,6 +65778,76 @@ static int test_override_alt_cert_chain(void) } #endif +#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) + + +static int test_dtls13_bad_epoch_ch(void) +{ + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + const int EPOCH_OFF = 3; + int ret, err; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method); + if (ret != 0) + return TEST_FAIL; + + /* disable hrr cookie so we can later check msgsReceived.got_client_hello + * with just one message */ + ret = wolfSSL_disable_hrr_cookie(ssl_s); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + if (test_ctx.s_len < EPOCH_OFF + 2) + return TEST_FAIL; + + /* first CH should use epoch 0x0 */ + if (test_ctx.s_buff[EPOCH_OFF] != 0x0 || + test_ctx.s_buff[EPOCH_OFF + 1] != 0x0) + return TEST_FAIL; + + /* change epoch to 2 */ + test_ctx.s_buff[EPOCH_OFF + 1] = 0x2; + + ret = wolfSSL_accept(ssl_s); + err = wolfSSL_get_error(ssl_s, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + if (ssl_s->msgsReceived.got_client_hello == 1) + return TEST_FAIL; + + /* resend the CH */ + ret = wolfSSL_dtls_got_timeout(ssl_c); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + + ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL); + if (ret != 0) + return TEST_FAIL; + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + + return TEST_SUCCESS; +} +#else +static int test_dtls13_bad_epoch_ch(void) +{ + return TEST_SKIPPED; +} +#endif + /*----------------------------------------------------------------------------* | Main @@ -66815,6 +66885,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_extra_alerts_bad_psk), TEST_DECL(test_harden_no_secure_renegotiation), TEST_DECL(test_override_alt_cert_chain), + TEST_DECL(test_dtls13_bad_epoch_ch), /* If at some point a stub get implemented this test should fail indicating * a need to implement a new test case */