Skip to content

Commit 9f6ef65

Browse files
authored
Merge pull request #6557 from julek-wolfssl/zd/16332
Don't allow a resumption handshake inside of a SCR
2 parents fa053be + 2248140 commit 9f6ef65

5 files changed

Lines changed: 132 additions & 8 deletions

File tree

src/internal.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7387,7 +7387,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
73877387
ret = wolfSSL_UseSecureRenegotiation(ssl);
73887388
if (ret != WOLFSSL_SUCCESS)
73897389
return ret;
7390-
}
7390+
}
73917391
}
73927392
#endif /* HAVE_SECURE_RENEGOTIATION */
73937393

@@ -15410,6 +15410,9 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
1541015410
#endif
1541115411
ssl->options.handShakeState = HANDSHAKE_DONE;
1541215412
ssl->options.handShakeDone = 1;
15413+
#ifdef HAVE_SECURE_RENEGOTIATION
15414+
ssl->options.resumed = ssl->options.resuming;
15415+
#endif
1541315416
}
1541415417
}
1541515418
else {
@@ -15426,6 +15429,9 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
1542615429
#endif
1542715430
ssl->options.handShakeState = HANDSHAKE_DONE;
1542815431
ssl->options.handShakeDone = 1;
15432+
#ifdef HAVE_SECURE_RENEGOTIATION
15433+
ssl->options.resumed = ssl->options.resuming;
15434+
#endif
1542915435
}
1543015436
}
1543115437
#ifdef WOLFSSL_DTLS
@@ -15975,8 +15981,10 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1597515981
}
1597615982

1597715983
if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
15978-
ssl->options.serverState == NULL_STATE && type != server_hello) {
15979-
WOLFSSL_MSG("First server message not server hello");
15984+
ssl->options.serverState == NULL_STATE && type != server_hello &&
15985+
type != hello_request) {
15986+
WOLFSSL_MSG("First server message not server hello or "
15987+
"hello request");
1598015988
SendAlert(ssl, alert_fatal, unexpected_message);
1598115989
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1598215990
return OUT_OF_ORDER_E;
@@ -21927,6 +21935,9 @@ int SendFinished(WOLFSSL* ssl)
2192721935
#endif
2192821936
ssl->options.handShakeState = HANDSHAKE_DONE;
2192921937
ssl->options.handShakeDone = 1;
21938+
#ifdef HAVE_SECURE_RENEGOTIATION
21939+
ssl->options.resumed = ssl->options.resuming;
21940+
#endif
2193021941
}
2193121942
}
2193221943
else {
@@ -21939,6 +21950,9 @@ int SendFinished(WOLFSSL* ssl)
2193921950
#endif
2194021951
ssl->options.handShakeState = HANDSHAKE_DONE;
2194121952
ssl->options.handShakeDone = 1;
21953+
#ifdef HAVE_SECURE_RENEGOTIATION
21954+
ssl->options.resumed = ssl->options.resuming;
21955+
#endif
2194221956
}
2194321957
}
2194421958

@@ -27143,13 +27157,20 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
2714327157
return BAD_FUNC_ARG;
2714427158
}
2714527159

27146-
idSz = ssl->options.resuming ? ssl->session->sessionIDSz : 0;
27147-
2714827160
#ifdef WOLFSSL_TLS13
2714927161
if (IsAtLeastTLSv1_3(ssl->version))
2715027162
return SendTls13ClientHello(ssl);
2715127163
#endif
2715227164

27165+
#ifdef HAVE_SECURE_RENEGOTIATION
27166+
/* We don't want to resume in SCR */
27167+
if (IsSCR(ssl))
27168+
ssl->options.resuming = 0;
27169+
#endif
27170+
27171+
idSz = ssl->options.resuming ? ssl->session->sessionIDSz : 0;
27172+
27173+
2715327174
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
2715427175
WOLFSSL_ENTER("SendClientHello");
2715527176

@@ -34310,6 +34331,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3431034331
ssl->options.dtlsStateful = 1;
3431134332
#endif /* WOLFSSL_DTLS */
3431234333

