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 39538df0660bc3fd1935970a25e95e219bd7cb00
Author: Colm O hEigeartaigh <cohei...@apache.org>
AuthorDate: Wed Apr 24 11:52:08 2019 +0100

    Added initial support for raw public keys
---
 .../camel-coap/src/main/docs/coap-component.adoc   |  5 +-
 .../java/org/apache/camel/coap/CoAPEndpoint.java   | 82 +++++++++++++++++++---
 .../apache/camel/coap/CoAPComponentTLSTest.java    | 36 ++++++++++
 3 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/components/camel-coap/src/main/docs/coap-component.adoc 
b/components/camel-coap/src/main/docs/coap-component.adoc
index 0ac6390..1c7f280 100644
--- a/components/camel-coap/src/main/docs/coap-component.adoc
+++ b/components/camel-coap/src/main/docs/coap-component.adoc
@@ -50,7 +50,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (12 parameters):
+==== Query Parameters (15 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -60,6 +60,9 @@ with the following path and query parameters:
 | *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
+| *privateKey* (common) | Set the configured private key for use with Raw 
Public Key. |  | PrivateKey
+| *publicKey* (common) | Set the configured public key for use with Raw Public 
Key. |  | PublicKey
+| *trustedRpkStore* (common) | Set the TrustedRpkStore to use to determine 
trust in raw public keys. |  | TrustedRpkStore
 | *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
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 e2d9dbb..926bc24 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
@@ -23,6 +23,7 @@ import java.security.GeneralSecurityException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.PrivateKey;
+import java.security.PublicKey;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -41,6 +42,7 @@ import org.apache.camel.util.jsse.KeyStoreParameters;
 import org.eclipse.californium.core.CoapServer;
 import org.eclipse.californium.scandium.DTLSConnector;
 import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
+import org.eclipse.californium.scandium.dtls.rpkstore.TrustedRpkStore;
 
 /**
  * The coap component is used for sending and receiving messages from COAP 
capable devices.
@@ -63,7 +65,16 @@ public class CoAPEndpoint extends DefaultEndpoint {
     
     @UriParam
     private KeyStore truststore;
-    
+
+    @UriParam
+    private PrivateKey privateKey;
+
+    @UriParam
+    private PublicKey publicKey;
+
+    @UriParam
+    private TrustedRpkStore trustedRpkStore;
+
     @UriParam
     private String alias;
     
@@ -202,8 +213,50 @@ public class CoAPEndpoint extends DefaultEndpoint {
     public void setAlias(String alias) {
         this.alias = alias;
     }
+
+    /**
+     * Get the TrustedRpkStore to use to determine trust in raw public keys.
+     */
+    public TrustedRpkStore getTrustedRpkStore() {
+        return trustedRpkStore;
+    }
+
+    /**
+     * Set the TrustedRpkStore to use to determine trust in raw public keys.
+     */
+    public void setTrustedRpkStore(TrustedRpkStore trustedRpkStore) {
+        this.trustedRpkStore = trustedRpkStore;
+    }
     
     /**
+     * Get the configured private key for use with Raw Public Key.
+     */
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    /**
+     * Set the configured private key for use with Raw Public Key.
+     */
+    public void setPrivateKey(PrivateKey privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    /**
+     * Get the configured public key for use with Raw Public Key.
+     */
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
+
+    /**
+     * Set the configured public key for use with Raw Public Key.
+     */
+    public void setPublicKey(PublicKey publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    /**
      * Gets the password used to access an aliased {@link PrivateKey} in the 
KeyStore.
      */
     public char[] getPassword() {
@@ -293,19 +346,22 @@ public class CoAPEndpoint extends DefaultEndpoint {
 
         DtlsConnectorConfig.Builder builder = new 
DtlsConnectorConfig.Builder();
         if (client) {
-            if (getTruststore() == null) {
+            if (trustedRpkStore == null && getTruststore() == null) {
                 throw new IllegalStateException("A truststore must be 
configured to use TLS");
             }
             
             builder.setClientOnly();
         } else {
-            if (getKeystore() == null) {
-                throw new IllegalStateException("A keystore must be configured 
to use TLS");
+            if (privateKey == null && getKeystore() == null) {
+                throw new IllegalStateException("A keystore or private key 
must be configured to use TLS");
+            }
+            if (privateKey != null && publicKey == null) {
+                throw new IllegalStateException("A public key must be 
configured to use a Raw Public Key with TLS");
             }
-            if (getAlias() == null) {
+            if (privateKey == null && getAlias() == null) {
                 throw new IllegalStateException("An alias must be configured 
to use TLS");
             }
-            if (getPassword() == null) {
+            if (privateKey == null && getPassword() == null) {
                 throw new IllegalStateException("A password must be configured 
to use TLS");
             }
             if ((isClientAuthenticationRequired() || 
isClientAuthenticationWanted())
@@ -319,15 +375,23 @@ public class CoAPEndpoint extends DefaultEndpoint {
         }
 
         try {
-            // Configure the identity if the keystore parameter is specified
+            // Configure the identity if the keystore or privateKey parameter 
is specified
             if (getKeystore() != null) {
                 PrivateKey privateKey = 
                     (PrivateKey)getKeystore().getKey(getAlias(), 
getPassword());
                 builder.setIdentity(privateKey, 
getKeystore().getCertificateChain(getAlias()));
+            } else if (privateKey != null) {
+                builder.setIdentity(privateKey, publicKey);
             }
-    
+
             // Add all certificates from the truststore
-            builder.setTrustStore(getTrustedCerts());
+            Certificate[] certs = getTrustedCerts();
+            if (certs.length > 0) {
+                builder.setTrustStore(certs);
+            }
+            if (trustedRpkStore != null) {
+                builder.setRpkTrustStore(trustedRpkStore);
+            }
         } catch (GeneralSecurityException e) {
             throw new IllegalStateException("Error in configuring TLS", e);
         }
diff --git 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTest.java
 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTest.java
index f78bcb5..146fd1d 100644
--- 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTest.java
+++ 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.coap;
 
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
@@ -29,6 +33,7 @@ import org.apache.camel.test.junit4.CamelTestSupport;
 import org.apache.camel.util.jsse.KeyStoreParameters;
 import org.eclipse.californium.core.coap.CoAP;
 import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.eclipse.californium.scandium.dtls.rpkstore.TrustedRpkStore;
 import org.junit.Test;
 
 public class CoAPComponentTLSTest extends CamelTestSupport {
@@ -37,6 +42,7 @@ public class CoAPComponentTLSTest extends CamelTestSupport {
     protected static final int PORT2 = AvailablePortFinder.getNextAvailable();
     protected static final int PORT3 = AvailablePortFinder.getNextAvailable();
     protected static final int PORT4 = AvailablePortFinder.getNextAvailable();
+    protected static final int PORT5 = AvailablePortFinder.getNextAvailable();
 
     @Produce(uri = "direct:start")
     protected ProducerTemplate sender;
@@ -109,6 +115,17 @@ public class CoAPComponentTLSTest extends CamelTestSupport 
{
         assertMockEndpointsSatisfied();
     }
 
+    @Test
+    public void testRawPublicKey() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMinimumMessageCount(1);
+        mock.expectedBodiesReceived("Hello Camel CoAP");
+        mock.expectedHeaderReceived(Exchange.CONTENT_TYPE, 
MediaTypeRegistry.toString(MediaTypeRegistry.APPLICATION_OCTET_STREAM));
+        mock.expectedHeaderReceived(CoAPConstants.COAP_RESPONSE_CODE, 
CoAP.ResponseCode.CONTENT.toString());
+        sendBodyAndHeader("direct:rpk", "Camel CoAP", 
CoAPConstants.COAP_METHOD, "POST");
+        assertMockEndpointsSatisfied();
+    }
+
     @Override
     protected JndiRegistry createRegistry() throws Exception {
         JndiRegistry registry = super.createRegistry();
@@ -117,6 +134,12 @@ public class CoAPComponentTLSTest extends CamelTestSupport 
{
         keystoreParameters.setResource("service.jks");
         keystoreParameters.setPassword("security");
 
+        KeyStore keyStore = keystoreParameters.createKeyStore();
+        PrivateKey privateKey =
+            (PrivateKey)keyStore.getKey("service", "security".toCharArray());
+        PublicKey publicKey =
+            keyStore.getCertificate("service").getPublicKey();
+
         KeyStoreParameters keystoreParameters2 = new KeyStoreParameters();
         keystoreParameters2.setResource("selfsigned.jks");
         keystoreParameters2.setPassword("security");
@@ -133,11 +156,16 @@ public class CoAPComponentTLSTest extends 
CamelTestSupport {
         truststoreParameters2.setResource("truststore2.jks");
         truststoreParameters2.setPassword("storepass");
 
+        TrustedRpkStore trustedRpkStore = id -> { return true;};
+
         registry.bind("keyParams", keystoreParameters);
         registry.bind("keyParams2", keystoreParameters2);
         registry.bind("keyParams3", keystoreParameters3);
         registry.bind("trustParams", truststoreParameters);
         registry.bind("trustParams2", truststoreParameters2);
+        registry.bind("privateKey", privateKey);
+        registry.bind("publicKey", publicKey);
+        registry.bind("trustedRpkStore", trustedRpkStore);
 
         return registry;
     }
@@ -165,6 +193,10 @@ public class CoAPComponentTLSTest extends CamelTestSupport 
{
                     + 
"keyStoreParameters=#keyParams&cipherSuites=TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8",
 PORT4)
                   .transform(body().prepend("Hello "));
 
+                
fromF("coaps://localhost:%d/TestResource?alias=service&password=security&"
+                    + "privateKey=#privateKey&publicKey=#publicKey", PORT5)
+                  .transform(body().prepend("Hello "));
+
                 from("direct:start")
                     
.toF("coaps://localhost:%d/TestResource?trustStoreParameters=#trustParams", 
PORT)
                     .to("mock:result");
@@ -195,6 +227,10 @@ public class CoAPComponentTLSTest extends CamelTestSupport 
{
                     
.toF("coaps://localhost:%d/TestResource?trustStoreParameters=#trustParams&"
                          + "cipherSuites=TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 
PORT4)
                     .to("mock:result");
+
+                from("direct:rpk")
+                    
.toF("coaps://localhost:%d/TestResource?trustedRpkStore=#trustedRpkStore", 
PORT5)
+                    .to("mock:result");
             }
         };
     }

Reply via email to