Skip to content

Commit a8c94cf

Browse files
authored
Merge pull request #7102 from julek-wolfssl/gh/7093
server: allow reading 0-RTT data after writing 0.5-RTT data
2 parents 32f3f7d + 14c812c commit a8c94cf

4 files changed

Lines changed: 141 additions & 89 deletions

File tree

src/internal.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23985,7 +23985,9 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
2398523985
}
2398623986

2398723987
#ifdef WOLFSSL_EARLY_DATA
23988-
if (ssl->earlyData != no_early_data) {
23988+
if (ssl->options.side == WOLFSSL_CLIENT_END &&
23989+
ssl->earlyData != no_early_data &&
23990+
ssl->earlyData != done_early_data) {
2398923991
if (ssl->options.handShakeState == HANDSHAKE_DONE) {
2399023992
WOLFSSL_MSG("handshake complete, trying to send early data");
2399123993
ssl->error = BUILD_MSG_ERROR;
@@ -24079,7 +24081,9 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
2407924081
return ssl->error = BAD_STATE_E;
2408024082

2408124083
#ifdef WOLFSSL_EARLY_DATA
24082-
isEarlyData = ssl->earlyData != no_early_data;
24084+
isEarlyData = ssl->options.side == WOLFSSL_CLIENT_END &&
24085+
ssl->earlyData != no_early_data &&
24086+
ssl->earlyData != done_early_data;
2408324087
#endif
2408424088

2408524089
if (isEarlyData) {
@@ -24247,7 +24251,8 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
2424724251
}
2424824252

2424924253
#ifdef WOLFSSL_EARLY_DATA
24250-
if (ssl->earlyData != no_early_data) {
24254+
if (ssl->options.side == WOLFSSL_SERVER_END &&
24255+
ssl->earlyData > early_data_ext && ssl->earlyData < done_early_data) {
2425124256
}
2425224257
else
2425324258
#endif

src/ssl.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,20 +3240,6 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
32403240
return BAD_FUNC_ARG;
32413241
}
32423242
#endif
3243-
#ifdef WOLFSSL_EARLY_DATA
3244-
if (IsAtLeastTLSv1_3(ssl->version) &&
3245-
ssl->options.side == WOLFSSL_SERVER_END &&
3246-
ssl->options.acceptState >= TLS13_ACCEPT_FINISHED_SENT) {
3247-
/* We can send data without waiting on peer finished msg */
3248-
WOLFSSL_MSG("server sending data before receiving client finished");
3249-
}
3250-
else if (ssl->earlyData != no_early_data &&
3251-
(ret = wolfSSL_negotiate(ssl)) < 0) {
3252-
ssl->error = ret;
3253-
return WOLFSSL_FATAL_ERROR;
3254-
}
3255-
ssl->earlyData = no_early_data;
3256-
#endif
32573243

32583244
#ifdef HAVE_WRITE_DUP
32593245
{ /* local variable scope */

src/tls13.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10378,6 +10378,8 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
1037810378
if (!ssl->options.groupMessages)
1037910379
ret = SendBuffered(ssl);
1038010380

10381+
ssl->earlyData = done_early_data;
10382+
1038110383
WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret);
1038210384
WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_SEND);
1038310385

tests/api.c

Lines changed: 131 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -68693,102 +68693,161 @@ static int test_tls13_pq_groups(void)
6869368693
return EXPECT_RESULT();
6869468694
}
6869568695

68696-
static int test_dtls13_early_data(void)
68696+
static int test_tls13_early_data(void)
6869768697
{
6869868698
EXPECT_DECLS;
68699-
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) && \
68699+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
6870068700
defined(WOLFSSL_EARLY_DATA) && defined(HAVE_SESSION_TICKET)
68701-
struct test_memio_ctx test_ctx;
68702-
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
68703-
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
68704-
WOLFSSL_SESSION *sess = NULL;
6870568701
int written = 0;
6870668702
int read = 0;
68703+
size_t i;
68704+
int splitEarlyData;
6870768705
char msg[] = "This is early data";
6870868706
char msg2[] = "This is client data";
6870968707
char msg3[] = "This is server data";
6871068708
char msg4[] = "This is server immediate data";
6871168709
char msgBuf[50];
68710+
struct {
68711+
method_provider client_meth;
68712+
method_provider server_meth;
68713+
const char* tls_version;
68714+
int isUdp;
68715+
} params[] = {
68716+
#ifdef WOLFSSL_TLS13
68717+
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
68718+
"TLS 1.3", 0 },
68719+
#endif
68720+
#ifdef WOLFSSL_DTLS13
68721+
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
68722+
"DTLS 1.3", 1 },
68723+
#endif
68724+
};
6871268725