34334+
/* Reset to sane value for SCR */
34335+
ssl->options.resuming = 0;
34336+
ssl->arrays->sessionIDSz = 0;
34337+
3431334338
/* protocol version, random and session id length check */
3431434339
if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
3431534340
return BUFFER_ERROR;
@@ -34503,7 +34528,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3450334528
ret = BUFFER_ERROR; /* session ID greater than 32 bytes long */
3450434529
goto out;
3450534530
}
34506-
else if (b > 0) {
34531+
else if (b > 0 && !IsSCR(ssl)) {
3450734532
if ((i - begin) + b > helloSz) {
3450834533
ret = BUFFER_ERROR;
3450934534
goto out;
@@ -34516,8 +34541,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3451634541
if (b == ID_LEN)
3451734542
ssl->options.resuming = 1; /* client wants to resume */
3451834543
WOLFSSL_MSG("Client wants to resume session");
34519-
i += b;
3452034544
}
34545+
i += b;
3452134546

3452234547
#ifdef WOLFSSL_DTLS
3452334548
/* cookie */

src/ssl.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4103,6 +4103,8 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl)
41034103
if (ssl->options.side == WOLFSSL_SERVER_END) {
41044104
/* Reset option to send certificate verify. */
41054105
ssl->options.sendVerify = 0;
4106+
/* Reset resuming flag to do full secure handshake. */
4107+
ssl->options.resuming = 0;
41064108
}
41074109
else {
41084110
/* Reset resuming flag to do full secure handshake. */
@@ -21413,8 +21415,13 @@ int wolfSSL_session_reused(WOLFSSL* ssl)
2141321415
{
2141421416
int resuming = 0;
2141521417
WOLFSSL_ENTER("wolfSSL_session_reused");
21416-
if (ssl)
21418+
if (ssl) {
21419+
#ifndef HAVE_SECURE_RENEGOTIATION
2141721420
resuming = ssl->options.resuming;
21421+
#else
21422+
resuming = ssl->options.resuming || ssl->options.resumed;
21423+
#endif
21424+
}
2141821425
WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
2141921426
return resuming;
2142021427
}

src/tls.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,6 +5397,13 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
53975397
return 0;
53985398
}
53995399

5400+
#ifdef HAVE_SECURE_RENEGOTIATION
5401+
if (IsSCR(ssl)) {
5402+
WOLFSSL_MSG("Client sent session ticket during SCR. Ignoring.");
5403+
return 0;
5404+
}
5405+
#endif
5406+
54005407
if (length > SESSION_TICKET_LEN) {
54015408
ret = BAD_TICKET_MSG_SZ;
54025409
WOLFSSL_ERROR_VERBOSE(ret);

tests/api.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62082,6 +62082,87 @@ static int test_dtls_ipv6_check(void)
6208262082
}
6208362083
#endif
6208462084

62085+
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
62086+
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
62087+
62088+
static WOLFSSL_SESSION* test_wolfSSL_SCR_after_resumption_session = NULL;
62089+
62090+
static void test_wolfSSL_SCR_after_resumption_ctx_ready(WOLFSSL_CTX* ctx)
62091+
{
62092+
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
62093+
}
62094+
62095+
static void test_wolfSSL_SCR_after_resumption_on_result(WOLFSSL* ssl)
62096+
{
62097+
if (test_wolfSSL_SCR_after_resumption_session == NULL) {
62098+
test_wolfSSL_SCR_after_resumption_session = wolfSSL_get1_session(ssl);
62099+
AssertNotNull(test_wolfSSL_SCR_after_resumption_session);
62100+
}
62101+
else {
62102+
char testMsg[] = "Message after SCR";
62103+
char msgBuf[sizeof(testMsg)];
62104+
int ret;
62105+
if (!wolfSSL_is_server(ssl)) {
62106+
AssertIntEQ(WOLFSSL_SUCCESS,
62107+
wolfSSL_set_session(ssl,
62108+
test_wolfSSL_SCR_after_resumption_session));
62109+
}
62110+
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
62111+
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
62112+
sizeof(testMsg));
62113+
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
62114+
if (ret != sizeof(msgBuf)) /* Possibly APP_DATA_READY error. Retry. */
62115+
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
62116+
AssertIntEQ(ret, sizeof(msgBuf));
62117+
}
62118+
}
62119+
62120+
static void test_wolfSSL_SCR_after_resumption_ssl_ready(WOLFSSL* ssl)
62121+
{
62122+
AssertIntEQ(WOLFSSL_SUCCESS,
62123+
wolfSSL_set_session(ssl, test_wolfSSL_SCR_after_resumption_session));
62124+
}
62125+
62126+
static int test_wolfSSL_SCR_after_resumption(void)
62127+
{
62128+
EXPECT_DECLS;
62129+
callback_functions func_cb_client;
62130+
callback_functions func_cb_server;
62131+
62132+
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
62133+
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
62134+
62135+
func_cb_client.method = wolfTLSv1_2_client_method;
62136+
func_cb_client.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;
62137+
func_cb_client.on_result = test_wolfSSL_SCR_after_resumption_on_result;
62138+
func_cb_server.method = wolfTLSv1_2_server_method;
62139+
func_cb_server.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;
62140+
62141+
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
62142+
62143+
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
62144+
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
62145+
62146+
func_cb_client.ssl_ready = test_wolfSSL_SCR_after_resumption_ssl_ready;
62147+
func_cb_server.on_result = test_wolfSSL_SCR_after_resumption_on_result;
62148+
62149+
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
62150+
62151+
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
62152+
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
62153+
62154+
wolfSSL_SESSION_free(test_wolfSSL_SCR_after_resumption_session);
62155+
62156+
return EXPECT_RESULT();
62157+
}
62158+
62159+
#else
62160+
static int test_wolfSSL_SCR_after_resumption(void)
62161+
{
62162+
return TEST_SKIPPED;
62163+
}
62164+
#endif
62165+
6208562166
static int test_wolfSSL_configure_args(void)
6208662167
{
6208762168
EXPECT_DECLS;
@@ -63332,6 +63413,7 @@ TEST_CASE testCases[] = {
6333263413
/* Can't memory test as client/server hangs. */
6333363414
TEST_DECL(test_dtls_msg_from_other_peer),
6333463415
TEST_DECL(test_dtls_ipv6_check),
63416+
TEST_DECL(test_wolfSSL_SCR_after_resumption),
6333563417
/* This test needs to stay at the end to clean up any caches allocated. */
6333663418
TEST_DECL(test_wolfSSL_Cleanup)
6333763419
};

wolfssl/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,6 +4541,9 @@ struct Options {
45414541
word16 failNoCertxPSK:1; /* fail for no cert except with PSK */
45424542
word16 downgrade:1; /* allow downgrade of versions */
45434543
word16 resuming:1;
4544+
#ifdef HAVE_SECURE_RENEGOTIATION
4545+
word16 resumed:1; /* resuming may be reset on SCR */
4546+
#endif
45444547
word16 isPSK:1;
45454548
word16 haveSessionId:1; /* server may not send */
45464549
word16 tls:1; /* using TLS ? */

0 commit comments

Comments
 (0)