Skip to content

Commit b67fd6f

Browse files
committed
Fix failing test_dtls_frag_ch
- Add option to disable ECH - InitSuites: clean up DTLS paths - wolfSSL_parse_cipher_list: remove WOLFSSL_MAX_SUITE_SZ setting - wolfSSL_parse_cipher_list: add rationale for keeping ciphersuites - test_dtls_frag_ch: ECH and ciphersuites were pushing the ClientHello message over the fragmentation limit. Disabling ECH and limiting ciphersuites fixes the test.
1 parent d475ecc commit b67fd6f

8 files changed

Lines changed: 95 additions & 38 deletions

File tree

.github/workflows/os-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535
CPPFLAGS=''-DWOLFSSL_DTLS13_NO_HRR_ON_RESUME'' ',
3636
'--enable-experimental --enable-kyber --enable-dtls --enable-dtls13
3737
--enable-dtls-frag-ch',
38+
'--enable-all --enable-dtls13 --enable-dtls-frag-ch',
39+
'--enable-dtls --enable-dtls13 --enable-dtls-frag-ch
40+
--enable-dtls-mtu',
3841
]
3942
name: make check
4043
runs-on: ${{ matrix.os }}

src/internal.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2563,7 +2563,7 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data)
25632563

25642564
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
25652565
/* free all ech configs in the list */
2566-
static void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap)
2566+
void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap)
25672567
{
25682568
WOLFSSL_EchConfig* working_config = configs;
25692569
WOLFSSL_EchConfig* next_config;
@@ -3268,9 +3268,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
32683268
int haveRSAsig = 1;
32693269

32703270
#ifdef WOLFSSL_DTLS
3271-
/* If DTLS v1.2 or later than set tls1_2 flag */
3272-
if (pv.major == DTLS_MAJOR && pv.minor <= DTLSv1_2_MINOR) {
3273-
tls1_2 = 1;
3271+
if (pv.major == DTLS_MAJOR) {
3272+
dtls = 1;
3273+
tls = 1;
3274+
/* May be dead assignments dependent upon configuration */
3275+
(void) dtls;
3276+
(void) tls;
3277+
tls1_2 = pv.minor <= DTLSv1_2_MINOR;
32743278
}
32753279
#endif
32763280

@@ -3381,17 +3385,6 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
33813385
haveRSAsig = 0; /* can't have RSA sig if don't have RSA */
33823386
#endif
33833387

3384-
#ifdef WOLFSSL_DTLS
3385-
if (pv.major == DTLS_MAJOR) {
3386-
dtls = 1;
3387-
tls = 1;
3388-
/* May be dead assignments dependent upon configuration */
3389-
(void) dtls;
3390-
(void) tls;
3391-
tls1_2 = pv.minor <= DTLSv1_2_MINOR;
3392-
}
3393-
#endif
3394-
33953388
#ifdef HAVE_RENEGOTIATION_INDICATION
33963389
if (side == WOLFSSL_CLIENT_END) {
33973390
suites->suites[idx++] = CIPHER_BYTE;
@@ -7512,6 +7505,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
75127505
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
75137506
ssl->options.disallowEncThenMac = ctx->disallowEncThenMac;
75147507
#endif
7508+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
7509+
ssl->options.disableECH = ctx->disableECH;
7510+
#endif
75157511

75167512
/* default alert state (none) */
75177513
ssl->alert_history.last_rx.code = -1;

src/ssl.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,18 @@ int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
553553
return GetEchConfigsEx(ctx->echConfigs, output, outputLen);
554554
}
555555

556+
void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable)
557+
{
558+
if (ctx != NULL) {
559+
ctx->disableECH = !enable;
560+
if (ctx->disableECH) {
561+
TLSX_Remove(&ctx->extensions, TLSX_ECH, ctx->heap);
562+
FreeEchConfigs(ctx->echConfigs, ctx->heap);
563+
ctx->echConfigs = NULL;
564+
}
565+
}
566+
}
567+
556568
/* set the ech config from base64 for our client ssl object, base64 is the
557569
* format ech configs are sent using dns records */
558570
int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
@@ -942,6 +954,18 @@ int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen)
942954
return GetEchConfigsEx(ssl->echConfigs, output, outputLen);
943955
}
944956

957+
void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable)
958+
{
959+
if (ssl != NULL) {
960+
ssl->options.disableECH = !enable;
961+
if (ssl->options.disableECH) {
962+
TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap);
963+
FreeEchConfigs(ssl->echConfigs, ssl->heap);
964+
ssl->echConfigs = NULL;
965+
}
966+
}
967+
}
968+
945969
/* get the raw ech configs from our linked list of ech config structs */
946970
int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen)
947971
{
@@ -8480,10 +8504,6 @@ static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
84808504
}
84818505

