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