@@ -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 }
0 commit comments