68713-
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
68726+
for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
68727+
for (splitEarlyData = 0; splitEarlyData < 2; splitEarlyData++) {
68728+
struct test_memio_ctx test_ctx;
68729+
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
68730+
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
68731+
WOLFSSL_SESSION *sess = NULL;
6871468732

68715-
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
68716-
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
68733+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
6871768734

68718-
/* Get a ticket so that we can do 0-RTT on the next connection */
68719-
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
68720-
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
68735+
fprintf(stderr, "\tEarly data with %s\n", params[i].tls_version);
6872168736

68722-
wolfSSL_free(ssl_c);
68723-
ssl_c = NULL;
68724-
wolfSSL_free(ssl_s);
68725-
ssl_s = NULL;
68726-
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
68727-
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
68728-
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
68729-
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
68737+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
68738+
&ssl_s, params[i].client_meth, params[i].server_meth), 0);
68739+
68740+
/* Get a ticket so that we can do 0-RTT on the next connection */
68741+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
68742+
/* Make sure we read the ticket */
68743+
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), -1);
68744+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
68745+
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
68746+
68747+
wolfSSL_free(ssl_c);
68748+
ssl_c = NULL;
68749+
wolfSSL_free(ssl_s);
68750+
ssl_s = NULL;
68751+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
68752+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
68753+
params[i].client_meth, params[i].server_meth), 0);
68754+
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
68755+
#ifdef WOLFSSL_DTLS13
68756+
if (params[i].isUdp) {
6873068757
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
68731-
ExpectIntEQ(wolfSSL_dtls13_no_hrr_on_resume(ssl_s, 1), WOLFSSL_SUCCESS);
68758+
ExpectIntEQ(wolfSSL_dtls13_no_hrr_on_resume(ssl_s, 1), WOLFSSL_SUCCESS);
6873268759
#else
68733-
/* Let's test this but we generally don't recommend turning off the
68734-
* cookie exchange */
68735-
ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
68760+
/* Let's test this but we generally don't recommend turning off the
68761+
* cookie exchange */
68762+
ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
68763+
#endif
68764+
}
6873668765
#endif
6873768766

68738-
/* Test 0-RTT data */
68739-
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
68740-
&written), sizeof(msg));
68741-
ExpectIntEQ(written, sizeof(msg));
68742-
68743-
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68744-
&read), sizeof(msg));
68745-
ExpectIntEQ(read, sizeof(msg));
68746-
ExpectStrEQ(msg, msgBuf);
68747-
68748-
/* Test 0.5-RTT data */
68749-
ExpectIntEQ(wolfSSL_write(ssl_s, msg4, sizeof(msg4)), sizeof(msg4));
68750-
68751-
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
68752-
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
68753-
68754-
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
68755-
ExpectStrEQ(msg4, msgBuf);
68767+
/* Test 0-RTT data */
68768+
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
68769+
&written), sizeof(msg));
68770+
ExpectIntEQ(written, sizeof(msg));
6875668771

68757-
/* Complete handshake */
68758-
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
68759-
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
68760-
/* Use wolfSSL_is_init_finished to check if handshake is complete. Normally
68761-
* a user would loop until it is true but here we control both sides so we
68762-
* just assert the expected value. wolfSSL_read_early_data does not provide
68763-
* handshake status to us with non-blocking IO and we can't use
68764-
* wolfSSL_accept as TLS layer may return ZERO_RETURN due to early data
68765-
* parsing logic. */
68766-
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
68767-
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68768-
&read), -1);
68769-
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
68772+
if (splitEarlyData) {
68773+
ExpectIntEQ(wolfSSL_write_early_data(ssl_c, msg, sizeof(msg),
68774+
&written), sizeof(msg));
68775+
ExpectIntEQ(written, sizeof(msg));
68776+
}
6877068777

68771-
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
68778+
/* Read first 0-RTT data (if split otherwise entire data) */
68779+
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68780+
&read), sizeof(msg));
68781+
ExpectIntEQ(read, sizeof(msg));
68782+
ExpectStrEQ(msg, msgBuf);
68783+
68784+
/* Test 0.5-RTT data */
68785+
ExpectIntEQ(wolfSSL_write(ssl_s, msg4, sizeof(msg4)), sizeof(msg4));
68786+
68787+
if (splitEarlyData) {
68788+
/* Read second 0-RTT data */
68789+
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68790+
&read), sizeof(msg));
68791+
ExpectIntEQ(read, sizeof(msg));
68792+
ExpectStrEQ(msg, msgBuf);
68793+
}
6877268794

