Repository: camel
Updated Branches:
  refs/heads/master f4a81c8f4 -> a45fa8998


CAMEL-7281: Add support for certAlias in SSLContextParameters. Thanks to Colm 
for the patch.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a45fa899
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a45fa899
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a45fa899

Branch: refs/heads/master
Commit: a45fa89984f84bc8ddcbf8a29652319ae82b73c3
Parents: f4a81c8
Author: Claus Ibsen <davscl...@apache.org>
Authored: Mon Mar 10 19:36:37 2014 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Mon Mar 10 19:36:37 2014 +0100

----------------------------------------------------------------------
 .../jsse/AliasedX509ExtendedKeyManager.java     | 118 +++++++++++++++++++
 .../camel/util/jsse/SSLContextParameters.java   |  36 ++++++
 .../util/jsse/KeyManagersParametersTest.java    |  12 ++
 ...AbstractSSLContextParametersFactoryBean.java |  12 ++
 .../component/jetty/HttpsRouteAliasTest.java    |  75 ++++++++++++
 .../src/test/resources/jsse/localhost-alias.ks  | Bin 0 -> 2507 bytes
 .../SSLContextParametersFactoryBeanTest.java    |   1 +
 ...ContextParametersFactoryBeanTest-context.xml |   3 +-
 8 files changed, 256 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/camel-core/src/main/java/org/apache/camel/util/jsse/AliasedX509ExtendedKeyManager.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/util/jsse/AliasedX509ExtendedKeyManager.java
 
