@@ -81189,6 +81189,90 @@ static int test_extra_alerts_bad_psk(void)
8118981189}
8119081190#endif
8119181191
81192+ #if defined(OPENSSL_EXTRA) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
81193+ /*
81194+ * Emulates wolfSSL_shutdown that goes on EAGAIN,
81195+ * by returning on output WOLFSSL_ERROR_WANT_WRITE.*/
81196+ static int custom_wolfSSL_shutdown(WOLFSSL *ssl, char *buf,
81197+ int sz, void *ctx)
81198+ {
81199+ (void)ssl;
81200+ (void)buf;
81201+ (void)ctx;
81202+ (void)sz;
81203+
81204+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
81205+ }
81206+
81207+ static int test_multiple_alerts_EAGAIN(void)
81208+ {
81209+ EXPECT_DECLS;
81210+ size_t size_of_last_packet = 0;
81211+
81212+ /* declare wolfSSL objects */
81213+ struct test_memio_ctx test_ctx;
81214+ WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
81215+ WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
81216+
81217+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
81218+
81219+ /* Create and initialize WOLFSSL_CTX and WOLFSSL objects */
81220+ #ifdef USE_TLSV13
81221+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
81222+ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
81223+ #else
81224+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
81225+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
81226+ #endif
81227+ ExpectNotNull(ctx_c);
81228+ ExpectNotNull(ssl_c);
81229+ ExpectNotNull(ctx_s);
81230+ ExpectNotNull(ssl_s);
81231+
81232+ /* Load client certificates into WOLFSSL_CTX */
81233+ ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c, "./certs/ca-cert.pem", NULL), WOLFSSL_SUCCESS);
81234+
81235+ ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
81236+
81237+ /*
81238+ * We set the custom callback for the IO to emulate multiple EAGAINs
81239+ * on shutdown, so we can check that we don't send multiple packets.
81240+ * */
81241+ wolfSSL_SSLSetIOSend(ssl_c, custom_wolfSSL_shutdown);
81242+
81243+ /*
81244+ * We call wolfSSL_shutdown multiple times to reproduce the behaviour,
81245+ * to check that it doesn't add the CLOSE_NOTIFY packet multiple times
81246+ * on the output buffer.
81247+ * */
81248+ wolfSSL_shutdown(ssl_c);
81249+ wolfSSL_shutdown(ssl_c);
81250+
81251+ if (ssl_c != NULL) {
81252+ size_of_last_packet = ssl_c->buffers.outputBuffer.length;
81253+ }
81254+ wolfSSL_shutdown(ssl_c);
81255+
81256+ /*
81257+ * Finally we check the length of the output buffer.
81258+ * */
81259+ ExpectIntEQ((ssl_c->buffers.outputBuffer.length - size_of_last_packet), 0);
81260+
81261+ /* Cleanup and return */
81262+ wolfSSL_CTX_free(ctx_c);
81263+ wolfSSL_free(ssl_c);
81264+ wolfSSL_CTX_free(ctx_s);
81265+ wolfSSL_free(ssl_s);
81266+
81267+ return EXPECT_RESULT();
81268+ }
81269+ #else
81270+ static int test_multiple_alerts_EAGAIN(void)
81271+ {
81272+ return TEST_SKIPPED;
81273+ }
81274+ #endif
81275+
8119281276#if defined(WOLFSSL_TLS13) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
8119381277 && !defined(NO_PSK)
8119481278static unsigned int test_tls13_bad_psk_binder_client_cb(WOLFSSL* ssl,
@@ -86705,6 +86789,7 @@ TEST_CASE testCases[] = {
8670586789 TEST_DECL(test_extra_alerts_wrong_cs),
8670686790 TEST_DECL(test_extra_alerts_skip_hs),
8670786791 TEST_DECL(test_extra_alerts_bad_psk),
86792+ TEST_DECL(test_multiple_alerts_EAGAIN),
8670886793 TEST_DECL(test_tls13_bad_psk_binder),
8670986794 /* Can't memory test as client/server Asserts. */
8671086795 TEST_DECL(test_harden_no_secure_renegotiation),
0 commit comments