diff --git a/configure.ac b/configure.ac index c61505198..68f9752a2 100644 --- a/configure.ac +++ b/configure.ac @@ -8233,6 +8233,7 @@ AM_CONDITIONAL([BUILD_PSA],[test "x$ENABLED_PSA" = "xyes"]) AM_CONDITIONAL([BUILD_DTLS13],[test "x$ENABLED_DTLS13" = "xyes"]) AM_CONDITIONAL([BUILD_QUIC],[test "x$ENABLED_QUIC" = "xyes"]) AM_CONDITIONAL([BUILD_DTLS_CID],[test "x$ENABLED_DTLS_CID" = "xyes"]) +AM_CONDITIONAL([BUILD_DTLS],[test "x$ENABLED_DTLS" = "xyes"]) if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes" && (test "$ax_enable_debug" = "yes" || diff --git a/src/dtls.c b/src/dtls.c index 9b4ec5764..79277b152 100644 --- a/src/dtls.c +++ b/src/dtls.c @@ -24,12 +24,53 @@ #endif #include - -#if defined(WOLFSSL_DTLS_CID) - #include #include #include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#ifdef WOLFSSL_DTLS + +void DtlsResetState(WOLFSSL *ssl) +{ + /* Reset the state so that we can statelessly await the + * ClientHello that contains the cookie. Don't gate on IsAtLeastTLSv1_3 + * to handle the edge case when the peer wants a lower version. */ + +#ifdef WOLFSSL_SEND_HRR_COOKIE + /* Remove cookie so that it will get computed again */ + TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap); +#endif + + /* Reset DTLS window */ +#ifdef WOLFSSL_DTLS13 + w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber); + w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber); + XMEMSET(ssl->dtls13Epochs[0].window, 0, + sizeof(ssl->dtls13Epochs[0].window)); + Dtls13FreeFsmResources(ssl); +#endif + ssl->keys.dtls_expected_peer_handshake_number = 0; + ssl->keys.dtls_handshake_number = 0; + + /* Reset states */ + ssl->options.serverState = NULL_STATE; + ssl->options.clientState = NULL_STATE; + ssl->options.connectState = CONNECT_BEGIN; + ssl->options.acceptState = ACCEPT_BEGIN; + ssl->options.handShakeState = NULL_STATE; + ssl->msgsReceived.got_client_hello = 0; + ssl->keys.dtls_handshake_number = 0; + ssl->keys.dtls_expected_peer_handshake_number = 0; + ssl->options.clientState = 0; +} + +#if defined(WOLFSSL_DTLS_CID) typedef struct ConnectionID { byte length; @@ -382,3 +423,5 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf, } #endif /* WOLFSSL_DTLS_CID */ + +#endif /* WOLFSSL_DTLS */ diff --git a/src/include.am b/src/include.am index 13c8523e5..595247f71 100644 --- a/src/include.am +++ b/src/include.am @@ -747,7 +747,7 @@ if BUILD_QUIC src_libwolfssl_la_SOURCES += src/quic.c endif -if BUILD_DTLS_CID +if BUILD_DTLS src_libwolfssl_la_SOURCES += src/dtls.c endif diff --git a/src/internal.c b/src/internal.c index aef649c80..f66b6f0c3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -30353,14 +30353,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - if (((ssl->keys.dtls_sequence_number_hi == ssl->keys.curSeq_hi && - ssl->keys.dtls_sequence_number_lo < ssl->keys.curSeq_lo) || - (ssl->keys.dtls_sequence_number_hi < ssl->keys.curSeq_hi))) { - /* Server Hello should use the same sequence number as the - * Client Hello if available. */ - ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi; - ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo; - } idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; } @@ -32738,6 +32730,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) { + if (((ssl->keys.dtls_sequence_number_hi == ssl->keys.curSeq_hi && + ssl->keys.dtls_sequence_number_lo < ssl->keys.curSeq_lo) || + (ssl->keys.dtls_sequence_number_hi < ssl->keys.curSeq_hi))) { + /* We should continue with the same sequence number as the + * Client Hello if available. */ + ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi; + ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo; + } + /* We should continue with the same handshake number as the + * Client Hello. */ + ssl->keys.dtls_handshake_number = + ssl->keys.dtls_peer_handshake_number; + #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" #endif /* NO_SHA && NO_SHA256 */ @@ -35000,11 +35005,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], sendSz += MAX_MSG_EXTRA; } - /* reset states */ - ssl->msgsReceived.got_client_hello = 0; - ssl->keys.dtls_handshake_number = 0; - ssl->keys.dtls_expected_peer_handshake_number = 0; - ssl->options.clientState = 0; + /* reset hashes */ ret = InitHandshakeHashes(ssl); if (ret != 0) return ret; @@ -35071,7 +35072,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], } ssl->buffers.outputBuffer.length += sendSz; - DtlsSEQIncrement(ssl, CUR_ORDER); + DtlsResetState(ssl); return SendBuffered(ssl); } diff --git a/src/tls13.c b/src/tls13.c index 6a6bd4042..23b871d81 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -11641,36 +11641,6 @@ const char* wolfSSL_get_cipher_name_by_hash(WOLFSSL* ssl, const char* hash) #ifndef NO_WOLFSSL_SERVER #if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) -static void DtlsResetState(WOLFSSL *ssl) -{ - /* Reset the state so that we can statelessly await the - * ClientHello that contains the cookie. */ - - /* Reset DTLS window */ - w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber); - w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber); - XMEMSET(ssl->dtls13Epochs[0].window, 0, - sizeof(ssl->dtls13Epochs[0].window)); - - ssl->keys.dtls_expected_peer_handshake_number = 0; - ssl->keys.dtls_handshake_number = 0; - - ssl->msgsReceived.got_client_hello = 0; -#ifdef WOLFSSL_SEND_HRR_COOKIE - /* Remove cookie so that it will get computed again */ - TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap); -#endif - - /* Reset states */ - ssl->options.serverState = NULL_STATE; - ssl->options.clientState = NULL_STATE; - ssl->options.connectState = CONNECT_BEGIN; - ssl->options.acceptState = ACCEPT_BEGIN; - ssl->options.handShakeState = NULL_STATE; - - Dtls13FreeFsmResources(ssl); -} - static int DtlsAcceptStateless(WOLFSSL *ssl) { int ret; diff --git a/tests/api.c b/tests/api.c index 1032067c3..9602268d6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -56340,7 +56340,7 @@ static int test_wolfSSL_dtls_AEAD_limit(void) } #endif -#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) && \ +#if defined(WOLFSSL_DTLS) && \ defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) static void test_wolfSSL_dtls_send_ch(WOLFSSL* ssl) { @@ -56396,36 +56396,57 @@ static void test_wolfSSL_dtls_send_ch(WOLFSSL* ssl) ret = (int)send(fd, ch_msg, sizeof(ch_msg), 0); AssertIntGT(ret, 0); /* consume the HRR otherwise handshake will fail */ - ret = recv(fd, ch_msg, sizeof(ch_msg), 0); + ret = (int)recv(fd, ch_msg, sizeof(ch_msg), 0); AssertIntGT(ret, 0); } +#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) static void test_wolfSSL_dtls_enable_hrrcookie(WOLFSSL* ssl) { int ret; ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0); AssertIntEQ(ret, WOLFSSL_SUCCESS); } +#endif static int test_wolfSSL_dtls_stateless(void) { callback_functions client_cbs, server_cbs; + size_t i; + struct { + method_provider client_meth; + method_provider server_meth; + ssl_callback client_ssl_ready; + ssl_callback server_ssl_ready; + } test_params[] = { + {wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, + test_wolfSSL_dtls_send_ch, NULL}, +#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) + {wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, + test_wolfSSL_dtls_send_ch, test_wolfSSL_dtls_enable_hrrcookie}, +#endif + }; - XMEMSET(&client_cbs, 0, sizeof(client_cbs)); - XMEMSET(&server_cbs, 0, sizeof(server_cbs)); - client_cbs.doUdp = server_cbs.doUdp = 1; - client_cbs.method = wolfDTLSv1_3_client_method; - server_cbs.method = wolfDTLSv1_3_server_method; + printf(testingFmt, "test_wolfSSL_dtls_stateless"); - client_cbs.ssl_ready = test_wolfSSL_dtls_send_ch; - server_cbs.ssl_ready = test_wolfSSL_dtls_enable_hrrcookie; - test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + for (i = 0; i < sizeof(test_params)/sizeof(*test_params); i++) { + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + client_cbs.doUdp = server_cbs.doUdp = 1; + client_cbs.method = test_params[i].client_meth; + server_cbs.method = test_params[i].server_meth; - if (!client_cbs.return_code) - return -1; - if (!server_cbs.return_code) - return -1; + client_cbs.ssl_ready = test_params[i].client_ssl_ready; + server_cbs.ssl_ready = test_params[i].server_ssl_ready; + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + if (!client_cbs.return_code) + return -1; + if (!server_cbs.return_code) + return -1; + } + + printf(resultFmt, passed); return 0; } #else diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0d6f8de42..4e186e14c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5798,6 +5798,7 @@ WOLFSSL_LOCAL word32 nid2oid(int nid, int grp); #ifdef WOLFSSL_DTLS WOLFSSL_API int wolfSSL_DtlsUpdateWindow(word16 cur_hi, word32 cur_lo, word16* next_hi, word32* next_lo, word32 *window); +WOLFSSL_LOCAL void DtlsResetState(WOLFSSL *ssl); #endif #ifdef WOLFSSL_DTLS13