@@ -9769,6 +9769,115 @@ static int test_wolfSSL_SCR_Reconnect(void)
97699769 return EXPECT_RESULT();
97709770}
97719771
9772+ /* Test SCR check when server doesn't reply to secure_renegotiation. */
9773+ #if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
9774+ defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK) && \
9775+ defined(HAVE_SECURE_RENEGOTIATION) && \
9776+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
9777+ /* IO callback to remove secure renegotiation extension from ServerHello */
9778+ static int test_SCR_check_remove_ext_io_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
9779+ {
9780+ static int sentServerHello = FALSE;
9781+
9782+ if (!sentServerHello) {
9783+ /* Look for secure renegotiation extension: 0xFF 0x01 (extension type) */
9784+ byte renegExt[] = { 0xFF, 0x01 };
9785+ size_t i;
9786+
9787+ if (sz < (int)sizeof(renegExt))
9788+ return test_memio_write_cb(ssl, buf, sz, ctx);
9789+
9790+ /* Search for the extension in the buffer */
9791+ for (i = 0; i < (size_t)sz - sizeof(renegExt); i++) {
9792+ if (XMEMCMP(buf + i, renegExt, sizeof(renegExt)) == 0) {
9793+ /* Found the extension. Remove it by changing the type to something
9794+ * unrecognized so it won't be parsed as secure renegotiation. */
9795+ buf[i+1] = 0x11;
9796+ break;
9797+ }
9798+ }
9799+ sentServerHello = TRUE;
9800+ }
9801+
9802+ /* Call the original test_memio_write_cb */
9803+ return test_memio_write_cb(ssl, buf, sz, ctx);
9804+ }
9805+ #endif
9806+
9807+ static int test_wolfSSL_SCR_check_enabled(void)
9808+ {
9809+ EXPECT_DECLS;
9810+ #if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
9811+ defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK) && \
9812+ defined(HAVE_SECURE_RENEGOTIATION) && \
9813+ defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
9814+ struct test_memio_ctx test_ctx;
9815+ WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
9816+ WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
9817+ int ret;
9818+ int enabled;
9819+
9820+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
9821+
9822+ /* Set up client and server */
9823+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
9824+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
9825+
9826+ /* Enable secure renegotiation on client (so it sends the extension) */
9827+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
9828+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
9829+
9830+ /* Set up IO callback on server to remove the extension from ServerHello */
9831+ wolfSSL_SSLSetIOSend(ssl_s, test_SCR_check_remove_ext_io_cb);
9832+
9833+ /* Try to connect - should fail with SECURE_RENEGOTIATION_E */
9834+ ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
9835+ ExpectIntNE(0, ret); /* Handshake should fail */
9836+ ret = wolfSSL_get_error(ssl_c, 0);
9837+ ExpectIntEQ(WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E), ret);
9838+
9839+ /* Clean up for next attempt */
9840+ wolfSSL_free(ssl_c);
9841+ ssl_c = NULL;
9842+ wolfSSL_free(ssl_s);
9843+ ssl_s = NULL;
9844+ test_memio_clear_buffer(&test_ctx, 1);
9845+ test_memio_clear_buffer(&test_ctx, 0);
9846+
9847+ /* Set up new client and server */
9848+ ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
9849+ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
9850+
9851+ /* Enable secure renegotiation on client */
9852+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
9853+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
9854+
9855+ /* Set up IO callback on server to remove the extension from ServerHello */
9856+ wolfSSL_SSLSetIOSend(ssl_s, test_SCR_check_remove_ext_io_cb);
9857+
9858+ /* Disable the SCR check */
9859+ ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_scr_check_enabled(ssl_c, 0));
9860+
9861+ /* Verify the state is 0 */
9862+ enabled = wolfSSL_get_scr_check_enabled(ssl_c);
9863+ ExpectIntEQ(0, enabled);
9864+
9865+ /* Now connection should succeed */
9866+ ExpectIntEQ(0, test_memio_do_handshake(ssl_c, ssl_s, 10, NULL));
9867+
9868+ /* Cleanup */
9869+ wolfSSL_free(ssl_c);
9870+ ssl_c = NULL;
9871+ wolfSSL_free(ssl_s);
9872+ ssl_s = NULL;
9873+ wolfSSL_CTX_free(ctx_c);
9874+ ctx_c = NULL;
9875+ wolfSSL_CTX_free(ctx_s);
9876+ ctx_s = NULL;
9877+ #endif
9878+ return EXPECT_RESULT();
9879+ }
9880+
97729881#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
97739882 !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
97749883/* Called when writing. */
@@ -31645,6 +31754,7 @@ TEST_CASE testCases[] = {
3164531754 TEST_DECL(test_certificate_authorities_client_hello),
3164631755 TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
3164731756 TEST_DECL(test_wolfSSL_SCR_Reconnect),
31757+ TEST_DECL(test_wolfSSL_SCR_check_enabled),
3164831758 TEST_DECL(test_tls_ext_duplicate),
3164931759 TEST_DECL(test_tls_bad_legacy_version),
3165031760#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
0 commit comments