@@ -16086,11 +16086,18 @@ static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX,
1608616086
1608716087 if (serverNameX == NULL && ssl->ctx && ssl->ctx->extensions) {
1608816088 serverNameX = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
16089- extensions = &ssl->ctx->extensions;
16089+ if (serverNameX != NULL)
16090+ extensions = &ssl->ctx->extensions;
16091+ }
16092+
16093+ /* ECH requires an inner SNI to be present for ClientHelloInner.
16094+ * Without it, fail instead of mutating extension lists. */
16095+ if (serverNameX == NULL) {
16096+ ret = BAD_FUNC_ARG;
1609016097 }
1609116098
1609216099 /* store the inner server name */
16093- if (serverNameX != NULL) {
16100+ if (ret == 0 && serverNameX != NULL) {
1609416101 char* hostName = ((SNI*)serverNameX->data)->data.host_name;
1609516102 word32 hostNameSz = (word32)XSTRLEN(hostName) + 1;
1609616103
@@ -16101,15 +16108,19 @@ static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX,
1610116108 XMEMCPY(serverName, hostName, hostNameSz);
1610216109 }
1610316110
16104- /* remove the inner server name */
16105- TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap);
16111+ /* only swap the SNI if one was found; extensions is non-NULL if an
16112+ * SNI entry was found on ssl->extensions or ctx->extensions */
16113+ if (ret == 0 && extensions != NULL) {
16114+ /* remove the inner server name */
16115+ TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap);
1610616116
16107- /* set the public name as the server name */
16108- if ((ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME,
16109- ((WOLFSSL_ECH*)echX->data)->echConfig->publicName,
16110- XSTRLEN(((WOLFSSL_ECH*)echX->data)->echConfig->publicName),
16111- ssl->heap)) == WOLFSSL_SUCCESS)
16112- ret = 0;
16117+ /* set the public name as the server name */
16118+ if ((ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME,
16119+ ((WOLFSSL_ECH*)echX->data)->echConfig->publicName,
16120+ XSTRLEN(((WOLFSSL_ECH*)echX->data)->echConfig->publicName),
16121+ ssl->heap)) == WOLFSSL_SUCCESS)
16122+ ret = 0;
16123+ }
1611316124 }
1611416125 *pServerNameX = serverNameX;
1611516126 *pExtensions = extensions;
@@ -16122,10 +16133,12 @@ static int TLSX_EchRestoreSNI(WOLFSSL* ssl, char* serverName,
1612216133{
1612316134 int ret = 0;
1612416135
16125- if (serverNameX != NULL) {
16126- /* remove the public name SNI */
16136+ /* always remove the publicName SNI we injected, regardless of whether
16137+ * there was a prior inner SNI to restore */
16138+ if (extensions != NULL)
1612716139 TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap);
1612816140
16141+ if (serverNameX != NULL) {
1612916142 /* restore the inner server name */
1613016143 ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME,
1613116144 serverName, XSTRLEN(serverName), ssl->heap);
0 commit comments