@@ -13414,10 +13414,20 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType)
1341413414 return (int)size;
1341513415}
1341613416
13417- /* locate the given extension type, use the extOffset to start off after where a
13418- * previous call to this function ended */
13419- static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
13420- word16 extType, word16* extLen, word16* extOffset,
13417+ /* Locate the given extension type, use the extOffset to start off after where a
13418+ * previous call to this function ended
13419+ *
13420+ * outerCh The outer ClientHello buffer.
13421+ * chLen Outer ClientHello length.
13422+ * extType Extension type to look for.
13423+ * extLen Out parameter, length of found extension.
13424+ * extOffset Offset into outer ClientHello to look for extension from.
13425+ * extensionsStart Start of outer ClientHello extensions.
13426+ * extensionsLen Length of outer ClientHello extensions.
13427+ * returns 0 on success and otherwise failure.
13428+ */
13429+ static const byte* TLSX_ECH_FindOuterExtension(const byte* outerCh,
13430+ word32 chLen, word16 extType, word16* extLen, word16* extOffset,
1342113431 word16* extensionsStart, word16* extensionsLen)
1342213432{
1342313433 word32 idx = *extOffset;
@@ -13479,10 +13489,19 @@ static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
1347913489 return NULL;
1348013490}
1348113491
13482- /* if newInnerCh is NULL, validate ordering and existence of references
13483- * - updates newInnerChLen with total length of selected extensions
13484- * if not NULL, copy extensions into the provided buffer */
13485- static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
13492+ /* If newinnerCh is NULL, validate ordering and existence of references
13493+ * - updates newInnerChLen with total length of selected extensions
13494+ * If newinnerCh in not NULL, copy extensions into newInnerCh
13495+ *
13496+ * outerCh The outer ClientHello buffer.
13497+ * outerChLen Outer ClientHello length.
13498+ * newInnerCh The inner ClientHello buffer.
13499+ * newInnerChLen Inner ClientHello length.
13500+ * numOuterRefs Number of references described by OuterExtensions extension.
13501+ * numOuterTypes References described by OuterExtensions extension.
13502+ * returns 0 on success and otherwise failure.
13503+ */
13504+ static int TLSX_ECH_CopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1348613505 byte** newInnerCh, word32* newInnerChLen,
1348713506 word16 numOuterRefs, const byte* outerRefTypes)
1348813507{
@@ -13506,9 +13525,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1350613525 break;
1350713526 }
1350813527
13509- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13510- refType, &outerExtLen, &outerExtOffset,
13511- &extsStart, &extsLen);
13528+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13529+ refType, &outerExtLen, &outerExtOffset,
13530+ &extsStart, &extsLen);
1351213531
1351313532 if (outerExtData == NULL) {
1351413533 WOLFSSL_MSG("ECH: referenced extension not in outer CH");
@@ -13525,9 +13544,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1352513544 while (numOuterRefs-- > 0) {
1352613545 ato16(outerRefTypes, &refType);
1352713546
13528- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13529- refType, &outerExtLen, &outerExtOffset,
13530- &extsStart, &extsLen);
13547+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13548+ refType, &outerExtLen, &outerExtOffset,
13549+ &extsStart, &extsLen);
1353113550
1353213551 if (outerExtData == NULL) {
1353313552 ret = INVALID_PARAMETER;
@@ -13544,13 +13563,21 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1354413563 return ret;
1354513564}
1354613565
13547- /* expand ech_outer_extensions in the inner ClientHello by copying referenced
13548- * extensions from the outer ClientHello
13566+ /* Expand ech_outer_extensions in the inner ClientHello by copying referenced
13567+ * extensions from the outer ClientHello.
13568+ * If the sessionID exists in the outer ClientHello then also copy that into the
13569+ * expanded inner ClientHello.
13570+ *
13571+ * ssl SSL/TLS object.
13572+ * ech ECH object.
13573+ * heap Heap hint.
13574+ * returns 0 on success and otherwise failure.
1354913575 */
13550- static int TLSX_ExpandEchOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
13576+ static int TLSX_ECH_ExpandOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
1355113577 void* heap)
1355213578{
1355313579 int ret = 0;
13580+ int headerSz;
1355413581 const byte* innerCh;
1355513582 word32 innerChLen;
1355613583 const byte* outerCh;
@@ -13578,7 +13605,14 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1357813605 if (ech == NULL || ech->innerClientHello == NULL || ech->aad == NULL)
1357913606 return BAD_FUNC_ARG;
1358013607
13581- innerCh = ech->innerClientHello + HANDSHAKE_HEADER_SZ;
13608+ #ifdef WOLFSSL_DTLS13
13609+ headerSz = ssl->options.dtls ? DTLS13_HANDSHAKE_HEADER_SZ :
13610+ HANDSHAKE_HEADER_SZ;
13611+ #else
13612+ headerSz = HANDSHAKE_HEADER_SZ;
13613+ #endif
13614+
13615+ innerCh = ech->innerClientHello + headerSz;
1358213616 innerChLen = ech->innerClientHelloLen;
1358313617 outerCh = ech->aad;
1358413618 outerChLen = ech->aadLen;
@@ -13649,8 +13683,8 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1364913683 outerRefTypes = innerCh + idx + 1;
1365013684 numOuterRefs = outerExtListLen / OPAQUE16_LEN;
1365113685
13652- ret = EchCopyOuterExtensions (outerCh, outerChLen, NULL, &extraSize ,
13653- numOuterRefs, outerRefTypes);
13686+ ret = TLSX_ECH_CopyOuterExtensions (outerCh, outerChLen, NULL,
13687+ &extraSize, numOuterRefs, outerRefTypes);
1365413688 if (ret != 0)
1365513689 return ret;
1365613690 }
@@ -13659,16 +13693,16 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1365913693 }
1366013694
1366113695 newInnerChLen = innerChLen - echOuterExtLen + extraSize - sessionIdLen +
13662- ssl->session->sessionIDSz;
13696+ ssl->session->sessionIDSz;
1366313697
1366413698 if (!foundEchOuter && sessionIdLen == ssl->session->sessionIDSz) {
1366513699 /* no extensions + no sessionID to copy */
1366613700 WOLFSSL_MSG("ECH: no EchOuterExtensions extension found");
1366713701 return ret;
1366813702 }
1366913703 else {
13670- newInnerCh = (byte*)XMALLOC(newInnerChLen + HANDSHAKE_HEADER_SZ , heap,
13671- DYNAMIC_TYPE_TMP_BUFFER);
13704+ newInnerCh = (byte*)XMALLOC(newInnerChLen + headerSz , heap,
13705+ DYNAMIC_TYPE_TMP_BUFFER);
1367213706 if (newInnerCh == NULL)
1367313707 return MEMORY_E;
1367413708 }
@@ -13678,7 +13712,7 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1367813712 * AddTls13HandShakeHeader() in DoTls13ClientHello(). */
1367913713
1368013714 /* copy everything up to EchOuterExtensions */
13681- newInnerChRef = newInnerCh + HANDSHAKE_HEADER_SZ ;
13715+ newInnerChRef = newInnerCh + headerSz ;
1368213716 copyLen = OPAQUE16_LEN + RAN_LEN;
1368313717 XMEMCPY(newInnerChRef, innerCh, copyLen);
1368413718 newInnerChRef += copyLen;
@@ -13700,24 +13734,22 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1370013734 }
1370113735 else {
1370213736 copyLen = echOuterExtIdx - OPAQUE16_LEN - RAN_LEN - OPAQUE8_LEN -
13703- sessionIdLen;
13737+ sessionIdLen;
1370413738 XMEMCPY(newInnerChRef, innerCh + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN +
13705- sessionIdLen, copyLen);
13739+ sessionIdLen, copyLen);
1370613740 newInnerChRef += copyLen;
1370713741
1370813742 /* update extensions length in the new ClientHello */
13709- innerExtIdx = innerExtIdx - sessionIdLen + ssl->session->sessionIDSz;
1371013743 c16toa(innerExtLen - echOuterExtLen + (word16)extraSize,
13711- newInnerChRef - OPAQUE16_LEN);
13744+ newInnerChRef - OPAQUE16_LEN);
1371213745
13713- /* insert expanded extensions from outer ClientHello */
13714- ret = EchCopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
13746+ ret = TLSX_ECH_CopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
1371513747 &newInnerChLen, numOuterRefs, outerRefTypes);
1371613748 if (ret == 0) {
1371713749 /* copy remaining extensions after ech_outer_extensions */
1371813750 copyLen = innerChLen - (echOuterExtIdx + echOuterExtLen);
1371913751 XMEMCPY(newInnerChRef, innerCh + echOuterExtIdx + echOuterExtLen,
13720- copyLen);
13752+ copyLen);
1372113753
1372213754 WOLFSSL_MSG("ECH: expanded ech_outer_extensions successfully");
1372313755 }
@@ -13972,13 +14004,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1397214004 echConfig = echConfig->next;
1397314005 }
1397414006 }
13975- /* if we failed to extract, set state to retry configs */
13976- if (ret != 0) {
13977- XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
13978- ech->innerClientHello = NULL;
13979- ech->state = ECH_WRITE_RETRY_CONFIGS;
13980- }
13981- else {
14007+ if (ret == 0) {
1398214008 i = 0;
1398314009 /* decrement until before the padding */
1398414010 while (ech->innerClientHello[ech->innerClientHelloLen +
@@ -13988,15 +14014,15 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1398814014 /* subtract the length of the padding from the length */
1398914015 ech->innerClientHelloLen -= i;
1399014016
13991- /* expand EchOuterExtensions if present */
13992- ret = TLSX_ExpandEchOuterExtensions(ssl, ech, ssl->heap);
13993- if ( ret != 0) {
13994- WOLFSSL_MSG_EX("ECH: failed to expand EchOuterExtensions");
13995- XFREE(ech->innerClientHello, ssl->heap,
13996- DYNAMIC_TYPE_TMP_BUFFER);
13997- ech->innerClientHello = NULL ;
13998- ech->state = ECH_WRITE_RETRY_CONFIGS ;
13999- }
14017+ /* expand EchOuterExtensions if present
14018+ * and, if it exists, copy sessionID from outer hello */
14019+ ret = TLSX_ECH_ExpandOuterExtensions(ssl, ech, ssl->heap);
14020+ }
14021+ /* if we failed to extract/expand, set state to retry configs */
14022+ if (ret != 0) {
14023+ XFREE( ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER) ;
14024+ ech->innerClientHello = NULL ;
14025+ ech->state = ECH_WRITE_RETRY_CONFIGS;
1400014026 }
1400114027 XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1400214028 return 0;
0 commit comments