@@ -13440,10 +13440,20 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType)
1344013440 return (int)size;
1344113441}
1344213442
13443- /* locate the given extension type, use the extOffset to start off after where a
13444- * previous call to this function ended */
13445- static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
13446- word16 extType, word16* extLen, word16* extOffset,
13443+ /* Locate the given extension type, use the extOffset to start off after where a
13444+ * previous call to this function ended
13445+ *
13446+ * outerCh The outer ClientHello buffer.
13447+ * chLen Outer ClientHello length.
13448+ * extType Extension type to look for.
13449+ * extLen Out parameter, length of found extension.
13450+ * extOffset Offset into outer ClientHello to look for extension from.
13451+ * extensionsStart Start of outer ClientHello extensions.
13452+ * extensionsLen Length of outer ClientHello extensions.
13453+ * returns 0 on success and otherwise failure.
13454+ */
13455+ static const byte* TLSX_ECH_FindOuterExtension(const byte* outerCh,
13456+ word32 chLen, word16 extType, word16* extLen, word16* extOffset,
1344713457 word16* extensionsStart, word16* extensionsLen)
1344813458{
1344913459 word32 idx = *extOffset;
@@ -13505,10 +13515,19 @@ static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
1350513515 return NULL;
1350613516}
1350713517
13508- /* if newInnerCh is NULL, validate ordering and existence of references
13509- * - updates newInnerChLen with total length of selected extensions
13510- * if not NULL, copy extensions into the provided buffer */
13511- static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
13518+ /* If newinnerCh is NULL, validate ordering and existence of references
13519+ * - updates newInnerChLen with total length of selected extensions
13520+ * If newinnerCh in not NULL, copy extensions into newInnerCh
13521+ *
13522+ * outerCh The outer ClientHello buffer.
13523+ * outerChLen Outer ClientHello length.
13524+ * newInnerCh The inner ClientHello buffer.
13525+ * newInnerChLen Inner ClientHello length.
13526+ * numOuterRefs Number of references described by OuterExtensions extension.
13527+ * numOuterTypes References described by OuterExtensions extension.
13528+ * returns 0 on success and otherwise failure.
13529+ */
13530+ static int TLSX_ECH_CopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1351213531 byte** newInnerCh, word32* newInnerChLen,
1351313532 word16 numOuterRefs, const byte* outerRefTypes)
1351413533{
@@ -13532,9 +13551,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1353213551 break;
1353313552 }
1353413553
13535- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13536- refType, &outerExtLen, &outerExtOffset,
13537- &extsStart, &extsLen);
13554+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13555+ refType, &outerExtLen, &outerExtOffset,
13556+ &extsStart, &extsLen);
1353813557
1353913558 if (outerExtData == NULL) {
1354013559 WOLFSSL_MSG("ECH: referenced extension not in outer CH");
@@ -13551,9 +13570,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1355113570 while (numOuterRefs-- > 0) {
1355213571 ato16(outerRefTypes, &refType);
1355313572
13554- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13555- refType, &outerExtLen, &outerExtOffset,
13556- &extsStart, &extsLen);
13573+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13574+ refType, &outerExtLen, &outerExtOffset,
13575+ &extsStart, &extsLen);
1355713576
1355813577 if (outerExtData == NULL) {
1355913578 ret = INVALID_PARAMETER;
@@ -13570,13 +13589,21 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1357013589 return ret;
1357113590}
1357213591
13573- /* expand ech_outer_extensions in the inner ClientHello by copying referenced
13574- * extensions from the outer ClientHello
13592+ /* Expand ech_outer_extensions in the inner ClientHello by copying referenced
13593+ * extensions from the outer ClientHello.
13594+ * If the sessionID exists in the outer ClientHello then also copy that into the
13595+ * expanded inner ClientHello.
13596+ *
13597+ * ssl SSL/TLS object.
13598+ * ech ECH object.
13599+ * heap Heap hint.
13600+ * returns 0 on success and otherwise failure.
1357513601 */
13576- static int TLSX_ExpandEchOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
13602+ static int TLSX_ECH_ExpandOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
1357713603 void* heap)
1357813604{
1357913605 int ret = 0;
13606+ int headerSz;
1358013607 const byte* innerCh;
1358113608 word32 innerChLen;
1358213609 const byte* outerCh;
@@ -13604,7 +13631,14 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1360413631 if (ech == NULL || ech->innerClientHello == NULL || ech->aad == NULL)
1360513632 return BAD_FUNC_ARG;
1360613633
13607- innerCh = ech->innerClientHello + HANDSHAKE_HEADER_SZ;
13634+ #ifdef WOLFSSL_DTLS13
13635+ headerSz = ssl->options.dtls ? DTLS13_HANDSHAKE_HEADER_SZ :
13636+ HANDSHAKE_HEADER_SZ;
13637+ #else
13638+ headerSz = HANDSHAKE_HEADER_SZ;
13639+ #endif
13640+
13641+ innerCh = ech->innerClientHello + headerSz;
1360813642 innerChLen = ech->innerClientHelloLen;
1360913643 outerCh = ech->aad;
1361013644 outerChLen = ech->aadLen;
@@ -13675,8 +13709,8 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1367513709 outerRefTypes = innerCh + idx + 1;
1367613710 numOuterRefs = outerExtListLen / OPAQUE16_LEN;
1367713711
13678- ret = EchCopyOuterExtensions (outerCh, outerChLen, NULL, &extraSize ,
13679- numOuterRefs, outerRefTypes);
13712+ ret = TLSX_ECH_CopyOuterExtensions (outerCh, outerChLen, NULL,
13713+ &extraSize, numOuterRefs, outerRefTypes);
1368013714 if (ret != 0)
1368113715 return ret;
1368213716 }
@@ -13685,16 +13719,16 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1368513719 }
1368613720
1368713721 newInnerChLen = innerChLen - echOuterExtLen + extraSize - sessionIdLen +
13688- ssl->session->sessionIDSz;
13722+ ssl->session->sessionIDSz;
1368913723
1369013724 if (!foundEchOuter && sessionIdLen == ssl->session->sessionIDSz) {
1369113725 /* no extensions + no sessionID to copy */
1369213726 WOLFSSL_MSG("ECH: no EchOuterExtensions extension found");
1369313727 return ret;
1369413728 }
1369513729 else {
13696- newInnerCh = (byte*)XMALLOC(newInnerChLen + HANDSHAKE_HEADER_SZ , heap,
13697- DYNAMIC_TYPE_TMP_BUFFER);
13730+ newInnerCh = (byte*)XMALLOC(newInnerChLen + headerSz , heap,
13731+ DYNAMIC_TYPE_TMP_BUFFER);
1369813732 if (newInnerCh == NULL)
1369913733 return MEMORY_E;
1370013734 }
@@ -13704,7 +13738,7 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1370413738 * AddTls13HandShakeHeader() in DoTls13ClientHello(). */
1370513739
1370613740 /* copy everything up to EchOuterExtensions */
13707- newInnerChRef = newInnerCh + HANDSHAKE_HEADER_SZ ;
13741+ newInnerChRef = newInnerCh + headerSz ;
1370813742 copyLen = OPAQUE16_LEN + RAN_LEN;
1370913743 XMEMCPY(newInnerChRef, innerCh, copyLen);
1371013744 newInnerChRef += copyLen;
@@ -13726,24 +13760,22 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1372613760 }
1372713761 else {
1372813762 copyLen = echOuterExtIdx - OPAQUE16_LEN - RAN_LEN - OPAQUE8_LEN -
13729- sessionIdLen;
13763+ sessionIdLen;
1373013764 XMEMCPY(newInnerChRef, innerCh + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN +
13731- sessionIdLen, copyLen);
13765+ sessionIdLen, copyLen);
1373213766 newInnerChRef += copyLen;
1373313767
1373413768 /* update extensions length in the new ClientHello */
13735- innerExtIdx = innerExtIdx - sessionIdLen + ssl->session->sessionIDSz;
1373613769 c16toa(innerExtLen - echOuterExtLen + (word16)extraSize,
13737- newInnerChRef - OPAQUE16_LEN);
13770+ newInnerChRef - OPAQUE16_LEN);
1373813771
13739- /* insert expanded extensions from outer ClientHello */
13740- ret = EchCopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
13772+ ret = TLSX_ECH_CopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
1374113773 &newInnerChLen, numOuterRefs, outerRefTypes);
1374213774 if (ret == 0) {
1374313775 /* copy remaining extensions after ech_outer_extensions */
1374413776 copyLen = innerChLen - (echOuterExtIdx + echOuterExtLen);
1374513777 XMEMCPY(newInnerChRef, innerCh + echOuterExtIdx + echOuterExtLen,
13746- copyLen);
13778+ copyLen);
1374713779
1374813780 WOLFSSL_MSG("ECH: expanded ech_outer_extensions successfully");
1374913781 }
@@ -14020,13 +14052,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1402014052 echConfig = echConfig->next;
1402114053 }
1402214054 }
14023- /* if we failed to extract, set state to retry configs */
14024- if (ret != 0) {
14025- XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14026- ech->innerClientHello = NULL;
14027- ech->state = ECH_WRITE_RETRY_CONFIGS;
14028- }
14029- else {
14055+ if (ret == 0) {
1403014056 i = 0;
1403114057 /* decrement until before the padding */
1403214058 while (ech->innerClientHello[ech->innerClientHelloLen +
@@ -14036,15 +14062,15 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1403614062 /* subtract the length of the padding from the length */
1403714063 ech->innerClientHelloLen -= i;
1403814064
14039- /* expand EchOuterExtensions if present */
14040- ret = TLSX_ExpandEchOuterExtensions(ssl, ech, ssl->heap);
14041- if ( ret != 0) {
14042- WOLFSSL_MSG_EX("ECH: failed to expand EchOuterExtensions");
14043- XFREE(ech->innerClientHello, ssl->heap,
14044- DYNAMIC_TYPE_TMP_BUFFER);
14045- ech->innerClientHello = NULL ;
14046- ech->state = ECH_WRITE_RETRY_CONFIGS ;
14047- }
14065+ /* expand EchOuterExtensions if present
14066+ * and, if it exists, copy sessionID from outer hello */
14067+ ret = TLSX_ECH_ExpandOuterExtensions(ssl, ech, ssl->heap);
14068+ }
14069+ /* if we failed to extract/expand, set state to retry configs */
14070+ if (ret != 0) {
14071+ XFREE( ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER) ;
14072+ ech->innerClientHello = NULL ;
14073+ ech->state = ECH_WRITE_RETRY_CONFIGS;
1404814074 }
1404914075 XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1405014076 return 0;
0 commit comments