@@ -12844,6 +12844,115 @@ static int test_wolfSSL_SCR_Reconnect(void)
1284412844 return EXPECT_RESULT();
1284512845}
1284612846
12847+ /* Test SCR check when server doesn't reply to secure_renegotiation. */
12848+ #if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
12849+ defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK) && \
12850+ defined(HAVE_SECURE_RENEGOTIATION) && \
12851+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
12852+ /* IO callback to remove secure renegotiation extension from ServerHello */
12853+ static int test_SCR_check_remove_ext_io_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
12854+ {
12855+ static int sentServerHello = FALSE;
12856+
12857+ if (!sentServerHello) {
12858+ /* Look for secure renegotiation extension: 0xFF 0x01 (extension type) */
12859+ byte renegExt[] = { 0xFF, 0x01 };
12860+ size_t i;
12861+
12862+ if (sz < (int)sizeof(renegExt))
12863+ return test_memio_write_cb(ssl, buf, sz, ctx);
12864+
12865+ /* Search for the extension in the buffer */
12866+ for (i = 0; i < (size_t)sz - sizeof(renegExt); i++) {
12867+ if (XMEMCMP(buf + i, renegExt, sizeof(renegExt)) == 0) {
12868+ /* Found the extension. Remove it by changing the type to something
12869+ * unrecognized so it won't be parsed as secure renegotiation. */
12870+ buf[i+1] = 0x11;
12871+ break;
12872+ }
12873+ }
12874+ sentServerHello = TRUE;
12875+ }
12876+
12877+ /* Call the original test_memio_write_cb */
12878+ return test_memio_write_cb(ssl, buf, sz, ctx);
12879+ }
12880+ #endif
12881+
12882+ static int test_wolfSSL_SCR_check_enabled(void)
12883+ {
12884+ EXPECT_DECLS;
12885+ #if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
12886+ defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK) && \
12887+ defined(HAVE_SECURE_RENEGOTIATION) && \
12888+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
12889+ struct test_memio_ctx test_ctx;
12890+ WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
12891+ WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
12892+ int ret;
12893+ int enabled;
12894+
12895+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
12896+
12897+ /* Set up client and server */
12898+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
12899+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
12900+
12901+ /* Enable secure renegotiation on client (so it sends the extension) */
12902+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
12903+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
12904+
12905+ /* Set up IO callback on server to remove the extension from ServerHello */
12906+ wolfSSL_SSLSetIOSend(ssl_s, test_SCR_check_remove_ext_io_cb);
12907+
12908+ /* Try to connect - should fail with SECURE_RENEGOTIATION_E */
12909+ ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
12910+ ExpectIntNE(0, ret); /* Handshake should fail */
12911+ ret = wolfSSL_get_error(ssl_c, 0);
12912+ ExpectIntEQ(WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E), ret);
12913+
12914+ /* Clean up for next attempt */
12915+ wolfSSL_free(ssl_c);
12916+ ssl_c = NULL;
12917+ wolfSSL_free(ssl_s);
12918+ ssl_s = NULL;
12919+ test_memio_clear_buffer(&test_ctx, 1);
12920+ test_memio_clear_buffer(&test_ctx, 0);
12921+
12922+ /* Set up new client and server */
12923+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
12924+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
12925+
12926+ /* Enable secure renegotiation on client */
12927+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
12928+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
12929+
12930+ /* Set up IO callback on server to remove the extension from ServerHello */
12931+ wolfSSL_SSLSetIOSend(ssl_s, test_SCR_check_remove_ext_io_cb);
12932+
12933+ /* Disable the SCR check */
12934+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_scr_check_enabled(ssl_c, 0));
12935+
12936+ /* Verify the state is 0 */
12937+ enabled = wolfSSL_get_scr_check_enabled(ssl_c);
12938+ ExpectIntEQ(0, enabled);
12939+
12940+ /* Now connection should succeed */
12941+ ExpectIntEQ(0, test_memio_do_handshake(ssl_c, ssl_s, 10, NULL));
12942+
12943+ /* Cleanup */
12944+ wolfSSL_free(ssl_c);
12945+ ssl_c = NULL;
12946+ wolfSSL_free(ssl_s);
12947+ ssl_s = NULL;
12948+ wolfSSL_CTX_free(ctx_c);
12949+ ctx_c = NULL;
12950+ wolfSSL_CTX_free(ctx_s);
12951+ ctx_s = NULL;
12952+ #endif
12953+ return EXPECT_RESULT();
12954+ }
12955+
1284712956#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
1284812957 !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
1284912958/* Called when writing. */
@@ -42164,6 +42273,7 @@ TEST_CASE testCases[] = {
4216442273 TEST_DECL(test_certificate_authorities_client_hello),
4216542274 TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
4216642275 TEST_DECL(test_wolfSSL_SCR_Reconnect),
42276+ TEST_DECL(test_wolfSSL_SCR_check_enabled),
4216742277 TEST_DECL(test_tls_ext_duplicate),
4216842278 TEST_DECL(test_tls_bad_legacy_version),
4216942279#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
0 commit comments