Skip to content

Commit c6d6100

Browse files
authored
Merge pull request #7010 from julek-wolfssl/dtls13-0.5-rtt
dtls13: Add support for 0.5-RTT data
2 parents 0ffb586 + e891c72 commit c6d6100

3 files changed

Lines changed: 64 additions & 13 deletions

File tree

src/internal.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19609,7 +19609,8 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
1960919609
return BUFFER_ERROR;
1961019610
}
1961119611
#ifdef WOLFSSL_EARLY_DATA
19612-
if (ssl->earlyData > early_data_ext) {
19612+
if (ssl->options.side == WOLFSSL_SERVER_END &&
19613+
ssl->earlyData > early_data_ext) {
1961319614
if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
1961419615
if (sniff == NO_SNIFF) {
1961519616
SendAlert(ssl, alert_fatal, unexpected_message);
@@ -19649,11 +19650,14 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
1964919650
#endif
1965019651

1965119652
*inOutIdx = idx;
19653+
#ifdef WOLFSSL_DTLS13
19654+
if (ssl->options.connectState == WAIT_FINISHED_ACK) {
19655+
/* DTLS 1.3 is waiting for an ACK but we can still return app data. */
19656+
return APP_DATA_READY;
19657+
}
19658+
#endif
1965219659
#ifdef HAVE_SECURE_RENEGOTIATION
1965319660
if (IsSCR(ssl)) {
19654-
/* Reset the processReply state since
19655-
* we finished processing this message. */
19656-
ssl->options.processReply = doProcessInit;
1965719661
/* If we are in a secure renegotiation then APP DATA is treated
1965819662
* differently */
1965919663
return APP_DATA_READY;
@@ -20246,7 +20250,7 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
2024620250
#endif
2024720251

2024820252
if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE
20249-
#ifdef HAVE_SECURE_RENEGOTIATION
20253+
#if defined(HAVE_SECURE_RENEGOTIATION) || defined(WOLFSSL_DTLS13)
2025020254
&& ssl->error != APP_DATA_READY
2025120255
#endif
2025220256
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -21213,7 +21217,13 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
2121321217
&ssl->buffers.inputBuffer.idx,
2121421218
NO_SNIFF)) != 0) {
2121521219
WOLFSSL_ERROR(ret);
21216-
return ret;
21220+
#if defined(WOLFSSL_DTLS13) || \
21221+
defined(HAVE_SECURE_RENEGOTIATION)
21222+
/* Not really an error. We will return after cleaning
21223+
* up the processReply state. */
21224+
if (ret != APP_DATA_READY)
21225+
#endif
21226+
return ret;
2121721227
}
2121821228
break;
2121921229

@@ -21270,9 +21280,18 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
2127021280
/* input exhausted */
2127121281
if (ssl->buffers.inputBuffer.idx >= ssl->buffers.inputBuffer.length
2127221282
#ifdef WOLFSSL_DTLS
21273-
/* If app data was processed then return now to avoid
21274-
* dropping any app data. */
21275-
|| (ssl->options.dtls && ssl->curRL.type == application_data)
21283+
|| (ssl->options.dtls &&
21284+
/* If app data was processed then return now to avoid
21285+
* dropping any app data. */
21286+
(ssl->curRL.type == application_data ||
21287+
/* client: if we processed a finished message, return to
21288+
* allow higher layers to establish the crypto
21289+
* parameters of the connection. The remaining data
21290+
* may be app data that we would drop without the
21291+
* crypto setup. */
21292+
(ssl->options.side == WOLFSSL_CLIENT_END &&
21293+
ssl->options.serverState == SERVER_FINISHED_COMPLETE &&
21294+
ssl->options.handShakeState != HANDSHAKE_DONE)))
2127621295
#endif
2127721296
) {
2127821297
/* Shrink input buffer when we successfully finish record
@@ -21327,6 +21346,11 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
2132721346
* by higher layers. */
2132821347
if (ret != 0)
2132921348
return ret;
21349+
#endif
21350+
#if defined(WOLFSSL_DTLS13) || defined(HAVE_SECURE_RENEGOTIATION)
21351+
/* Signal to user that we have application data ready to read */
21352+
if (ret == APP_DATA_READY)
21353+
return ret;
2133021354
#endif
2133121355
/* It is safe to shrink the input buffer here now. local vars will
2133221356
* be reset to the new starting value. */
@@ -23598,6 +23622,12 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
2359823622
groupMsgs = 1;
2359923623
#endif
2360023624
}
23625+
else if (IsAtLeastTLSv1_3(ssl->version) &&
23626+
ssl->options.side == WOLFSSL_SERVER_END &&
23627+
ssl->options.acceptState >= TLS13_ACCEPT_FINISHED_SENT) {
23628+
/* We can send data without waiting on peer finished msg */
23629+
WOLFSSL_MSG("server sending data before receiving client finished");
23630+
}
2360123631
else
2360223632
#endif
2360323633
if (ssl->options.handShakeState != HANDSHAKE_DONE && !IsSCR(ssl)) {
@@ -23835,7 +23865,7 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
2383523865
#ifdef WOLFSSL_ASYNC_CRYPT
2383623866
&& ssl->error != WC_PENDING_E
2383723867
#endif
23838-
#ifdef HAVE_SECURE_RENEGOTIATION
23868+
#if defined(HAVE_SECURE_RENEGOTIATION) || defined(WOLFSSL_DTLS13)
2383923869
&& ssl->error != APP_DATA_READY
2384023870
#endif
2384123871
) {

src/ssl.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,14 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
32333233
}
32343234
#endif
32353235
#ifdef WOLFSSL_EARLY_DATA
3236-
if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
3236+
if (IsAtLeastTLSv1_3(ssl->version) &&
3237+
ssl->options.side == WOLFSSL_SERVER_END &&
3238+
ssl->options.acceptState >= TLS13_ACCEPT_FINISHED_SENT) {
3239+
/* We can send data without waiting on peer finished msg */
3240+
WOLFSSL_MSG("server sending data before receiving client finished");
3241+
}
3242+
else if (ssl->earlyData != no_early_data &&
3243+
(ret = wolfSSL_negotiate(ssl)) < 0) {
32373244
ssl->error = ret;
32383245
return WOLFSSL_FATAL_ERROR;
32393246
}

tests/api.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68148,6 +68148,7 @@ static int test_dtls13_early_data(void)
6814868148
char msg[] = "This is early data";
6814968149
char msg2[] = "This is client data";
6815068150
char msg3[] = "This is server data";
68151+
char msg4[] = "This is server immediate data";
6815168152
char msgBuf[50];
6815268153

6815368154
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
@@ -68175,6 +68176,7 @@ static int test_dtls13_early_data(void)
6817568176
ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
6817668177
#endif
6817768178

68179+
/* Test 0-RTT data */
6817868180
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
6817968181
&written), sizeof(msg));
6818068182
ExpectIntEQ(written, sizeof(msg));
@@ -68184,6 +68186,15 @@ static int test_dtls13_early_data(void)
6818468186
ExpectIntEQ(read, sizeof(msg));
6818568187
ExpectStrEQ(msg, msgBuf);
6818668188

68189+
/* Test 0.5-RTT data */
68190+
ExpectIntEQ(wolfSSL_write(ssl_s, msg4, sizeof(msg4)), sizeof(msg4));
68191+
68192+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
68193+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
68194+
68195+
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
68196+
ExpectStrEQ(msg4, msgBuf);
68197+
6818768198
/* Complete handshake */
6818868199
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
6818968200
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
@@ -68195,11 +68206,14 @@ static int test_dtls13_early_data(void)
6819568206
* parsing logic. */
6819668207
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
6819768208
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68198-
&read), WOLFSSL_FAILURE);
68199-
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
68209+
&read), -1);
68210+
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
6820068211

6820168212
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
6820268213

68214+
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
68215+
68216+
6820368217
/* Test bi-directional write */
6820468218
ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
6820568219
ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));

0 commit comments

Comments
 (0)