@@ -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,50 @@ 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+ matched = cacheOnly || (XSTRLEN(ech->privateName) == size &&
2351+ XSTRNCMP(ech->privateName, (const char*)input + offset, size) == 0);
2352+ }
2353+ else
2354+ #endif
2355+ {
2356+ matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
2357+ XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
2358+ }
23322359
2333- if (!matched && ech != NULL) {
2360+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2361+ if (!matched && ech != NULL && ech->processingInner == 0) {
23342362 workingConfig = ech->echConfig;
2335-
23362363 while (workingConfig != NULL) {
23372364 matched = XSTRLEN(workingConfig->publicName) == size &&
23382365 XSTRNCMP(workingConfig->publicName,
@@ -2348,8 +2375,25 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23482375
23492376 if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
23502377 int matchStat;
2351- int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
2378+ int r;
2379+
2380+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2381+ /* save the private SNI before it is overwritten by the public SNI */
2382+ if (ech != NULL && ech->processingInner == 0 && sni != NULL &&
2383+ ech->privateName == NULL) {
2384+ privateNameLen = (word16)XSTRLEN(sni->data.host_name) + 1;
2385+ ech->privateName = (char*)XMALLOC(privateNameLen, ssl->heap,
2386+ DYNAMIC_TYPE_TMP_BUFFER);
2387+ if (ech->privateName == NULL)
2388+ return MEMORY_E;
2389+ XMEMCPY((char*)ech->privateName, sni->data.host_name,
2390+ privateNameLen);
2391+ }
2392+ #endif
2393+
2394+ r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
23522395 ssl->heap);
2396+
23532397 if (r != WOLFSSL_SUCCESS)
23542398 return r; /* throws error. */
23552399
@@ -13886,12 +13930,12 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1388613930 byte* aadCopy;
1388713931 byte* readBuf_p = (byte*)readBuf;
1388813932 WOLFSSL_MSG("TLSX_ECH_Parse");
13889- if (size == 0)
13890- return BAD_FUNC_ARG;
1389113933 if (ssl->options.disableECH) {
1389213934 WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
1389313935 return 0;
1389413936 }
13937+ if (size == 0)
13938+ return BAD_FUNC_ARG;
1389513939 /* retry configs */
1389613940 if (msgType == encrypted_extensions) {
1389713941 ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
@@ -13900,7 +13944,8 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1390013944 ret = 0;
1390113945 }
1390213946 /* HRR with special confirmation */
13903- else if (msgType == hello_retry_request && ssl->options.useEch) {
13947+ else if (msgType == hello_retry_request && ssl->echConfigs != NULL &&
13948+ !ssl->options.disableECH) {
1390413949 /* length must be 8 */
1390513950 if (size != ECH_ACCEPT_CONFIRMATION_SZ)
1390613951 return BAD_FUNC_ARG;
@@ -14000,6 +14045,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1400014045 if (ret == 0) {
1400114046 i = 0;
1400214047 /* decrement until before the padding */
14048+ /* TODO: verify padding is 0, abort with illegal_parameter */
1400314049 while (ech->innerClientHello[ech->innerClientHelloLen +
1400414050 HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) {
1400514051 i++;
@@ -14035,6 +14081,8 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
1403514081 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403614082 if (ech->hpkeContext != NULL)
1403714083 XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
14084+ if (ech->privateName != NULL)
14085+ XFREE((char*)ech->privateName, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403814086
1403914087 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
1404014088 (void)heap;
@@ -15814,7 +15862,7 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
1581415862 }
1581515863 #endif
1581615864#if defined(HAVE_ECH)
15817- if (ssl->options.useEch == 1 && !ssl->options.disableECH
15865+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1581815866 && msgType == client_hello) {
1581915867 ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
1582015868 if (ret != 0)
@@ -16000,7 +16048,7 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
1600016048 #endif
1600116049#endif
1600216050#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16003- if (ssl->options.useEch == 1 && !ssl->options.disableECH
16051+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1600416052 && msgType == client_hello) {
1600516053 ret = TLSX_WriteWithEch(ssl, output, semaphore,
1600616054 msgType, &offset);
@@ -17280,7 +17328,8 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
1728017328
1728117329#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1728217330 /* If client used ECH, server HRR must include ECH confirmation */
17283- if (ret == 0 && msgType == hello_retry_request && ssl->options.useEch == 1) {
17331+ if (ret == 0 && msgType == hello_retry_request && ssl->echConfigs != NULL &&
17332+ !ssl->options.disableECH) {
1728417333 TLSX* echX = TLSX_Find(ssl->extensions, TLSX_ECH);
1728517334 if (echX == NULL || ((WOLFSSL_ECH*)echX->data)->confBuf == NULL) {
1728617335 WOLFSSL_MSG("ECH used but HRR missing ECH confirmation");
0 commit comments