Merge pull request #10166 from JeremiahM37/test-coverage

Add negative tests for TLS handshake verification paths
This commit is contained in:
Sean Parkinson
2026-04-17 10:41:53 +10:00
committed by GitHub
4 changed files with 691 additions and 2 deletions
+222
View File
@@ -899,3 +899,225 @@ int test_tls_set_curves_list_ecc_fallback(void)
return EXPECT_RESULT();
}
#if !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
static int test_tls12_find_client_finished(const struct test_memio_ctx* test_ctx,
int* finishedMsgPos, int* finishedOffInMsg, int* finishedLen)
{
int i;
const char* msg = NULL;
int msgSz = 0;
int ccsPos = -1;
*finishedMsgPos = -1;
*finishedOffInMsg = -1;
*finishedLen = 0;
for (i = 0; i < test_ctx->s_msg_count; i++) {
if (test_memio_get_message(test_ctx, 0, &msg, &msgSz, i) != 0 ||
msgSz < RECORD_HEADER_SZ) {
return -1;
}
if ((byte)msg[0] == change_cipher_spec) {
ccsPos = i;
break;
}
}
if (ccsPos >= 0 &&
test_memio_get_message(test_ctx, 0, &msg, &msgSz, ccsPos + 1) == 0 &&
msgSz >= RECORD_HEADER_SZ && (byte)msg[0] == handshake) {
*finishedMsgPos = ccsPos + 1;
*finishedOffInMsg = 0;
*finishedLen = msgSz;
return 0;
}
if (test_ctx->s_msg_count == 1) {
int off = 0;
while (off + RECORD_HEADER_SZ <= test_ctx->s_len) {
word16 recLen;
int totalLen;
ato16(test_ctx->s_buff + off + 3, &recLen);
totalLen = RECORD_HEADER_SZ + recLen;
if (off + totalLen > test_ctx->s_len) {
return -1;
}
if (test_ctx->s_buff[off] == change_cipher_spec) {
int nextOff = off + totalLen;
if (nextOff + RECORD_HEADER_SZ > test_ctx->s_len ||
test_ctx->s_buff[nextOff] != handshake) {
return -1;
}
ato16(test_ctx->s_buff + nextOff + 3, &recLen);
totalLen = RECORD_HEADER_SZ + recLen;
if (nextOff + totalLen > test_ctx->s_len) {
return -1;
}
*finishedMsgPos = 0;
*finishedOffInMsg = nextOff;
*finishedLen = totalLen;
return 0;
}
off += totalLen;
}
}
return -1;
}
#endif
/* Test that a corrupted TLS 1.2 Finished verify_data is properly rejected
* with VERIFY_FINISHED_ERROR. We let the client queue its second flight,
* remove the Finished record from the memio queue, allow the server to
* process up through CCS, then inject a corrupted Finished record. */
int test_tls12_corrupted_finished(void)
{
EXPECT_DECLS;
#if !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
char finishedMsg[1024];
int finishedSz = (int)sizeof(finishedMsg);
int finishedMsgPos = -1;
int finishedOffInMsg = -1;
int finishedLen = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
/* Step 1: Client sends ClientHello */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 2: Server sends ServerHello..ServerHelloDone */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 3: Client processes server flight and queues its second flight. */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
if (EXPECT_SUCCESS()) {
ExpectIntEQ(test_tls12_find_client_finished(&test_ctx, &finishedMsgPos,
&finishedOffInMsg, &finishedLen), 0);
ExpectIntGT(finishedLen, 0);
if (finishedOffInMsg == 0) {
ExpectIntEQ(test_memio_copy_message(&test_ctx, 0, finishedMsg,
&finishedSz, finishedMsgPos), 0);
ExpectIntEQ(test_memio_drop_message(&test_ctx, 0, finishedMsgPos), 0);
}
else {
ExpectIntGE(finishedSz, finishedLen);
XMEMCPY(finishedMsg, test_ctx.s_buff + finishedOffInMsg, finishedLen);
finishedSz = finishedLen;
ExpectIntEQ(test_memio_modify_message_len(&test_ctx, 0,
finishedMsgPos, finishedOffInMsg), 0);
}
}
/* Step 4: Server processes up through CCS but blocks waiting for Finished. */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
if (EXPECT_SUCCESS()) {
ExpectIntEQ(ssl_s->msgsReceived.got_change_cipher, 1);
ExpectNotNull(ssl_s->hsHashes);
XMEMSET(&ssl_s->hsHashes->verifyHashes, 0xA5,
sizeof(ssl_s->hsHashes->verifyHashes));
ExpectIntEQ(test_memio_inject_message(&test_ctx, 0, finishedMsg,
finishedSz), 0);
}
/* Step 5: Server processes corrupted Finished and must reject it. */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(VERIFY_FINISHED_ERROR));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test the TLS 1.2 peerAuthGood fail-safe checks directly on both sides.
* The client branch sets NO_PEER_VERIFY; the server branch returns a generic
* fatal error from TICKET_SENT before sending its Finished. */
int test_tls12_peerauth_failsafe(void)
{
EXPECT_DECLS;
#if !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
int ret;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
if (EXPECT_SUCCESS()) {
ssl_c->options.connectState = FIRST_REPLY_SECOND;
ssl_c->options.peerAuthGood = 0;
ssl_c->options.sendVerify = 0;
ret = wolfSSL_connect(ssl_c);
ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_get_error(ssl_c, ret),
WC_NO_ERR_TRACE(NO_PEER_VERIFY));
ExpectIntEQ(ssl_c->options.connectState, FIRST_REPLY_SECOND);
}
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ctx_c = NULL;
ctx_s = NULL;
ssl_c = NULL;
ssl_s = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
if (EXPECT_SUCCESS()) {
ssl_s->options.acceptState = TICKET_SENT;
ssl_s->options.peerAuthGood = 0;
ret = wolfSSL_accept(ssl_s);
ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR);
ExpectIntEQ(ssl_s->options.acceptState, TICKET_SENT);
}
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
+5 -1
View File
@@ -33,6 +33,8 @@ int test_tls12_bad_cv_sig_alg(void);
int test_tls12_no_null_compression(void);
int test_tls12_etm_failed_resumption(void);
int test_tls_set_curves_list_ecc_fallback(void);
int test_tls12_corrupted_finished(void);
int test_tls12_peerauth_failsafe(void);
#define TEST_TLS_DECLS \
TEST_DECL_GROUP("tls", test_utils_memio_move_message), \
@@ -45,6 +47,8 @@ int test_tls_set_curves_list_ecc_fallback(void);
TEST_DECL_GROUP("tls", test_tls12_bad_cv_sig_alg), \
TEST_DECL_GROUP("tls", test_tls12_no_null_compression), \
TEST_DECL_GROUP("tls", test_tls12_etm_failed_resumption), \
TEST_DECL_GROUP("tls", test_tls_set_curves_list_ecc_fallback)
TEST_DECL_GROUP("tls", test_tls_set_curves_list_ecc_fallback), \
TEST_DECL_GROUP("tls", test_tls12_corrupted_finished), \
TEST_DECL_GROUP("tls", test_tls12_peerauth_failsafe)
#endif /* TESTS_API_TEST_TLS_H */
+451
View File
@@ -3058,6 +3058,7 @@ static int DERecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
/* Amount actually copied. */
return len;
}
#endif
int test_tls13_duplicate_extension(void)
@@ -3929,3 +3930,453 @@ int test_tls13_short_session_ticket(void)
return EXPECT_RESULT();
}
/* Test that a corrupted TLS 1.3 Finished verify_data is properly rejected
* with VERIFY_FINISHED_ERROR. We run the handshake step-by-step and corrupt
* the server's client_write_MAC_secret before it processes the client's
* Finished, causing the HMAC comparison to fail.
*/
int test_tls13_corrupted_finished(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
/* Step 1: Client sends ClientHello */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 2: Server processes CH, sends SH + EE + Cert + CV + Finished */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 3: Client processes server flight, verifies server Finished,
* sends client Finished */
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
/* Corrupt the server's client_write_MAC_secret so that when it computes
* the expected Finished HMAC, the result won't match the client's actual
* Finished message. */
if (EXPECT_SUCCESS()) {
XMEMSET(ssl_s->keys.client_write_MAC_secret, 0xFF,
sizeof(ssl_s->keys.client_write_MAC_secret));
}
/* Step 4: Server processes client Finished - should fail */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(VERIFY_FINISHED_ERROR));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test the TLS 1.3 peerAuthGood fail-safe checks on both sides.
* The client branch queues a real server flight before forcing
* FIRST_REPLY_SECOND on a live handshake object, and the server branch clears
* peerAuthGood just before processing the client's Finished.
*/
int test_tls13_peerauth_failsafe(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
int ret;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
if (EXPECT_SUCCESS()) {
/* Queue ClientHello and server flight. */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ssl_c->options.peerAuthGood = 0;
ssl_c->options.sendVerify = 0;
ssl_c->options.connectState = FIRST_REPLY_SECOND;
ret = wolfSSL_connect(ssl_c);
ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR);
ExpectIntEQ(ssl_c->options.connectState, FIRST_REPLY_SECOND);
}
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ctx_c = NULL;
ctx_s = NULL;
ssl_c = NULL;
ssl_s = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
if (EXPECT_SUCCESS()) {
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ssl_s->options.peerAuthGood = 0;
ret = wolfSSL_accept(ssl_s);
ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR);
ExpectIntEQ(ssl_s->options.peerAuthGood, 0);
}
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test that a corrupted HRR cookie HMAC is rejected with HRR_COOKIE_ERROR. */
int test_tls13_hrr_bad_cookie(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_SEND_HRR_COOKIE) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectIntEQ(wolfSSL_send_hrr_cookie(ssl_s, NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_NoKeyShares(ssl_c), WOLFSSL_SUCCESS);
/* Step 1: Client sends CH1 (no key shares) */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 2: Server sends HRR with cookie */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Step 3: Client processes HRR, sends CH2 with cookie */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* Corrupt the server-side cookie secret after HRR so CH2's cookie no longer
* verifies in TlsCheckCookie(). */
if (EXPECT_SUCCESS()) {
ExpectNotNull(ssl_s->buffers.tls13CookieSecret.buffer);
ExpectIntGT(ssl_s->buffers.tls13CookieSecret.length, 0);
ssl_s->buffers.tls13CookieSecret.buffer[
ssl_s->buffers.tls13CookieSecret.length - 1] ^= 0xFF;
}
/* Step 4: Server processes corrupted CH2 - should fail */
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(HRR_COOKIE_ERROR));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test that a TLS 1.3 encrypted record whose inner content type resolves to
* zero is rejected in removeMsgInnerPadding() with PARSE_ERROR and an
* unexpected_message alert. */
int test_tls13_zero_inner_content_type(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
byte record[64];
byte dummy = 0;
char readBuf[8];
int recordSz;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
XMEMSET(&h, 0, sizeof(h));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectIntEQ(wolfSSL_no_ticket_TLSv13(ssl_s), 0);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
if (EXPECT_SUCCESS()) {
ExpectIntEQ(test_ctx.c_len, 0);
ExpectIntEQ(test_ctx.s_len, 0);
recordSz = BuildTls13Message(ssl_c, record, (int)sizeof(record), &dummy,
0, no_type, 0, 0, 0);
ExpectIntGT(recordSz, 0);
ExpectIntEQ(wolfSSL_inject(ssl_s, record, recordSz), WOLFSSL_SUCCESS);
}
ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, (int)sizeof(readBuf)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WC_NO_ERR_TRACE(PARSE_ERROR));
ExpectIntEQ(wolfSSL_get_alert_history(ssl_s, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_tx.code, unexpected_message);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/* Test that a TLS 1.3-capable client rejects downgrade sentinels in a
* downgraded ServerHello random for both TLS 1.2 and TLS 1.1-or-lower. */
int test_tls13_downgrade_sentinel(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
int randomOff = 11 + 24;
static const byte downgradeTls12[8] = {
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01
};
#ifndef NO_OLD_TLS
static const byte downgradeTls11[8] = {
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00
};
#endif
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
XMEMSET(&h, 0, sizeof(h));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLS_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
if (EXPECT_SUCCESS()) {
ExpectIntGT(test_ctx.c_len, randomOff + (int)sizeof(downgradeTls12));
XMEMCPY(test_ctx.c_buff + randomOff, downgradeTls12,
sizeof(downgradeTls12));
}
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(VERSION_ERROR));
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectTrue(h.last_tx.code == illegal_parameter ||
h.last_tx.code == wolfssl_alert_protocol_version);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#ifndef NO_OLD_TLS
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
XMEMSET(&h, 0, sizeof(h));
ctx_c = NULL;
ctx_s = NULL;
ssl_c = NULL;
ssl_s = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLS_client_method, wolfTLSv1_1_server_method), 0);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
if (EXPECT_SUCCESS()) {
ExpectIntGT(test_ctx.c_len, randomOff + (int)sizeof(downgradeTls11));
XMEMCPY(test_ctx.c_buff + randomOff, downgradeTls11,
sizeof(downgradeTls11));
}
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(VERSION_ERROR));
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectTrue(h.last_tx.code == illegal_parameter ||
h.last_tx.code == wolfssl_alert_protocol_version);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
#endif
return EXPECT_RESULT();
}
/* Test that a TLS 1.3 client rejects ServerHello cipher suites that are not
* TLS 1.3 suites or were not offered by the client. */
int test_tls13_serverhello_bad_cipher_suites(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
!defined(WOLFSSL_NO_TLS12) && \
defined(BUILD_TLS_AES_128_GCM_SHA256) && \
defined(BUILD_TLS_AES_256_GCM_SHA384)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx12_c = NULL;
WOLFSSL_CTX *ctx12_s = NULL;
WOLFSSL *ssl12_c = NULL;
WOLFSSL *ssl12_s = NULL;
struct test_memio_ctx test_ctx12;
int suiteOff;
byte tls12Suite0 = 0;
byte tls12Suite = 0;
XMEMSET(&test_ctx12, 0, sizeof(test_ctx12));
ExpectIntEQ(test_memio_setup(&test_ctx12, &ctx12_c, &ctx12_s, &ssl12_c,
&ssl12_s, wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(test_memio_do_handshake(ssl12_c, ssl12_s, 10, NULL), 0);
if (EXPECT_SUCCESS()) {
tls12Suite0 = ssl12_c->options.cipherSuite0;
tls12Suite = ssl12_c->options.cipherSuite;
ExpectIntNE(tls12Suite0, TLS13_BYTE);
}
wolfSSL_free(ssl12_c);
wolfSSL_CTX_free(ctx12_c);
wolfSSL_free(ssl12_s);
wolfSSL_CTX_free(ctx12_s);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
suiteOff = 44 + (byte)test_ctx.c_buff[43];
if (EXPECT_SUCCESS()) {
ExpectIntGT(test_ctx.c_len, suiteOff + 1);
ExpectNotNull(ssl_c->suites);
ssl_c->suites->suiteSz = 2;
ssl_c->suites->suites[0] = tls12Suite0;
ssl_c->suites->suites[1] = tls12Suite;
test_ctx.c_buff[suiteOff + 0] = tls12Suite0;
test_ctx.c_buff[suiteOff + 1] = tls12Suite;
}
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(INVALID_PARAMETER));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ctx_c = NULL;
ctx_s = NULL;
ssl_c = NULL;
ssl_s = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
suiteOff = 44 + (byte)test_ctx.c_buff[43];
if (EXPECT_SUCCESS()) {
ExpectIntGT(test_ctx.c_len, suiteOff + 1);
test_ctx.c_buff[suiteOff + 0] = TLS13_BYTE;
test_ctx.c_buff[suiteOff + 1] = TLS_AES_256_GCM_SHA384;
}
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WC_NO_ERR_TRACE(INVALID_PARAMETER));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
+13 -1
View File
@@ -46,6 +46,12 @@ int test_tls13_derive_keys_no_key(void);
int test_tls13_pqc_hybrid_truncated_keyshare(void);
int test_tls13_short_session_ticket(void);
int test_tls13_early_data_0rtt_replay(void);
int test_tls13_corrupted_finished(void);
int test_tls13_peerauth_failsafe(void);
int test_tls13_hrr_bad_cookie(void);
int test_tls13_zero_inner_content_type(void);
int test_tls13_downgrade_sentinel(void);
int test_tls13_serverhello_bad_cipher_suites(void);
#define TEST_TLS13_DECLS \
TEST_DECL_GROUP("tls13", test_tls13_apis), \
@@ -69,6 +75,12 @@ int test_tls13_early_data_0rtt_replay(void);
TEST_DECL_GROUP("tls13", test_tls13_pqc_hybrid_truncated_keyshare), \
TEST_DECL_GROUP("tls13", test_tls13_short_session_ticket), \
TEST_DECL_GROUP("tls13", test_tls13_early_data_0rtt_replay), \
TEST_DECL_GROUP("tls13", test_tls13_unknown_ext_rejected)
TEST_DECL_GROUP("tls13", test_tls13_unknown_ext_rejected), \
TEST_DECL_GROUP("tls13", test_tls13_corrupted_finished), \
TEST_DECL_GROUP("tls13", test_tls13_peerauth_failsafe), \
TEST_DECL_GROUP("tls13", test_tls13_hrr_bad_cookie), \
TEST_DECL_GROUP("tls13", test_tls13_zero_inner_content_type), \
TEST_DECL_GROUP("tls13", test_tls13_downgrade_sentinel), \
TEST_DECL_GROUP("tls13", test_tls13_serverhello_bad_cipher_suites)
#endif /* WOLFCRYPT_TEST_TLS13_H */