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

ffang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/main by this push:
     new 16ac0e403ca [CXF-9229] Add PQC TLS 1.3 support via X25519MLKEM768 
hybrid KEM (#3299)
16ac0e403ca is described below

commit 16ac0e403ca3cc5f97d3c93d8ccfe98d993b4a66
Author: Freeman(Yue) Fang <[email protected]>
AuthorDate: Fri Jul 10 09:59:01 2026 -0400

    [CXF-9229] Add PQC TLS 1.3 support via X25519MLKEM768 hybrid KEM (#3299)
    
    * [CXF-9229] Add PQC TLS 1.3 support via X25519MLKEM768 hybrid KEM
    
    - TLSParameterBase: new namedGroups API (getNamedGroups/setNamedGroups) to
      configure the ordered list of TLS named groups offered during the 
handshake
    - security.xsd: new NamedGroups complex type and 
<sec:namedGroups>/<sec:namedGroup>
      elements on both TLSClientParametersType and TLSServerParametersType
    - TLSClientParametersConfig / TLSServerParametersConfig: wire namedGroups 
from
      XML config into SSLParameters via SSLUtils.applyNamedGroups() (JDK 20+)
    - SSLUtils.applyNamedGroupsBC(): reflection-based helper to set named groups
      on BC JSSE's ProvSSLEngine without a compile-time bctls-jdk18on dependency
    - JettyHTTPServerEngine: override customize(SSLEngine) to call 
applyNamedGroupsBC()
      so each accepted engine gets named groups from tlsServerParameters 
configuration
    - BCJsseServerALPNProcessor: ALPNProcessor.Server for BC JSSE's 
ProvSSLEngine;
      bridges it into Jetty's ALPN negotiation (JDK9ServerALPNProcessor only 
accepts
      java.base engines); registered via META-INF/services; enables HTTP/2 + BC 
JSSE
    - BCJssePQCTest + BCJsseJettyServer: system test using BC JSSE on JDK 17-26;
      sets jdk.tls.namedGroups=X25519MLKEM768 before SSLContext creation so the
      BC JSSE context-level named-group map includes the PQC group; verifies
      X25519MLKEM768 was negotiated by restricting a raw BCSSLSocket to that 
group only
    - PQCTLSTest: system test for SunJSSE on JDK 27+ (JEP 527); skips 
automatically
      when X25519MLKEM768 is absent from the configured named groups
    
    * [CXF-9229]update BC version to 1.84 for jdk25 compatibility
---
 .../jsse/TLSClientParametersConfig.java            |   3 +
 .../cxf/configuration/jsse/TLSParameterBase.java   |  21 +++
 .../jsse/TLSServerParametersConfig.java            |   3 +
 .../resources/schemas/configuration/security.xsd   |  32 ++++
 parent/pom.xml                                     |   2 +-
 .../http_jetty/BCJsseServerALPNProcessor.java      |  79 ++++++++++
 .../http_jetty/JettyHTTPServerEngine.java          |  31 +++-
 .../org.eclipse.jetty.io.ssl.ALPNProcessor$Server  |   1 +
 .../cxf/transport/http/HttpClientHTTPConduit.java  |   4 +
 .../org/apache/cxf/transport/https/SSLUtils.java   |  40 +++++
 systests/transports/pom.xml                        |  29 ++++
 .../cxf/systest/https/pqc/BCJssePQCTest.java       | 166 +++++++++++++++++++++
 .../apache/cxf/systest/https/pqc/PQCTLSTest.java   | 148 ++++++++++++++++++
 .../src/test/resources/logging.properties          |   4 +-
 .../apache/cxf/systest/https/pqc/bcjsse-client.xml |  52 +++++++
 .../apache/cxf/systest/https/pqc/bcjsse-server.xml |  74 +++++++++
 .../apache/cxf/systest/https/pqc/pqc-client.xml    |  49 ++++++
 .../apache/cxf/systest/https/pqc/pqc-server.xml    |  69 +++++++++
 18 files changed, 803 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java
 
b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java
index 7eb060074f9..d0fdcd9cde0 100644
--- 
a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java
+++ 
b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParametersConfig.java
@@ -131,6 +131,9 @@ public final class TLSClientParametersConfig {
         if (params.isSetCertAlias()) {
             ret.setCertAlias(params.getCertAlias());
         }
+        if (params.isSetNamedGroups()) {
+            ret.setNamedGroups(params.getNamedGroups().getNamedGroup());
+        }
         if (iparams != null && iparams.isSetKeyManagersRef() && 
!usingDefaults) {
             ret.setKeyManagers(iparams.getKeyManagersRef());
         }
diff --git 
a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterBase.java 
b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterBase.java
index ac17533ad2d..920b85cc895 100644
--- a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterBase.java
+++ b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSParameterBase.java
@@ -50,6 +50,7 @@ public class TLSParameterBase {
     protected SecureRandom    secureRandom;
     protected String          protocol;
     protected String          certAlias;
+    protected List<String>    namedGroups = new ArrayList<>();
     /**
      * Set the JSSE provider. If not set,
      * it uses system default.
@@ -187,4 +188,24 @@ public class TLSParameterBase {
     public String getCertAlias() {
         return certAlias;
     }
+
+    /**
+     * Sets the ordered list of TLS named groups (key-exchange groups) to offer
+     * during the handshake, e.g. {@code "X25519MLKEM768"}, {@code "x25519"}.
+     * Applied via {@code SSLParameters.setNamedGroups()} which requires JDK 
20+;
+     * silently ignored on older JDKs.
+     */
+    public final void setNamedGroups(List<String> groups) {
+        namedGroups = groups;
+    }
+
+    /**
+     * Returns the configured TLS named groups list.
+     */
+    public List<String> getNamedGroups() {
+        if (namedGroups == null) {
+            namedGroups = new ArrayList<>();
+        }
+        return namedGroups;
+    }
 }
diff --git 
a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java
 
b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java
index e63623b2caa..625fbbb42f2 100644
--- 
a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java
+++ 
b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSServerParametersConfig.java
@@ -95,6 +95,9 @@ public class TLSServerParametersConfig
         if (params.isSetSniHostCheck()) {
             this.setSniHostCheck(params.isSniHostCheck());
         }
+        if (params.isSetNamedGroups()) {
+            this.setNamedGroups(params.getNamedGroups().getNamedGroup());
+        }
         if (iparams != null && iparams.isSetKeyManagersRef()) {
             this.setKeyManagers(iparams.getKeyManagersRef());
         }
diff --git a/core/src/main/resources/schemas/configuration/security.xsd 
b/core/src/main/resources/schemas/configuration/security.xsd
index fbc28a30e78..0055e78f5a2 100644
--- a/core/src/main/resources/schemas/configuration/security.xsd
+++ b/core/src/main/resources/schemas/configuration/security.xsd
@@ -383,6 +383,20 @@
            <xs:element name="includeProtocol" type="xs:string" minOccurs="0" 
maxOccurs="unbounded"/>
         </xs:sequence>
     </xs:complexType>
+
+    <xs:complexType name="NamedGroups">
+      <xs:annotation>
+        <xs:documentation>
+        This structure holds an ordered list of TLS named groups (key-exchange 
groups) to offer
+        during the handshake.  Examples: "X25519MLKEM768" (PQC hybrid, JDK 27+ 
/ BC JSSE 1.81+),
+        "x25519", "secp256r1".  When set, the list is applied via 
SSLParameters.setNamedGroups()
+        (requires JDK 20+; silently ignored on older JDKs).
+        </xs:documentation>
+      </xs:annotation>
+        <xs:sequence>
+           <xs:element name="namedGroup" type="xs:string" minOccurs="0" 
maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
     
     <xs:complexType name="SecureRandomParameters">
       <xs:annotation>
@@ -512,6 +526,15 @@
                 </xs:documentation>
               </xs:annotation>
            </xs:element>
+           <xs:element name="namedGroups" type="tns:NamedGroups" minOccurs="0">
+              <xs:annotation>
+                <xs:documentation>
+                This element contains the ordered list of TLS named groups to 
offer during
+                the handshake (e.g. "X25519MLKEM768", "x25519", "secp256r1").
+                Requires JDK 20+; silently ignored on older JDKs.
+                </xs:documentation>
+              </xs:annotation>
+           </xs:element>
         </xs:all>
            <xs:attribute name="useHttpsURLConnectionDefaultSslSocketFactory" 
type="pt:ParameterizedBoolean" default="false">
              <xs:annotation>
@@ -651,6 +674,15 @@
                 </xs:documentation>
               </xs:annotation>
            </xs:element>
+           <xs:element name="namedGroups" type="tns:NamedGroups" minOccurs="0">
+              <xs:annotation>
+                <xs:documentation>
+                This element contains the ordered list of TLS named groups to 
offer during
+                the handshake (e.g. "X25519MLKEM768", "x25519", "secp256r1").
+                Requires JDK 20+; silently ignored on older JDKs.
+                </xs:documentation>
+              </xs:annotation>
+           </xs:element>
         </xs:all>
            <xs:attribute name="jsseProvider"          type="xs:string">
               <xs:annotation>
diff --git a/parent/pom.xml b/parent/pom.xml
index 338708b66d9..3165b508f39 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -97,7 +97,7 @@
         <cxf.assertj.version>4.0.0-M1</cxf.assertj.version>
         <cxf.atmosphere.version.range>[3.0, 4.0)</cxf.atmosphere.version.range>
         <cxf.atmosphere.version>3.1.0</cxf.atmosphere.version>
-        <cxf.bcprov.version>1.81</cxf.bcprov.version>
+        <cxf.bcprov.version>1.84</cxf.bcprov.version>
         <cxf.brave.version>6.3.1</cxf.brave.version>
         <cxf.cdi.api.version>4.1.0</cxf.cdi.api.version>
         <cxf.classgraph.version>4.8.25</cxf.classgraph.version>
diff --git 
a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/BCJsseServerALPNProcessor.java
 
b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/BCJsseServerALPNProcessor.java
new file mode 100644
index 00000000000..3fcf1c072d4
--- /dev/null
+++ 
b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/BCJsseServerALPNProcessor.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import javax.net.ssl.SSLEngine;
+
+import org.eclipse.jetty.alpn.server.ALPNServerConnection;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.ssl.ALPNProcessor;
+import org.eclipse.jetty.io.ssl.SslConnection;
+import org.eclipse.jetty.io.ssl.SslHandshakeListener;
+
+/**
+ * Jetty {@link ALPNProcessor.Server} for BouncyCastle JSSE ({@code 
bctls-jdk18on}).
+ *
+ * <p>Jetty's built-in {@code JDK9ServerALPNProcessor} only matches engines 
whose
+ * module is {@code java.base}, so it rejects BC JSSE's {@code ProvSSLEngine} 
and
+ * throws {@code IllegalStateException: No suitable ALPNProcessor}.  This 
processor
+ * bridges the gap: it claims BC JSSE engines and wires up the same
+ * {@link SSLEngine#setHandshakeApplicationProtocolSelector} callback that the
+ * built-in processor uses, delegating to {@link ALPNServerConnection#select}.
+ *
+ * <p>A {@link SslHandshakeListener} is also registered so that if the client 
does not
+ * advertise any ALPN protocols, {@link ALPNServerConnection#unsupported()} is 
called
+ * on handshake success to fall back to the server's default protocol 
(HTTP/1.1).
+ *
+ * <p>Registered via {@code 
META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server}.
+ */
+public class BCJsseServerALPNProcessor implements ALPNProcessor.Server {
+
+    @Override
+    public boolean appliesTo(SSLEngine sslEngine) {
+        return sslEngine.getClass().getName().startsWith("org.bouncycastle.");
+    }
+
+    @Override
+    public void configure(SSLEngine sslEngine, Connection connection) {
+        ALPNServerConnection alpnConn = (ALPNServerConnection) connection;
+
+        // Called when the client includes an ALPN extension in its 
ClientHello.
+        sslEngine.setHandshakeApplicationProtocolSelector((engine, protocols) 
-> {
+            try {
+                alpnConn.select(protocols);
+                return alpnConn.getProtocol();
+            } catch (Throwable t) {
+                return null;
+            }
+        });
+
+        // When the client sends no ALPN extension the selector above is never 
invoked,
+        // leaving getProtocol() null.  The SslHandshakeListener fires on 
handshake
+        // completion and calls unsupported() to fall back to the default 
protocol.
+        SslConnection.SslEndPoint sslEndPoint = (SslConnection.SslEndPoint) 
alpnConn.getEndPoint();
+        sslEndPoint.getSslConnection().addHandshakeListener(new 
SslHandshakeListener() {
+            @Override
+            public void handshakeSucceeded(Event event) {
+                if (alpnConn.getProtocol() == null) {
+                    alpnConn.unsupported();
+                }
+            }
+        });
+    }
+}
diff --git 
a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
 
b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
index 9a32cd63bb6..f17a42dc9ef 100644
--- 
a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
+++ 
b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
@@ -40,6 +40,8 @@ import java.util.logging.Logger;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
 
 import jakarta.annotation.PostConstruct;
 import jakarta.servlet.RequestDispatcher;
@@ -731,6 +733,19 @@ public class JettyHTTPServerEngine implements 
ServerEngine, HttpServerEngineSupp
                 public void checkKeyStore() {
                     //we'll handle this later
                 }
+                @Override
+                public SSLParameters customize(SSLParameters sslParams) {
+                    sslParams = super.customize(sslParams);
+                    org.apache.cxf.transport.https.SSLUtils.applyNamedGroups(
+                        sslParams, tlsServerParameters.getNamedGroups());
+                    return sslParams;
+                }
+                @Override
+                public void customize(SSLEngine sslEngine) {
+                    super.customize(sslEngine);
+                    org.apache.cxf.transport.https.SSLUtils.applyNamedGroupsBC(
+                        sslEngine, tlsServerParameters.getNamedGroups());
+                }
             };
             decorateCXFJettySslSocketConnector(sslcf);
         }