68773-
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
68795+
if (params[i].isUdp) {
68796+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
68797+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY);
68798+
68799+
/* Read server 0.5-RTT data */
68800+
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
68801+
ExpectStrEQ(msg4, msgBuf);
68802+
68803+
/* Complete handshake */
68804+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
68805+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
68806+
/* Use wolfSSL_is_init_finished to check if handshake is complete. Normally
68807+
* a user would loop until it is true but here we control both sides so we
68808+
* just assert the expected value. wolfSSL_read_early_data does not provide
68809+
* handshake status to us with non-blocking IO and we can't use
68810+
* wolfSSL_accept as TLS layer may return ZERO_RETURN due to early data
68811+
* parsing logic. */
68812+
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
68813+
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68814+
&read), 0);
68815+
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
68816+
68817+
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
68818+
}
68819+
else {
68820+
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
6877468821

68822+
ExpectFalse(wolfSSL_is_init_finished(ssl_s));
68823+
ExpectIntEQ(wolfSSL_read_early_data(ssl_s, msgBuf, sizeof(msgBuf),
68824+
&read), 0);
6877568825

68776-
/* Test bi-directional write */
68777-
ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
68778-
ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));
68779-
ExpectStrEQ(msg2, msgBuf);
68780-
ExpectIntEQ(wolfSSL_write(ssl_s, msg3, sizeof(msg3)), sizeof(msg3));
68781-
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg3));
68782-
ExpectStrEQ(msg3, msgBuf);
68826+
ExpectTrue(wolfSSL_is_init_finished(ssl_s));
6878368827

68784-
ExpectTrue(wolfSSL_session_reused(ssl_c));
68785-
ExpectTrue(wolfSSL_session_reused(ssl_s));
68828+
/* Read server 0.5-RTT data */
68829+
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg4));
68830+
ExpectStrEQ(msg4, msgBuf);
68831+
}
6878668832

68787-
wolfSSL_SESSION_free(sess);
68788-
wolfSSL_free(ssl_c);
68789-
wolfSSL_free(ssl_s);
68790-
wolfSSL_CTX_free(ctx_c);
68791-
wolfSSL_CTX_free(ctx_s);
68833+
/* Test bi-directional write */
68834+
ExpectIntEQ(wolfSSL_write(ssl_c, msg2, sizeof(msg2)), sizeof(msg2));
68835+
ExpectIntEQ(wolfSSL_read(ssl_s, msgBuf, sizeof(msgBuf)), sizeof(msg2));
68836+
ExpectStrEQ(msg2, msgBuf);
68837+
ExpectIntEQ(wolfSSL_write(ssl_s, msg3, sizeof(msg3)), sizeof(msg3));
68838+
ExpectIntEQ(wolfSSL_read(ssl_c, msgBuf, sizeof(msgBuf)), sizeof(msg3));
68839+
ExpectStrEQ(msg3, msgBuf);
68840+
68841+
ExpectTrue(wolfSSL_session_reused(ssl_c));
68842+
ExpectTrue(wolfSSL_session_reused(ssl_s));
68843+
68844+
wolfSSL_SESSION_free(sess);
68845+
wolfSSL_free(ssl_c);
68846+
wolfSSL_free(ssl_s);
68847+
wolfSSL_CTX_free(ctx_c);
68848+
wolfSSL_CTX_free(ctx_s);
68849+
}
68850+
}
6879268851
#endif
6879368852
return EXPECT_RESULT();
6879468853
}
@@ -70188,7 +70247,7 @@ TEST_CASE testCases[] = {
7018870247
TEST_DECL(test_dtls13_frag_ch_pq),
7018970248
TEST_DECL(test_dtls_empty_keyshare_with_cookie),
7019070249
TEST_DECL(test_tls13_pq_groups),
70191-
TEST_DECL(test_dtls13_early_data),
70250+
TEST_DECL(test_tls13_early_data),
7019270251
/* This test needs to stay at the end to clean up any caches allocated. */
7019370252
TEST_DECL(test_wolfSSL_Cleanup)
7019470253
};

0 commit comments

Comments
 (0)