Merge pull request #6700 from julek-wolfssl/dtls13-downgrade-acks

DTLS 1.3: do not send ACKs until we negotiate 1.3 (through SH)
This commit is contained in:
JacobBarthelmeh
2023-08-25 09:34:53 -06:00
committed by GitHub
9 changed files with 318 additions and 19 deletions

View File

@@ -91,7 +91,7 @@ set -e
if [ -d ./async ]; if [ -d ./async ];
then then
echo "\n\nUsing existing async repo\n\n" echo "Using existing async repo"
else else
# make a clone of the wolfAsyncCrypt repository # make a clone of the wolfAsyncCrypt repository
git clone --depth 1 $ASYNC_REPO async git clone --depth 1 $ASYNC_REPO async

View File

@@ -75,6 +75,7 @@ void DtlsResetState(WOLFSSL* ssl)
ssl->options.connectState = CONNECT_BEGIN; ssl->options.connectState = CONNECT_BEGIN;
ssl->options.acceptState = ACCEPT_BEGIN; ssl->options.acceptState = ACCEPT_BEGIN;
ssl->options.handShakeState = NULL_STATE; ssl->options.handShakeState = NULL_STATE;
ssl->options.seenUnifiedHdr = 0;
ssl->msgsReceived.got_client_hello = 0; ssl->msgsReceived.got_client_hello = 0;
ssl->keys.dtls_handshake_number = 0; ssl->keys.dtls_handshake_number = 0;
ssl->keys.dtls_expected_peer_handshake_number = 0; ssl->keys.dtls_expected_peer_handshake_number = 0;

View File

