@@ -2609,3 +2609,98 @@ int test_dtls13_min_rtx_interval(void)
26092609#endif
26102610 return EXPECT_RESULT ();
26112611}
2612+
2613+ /* Test that a DTLS 1.3 handshake with an oversized certificate chain does
2614+ * not crash or cause out-of-bounds access in SendTls13Certificate. */
2615+ int test_dtls13_oversized_cert_chain (void )
2616+ {
2617+ EXPECT_DECLS ;
2618+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && defined(WOLFSSL_DTLS13 ) \
2619+ && !defined(NO_FILESYSTEM ) && !defined(NO_RSA )
2620+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
2621+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
2622+ struct test_memio_ctx test_ctx ;
2623+ XFILE f = XBADFILE ;
2624+ long sz = 0 ;
2625+ byte * cert = NULL ;
2626+ byte * chain = NULL ;
2627+ int copies , off , i ;
2628+
2629+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
2630+
2631+ /* Read server cert */
2632+ f = XFOPEN (svrCertFile , "rb" );
2633+ ExpectTrue (f != XBADFILE );
2634+ if (EXPECT_SUCCESS ()) {
2635+ XFSEEK (f , 0 , XSEEK_END );
2636+ sz = XFTELL (f );
2637+ XFSEEK (f , 0 , XSEEK_SET );
2638+ }
2639+ ExpectTrue (sz > 0 );
2640+ cert = (byte * )XMALLOC ((size_t )(sz + 1 ), NULL , DYNAMIC_TYPE_TMP_BUFFER );
2641+ ExpectNotNull (cert );
2642+ if (EXPECT_SUCCESS ())
2643+ ExpectIntEQ ((int )XFREAD (cert , 1 , (size_t )sz , f ), (int )sz );
2644+ if (f != XBADFILE )
2645+ XFCLOSE (f );
2646+
2647+ /* Build an oversized chain by duplicating the cert */
2648+ copies = (int )(70000 / sz ) + 2 ;
2649+ chain = (byte * )XMALLOC ((size_t )(sz * copies + 1 ), NULL ,
2650+ DYNAMIC_TYPE_TMP_BUFFER );
2651+ ExpectNotNull (chain );
2652+ off = 0 ;
2653+ if (EXPECT_SUCCESS ()) {
2654+ for (i = 0 ; i < copies ; i ++ ) {
2655+ XMEMCPY (chain + off , cert , (size_t )sz );
2656+ off += (int )sz ;
2657+ }
2658+ }
2659+
2660+ /* Server context: load the oversized chain */
2661+ ExpectNotNull (ctx_s = wolfSSL_CTX_new (wolfDTLSv1_3_server_method ()));
2662+ ExpectIntEQ (wolfSSL_CTX_use_certificate_chain_buffer (ctx_s ,
2663+ chain , (long )off ), WOLFSSL_SUCCESS );
2664+ ExpectIntEQ (wolfSSL_CTX_use_PrivateKey_file (ctx_s , svrKeyFile ,
2665+ WOLFSSL_FILETYPE_PEM ), WOLFSSL_SUCCESS );
2666+ if (EXPECT_SUCCESS ()) {
2667+ wolfSSL_SetIORecv (ctx_s , test_memio_read_cb );
2668+ wolfSSL_SetIOSend (ctx_s , test_memio_write_cb );
2669+ }
2670+
2671+ /* Client context: no verification (chain certs are duplicates) */
2672+ ExpectNotNull (ctx_c = wolfSSL_CTX_new (wolfDTLSv1_3_client_method ()));
2673+ if (EXPECT_SUCCESS ()) {
2674+ wolfSSL_CTX_set_verify (ctx_c , WOLFSSL_VERIFY_NONE , NULL );
2675+ wolfSSL_SetIORecv (ctx_c , test_memio_read_cb );
2676+ wolfSSL_SetIOSend (ctx_c , test_memio_write_cb );
2677+ }
2678+
2679+ ExpectNotNull (ssl_s = wolfSSL_new (ctx_s ));
2680+ if (EXPECT_SUCCESS ()) {
2681+ wolfSSL_SetIOWriteCtx (ssl_s , & test_ctx );
2682+ wolfSSL_SetIOReadCtx (ssl_s , & test_ctx );
2683+ }
2684+
2685+ ExpectNotNull (ssl_c = wolfSSL_new (ctx_c ));
2686+ if (EXPECT_SUCCESS ()) {
2687+ wolfSSL_SetIOWriteCtx (ssl_c , & test_ctx );
2688+ wolfSSL_SetIOReadCtx (ssl_c , & test_ctx );
2689+ }
2690+
2691+ /* Handshake must not crash. If SendTls13Certificate mishandles the
2692+ * oversized chain this will trigger a wild pointer dereference or stack
2693+ * overflow resulting with the test failing.
2694+ * The correct behaviour either returns BUFFER_E or succeeds
2695+ * if the build config truncated the chain during loading. */
2696+ (void )test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL );
2697+
2698+ wolfSSL_free (ssl_c );
2699+ wolfSSL_free (ssl_s );
2700+ wolfSSL_CTX_free (ctx_c );
2701+ wolfSSL_CTX_free (ctx_s );
2702+ XFREE (cert , NULL , DYNAMIC_TYPE_TMP_BUFFER );
2703+ XFREE (chain , NULL , DYNAMIC_TYPE_TMP_BUFFER );
2704+ #endif
2705+ return EXPECT_RESULT ();
2706+ }
0 commit comments