From f666a7d4b74a2bc2f40d2cc27e2888f4963930b7 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 21 Feb 2023 09:06:48 +0000 Subject: [PATCH 1/5] internal.c: fix fall_through compilation issues src/internal.c: In function 'SendCertificateVerify': ./wolfssl/wolfcrypt/types.h:345:40: error: attribute 'fallthrough' not preceding a case label or default label [-Werror] 345 | #define FALL_THROUGH ; __attribute__ ((fallthrough)) In file included from ./wolfssl/internal.h:27, from src/internal.c:92: src/internal.c: In function 'SendCertificateVerify': ./wolfssl/wolfcrypt/types.h:345:40: error: attribute 'fallthrough' not preceding a case label or default label [-Werror] 345 | #define FALL_THROUGH ; __attribute__ ((fallthrough)) --- src/internal.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 731495eb3..9b9633f18 100644 --- a/src/internal.c +++ b/src/internal.c @@ -30290,7 +30290,7 @@ int SendCertificateVerify(WOLFSSL* ssl) goto exit_scv; } } - #if defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + #if defined(HAVE_ED25519) || defined(HAVE_ED448) FALL_THROUGH; #endif #endif /* WOLFSSL_CHECK_SIG_FAULTS */ @@ -32381,8 +32381,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_sske; } } - #if defined(HAVE_CURVE25519) || \ - defined(HAVE_CURVE448) + #if defined(HAVE_E25519) || defined(HAVE_ED448) FALL_THROUGH; #endif #endif /* WOLFSSL_CHECK_SIG_FAULTS */ From 7b53baea62144d66d943ffc147e671467a97cd01 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 6 Mar 2023 16:47:57 +0000 Subject: [PATCH 2/5] refactor: more centralized extra alerts on handshake messages' errors: - don't send alerts on WANT_READ, WANT_WRITE and WC_PENDING_E "errors" - use return error code to decide which alert description to send - use alert description handshake_failure in the general case - if a fatal alert was already sent, do not send any new alerts. This allow a more specific alert description in case the exact description can't be derived from the return code --- src/internal.c | 103 +++++++++++++++++++++++++++------------------ wolfssl/internal.h | 1 + 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/internal.c b/src/internal.c index 9b9633f18..da44bcee2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14728,10 +14728,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* SESSION_CERTS */ ret = ProcessPeerCerts(ssl, input, inOutIdx, size); -#ifdef WOLFSSL_EXTRA_ALERTS - if (ret == BUFFER_ERROR || ret == ASN_PARSE_E) - SendAlert(ssl, alert_fatal, decode_error); -#endif #ifdef OPENSSL_EXTRA ssl->options.serverState = SERVER_CERT_COMPLETE; @@ -15008,9 +15004,6 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, if (sniff == NO_SNIFF) { if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){ WOLFSSL_MSG("Verify finished error on hashes"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, decrypt_error); - #endif WOLFSSL_ERROR_VERBOSE(VERIFY_FINISHED_ERROR); return VERIFY_FINISHED_ERROR; } @@ -15134,9 +15127,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) #endif if (ssl->msgsReceived.got_client_hello) { WOLFSSL_MSG("Duplicate ClientHello received"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, unexpected_message); - #endif WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E); return DUPLICATE_MSG_E; } @@ -15428,9 +15418,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) #endif if (ssl->msgsReceived.got_client_key_exchange) { WOLFSSL_MSG("Duplicate ClientKeyExchange received"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, unexpected_message); - #endif WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E); return DUPLICATE_MSG_E; } @@ -15463,9 +15450,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) if (ssl->msgsReceived.got_change_cipher == 0) { WOLFSSL_MSG("Finished received before ChangeCipher"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, unexpected_message); - #endif WOLFSSL_ERROR_VERBOSE(NO_CHANGE_CIPHER_E); return NO_CHANGE_CIPHER_E; } @@ -15519,9 +15503,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) if (!ssl->options.resuming && ssl->msgsReceived.got_client_key_exchange == 0) { WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher"); - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, unexpected_message); - #endif WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E); return OUT_OF_ORDER_E; } @@ -16052,6 +16033,61 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* !WOLFSSL_NO_TLS12 */ +#ifdef WOLFSSL_EXTRA_ALERTS +void SendFatalAlertOnly(WOLFSSL *ssl, int error) +{ + int why; + + /* already sent a more specific fatal alert */ + if (ssl->alert_history.last_tx.level == alert_fatal) + return; + + switch (error) { + /* not fatal errors */ + case WANT_WRITE: + case WANT_READ: + case ZERO_RETURN: +#ifdef WOLFSSL_ASYNC + case WC_PENGIND_E: +#endif + return; + case BUFFER_ERROR: + case ASN_PARSE_E: + case COMPRESSION_ERROR: + why = decode_error; + break; + case MATCH_SUITE_ERROR: + why = illegal_parameter; + break; + case VERIFY_FINISHED_ERROR: + case SIG_VERIFY_E: + why = decrypt_error; + break; + case DUPLICATE_MSG_E: + case NO_CHANGE_CIPHER_E: + case OUT_OF_ORDER_E: + why = unexpected_message; + break; + case ECC_OUT_OF_RANGE_E: + why = bad_record_mac; + break; + case VERSION_ERROR: + default: + why = handshake_failure; + break; + } + + SendAlert(ssl, alert_fatal, why); +} +#else +void SendFatalAlertOnly(WOLFSSL *ssl, int error) +{ + (void)ssl; + (void)error; + /* no op */ +} +#endif /* WOLFSSL_EXTRA_ALERTS */ + #ifdef WOLFSSL_DTLS static int _DtlsCheckWindow(WOLFSSL* ssl) @@ -16456,7 +16492,6 @@ static WC_INLINE int Dtls13UpdateWindow(WOLFSSL* ssl) } #endif /* WOLFSSL_DTLS13 */ - int DtlsMsgDrain(WOLFSSL* ssl) { DtlsMsg* item = ssl->dtls_rx_msg_list; @@ -16482,6 +16517,9 @@ int DtlsMsgDrain(WOLFSSL* ssl) if (ret == 0) { DtlsTxMsgListClean(ssl); } + else if (!IsAtLeastTLSv1_3(ssl->version)) { + SendFatalAlertOnly(ssl, ret); + } #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) { break; @@ -19784,6 +19822,8 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) ssl->buffers.inputBuffer.buffer, &ssl->buffers.inputBuffer.idx, ssl->buffers.inputBuffer.length); + if (ret != 0) + SendFatalAlertOnly(ssl, ret); } #endif #ifdef WOLFSSL_DTLS13 @@ -19820,6 +19860,8 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr) ssl->buffers.inputBuffer.buffer, &ssl->buffers.inputBuffer.idx, ssl->buffers.inputBuffer.length); + if (ret != 0) + SendFatalAlertOnly(ssl, ret); #else ret = BUFFER_ERROR; #endif @@ -33226,9 +33268,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!ssl->options.downgrade) { WOLFSSL_MSG("Client trying to connect with lesser version"); -#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA) - SendAlert(ssl, alert_fatal, handshake_failure); -#endif ret = VERSION_ERROR; goto out; } @@ -33242,9 +33281,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (belowMinDowngrade) { WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); -#if defined(WOLFSSL_EXTRA_ALERTS) || defined(OPENSSL_EXTRA) - SendAlert(ssl, alert_fatal, handshake_failure); -#endif ret = VERSION_ERROR; goto out; } @@ -33742,12 +33778,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ret == 0) ret = MatchSuite(ssl, clSuites); -#ifdef WOLFSSL_EXTRA_ALERTS - if (ret == BUFFER_ERROR) - SendAlert(ssl, alert_fatal, decode_error); - else if (ret < 0) - SendAlert(ssl, alert_fatal, handshake_failure); -#endif #if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_ENCRYPT_THEN_MAC) && \ !defined(WOLFSSL_AEAD_ONLY) if (ret == 0 && ssl->options.encThenMac && @@ -35919,18 +35949,12 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], /* import peer ECC key */ if ((args->idx - args->begin) + OPAQUE8_LEN > size) { - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, decode_error); - #endif ERROR_OUT(BUFFER_ERROR, exit_dcke); } args->length = input[args->idx++]; if ((args->idx - args->begin) + args->length > size) { - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, decode_error); - #endif ERROR_OUT(BUFFER_ERROR, exit_dcke); } @@ -36115,9 +36139,6 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], args->idx += OPAQUE16_LEN; if ((args->idx - args->begin) + clientPubSz > size) { - #ifdef WOLFSSL_EXTRA_ALERTS - SendAlert(ssl, alert_fatal, decode_error); - #endif ERROR_OUT(BUFFER_ERROR, exit_dcke); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 575c3e917..6dd1eac45 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5685,6 +5685,7 @@ WOLFSSL_LOCAL int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek); WOLFSSL_LOCAL int SendFinished(WOLFSSL* ssl); WOLFSSL_LOCAL int RetrySendAlert(WOLFSSL* ssl); WOLFSSL_LOCAL int SendAlert(WOLFSSL* ssl, int severity, int type); +WOLFSSL_LOCAL void SendFatalAlertOnly(WOLFSSL *ssl, int error); WOLFSSL_LOCAL int ProcessReply(WOLFSSL* ssl); WOLFSSL_LOCAL int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr); From 4227f763a825796ee6708b9957c4981ae48db0a2 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 7 Mar 2023 10:40:27 +0000 Subject: [PATCH 3/5] ssl: send alert on bad psk --- src/ssl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 3a5e7d98a..8e31fb10d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13505,6 +13505,12 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #ifdef WOLFSSL_CHECK_ALERT_ON_ERR ProcessReplyEx(ssl, 1); /* See if an alert was sent. */ #endif +#ifdef WOLFSSL_EXTRA_ALERTS + if (ssl->error == NO_PEER_KEY || + ssl->error == PSK_KEY_ERROR) { + SendAlert(ssl, alert_fatal, handshake_failure); + } +#endif WOLFSSL_ERROR(ssl->error); return WOLFSSL_FATAL_ERROR; } From 898fed9a8bc65e1b81b4bccbd6cfd69a57950d8a Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 6 Mar 2023 16:53:39 +0000 Subject: [PATCH 4/5] tests: memio: allow NULL client and/or server ctx --- wolfssl/test.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfssl/test.h b/wolfssl/test.h index 18419975d..3202099b4 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -5375,7 +5375,7 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx, { int ret; - if (*ctx_c == NULL) { + if (ctx_c != NULL && *ctx_c == NULL) { *ctx_c = wolfSSL_CTX_new(method_c()); if (*ctx_c == NULL) return -1; @@ -5391,7 +5391,7 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx, } } - if (*ctx_s == NULL) { + if (ctx_s != NULL && *ctx_s == NULL) { *ctx_s = wolfSSL_CTX_new(method_s()); if (*ctx_s == NULL) return -1; @@ -5412,14 +5412,14 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx, } } - if (ssl_c != NULL) { + if (ctx_c != NULL && ssl_c != NULL) { *ssl_c = wolfSSL_new(*ctx_c); if (*ssl_c == NULL) return -1; wolfSSL_SetIOWriteCtx(*ssl_c, ctx); wolfSSL_SetIOReadCtx(*ssl_c, ctx); } - if (ssl_s != NULL) { + if (ctx_s != NULL && ssl_s != NULL) { *ssl_s = wolfSSL_new(*ctx_s); if (*ssl_s == NULL) return -1; From 94d983f94ad3f7a38969d54403f0ce76e09bbdcb Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 6 Mar 2023 16:54:12 +0000 Subject: [PATCH 5/5] tests: add WOLFSSL_EXTRA_ALERTS tests --- tests/api.c | 329 +++++++++++++++++++++++++++++++++++++++++++++++++ wolfssl/test.h | 9 +- 2 files changed, 337 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index b0d656de0..c8ffaa12b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -63055,7 +63055,333 @@ static int test_TLS_13_ticket_different_ciphers(void) return TEST_SKIPPED; } #endif +#if defined(WOLFSSL_EXTRA_ALERTS) && !defined(WOLFSSL_NO_TLS12) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) +#define TEST_WRONG_CS_CLIENT "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" + +byte test_extra_alerts_wrong_cs_sh[] = { + 0x16, 0x03, 0x03, 0x00, 0x56, 0x02, 0x00, 0x00, 0x52, 0x03, 0x03, 0xef, + 0x0c, 0x30, 0x98, 0xa2, 0xac, 0xfa, 0x68, 0xe9, 0x3e, 0xaa, 0x5c, 0xcf, + 0xa7, 0x42, 0x72, 0xaf, 0xa0, 0xe8, 0x39, 0x2b, 0x3e, 0x81, 0xa7, 0x7a, + 0xa5, 0x62, 0x8a, 0x0e, 0x41, 0xba, 0xda, 0x20, 0x18, 0x9f, 0xe1, 0x8c, + 0x1d, 0xc0, 0x37, 0x9c, 0xf4, 0x90, 0x5d, 0x8d, 0xa0, 0x79, 0xa7, 0x4b, + 0xa8, 0x79, 0xdf, 0xcd, 0x8d, 0xf5, 0xb5, 0x50, 0x5f, 0xf1, 0xdb, 0x4d, + 0xbb, 0x07, 0x54, 0x1c, + 0x00, 0x02, /* TLS_RSA_WITH_NULL_SHA */ + 0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00 +}; + +static int test_extra_alerts_wrong_cs(void) +{ + struct test_memio_ctx test_ctx; + WOLFSSL_CTX *ctx_c = NULL; + WOLFSSL_ALERT_HISTORY h; + WOLFSSL *ssl_c = NULL; + int ret, err; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ret = test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL, + wolfTLSv1_2_client_method, NULL); + if (ret != 0) + return TEST_FAIL; + + ret = wolfSSL_set_cipher_list(ssl_c, TEST_WRONG_CS_CLIENT); + if (ret != WOLFSSL_SUCCESS) { + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + return TEST_SKIPPED; + } + + /* CH */ + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + /* consume CH */ + test_ctx.s_len = 0; + /* inject SH */ + XMEMCPY(test_ctx.c_buff, test_extra_alerts_wrong_cs_sh, + sizeof(test_extra_alerts_wrong_cs_sh)); + test_ctx.c_len = sizeof(test_extra_alerts_wrong_cs_sh); + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err == WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + ret = wolfSSL_get_alert_history(ssl_c, &h); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + if (h.last_tx.code != illegal_parameter) + return TEST_FAIL; + if (h.last_tx.level != alert_fatal) + return TEST_FAIL; + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + + return TEST_SUCCESS; +} +#else +static int test_extra_alerts_wrong_cs(void) +{ + return TEST_SKIPPED; +} +#endif + +#if !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_EXTRA_ALERTS) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) + +static void test_remove_msg(byte *msg, int tail_len, int *len, int msg_length) +{ + tail_len -= msg_length; + XMEMMOVE(msg, msg + msg_length, tail_len); + *len = *len - msg_length; +} + +static int test_remove_hs_msg_from_buffer(byte *buf, int *len, byte type, + byte *found) +{ + const unsigned int _HANDSHAKE_HEADER_SZ = 4; + const unsigned int _RECORD_HEADER_SZ = 5; + const int _change_cipher_hs = 55; + const int _change_cipher = 20; + const int _handshake = 22; + unsigned int tail_len; + byte *idx, *curr; + word8 currType; + word16 rLength; + word32 hLength; + + idx = buf; + tail_len = *len; + *found = 0; + while (tail_len > _RECORD_HEADER_SZ) { + curr = idx; + currType = *idx; + ato16(idx + 3, &rLength); + idx += _RECORD_HEADER_SZ; + tail_len -= _RECORD_HEADER_SZ; + + if (tail_len < rLength) + return -1; + + if (type == _change_cipher_hs && currType == _change_cipher) { + if (rLength != 1) + return -1; + /* match */ + test_remove_msg(curr, *len - (int)(curr - buf), + len, _RECORD_HEADER_SZ + 1); + *found = 1; + return 0; + } + + if (currType != _handshake) { + idx += rLength; + tail_len -= rLength; + continue; + } + + if (rLength < _HANDSHAKE_HEADER_SZ) + return -1; + currType = *idx; + ato24(idx+1, &hLength); + hLength += _HANDSHAKE_HEADER_SZ; + if (tail_len < hLength) + return -1; + if (currType != type) { + idx += hLength; + tail_len -= hLength; + continue; + } + + /* match */ + test_remove_msg(curr, *len - (int)(curr - buf), len, + hLength + _RECORD_HEADER_SZ); + *found = 1; + return 0; + } + + /* not found */ + return 0; +} + +static int test_remove_hs_message(byte hs_message_type, + int extra_round, byte alert_type) +{ + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + WOLFSSL_ALERT_HISTORY h; + int ret, err; + byte found; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfTLSv1_2_client_method, wolfTLSv1_2_server_method); + if (ret != 0) + return TEST_FAIL; + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + ret = wolfSSL_accept(ssl_s); + err = wolfSSL_get_error(ssl_s, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + if (extra_round) { + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + /* this will complete handshake from server side */ + ret = wolfSSL_accept(ssl_s); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + } + + ret = test_remove_hs_msg_from_buffer(test_ctx.c_buff, + &test_ctx.c_len, hs_message_type, &found); + if (ret != 0) + return TEST_FAIL; + + if (!found) { + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + return TEST_SKIPPED; + } + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err == WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + ret = wolfSSL_get_alert_history(ssl_c, &h); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + if (alert_type != 0xff && h.last_tx.code != alert_type) + return TEST_FAIL; + if (h.last_tx.level != alert_fatal) + return TEST_FAIL; + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + + return TEST_SUCCESS; +} + +static int test_extra_alerts_skip_hs(void) +{ + const byte _server_key_exchange = 12; + const byte _server_hello = 2; + const byte _certificate = 11; + int ret; + + /* server_hello */ + ret = test_remove_hs_message(_server_hello, 0, + unexpected_message); + if (ret == TEST_FAIL) + return ret; + ret = test_remove_hs_message(_certificate, 0, + 0xff); + if (ret == TEST_FAIL) + return ret; + ret = test_remove_hs_message(_server_key_exchange, 0, + unexpected_message); + if (ret == TEST_FAIL) + return ret; + + return TEST_SUCCESS; +} +#else +static int test_extra_alerts_skip_hs(void) +{ + return TEST_SKIPPED; +} +#endif + +#if !defined(WOLFSSL_NO_TLS12) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_EXTRA_ALERTS) && !defined(NO_PSK) && !defined(NO_DH) + +static unsigned int test_server_psk_cb(WOLFSSL* ssl, const char* id, + unsigned char* key, unsigned int key_max_len) +{ + (void)ssl; + (void)id; + (void)key_max_len; + /* zero means error */ + key[0] = 0x10; + return 1; +} + +static int test_extra_alerts_bad_psk(void) +{ + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + WOLFSSL_ALERT_HISTORY h; + int ret, err; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfTLSv1_2_client_method, wolfTLSv1_2_server_method); + if (ret != 0) + return TEST_FAIL; + + ret = wolfSSL_set_cipher_list(ssl_c, "DHE-PSK-AES128-GCM-SHA256"); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + + ret = wolfSSL_set_cipher_list(ssl_s, "DHE-PSK-AES128-GCM-SHA256"); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + + wolfSSL_set_psk_server_callback(ssl_s, test_server_psk_cb); + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + ret = wolfSSL_accept(ssl_s); + err = wolfSSL_get_error(ssl_s, ret); + if (ret == WOLFSSL_SUCCESS || err != WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + + ret = wolfSSL_connect(ssl_c); + err = wolfSSL_get_error(ssl_c, ret); + if (ret == WOLFSSL_SUCCESS || err == WOLFSSL_ERROR_WANT_READ) + return TEST_FAIL; + ret = wolfSSL_get_alert_history(ssl_c, &h); + if (ret != WOLFSSL_SUCCESS) + return TEST_FAIL; + if (h.last_tx.code != handshake_failure) + return TEST_FAIL; + if (h.last_tx.level != alert_fatal) + return TEST_FAIL; + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + + return TEST_SUCCESS; +} +#else +static int test_extra_alerts_bad_psk(void) +{ + return TEST_SKIPPED; +} +#endif /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -64072,6 +64398,9 @@ TEST_CASE testCases[] = { TEST_DECL(test_various_pathlen_chains), #endif TEST_DECL(test_ticket_ret_create), + TEST_DECL(test_extra_alerts_wrong_cs), + TEST_DECL(test_extra_alerts_skip_hs), + TEST_DECL(test_extra_alerts_bad_psk), /* If at some point a stub get implemented this test should fail indicating * a need to implement a new test case */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 3202099b4..98e0fc9cc 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -5253,7 +5253,11 @@ void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName); (defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \ !defined(WOLFSSL_TICKET_DECRYPT_NO_CREATE) && \ !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \ - !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)) + !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)) || \ + (defined(WOLFSSL_EXTRA_ALERTS) && !defined(WOLFSSL_NO_TLS12) && \ + !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && !defined(SINGLE_THREADED) && \ + !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT)) #define TEST_MEMIO_BUF_SZ (64 * 1024) struct test_memio_ctx { @@ -5425,6 +5429,9 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx, return -1; wolfSSL_SetIOWriteCtx(*ssl_s, ctx); wolfSSL_SetIOReadCtx(*ssl_s, ctx); +#if !defined(NO_DH) + SetDH(*ssl_s); +#endif } return 0;