Skip to content

Commit e7e2053

Browse files
authored
Merge pull request #8097 from julek-wolfssl/zd/18822
Fix TLS v1.2 session resumption edge cases
2 parents 830c5da + 25e32c2 commit e7e2053

File tree

2 files changed

+71
-51
lines changed

2 files changed

+71
-51
lines changed

src/internal.c

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17471,6 +17471,18 @@ int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1747117471
case certificate_request:
1747217472
case server_hello_done:
1747317473
if (ssl->options.resuming) {
17474+
/* Client requested resumption, but server is doing a
17475+
* full handshake */
17476+
17477+
/* The server's decision to resume isn't known until after the
17478+
* "server_hello". If subsequent handshake messages like
17479+
* "certificate" or "server_key_exchange" are recevied then we
17480+
* are doing a full handshake */
17481+
17482+
/* If the server included a session id then we
17483+
* treat this as a fatal error, since the server said it was
17484+
* doing resumption, but did not. */
17485+
1747417486
/* https://www.rfc-editor.org/rfc/rfc5077.html#section-3.4
1747517487
* Alternatively, the client MAY include an empty Session ID
1747617488
* in the ClientHello. In this case, the client ignores the
@@ -17479,7 +17491,7 @@ int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1747917491
* messages.
1748017492
*/
1748117493
#ifndef WOLFSSL_WPAS
17482-
if (ssl->session->sessionIDSz != 0) {
17494+
if (ssl->arrays->sessionIDSz != 0) {
1748317495
/* Fatal error. Only try to send an alert. RFC 5246 does not
1748417496
* allow for reverting back to a full handshake after the
1748517497
* server has indicated the intention to do a resumption. */
@@ -34510,6 +34522,29 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3451034522

3451134523
#ifndef WOLFSSL_NO_TLS12
3451234524

34525+
static int getSessionID(WOLFSSL* ssl)
34526+
{
34527+
int sessIdSz = 0;
34528+
(void)ssl;
34529+
#ifndef NO_SESSION_CACHE
34530+
/* if no session cache don't send a session ID */
34531+
if (!ssl->options.sessionCacheOff)
34532+
sessIdSz = ID_LEN;
34533+
#endif
34534+
#ifdef HAVE_SESSION_TICKET
34535+
/* we may be echoing an ID as part of session tickets */
34536+
if (ssl->options.useTicket) {
34537+
/* echo session id sz can be 0,32 or bogus len in between */
34538+
sessIdSz = ssl->arrays->sessionIDSz;
34539+
if (sessIdSz > ID_LEN) {
34540+
WOLFSSL_MSG("Bad bogus session id len");
34541+
return BUFFER_ERROR;
34542+
}
34543+
}
34544+
#endif /* HAVE_SESSION_TICKET */
34545+
return sessIdSz;
34546+
}
34547+
3451334548
/* handle generation of server_hello (2) */
3451434549
int SendServerHello(WOLFSSL* ssl)
3451534550
{
@@ -34518,63 +34553,31 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3451834553
word16 length;
3451934554
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
3452034555
int sendSz;
34521-
byte sessIdSz = ID_LEN;
34522-
#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SESSION_TICKET)
34523-
byte echoId = 0; /* ticket echo id flag */
34524-
#endif
34525-
byte cacheOff = 0; /* session cache off flag */
34556+
byte sessIdSz;
3452634557

3452734558
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
3452834559
WOLFSSL_ENTER("SendServerHello");
3452934560

34561+
ret = getSessionID(ssl);
34562+
if (ret < 0)
34563+
return ret;
34564+
sessIdSz = (byte)ret;
34565+
3453034566
length = VERSION_SZ + RAN_LEN
34531-
+ ID_LEN + ENUM_LEN
34567+
+ ENUM_LEN + sessIdSz
3453234568
+ SUITE_LEN
3453334569
+ ENUM_LEN;
3453434570

3453534571
#ifdef HAVE_TLS_EXTENSIONS
3453634572
ret = TLSX_GetResponseSize(ssl, server_hello, &length);
3453734573
if (ret != 0)
3453834574
return ret;
34539-
#ifdef HAVE_SESSION_TICKET
34540-
if (ssl->options.useTicket) {
34541-
/* echo session id sz can be 0,32 or bogus len in between */
34542-
sessIdSz = ssl->arrays->sessionIDSz;
34543-
if (sessIdSz > ID_LEN) {
34544-
WOLFSSL_MSG("Bad bogus session id len");
34545-
return BUFFER_ERROR;
34546-
}
34547-
if (!IsAtLeastTLSv1_3(ssl->version))
34548-
length -= (ID_LEN - sessIdSz); /* adjust ID_LEN assumption */
34549-
echoId = 1;
34550-
}
34551-
#endif /* HAVE_SESSION_TICKET */
3455234575
#else
3455334576
if (ssl->options.haveEMS) {
3455434577
length += HELLO_EXT_SZ_SZ + HELLO_EXT_SZ;
3455534578
}
3455634579
#endif
3455734580

34558-
/* is the session cache off at build or runtime */
34559-
#ifdef NO_SESSION_CACHE
34560-
cacheOff = 1;
34561-
#else
34562-
if (ssl->options.sessionCacheOff == 1) {
34563-
cacheOff = 1;
34564-
}
34565-
#endif
34566-
34567-
/* if no session cache don't send a session ID unless we're echoing
34568-
* an ID as part of session tickets */
34569-
if (cacheOff == 1
34570-
#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SESSION_TICKET)
34571-
&& echoId == 0
34572-
#endif
34573-
) {
34574-
length -= ID_LEN; /* adjust ID_LEN assumption */
34575-
sessIdSz = 0;
34576-
}
34577-
3457834581
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
3457934582
#ifdef WOLFSSL_DTLS
3458034583
if (ssl->options.dtls) {
@@ -34605,18 +34608,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3460534608

3460634609
/* then random and session id */
3460734610
if (!ssl->options.resuming) {
34608-
/* generate random part and session id */
34609-
ret = wc_RNG_GenerateBlock(ssl->rng, output + idx,
34610-
RAN_LEN + sizeof(sessIdSz) + sessIdSz);
34611-
if (ret != 0)
34612-
return ret;
34611+
word32 genRanLen = RAN_LEN;
3461334612

3461434613
#ifdef WOLFSSL_TLS13
3461534614
if (TLSv1_3_Capable(ssl)) {
3461634615
/* TLS v1.3 capable server downgraded. */
3461734616
XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1),
3461834617
tls13Downgrade, TLS13_DOWNGRADE_SZ);
3461934618
output[idx + RAN_LEN - 1] = (byte)IsAtLeastTLSv1_2(ssl);
34619+
genRanLen -= TLS13_DOWNGRADE_SZ + 1;
3462034620
}
3462134621
else
3462234622
#endif
@@ -34628,12 +34628,21 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3462834628
XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1),
3462934629
tls13Downgrade, TLS13_DOWNGRADE_SZ);
3463034630
output[idx + RAN_LEN - 1] = 0;
34631+
genRanLen -= TLS13_DOWNGRADE_SZ + 1;
3463134632
}
3463234633

34633-
/* store info in SSL for later */
34634+
/* generate random part */
34635+
ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, genRanLen);
34636+
if (ret != 0)
34637+
return ret;
3463434638
XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
3463534639
idx += RAN_LEN;
34640+
34641+
/* generate session id */
3463634642
output[idx++] = sessIdSz;
34643+
ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, sessIdSz);
34644+
if (ret != 0)
34645+
return ret;
3463734646
XMEMCPY(ssl->arrays->sessionID, output + idx, sessIdSz);
3463834647
ssl->arrays->sessionIDSz = sessIdSz;
3463934648
}