@@ -857,7 +872,21 @@ public class JettyHTTPServerEngine implements 
ServerEngine, HttpServerEngineSupp
     protected SSLContext createSSLContext(SslContextFactory scf) throws 
Exception  {
         // The full SSL context is provided by SSLContextServerParameters
         if (tlsServerParameters instanceof SSLContextServerParameters 
sslContextServerParameters) {
-            return sslContextServerParameters.getSslContext();
+            SSLContext context = sslContextServerParameters.getSslContext();
+            // Without setting included cipher suites here, Jetty's default
+            // SslContextFactory filter drops suite names it does not
+            // recognise (e.g. BouncyCastle JSSE names), causing
+            // handshake_failure even if the SSLContext supports them.
+            String[] supported =
+                SSLUtils.getServerSupportedCipherSuites(context);
+            String[] included = SSLUtils.getCiphersuitesToInclude(
+                tlsServerParameters.getCipherSuites(),
+                tlsServerParameters.getCipherSuitesFilter(),
+                context.getServerSocketFactory().getDefaultCipherSuites(),
+                supported,
+                LOG);
+            scf.setIncludeCipherSuites(included);
+            return context;
         }
 
         String proto = tlsServerParameters.getSecureSocketProtocol() == null
diff --git 
a/rt/transports/http-jetty/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server
 
b/rt/transports/http-jetty/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server
new file mode 100644
index 00000000000..4bef6cb1d47
--- /dev/null
+++ 
b/rt/transports/http-jetty/src/main/resources/META-INF/services/org.eclipse.jetty.io.ssl.ALPNProcessor$Server
@@ -0,0 +1 @@
+org.apache.cxf.transport.http_jetty.BCJsseServerALPNProcessor
diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
index 5efbef4c1e6..a4840ec06ef 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
@@ -433,10 +433,14 @@ public class HttpClientHTTPConduit extends 
URLConnectionHTTPConduit {
                         if (clientParameters.getSecureSocketProtocol() != 
null) {
                             String protocol = 
clientParameters.getSecureSocketProtocol();
                             SSLParameters params = new 
SSLParameters(cipherSuites, new String[] {protocol});
+                            
org.apache.cxf.transport.https.SSLUtils.applyNamedGroups(
+                                params, clientParameters.getNamedGroups());
                             cb.sslParameters(params);
                         } else {
                             final SSLParameters params = new 
SSLParameters(cipherSuites,
                                 
TLSClientParameters.getPreferredClientProtocols());
+                            
org.apache.cxf.transport.https.SSLUtils.applyNamedGroups(
+                                params, clientParameters.getNamedGroups());
                             cb.sslParameters(params);
                         }
                     }
diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
index 9ef974cc11d..970f9382710 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/https/SSLUtils.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cxf.transport.https;
 
+import java.lang.reflect.Method;
 import java.net.Socket;
 import java.nio.ByteBuffer;
 import java.security.GeneralSecurityException;
@@ -531,4 +532,43 @@ public final class SSLUtils {
         }
     };
 
