Skip to content

Commit 9fd88d1

Browse files
correct error propagation for unsupported KEM
1 parent fa6f294 commit 9fd88d1

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

src/ssl_ech.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,15 +612,18 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
612612
}
613613
ato16(echConfig + idx, &hpkePubkeyLen);
614614
idx += 2;
615-
if (hpkePubkeyLen == 0 || hpkePubkeyLen > HPKE_Npk_MAX) {
616-
ret = BUFFER_E;
617-
break;
618-
}
619615
if (idx + hpkePubkeyLen > length) {
620616
ret = BUFFER_E;
621617
break;
622618
}
623-
XMEMCPY(workingConfig->receiverPubkey, echConfig + idx, hpkePubkeyLen);
619+
/* unsupported KEM: skip pubkey; end of loop will free this config */
620+
if (wc_HpkeKemIsSupported(workingConfig->kemId)) {
621+
if (hpkePubkeyLen != wc_HpkeKemGetEncLen(workingConfig->kemId)) {
622+
ret = BUFFER_E;
623+
break;
624+
}
625+
XMEMCPY(workingConfig->receiverPubkey, echConfig + idx, hpkePubkeyLen);
626+
}
624627
idx += hpkePubkeyLen;
625628

626629
/* cipher suites */
@@ -765,7 +768,6 @@ int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen)
765768
return BAD_FUNC_ARG;
766769
}
767770

768-
769771
/* skip over total length which we fill in later */
770772
if (output != NULL) {
771773
workingOutputLen = *outputLen - totalLen;

src/tls.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14288,8 +14288,9 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
1428814288
}
1428914289

1429014290
ret = SetRetryConfigs(ssl, readBuf, (word32)size);
14291-
if (ret == UNSUPPORTED_SUITE || ret == UNSUPPORTED_PROTO_VERSION) {
14292-
WOLFSSL_ERROR_VERBOSE(ret);
14291+
if (ret == WC_NO_ERR_TRACE(UNSUPPORTED_SUITE) ||
14292+
ret == WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION)) {
14293+
WOLFSSL_MSG("ECH retry configs had 'bad version' or 'bad suite'");
1429314294
ret = 0;
1429414295
}
1429514296

tests/api.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14373,6 +14373,10 @@ static int test_wolfSSL_Tls13_ECH_params_b64(void)
1437314373
const char* b64BadVers = "AEX+/gBBFAAgACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
1437414374
/* ech configs with bad/unsupported algorithm */
1437514375
const char* b64BadAlgo = "AEX+DQBBFP7+ACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
14376+
/* ech configs with 0 length algorithm */
14377+
const char* b64BadAlgo0 = "ACX+DQAhFAAgAAAABAABAAEAEmNsb3VkZmxhcmUtZWNoLmNvbQAA";
14378+
/* ech configs with long algorithm */
14379+
const char* b64BadAlgo33 = "AEb+DQBCFAAgACEBbgKECPPpYhFWEG1ygQ3lYE5hdq317ijtpJ4cKze44E4ABAABAAEAEmNsb3VkZmxhcmUtZWNoLmNvbQAA";
1437614380
/* ech configs with bad/unsupported ciphersuite */
1437714381
const char* b64BadCiph = "AEX+DQBBFAAgACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAE/v4AAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
1437814382
/* ech configs with unrecognized mandatory extension */
@@ -14420,6 +14424,18 @@ static int test_wolfSSL_Tls13_ECH_params_b64(void)
1442014424
ExpectIntEQ(UNSUPPORTED_SUITE, wolfSSL_SetEchConfigsBase64(ssl,
1442114425
b64BadAlgo, (word32)XSTRLEN(b64BadAlgo)));
1442214426