src/tls.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5905,14 +5905,25 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
59055905
/* SERVER: ticket is peer auth. */
59065906
ssl->options.peerAuthGood = 1;
59075907
}
5908-
} else if (ret == WOLFSSL_TICKET_RET_REJECT) {
5908+
} else if (ret == WOLFSSL_TICKET_RET_REJECT ||
5909+
ret == WC_NO_ERR_TRACE(VERSION_ERROR)) {
59095910
WOLFSSL_MSG("Process client ticket rejected, not using");
5910-
ssl->options.rejectTicket = 1;
5911+
if (ret == WC_NO_ERR_TRACE(VERSION_ERROR))
5912+
WOLFSSL_MSG("\tbad TLS version");
59115913
ret = 0; /* not fatal */
5912-
} else if (ret == WC_NO_ERR_TRACE(VERSION_ERROR)) {
5913-
WOLFSSL_MSG("Process client ticket rejected, bad TLS version");
5914+
59145915
ssl->options.rejectTicket = 1;
5915-
ret = 0; /* not fatal */
5916+
/* If we have session tickets enabled then send a new ticket */
5917+
if (!TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET)) {
5918+
ret = TLSX_UseSessionTicket(&ssl->extensions, NULL,
5919+
ssl->heap);
5920+
if (ret == WOLFSSL_SUCCESS) {
5921+
ret = 0;
5922+
TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
5923+
ssl->options.createTicket = 1;
5924+
ssl->options.useTicket = 1;
5925+
}
5926+
}
59165927
} else if (ret == WOLFSSL_TICKET_RET_FATAL) {
59175928
WOLFSSL_MSG("Process client ticket fatal error, not using");
59185929
} else if (ret < 0) {

0 commit comments

Comments
 (0)