forked from wolfSSL/wolfssl
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:
@ -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
|
||||
|
@ -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;
|
||||
|
48
src/dtls13.c
48
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;
|
||||
|
@ -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;
|
||||
|
12
src/ssl.c
12
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 */
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
235
tests/api.c
235
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)
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user