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

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

commit a7f884d132bc0ace1682d90efdd6e367240f3ab6
Author: Colm O hEigeartaigh <cohei...@apache.org>
AuthorDate: Wed Apr 10 13:48:52 2019 +0100

    Improving TLS configuration
---
 .../camel-coap/src/main/docs/coap-component.adoc   |  10 +-
 .../java/org/apache/camel/coap/CoAPComponent.java  |  53 ++++----
 .../java/org/apache/camel/coap/CoAPEndpoint.java   | 150 ++++++++++++++++++++-
 .../java/org/apache/camel/coap/CoAPProducer.java   |  45 +++----
 4 files changed, 198 insertions(+), 60 deletions(-)

diff --git a/components/camel-coap/src/main/docs/coap-component.adoc 
b/components/camel-coap/src/main/docs/coap-component.adoc
index 1517f4f..0ac6390 100644
--- a/components/camel-coap/src/main/docs/coap-component.adoc
+++ b/components/camel-coap/src/main/docs/coap-component.adoc
@@ -50,18 +50,24 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (6 parameters):
+==== Query Parameters (12 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *keyStoreParameters* (common) | The KeyStoreParameters object to use with 
TLS |  | KeyStoreParameters
+| *alias* (common) | Sets the alias used to query the KeyStore for the private 
key and certificate. |  | String
+| *cipherSuites* (common) | Sets the cipherSuites String. This is a comma 
separated String of ciphersuites to configure. |  | String
+| *keystore* (common) | Sets the TLS key store. Alternatively, a 
KeyStoreParameters object can be configured instead. An alias and password 
should also be configured on the route definition. |  | KeyStore
+| *keyStoreParameters* (common) | The KeyStoreParameters object to use with 
TLS to configure the keystore. Alternatively, a keystore parameter can be 
directly configured instead. An alias and password should also be configured on 
the route definition. |  | KeyStoreParameters
+| *truststore* (common) | Sets the TLS trust store. Alternatively, a 
trustStoreParameters object can be configured instead. All certificates in the 
truststore are used to establish trust. |  | KeyStore
+| *trustStoreParameters* (common) | The KeyStoreParameters object to use with 
TLS to configure the truststore. Alternatively, a truststore object can be 
directly configured instead. All certificates in the truststore are used to 
establish trust. |  | 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
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer 
creates an exchange. |  | ExchangePattern
 | *synchronous* (advanced) | Sets whether synchronous processing should be 
strictly used, or Camel is allowed to use asynchronous processing (if 
supported). | false | boolean
+| *password* (security) | Sets the password used to access an aliased 
PrivateKey in the KeyStore. |  | String
 |===
 // endpoint options: END
 // spring-boot-auto-configure options: START
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 40e2c20..13f0c9b 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,17 +16,10 @@
  */
 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;
@@ -68,10 +61,10 @@ public class CoAPComponent extends UriEndpointComponent 
implements RestConsumerF
         super(context, CoAPEndpoint.class);
     }
 