b/camel-core/src/main/java/org/apache/camel/util/jsse/AliasedX509ExtendedKeyManager.java
new file mode 100644
index 0000000..be63684
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/util/jsse/AliasedX509ExtendedKeyManager.java
@@ -0,0 +1,118 @@
+/**
+ * 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.
+ */
+package org.apache.camel.util.jsse;
+
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+
+/* ------------------------------------------------------------ */
+/**
+ * KeyManager to select a key with desired alias while delegating processing 
to specified KeyManager Can be
+ * used both with server and client sockets
+ */
+public class AliasedX509ExtendedKeyManager extends X509ExtendedKeyManager {
+    private String keyAlias;
+    private X509KeyManager keyManager;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct KeyManager instance
+     * 
+     * @param keyAlias Alias of the key to be selected
+     * @param keyManager Instance of KeyManager to be wrapped
+     * @throws Exception
+     */
+    public AliasedX509ExtendedKeyManager(String keyAlias, X509KeyManager 
keyManager) throws Exception {
+        this.keyAlias = keyAlias;
+        this.keyManager = keyManager;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], 
java.security.Principal[],
+     *      java.net.Socket)
+     */
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, 
Socket socket) {
+        return keyAlias == null ? keyManager.chooseClientAlias(keyType, 
issuers, socket) : keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, 
java.security.Principal[],
+     *      java.net.Socket)
+     */
+    public String chooseServerAlias(String keyType, Principal[] issuers, 
Socket socket) {
+        return keyAlias == null ? keyManager.chooseServerAlias(keyType, 
issuers, socket) : keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, 
java.security.Principal[])
+     */
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return keyManager.getClientAliases(keyType, issuers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, 
java.security.Principal[])
+     */
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return keyManager.getServerAliases(keyType, issuers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String)
+     */
+    public X509Certificate[] getCertificateChain(String alias) {
+        return keyManager.getCertificateChain(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String)
+     */
+    public PrivateKey getPrivateKey(String alias) {
+        return keyManager.getPrivateKey(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see 
javax.net.ssl.X509ExtendedKeyManager#chooseEngineServerAlias(java.lang.String,
+     *      java.security.Principal[], javax.net.ssl.SSLEngine)
+     */
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, 
SSLEngine engine) {
+        return keyAlias == null ? super.chooseEngineServerAlias(keyType, 
issuers, engine) : keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see 
javax.net.ssl.X509ExtendedKeyManager#chooseEngineClientAlias(String[], 
Principal[], SSLEngine)
+     */
+    @Override
+    public String chooseEngineClientAlias(String keyType[], Principal[] 
issuers, SSLEngine engine) {
+        return keyAlias == null ? super.chooseEngineClientAlias(keyType, 
issuers, engine) : keyAlias;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextParameters.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextParameters.java 
b/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextParameters.java
index aa8b49b..ab0eb9c 100644
--- 
a/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextParameters.java
+++ 
b/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextParameters.java
@@ -28,6 +28,7 @@ import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509KeyManager;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -92,6 +93,12 @@ public class SSLContextParameters extends 
BaseSSLContextParameters {
      * standard protocol names.
      */
     private String secureSocketProtocol;    
+    
+    /**
+     * An optional certificate alias to use. This is useful when the keystore 
has multiple 
+     * certificates.
+     */
+    private String certAlias;
 
     public KeyManagersParameters getKeyManagers() {
         return keyManagers;
@@ -213,6 +220,19 @@ public class SSLContextParameters extends 
BaseSSLContextParameters {
         this.secureSocketProtocol = secureSocketProtocol;
     }
     
+    public String getCertAlias() {
+        return certAlias;
+    }
+
+    /**
+     * An optional certificate alias to use. This is useful when the keystore 
has multiple 
+     * certificates.
+     * @param certAlias an optional certificate alias to use
+     */
+    public void setCertAlias(String certAlias) {
+        this.certAlias = certAlias;
+    }
+    
     ////////////////////////////////////////////
     
     /**
@@ -245,6 +265,19 @@ public class SSLContextParameters extends 
BaseSSLContextParameters {
                                              
this.parsePropertyValue(this.getProvider()));
         }
         
+        if (this.getCertAlias() != null && keyManagers != null) {
+            for (int idx = 0; idx < keyManagers.length; idx++) {
+                if (keyManagers[idx] instanceof X509KeyManager) {
+                    try {
+                        keyManagers[idx] = new 
AliasedX509ExtendedKeyManager(this.getCertAlias(),
+                                                                             
(X509KeyManager)keyManagers[idx]);
+                    } catch (Exception e) {
+                        throw new GeneralSecurityException(e);
+                    }
+                }
+            }
+        }
+        
         LOG.debug("SSLContext [{}], initialized from [{}], is using provider 
[{}], protocol [{}], key managers {}, trust managers {}, and secure random 
[{}].",
                  new Object[] {context, this, context.getProvider(), 
context.getProtocol(), keyManagers, trustManagers, secureRandom});
         
@@ -354,6 +387,8 @@ public class SSLContextParameters extends 
BaseSSLContextParameters {
         builder.append(provider);
         builder.append(", secureSocketProtocol=");
         builder.append(secureSocketProtocol);
+        builder.append(", certAlias=");
+        builder.append(certAlias);
         builder.append(", getCipherSuites()=");
         builder.append(getCipherSuites());
         builder.append(", getCipherSuitesFilter()=");
@@ -369,4 +404,5 @@ public class SSLContextParameters extends 
BaseSSLContextParameters {
         builder.append("]");
         return builder.toString();
     }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/camel-core/src/test/java/org/apache/camel/util/jsse/KeyManagersParametersTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/util/jsse/KeyManagersParametersTest.java
 
b/camel-core/src/test/java/org/apache/camel/util/jsse/KeyManagersParametersTest.java
index a6b7937..f3f55c8 100644
--- 
a/camel-core/src/test/java/org/apache/camel/util/jsse/KeyManagersParametersTest.java
+++ 
b/camel-core/src/test/java/org/apache/camel/util/jsse/KeyManagersParametersTest.java
@@ -128,6 +128,18 @@ public class KeyManagersParametersTest extends 
AbstractJsseParametersTest {
             // expected
         }
     }
+    
+    public void testAliasedKeyManager() throws Exception {
+        KeyManagersParameters kmp = this.createMinimalKeyManagersParameters();
+        
+        KeyManager[] kms = kmp.createKeyManagers();
+        assertEquals(1, kms.length);
+        assertTrue(kms[0] instanceof X509KeyManager);
+        
+        kms[0] = new AliasedX509ExtendedKeyManager("server", 
(X509KeyManager)kms[0]);
+        AliasedX509ExtendedKeyManager km = (AliasedX509ExtendedKeyManager) 
kms[0];
+        assertNotNull(km.getPrivateKey("server"));
+    }
 
     protected void validateKeyManagers(KeyManager[] kms) {
         assertEquals(1, kms.length);

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextParametersFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextParametersFactoryBean.java
 
b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextParametersFactoryBean.java
index 2121b94..81aeeef 100644
--- 
a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextParametersFactoryBean.java
+++ 
b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextParametersFactoryBean.java
@@ -32,6 +32,9 @@ public abstract class AbstractSSLContextParametersFactoryBean 
extends AbstractBa
 
     @XmlAttribute
     private String secureSocketProtocol;
+    
+    @XmlAttribute
+    private String certAlias;
 
     @Override
     protected SSLContextParameters createInstance() throws Exception {
@@ -65,6 +68,7 @@ public abstract class AbstractSSLContextParametersFactoryBean 
extends AbstractBa
         
         newInstance.setProvider(provider);
         newInstance.setSecureSocketProtocol(secureSocketProtocol);
+        newInstance.setCertAlias(certAlias);
         newInstance.setCamelContext(getCamelContext());
         
         return newInstance;
@@ -90,6 +94,14 @@ public abstract class 
AbstractSSLContextParametersFactoryBean extends AbstractBa
     public void setSecureSocketProtocol(String secureSocketProtocol) {
         this.secureSocketProtocol = secureSocketProtocol;
     }
+    
+    public String getCertAlias() {
+        return certAlias;
+    }
+
+    public void setCertAlias(String certAlias) {
+        this.certAlias = certAlias;
+    }
 
     protected abstract AbstractKeyManagersParametersFactoryBean 
getKeyManagers();
 

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpsRouteAliasTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpsRouteAliasTest.java
 
b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpsRouteAliasTest.java
new file mode 100644
index 0000000..47a3595
--- /dev/null
+++ 
b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpsRouteAliasTest.java
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ */
+package org.apache.camel.component.jetty;
+
+import java.net.URISyntaxException;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.util.jsse.KeyManagersParameters;
+import org.apache.camel.util.jsse.KeyStoreParameters;
+import org.apache.camel.util.jsse.SSLContextParameters;
+
+public class HttpsRouteAliasTest extends HttpsRouteTest {
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws URISyntaxException {
+                // create jetty component
+                JettyHttpComponent jetty = new JettyHttpComponent();
+                
+                KeyStoreParameters ksp = new KeyStoreParameters();
+                
ksp.setResource(this.getClass().getClassLoader().getResource("jsse/localhost-alias.ks").toString());
+                ksp.setPassword(pwd);
+                
+                KeyManagersParameters kmp = new KeyManagersParameters();
+                kmp.setKeyPassword(pwd);
+                kmp.setKeyStore(ksp);
+                
+                SSLContextParameters sslContextParameters = new 
SSLContextParameters();
+                sslContextParameters.setKeyManagers(kmp);
+                
+                // Specify "server" cert alias
+                sslContextParameters.setCertAlias("server");
+                
+                jetty.setSslContextParameters(sslContextParameters);
+                
+                // NOTE: These are here to check that they are properly 
ignored.
+                jetty.addSslSocketConnectorProperty("keyPassword", 
"sadfasdfasdfas");
+                jetty.addSslSocketConnectorProperty("password", 
"asdfasdfasdfdasfs");
+                jetty.addSslSocketConnectorProperty("keystore", "");
+                jetty.addSslSocketConnectorProperty("truststoreType", "JKS");
+
+                // add jetty to camel context
+                context.addComponent("jetty", jetty);
+
+                from("jetty:https://localhost:"; + port1 + 
"/test").to("mock:a");
+
+                Processor proc = new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        exchange.getOut().setBody("<b>Hello World</b>");
+                    }
+                };
+                from("jetty:https://localhost:"; + port1 + 
"/hello").process(proc);
+
+                from("jetty:https://localhost:"; + port2 + 
"/test").to("mock:b");
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/components/camel-jetty/src/test/resources/jsse/localhost-alias.ks
----------------------------------------------------------------------
diff --git a/components/camel-jetty/src/test/resources/jsse/localhost-alias.ks 
b/components/camel-jetty/src/test/resources/jsse/localhost-alias.ks
new file mode 100644
index 0000000..33fb9b6
Binary files /dev/null and 
b/components/camel-jetty/src/test/resources/jsse/localhost-alias.ks differ

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/components/camel-spring/src/test/java/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring/src/test/java/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest.java
 
b/components/camel-spring/src/test/java/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest.java
index ce3496f..5f322bf 100644
--- 
a/components/camel-spring/src/test/java/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest.java
+++ 
b/components/camel-spring/src/test/java/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest.java
@@ -44,6 +44,7 @@ public class SSLContextParametersFactoryBeanTest {
         
         assertEquals("provider", scp.getProvider());
         assertEquals("protocol", scp.getSecureSocketProtocol());
+        assertEquals("alice", scp.getCertAlias());
         
         validateBaseSSLContextParameters(scp);
         

http://git-wip-us.apache.org/repos/asf/camel/blob/a45fa899/components/camel-spring/src/test/resources/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest-context.xml
----------------------------------------------------------------------
diff --git 
a/components/camel-spring/src/test/resources/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest-context.xml
 
b/components/camel-spring/src/test/resources/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest-context.xml
index dc60b10..b9dfde6 100644
--- 
a/components/camel-spring/src/test/resources/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest-context.xml
+++ 
b/components/camel-spring/src/test/resources/org/apache/camel/util/spring/SSLContextParametersFactoryBeanTest-context.xml
@@ -28,7 +28,8 @@
       id="scp"
       sessionTimeout="1"
       secureSocketProtocol="protocol"
-      provider="provider">
+      provider="provider"
+      certAlias="alice">
     
     <camel:cipherSuites>
       <camel:cipherSuite>cipherSuite</camel:cipherSuite>

Reply via email to