@@ -2236,6 +2236,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
22362236 WOLFSSL_ECH* ech = NULL;
22372237 WOLFSSL_EchConfig* workingConfig;
22382238 TLSX* echX;
2239+ word16 privateNameLen;
22392240#endif
22402241#endif /* !NO_WOLFSSL_SERVER */
22412242 TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
@@ -2315,24 +2316,56 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23152316 if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
23162317 return 0; /* not using this type of SNI. */
23172318
2318- #ifdef WOLFSSL_TLS13
2319+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2320+ echX = TLSX_Find(ssl->extensions, TLSX_ECH);
2321+ if (echX != NULL)
2322+ ech = (WOLFSSL_ECH*)(echX->data);
2323+
2324+ /* SNI status is carried over from processing the outer hello so it is
2325+ * necessary to clear it before processing the inner hello */
2326+ if (ech != NULL && ech->processingInner == 1) {
2327+ ech->processingInner = 2;
2328+ sni->status = 0;
2329+
2330+ if (ssl->ctx->sniRecvCb) {
2331+ cacheOnly = 1;
2332+ }
2333+
2334+ if (cacheOnly) {
2335+ WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
2336+ }
2337+ }
2338+ #endif
2339+
2340+ #if defined(WOLFSSL_TLS13)
23192341 /* Don't process the second ClientHello SNI extension if there
23202342 * was problems with the first.
23212343 */
23222344 if (!cacheOnly && sni->status != 0)
23232345 return 0;
23242346#endif
2325- matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
2326- XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
23272347
2328- #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2329- echX = TLSX_Find(ssl->extensions, TLSX_ECH);
2330- if (echX != NULL)
2331- ech = (WOLFSSL_ECH*)(echX->data);
2348+ #if defined(HAVE_ECH)
2349+ if (ech != NULL && ech->processingInner == 2) {
2350+ if (ech->privateName != NULL) {
2351+ matched = cacheOnly || (XSTRLEN(ech->privateName) == size &&
2352+ XSTRNCMP(ech->privateName, (const char*)input + offset,
2353+ size) == 0);
2354+ }
2355+ else {
2356+ matched = 0;
2357+ }
2358+ }
2359+ else
2360+ #endif
2361+ {
2362+ matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
2363+ XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
2364+ }
23322365
2333- if (!matched && ech != NULL) {
2366+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2367+ if (!matched && ech != NULL && ech->processingInner == 0) {
23342368 workingConfig = ech->echConfig;
2335-
23362369 while (workingConfig != NULL) {
23372370 matched = XSTRLEN(workingConfig->publicName) == size &&
23382371 XSTRNCMP(workingConfig->publicName,
@@ -2348,8 +2381,25 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23482381
23492382 if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
23502383 int matchStat;
2351- int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
2384+ int r;
2385+
2386+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2387+ /* save the private SNI before it is overwritten by the public SNI */
2388+ if (ech != NULL && ech->processingInner == 0 && sni != NULL &&
2389+ ech->privateName == NULL) {
2390+ privateNameLen = (word16)XSTRLEN(sni->data.host_name) + 1;
2391+ ech->privateName = (char*)XMALLOC(privateNameLen, ssl->heap,
2392+ DYNAMIC_TYPE_TMP_BUFFER);
2393+ if (ech->privateName == NULL)
2394+ return MEMORY_E;
2395+ XMEMCPY((char*)ech->privateName, sni->data.host_name,
2396+ privateNameLen);
2397+ }
2398+ #endif
2399+
2400+ r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
23522401 ssl->heap);
2402+
23532403 if (r != WOLFSSL_SUCCESS)
23542404 return r; /* throws error. */
23552405
@@ -13886,12 +13936,12 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1388613936 byte* aadCopy;
1388713937 byte* readBuf_p = (byte*)readBuf;
1388813938 WOLFSSL_MSG("TLSX_ECH_Parse");
13889- if (size == 0)
13890- return BAD_FUNC_ARG;
1389113939 if (ssl->options.disableECH) {
1389213940 WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
1389313941 return 0;
1389413942 }
13943+ if (size == 0)
13944+ return BAD_FUNC_ARG;
1389513945 /* retry configs */
1389613946 if (msgType == encrypted_extensions) {
1389713947 ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
@@ -13900,7 +13950,8 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1390013950 ret = 0;
1390113951 }
1390213952 /* HRR with special confirmation */
13903- else if (msgType == hello_retry_request && ssl->options.useEch) {
13953+ else if (msgType == hello_retry_request && ssl->echConfigs != NULL &&
13954+ !ssl->options.disableECH) {
1390413955 /* length must be 8 */
1390513956 if (size != ECH_ACCEPT_CONFIRMATION_SZ)
1390613957 return BAD_FUNC_ARG;
@@ -14000,6 +14051,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1400014051 if (ret == 0) {
1400114052 i = 0;
1400214053 /* decrement until before the padding */
14054+ /* TODO: verify padding is 0, abort with illegal_parameter */
1400314055 while (ech->innerClientHello[ech->innerClientHelloLen +
1400414056 HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) {
1400514057 i++;
@@ -14035,6 +14087,8 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
1403514087 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403614088 if (ech->hpkeContext != NULL)
1403714089 XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
14090+ if (ech->privateName != NULL)
14091+ XFREE((char*)ech->privateName, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403814092
1403914093 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
1404014094 (void)heap;
@@ -15814,7 +15868,7 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
1581415868 }
1581515869 #endif
1581615870#if defined(HAVE_ECH)
15817- if (ssl->options.useEch == 1 && !ssl->options.disableECH
15871+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1581815872 && msgType == client_hello) {
1581915873 ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
1582015874 if (ret != 0)
@@ -16000,7 +16054,7 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
1600016054 #endif
1600116055#endif
1600216056#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16003- if (ssl->options.useEch == 1 && !ssl->options.disableECH
16057+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1600416058 && msgType == client_hello) {
1600516059 ret = TLSX_WriteWithEch(ssl, output, semaphore,
1600616060 msgType, &offset);
@@ -17280,7 +17334,8 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
1728017334
1728117335#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1728217336 /* If client used ECH, server HRR must include ECH confirmation */
17283- if (ret == 0 && msgType == hello_retry_request && ssl->options.useEch == 1) {
17337+ if (ret == 0 && msgType == hello_retry_request && ssl->echConfigs != NULL &&
17338+ !ssl->options.disableECH) {
1728417339 TLSX* echX = TLSX_Find(ssl->extensions, TLSX_ECH);
1728517340 if (echX == NULL || ((WOLFSSL_ECH*)echX->data)->confBuf == NULL) {
1728617341 WOLFSSL_MSG("ECH used but HRR missing ECH confirmation");
0 commit comments