Skip to content

Commit e86f84d

Browse files
committed
Fix TLSX_Parse to check dup ECH
1 parent 178e10e commit e86f84d

3 files changed

Lines changed: 107 additions & 0 deletions

File tree

src/tls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17043,6 +17043,9 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
1704317043
#ifdef WOLFSSL_QUIC
1704417044
|| (type == TLSX_KEY_QUIC_TP_PARAMS_DRAFT)
1704517045
#endif
17046+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
17047+
|| (type == TLSX_ECH)
17048+
#endif
1704617049
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
1704717050
|| (type == TLSX_CKS)
1704817051
#endif

tests/api/test_tls13.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,108 @@ int test_tls13_duplicate_extension(void)
29222922
}
29232923

29242924

2925+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
2926+
!defined(NO_WOLFSSL_SERVER) && !defined(NO_FILESYSTEM) && \
2927+
(!defined(NO_RSA) || defined(HAVE_ECC))
2928+
static int DupEchSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
2929+
{
2930+
(void)ssl;
2931+
(void)buf;
2932+
(void)sz;
2933+
(void)ctx;
2934+
2935+
return sz;
2936+
}
2937+
static int DupEchRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
2938+
{
2939+
WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
2940+
int len = (int)msg->length;
2941+
2942+
(void)ssl;
2943+
(void)sz;
2944+
2945+
if (len > sz)
2946+
len = sz;
2947+
XMEMCPY(buf, msg->buffer, len);
2948+
msg->buffer += len;
2949+
msg->length -= len;
2950+
2951+
return len;
2952+
}
2953+
#endif
2954+
2955+
/* Test detection of duplicate ECH extension (type 0xfe0d) in ClientHello.
2956+
* ECH has a semaphore mapping in TLSX_ToSemaphore() and needs to be included
2957+
* in the duplicate-detection gate in TLSX_Parse(). RFC 8446 section 4.2
2958+
* requires rejecting messages with duplicate extensions.
2959+
*/
2960+
int test_tls13_duplicate_ech_extension(void)
2961+
{
2962+
EXPECT_DECLS;
2963+
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
2964+
!defined(NO_WOLFSSL_SERVER) && !defined(NO_FILESYSTEM) && \
2965+
(!defined(NO_RSA) || defined(HAVE_ECC))
2966+
/* TLS 1.3 ClientHello with two ECH extensions (type 0xfe0d).
2967+
* Extensions block contains: supported_versions + ECH + ECH (dup). */
2968+
const unsigned char clientHelloDupEch[] = {
2969+
0x16, 0x03, 0x03, 0x00, 0x40, 0x01, 0x00, 0x00,
2970+
0x3c, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
2971+
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2972+
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2973+
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2974+
0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x13, 0x01,
2975+
0x01, 0x00, 0x00, 0x11, 0x00, 0x2b, 0x00, 0x03,
2976+
0x02, 0x03, 0x04, 0xfe, 0x0d, 0x00, 0x01, 0x00,
2977+
0xfe, 0x0d, 0x00, 0x01, 0x00
2978+
};
2979+
WOLFSSL_BUFFER_INFO msg;
2980+
const char* testCertFile;
2981+
const char* testKeyFile;
2982+
WOLFSSL_CTX *ctx = NULL;
2983+
WOLFSSL *ssl = NULL;
2984+
2985+
#ifndef NO_RSA
2986+
testCertFile = svrCertFile;
2987+
testKeyFile = svrKeyFile;
2988+
#elif defined(HAVE_ECC)
2989+
testCertFile = eccCertFile;
2990+
testKeyFile = eccKeyFile;
2991+
#endif
2992+
2993+
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
2994+
2995+
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
2996+
CERT_FILETYPE));
2997+
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
2998+
CERT_FILETYPE));
2999+
3000+
/* Read from 'msg'. */
3001+
wolfSSL_SetIORecv(ctx, DupEchRecv);
3002+
/* No where to send to - dummy sender. */
3003+
wolfSSL_SetIOSend(ctx, DupEchSend);
3004+
3005+
ssl = wolfSSL_new(ctx);
3006+
ExpectNotNull(ssl);
3007+
3008+
msg.buffer = (unsigned char*)clientHelloDupEch;
3009+
msg.length = (unsigned int)sizeof(clientHelloDupEch);
3010+
wolfSSL_SetIOReadCtx(ssl, &msg);
3011+
3012+
ExpectIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
3013+
/* Can return duplicate ext error or socket error if the peer closed
3014+
* down while sending alert. */
3015+
if (wolfSSL_get_error(ssl, 0) != WC_NO_ERR_TRACE(SOCKET_ERROR_E)) {
3016+
ExpectIntEQ(wolfSSL_get_error(ssl, 0),
3017+
WC_NO_ERR_TRACE(DUPLICATE_TLS_EXT_E));
3018+
}
3019+
3020+
wolfSSL_free(ssl);
3021+
wolfSSL_CTX_free(ctx);
3022+
#endif
3023+
return EXPECT_RESULT();
3024+
}
3025+
3026+
29253027
int test_key_share_mismatch(void)
29263028
{
29273029
EXPECT_DECLS;

tests/api/test_tls13.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int test_tls13_ch2_different_cs(void);
3636
int test_tls13_sg_missing(void);
3737
int test_tls13_ks_missing(void);
3838
int test_tls13_duplicate_extension(void);
39+
int test_tls13_duplicate_ech_extension(void);
3940
int test_key_share_mismatch(void);
4041
int test_tls13_middlebox_compat_empty_session_id(void);
4142
int test_tls13_plaintext_alert(void);
@@ -59,6 +60,7 @@ int test_tls13_short_session_ticket(void);
5960
TEST_DECL_GROUP("tls13", test_tls13_sg_missing), \
6061
TEST_DECL_GROUP("tls13", test_tls13_ks_missing), \
6162
TEST_DECL_GROUP("tls13", test_tls13_duplicate_extension), \
63+
TEST_DECL_GROUP("tls13", test_tls13_duplicate_ech_extension), \
6264
TEST_DECL_GROUP("tls13", test_key_share_mismatch), \
6365
TEST_DECL_GROUP("tls13", test_tls13_middlebox_compat_empty_session_id), \
6466
TEST_DECL_GROUP("tls13", test_tls13_plaintext_alert), \

0 commit comments

Comments
 (0)