+    /**
+     * Applies the given named groups to {@code SSLParameters} via reflection.
+     * {@code SSLParameters.setNamedGroups()} requires JDK 20+; this method
+     * silently skips the call on older JDKs.
+     */
+    public static void applyNamedGroups(SSLParameters params, List<String> 
namedGroups) {
+        if (namedGroups == null || namedGroups.isEmpty()) {
+            return;
+        }
+        try {
+            Method m = SSLParameters.class.getMethod("setNamedGroups", 
String[].class);
+            m.invoke(params, (Object) namedGroups.toArray(new String[0]));
+        } catch (NoSuchMethodException e) {
+            LOG.fine("SSLParameters.setNamedGroups() not available on this 
JDK; namedGroups ignored");
+        } catch (ReflectiveOperationException e) {
+            LOG.warning("Failed to apply TLS namedGroups: " + e.getMessage());
+        }
+    }
+
+    // Reflection-based BC JSSE path: avoids a compile-time dependency on 
bctls-jdk18on.
+    public static void applyNamedGroupsBC(SSLEngine sslEngine, List<String> 
namedGroups) {
+        if (namedGroups == null || namedGroups.isEmpty()) {
+            return;
+        }
+        try {
+            Class<?> bcEngineClass = 
Class.forName("org.bouncycastle.jsse.BCSSLEngine");
+            if (!bcEngineClass.isInstance(sslEngine)) {
+                return;
+            }
+            Class<?> bcParamsClass = 
Class.forName("org.bouncycastle.jsse.BCSSLParameters");
+            Object bcParams = 
bcEngineClass.getMethod("getParameters").invoke(sslEngine);
+            bcParamsClass.getMethod("setNamedGroups", String[].class)
+                .invoke(bcParams, (Object) namedGroups.toArray(new String[0]));
+            bcEngineClass.getMethod("setParameters", 
bcParamsClass).invoke(sslEngine, bcParams);
+        } catch (ReflectiveOperationException e) {
+            LOG.fine("Could not apply named groups via BC JSSE engine: " + 
e.getMessage());
+        }
+    }
+
 }
