@@ -1775,6 +1775,121 @@ int test_tls13_bad_psk_binder(void)
17751775}
17761776
17771777
1778+ #if defined(WOLFSSL_TLS13 ) && \
1779+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES_NO_CERTS ) && !defined(NO_PSK )
1780+ static unsigned int test_tls13_psk_no_cert_client_cb (WOLFSSL * ssl ,
1781+ const char * hint , char * identity , unsigned int id_max_len ,
1782+ unsigned char * key , unsigned int key_max_len )
1783+ {
1784+ (void )ssl ;
1785+ (void )hint ;
1786+ (void )key_max_len ;
1787+
1788+ /* Offer a PSK so the client sends a pre_shared_key extension. */
1789+ XSTRNCPY (identity , "Client_identity" , id_max_len );
1790+ key [0 ] = 0x20 ;
1791+ return 1 ;
1792+ }
1793+
1794+ static unsigned int test_tls13_psk_no_cert_server_cb (WOLFSSL * ssl ,
1795+ const char * id , unsigned char * key , unsigned int key_max_len )
1796+ {
1797+ (void )ssl ;
1798+ (void )id ;
1799+ (void )key ;
1800+ (void )key_max_len ;
1801+
1802+ /* Reject every identity so the server finds no matching PSK. */
1803+ return 0 ;
1804+ }
1805+ #endif
1806+
1807+ /* When no offered PSK matches and the server has no certificate to fall back
1808+ * to, the server must abort the handshake with BAD_BINDER rather than silently
1809+ * continuing. This covers both cases:
1810+ * - NO_CERTS defined: the certificate fall-back branch is compiled out.
1811+ * - certificates compiled in but none loaded: ssl->buffers.certificate is
1812+ * NULL, so the same branch is taken at runtime.
1813+ * It uses the cert-less memio harness so it builds and runs in either
1814+ * configuration. */
1815+ int test_tls13_psk_no_cert_bad_binder (void )
1816+ {
1817+ EXPECT_DECLS ;
1818+ #if defined(WOLFSSL_TLS13 ) && \
1819+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES_NO_CERTS ) && !defined(NO_PSK )
1820+ WOLFSSL_CTX * ctx_c = NULL ;
1821+ WOLFSSL_CTX * ctx_s = NULL ;
1822+ WOLFSSL * ssl_c = NULL ;
1823+ WOLFSSL * ssl_s = NULL ;
1824+ struct test_memio_ctx test_ctx ;
1825+ WOLFSSL_ALERT_HISTORY h ;
1826+
1827+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1828+
1829+ /* Don't use test_memio_setup(): it loads a default server certificate,
1830+ * which would let the server fall back to a certificate handshake. Build
1831+ * the contexts by hand so the server has no certificate loaded. */
1832+ ExpectNotNull (ctx_c = wolfSSL_CTX_new (wolfTLSv1_3_client_method ()));
1833+ ExpectNotNull (ctx_s = wolfSSL_CTX_new (wolfTLSv1_3_server_method ()));
1834+ if (ctx_c != NULL ) {
1835+ wolfSSL_SetIORecv (ctx_c , test_memio_read_cb );
1836+ wolfSSL_SetIOSend (ctx_c , test_memio_write_cb );
1837+ }
1838+ if (ctx_s != NULL ) {
1839+ wolfSSL_SetIORecv (ctx_s , test_memio_read_cb );
1840+ wolfSSL_SetIOSend (ctx_s , test_memio_write_cb );
1841+ }
1842+
1843+ ExpectNotNull (ssl_c = wolfSSL_new (ctx_c ));
1844+ ExpectNotNull (ssl_s = wolfSSL_new (ctx_s ));
1845+ if (ssl_c != NULL ) {
1846+ wolfSSL_SetIOWriteCtx (ssl_c , & test_ctx );
1847+ wolfSSL_SetIOReadCtx (ssl_c , & test_ctx );
1848+ }
1849+ if (ssl_s != NULL ) {
1850+ wolfSSL_SetIOWriteCtx (ssl_s , & test_ctx );
1851+ wolfSSL_SetIOReadCtx (ssl_s , & test_ctx );
1852+ }
1853+
1854+ wolfSSL_set_psk_client_callback (ssl_c , test_tls13_psk_no_cert_client_cb );
1855+ wolfSSL_set_psk_server_callback (ssl_s , test_tls13_psk_no_cert_server_cb );
1856+
1857+ /* Confirm the precondition: the server really has no certificate. */
1858+ #ifndef NO_CERTS
1859+ if (ssl_s != NULL ) {
1860+ ExpectNull (ssl_s -> buffers .certificate );
1861+ }
1862+ #endif
1863+
1864+ /* Client sends ClientHello (with PSK) and waits for the response. */
1865+ ExpectIntNE (wolfSSL_connect (ssl_c ), WOLFSSL_SUCCESS );
1866+ ExpectIntEQ (wolfSSL_get_error (ssl_c , WC_NO_ERR_TRACE (WOLFSSL_FATAL_ERROR )),
1867+ WOLFSSL_ERROR_WANT_READ );
1868+
1869+ /* Server processes ClientHello: no PSK matches and no certificate is
1870+ * available, so it must abort with BAD_BINDER. */
1871+ ExpectIntNE (wolfSSL_accept (ssl_s ), WOLFSSL_SUCCESS );
1872+ ExpectIntEQ (wolfSSL_get_error (ssl_s , WC_NO_ERR_TRACE (WOLFSSL_FATAL_ERROR )),
1873+ WC_NO_ERR_TRACE (BAD_BINDER ));
1874+
1875+ /* Client reads the server's alert: BAD_BINDER maps to a fatal
1876+ * illegal_parameter alert (see TranslateErrorToAlert). */
1877+ ExpectIntNE (wolfSSL_connect (ssl_c ), WOLFSSL_SUCCESS );
1878+ ExpectIntEQ (wolfSSL_get_error (ssl_c , WC_NO_ERR_TRACE (WOLFSSL_FATAL_ERROR )),
1879+ WC_NO_ERR_TRACE (FATAL_ERROR ));
1880+ ExpectIntEQ (wolfSSL_get_alert_history (ssl_c , & h ), WOLFSSL_SUCCESS );
1881+ ExpectIntEQ (h .last_rx .code , illegal_parameter );
1882+ ExpectIntEQ (h .last_rx .level , alert_fatal );
1883+
1884+ wolfSSL_free (ssl_c );
1885+ wolfSSL_CTX_free (ctx_c );
1886+ wolfSSL_free (ssl_s );
1887+ wolfSSL_CTX_free (ctx_s );
1888+ #endif
1889+ return EXPECT_RESULT ();
1890+ }
1891+
1892+
17781893#if defined(HAVE_RPK ) && !defined(NO_TLS ) && !defined(NO_WOLFSSL_CLIENT ) && \
17791894 !defined(NO_WOLFSSL_SERVER )
17801895
0 commit comments