Merge pull request #9528 from SparkiDev/tls13_missing_ext_fix

TLS 1.3 missing extension: return correct alert code
This commit is contained in:
Daniel Pouzzner
2025-12-15 11:05:02 -06:00
committed by GitHub
3 changed files with 178 additions and 6 deletions

View File

@@ -16567,15 +16567,18 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
* contain SupportedGroups and vice-versa. */
if (IsAtLeastTLSv1_3(ssl->version) && msgType == client_hello && isRequest) {
int hasKeyShare = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_KEY_SHARE));
int hasSupportedGroups = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
int hasSupportedGroups = !IS_OFF(seenType,
TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
if (hasKeyShare && !hasSupportedGroups) {
WOLFSSL_MSG("ClientHello with KeyShare extension missing required SupportedGroups extension");
return MISSING_HANDSHAKE_DATA;
WOLFSSL_MSG("ClientHello with KeyShare extension missing required "
"SupportedGroups extension");
return INCOMPLETE_DATA;
}
if (hasSupportedGroups && !hasKeyShare) {
WOLFSSL_MSG("ClientHello with SupportedGroups extension missing required KeyShare extension");
return MISSING_HANDSHAKE_DATA;
WOLFSSL_MSG("ClientHello with SupportedGroups extension missing "
"required KeyShare extension");
return INCOMPLETE_DATA;
}
}
#endif

View File

@@ -2318,3 +2318,168 @@ int test_tls13_hrr_different_cs(void)
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_ECC)
/* Called when writing. */
static int MESend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
(void)ssl;
(void)buf;
(void)sz;
(void)ctx;
/* Force error return from wolfSSL_accept_TLSv13(). */
return WANT_WRITE;
}
/* Called when reading. */
static int MERecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
int len = (int)msg->length;
(void)ssl;
(void)sz;
/* Pass back as much of message as will fit in buffer. */
if (len > sz)
len = sz;
XMEMCPY(buf, msg->buffer, len);
/* Move over returned data. */
msg->buffer += len;
msg->length -= len;
/* Amount actually copied. */
return len;
}
#endif
int test_tls13_sg_missing(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_ECC)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
byte clientHello[] = {
0x16, 0x03, 0x03, 0x00, 0xcb, 0x01, 0x00, 0x00,
0xc7, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x20, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x00, 0x02, 0x13, 0x01,
0x01, 0x00, 0x00, 0x7c, 0x00, 0x0d, 0x00, 0x06,
0x00, 0x04, 0x04, 0x01, 0x08, 0x04,
/* KeyShare */
0x00, 0x33,
0x00, 0x67, 0x00, 0x65, 0x00, 0x18, 0x00, 0x61,
0x04, 0x53, 0x3e, 0xe5, 0xbf, 0x40, 0xec, 0x2d,
0x67, 0x98, 0x8b, 0x77, 0xf3, 0x17, 0x48, 0x9b,
0xb6, 0xdf, 0x95, 0x29, 0x25, 0xc7, 0x09, 0xfc,
0x03, 0x81, 0x11, 0x1a, 0x59, 0x56, 0xf2, 0xd7,
0x58, 0x11, 0x0e, 0x59, 0xd3, 0xd7, 0xc1, 0x72,
0x9e, 0x2c, 0x0d, 0x70, 0xea, 0xf7, 0x73, 0xe6,
0x12, 0x01, 0x16, 0x42, 0x6d, 0xe2, 0x43, 0x6a,
0x2f, 0x5f, 0xdd, 0x7f, 0xe5, 0x4f, 0xaf, 0x95,
0x2b, 0x04, 0xfd, 0x13, 0xf5, 0x16, 0xce, 0x62,
0x7f, 0x89, 0xd2, 0x01, 0x9d, 0x4c, 0x87, 0x96,
0x95, 0x9e, 0x43, 0x33, 0xc7, 0x06, 0x5b, 0x49,
0x6c, 0xa6, 0x34, 0xd5, 0xdc, 0x63, 0xbd, 0xe9,
0x1f,
/* SupportedVersions */
0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04
/* Missing SupportedGroups. */
};
WOLFSSL_BUFFER_INFO msg;
WOLFSSL_ALERT_HISTORY h;
/* Set up wolfSSL context. */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
CERT_FILETYPE));
/* Read from 'msg'. */
wolfSSL_SetIORecv(ctx, MERecv);
/* No where to send to - dummy sender. */
wolfSSL_SetIOSend(ctx, MESend);
/* Test cipher suite list with many copies of a cipher suite. */
ExpectNotNull(ssl = wolfSSL_new(ctx));
msg.buffer = clientHello;
msg.length = (unsigned int)sizeof(clientHello);
wolfSSL_SetIOReadCtx(ssl, &msg);
ExpectIntEQ(wolfSSL_accept_TLSv13(ssl),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_tx.code, missing_extension);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
int test_tls13_ks_missing(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_ECC)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
byte clientHello[] = {
0x16, 0x03, 0x03, 0x00, 0x66, 0x01, 0x00, 0x00,
0x62, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x20, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x00, 0x02, 0x13, 0x01,
0x01, 0x00, 0x00, 0x17, 0x00, 0x0d, 0x00, 0x06,
0x00, 0x04, 0x04, 0x01, 0x08, 0x04,
/* SupportedGroups */
0x00, 0x0a,
0x00, 0x02, 0x00, 0x18,
/* SupportedVersions */
0x00, 0x2b, 0x00, 0x03,
0x02, 0x03, 0x04
/* Missing KeyShare. */
};
WOLFSSL_BUFFER_INFO msg;
WOLFSSL_ALERT_HISTORY h;
/* Set up wolfSSL context. */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
CERT_FILETYPE));
/* Read from 'msg'. */
wolfSSL_SetIORecv(ctx, MERecv);
/* No where to send to - dummy sender. */
wolfSSL_SetIOSend(ctx, MESend);
/* Test cipher suite list with many copies of a cipher suite. */
ExpectNotNull(ssl = wolfSSL_new(ctx));
msg.buffer = clientHello;
msg.length = (unsigned int)sizeof(clientHello);
wolfSSL_SetIOReadCtx(ssl, &msg);
ExpectIntEQ(wolfSSL_accept_TLSv13(ssl),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_tx.code, missing_extension);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}

View File

@@ -32,6 +32,8 @@ int test_tls13_pq_groups(void);
int test_tls13_early_data(void);
int test_tls13_same_ch(void);
int test_tls13_hrr_different_cs(void);
int test_tls13_sg_missing(void);
int test_tls13_ks_missing(void);
#define TEST_TLS13_DECLS \
TEST_DECL_GROUP("tls13", test_tls13_apis), \
@@ -41,6 +43,8 @@ int test_tls13_hrr_different_cs(void);
TEST_DECL_GROUP("tls13", test_tls13_pq_groups), \
TEST_DECL_GROUP("tls13", test_tls13_early_data), \
TEST_DECL_GROUP("tls13", test_tls13_same_ch), \
TEST_DECL_GROUP("tls13", test_tls13_hrr_different_cs)
TEST_DECL_GROUP("tls13", test_tls13_hrr_different_cs), \
TEST_DECL_GROUP("tls13", test_tls13_sg_missing), \
TEST_DECL_GROUP("tls13", test_tls13_ks_missing)
#endif /* WOLFCRYPT_TEST_TLS13_H */