This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new e21bff913015 CAMEL-24653: SSLCertTrustTest: replace external
badssl.com with local self-signed HTTPS endpoint (#26205)
e21bff913015 is described below
commit e21bff913015c097acaa741c26791b133e8224bb
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Sep 8 20:12:11 2026 +0200
CAMEL-24653: SSLCertTrustTest: replace external badssl.com with local
self-signed HTTPS endpoint (#26205)
* CAMEL-24653: replace external badssl.com dependency with local
self-signed HTTPS endpoint
The testUntrustedCertificate test connected to
https://untrusted-root.badssl.com
which is unreachable in CI environments with network restrictions, causing
flaky
failures.
Replace with a local SSLServerSocket using a self-signed certificate whose
CA is
not in the JVM's default trust store. The server starts in @BeforeAll on an
OS-assigned port and shuts down in @AfterAll, preserving the same test
semantics
(SSLHandshakeException on untrusted cert) without any network dependency.
Signed-off-by: Guillaume Nodet <[email protected]>
* Address review: restore timeout constants, use explicit charset
---------
Signed-off-by: Guillaume Nodet <[email protected]>
---
.../apache/camel/test/oauth/SSLCertTrustTest.java | 73 ++++++++++++++++++++-
.../src/test/resources/selfsigned-keystore.p12 | Bin 0 -> 2720 bytes
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git
a/components/camel-oauth/src/test/java/org/apache/camel/test/oauth/SSLCertTrustTest.java
b/components/camel-oauth/src/test/java/org/apache/camel/test/oauth/SSLCertTrustTest.java
index e5e1e7cc8b87..ecd28dc14e05 100644
---
a/components/camel-oauth/src/test/java/org/apache/camel/test/oauth/SSLCertTrustTest.java
+++
b/components/camel-oauth/src/test/java/org/apache/camel/test/oauth/SSLCertTrustTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.test.oauth;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.security.KeyStore;
import java.security.cert.CertificateException;
@@ -25,12 +26,17 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,6 +45,65 @@ class SSLCertTrustTest extends AbstractKeycloakTest {
private static final Logger LOG =
LoggerFactory.getLogger(SSLCertTrustTest.class);
+ /** PKCS12 keystore containing a self-signed certificate not in any
default trust store. */
+ private static final String SELFSIGNED_KEYSTORE =
"selfsigned-keystore.p12";
+ private static final String KEYSTORE_PASSWORD = "changeit";
+ private static final int CONNECT_TIMEOUT_MS = 10_000;
+ private static final int READ_TIMEOUT_MS = 10_000;
+
+ private static SSLServerSocket serverSocket;
+ private static Thread serverThread;
+ private static int localHttpsPort;
+
+ @BeforeAll
+ static void startLocalHttpsServer() throws Exception {
+ // Load the self-signed keystore from test resources
+ KeyStore ks = KeyStore.getInstance("PKCS12");
+ try (InputStream is =
SSLCertTrustTest.class.getClassLoader().getResourceAsStream(SELFSIGNED_KEYSTORE))
{
+ Assertions.assertNotNull(is, "Test keystore not found on
classpath: " + SELFSIGNED_KEYSTORE);
+ ks.load(is, KEYSTORE_PASSWORD.toCharArray());
+ }
+
+ KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, KEYSTORE_PASSWORD.toCharArray());
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(kmf.getKeyManagers(), null, null);
+
+ serverSocket = (SSLServerSocket)
sslContext.getServerSocketFactory().createServerSocket(0);
+ localHttpsPort = serverSocket.getLocalPort();
+
+ // Accept connections in a daemon thread — just complete TLS handshake
and respond
+ serverThread = new Thread(() -> {
+ while (!serverSocket.isClosed()) {
+ try (var socket = serverSocket.accept()) {
+ // Read enough to satisfy the HTTP request, then send a
minimal response
+ socket.getInputStream().read(new byte[1]);
+ socket.getOutputStream().write("HTTP/1.1 200
OK\r\nContent-Length:
0\r\n\r\n".getBytes(java.nio.charset.StandardCharsets.US_ASCII));
+ socket.getOutputStream().flush();
+ } catch (IOException e) {
+ if (!serverSocket.isClosed()) {
+ LOG.debug("Server accept error", e);
+ }
+ }
+ }
+ }, "ssl-test-server");
+ serverThread.setDaemon(true);
+ serverThread.start();
+
+ LOG.info("Started local HTTPS server with self-signed cert on port
{}", localHttpsPort);
+ }
+
+ @AfterAll
+ static void stopLocalHttpsServer() throws Exception {
+ if (serverSocket != null && !serverSocket.isClosed()) {
+ serverSocket.close();
+ }
+ if (serverThread != null) {
+ serverThread.join(5000);
+ }
+ }
+
@Test
void testCheckClusterCertificateTrust() throws Exception {
@@ -78,13 +143,17 @@ class SSLCertTrustTest extends AbstractKeycloakTest {
@Test
void testUntrustedCertificate() {
- String url = "https://untrusted-root.badssl.com"; // Example of an
untrusted cert
- Assertions.assertThrows(SSLHandshakeException.class, () ->
connectToUrl(url), "Certificate should not be trusted");
+ // Connect to local HTTPS server whose self-signed cert is NOT in the
default trust store
+ String url = "https://localhost:" + localHttpsPort;
+ Assertions.assertThrows(SSLHandshakeException.class, () ->
connectToUrl(url),
+ "Certificate should not be trusted");
}
private static void connectToUrl(String httpsUrl) throws IOException {
var url = URI.create(httpsUrl).toURL();
var con = (HttpsURLConnection) url.openConnection();
+ con.setConnectTimeout(CONNECT_TIMEOUT_MS);
+ con.setReadTimeout(READ_TIMEOUT_MS);
con.connect();
}
}
diff --git a/components/camel-oauth/src/test/resources/selfsigned-keystore.p12
b/components/camel-oauth/src/test/resources/selfsigned-keystore.p12
new file mode 100644
index 000000000000..0c7229c076ef
Binary files /dev/null and
b/components/camel-oauth/src/test/resources/selfsigned-keystore.p12 differ