@@ -545,3 +545,67 @@ int test_certificate_authorities_client_hello(void) {
545545#endif
546546 return EXPECT_RESULT ();
547547}
548+
549+ /* Test that the SNI size calculation returns 0 on overflow instead of
550+ * wrapping around to a small value (integer overflow vulnerability). */
551+ int test_TLSX_SNI_GetSize_overflow (void )
552+ {
553+ EXPECT_DECLS ;
554+ #if defined(HAVE_SNI ) && !defined(NO_WOLFSSL_CLIENT ) && !defined(NO_TLS )
555+ WOLFSSL_CTX * ctx = NULL ;
556+ WOLFSSL * ssl = NULL ;
557+ TLSX * sni_ext = NULL ;
558+ SNI * head = NULL ;
559+ SNI * sni = NULL ;
560+ int i ;
561+ /* Each SNI adds ENUM_LEN(1) + OPAQUE16_LEN(2) + hostname_len to the size.
562+ * With a 1-byte hostname, each entry adds 4 bytes. Starting from
563+ * OPAQUE16_LEN(2) base, we need enough entries to exceed UINT16_MAX. */
564+ const int num_sni = (0xFFFF / 4 ) + 2 ;
565+
566+ ExpectNotNull (ctx = wolfSSL_CTX_new (wolfSSLv23_client_method ()));
567+ ExpectNotNull (ssl = wolfSSL_new (ctx ));
568+
569+ /* Add initial SNI via public API */
570+ ExpectIntEQ (WOLFSSL_SUCCESS ,
571+ wolfSSL_UseSNI (ssl , WOLFSSL_SNI_HOST_NAME , "a" , 1 ));
572+
573+ /* Find the SNI extension and manually build a long chain */
574+ if (EXPECT_SUCCESS ()) {
575+ sni_ext = TLSX_Find (ssl -> extensions , TLSX_SERVER_NAME );
576+ ExpectNotNull (sni_ext );
577+ }
578+
579+ if (EXPECT_SUCCESS ()) {
580+ head = (SNI * )sni_ext -> data ;
581+ ExpectNotNull (head );
582+ }
583+
584+ /* Append many SNI nodes to force overflow in the size calculation */
585+ for (i = 1 ; EXPECT_SUCCESS () && i < num_sni ; i ++ ) {
586+ sni = (SNI * )XMALLOC (sizeof (SNI ), NULL , DYNAMIC_TYPE_TLSX );
587+ ExpectNotNull (sni );
588+ if (sni != NULL ) {
589+ XMEMSET (sni , 0 , sizeof (SNI ));
590+ sni -> type = WOLFSSL_SNI_HOST_NAME ;
591+ sni -> data .host_name = (char * )XMALLOC (2 , NULL , DYNAMIC_TYPE_TLSX );
592+ ExpectNotNull (sni -> data .host_name );
593+ if (sni -> data .host_name != NULL ) {
594+ sni -> data .host_name [0 ] = 'a' ;
595+ sni -> data .host_name [1 ] = '\0' ;
596+ }
597+ sni -> next = head -> next ;
598+ head -> next = sni ;
599+ }
600+ }
601+
602+ if (EXPECT_SUCCESS ()) {
603+ /* The fixed calculation should return 0 (overflow detected) */
604+ ExpectIntEQ (TLSX_SNI_GetSize ((SNI * )sni_ext -> data ), 0 );
605+ }
606+
607+ wolfSSL_free (ssl );
608+ wolfSSL_CTX_free (ctx );
609+ #endif
610+ return EXPECT_RESULT ();
611+ }
0 commit comments