84828506
/* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */
8483-
if (suites->suiteSz == 0) {
8484-
WOLFSSL_MSG("Warning suites->suiteSz = 0 set to WOLFSSL_MAX_SUITE_SZ");
8485-
suites->suiteSz = WOLFSSL_MAX_SUITE_SZ;
8486-
}
84878507
#ifdef WOLFSSL_SMALL_STACK
84888508
if (suites->suiteSz > 0) {
84898509
suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL,
@@ -8510,6 +8530,12 @@ static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
85108530
return WOLFSSL_FAILURE;
85118531
}
85128532

8533+
/* The idea in this section is that OpenSSL has two API to set ciphersuites.
8534+
* - SSL_CTX_set_cipher_list for setting TLS <= 1.2 suites
8535+
* - SSL_CTX_set_ciphersuites for setting TLS 1.3 suites
8536+
* Since we direct both API here we attempt to provide API compatibility. If
8537+
* we only get suites from <= 1.2 or == 1.3 then we will only update those
8538+
* suites and keep the suites from the other group. */
85138539
for (i = 0; i < suitesCpySz &&
85148540
suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) {
85158541
/* Check for duplicates */

src/tls.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12083,6 +12083,11 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1208312083
if (size == 0)
1208412084
return BAD_FUNC_ARG;
1208512085

12086+
if (ssl->options.disableECH) {
12087+
WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
12088+
return 0;
12089+
}
12090+
1208612091
if (msgType == encrypted_extensions) {
1208712092
ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
1208812093

@@ -13588,18 +13593,21 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
1358813593
#endif
1358913594
#if defined(HAVE_ECH)
1359013595
/* GREASE ECH */
13591-
if (ssl->echConfigs == NULL) {
13592-
ret = GREASE_ECH_USE(&(ssl->extensions), ssl->heap, ssl->rng);
13593-
}
13594-
else if (ssl->echConfigs != NULL) {
13595-
ret = ECH_USE(ssl->echConfigs, &(ssl->extensions), ssl->heap,
13596-
ssl->rng);
13596+
if (!ssl->options.disableECH) {
13597+
if (ssl->echConfigs == NULL) {
13598+
ret = GREASE_ECH_USE(&(ssl->extensions), ssl->heap,
13599+
ssl->rng);
13600+
}
13601+
else if (ssl->echConfigs != NULL) {
13602+
ret = ECH_USE(ssl->echConfigs, &(ssl->extensions),
13603+
ssl->heap, ssl->rng);
13604+
}
1359713605
}
1359813606
#endif
1359913607
}
1360013608
#if defined(HAVE_ECH)
1360113609
else if (IsAtLeastTLSv1_3(ssl->version)) {
13602-
if (ssl->ctx->echConfigs != NULL) {
13610+
if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
1360313611
ret = SERVER_ECH_USE(&(ssl->extensions), ssl->heap,
1360413612
ssl->ctx->echConfigs);
1360513613

@@ -13789,7 +13797,8 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
1378913797
}
1379013798
#endif
1379113799
#if defined(HAVE_ECH)
13792-
if (ssl->options.useEch == 1 && msgType == client_hello) {
13800+
if (ssl->options.useEch == 1 && !ssl->options.disableECH
13801+
&& msgType == client_hello) {
1379313802
ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
1379413803
if (ret != 0)
1379513804
return ret;
@@ -14034,7 +14043,8 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
1403414043
#endif
1403514044
#endif
1403614045
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
14037-
if (ssl->options.useEch == 1 && msgType == client_hello) {
14046+
if (ssl->options.useEch == 1 && !ssl->options.disableECH
14047+
&& msgType == client_hello) {
1403814048
ret = TLSX_WriteWithEch(ssl, output, semaphore,
1403914049
msgType, &offset);
1404014050
if (ret != 0)

src/tls13.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4415,7 +4415,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
44154415

44164416
/* find length of outer and inner */
44174417
#if defined(HAVE_ECH)
4418-
if (ssl->options.useEch == 1) {
4418+
if (ssl->options.useEch == 1 && !ssl->options.disableECH) {
44194419
TLSX* echX = TLSX_Find(ssl->extensions, TLSX_ECH);
44204420
if (echX == NULL)
44214421
return -1;
@@ -4566,7 +4566,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
45664566

45674567
#if defined(HAVE_ECH)
45684568
/* write inner then outer */
4569-
if (ssl->options.useEch == 1) {
4569+
if (ssl->options.useEch == 1 && !ssl->options.disableECH) {
45704570
/* set the type to inner */
45714571
args->ech->type = ECH_TYPE_INNER;
45724572

@@ -4626,7 +4626,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
46264626

46274627
#if defined(HAVE_ECH)
46284628
/* encrypt and pack the ech innerClientHello */
4629-
if (ssl->options.useEch == 1) {
4629+
if (ssl->options.useEch == 1 && !ssl->options.disableECH) {
46304630
ret = TLSX_FinalizeEch(args->ech,
46314631
args->output + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ,
46324632
(word32)(args->sendSz - (RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ)));
@@ -4656,11 +4656,9 @@ int SendTls13ClientHello(WOLFSSL* ssl)
46564656
{
46574657
#if defined(HAVE_ECH)
46584658
/* compute the inner hash */
4659-
if (ssl->options.useEch == 1) {
4659+
if (ssl->options.useEch == 1 && !ssl->options.disableECH)
46604660
ret = EchHashHelloInner(ssl, args->ech);
4661-
}
46624661
#endif
4663-
46644662
/* compute the outer hash */
46654663
if (ret == 0)
46664664
ret = HashOutput(ssl, args->output, (int)args->idx, 0);
@@ -5475,7 +5473,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
54755473

54765474
#if defined(HAVE_ECH)
54775475
/* check for acceptConfirmation and HashInput with 8 0 bytes */
5478-
if (ssl->options.useEch == 1) {
5476+
if (ssl->options.useEch == 1 && !ssl->options.disableECH) {
54795477
ret = EchCheckAcceptance(ssl, input, args->serverRandomOffset, (int)helloSz);
54805478
if (ret != 0)
54815479
return ret;
@@ -6935,7 +6933,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
69356933
goto exit_dch;
69366934

69376935
#if defined(HAVE_ECH)
6938-
if (ssl->ctx->echConfigs != NULL) {
6936+
if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
69396937
/* save the start of the buffer so we can use it when parsing ech */
69406938
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
69416939

@@ -7407,7 +7405,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
74077405
#endif /* WOLFSSL_DTLS13 */
74087406
{
74097407
#if defined(HAVE_ECH)
7410-
if (ssl->ctx->echConfigs != NULL) {
7408+
if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
74117409
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
74127410

74137411
if (echX == NULL)

tests/api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88883,6 +88883,20 @@ static int test_dtls_frag_ch(void)
8888388883
/* Expect quietly dropping fragmented first CH */
8888488884
ExpectIntEQ(test_ctx.c_len, 0);
8888588885

88886+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
88887+
/* Disable ECH as it pushes it over our MTU */
88888+
wolfSSL_SetEchEnable(ssl_c, 0);
88889+
#endif
88890+
88891+
/* Limit options to make the CH a fixed length */
88892+
/* See wolfSSL_parse_cipher_list for reason why we provide 1.3 AND 1.2
88893+
* ciphersuite. This is only necessary when building with OPENSSL_EXTRA. */
88894+
ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"
88895+
#ifdef OPENSSL_EXTRA
88896+
":DHE-RSA-AES256-GCM-SHA384"
88897+
#endif
88898+
));
88899+
8888688900
/* CH1 */
8888788901
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
8888888902
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);

wolfssl/internal.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3088,6 +3088,8 @@ WOLFSSL_LOCAL int GetEchConfig(WOLFSSL_EchConfig* config, byte* output,
30883088

30893089
WOLFSSL_LOCAL int GetEchConfigsEx(WOLFSSL_EchConfig* configs,
30903090
byte* output, word32* outputLen);
3091+
3092+
WOLFSSL_LOCAL void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap);
30913093
#endif
30923094

30933095
struct TLSX {
@@ -3806,6 +3808,9 @@ struct WOLFSSL_CTX {
38063808
#endif
38073809
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP)
38083810
byte dtlsSctp:1; /* DTLS-over-SCTP mode */
3811+
#endif
3812+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
3813+
byte disableECH:1;
38093814
#endif
38103815
word16 minProto:1; /* sets min to min available */
38113816
word16 maxProto:1; /* sets max to max available */
@@ -4957,7 +4962,8 @@ struct Options {
49574962
word16 useDtlsCID:1;
49584963
#endif /* WOLFSSL_DTLS_CID */
49594964
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
4960-
word16 useEch:1;
4965+
word16 useEch:1; /* Do we have a valid config */
4966+
byte disableECH:1; /* Did the user disable ech */
49614967
#endif
49624968
#ifdef WOLFSSL_SEND_HRR_COOKIE
49634969
word16 cookieGood:1;

wolfssl/ssl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,8 @@ WOLFSSL_API int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx,
988988
WOLFSSL_API int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
989989
word32* outputLen);
990990

991+
WOLFSSL_API void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable);
992+
991993
WOLFSSL_API int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
992994
word32 echConfigs64Len);
993995

@@ -996,6 +998,8 @@ WOLFSSL_API int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs,
996998

997999
WOLFSSL_API int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* echConfigs,
9981000
word32* echConfigsLen);
1001+
1002+
WOLFSSL_API void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable);
9991003
#endif /* WOLFSSL_TLS13 && HAVE_ECH */
10001004

10011005
#ifdef HAVE_POLY1305

0 commit comments

Comments
 (0)