diff --git a/systests/transports/pom.xml b/systests/transports/pom.xml
index 2326fb1db1f..cafe5d38abf 100644
--- a/systests/transports/pom.xml
+++ b/systests/transports/pom.xml
@@ -111,6 +111,23 @@
                             </systemPropertyVariables>
                         </configuration>
                     </execution>
+                    <execution>
+                        <!-- Runs PQCTLSTest with jdk.tls.namedGroups 
including X25519MLKEM768,
+                             overriding the parent pom's BouncyCastle 
workaround that restricts
+                             named groups to classical-only. Requires JDK 27+ 
(JEP 527). -->
+                        <id>pqc-tls-test</id>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <includes>
+                                <include>**/pqc/PQCTLSTest.java</include>
+                            </includes>
+                            <systemPropertyVariables>
+                                
<jdk.tls.namedGroups>X25519MLKEM768,x25519,secp256r1,secp384r1,secp521r1</jdk.tls.namedGroups>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </execution>
                 </executions>
             </plugin>
             <plugin>
@@ -245,6 +262,18 @@
             <scope>test</scope>
             <classifier>keys</classifier>
         </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+            <version>${cxf.bcprov.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bctls-jdk18on</artifactId>
+            <version>${cxf.bcprov.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
diff --git 
a/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/BCJssePQCTest.java
 
b/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/BCJssePQCTest.java
new file mode 100644
index 00000000000..6be5fe5f83e
--- /dev/null
+++ 
b/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/BCJssePQCTest.java
@@ -0,0 +1,166 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.https.pqc;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.Security;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManagerFactory;
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jsse.BCSSLParameters;
+import org.bouncycastle.jsse.BCSSLSocket;
+import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
+
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Verifies BouncyCastle JSSE ({@code bctls-jdk18on} 1.84+) TLS support on JDK 
17-26
+ * using standard CXF XML configuration.
+ *
+ * <p>The server is configured via {@code bcjsse-server.xml} using
+ * {@code jsseProvider="BCJSSE"} on {@code httpj:tlsServerParameters}.
+ * HTTP/2 is supported via {@link BCJsseServerALPNProcessor}, which bridges
+ * BC JSSE's {@code ProvSSLEngine} into Jetty's ALPN negotiation framework.
+ * The client is configured via {@code bcjsse-client.xml}.
+ *
+ * <p>On JDK 27+, {@code PQCTLSTest} provides coverage via SunJSSE (JEP 527).
+ */
+public class BCJssePQCTest extends AbstractBusClientServerTestBase {
+
+    static final String PORT = allocatePort(BCJsseJettyServer.class);
+
+    // ------------------------------------------------------------------ setup
+
+    @BeforeClass
+    public static void setup() throws Exception {
+        // JDK 27+ is covered by PQCTLSTest via SunJSSE (JEP 527).
+        Assume.assumeTrue(
+            "BCJssePQCTest targets JDK 17-26; use PQCTLSTest on JDK 27+",
+            Runtime.version().feature() < 27);
+        // BC JSSE builds its context-level named-group map when SSLContext is 
first
+        // created; X25519MLKEM768 must be present there before the server 
starts.
+        System.setProperty("jdk.tls.namedGroups", "X25519MLKEM768");
+        // Append so Sun's JKS (which supports private-key entries) stays 
first.
+        // BC's JKS is read-only and cannot load private-key entries.
+        Security.addProvider(new BouncyCastleProvider());
+        Security.addProvider(new BouncyCastleJsseProvider());
+        assertTrue("Server failed to launch", 
launchServer(BCJsseJettyServer.class, true));
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        stopAllServers();
+        Security.removeProvider(BouncyCastleJsseProvider.PROVIDER_NAME);
+        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        System.clearProperty("jdk.tls.namedGroups");
+    }
+
+    // ------------------------------------------------------------------ 
server
+
+    /**
+     * CXF/Jetty server configured via {@code bcjsse-server.xml}: uses
+     * {@code jsseProvider="BCJSSE"} on {@code httpj:tlsServerParameters} so 
that
+     * CXF builds the SSLContext from BC JSSE rather than SunJSSE.  HTTP/2 is
+     * enabled via {@link BCJsseServerALPNProcessor}.
+     */
+    public static class BCJsseJettyServer extends AbstractBusTestServerBase {
+        @Override
+        protected void run() {
+            URL busFile = 
BCJsseJettyServer.class.getResource("bcjsse-server.xml");
+            Bus busLocal = new SpringBusFactory().createBus(busFile);
+            BusFactory.setDefaultBus(busLocal);
+            setBus(busLocal);
+        }
+    }
+
+    // ------------------------------------------------------------------ tests
+
+    @Test
+    public void testJettyMlKemHandshake() throws Exception {
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = BCJssePQCTest.class.getResource("bcjsse-client.xml");
+        Bus bus = bf.createBus(busFile.toString());
+        BusFactory.setDefaultBus(bus);
+        BusFactory.setThreadDefaultBus(bus);
+
+        QName serviceName =
+            new QName("http://apache.org/hello_world/services";, "SOAPService");
+        URL wsdl = SOAPService.WSDL_LOCATION;
+        SOAPService service = new SOAPService(wsdl, serviceName);
+        assertNotNull("Service is null", service);
+
+        Greeter greeter = service.getHttpsPort();
+        assertNotNull("Port is null", greeter);
+
+        updateAddressPort(greeter, PORT);
+
+        assertEquals("Hello Kitty", greeter.greetMe("Kitty"));
+
+        assertX25519MlKem768Negotiated();
+
+        ((java.io.Closeable) greeter).close();
+        bus.shutdown(true);
+    }
+
+    // Indirect proof: client restricted to X25519MLKEM768 only; server must 
pick from offered groups.
+    private void assertX25519MlKem768Negotiated() throws Exception {
+        KeyStore ts = KeyStore.getInstance("JKS");
+        try (InputStream is = BCJssePQCTest.class.getClassLoader()
+                .getResourceAsStream("keys/Truststore.jks")) {
+            ts.load(is, "password".toCharArray());
+        }
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+            TrustManagerFactory.getDefaultAlgorithm());
+        tmf.init(ts);
+
+        SSLContext ctx = SSLContext.getInstance("TLS", "BCJSSE");
+        ctx.init(null, tmf.getTrustManagers(), null);
+
+        try (SSLSocket sock = (SSLSocket) ctx.getSocketFactory()
+                .createSocket("localhost", Integer.parseInt(PORT))) {
+            sock.setSoTimeout(5000);
+            BCSSLSocket bcSock = (BCSSLSocket) sock;
+            BCSSLParameters p = bcSock.getParameters();
+            p.setNamedGroups(new String[] {"X25519MLKEM768"});
+            bcSock.setParameters(p);
+            sock.startHandshake();
+            assertEquals("TLSv1.3", sock.getSession().getProtocol());
+        }
+    }
+}
diff --git 
a/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/PQCTLSTest.java
 
b/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/PQCTLSTest.java
new file mode 100644
index 00000000000..3f6b3e94cef
--- /dev/null
+++ 
b/systests/transports/src/test/java/org/apache/cxf/systest/https/pqc/PQCTLSTest.java
@@ -0,0 +1,148 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.https.pqc;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Verifies that CXF can complete a TLS 1.3 handshake using the post-quantum
+ * hybrid key-encapsulation mechanism X25519MLKEM768 (JEP 527, JDK 27+).
+ *
+ * <p>The test requires SunJSSE to list {@value #MLKEM_GROUP} as a supported 
TLS
+ * named group.  This is the case only when running under the {@code 
pqc-tls-test}
+ * surefire execution, which overrides the parent-pom's classical-only
+ * {@code jdk.tls.namedGroups} setting and requires JDK 27+.  The test is
+ * automatically skipped on older JDKs or when the named-group override is 
absent.
+ *
+ * <p>The server is configured via {@code pqc-server.xml} (standard
+ * {@code httpj:tlsServerParameters}) and the client via {@code 
pqc-client.xml}.
+ * Because {@code jdk.tls.namedGroups} lists {@code X25519MLKEM768} first in 
the
+ * {@code pqc-tls-test} surefire execution, SunJSSE negotiates it by preference
+ * without any per-connection named-group override.
+ */
+public class PQCTLSTest extends AbstractBusClientServerTestBase {
+
+    static final String MLKEM_GROUP = "X25519MLKEM768";
+
+    static final String PORT = allocatePort(PQCServer.class);
+
+    /**
+     * True when SunJSSE lists {@value #MLKEM_GROUP} as a supported TLS named
+     * group in the current JVM configuration — JDK 27+ (JEP 527) with the 
right
+     * {@code jdk.tls.namedGroups} setting.
+     */
+    private static final boolean ML_KEM_AVAILABLE = isMlKemTlsSupported();
+
+    // ------------------------------------------------------------------ 
server
+
+    public static class PQCServer extends AbstractBusTestServerBase {
+        @Override
+        protected void run() {
+            URL busFile = PQCServer.class.getResource("pqc-server.xml");
+            Bus busLocal = new SpringBusFactory().createBus(busFile);
+            BusFactory.setDefaultBus(busLocal);
+            setBus(busLocal);
+        }
+    }
+
+    // ------------------------------------------------------------------ setup
+
+    @BeforeClass
+    public static void startServer() throws Exception {
+        Assume.assumeTrue(
+            "X25519MLKEM768 TLS not available — requires JDK 27+ with "
+            + "jdk.tls.namedGroups including " + MLKEM_GROUP,
+            ML_KEM_AVAILABLE);
+        assertTrue("Server failed to launch",
+            launchServer(PQCServer.class, true));
+    }
+
+    @AfterClass
+    public static void cleanup() throws Exception {
+        stopAllServers();
+    }
+
+    // ------------------------------------------------------------------ tests
+
+    @Test
+    public void testMlKemHandshakeSucceeds() throws Exception {
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = PQCTLSTest.class.getResource("pqc-client.xml");
+        Bus bus = bf.createBus(busFile.toString());
+        BusFactory.setDefaultBus(bus);
+        BusFactory.setThreadDefaultBus(bus);
+
+        QName serviceName =
+            new QName("http://apache.org/hello_world/services";, "SOAPService");
+        URL wsdl = SOAPService.WSDL_LOCATION;
+        SOAPService service = new SOAPService(wsdl, serviceName);
+        assertNotNull("Service is null", service);
+
+        Greeter port = service.getHttpsPort();
+        assertNotNull("Port is null", port);
+
+        updateAddressPort(port, PORT);
+
+        assertEquals("Hello Kitty", port.greetMe("Kitty"));
+
+        ((java.io.Closeable) port).close();
+        bus.shutdown(true);
+    }
+
+    // ------------------------------------------------------------------ 
helpers
+
+    /**
+     * Returns true only when SunJSSE lists {@value #MLKEM_GROUP} in its 
supported
+     * TLS named groups — JDK 27+ (JEP 527) with the right
+     * {@code jdk.tls.namedGroups} configuration.
+     */
+    private static boolean isMlKemTlsSupported() {
+        try {
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            ctx.init(null, null, null);
+            Method gm = SSLParameters.class.getMethod("getNamedGroups");
+            String[] groups = (String[]) 
gm.invoke(ctx.getSupportedSSLParameters());
+            return groups != null && 
java.util.Arrays.asList(groups).contains(MLKEM_GROUP);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}
diff --git a/systests/transports/src/test/resources/logging.properties 
b/systests/transports/src/test/resources/logging.properties
index 4889366a3ab..d7cb5074122 100644
--- a/systests/transports/src/test/resources/logging.properties
+++ b/systests/transports/src/test/resources/logging.properties
@@ -22,7 +22,7 @@
 # Default Logging Configuration File
 #
 # You can use a different file by specifying a filename
-# with the java.util.logging.config.file system property.  
+# with the java.util.logging.config.file system property.
 # For example java -Djava.util.logging.config.file=myfile
 ############################################################
 
@@ -30,7 +30,7 @@
 # Global properties
 ############################################################
 
-# "handlers" specifies a comma separated list of log Handler 
+# "handlers" specifies a comma separated list of log Handler
 # classes.  These handlers will be installed during VM startup.
 # Note that these classes must be on the system classpath.
 # By default we only configure a ConsoleHandler, which will only
diff --git 
a/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-client.xml
 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-client.xml
new file mode 100644
index 00000000000..e452fe527bf
--- /dev/null
+++ 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-client.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xmlns:http="http://cxf.apache.org/transports/http/configuration";
+    xmlns:cxf="http://cxf.apache.org/core";
+    xmlns:sec="http://cxf.apache.org/configuration/security";
+    xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+            http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://cxf.apache.org/transports/http/configuration
+            http://cxf.apache.org/schemas/configuration/http-conf.xsd
+        http://cxf.apache.org/configuration/security
+            http://cxf.apache.org/schemas/configuration/security.xsd
+        http://cxf.apache.org/core
+            http://cxf.apache.org/schemas/core.xsd";>
+
+    <cxf:bus>
+        <cxf:features>
+            <bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
+        </cxf:features>
+    </cxf:bus>
+
+    <http:conduit name="https://localhost:.*";>
+        <http:tlsClientParameters jsseProvider="BCJSSE" disableCNCheck="true">
+            <sec:trustManagers>
+                <sec:keyStore type="JKS" password="password" 
resource="keys/Truststore.jks"/>
+            </sec:trustManagers>
+            <sec:namedGroups>
+                <sec:namedGroup>X25519MLKEM768</sec:namedGroup>
+            </sec:namedGroups>
+        </http:tlsClientParameters>
+    </http:conduit>
+
+</beans>
diff --git 
a/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-server.xml
 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-server.xml
new file mode 100644
index 00000000000..9a7a877579f
--- /dev/null
+++ 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/bcjsse-server.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xmlns:jaxws="http://cxf.apache.org/jaxws";
+    xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration";
+    xmlns:sec="http://cxf.apache.org/configuration/security";
+    xmlns:cxf="http://cxf.apache.org/core";
+    xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+            http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://cxf.apache.org/jaxws
+            http://cxf.apache.org/schemas/jaxws.xsd
+        http://cxf.apache.org/core
+            http://cxf.apache.org/schemas/core.xsd
+        http://cxf.apache.org/transports/http-jetty/configuration
+            http://cxf.apache.org/schemas/configuration/http-jetty.xsd
+        http://cxf.apache.org/configuration/security
+            http://cxf.apache.org/schemas/configuration/security.xsd";>
+
+    <bean 
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+
+    <cxf:bus>
+        <cxf:features>
+            <bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
+        </cxf:features>
+    </cxf:bus>
+
+    <httpj:engine-factory id="bcjsse-tls-settings">
+        <httpj:engine port="${testutil.ports.BCJsseJettyServer}">
+            <httpj:tlsServerParameters jsseProvider="BCJSSE">
+                <sec:keyManagers keyPassword="password">
+                    <sec:keyStore type="JKS" password="password" 
resource="keys/Bethal.jks"/>
+                </sec:keyManagers>
+                <sec:trustManagers>
+                    <sec:keyStore type="JKS" password="password" 
resource="keys/Truststore.jks"/>
+                </sec:trustManagers>
+                <!-- Disable client authentication: BC JSSE rejects an empty 
client
+                     Certificate message even when only wantClientAuth is set. 
-->
+                <sec:clientAuthentication want="false" required="false"/>
+                <sec:namedGroups>
+                    <sec:namedGroup>X25519MLKEM768</sec:namedGroup>
+                </sec:namedGroups>
+            </httpj:tlsServerParameters>
+        </httpj:engine>
+    </httpj:engine-factory>
+
+    <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services";
+                    xmlns:s="http://apache.org/hello_world/services";
+                    id="BCJsseServer"
+                    implementor="org.apache.cxf.systest.http.GreeterImpl"
+                    
address="https://localhost:${testutil.ports.BCJsseJettyServer}/SoapContext/HttpsPort";
+                    serviceName="s:SOAPService"
+                    endpointName="e:HttpsPort"
+                    depends-on="bcjsse-tls-settings"/>
+
+</beans>
diff --git 
a/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-client.xml
 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-client.xml
new file mode 100644
index 00000000000..d18ba890af7
--- /dev/null
+++ 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-client.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xmlns:http="http://cxf.apache.org/transports/http/configuration";
+    xmlns:cxf="http://cxf.apache.org/core";
+    xmlns:sec="http://cxf.apache.org/configuration/security";
+    xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+            http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://cxf.apache.org/transports/http/configuration
+            http://cxf.apache.org/schemas/configuration/http-conf.xsd
+        http://cxf.apache.org/configuration/security
+            http://cxf.apache.org/schemas/configuration/security.xsd
+        http://cxf.apache.org/core
+            http://cxf.apache.org/schemas/core.xsd";>
+
+    <cxf:bus>
+        <cxf:features>
+            <bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
+        </cxf:features>
+    </cxf:bus>
+
+    <http:conduit name="https://localhost:.*";>
+        <http:tlsClientParameters disableCNCheck="true">
+            <sec:trustManagers>
+                <sec:keyStore type="JKS" password="password" 
resource="keys/Truststore.jks"/>
+            </sec:trustManagers>
+        </http:tlsClientParameters>
+    </http:conduit>
+
+</beans>
diff --git 
a/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-server.xml
 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-server.xml
new file mode 100644
index 00000000000..b9c900b3f22
--- /dev/null
+++ 
b/systests/transports/src/test/resources/org/apache/cxf/systest/https/pqc/pqc-server.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xmlns:jaxws="http://cxf.apache.org/jaxws";
+    xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration";
+    xmlns:sec="http://cxf.apache.org/configuration/security";
+    xmlns:cxf="http://cxf.apache.org/core";
+    xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+            http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://cxf.apache.org/jaxws
+            http://cxf.apache.org/schemas/jaxws.xsd
+        http://cxf.apache.org/core
+            http://cxf.apache.org/schemas/core.xsd
+        http://cxf.apache.org/transports/http-jetty/configuration
+            http://cxf.apache.org/schemas/configuration/http-jetty.xsd
+        http://cxf.apache.org/configuration/security
+            http://cxf.apache.org/schemas/configuration/security.xsd";>
+
+    <bean 
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+
+    <cxf:bus>
+        <cxf:features>
+            <bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
+        </cxf:features>
+    </cxf:bus>
+
+    <httpj:engine-factory id="pqc-tls-settings">
+        <httpj:engine port="${testutil.ports.PQCServer}">
+            <httpj:tlsServerParameters>
+                <sec:keyManagers keyPassword="password">
+                    <sec:keyStore type="JKS" password="password" 
resource="keys/Bethal.jks"/>
+                </sec:keyManagers>
+                <sec:trustManagers>
+                    <sec:keyStore type="JKS" password="password" 
resource="keys/Truststore.jks"/>
+                </sec:trustManagers>
+                <sec:clientAuthentication want="false" required="false"/>
+            </httpj:tlsServerParameters>
+        </httpj:engine>
+    </httpj:engine-factory>
+
+    <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services";
+                    xmlns:s="http://apache.org/hello_world/services";
+                    id="PQCTLSServer"
+                    implementor="org.apache.cxf.systest.http.GreeterImpl"
+                    
address="https://localhost:${testutil.ports.PQCServer}/SoapContext/HttpsPort";
+                    serviceName="s:SOAPService"
+                    endpointName="e:HttpsPort"
+                    depends-on="pqc-tls-settings"/>
+
+</beans>

Reply via email to