summaryrefslogtreecommitdiff
path: root/qpid/java/broker
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2013-08-08 15:05:58 +0000
committerRobert Godfrey <rgodfrey@apache.org>2013-08-08 15:05:58 +0000
commit414074d9fcec48fe395a061d3d31c255c4bbc13f (patch)
tree1e7f921c6606c23518f67795bc8955a565692e68 /qpid/java/broker
parente33c4e5c33768233282b69c9cb14dd515d191bb7 (diff)
downloadqpid-python-414074d9fcec48fe395a061d3d31c255c4bbc13f.tar.gz
QPID-5056 : [Java Broker] Change configuration model to allow for KeyStores/TrustStores which are not JKS files on the filesystem
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1511825 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker')
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java76
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java63
5 files changed, 161 insertions, 30 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
index 74a7469ffb..ab909390bd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
@@ -20,9 +20,11 @@
*/
package org.apache.qpid.server.model;
+import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import javax.net.ssl.KeyManager;
public interface KeyStore extends ConfiguredObject
{
@@ -64,4 +66,7 @@ public interface KeyStore extends ConfiguredObject
public String getPassword();
public void setPassword(String password);
+
+ public KeyManager[] getKeyManagers() throws GeneralSecurityException;
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
index c686e7bd50..d313e1832f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
@@ -20,9 +20,11 @@
*/
package org.apache.qpid.server.model;
+import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import javax.net.ssl.TrustManager;
public interface TrustStore extends ConfiguredObject
{
@@ -64,4 +66,8 @@ public interface TrustStore extends ConfiguredObject
public String getPassword();
public void setPassword(String password);
+
+ public TrustManager[] getTrustManagers() throws GeneralSecurityException;
+
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
index 02ff98fb0e..a4ce95e5aa 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
@@ -21,18 +21,21 @@ package org.apache.qpid.server.model.adapter;
import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -46,10 +49,9 @@ import org.apache.qpid.server.model.TrustStore;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
-import org.apache.qpid.server.util.MapValueConverter;
-import org.apache.qpid.ssl.SSLContextFactory;
import org.apache.qpid.transport.NetworkTransportConfiguration;
import org.apache.qpid.transport.network.IncomingNetworkTransport;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
public class AmqpPortAdapter extends PortAdapter
{
@@ -136,8 +138,8 @@ public class AmqpPortAdapter extends PortAdapter
private SSLContext createSslContext()
{
KeyStore keyStore = getKeyStore();
-
Collection<TrustStore> trustStores = getTrustStores();
+
boolean needClientCert = (Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH);
if (needClientCert && trustStores.isEmpty())
{
@@ -145,44 +147,58 @@ public class AmqpPortAdapter extends PortAdapter
+ this.getName() + "' but no trust store defined");
}
- String keystorePath = (String)keyStore.getAttribute(KeyStore.PATH);
- String keystorePassword = keyStore.getPassword();
- String keystoreType = (String)keyStore.getAttribute(KeyStore.TYPE);
- String keyManagerFactoryAlgorithm = (String)keyStore.getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
- String certAlias = (String)keyStore.getAttribute(KeyStore.CERTIFICATE_ALIAS);
-
- final SSLContext sslContext;
try
{
- if(! trustStores.isEmpty())
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ KeyManager[] keyManagers = keyStore.getKeyManagers();
+
+ TrustManager[] trustManagers;
+ if(trustStores == null || trustStores.isEmpty())
{
- Collection<SSLContextFactory.TrustStoreWrapper> trstWrappers = new ArrayList<SSLContextFactory.TrustStoreWrapper>();
- for (TrustStore trustStore : trustStores)
- {
- trstWrappers.add(new SSLContextFactory.TrustStoreWrapper((String)trustStore.getAttribute(TrustStore.PATH),
- trustStore.getPassword(),
- (String)trustStore.getAttribute(TrustStore.TYPE),
- (Boolean) trustStore.getAttribute(TrustStore.PEERS_ONLY),
- (String)trustStore.getAttribute(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM)));
- }
- sslContext = SSLContextFactory.buildClientContext(trstWrappers, keystorePath,
- keystorePassword, keystoreType,
- keyManagerFactoryAlgorithm, certAlias);
+ trustManagers = null;
+ }
+ else if(trustStores.size() == 1)
+ {
+ trustManagers = trustStores.iterator().next().getTrustManagers();
}
else
{
- sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm);
+ Collection<TrustManager> trustManagerList = new ArrayList<TrustManager>();
+ final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+
+ for(TrustStore ts : trustStores)
+ {
+ TrustManager[] managers = ts.getTrustManagers();
+ if(managers != null)
+ {
+ for(TrustManager manager : managers)
+ {
+ if(manager instanceof X509TrustManager)
+ {
+ mulTrustManager.addTrustManager((X509TrustManager)manager);
+ }
+ else
+ {
+ trustManagerList.add(manager);
+ }
+ }
+ }
+ }
+ if(!mulTrustManager.isEmpty())
+ {
+ trustManagerList.add(mulTrustManager);
+ }
+ trustManagers = trustManagerList.toArray(new TrustManager[trustManagerList.size()]);
}
+ sslContext.init(keyManagers, trustManagers, null);
+
+ return sslContext;
+
}
catch (GeneralSecurityException e)
{
throw new RuntimeException("Unable to create SSLContext for key or trust store", e);
}
- catch (IOException e)
- {
- throw new RuntimeException("Unable to create SSLContext - unable to load key/trust store", e);
- }
- return sslContext;
}
private AmqpProtocolVersion getDefaultAmqpSupportedReply()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
index 4d4d3bb31d..1101232c96 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
@@ -20,8 +20,10 @@
*/
package org.apache.qpid.server.model.adapter;
+import java.io.IOException;
import java.lang.reflect.Type;
import java.security.AccessControlException;
+import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
@@ -32,6 +34,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
@@ -42,6 +45,7 @@ import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.QpidClientX509KeyManager;
import org.apache.qpid.transport.network.security.ssl.SSLUtil;
public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore
@@ -210,4 +214,41 @@ public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore
+ keyManagerFactoryAlgorithm);
}
}
+
+ public KeyManager[] getKeyManagers() throws GeneralSecurityException
+ {
+ String keyStorePath = (String)getAttribute(KeyStore.PATH);
+ String keyStorePassword = getPassword();
+ String keyStoreType = (String)getAttribute(KeyStore.TYPE);
+ String keyManagerFactoryAlgorithm = (String)getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
+ String certAlias = (String)getAttribute(KeyStore.CERTIFICATE_ALIAS);
+
+ try
+ {
+ if (certAlias != null)
+ {
+ return new KeyManager[] {
+ new QpidClientX509KeyManager( certAlias, keyStorePath, keyStoreType, keyStorePassword,
+ keyManagerFactoryAlgorithm)
+ };
+
+ }
+ else
+ {
+ final java.security.KeyStore ks = SSLUtil.getInitializedKeyStore(keyStorePath, keyStorePassword, keyStoreType);
+
+ char[] keyStoreCharPassword = keyStorePassword == null ? null : keyStorePassword.toCharArray();
+
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm);
+
+ kmf.init(ks, keyStoreCharPassword);
+
+ return kmf.getKeyManagers();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new GeneralSecurityException(e);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
index 06089e43c6..5e7bfff4de 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
@@ -20,8 +20,11 @@
*/
package org.apache.qpid.server.model.adapter;
+import java.io.IOException;
import java.lang.reflect.Type;
import java.security.AccessControlException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
@@ -30,8 +33,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.IntegrityViolationException;
@@ -40,6 +45,8 @@ import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.TrustStore;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
+import org.apache.qpid.transport.network.security.ssl.QpidPeersOnlyTrustManager;
import org.apache.qpid.transport.network.security.ssl.SSLUtil;
public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustStore
@@ -189,4 +196,60 @@ public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustS
throw new IllegalConfigurationException("Unknown trustManagerFactoryAlgorithm: " + trustManagerFactoryAlgorithm);
}
}
+
+ public TrustManager[] getTrustManagers() throws GeneralSecurityException
+ {
+ String trustStorePath = (String)getAttribute(TrustStore.PATH);
+ String trustStorePassword = getPassword();
+ String trustStoreType = (String)getAttribute(TrustStore.TYPE);
+ String trustManagerFactoryAlgorithm = (String)getAttribute(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM);
+
+ try
+ {
+ KeyStore ts = SSLUtil.getInitializedKeyStore(trustStorePath, trustStorePassword, trustStoreType);
+ final TrustManagerFactory tmf = TrustManagerFactory
+ .getInstance(trustManagerFactoryAlgorithm);
+ tmf.init(ts);
+ final Collection<TrustManager> trustManagersCol = new ArrayList<TrustManager>();
+ final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+ TrustManager[] delegateManagers = tmf.getTrustManagers();
+ for (TrustManager tm : delegateManagers)
+ {
+ if (tm instanceof X509TrustManager)
+ {
+ if (Boolean.TRUE.equals(getAttribute(PEERS_ONLY)))
+ {
+ // truststore is supposed to trust only clients which peers certificates
+ // are directly in the store. CA signing will not be considered.
+ mulTrustManager.addTrustManager(new QpidPeersOnlyTrustManager(ts, (X509TrustManager) tm));
+ }
+ else
+ {
+ mulTrustManager.addTrustManager((X509TrustManager) tm);
+ }
+ }
+ else
+ {
+ trustManagersCol.add(tm);
+ }
+ }
+ if (! mulTrustManager.isEmpty())
+ {
+ trustManagersCol.add(mulTrustManager);
+ }
+
+ if (trustManagersCol.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ return trustManagersCol.toArray(new TrustManager[trustManagersCol.size()]);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new GeneralSecurityException(e);
+ }
+ }
}