You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2020/03/27 17:55:34 UTC

[camel-k-runtime] branch master updated: platform-http: add support for ssl to PlatformHttpServer

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

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k-runtime.git


The following commit(s) were added to refs/heads/master by this push:
     new 4059eeb  platform-http: add support for ssl to PlatformHttpServer
4059eeb is described below

commit 4059eeb9ac1c711f05a4bc49b0d18331e7665bb6
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Fri Mar 27 16:46:52 2020 +0100

    platform-http: add support for ssl to PlatformHttpServer
---
 camel-k-runtime-http/pom.xml                       |  10 ++
 .../apache/camel/k/http/PlatformHttpServer.java    | 118 +++++++++++++++++-
 .../k/http/PlatformHttpServiceConfiguration.java   |   9 ++
 .../k/http/PlatformHttpServiceCustomizerTest.java  | 132 +++++++++++++++++++++
 .../src/test/resources/jsse/service.jks            | Bin 0 -> 1969 bytes
 .../src/test/resources/jsse/truststore.jks         | Bin 0 -> 582 bytes
 6 files changed, 264 insertions(+), 5 deletions(-)

diff --git a/camel-k-runtime-http/pom.xml b/camel-k-runtime-http/pom.xml
index c4d4eb2..a581d43 100644
--- a/camel-k-runtime-http/pom.xml
+++ b/camel-k-runtime-http/pom.xml
@@ -66,6 +66,16 @@
             <artifactId>camel-k-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jetty</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-http</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServer.java b/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServer.java
index 2e86409..62cd280 100644
--- a/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServer.java
+++ b/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServer.java
@@ -16,20 +16,32 @@
  */
 package org.apache.camel.k.http;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
 import java.util.Collections;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
+
 import io.vertx.core.Handler;
 import io.vertx.core.Vertx;
 import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.net.KeyCertOptions;
+import io.vertx.core.net.TrustOptions;
 import io.vertx.ext.web.Router;
 import io.vertx.ext.web.RoutingContext;
 import io.vertx.ext.web.handler.BodyHandler;
 import org.apache.camel.CamelContext;
 import org.apache.camel.component.platform.http.PlatformHttpConstants;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.camel.support.service.ServiceSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,13 +90,19 @@ public final class PlatformHttpServer extends ServiceSupport {
             new PlatformHttp(vertx, subRouter, Collections.singletonList(createBodyHandler()))
         );
 