14427+
/* bad algorithm with 0 length key */
14428+
ExpectIntEQ(BUFFER_E, wolfSSL_CTX_SetEchConfigsBase64(ctx,
14429+
b64BadAlgo0, (word32)XSTRLEN(b64BadAlgo0)));
14430+
ExpectIntEQ(BUFFER_E, wolfSSL_SetEchConfigsBase64(ssl,
14431+
b64BadAlgo0, (word32)XSTRLEN(b64BadAlgo0)));
14432+
14433+
/* bad algorithm with long key */
14434+
ExpectIntEQ(BUFFER_E, wolfSSL_CTX_SetEchConfigsBase64(ctx,
14435+
b64BadAlgo33, (word32)XSTRLEN(b64BadAlgo33)));
14436+
ExpectIntEQ(BUFFER_E, wolfSSL_SetEchConfigsBase64(ssl,
14437+
b64BadAlgo33, (word32)XSTRLEN(b64BadAlgo33)));
14438+
1442314439
/* bad ciphersuite */
1442414440
ExpectIntEQ(UNSUPPORTED_SUITE, wolfSSL_CTX_SetEchConfigsBase64(ctx,
1442514441
b64BadCiph, (word32)XSTRLEN(b64BadCiph)));
@@ -15134,6 +15150,47 @@ static int test_wolfSSL_Tls13_ECH_retry_configs_auth_fail(void)
1513415150
return EXPECT_RESULT();
1513515151
}
1513615152

15153+
/* Test that bad retry configs (unsupported cipher suite) from the server are
15154+
* ignored rather than propagating an error */
15155+
static int test_wolfSSL_Tls13_ECH_retry_configs_bad(void)
15156+
{
15157+
EXPECT_DECLS;
15158+
test_ssl_memio_ctx test_ctx;
15159+
word32 retryConfigsLen = sizeof(echCbTestConfigs);
15160+
15161+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
15162+
test_ctx.s_cb.method = wolfTLSv1_3_server_method;
15163+
test_ctx.c_cb.method = wolfTLSv1_3_client_method;
15164+
test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready;
15165+
test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready;
15166+
test_ctx.c_cb.ssl_ready = test_ech_client_ssl_ready;
15167+
15168+
ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
15169+
15170+
/* corrupt the server's cipher suite -> ECH decrypt will fail, and retry
15171+
* configs will have an unsupported KDF/AEAD pair.
15172+
* This will trigger the UNSUPPORTED_SUITE path in TLSX_ECH_Parse */
15173+
if (EXPECT_SUCCESS() && test_ctx.s_ctx->echConfigs != NULL &&
15174+
test_ctx.s_ctx->echConfigs->cipherSuites != NULL) {
15175+
test_ctx.s_ctx->echConfigs->cipherSuites[0].aeadId = 0xFEFE;
15176+
}
15177+
15178+
/* bad retry configs are discarded — failure must be ECH_REQUIRED_E,
15179+
* not a retry-config parse error */
15180+
ExpectIntNE(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
15181+
ExpectIntEQ(test_ctx.c_ssl->options.echAccepted, 0);
15182+
ExpectIntEQ(wolfSSL_get_error(test_ctx.c_ssl, 0),
15183+
WC_NO_ERR_TRACE(ECH_REQUIRED_E));
15184+
15185+
/* no retry configs should be stored since they were all unsupported */
15186+
ExpectIntNE(wolfSSL_GetEchRetryConfigs(test_ctx.c_ssl, NULL,
15187+
&retryConfigsLen), WOLFSSL_SUCCESS);
15188+
15189+
test_ssl_memio_cleanup(&test_ctx);
15190+
15191+
return EXPECT_RESULT();
15192+
}
15193+
1513715194
/* Test that client info can be successfully decoded from one of multiple server
1513815195
* ECH configs
1513915196
* In this case the server is expected to try it's first config, fail, then try
@@ -37040,6 +37097,7 @@ TEST_CASE testCases[] = {
3704037097
TEST_DECL(test_wolfSSL_Tls13_ECH_no_private_name),
3704137098
TEST_DECL(test_wolfSSL_Tls13_ECH_bad_configs),
3704237099
TEST_DECL(test_wolfSSL_Tls13_ECH_retry_configs),
37100+
TEST_DECL(test_wolfSSL_Tls13_ECH_retry_configs_bad),
3704337101
TEST_DECL(test_wolfSSL_Tls13_ECH_retry_configs_auth_fail),
3704437102
TEST_DECL(test_wolfSSL_Tls13_ECH_new_config),
3704537103
TEST_DECL(test_wolfSSL_Tls13_ECH_GREASE),

0 commit comments

Comments
 (0)