@@ -13407,10 +13407,20 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType)
1340713407 return (int)size;
1340813408}
1340913409
13410- /* locate the given extension type, use the extOffset to start off after where a
13411- * previous call to this function ended */
13412- static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
13413- word16 extType, word16* extLen, word16* extOffset,
13410+ /* Locate the given extension type, use the extOffset to start off after where a
13411+ * previous call to this function ended
13412+ *
13413+ * outerCh The outer ClientHello buffer.
13414+ * chLen Outer ClientHello length.
13415+ * extType Extension type to look for.
13416+ * extLen Out parameter, length of found extension.
13417+ * extOffset Offset into outer ClientHello to look for extension from.
13418+ * extensionsStart Start of outer ClientHello extensions.
13419+ * extensionsLen Length of outer ClientHello extensions.
13420+ * returns 0 on success and otherwise failure.
13421+ */
13422+ static const byte* TLSX_ECH_FindOuterExtension(const byte* outerCh,
13423+ word32 chLen, word16 extType, word16* extLen, word16* extOffset,
1341413424 word16* extensionsStart, word16* extensionsLen)
1341513425{
1341613426 word32 idx = *extOffset;
@@ -13472,10 +13482,19 @@ static const byte* EchFindOuterExtension(const byte* outerCh, word32 chLen,
1347213482 return NULL;
1347313483}
1347413484
13475- /* if newInnerCh is NULL, validate ordering and existence of references
13476- * - updates newInnerChLen with total length of selected extensions
13477- * if not NULL, copy extensions into the provided buffer */
13478- static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
13485+ /* If newinnerCh is NULL, validate ordering and existence of references
13486+ * - updates newInnerChLen with total length of selected extensions
13487+ * If newinnerCh in not NULL, copy extensions into newInnerCh
13488+ *
13489+ * outerCh The outer ClientHello buffer.
13490+ * outerChLen Outer ClientHello length.
13491+ * newInnerCh The inner ClientHello buffer.
13492+ * newInnerChLen Inner ClientHello length.
13493+ * numOuterRefs Number of references described by OuterExtensions extension.
13494+ * numOuterTypes References described by OuterExtensions extension.
13495+ * returns 0 on success and otherwise failure.
13496+ */
13497+ static int TLSX_ECH_CopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1347913498 byte** newInnerCh, word32* newInnerChLen,
1348013499 word16 numOuterRefs, const byte* outerRefTypes)
1348113500{
@@ -13499,9 +13518,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1349913518 break;
1350013519 }
1350113520
13502- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13503- refType, &outerExtLen, &outerExtOffset,
13504- &extsStart, &extsLen);
13521+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13522+ refType, &outerExtLen, &outerExtOffset,
13523+ &extsStart, &extsLen);
1350513524
1350613525 if (outerExtData == NULL) {
1350713526 WOLFSSL_MSG("ECH: referenced extension not in outer CH");
@@ -13518,9 +13537,9 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1351813537 while (numOuterRefs-- > 0) {
1351913538 ato16(outerRefTypes, &refType);
1352013539
13521- outerExtData = EchFindOuterExtension (outerCh, outerChLen,
13522- refType, &outerExtLen, &outerExtOffset,
13523- &extsStart, &extsLen);
13540+ outerExtData = TLSX_ECH_FindOuterExtension (outerCh, outerChLen,
13541+ refType, &outerExtLen, &outerExtOffset,
13542+ &extsStart, &extsLen);
1352413543
1352513544 if (outerExtData == NULL) {
1352613545 ret = INVALID_PARAMETER;
@@ -13537,13 +13556,21 @@ static int EchCopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1353713556 return ret;
1353813557}
1353913558
13540- /* expand ech_outer_extensions in the inner ClientHello by copying referenced
13541- * extensions from the outer ClientHello
13559+ /* Expand ech_outer_extensions in the inner ClientHello by copying referenced
13560+ * extensions from the outer ClientHello.
13561+ * If the sessionID exists in the outer ClientHello then also copy that into the
13562+ * expanded inner ClientHello.
13563+ *
13564+ * ssl SSL/TLS object.
13565+ * ech ECH object.
13566+ * heap Heap hint.
13567+ * returns 0 on success and otherwise failure.
1354213568 */
13543- static int TLSX_ExpandEchOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
13569+ static int TLSX_ECH_ExpandOuterExtensions (WOLFSSL* ssl, WOLFSSL_ECH* ech,
1354413570 void* heap)
1354513571{
1354613572 int ret = 0;
13573+ int headerSz;
1354713574 const byte* innerCh;
1354813575 word32 innerChLen;
1354913576 const byte* outerCh;
@@ -13571,7 +13598,14 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1357113598 if (ech == NULL || ech->innerClientHello == NULL || ech->aad == NULL)
1357213599 return BAD_FUNC_ARG;
1357313600
13574- innerCh = ech->innerClientHello + HANDSHAKE_HEADER_SZ;
13601+ #ifdef WOLFSSL_DTLS13
13602+ headerSz = ssl->options.dtls ? DTLS13_HANDSHAKE_HEADER_SZ :
13603+ HANDSHAKE_HEADER_SZ;
13604+ #else
13605+ headerSz = HANDSHAKE_HEADER_SZ;
13606+ #endif
13607+
13608+ innerCh = ech->innerClientHello + headerSz;
1357513609 innerChLen = ech->innerClientHelloLen;
1357613610 outerCh = ech->aad;
1357713611 outerChLen = ech->aadLen;
@@ -13642,8 +13676,8 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1364213676 outerRefTypes = innerCh + idx + 1;
1364313677 numOuterRefs = outerExtListLen / OPAQUE16_LEN;
1364413678
13645- ret = EchCopyOuterExtensions (outerCh, outerChLen, NULL, &extraSize ,
13646- numOuterRefs, outerRefTypes);
13679+ ret = TLSX_ECH_CopyOuterExtensions (outerCh, outerChLen, NULL,
13680+ &extraSize, numOuterRefs, outerRefTypes);
1364713681 if (ret != 0)
1364813682 return ret;
1364913683 }
@@ -13652,16 +13686,16 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1365213686 }
1365313687
1365413688 newInnerChLen = innerChLen - echOuterExtLen + extraSize - sessionIdLen +
13655- ssl->session->sessionIDSz;
13689+ ssl->session->sessionIDSz;
1365613690
1365713691 if (!foundEchOuter && sessionIdLen == ssl->session->sessionIDSz) {
1365813692 /* no extensions + no sessionID to copy */
1365913693 WOLFSSL_MSG("ECH: no EchOuterExtensions extension found");
1366013694 return ret;
1366113695 }
1366213696 else {
13663- newInnerCh = (byte*)XMALLOC(newInnerChLen + HANDSHAKE_HEADER_SZ , heap,
13664- DYNAMIC_TYPE_TMP_BUFFER);
13697+ newInnerCh = (byte*)XMALLOC(newInnerChLen + headerSz , heap,
13698+ DYNAMIC_TYPE_TMP_BUFFER);
1366513699 if (newInnerCh == NULL)
1366613700 return MEMORY_E;
1366713701 }
@@ -13671,7 +13705,7 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1367113705 * AddTls13HandShakeHeader() in DoTls13ClientHello(). */
1367213706
1367313707 /* copy everything up to EchOuterExtensions */
13674- newInnerChRef = newInnerCh + HANDSHAKE_HEADER_SZ ;
13708+ newInnerChRef = newInnerCh + headerSz ;
1367513709 copyLen = OPAQUE16_LEN + RAN_LEN;
1367613710 XMEMCPY(newInnerChRef, innerCh, copyLen);
1367713711 newInnerChRef += copyLen;
@@ -13693,24 +13727,22 @@ static int TLSX_ExpandEchOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
1369313727 }
1369413728 else {
1369513729 copyLen = echOuterExtIdx - OPAQUE16_LEN - RAN_LEN - OPAQUE8_LEN -
13696- sessionIdLen;
13730+ sessionIdLen;
1369713731 XMEMCPY(newInnerChRef, innerCh + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN +
13698- sessionIdLen, copyLen);
13732+ sessionIdLen, copyLen);
1369913733 newInnerChRef += copyLen;
1370013734
1370113735 /* update extensions length in the new ClientHello */
13702- innerExtIdx = innerExtIdx - sessionIdLen + ssl->session->sessionIDSz;
1370313736 c16toa(innerExtLen - echOuterExtLen + (word16)extraSize,
13704- newInnerChRef - OPAQUE16_LEN);
13737+ newInnerChRef - OPAQUE16_LEN);
1370513738
13706- /* insert expanded extensions from outer ClientHello */
13707- ret = EchCopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
13739+ ret = TLSX_ECH_CopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
1370813740 &newInnerChLen, numOuterRefs, outerRefTypes);
1370913741 if (ret == 0) {
1371013742 /* copy remaining extensions after ech_outer_extensions */
1371113743 copyLen = innerChLen - (echOuterExtIdx + echOuterExtLen);
1371213744 XMEMCPY(newInnerChRef, innerCh + echOuterExtIdx + echOuterExtLen,
13713- copyLen);
13745+ copyLen);
1371413746
1371513747 WOLFSSL_MSG("ECH: expanded ech_outer_extensions successfully");
1371613748 }
@@ -13965,13 +13997,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1396513997 echConfig = echConfig->next;
1396613998 }
1396713999 }
13968- /* if we failed to extract, set state to retry configs */
13969- if (ret != 0) {
13970- XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
13971- ech->innerClientHello = NULL;
13972- ech->state = ECH_WRITE_RETRY_CONFIGS;
13973- }
13974- else {
14000+ if (ret == 0) {
1397514001 i = 0;
1397614002 /* decrement until before the padding */
1397714003 while (ech->innerClientHello[ech->innerClientHelloLen +
@@ -13981,15 +14007,15 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1398114007 /* subtract the length of the padding from the length */
1398214008 ech->innerClientHelloLen -= i;
1398314009
13984- /* expand EchOuterExtensions if present */
13985- ret = TLSX_ExpandEchOuterExtensions(ssl, ech, ssl->heap);
13986- if ( ret != 0) {
13987- WOLFSSL_MSG_EX("ECH: failed to expand EchOuterExtensions");
13988- XFREE(ech->innerClientHello, ssl->heap,
13989- DYNAMIC_TYPE_TMP_BUFFER);
13990- ech->innerClientHello = NULL ;
13991- ech->state = ECH_WRITE_RETRY_CONFIGS ;
13992- }
14010+ /* expand EchOuterExtensions if present
14011+ * and, if it exists, copy sessionID from outer hello */
14012+ ret = TLSX_ECH_ExpandOuterExtensions(ssl, ech, ssl->heap);
14013+ }
14014+ /* if we failed to extract/expand, set state to retry configs */
14015+ if (ret != 0) {
14016+ XFREE( ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER) ;
14017+ ech->innerClientHello = NULL ;
14018+ ech->state = ECH_WRITE_RETRY_CONFIGS;
1399314019 }
1399414020 XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1399514021 return 0;
0 commit comments