-        //HttpServerOptions options = new HttpServerOptions();
-        if (configuration.getSslContextParameters() != null) {
-            // TODO: add ssl support
-            throw new UnsupportedOperationException("Not yet implemented");
+        SSLContextParameters sslParameters = configuration.getSslContextParameters();
+        if (sslParameters == null && configuration.isUseGlobalSslContextParameters()) {
+            sslParameters = context.getSSLContextParameters();
+        }
+
+        HttpServerOptions options = new HttpServerOptions();
+        if (sslParameters != null) {
+            options.setSsl(true);
+            options.setKeyCertOptions(createKeyCertOptions(sslParameters));
+            options.setTrustOptions(createTrustOptions(sslParameters));
         }
 
-        server = vertx.createHttpServer();
+        server = vertx.createHttpServer(options);
 
         return CompletableFuture.runAsync(
             () -> {
@@ -172,4 +190,94 @@ public final class PlatformHttpServer extends ServiceSupport {
             }
         };
     }
+
+    // *****************************
+    //
+    // SSL
+    //
+    // *****************************
+
+    private KeyCertOptions createKeyCertOptions(SSLContextParameters sslContextParameters) {
+        return new KeyCertOptions() {
+            @Override
+            public KeyManagerFactory getKeyManagerFactory(Vertx vertx) throws Exception {
+                return createKeyManagerFactory(sslContextParameters);
+            }
+
+            @Override
+            public KeyCertOptions clone() {
+                return this;
+            }
+        };
+    }
+
+    private KeyManagerFactory createKeyManagerFactory(SSLContextParameters sslContextParameters) throws GeneralSecurityException, IOException {
+        final KeyManagersParameters keyManagers = sslContextParameters.getKeyManagers();
+        if (keyManagers == null) {
+            return null;
+        }
+
+        String kmfAlgorithm = context.resolvePropertyPlaceholders(keyManagers.getAlgorithm());
+        if (kmfAlgorithm == null) {
+            kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
+        }
+
+        KeyManagerFactory kmf;
+        if (keyManagers.getProvider() == null) {
+            kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
+        } else {
+            kmf = KeyManagerFactory.getInstance(kmfAlgorithm, context.resolvePropertyPlaceholders(keyManagers.getProvider()));
+        }
+
+        char[] kmfPassword = null;
+        if (keyManagers.getKeyPassword() != null) {
+            kmfPassword = context.resolvePropertyPlaceholders(keyManagers.getKeyPassword()).toCharArray();
+        }
+
+        KeyStore ks = keyManagers.getKeyStore() == null ? null : keyManagers.getKeyStore().createKeyStore();
+
+        kmf.init(ks, kmfPassword);
+        return kmf;
+    }
+
+    private TrustOptions createTrustOptions(SSLContextParameters sslContextParameters) {
+        return new TrustOptions() {
+            @Override
+            public TrustOptions clone() {
+                return this;
+            }
+
+            @Override
+            public TrustManagerFactory getTrustManagerFactory(Vertx vertx) throws Exception {
+                return createTrustManagerFactory(sslContextParameters);
+            }
+        };
+    }
+
+    private TrustManagerFactory createTrustManagerFactory(SSLContextParameters sslContextParameters) throws GeneralSecurityException, IOException {
+        final TrustManagersParameters trustManagers = sslContextParameters.getTrustManagers();
+        if (trustManagers == null) {
+            return null;
+        }
+
+        TrustManagerFactory tmf = null;
+
+        if (trustManagers.getKeyStore() != null) {
+            String tmfAlgorithm = context.resolvePropertyPlaceholders(trustManagers.getAlgorithm());
+            if (tmfAlgorithm == null) {
+                tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+            }
+
+            if (trustManagers.getProvider() == null) {
+                tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+            } else {
+                tmf = TrustManagerFactory.getInstance(tmfAlgorithm, context.resolvePropertyPlaceholders(trustManagers.getProvider()));
+            }
+
+            KeyStore ks = trustManagers.getKeyStore() == null ? null : trustManagers.getKeyStore().createKeyStore();
+            tmf.init(ks);
+        }
+
+        return tmf;
+    }
 }
