Skip to content

Commit

Permalink
Merge pull request #7914 from julek-wolfssl/gh/7825
Browse files Browse the repository at this point in the history
Fix failing test_dtls_frag_ch
  • Loading branch information
douzzer authored Sep 5, 2024
2 parents 1c8767b + b67fd6f commit a3fea48
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/os-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
CPPFLAGS=''-DWOLFSSL_DTLS13_NO_HRR_ON_RESUME'' ',
'--enable-experimental --enable-kyber --enable-dtls --enable-dtls13
--enable-dtls-frag-ch',
'--enable-all --enable-dtls13 --enable-dtls-frag-ch',
'--enable-dtls --enable-dtls13 --enable-dtls-frag-ch
--enable-dtls-mtu',
]
name: make check
runs-on: ${{ matrix.os }}
Expand Down
26 changes: 11 additions & 15 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2563,7 +2563,7 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data)

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

#ifdef WOLFSSL_DTLS
/* If DTLS v1.2 or later than set tls1_2 flag */
if (pv.major == DTLS_MAJOR && pv.minor <= DTLSv1_2_MINOR) {
tls1_2 = 1;
if (pv.major == DTLS_MAJOR) {
dtls = 1;
tls = 1;
/* May be dead assignments dependent upon configuration */
(void) dtls;
(void) tls;
tls1_2 = pv.minor <= DTLSv1_2_MINOR;
}
#endif

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

#ifdef WOLFSSL_DTLS
if (pv.major == DTLS_MAJOR) {
dtls = 1;
tls = 1;
/* May be dead assignments dependent upon configuration */
(void) dtls;
(void) tls;
tls1_2 = pv.minor <= DTLSv1_2_MINOR;
}
#endif

#ifdef HAVE_RENEGOTIATION_INDICATION
if (side == WOLFSSL_CLIENT_END) {
suites->suites[idx++] = CIPHER_BYTE;
Expand Down Expand Up @@ -7512,6 +7505,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
ssl->options.disallowEncThenMac = ctx->disallowEncThenMac;
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
ssl->options.disableECH = ctx->disableECH;
#endif

/* default alert state (none) */
ssl->alert_history.last_rx.code = -1;
Expand Down
34 changes: 30 additions & 4 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,18 @@ int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
return GetEchConfigsEx(ctx->echConfigs, output, outputLen);
}

void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable)
{
if (ctx != NULL) {
ctx->disableECH = !enable;
if (ctx->disableECH) {
TLSX_Remove(&ctx->extensions, TLSX_ECH, ctx->heap);
FreeEchConfigs(ctx->echConfigs, ctx->heap);
ctx->echConfigs = NULL;
}
}
}

/* set the ech config from base64 for our client ssl object, base64 is the
* format ech configs are sent using dns records */
int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
Expand Down Expand Up @@ -942,6 +954,18 @@ int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen)
return GetEchConfigsEx(ssl->echConfigs, output, outputLen);
}

void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable)
{
if (ssl != NULL) {
ssl->options.disableECH = !enable;
if (ssl->options.disableECH) {
TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap);
FreeEchConfigs(ssl->echConfigs, ssl->heap);
ssl->echConfigs = NULL;
}
}
}

/* get the raw ech configs from our linked list of ech config structs */
int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen)
{
Expand Down Expand Up @@ -8481,10 +8505,6 @@ static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
}

/* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */
if (suites->suiteSz == 0) {
WOLFSSL_MSG("Warning suites->suiteSz = 0 set to WOLFSSL_MAX_SUITE_SZ");
suites->suiteSz = WOLFSSL_MAX_SUITE_SZ;
}
#ifdef WOLFSSL_SMALL_STACK
if (suites->suiteSz > 0) {
suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL,
Expand All @@ -8511,6 +8531,12 @@ static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
return WOLFSSL_FAILURE;
}

