@@ -568,6 +568,166 @@ int test_dtls13_basic_connection_id(void)
568568 return EXPECT_RESULT ();
569569}
570570
571+ /** Test DTLS 1.3 behavior when server hits WANT_WRITE during HRR
572+ * The test sets up a DTLS 1.3 connection where the server is forced to
573+ * return WANT_WRITE when sending the HelloRetryRequest. After the handshake,
574+ * application data is exchanged in both directions to verify the connection
575+ * works as expected.
576+ */
577+ int test_dtls13_hrr_want_write (void )
578+ {
579+ EXPECT_DECLS ;
580+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && defined(WOLFSSL_DTLS13 )
581+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
582+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
583+ const char msg [] = "hello" ;
584+ const int msgLen = sizeof (msg );
585+ struct test_memio_ctx test_ctx ;
586+ char readBuf [sizeof (msg )];
587+
588+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
589+
590+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
591+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ),
592+ 0 );
593+
594+ /* Client sends first ClientHello */
595+ ExpectIntEQ (wolfSSL_negotiate (ssl_c ), -1 );
596+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
597+
598+ /* Force server to hit WANT_WRITE when producing the HRR */
599+ test_memio_simulate_want_write (& test_ctx , 0 , 1 );
600+ ExpectIntEQ (wolfSSL_negotiate (ssl_s ), -1 );
601+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_WRITE );
602+
603+ /* Allow the server to flush the HRR and proceed */
604+ test_memio_simulate_want_write (& test_ctx , 0 , 0 );
605+ ExpectIntEQ (wolfSSL_negotiate (ssl_s ), -1 );
606+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
607+
608+ /* Resume the DTLS 1.3 handshake */
609+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
610+
611+ /* Verify post-handshake application data in both directions */
612+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
613+ ExpectIntEQ (wolfSSL_write (ssl_c , msg , msgLen ), msgLen );
614+ ExpectIntEQ (wolfSSL_read (ssl_s , readBuf , sizeof (readBuf )), msgLen );
615+ ExpectStrEQ (readBuf , msg );
616+
617+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
618+ ExpectIntEQ (wolfSSL_write (ssl_s , msg , msgLen ), msgLen );
619+ ExpectIntEQ (wolfSSL_read (ssl_c , readBuf , sizeof (readBuf )), msgLen );
620+ ExpectStrEQ (readBuf , msg );
621+
622+ wolfSSL_free (ssl_c );
623+ wolfSSL_CTX_free (ctx_c );
624+ wolfSSL_free (ssl_s );
625+ wolfSSL_CTX_free (ctx_s );
626+ #endif
627+ return EXPECT_RESULT ();
628+ }
629+
630+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && defined(WOLFSSL_DTLS13 )
631+ struct test_dtls13_wwrite_ctx {
632+ int want_write ;
633+ struct test_memio_ctx * text_ctx ;
634+ };
635+ static int test_dtls13_want_write_send_cb (WOLFSSL * ssl , char * data , int sz , void * ctx )
636+ {
637+ struct test_dtls13_wwrite_ctx * wwctx = (struct test_dtls13_wwrite_ctx * )ctx ;
638+ wwctx -> want_write = !wwctx -> want_write ;
639+ if (wwctx -> want_write ) {
640+ return WOLFSSL_CBIO_ERR_WANT_WRITE ;
641+ }
642+ return test_memio_write_cb (ssl , data , sz , wwctx -> text_ctx );
643+ }
644+ #endif
645+ /** Test DTLS 1.3 behavior when every other write returns WANT_WRITE
646+ * The test sets up a DTLS 1.3 connection where both client and server
647+ * alternate between WANT_WRITE and successful writes. After the handshake,
648+ * application data is exchanged in both directions to verify the connection
649+ * works as expected.
650+ *
651+ * Data exchanged after the handshake is also tested with simulated WANT_WRITE
652+ * conditions to ensure the connection remains functional.
653+ */
654+ int test_dtls13_every_write_want_write (void )
655+ {
656+ EXPECT_DECLS ;
657+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && defined(WOLFSSL_DTLS13 )
658+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
659+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
660+ struct test_memio_ctx test_ctx ;
661+ const char msg [] = "want-write" ;
662+ const int msgLen = sizeof (msg );
663+ char readBuf [sizeof (msg )];
664+ struct test_dtls13_wwrite_ctx wwctx_c ;
665+ struct test_dtls13_wwrite_ctx wwctx_s ;
666+
667+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
668+
669+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
670+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ),
671+ 0 );
672+
673+ wwctx_c .want_write = 0 ;
674+ wwctx_c .text_ctx = & test_ctx ;
675+ wolfSSL_SetIOWriteCtx (ssl_c , & wwctx_c );
676+ wolfSSL_SSLSetIOSend (ssl_c , test_dtls13_want_write_send_cb );
677+ wwctx_s .want_write = 0 ;
678+ wwctx_s .text_ctx = & test_ctx ;
679+ wolfSSL_SetIOWriteCtx (ssl_s , & wwctx_s );
680+ wolfSSL_SSLSetIOSend (ssl_s , test_dtls13_want_write_send_cb );
681+
682+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 20 , NULL ), 0 );
683+
684+ ExpectTrue (wolfSSL_is_init_finished (ssl_c ));
685+ ExpectTrue (wolfSSL_is_init_finished (ssl_s ));
686+
687+ test_memio_simulate_want_write (& test_ctx , 0 , 0 );
688+ test_memio_simulate_want_write (& test_ctx , 1 , 0 );
689+
690+ wolfSSL_SetIOWriteCtx (ssl_c , & test_ctx );
691+ wolfSSL_SSLSetIOSend (ssl_c , test_memio_write_cb );
692+ wolfSSL_SetIOWriteCtx (ssl_s , & test_ctx );
693+ wolfSSL_SSLSetIOSend (ssl_s , test_memio_write_cb );
694+
695+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
696+ ExpectIntEQ (wolfSSL_write (ssl_c , msg , msgLen ), msgLen );
697+ ExpectIntEQ (wolfSSL_read (ssl_s , readBuf , sizeof (readBuf )), msgLen );
698+ ExpectStrEQ (readBuf , msg );
699+
700+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
701+ ExpectIntEQ (wolfSSL_write (ssl_s , msg , msgLen ), msgLen );
702+ ExpectIntEQ (wolfSSL_read (ssl_c , readBuf , sizeof (readBuf )), msgLen );
703+ ExpectStrEQ (readBuf , msg );
704+
705+ test_memio_simulate_want_write (& test_ctx , 0 , 1 );
706+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
707+ ExpectIntEQ (wolfSSL_write (ssl_s , msg , msgLen ), -1 );
708+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_WRITE );
709+ test_memio_simulate_want_write (& test_ctx , 0 , 0 );
710+ ExpectIntEQ (wolfSSL_write (ssl_s , msg , msgLen ), msgLen );
711+ ExpectIntEQ (wolfSSL_read (ssl_c , readBuf , sizeof (readBuf )), msgLen );
712+ ExpectStrEQ (readBuf , msg );
713+
714+ XMEMSET (readBuf , 0 , sizeof (readBuf ));
715+ test_memio_simulate_want_write (& test_ctx , 1 , 1 );
716+ ExpectIntEQ (wolfSSL_write (ssl_c , msg , msgLen ), -1 );
717+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_WRITE );
718+ test_memio_simulate_want_write (& test_ctx , 1 , 0 );
719+ ExpectIntEQ (wolfSSL_write (ssl_c , msg , msgLen ), msgLen );
720+ ExpectIntEQ (wolfSSL_read (ssl_s , readBuf , sizeof (readBuf )), msgLen );
721+ ExpectStrEQ (readBuf , msg );
722+
723+ wolfSSL_free (ssl_c );
724+ wolfSSL_CTX_free (ctx_c );
725+ wolfSSL_free (ssl_s );
726+ wolfSSL_CTX_free (ctx_s );
727+ #endif
728+ return EXPECT_RESULT ();
729+ }
730+
571731int test_wolfSSL_dtls_cid_parse (void )
572732{
573733 EXPECT_DECLS ;
0 commit comments