diff --git a/async-check.sh b/async-check.sh index 206fd4ff6..5a0246940 100755 --- a/async-check.sh +++ b/async-check.sh @@ -91,7 +91,7 @@ set -e if [ -d ./async ]; then - echo "\n\nUsing existing async repo\n\n" + echo "Using existing async repo" else # make a clone of the wolfAsyncCrypt repository git clone --depth 1 $ASYNC_REPO async diff --git a/src/dtls.c b/src/dtls.c index 83b3dd252..c207f33fe 100644 --- a/src/dtls.c +++ b/src/dtls.c @@ -75,6 +75,7 @@ void DtlsResetState(WOLFSSL* ssl) ssl->options.connectState = CONNECT_BEGIN; ssl->options.acceptState = ACCEPT_BEGIN; ssl->options.handShakeState = NULL_STATE; + ssl->options.seenUnifiedHdr = 0; ssl->msgsReceived.got_client_hello = 0; ssl->keys.dtls_handshake_number = 0; ssl->keys.dtls_expected_peer_handshake_number = 0; diff --git a/src/dtls13.c b/src/dtls13.c index 1d810a872..cd84f27d6 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -352,6 +352,7 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl) WOLFSSL_ENTER("Dtls13ProcessBufferedMessages"); while (msg != NULL) { + int downgraded = 0; idx = 0; /* message not in order */ @@ -362,8 +363,18 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl) if (!msg->ready) break; - ret = DoTls13HandShakeMsgType(ssl, msg->fullMsg, &idx, msg->type, - msg->sz, msg->sz); + /* We may have DTLS <=1.2 msgs stored from before we knew which version + * we were going to use. Interpret correctly. */ + if (IsAtLeastTLSv1_3(ssl->version)) { + ret = DoTls13HandShakeMsgType(ssl, msg->fullMsg, &idx, msg->type, + msg->sz, msg->sz); + if (!IsAtLeastTLSv1_3(ssl->version)) + downgraded = 1; + } + else { + ret = DoHandShakeMsgType(ssl, msg->fullMsg, &idx, msg->type, + msg->sz, msg->sz); + } /* processing certificate_request triggers a connect. The error came * from there, the message can be considered processed successfully. @@ -371,7 +382,13 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl) * waiting to flush the output buffer. */ if ((ret == 0 || ret == WANT_WRITE) || (msg->type == certificate_request && ssl->options.handShakeDone && ret == WC_PENDING_E)) { - Dtls13MsgWasProcessed(ssl, (enum HandShakeType)msg->type); + if (IsAtLeastTLSv1_3(ssl->version)) + Dtls13MsgWasProcessed(ssl, (enum HandShakeType)msg->type); + else if (downgraded) + /* DoHandShakeMsgType normally handles the hs number but if + * DoTls13HandShakeMsgType processed 1.2 msgs then this wasn't + * incremented. */ + ssl->keys.dtls_expected_peer_handshake_number++; ssl->dtls_rx_msg_list = msg->next; DtlsMsgDelete(msg, ssl->heap); @@ -625,7 +642,7 @@ static void Dtls13RtxRecordUnlink(WOLFSSL* ssl, Dtls13RtxRecord** prevNext, *prevNext = r->next; } -static void Dtls13RtxFlushBuffered(WOLFSSL* ssl, byte keepNewSessionTicket) +void Dtls13RtxFlushBuffered(WOLFSSL* ssl, byte keepNewSessionTicket) { Dtls13RtxRecord *r, **prevNext; @@ -806,10 +823,16 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs, Dtls13MaybeSaveClientHello(ssl); /* In the handshake, receiving part of the next flight, acknowledge the - sent flight. The only exception is, on the server side, receiving the - last client flight does not ACK any sent new_session_ticket - messages. */ - Dtls13RtxFlushBuffered(ssl, 1); + * sent flight. */ + /* On the server side, receiving the last client flight does not ACK any + * sent new_session_ticket messages. */ + /* We don't want to clear the buffer until we have done version + * negotiation in the SH or have received a unified header in the + * DTLS record. */ + if (ssl->options.serverState >= SERVER_HELLO_COMPLETE || + ssl->options.seenUnifiedHdr) + /* Use 1.2 API to clear 1.2 buffers too */ + DtlsMsgPoolReset(ssl); } if (ssl->keys.dtls_peer_handshake_number < @@ -853,6 +876,8 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs, void Dtls13FreeFsmResources(WOLFSSL* ssl) { Dtls13RtxFlushAcks(ssl); + /* Use 1.2 API to clear 1.2 buffers too */ + DtlsMsgPoolReset(ssl); Dtls13RtxFlushBuffered(ssl, 0); } @@ -2471,7 +2496,12 @@ int Dtls13RtxTimeout(WOLFSSL* ssl) { int ret = 0; - if (ssl->dtls13Rtx.seenRecords != NULL) { + /* We don't want to send acks until we have done version + * negotiation in the SH or have received a unified header in the + * DTLS record. */ + if (ssl->dtls13Rtx.seenRecords != NULL && + (ssl->options.serverState >= SERVER_HELLO_COMPLETE || + ssl->options.seenUnifiedHdr)) { ssl->dtls13Rtx.sendAcks = 0; /* reset fast timeout as we are sending ACKs */ ssl->dtls13FastTimeout = 0; diff --git a/src/internal.c b/src/internal.c index ac6e58d62..722355090 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9185,6 +9185,10 @@ void DtlsMsgPoolReset(WOLFSSL* ssl) ssl->dtls_tx_msg = NULL; ssl->dtls_tx_msg_list_sz = 0; } +#ifdef WOLFSSL_DTLS13 + /* Clear DTLS 1.3 buffer too */ + Dtls13RtxFlushBuffered(ssl, 1); +#endif } @@ -10740,6 +10744,7 @@ static int GetDtlsRecordHeader(WOLFSSL* ssl, word32* inOutIdx, int ret; if (Dtls13IsUnifiedHeader(*(ssl->buffers.inputBuffer.buffer + *inOutIdx))) { + ssl->options.seenUnifiedHdr = 1; /* We can send ACKs to the peer */ /* version 1.3 already negotiated */ if (ssl->options.tls1_3) { @@ -15678,6 +15683,12 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E); return DUPLICATE_MSG_E; } + if (ssl->msgsReceived.got_hello_retry_request) { + WOLFSSL_MSG("Received HelloVerifyRequest after a " + "HelloRetryRequest"); + WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); + return VERSION_ERROR; + } ssl->msgsReceived.got_hello_verify_request = 1; break; @@ -16050,7 +16061,7 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) } -static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, +int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, byte type, word32 size, word32 totalSz) { int ret = 0; diff --git a/src/ssl.c b/src/ssl.c index 94f70e35a..24e79a2bc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12447,7 +12447,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return WOLFSSL_FATAL_ERROR; } /* if resumption failed, reset needed state */ - else if (neededState == SERVER_FINISHED_COMPLETE) + else if (neededState == SERVER_FINISHED_COMPLETE) { if (!ssl->options.resuming) { #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) @@ -12456,17 +12456,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif neededState = SERVER_HELLODONE_COMPLETE; } -#ifdef WOLFSSL_DTLS13 + } +#ifdef WOLFSSL_DTLS13 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version) - && ssl->dtls13Rtx.sendAcks == 1) { - ssl->dtls13Rtx.sendAcks = 0; + && ssl->dtls13Rtx.sendAcks == 1 + && ssl->options.seenUnifiedHdr) { /* we aren't negotiated the version yet, so we aren't sure * the other end can speak v1.3. On the other side we have * received a unified records, assuming that the * ServerHello got lost, we will send an empty ACK. In case * the server is a DTLS with version less than 1.3, it * should just ignore the message */ + ssl->dtls13Rtx.sendAcks = 0; if ((ssl->error = SendDtls13Ack(ssl)) < 0) { if (ssl->error == WANT_WRITE) ssl->dtls13SendingAckOrRtx = 1; @@ -12474,8 +12476,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return WOLFSSL_FATAL_ERROR; } } - - #endif /* WOLFSSL_DTLS13 */ } diff --git a/src/tls13.c b/src/tls13.c index 87f7e651b..9d668ecd3 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5088,6 +5088,13 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_MSG("HelloRetryRequest format"); *extMsgType = hello_retry_request; + if (ssl->msgsReceived.got_hello_verify_request) { + WOLFSSL_MSG("Received HelloRetryRequest after a " + "HelloVerifyRequest"); + WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); + return VERSION_ERROR; + } + /* A HelloRetryRequest comes in as an ServerHello for MiddleBox compat. * Found message to be a HelloRetryRequest. * Don't allow more than one HelloRetryRequest or ServerHello. diff --git a/tests/api.c b/tests/api.c index 912318f1a..9579f9076 100644 --- a/tests/api.c +++ b/tests/api.c @@ -5597,7 +5597,7 @@ static WC_INLINE int test_ssl_memio_write_cb(WOLFSSL *ssl, char *data, int sz, } if ((unsigned)(*len + sz) > TEST_SSL_MEMIO_BUF_SZ) - return WOLFSSL_CBIO_ERR_WANT_READ; + return WOLFSSL_CBIO_ERR_WANT_WRITE; XMEMCPY(buf + *len, data, sz); *len += sz; @@ -64662,6 +64662,237 @@ static int test_dtls_downgrade_scr(void) } #endif +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) +static int test_dtls_client_hello_timeout_downgrade_read_cb(WOLFSSL *ssl, + char *data, int sz, void *ctx) +{ + static int call_counter = 0; + call_counter++; + (void)ssl; + (void)data; + (void)sz; + (void)ctx; + switch (call_counter) { + case 1: + case 2: + return WOLFSSL_CBIO_ERR_TIMEOUT; + case 3: + return WOLFSSL_CBIO_ERR_WANT_READ; + default: + AssertIntLE(call_counter, 3); + return -1; + } +} +#endif + +/* Make sure we don't send acks before getting a server hello */ +static int test_dtls_client_hello_timeout_downgrade(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) + WOLFSSL_CTX *ctx_c = NULL; + WOLFSSL_CTX *ctx_s = NULL; + WOLFSSL *ssl_c = NULL; + WOLFSSL *ssl_s = NULL; + struct test_memio_ctx test_ctx; + DtlsRecordLayerHeader* dtlsRH; + size_t len; + byte sequence_number[8]; + int i; + + for (i = 0; i < 2; i++) { + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfDTLS_client_method, wolfDTLSv1_2_server_method), 0); + + if (i == 0) { + /* First time simulate timeout in IO layer */ + /* CH1 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + /* HVR */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + /* CH2 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + /* SH flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + /* Drop the SH */ + dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.c_buff); + len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]); + XMEMMOVE(test_ctx.c_buff, test_ctx.c_buff + + sizeof(DtlsRecordLayerHeader) + len, test_ctx.c_len - + (sizeof(DtlsRecordLayerHeader) + len)); + test_ctx.c_len -= sizeof(DtlsRecordLayerHeader) + len; + /* Read the remainder of the flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + wolfSSL_SSLSetIORecv(ssl_c, + test_dtls_client_hello_timeout_downgrade_read_cb); + /* CH3 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + wolfSSL_SSLSetIORecv(ssl_c, test_memio_read_cb); + } + else { + /* Second time call wolfSSL_dtls_got_timeout */ + /* CH1 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + /* HVR */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + /* CH2 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + /* SH flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + /* Drop the SH */ + dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.c_buff); + len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]); + XMEMMOVE(test_ctx.c_buff, test_ctx.c_buff + + sizeof(DtlsRecordLayerHeader) + len, test_ctx.c_len - + (sizeof(DtlsRecordLayerHeader) + len)); + test_ctx.c_len -= sizeof(DtlsRecordLayerHeader) + len; + /* Read the remainder of the flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + /* Quick timeout should be set as we received at least one msg */ + ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 1); + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS); + /* Quick timeout should be cleared after a quick timeout */ + /* CH3 */ + ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 0); + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS); + } + + /* Parse out to make sure we got exactly one ClientHello message */ + XMEMSET(&sequence_number, 0, sizeof(sequence_number)); + /* Second ClientHello after HVR */ + sequence_number[7] = 2; + dtlsRH = (DtlsRecordLayerHeader*)test_ctx.s_buff; + ExpectIntEQ(dtlsRH->type, handshake); + ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR); + ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR); + ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number, + sizeof(sequence_number)), 0); + len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]); + ExpectIntEQ(sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len); + + /* Connection should be able to continue */ + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); + ssl_c = NULL; + ssl_s = NULL; + ctx_c = NULL; + ctx_s = NULL; + if (!EXPECT_SUCCESS()) + break; + } + +#endif + return EXPECT_RESULT(); +} + +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) +static int test_dtls_client_hello_timeout_read_cb(WOLFSSL *ssl, char *data, + int sz, void *ctx) +{ + static int call_counter = 0; + call_counter++; + (void)ssl; + (void)data; + (void)sz; + (void)ctx; + switch (call_counter) { + case 1: + return WOLFSSL_CBIO_ERR_TIMEOUT; + case 2: + return WOLFSSL_CBIO_ERR_WANT_READ; + default: + AssertIntLE(call_counter, 2); + return -1; + } +} +#endif + +/* Make sure we don't send acks before getting a server hello */ +static int test_dtls_client_hello_timeout(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) + WOLFSSL *ssl_c = NULL; + WOLFSSL_CTX *ctx_c = NULL; + struct test_memio_ctx test_ctx; + DtlsRecordLayerHeader* dtlsRH; + size_t idx; + size_t len; + byte sequence_number[8]; + int i; + + for (i = 0; i < 2; i++) { + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL, + wolfDTLSv1_3_client_method, NULL), 0); + + if (i == 0) { + /* First time simulate timeout in IO layer */ + wolfSSL_SSLSetIORecv(ssl_c, test_dtls_client_hello_timeout_read_cb); + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + } + else { + /* Second time call wolfSSL_dtls_got_timeout */ + ExpectIntEQ(wolfSSL_connect(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS); + } + + /* Parse out to make sure we got exactly two ClientHello messages */ + idx = 0; + XMEMSET(&sequence_number, 0, sizeof(sequence_number)); + /* First ClientHello */ + dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx); + ExpectIntEQ(dtlsRH->type, handshake); + ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR); + ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR); + ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number, + sizeof(sequence_number)), 0); + len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]); + ExpectIntLT(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len); + idx += sizeof(DtlsRecordLayerHeader) + len; + /* Second ClientHello */ + sequence_number[7] = 1; + dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx); + ExpectIntEQ(dtlsRH->type, handshake); + ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR); + ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR); + ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number, + sizeof(sequence_number)), 0); + len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]); + ExpectIntEQ(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len); + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + ssl_c = NULL; + ctx_c = NULL; + if (!EXPECT_SUCCESS()) + break; + } + +#endif + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -65922,6 +66153,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_session_ticket_hs_update), TEST_DECL(test_dtls_downgrade_scr_server), TEST_DECL(test_dtls_downgrade_scr), + TEST_DECL(test_dtls_client_hello_timeout_downgrade), + TEST_DECL(test_dtls_client_hello_timeout), /* This test needs to stay at the end to clean up any caches allocated. */ TEST_DECL(test_wolfSSL_Cleanup) }; diff --git a/tests/utils.h b/tests/utils.h index c54633d1c..e7dcaa790 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -119,6 +119,17 @@ cleanup: /* This set of memio functions allows for more fine tuned control of the TLS * connection operations. For new tests, try to use ssl_memio first. */ +/* To dump the memory in gdb use + * dump memory client.bin test_ctx.c_buff test_ctx.c_buff+test_ctx.c_len + * dump memory server.bin test_ctx.s_buff test_ctx.s_buff+test_ctx.s_len + * This can be imported into Wireshark by transforming the file with + * od -Ax -tx1 -v client.bin > client.bin.hex + * od -Ax -tx1 -v server.bin > server.bin.hex + * And then loading test_output.dump.hex into Wireshark using the + * "Import from Hex Dump..." option ion and selecting the TCP + * encapsulation option. + */ + #define HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES #define TEST_MEMIO_BUF_SZ (64 * 1024) @@ -157,7 +168,7 @@ static WC_INLINE int test_memio_write_cb(WOLFSSL *ssl, char *data, int sz, } if ((unsigned)(*len + sz) > TEST_MEMIO_BUF_SZ) - return WOLFSSL_CBIO_ERR_WANT_READ; + return WOLFSSL_CBIO_ERR_WANT_WRITE; XMEMCPY(buf + *len, data, sz); *len += sz; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4cd593185..c7777b5f2 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2135,6 +2135,9 @@ WOLFSSL_LOCAL void InitSSL_CTX_Suites(WOLFSSL_CTX* ctx); WOLFSSL_LOCAL int InitSSL_Suites(WOLFSSL* ssl); WOLFSSL_LOCAL int InitSSL_Side(WOLFSSL* ssl, word16 side); + +WOLFSSL_LOCAL int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, + word32* inOutIdx, byte type, word32 size, word32 totalSz); /* for sniffer */ WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, word32 totalSz, int sniff); @@ -4607,6 +4610,7 @@ struct Options { word16 tls:1; /* using TLS ? */ word16 tls1_1:1; /* using TLSv1.1+ ? */ word16 tls1_3:1; /* using TLSv1.3+ ? */ + word16 seenUnifiedHdr:1; /* received msg with unified header */ word16 dtls:1; /* using datagrams ? */ word16 dtlsStateful:1; /* allow stateful processing ? */ word16 connReset:1; /* has the peer reset */ @@ -6532,6 +6536,8 @@ WOLFSSL_LOCAL int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, WOLFSSL_LOCAL int Dtls13HashClientHello(const WOLFSSL* ssl, byte* hash, int* hashSz, const byte* body, word32 length, CipherSpecs* specs); WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl); +WOLFSSL_LOCAL void Dtls13RtxFlushBuffered(WOLFSSL* ssl, + byte keepNewSessionTicket); WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl); WOLFSSL_LOCAL int Dtls13ProcessBufferedMessages(WOLFSSL* ssl); WOLFSSL_LOCAL int Dtls13CheckAEADFailLimit(WOLFSSL* ssl);