Merge pull request #7010 from julek-wolfssl/dtls13-0.5-rtt

dtls13: Add support for 0.5-RTT data
This commit is contained in:
Sean Parkinson
2023-12-07 08:41:42 +10:00
committed by GitHub
3 changed files with 64 additions and 13 deletions

View File

@@ -19609,7 +19609,8 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
return BUFFER_ERROR;
}
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData > early_data_ext) {
if (ssl->options.side == WOLFSSL_SERVER_END &&
ssl->earlyData > early_data_ext) {
if (ssl->earlyDataSz + dataSz > ssl->options.maxEarlyDataSz) {
if (sniff == NO_SNIFF) {
SendAlert(ssl, alert_fatal, unexpected_message);
@@ -19649,11 +19650,14 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
#endif
*inOutIdx = idx;
#ifdef WOLFSSL_DTLS13
if (ssl->options.connectState == WAIT_FINISHED_ACK) {
/* DTLS 1.3 is waiting for an ACK but we can still return app data. */
return APP_DATA_READY;
}
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (IsSCR(ssl)) {
/* Reset the processReply state since
* we finished processing this message. */
ssl->options.processReply = doProcessInit;
/* If we are in a secure renegotiation then APP DATA is treated
* differently */
return APP_DATA_READY;
@@ -20246,7 +20250,7 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
#endif
if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE
#ifdef HAVE_SECURE_RENEGOTIATION
#if defined(HAVE_SECURE_RENEGOTIATION) || defined(WOLFSSL_DTLS13)
&& ssl->error != APP_DATA_READY
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -21213,7 +21217,13 @@ default:
&ssl->buffers.inputBuffer.idx,
NO_SNIFF)) != 0) {
WOLFSSL_ERROR(ret);
return ret;
#if defined(WOLFSSL_DTLS13) || \
defined(HAVE_SECURE_RENEGOTIATION)
/* Not really an error. We will return after cleaning
* up the processReply state. */
if (ret != APP_DATA_READY)
#endif
return ret;
}
break;
@@ -21270,9 +21280,18 @@ default:
/* input exhausted */
if (ssl->buffers.inputBuffer.idx >= ssl->buffers.inputBuffer.length
#ifdef WOLFSSL_DTLS
/* If app data was processed then return now to avoid
* dropping any app data. */
|| (ssl->options.dtls && ssl->curRL.type == application_data)
|| (ssl->options.dtls &&
/* If app data was processed then return now to avoid
* dropping any app data. */
(ssl->curRL.type == application_data ||
/* client: if we processed a finished message, return to
* allow higher layers to establish the crypto
* parameters of the connection. The remaining data
* may be app data that we would drop without the
* crypto setup. */
(ssl->options.side == WOLFSSL_CLIENT_END &&
ssl->options.serverState == SERVER_FINISHED_COMPLETE &&
ssl->options.handShakeState != HANDSHAKE_DONE)))
#endif
) {
/* Shrink input buffer when we successfully finish record
@@ -21327,6 +21346,11 @@ default:
* by higher layers. */
if (ret != 0)
return ret;
#endif
#if defined(WOLFSSL_DTLS13) || defined(HAVE_SECURE_RENEGOTIATION)
/* Signal to user that we have application data ready to read */
if (ret == APP_DATA_READY)
return ret;
#endif
/* It is safe to shrink the input buffer here now. local vars will
* be reset to the new starting value. */
@@ -23598,6 +23622,12 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
groupMsgs = 1;
#endif
}
else if (IsAtLeastTLSv1_3(ssl->version) &&
ssl->options.side == WOLFSSL_SERVER_END &&
ssl->options.acceptState >= TLS13_ACCEPT_FINISHED_SENT) {
/* We can send data without waiting on peer finished msg */
WOLFSSL_MSG("server sending data before receiving client finished");
}
else
#endif
if (ssl->options.handShakeState != HANDSHAKE_DONE && !IsSCR(ssl)) {
@@ -23835,7 +23865,7 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
#ifdef WOLFSSL_ASYNC_CRYPT
&& ssl->error != WC_PENDING_E
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
#if defined(HAVE_SECURE_RENEGOTIATION) || defined(WOLFSSL_DTLS13)
&& ssl->error != APP_DATA_READY
#endif
) {

View File

@@ -3233,7 +3233,14 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
}
#endif
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
if (IsAtLeastTLSv1_3(ssl->version) &&
ssl->options.side == WOLFSSL_SERVER_END &&
ssl->options.acceptState >= TLS13_ACCEPT_FINISHED_SENT) {
/* We can send data without waiting on peer finished msg */
WOLFSSL_MSG("server sending data before receiving client finished");
}
else if (ssl->earlyData != no_early_data &&
(ret = wolfSSL_negotiate(ssl)) < 0) {
ssl->error = ret;
return WOLFSSL_FATAL_ERROR;
}

View File

@@ -68148,6 +68148,7 @@ static int test_dtls13_early_data(void)
char msg[] = "This is early data";
char msg2[] = "This is client data";
char msg3[] = "This is server data";
char msg4[] = "This is server immediate data";
char msgBuf[50];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
@@ -68175,6 +68176,7 @@ static int test_dtls13_early_data(void)
ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
#endif
/* Test 0-RTT data */
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
&written), sizeof(msg));
ExpectIntEQ(written, sizeof(msg));
@@ -68184,6 +68186,15 @@ static int test_dtls13_early_data(void)
ExpectIntEQ(read, sizeof(msg));
ExpectStrEQ(msg, msgBuf);
/* Test 0.5-RTT data */
ExpectIntEQ(wolfSSL_write(ssl_s, msg4, sizeof(msg4)), sizeof(msg4));
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
ExpectStrEQ(msg4, msgBuf);
/* Complete handshake */
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
@@ -68195,11 +68206,14 @@ static int test_dtls13_early_data(void)
* parsing logic. */
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
&read), WOLFSSL_FAILURE);
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
&read), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
/* Test bi-directional write */
ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));