/* The idea in this section is that OpenSSL has two API to set ciphersuites.
* - SSL_CTX_set_cipher_list for setting TLS <= 1.2 suites
* - SSL_CTX_set_ciphersuites for setting TLS 1.3 suites
* Since we direct both API here we attempt to provide API compatibility. If
* we only get suites from <= 1.2 or == 1.3 then we will only update those
* suites and keep the suites from the other group. */
for (i = 0; i < suitesCpySz &&
suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) {
/* Check for duplicates */
Expand Down
28 changes: 19 additions & 9 deletions src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -12083,6 +12083,11 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
if (size == 0)
return BAD_FUNC_ARG;

if (ssl->options.disableECH) {
WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
return 0;
}

if (msgType == encrypted_extensions) {
ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);

Expand Down Expand Up @@ -13588,18 +13593,21 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
#endif
#if defined(HAVE_ECH)
/* GREASE ECH */
if (ssl->echConfigs == NULL) {
ret = GREASE_ECH_USE(&(ssl->extensions), ssl->heap, ssl->rng);
}
else if (ssl->echConfigs != NULL) {
ret = ECH_USE(ssl->echConfigs, &(ssl->extensions), ssl->heap,
ssl->rng);
if (!ssl->options.disableECH) {
if (ssl->echConfigs == NULL) {
ret = GREASE_ECH_USE(&(ssl->extensions), ssl->heap,
ssl->rng);
}
else if (ssl->echConfigs != NULL) {
ret = ECH_USE(ssl->echConfigs, &(ssl->extensions),
ssl->heap, ssl->rng);
}
}
#endif
}
#if defined(HAVE_ECH)
else if (IsAtLeastTLSv1_3(ssl->version)) {
if (ssl->ctx->echConfigs != NULL) {
if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
ret = SERVER_ECH_USE(&(ssl->extensions), ssl->heap,
ssl->ctx->echConfigs);

Expand Down Expand Up @@ -13789,7 +13797,8 @@ int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
}
#endif
#if defined(HAVE_ECH)
if (ssl->options.useEch == 1 && msgType == client_hello) {
if (ssl->options.useEch == 1 && !ssl->options.disableECH
&& msgType == client_hello) {
ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
if (ret != 0)
return ret;
Expand Down Expand Up @@ -14034,7 +14043,8 @@ int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
#endif
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
if (ssl->options.useEch == 1 && msgType == client_hello) {
if (ssl->options.useEch == 1 && !ssl->options.disableECH
&& msgType == client_hello) {
ret = TLSX_WriteWithEch(ssl, output, semaphore,
msgType, &offset);
if (ret != 0)
Expand Down
16 changes: 7 additions & 9 deletions src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -4415,7 +4415,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)

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

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

Expand Down Expand Up @@ -4626,7 +4626,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)

#if defined(HAVE_ECH)
/* encrypt and pack the ech innerClientHello */
if (ssl->options.useEch == 1) {
if (ssl->options.useEch == 1 && !ssl->options.disableECH) {
ret = TLSX_FinalizeEch(args->ech,
args->output + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ,
(word32)(args->sendSz - (RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ)));
Expand Down Expand Up @@ -4656,11 +4656,9 @@ int SendTls13ClientHello(WOLFSSL* ssl)
{
#if defined(HAVE_ECH)
/* compute the inner hash */
if (ssl->options.useEch == 1) {
if (ssl->options.useEch == 1 && !ssl->options.disableECH)
ret = EchHashHelloInner(ssl, args->ech);
}
#endif

/* compute the outer hash */
if (ret == 0)
ret = HashOutput(ssl, args->output, (int)args->idx, 0);
Expand Down Expand Up @@ -5475,7 +5473,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,

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

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

Expand Down Expand Up @@ -7407,7 +7405,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
#endif /* WOLFSSL_DTLS13 */
{
#if defined(HAVE_ECH)
if (ssl->ctx->echConfigs != NULL) {
if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
echX = TLSX_Find(ssl->extensions, TLSX_ECH);

if (echX == NULL)
Expand Down
14 changes: 14 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -93278,6 +93278,20 @@ static int test_dtls_frag_ch(void)
/* Expect quietly dropping fragmented first CH */
ExpectIntEQ(test_ctx.c_len, 0);

#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
/* Disable ECH as it pushes it over our MTU */
wolfSSL_SetEchEnable(ssl_c, 0);
#endif

/* Limit options to make the CH a fixed length */
/* See wolfSSL_parse_cipher_list for reason why we provide 1.3 AND 1.2
* ciphersuite. This is only necessary when building with OPENSSL_EXTRA. */
ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"
#ifdef OPENSSL_EXTRA
":DHE-RSA-AES256-GCM-SHA384"
#endif
));

/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
Expand Down
8 changes: 7 additions & 1 deletion wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3088,6 +3088,8 @@ WOLFSSL_LOCAL int GetEchConfig(WOLFSSL_EchConfig* config, byte* output,

WOLFSSL_LOCAL int GetEchConfigsEx(WOLFSSL_EchConfig* configs,
byte* output, word32* outputLen);

WOLFSSL_LOCAL void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap);
#endif

struct TLSX {
Expand Down Expand Up @@ -3806,6 +3808,9 @@ struct WOLFSSL_CTX {
#endif
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP)
byte dtlsSctp:1; /* DTLS-over-SCTP mode */
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
byte disableECH:1;
#endif
word16 minProto:1; /* sets min to min available */
word16 maxProto:1; /* sets max to max available */
Expand Down Expand Up @@ -4957,7 +4962,8 @@ struct Options {
word16 useDtlsCID:1;
#endif /* WOLFSSL_DTLS_CID */
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
word16 useEch:1;
word16 useEch:1; /* Do we have a valid config */
byte disableECH:1; /* Did the user disable ech */
#endif
#ifdef WOLFSSL_SEND_HRR_COOKIE
word16 cookieGood:1;
Expand Down
4 changes: 4 additions & 0 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,8 @@ WOLFSSL_API int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx,
WOLFSSL_API int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
word32* outputLen);

WOLFSSL_API void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable);

WOLFSSL_API int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
word32 echConfigs64Len);

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

WOLFSSL_API int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* echConfigs,
word32* echConfigsLen);

WOLFSSL_API void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable);
#endif /* WOLFSSL_TLS13 && HAVE_ECH */

#ifdef HAVE_POLY1305
Expand Down

0 comments on commit a3fea48

Please sign in to comment.