@@ -2233,9 +2233,10 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
22332233 byte type;
22342234 byte matched;
22352235#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2236+ TLSX* echX = NULL;
22362237 WOLFSSL_ECH* ech = NULL;
22372238 WOLFSSL_EchConfig* workingConfig;
2238- TLSX* echX ;
2239+ word16 privateNameLen ;
22392240#endif
22402241#endif /* !NO_WOLFSSL_SERVER */
22412242 TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
@@ -2266,6 +2267,15 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
22662267 #endif
22672268 }
22682269
2270+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2271+ if (!ssl->options.disableECH) {
2272+ echX = TLSX_Find(ssl->extensions, TLSX_ECH);
2273+ if (echX != NULL) {
2274+ ech = (WOLFSSL_ECH*)(echX->data);
2275+ }
2276+ }
2277+ #endif
2278+
22692279#ifndef NO_WOLFSSL_SERVER
22702280 if (!extension || !extension->data) {
22712281 /* This will keep SNI even though TLSX_UseSNI has not been called.
@@ -2282,11 +2292,32 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
22822292 if (cacheOnly) {
22832293 WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
22842294 }
2295+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2296+ else if (ech != NULL && ech->sniState != ECH_OUTER_SNI) {
2297+ /* verifying the outer SNI is not necessary, but the inner SNI does
2298+ * need to be verified - so error when server SNI does not exist and
2299+ * ECH is being used */
2300+ SendAlert(ssl, alert_fatal, UNKNOWN_SNI_HOST_NAME_E);
2301+ WOLFSSL_ERROR_VERBOSE(UNKNOWN_SNI_HOST_NAME_E);
2302+ return UNKNOWN_SNI_HOST_NAME_E;
2303+ }
2304+ #endif
22852305 else {
22862306 /* Skipping, SNI not enabled at server side. */
22872307 return 0;
22882308 }
22892309 }
2310+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2311+ else if (ech != NULL && ech->sniState == ECH_INNER_SNI) {
2312+ if (ssl->ctx->sniRecvCb) {
2313+ cacheOnly = 1;
2314+ }
2315+
2316+ if (cacheOnly) {
2317+ WOLFSSL_MSG("Forcing SSL object to store SNI parameter (inner)");
2318+ }
2319+ }
2320+ #endif
22902321
22912322 if (OPAQUE16_LEN > length)
22922323 return BUFFER_ERROR;
@@ -2315,24 +2346,58 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23152346 if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
23162347 return 0; /* not using this type of SNI. */
23172348
2318- #ifdef WOLFSSL_TLS13
2349+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2350+ if (ech != NULL && ech->sniState == ECH_INNER_SNI){
2351+ /* SNI status is carried over from processing the outer hello so it is
2352+ * necessary to clear it before processing the inner hello */
2353+ ech->sniState = ECH_INNER_SNI_ATTEMPT;
2354+ if (sni != NULL){
2355+ sni->status = WOLFSSL_SNI_NO_MATCH;
2356+ }
2357+ }
2358+ else if (ech != NULL && ech->sniState == ECH_OUTER_SNI &&
2359+ ech->privateName == NULL && sni != NULL){
2360+ /* save the private SNI before it is overwritten by the public SNI */
2361+ privateNameLen = (word16)XSTRLEN(sni->data.host_name) + 1;
2362+ ech->privateName = (char*)XMALLOC(privateNameLen, ssl->heap,
2363+ DYNAMIC_TYPE_TMP_BUFFER);
2364+ if (ech->privateName == NULL)
2365+ return MEMORY_E;
2366+ XMEMCPY((char*)ech->privateName, sni->data.host_name,
2367+ privateNameLen);
2368+ }
2369+ #endif
2370+
2371+ #if defined(WOLFSSL_TLS13)
23192372 /* Don't process the second ClientHello SNI extension if there
23202373 * was problems with the first.
23212374 */
2322- if (!cacheOnly && sni->status != 0 )
2375+ if (!cacheOnly && sni->status != WOLFSSL_SNI_NO_MATCH )
23232376 return 0;
23242377#endif
2325- matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
2326- XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
23272378
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);
2379+ #if defined(HAVE_ECH)
2380+ if (ech != NULL && ech->sniState == ECH_INNER_SNI_ATTEMPT) {
2381+ if (ech->privateName != NULL) {
2382+ matched = cacheOnly || (XSTRLEN(ech->privateName) == size &&
2383+ XSTRNCMP(ech->privateName, (const char*)input + offset,
2384+ size) == 0);
2385+ }
2386+ else {
2387+ matched = cacheOnly;
2388+ }
2389+ }
2390+ else
2391+ #endif
2392+ {
2393+ matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
2394+ XSTRNCMP(sni->data.host_name, (const char*)input + offset,
2395+ size) == 0);
2396+ }
23322397
2333- if (!matched && ech != NULL) {
2398+ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2399+ if (!matched && ech != NULL && ech->sniState == ECH_OUTER_SNI) {
23342400 workingConfig = ech->echConfig;
2335-
23362401 while (workingConfig != NULL) {
23372402 matched = XSTRLEN(workingConfig->publicName) == size &&
23382403 XSTRNCMP(workingConfig->publicName,
@@ -2350,6 +2415,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23502415 int matchStat;
23512416 int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
23522417 ssl->heap);
2418+
23532419 if (r != WOLFSSL_SUCCESS)
23542420 return r; /* throws error. */
23552421
@@ -13886,12 +13952,12 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1388613952 byte* aadCopy;
1388713953 byte* readBuf_p = (byte*)readBuf;
1388813954 WOLFSSL_MSG("TLSX_ECH_Parse");
13889- if (size == 0)
13890- return BAD_FUNC_ARG;
1389113955 if (ssl->options.disableECH) {
1389213956 WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
1389313957 return 0;
1389413958 }
13959+ if (size == 0)
13960+ return BAD_FUNC_ARG;
1389513961 /* retry configs */
1389613962 if (msgType == encrypted_extensions) {
1389713963 ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
@@ -13900,7 +13966,8 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1390013966 ret = 0;
1390113967 }
1390213968 /* HRR with special confirmation */
13903- else if (msgType == hello_retry_request && ssl->options.useEch) {
13969+ else if (msgType == hello_retry_request && ssl->echConfigs != NULL &&
13970+ !ssl->options.disableECH) {
1390413971 /* length must be 8 */
1390513972 if (size != ECH_ACCEPT_CONFIRMATION_SZ)
1390613973 return BAD_FUNC_ARG;
@@ -14000,6 +14067,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1400014067 if (ret == 0) {
1400114068 i = 0;
1400214069 /* decrement until before the padding */
14070+ /* TODO: verify padding is 0, abort with illegal_parameter */
1400314071 while (ech->innerClientHello[ech->innerClientHelloLen +
1400414072 HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) {
1400514073 i++;
@@ -14035,6 +14103,8 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
1403514103 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403614104 if (ech->hpkeContext != NULL)
1403714105 XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
14106+ if (ech->privateName != NULL)
14107+ XFREE((char*)ech->privateName, heap, DYNAMIC_TYPE_TMP_BUFFER);
1403814108
1403914109 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
1404014110 (void)heap;
@@ -15814,7 +15884,7 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
1581415884 }
1581515885 #endif
1581615886#if defined(HAVE_ECH)
15817- if (ssl->options.useEch == 1 && !ssl->options.disableECH
15887+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1581815888 && msgType == client_hello) {
1581915889 ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
1582015890 if (ret != 0)
@@ -16000,7 +16070,7 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
1600016070 #endif
1600116071#endif
1600216072#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16003- if (ssl->options.useEch == 1 && !ssl->options.disableECH
16073+ if (ssl->echConfigs != NULL && !ssl->options.disableECH
1600416074 && msgType == client_hello) {
1600516075 ret = TLSX_WriteWithEch(ssl, output, semaphore,
1600616076 msgType, &offset);
@@ -17280,7 +17350,8 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
1728017350
1728117351#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1728217352 /* If client used ECH, server HRR must include ECH confirmation */
17283- if (ret == 0 && msgType == hello_retry_request && ssl->options.useEch == 1) {
17353+ if (ret == 0 && msgType == hello_retry_request && ssl->echConfigs != NULL &&
17354+ !ssl->options.disableECH) {
1728417355 TLSX* echX = TLSX_Find(ssl->extensions, TLSX_ECH);
1728517356 if (echX == NULL || ((WOLFSSL_ECH*)echX->data)->confBuf == NULL) {
1728617357 WOLFSSL_MSG("ECH used but HRR missing ECH confirmation");
0 commit comments