-    public synchronized CoapServer getServer(int port, KeyStoreParameters 
keyStoreParameters) {
+    public synchronized CoapServer getServer(int port, CoAPEndpoint endpoint) {
         CoapServer server = servers.get(port);
         if (server == null && port == -1) {
-            server = getServer(DEFAULT_PORT, keyStoreParameters);
+            server = getServer(DEFAULT_PORT, endpoint);
         }
         if (server == null) {
             CoapEndpoint.Builder coapBuilder = new CoapEndpoint.Builder();
@@ -79,37 +72,37 @@ public class CoAPComponent extends UriEndpointComponent 
implements RestConsumerF
             InetSocketAddress address = new InetSocketAddress(port);
             coapBuilder.setNetworkConfig(config);
             
-            if (keyStoreParameters != null) {
+            if (endpoint.getKeystore() != null) {
                 DtlsConnectorConfig.Builder builder = new 
DtlsConnectorConfig.Builder();
                 builder.setAddress(address);
+                if (endpoint.getAlias() == null) {
+                    throw new IllegalStateException("An alias must be 
configured to use TLS");
+                }
+                if (endpoint.getPassword() == null) {
+                    throw new IllegalStateException("A password must be 
configured to use TLS");
+                }
+                if (endpoint.getTruststore() == null) {
+                    throw new IllegalStateException("A truststore must be 
configured to use TLS");
+                }
 
                 try {
-                    KeyStore keyStore = keyStoreParameters.createKeyStore();
-                    // TODO
-                    PrivateKey privateKey = 
(PrivateKey)keyStoreParameters.createKeyStore().getKey("ec", 
"security".toCharArray());
-                    builder.setIdentity(privateKey, 
keyStore.getCertificateChain("ec"));
+                    // Configure the identity
+                    PrivateKey privateKey = 
+                        
(PrivateKey)endpoint.getKeystore().getKey(endpoint.getAlias(), 
endpoint.getPassword());
+                    builder.setIdentity(privateKey, 
endpoint.getKeystore().getCertificateChain(endpoint.getAlias()));
 
                     // 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.setTrustStore(endpoint.getTrustedCerts());
+
+                } catch (GeneralSecurityException e) {
+                    throw new IllegalStateException("Error in configuring 
TLS", e);
                 }
 
                 builder.setClientAuthenticationRequired(false); //TODO
 
-                builder.setSupportedCipherSuites(new String[] 
{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}); //TODO
+                if (endpoint.getConfiguredCipherSuites() != null) {
+                    
builder.setSupportedCipherSuites(endpoint.getConfiguredCipherSuites());
+                }
 
                 DTLSConnector connector = new DTLSConnector(builder.build());
                 coapBuilder.setConnector(connector);
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 5e989b7..2a3c0ad 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
@@ -16,7 +16,17 @@
  */
 package org.apache.camel.coap;
 
+import java.io.IOException;
 import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+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.List;
 
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
@@ -40,6 +50,26 @@ public class CoAPEndpoint extends DefaultEndpoint {
     
     @UriParam
     private KeyStoreParameters keyStoreParameters;
+    
+    @UriParam
+    private KeyStore keystore;
+    
+    @UriParam
+    private KeyStoreParameters trustStoreParameters;
+    
+    @UriParam
+    private KeyStore truststore;
+    
+    @UriParam
+    private String alias;
+    
+    @UriParam(label = "security", javaType = "java.lang.String", secret = true)
+    private char[] password;
+    
+    @UriParam
+    private String cipherSuites;
+    
+    private String[] configuredCipherSuites;
         
     private CoAPComponent component;
     
@@ -88,17 +118,131 @@ public class CoAPEndpoint extends DefaultEndpoint {
     }
 
     public CoapServer getCoapServer() {
-        return component.getServer(getUri().getPort(), keyStoreParameters);
+        return component.getServer(getUri().getPort(), this);
     }
     
     /**
-     * The KeyStoreParameters object to use with TLS
+     * The KeyStoreParameters object to use with TLS to configure the 
keystore. Alternatively, a "keystore" 
+     * parameter can be directly configured instead. An alias and password 
should also be configured on the route definition.
      */
     public KeyStoreParameters getKeyStoreParameters() {
         return keyStoreParameters;
     }
 
-    public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters) {
+    public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters) 
throws GeneralSecurityException, IOException {
         this.keyStoreParameters = keyStoreParameters;
+        if (keyStoreParameters != null) {
+            this.keystore = keyStoreParameters.createKeyStore();
+        }
+    }
+    
+    /**
+     * The KeyStoreParameters object to use with TLS to configure the 
truststore. Alternatively, a "truststore" 
+     * object can be directly configured instead. All certificates in the 
truststore are used to establish trust.
+     */
+    public KeyStoreParameters getTrustStoreParameters() {
+        return trustStoreParameters;
+    }
+
+    public void setTrustStoreParameters(KeyStoreParameters 
trustStoreParameters) throws GeneralSecurityException, IOException {
+        this.trustStoreParameters = trustStoreParameters;
+        if (trustStoreParameters != null) {
+            this.truststore = trustStoreParameters.createKeyStore();
+        }
+    }
+    
+    /**
+     * Gets the TLS key store. Alternatively, a KeyStoreParameters object can 
be configured instead.
+     * An alias and password should also be configured on the route definition.
+     */
+    public KeyStore getKeystore() {
+        return keystore;
+    }
+
+    /**
+     * Sets the TLS key store. Alternatively, a KeyStoreParameters object can 
be configured instead.
+     * An alias and password should also be configured on the route definition.
+     */
+    public void setKeystore(KeyStore keystore) {
+        this.keystore = keystore;
+    }
+    
+    /**
+     * Gets the TLS trust store. Alternatively, a "trustStoreParameters" 
object can be configured instead.
+     * All certificates in the truststore are used to establish trust.
+     */
+    public KeyStore getTruststore() {
+        return truststore;
+    }
+
+    /**
+     * Sets the TLS trust store. Alternatively, a "trustStoreParameters" 
object can be configured instead.
+     * All certificates in the truststore are used to establish trust.
+     */
+    public void setTruststore(KeyStore truststore) {
+        this.truststore = truststore;
+    }
+    
+    /**
+     * Gets the alias used to query the KeyStore for the private key and 
certificate.
+     */
+    public String getAlias() {
+        return alias;
+    }
+
+    /**
+     * Sets the alias used to query the KeyStore for the private key and 
certificate.
+     */
+    public void setAlias(String alias) {
+        this.alias = alias;
+    }
+    
+    /**
+     * Gets the password used to access an aliased {@link PrivateKey} in the 
KeyStore.
+     */
+    public char[] getPassword() {
+        return password;
+    }
+
+    /**
+     * Sets the password used to access an aliased {@link PrivateKey} in the 
KeyStore.
+     */
+    public void setPassword(char[] password) {
+        this.password = password;
+    }
+    
+    /**
+     * Gets the cipherSuites String. This is a comma separated String of 
ciphersuites to configure.
+     */
+    public String getCipherSuites() {
+        return cipherSuites;
+    }
+
+    /**
+     * Sets the cipherSuites String. This is a comma separated String of 
ciphersuites to configure.
+     */
+    public void setCipherSuites(String cipherSuites) {
+        this.cipherSuites = cipherSuites;
+        if (cipherSuites != null) {
+            configuredCipherSuites = cipherSuites.split(",");
+        }
+    }
+    
+    public String[] getConfiguredCipherSuites() {
+        return configuredCipherSuites;
+    }
+    
+    public Certificate[] getTrustedCerts() throws KeyStoreException {
+        Enumeration<String> aliases = truststore.aliases();
+        List<Certificate> trustCerts = new ArrayList<>();
+        while (aliases.hasMoreElements()) {
+            String alias = aliases.nextElement();
+            X509Certificate cert = (X509Certificate) 
truststore.getCertificate(alias);
+            if (cert != null) {
+                trustCerts.add(cert);
+            }
+        }
+        
+        return trustCerts.toArray(new Certificate[0]);
     }
 }
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 c4bc8c9..588e429 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,15 +16,9 @@
  */
 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 java.security.PrivateKey;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
@@ -103,32 +97,33 @@ public class CoAPProducer extends DefaultProducer {
             }
             client = new CoapClient(uri);
             
-            if (endpoint.getKeyStoreParameters() != null) {
+            if (endpoint.getTruststore() != 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);
+                    // Configure the identity if the keystore parameter is 
specified
+                    if (endpoint.getKeystore() != null) {
+                        if (endpoint.getAlias() == null) {
+                            throw new IllegalStateException("An alias must be 
configured to use TLS");
+                        }
+                        if (endpoint.getPassword() == null) {
+                            throw new IllegalStateException("A password must 
be configured to use TLS");
                         }
+                        PrivateKey privateKey = 
+                            
(PrivateKey)endpoint.getKeystore().getKey(endpoint.getAlias(), 
endpoint.getPassword());
+                        builder.setIdentity(privateKey, 
endpoint.getKeystore().getCertificateChain(endpoint.getAlias()));
                     }
-                    builder.setTrustStore(trustCerts.toArray(new 
Certificate[0]));
-                } catch (GeneralSecurityException | IOException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
+
+                    // Add all certificates from the truststore
+                    builder.setTrustStore(endpoint.getTrustedCerts());
+                } catch (GeneralSecurityException e) {
+                    throw new IllegalStateException("Error in configuring 
TLS", e);
                 }
 
-                builder.setSupportedCipherSuites(new String[] 
{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}); //TODO
+                if (endpoint.getConfiguredCipherSuites() != null) {
+                    
builder.setSupportedCipherSuites(endpoint.getConfiguredCipherSuites());
+                }
 
                 DTLSConnector connector = new DTLSConnector(builder.build());
                 CoapEndpoint.Builder coapBuilder = new CoapEndpoint.Builder();

Reply via email to