This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch camel-quarkus-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git

commit 816843a61ee070d5df27a1bc28ae20c3c45114fa
Author: James Netherton <[email protected]>
AuthorDate: Tue Nov 3 08:37:31 2026 +0000

    Fix http-pqc PqcOnlyTest for JDK builds where SunJSSE supports 
X25519MLKEM768
    
    SunJSSE supports X25519MLKEM768 on JDK 25.0.5, so an unrestricted client can
    connect to the PQC-only server. Restrict the SunJSSE client to classical 
named
    groups so that the test still proves clients not offering PQC are rejected.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 http-pqc/README.adoc                                   |  4 ++--
 .../test/java/org/acme/http/pqc/AbstractPqcTest.java   | 18 +++++++++++++++---
 .../src/test/java/org/acme/http/pqc/PqcOnlyTest.java   | 12 +++++++-----
 .../java/org/acme/http/pqc/PqcWithFallbackTest.java    |  2 +-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/http-pqc/README.adoc b/http-pqc/README.adoc
index 09a8b3c9..00ef4e50 100644
--- a/http-pqc/README.adoc
+++ b/http-pqc/README.adoc
@@ -173,12 +173,12 @@ The test suite validates:
 
 * **PqcOnlyTest**: Proves X25519MLKEM768 is enforced
   - BCJSSE client ✓ succeeds (supports X25519MLKEM768)
-  - SunJSSE client ✗ fails (no PQC support)
+  - SunJSSE client restricted to classical named groups ✗ fails (no PQC 
support offered)
   - This proves the server requires PQC with no classical fallback
 
 * **PqcWithFallbackTest**: Demonstrates backward compatibility
   - BCJSSE client ✓ succeeds (uses X25519MLKEM768)
-  - SunJSSE client ✓ succeeds (falls back to secp256r1)
+  - SunJSSE client ✓ succeeds (falls back to a classical group on JDK builds 
without X25519MLKEM768 support)
   - This proves gradual migration is possible
 
 Run individual tests:
diff --git a/http-pqc/src/test/java/org/acme/http/pqc/AbstractPqcTest.java 
b/http-pqc/src/test/java/org/acme/http/pqc/AbstractPqcTest.java
index 073274e1..42fcaaa5 100644
--- a/http-pqc/src/test/java/org/acme/http/pqc/AbstractPqcTest.java
+++ b/http-pqc/src/test/java/org/acme/http/pqc/AbstractPqcTest.java
@@ -22,6 +22,8 @@ import java.security.Security;
 
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManagerFactory;
 
 import io.restassured.RestAssured;
@@ -39,7 +41,7 @@ import static org.junit.jupiter.api.Assertions.fail;
 
 /**
  * Abstract base class for PQC tests with explicit JSSE provider selection.
- * Tests both BCJSSE (PQC-capable) and SunJSSE (classical only) providers.
+ * Tests both BCJSSE (PQC-capable) and SunJSSE (PQC-capable only on recent JDK 
builds, e.g. 25.0.5+) providers.
  *
  * Certificates are generated before tests via CertificateTestResource.
  */
@@ -75,14 +77,24 @@ abstract class AbstractPqcTest {
                 .statusCode(200);
     }
 
-    void testHttpClientConnection(String securityProvider, boolean 
expectFailure) throws Exception {
+    void testHttpClientConnection(String securityProvider, boolean 
expectFailure, String... clientNamedGroups)
+            throws Exception {
         try {
             SSLContext sslContext = createSslContext(securityProvider);
             SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
                     sslContext,
                     new String[] { "TLSv1.3" },
                     null,
-                    SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
+                    SSLSocketFactory.STRICT_HOSTNAME_VERIFIER) {
+                @Override
+                protected void prepareSocket(SSLSocket socket) {
+                    if (clientNamedGroups.length > 0) {
+                        SSLParameters sslParameters = 
socket.getSSLParameters();
+                        sslParameters.setNamedGroups(clientNamedGroups);
+                        socket.setSSLParameters(sslParameters);
+                    }
+                }
+            };
 
             LOG.info("Testing with " + securityProvider + " provider on port " 
+ RestAssured.port);
 
diff --git a/http-pqc/src/test/java/org/acme/http/pqc/PqcOnlyTest.java 
b/http-pqc/src/test/java/org/acme/http/pqc/PqcOnlyTest.java
index 0587a360..65e1d9ce 100644
--- a/http-pqc/src/test/java/org/acme/http/pqc/PqcOnlyTest.java
+++ b/http-pqc/src/test/java/org/acme/http/pqc/PqcOnlyTest.java
@@ -27,13 +27,15 @@ import org.junit.jupiter.api.Test;
  *
  * Expected results:
  * - BCJSSE: SUCCESS (supports X25519MLKEM768)
- * - SunJSSE: FAILURE (does not support X25519MLKEM768)
+ * - SunJSSE restricted to classical named groups: FAILURE (no key exchange 
group in common with the server)
  *
- * This proves that X25519MLKEM768 requires BouncyCastle JSSE.
+ * This proves that the server rejects clients that do not offer 
X25519MLKEM768. The client is restricted explicitly
+ * because SunJSSE supports X25519MLKEM768 on recent JDK builds (e.g. 25.0.5+).
  *
  * Note: @Order(2) ensures this test runs AFTER PqcWithFallbackTest.
- * SunJSSE's static initialization fails with PQC-only config and permanently 
marks the
- * class as failed. The fallback test must run first to validate SunJSSE works 
with classical algorithms.
+ * On JDK builds where SunJSSE does not support X25519MLKEM768, its static 
initialization fails with PQC-only config
+ * and permanently marks the class as failed. The fallback test must run first 
to validate SunJSSE works with
+ * classical algorithms.
  *
  * This test doesn't have a native *IT child, because the native executable 
can be build only with 1 configuration.
  */
@@ -54,6 +56,6 @@ class PqcOnlyTest extends AbstractPqcTest {
 
     @Test
     void testHttpClientWithSunJSSE() throws Exception {
-        testHttpClientConnection("SunJSSE", true);
+        testHttpClientConnection("SunJSSE", true, "x25519", "secp256r1");
     }
 }
diff --git a/http-pqc/src/test/java/org/acme/http/pqc/PqcWithFallbackTest.java 
b/http-pqc/src/test/java/org/acme/http/pqc/PqcWithFallbackTest.java
index 93647702..255ea14d 100644
--- a/http-pqc/src/test/java/org/acme/http/pqc/PqcWithFallbackTest.java
+++ b/http-pqc/src/test/java/org/acme/http/pqc/PqcWithFallbackTest.java
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
  *
  * Expected results:
  * - BCJSSE: SUCCESS (supports X25519MLKEM768 and fallback)
- * - SunJSSE: SUCCESS (ignores X25519MLKEM768, uses secp256r1 fallback)
+ * - SunJSSE: SUCCESS (uses a classical fallback on JDK builds without 
X25519MLKEM768 support)
  *
  * Note: @Order(1) ensures this test runs BEFORE PqcOnlyTest in JVM mode.
  * This test must run first because SunJSSE can successfully initialize with 
the fallback

Reply via email to