@@ -352,6 +352,7 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
WOLFSSL_ENTER("Dtls13ProcessBufferedMessages"); WOLFSSL_ENTER("Dtls13ProcessBufferedMessages");
while (msg != NULL) { while (msg != NULL) {
int downgraded = 0;
idx = 0; idx = 0;
/* message not in order */ /* message not in order */
@@ -362,8 +363,18 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
if (!msg->ready) if (!msg->ready)
break; break;
/* 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, ret = DoTls13HandShakeMsgType(ssl, msg->fullMsg, &idx, msg->type,
msg->sz, msg->sz); 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 /* processing certificate_request triggers a connect. The error came
* from there, the message can be considered processed successfully. * from there, the message can be considered processed successfully.
@@ -371,7 +382,13 @@ int Dtls13ProcessBufferedMessages(WOLFSSL* ssl)
* waiting to flush the output buffer. */ * waiting to flush the output buffer. */
if ((ret == 0 || ret == WANT_WRITE) || (msg->type == certificate_request && if ((ret == 0 || ret == WANT_WRITE) || (msg->type == certificate_request &&
ssl->options.handShakeDone && ret == WC_PENDING_E)) { ssl->options.handShakeDone && ret == WC_PENDING_E)) {
if (IsAtLeastTLSv1_3(ssl->version))
Dtls13MsgWasProcessed(ssl, (enum HandShakeType)msg->type); 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; ssl->dtls_rx_msg_list = msg->next;
DtlsMsgDelete(msg, ssl->heap); DtlsMsgDelete(msg, ssl->heap);
@@ -625,7 +642,7 @@ static void Dtls13RtxRecordUnlink(WOLFSSL* ssl, Dtls13RtxRecord** prevNext,
*prevNext = r->next; *prevNext = r->next;
} }
static void Dtls13RtxFlushBuffered(WOLFSSL* ssl, byte keepNewSessionTicket) void Dtls13RtxFlushBuffered(WOLFSSL* ssl, byte keepNewSessionTicket)
{ {
Dtls13RtxRecord *r, **prevNext; Dtls13RtxRecord *r, **prevNext;
@@ -806,10 +823,16 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
Dtls13MaybeSaveClientHello(ssl); Dtls13MaybeSaveClientHello(ssl);
/* In the handshake, receiving part of the next flight, acknowledge the /* In the handshake, receiving part of the next flight, acknowledge the
sent flight. The only exception is, on the server side, receiving the * sent flight. */
last client flight does not ACK any sent new_session_ticket /* On the server side, receiving the last client flight does not ACK any
messages. */ * sent new_session_ticket messages. */
Dtls13RtxFlushBuffered(ssl, 1); /* 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 < if (ssl->keys.dtls_peer_handshake_number <
@@ -853,6 +876,8 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
void Dtls13FreeFsmResources(WOLFSSL* ssl) void Dtls13FreeFsmResources(WOLFSSL* ssl)
{ {
Dtls13RtxFlushAcks(ssl); Dtls13RtxFlushAcks(ssl);
/* Use 1.2 API to clear 1.2 buffers too */
DtlsMsgPoolReset(ssl);
Dtls13RtxFlushBuffered(ssl, 0); Dtls13RtxFlushBuffered(ssl, 0);
} }
@@ -2471,7 +2496,12 @@ int Dtls13RtxTimeout(WOLFSSL* ssl)
{ {
int ret = 0; 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; ssl->dtls13Rtx.sendAcks = 0;
/* reset fast timeout as we are sending ACKs */ /* reset fast timeout as we are sending ACKs */
ssl->dtls13FastTimeout = 0; ssl->dtls13FastTimeout = 0;

View File

@@ -9185,6 +9185,10 @@ void DtlsMsgPoolReset(WOLFSSL* ssl)
ssl->dtls_tx_msg = NULL; ssl->dtls_tx_msg = NULL;
ssl->dtls_tx_msg_list_sz = 0; 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; int ret;
if (Dtls13IsUnifiedHeader(*(ssl->buffers.inputBuffer.buffer + *inOutIdx))) { if (Dtls13IsUnifiedHeader(*(ssl->buffers.inputBuffer.buffer + *inOutIdx))) {
ssl->options.seenUnifiedHdr = 1; /* We can send ACKs to the peer */
/* version 1.3 already negotiated */ /* version 1.3 already negotiated */
if (ssl->options.tls1_3) { if (ssl->options.tls1_3) {
@@ -15678,6 +15683,12 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E); WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
return 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; ssl->msgsReceived.got_hello_verify_request = 1;
break; 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) byte type, word32 size, word32 totalSz)
{ {
int ret = 0; int ret = 0;

View File

@@ -12447,7 +12447,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
/* if resumption failed, reset needed state */ /* if resumption failed, reset needed state */
else if (neededState == SERVER_FINISHED_COMPLETE) else if (neededState == SERVER_FINISHED_COMPLETE) {
if (!ssl->options.resuming) { if (!ssl->options.resuming) {
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) if (IsDtlsNotSctpMode(ssl))
@@ -12456,17 +12456,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
#endif #endif
neededState = SERVER_HELLODONE_COMPLETE; neededState = SERVER_HELLODONE_COMPLETE;
} }
#ifdef WOLFSSL_DTLS13 }
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version) if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
&& ssl->dtls13Rtx.sendAcks == 1) { && ssl->dtls13Rtx.sendAcks == 1
ssl->dtls13Rtx.sendAcks = 0; && ssl->options.seenUnifiedHdr) {
/* we aren't negotiated the version yet, so we aren't sure /* 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 * the other end can speak v1.3. On the other side we have
* received a unified records, assuming that the * received a unified records, assuming that the
* ServerHello got lost, we will send an empty ACK. In case * ServerHello got lost, we will send an empty ACK. In case
* the server is a DTLS with version less than 1.3, it * the server is a DTLS with version less than 1.3, it
* should just ignore the message */ * should just ignore the message */
ssl->dtls13Rtx.sendAcks = 0;
if ((ssl->error = SendDtls13Ack(ssl)) < 0) { if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
if (ssl->error == WANT_WRITE) if (ssl->error == WANT_WRITE)
ssl->dtls13SendingAckOrRtx = 1; ssl->dtls13SendingAckOrRtx = 1;
@@ -12474,8 +12476,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
} }
#endif /* WOLFSSL_DTLS13 */ #endif /* WOLFSSL_DTLS13 */
} }

View File

@@ -5088,6 +5088,13 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG("HelloRetryRequest format"); WOLFSSL_MSG("HelloRetryRequest format");
*extMsgType = hello_retry_request; *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. /* A HelloRetryRequest comes in as an ServerHello for MiddleBox compat.
* Found message to be a HelloRetryRequest. * Found message to be a HelloRetryRequest.
* Don't allow more than one HelloRetryRequest or ServerHello. * Don't allow more than one HelloRetryRequest or ServerHello.

View File

@@ -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) 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); XMEMCPY(buf + *len, data, sz);
*len += sz; *len += sz;
@@ -64662,6 +64662,237 @@ static int test_dtls_downgrade_scr(void)
} }
#endif #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 | Main
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@@ -65922,6 +66153,8 @@ TEST_CASE testCases[] = {
TEST_DECL(test_session_ticket_hs_update), TEST_DECL(test_session_ticket_hs_update),
TEST_DECL(test_dtls_downgrade_scr_server), TEST_DECL(test_dtls_downgrade_scr_server),
TEST_DECL(test_dtls_downgrade_scr), 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. */ /* This test needs to stay at the end to clean up any caches allocated. */
TEST_DECL(test_wolfSSL_Cleanup) TEST_DECL(test_wolfSSL_Cleanup)
}; };

View File

@@ -119,6 +119,17 @@ cleanup:
/* This set of memio functions allows for more fine tuned control of the TLS /* 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. */ * 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 HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES
#define TEST_MEMIO_BUF_SZ (64 * 1024) #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) 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); XMEMCPY(buf + *len, data, sz);
*len += sz; *len += sz;

View File

@@ -2135,6 +2135,9 @@ WOLFSSL_LOCAL void InitSSL_CTX_Suites(WOLFSSL_CTX* ctx);
WOLFSSL_LOCAL int InitSSL_Suites(WOLFSSL* ssl); WOLFSSL_LOCAL int InitSSL_Suites(WOLFSSL* ssl);
WOLFSSL_LOCAL int InitSSL_Side(WOLFSSL* ssl, word16 side); 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 */ /* for sniffer */
WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 size, word32 totalSz, int sniff); word32 size, word32 totalSz, int sniff);
@@ -4607,6 +4610,7 @@ struct Options {
word16 tls:1; /* using TLS ? */ word16 tls:1; /* using TLS ? */
word16 tls1_1:1; /* using TLSv1.1+ ? */ word16 tls1_1:1; /* using TLSv1.1+ ? */
word16 tls1_3:1; /* using TLSv1.3+ ? */ word16 tls1_3:1; /* using TLSv1.3+ ? */
word16 seenUnifiedHdr:1; /* received msg with unified header */
word16 dtls:1; /* using datagrams ? */ word16 dtls:1; /* using datagrams ? */
word16 dtlsStateful:1; /* allow stateful processing ? */ word16 dtlsStateful:1; /* allow stateful processing ? */
word16 connReset:1; /* has the peer reset */ 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, WOLFSSL_LOCAL int Dtls13HashClientHello(const WOLFSSL* ssl, byte* hash,
int* hashSz, const byte* body, word32 length, CipherSpecs* specs); int* hashSz, const byte* body, word32 length, CipherSpecs* specs);
WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl); WOLFSSL_LOCAL void Dtls13FreeFsmResources(WOLFSSL* ssl);
WOLFSSL_LOCAL void Dtls13RtxFlushBuffered(WOLFSSL* ssl,
byte keepNewSessionTicket);
WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl); WOLFSSL_LOCAL int Dtls13RtxTimeout(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13ProcessBufferedMessages(WOLFSSL* ssl); WOLFSSL_LOCAL int Dtls13ProcessBufferedMessages(WOLFSSL* ssl);
WOLFSSL_LOCAL int Dtls13CheckAEADFailLimit(WOLFSSL* ssl); WOLFSSL_LOCAL int Dtls13CheckAEADFailLimit(WOLFSSL* ssl);