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