You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by co...@apache.org on 2019/04/09 15:02:00 UTC

[camel] 02/02: Adding initial TLS support

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

coheigea pushed a commit to branch CAMEL-13402
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d786b6d5dd601198df6b0da2fd50ae21604f0fef
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Apr 9 16:01:30 2019 +0100

    Adding initial TLS support
---
 components/camel-coap/pom.xml                      |  5 ++
 .../camel-coap/src/main/docs/coap-component.adoc   |  3 +-
 .../java/org/apache/camel/coap/CoAPComponent.java  | 66 ++++++++++++++++++++--
 .../java/org/apache/camel/coap/CoAPEndpoint.java   | 17 +++++-
 .../java/org/apache/camel/coap/CoAPProducer.java   | 46 +++++++++++++++
 .../services/org/apache/camel/component/coaps      | 18 ++++++
 6 files changed, 147 insertions(+), 8 deletions(-)

diff --git a/components/camel-coap/pom.xml b/components/camel-coap/pom.xml
index e62d347..badedf1 100644
--- a/components/camel-coap/pom.xml
+++ b/components/camel-coap/pom.xml
@@ -46,6 +46,11 @@
             <artifactId>californium-core</artifactId>
             <version>${californium-version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.eclipse.californium</groupId>
+            <artifactId>scandium</artifactId>
+            <version>${californium-version}</version>
+        </dependency>
 
         <!-- logging -->
         <dependency>
diff --git a/components/camel-coap/src/main/docs/coap-component.adoc b/components/camel-coap/src/main/docs/coap-component.adoc
index 074744f..609f79e 100644
--- a/components/camel-coap/src/main/docs/coap-component.adoc
+++ b/components/camel-coap/src/main/docs/coap-component.adoc
@@ -50,12 +50,13 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (5 parameters):
+==== Query Parameters (6 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *keyStoreParameters* (common) | The KeyStoreParameters object to use with TLS |  | KeyStoreParameters
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *coapMethodRestrict* (consumer) | Comma separated list of methods that the CoAP consumer will bind to. The default is to bind to all methods (DELETE, GET, POST, PUT). |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
index 8f759d6..3629e5d 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPComponent.java
@@ -16,7 +16,17 @@
  */
 package org.apache.camel.coap;
 
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -29,12 +39,15 @@ import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spi.RestConsumerFactory;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.support.jsse.KeyStoreParameters;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.HostUtils;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.eclipse.californium.core.CoapServer;
-import org.eclipse.californium.core.network.config.NetworkConfig;
+import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.scandium.DTLSConnector;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,15 +64,56 @@ public class CoAPComponent extends DefaultComponent implements RestConsumerFacto
     public CoAPComponent() {
     }
 
-    public synchronized CoapServer getServer(int port) {
+    public synchronized CoapServer getServer(int port, KeyStoreParameters keyStoreParameters) {
         CoapServer server = servers.get(port);
         if (server == null && port == -1) {
-            server = getServer(DEFAULT_PORT);
+            server = getServer(DEFAULT_PORT, keyStoreParameters);
         }
         if (server == null) {
-            NetworkConfig config = new NetworkConfig();
-            //FIXME- configure the network stuff
-            server = new CoapServer(config, port);
+            CoapEndpoint.Builder coapBuilder = new CoapEndpoint.Builder();
+            InetSocketAddress address = new InetSocketAddress(port);
+            
+            if (keyStoreParameters != null) {
+                DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder();
+                builder.setAddress(address);
+
+                try {
+                    KeyStore keyStore = keyStoreParameters.createKeyStore();
+                    // TODO
+                    PrivateKey privateKey = (PrivateKey)keyStoreParameters.createKeyStore().getKey("ec", "security".toCharArray());
+                    builder.setIdentity(privateKey, keyStore.getCertificateChain("ec"));
+
+                    // Add all certificates from the truststore
+                    Enumeration<String> aliases = keyStore.aliases();
+                    List<Certificate> trustCerts = new ArrayList<>();
+                    while (aliases.hasMoreElements()) {
+                        String alias = aliases.nextElement();
+                        X509Certificate cert =
+                                (X509Certificate) keyStore.getCertificate(alias);
+                        if (cert != null) {
+                            trustCerts.add(cert);
+                        }
+                    }
+                    builder.setTrustStore(trustCerts.toArray(new Certificate[0]));
+
+                } catch (GeneralSecurityException | IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+
+                builder.setClientAuthenticationRequired(false); //TODO
+
+                builder.setSupportedCipherSuites(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}); //TODO
+
+                DTLSConnector connector = new DTLSConnector(builder.build());
+                coapBuilder.setConnector(connector);
+            } else {
+                coapBuilder.setInetSocketAddress(address);
+            }
+
+            server = new CoapServer();
+            server.addEndpoint(coapBuilder.build());
+            
             servers.put(port, server);
             if (this.isStarted()) {
                 server.start();
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
index 4cb3772..62a38f6 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
@@ -25,6 +25,7 @@ import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.support.jsse.KeyStoreParameters;
 import org.eclipse.californium.core.CoapServer;
 
 /**
@@ -36,6 +37,9 @@ public class CoAPEndpoint extends DefaultEndpoint {
     private URI uri;
     @UriParam(label = "consumer")
     private String coapMethodRestrict;
+    
+    @UriParam
+    private KeyStoreParameters keyStoreParameters;
         
     private CoAPComponent component;
     
@@ -84,6 +88,17 @@ public class CoAPEndpoint extends DefaultEndpoint {
     }
 
     public CoapServer getCoapServer() {
-        return component.getServer(getUri().getPort());
+        return component.getServer(getUri().getPort(), keyStoreParameters);
+    }
+    
+    /**
+     * The KeyStoreParameters object to use with TLS
+     */
+    public KeyStoreParameters getKeyStoreParameters() {
+        return keyStoreParameters;
+    }
+
+    public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters) {
+        this.keyStoreParameters = keyStoreParameters;
     }
 }
diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
index 633eded..74af733 100644
--- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
+++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPProducer.java
@@ -16,7 +16,15 @@
  */
 package org.apache.camel.coap;
 
+import java.io.IOException;
 import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
@@ -24,6 +32,9 @@ import org.apache.camel.support.DefaultProducer;
 import org.eclipse.californium.core.CoapClient;
 import org.eclipse.californium.core.CoapResponse;
 import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.scandium.DTLSConnector;
+import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
 
 /**
  * The CoAP producer.
@@ -91,6 +102,41 @@ public class CoAPProducer extends DefaultProducer {
                 uri = endpoint.getUri();
             }
             client = new CoapClient(uri);
+            
+            if (endpoint.getKeyStoreParameters() != null) {
+                DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder();
+                builder.setClientOnly();
+
+                try {
+                    // TODO Add client key config if specified
+                    
+                    KeyStore keyStore = endpoint.getKeyStoreParameters().createKeyStore();
+                    // Add all certificates from the truststore
+                    Enumeration<String> aliases = keyStore.aliases();
+                    List<Certificate> trustCerts = new ArrayList<>();
+                    while (aliases.hasMoreElements()) {
+                        String alias = aliases.nextElement();
+                        X509Certificate cert =
+                                (X509Certificate) keyStore.getCertificate(alias);
+                        if (cert != null) {
+                            trustCerts.add(cert);
+                        }
+                    }
+                    builder.setTrustStore(trustCerts.toArray(new Certificate[0]));
+                } catch (GeneralSecurityException | IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+
+                builder.setSupportedCipherSuites(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}); //TODO
+
+                DTLSConnector connector = new DTLSConnector(builder.build());
+                CoapEndpoint.Builder coapBuilder = new CoapEndpoint.Builder();
+                coapBuilder.setConnector(connector);
+
+                client.setEndpoint(coapBuilder.build());
+            }
+
         }
         return client;
     }
diff --git a/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps b/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps
new file mode 100644
index 0000000..e0129bc
--- /dev/null
+++ b/components/camel-coap/src/main/resources/META-INF/services/org/apache/camel/component/coaps
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.coap.CoAPComponent