diff --git a/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServiceConfiguration.java b/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServiceConfiguration.java
index 5aa5a3e..2180e7d 100644
--- a/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServiceConfiguration.java
+++ b/camel-k-runtime-http/src/main/java/org/apache/camel/k/http/PlatformHttpServiceConfiguration.java
@@ -32,6 +32,7 @@ public class PlatformHttpServiceConfiguration {
 
     private BodyHandlerConfiguration bodyHandlerConfiguration = new BodyHandlerConfiguration();
     private SSLContextParameters sslContextParameters;
+    private boolean useGlobalSslContextParameters;
 
     public String getBindHost() {
         return bindHost;
@@ -81,6 +82,14 @@ public class PlatformHttpServiceConfiguration {
         this.sslContextParameters = sslContextParameters;
     }
 
+    public boolean isUseGlobalSslContextParameters() {
+        return useGlobalSslContextParameters;
+    }
+
+    public void setUseGlobalSslContextParameters(boolean useGlobalSslContextParameters) {
+        this.useGlobalSslContextParameters = useGlobalSslContextParameters;
+    }
+
     public static class BodyHandlerConfiguration {
         private boolean handleFileUploads = true;
         private String uploadsDirectory = "file-uploads";
diff --git a/camel-k-runtime-http/src/test/java/org/apache/camel/k/http/PlatformHttpServiceCustomizerTest.java b/camel-k-runtime-http/src/test/java/org/apache/camel/k/http/PlatformHttpServiceCustomizerTest.java
index 6864b1b..044292a 100644
--- a/camel-k-runtime-http/src/test/java/org/apache/camel/k/http/PlatformHttpServiceCustomizerTest.java
+++ b/camel-k-runtime-http/src/test/java/org/apache/camel/k/http/PlatformHttpServiceCustomizerTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.k.http;
 import io.vertx.core.http.HttpMethod;
 import io.vertx.core.json.Json;
 import io.vertx.core.json.JsonObject;
+import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.component.platform.http.PlatformHttpConstants;
@@ -26,7 +27,13 @@ import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.k.Runtime;
 import org.apache.camel.k.http.engine.RuntimePlatformHttpEngine;
 import org.apache.camel.k.test.AvailablePortFinder;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.KeyStoreParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.SSLContextServerParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.camel.util.ObjectHelper;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
@@ -142,4 +149,129 @@ public class PlatformHttpServiceCustomizerTest {
             runtime.getCamelContext().stop();
         }
     }
+
+    @Test
+    public void testPlatformHttpComponentSSL() throws Exception {
+        KeyStoreParameters keystoreParameters = new KeyStoreParameters();
+        keystoreParameters.setResource("jsse/service.jks");
+        keystoreParameters.setPassword("security");
+
+        SSLContextParameters serviceSSLContextParameters = new SSLContextParameters();
+        KeyManagersParameters serviceSSLKeyManagers = new KeyManagersParameters();
+        serviceSSLKeyManagers.setKeyPassword("security");
+        serviceSSLKeyManagers.setKeyStore(keystoreParameters);
+        serviceSSLContextParameters.setKeyManagers(serviceSSLKeyManagers);
+
+        KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+        truststoreParameters.setResource("jsse/truststore.jks");
+        truststoreParameters.setPassword("storepass");
+
+        TrustManagersParameters clientAuthServiceSSLTrustManagers = new TrustManagersParameters();
+        clientAuthServiceSSLTrustManagers.setKeyStore(truststoreParameters);
+        serviceSSLContextParameters.setTrustManagers(clientAuthServiceSSLTrustManagers);
+        SSLContextServerParameters clientAuthSSLContextServerParameters = new SSLContextServerParameters();
+        clientAuthSSLContextServerParameters.setClientAuthentication("REQUIRE");
+        serviceSSLContextParameters.setServerParameters(clientAuthSSLContextServerParameters);
+
+        SSLContextParameters clientSSLContextParameters = new SSLContextParameters();
+        TrustManagersParameters clientSSLTrustManagers = new TrustManagersParameters();
+        clientSSLTrustManagers.setKeyStore(truststoreParameters);
+        clientSSLContextParameters.setTrustManagers(clientSSLTrustManagers);
+
+        KeyManagersParameters clientAuthClientSSLKeyManagers = new KeyManagersParameters();
+        clientAuthClientSSLKeyManagers.setKeyPassword("security");
+        clientAuthClientSSLKeyManagers.setKeyStore(keystoreParameters);
+        clientSSLContextParameters.setKeyManagers(clientAuthClientSSLKeyManagers);
+
+        CamelContext context = new DefaultCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                fromF("platform-http:/")
+                    .transform().body(String.class, b -> b.toUpperCase());
+            }
+        });
+
+        PlatformHttpServiceContextCustomizer httpService = new PlatformHttpServiceContextCustomizer();
+        httpService.setBindPort(AvailablePortFinder.getNextAvailable());
+        httpService.setSslContextParameters(serviceSSLContextParameters);
+        httpService.apply(context);
+
+        try {
+            context.getRegistry().bind("clientSSLContextParameters", clientSSLContextParameters);
+            context.start();
+
+            String result = context.createFluentProducerTemplate()
+                .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", httpService.getBindPort())
+                .withBody("test")
+                .request(String.class);
+
+            assertThat(result).isEqualTo("TEST");
+        } finally {
+            context.stop();
+        }
+    }
+
+    @Test
+    public void testPlatformHttpComponentGlobalSSL() throws Exception {
+        KeyStoreParameters keystoreParameters = new KeyStoreParameters();
+        keystoreParameters.setResource("jsse/service.jks");
+        keystoreParameters.setPassword("security");
+
+        SSLContextParameters serviceSSLContextParameters = new SSLContextParameters();
+        KeyManagersParameters serviceSSLKeyManagers = new KeyManagersParameters();
+        serviceSSLKeyManagers.setKeyPassword("security");
+        serviceSSLKeyManagers.setKeyStore(keystoreParameters);
+        serviceSSLContextParameters.setKeyManagers(serviceSSLKeyManagers);
+
+        KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+        truststoreParameters.setResource("jsse/truststore.jks");
+        truststoreParameters.setPassword("storepass");
+
+        TrustManagersParameters clientAuthServiceSSLTrustManagers = new TrustManagersParameters();
+        clientAuthServiceSSLTrustManagers.setKeyStore(truststoreParameters);
+        serviceSSLContextParameters.setTrustManagers(clientAuthServiceSSLTrustManagers);
+        SSLContextServerParameters clientAuthSSLContextServerParameters = new SSLContextServerParameters();
+        clientAuthSSLContextServerParameters.setClientAuthentication("REQUIRE");
+        serviceSSLContextParameters.setServerParameters(clientAuthSSLContextServerParameters);
+
+        SSLContextParameters clientSSLContextParameters = new SSLContextParameters();
+        TrustManagersParameters clientSSLTrustManagers = new TrustManagersParameters();
+        clientSSLTrustManagers.setKeyStore(truststoreParameters);
+        clientSSLContextParameters.setTrustManagers(clientSSLTrustManagers);
+
+        KeyManagersParameters clientAuthClientSSLKeyManagers = new KeyManagersParameters();
+        clientAuthClientSSLKeyManagers.setKeyPassword("security");
+        clientAuthClientSSLKeyManagers.setKeyStore(keystoreParameters);
+        clientSSLContextParameters.setKeyManagers(clientAuthClientSSLKeyManagers);
+
+        CamelContext context = new DefaultCamelContext();
+        context.setSSLContextParameters(serviceSSLContextParameters);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                fromF("platform-http:/")
+                    .transform().body(String.class, b -> b.toUpperCase());
+            }
+        });
+
+        PlatformHttpServiceContextCustomizer httpService = new PlatformHttpServiceContextCustomizer();
+        httpService.setBindPort(AvailablePortFinder.getNextAvailable());
+        httpService.setUseGlobalSslContextParameters(true);
+        httpService.apply(context);
+
+        try {
+            context.getRegistry().bind("clientSSLContextParameters", clientSSLContextParameters);
+            context.start();
+
+            String result = context.createFluentProducerTemplate()
+                .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", httpService.getBindPort())
+                .withBody("test")
+                .request(String.class);
+
+            assertThat(result).isEqualTo("TEST");
+        } finally {
+            context.stop();
+        }
+    }
 }
diff --git a/camel-k-runtime-http/src/test/resources/jsse/service.jks b/camel-k-runtime-http/src/test/resources/jsse/service.jks
new file mode 100644
index 0000000..52321ad
Binary files /dev/null and b/camel-k-runtime-http/src/test/resources/jsse/service.jks differ
diff --git a/camel-k-runtime-http/src/test/resources/jsse/truststore.jks b/camel-k-runtime-http/src/test/resources/jsse/truststore.jks
new file mode 100644
index 0000000..44d82a8
Binary files /dev/null and b/camel-k-runtime-http/src/test/resources/jsse/truststore.jks differ