summaryrefslogtreecommitdiff
path: root/java/common/src
diff options
context:
space:
mode:
authorRajith Muditha Attapattu <rajith@apache.org>2010-03-22 22:38:31 +0000
committerRajith Muditha Attapattu <rajith@apache.org>2010-03-22 22:38:31 +0000
commit445d8f537fefde2bd122469474ae9113928d1275 (patch)
tree0a900d73a21a65a9e7ff4639fbbe61a3efbe2061 /java/common/src
parent3d31ccffd3d37ce488d82c7f649d5a15b98e431c (diff)
downloadqpid-python-445d8f537fefde2bd122469474ae9113928d1275.tar.gz
This is related to QPID-2447
Added QpidClientX509KeyManager (a customer KeyManager) which will return the ssl_client_alias specified in the Connection URL. Note the alias here is actually the certificate name and not the alias used in the keytool. I also fixed a minor bug in SSLUtil to retrive the identitiy of the local certificate instead of the peer's certificate. Added a test for the above JIRA. Added AMQTestConnection_0_10 which allows the SecurityLayer to be exposed for testing purposes. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@926380 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/common/src')
-rw-r--r--java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java102
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java80
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java78
3 files changed, 201 insertions, 59 deletions
diff --git a/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java b/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java
index e142d21e06..702746b3da 100644
--- a/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java
+++ b/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java
@@ -27,10 +27,13 @@ import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
+import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
+
/**
* Factory used to create SSLContexts. SSL needs to be configured
* before this will work.
@@ -68,7 +71,7 @@ public class SSLContextFactory {
*/
private String _trustStoreCertType;
-
+ private KeyManager customKeyManager;
public SSLContextFactory(String trustStorePath, String trustStorePassword,
String trustStoreCertType)
@@ -90,7 +93,7 @@ public class SSLContextFactory {
_trustStorePath = trustStorePath;
_trustStorePassword = trustStorePassword;
- if (_trustStorePassword.equals("none"))
+ if (_trustStorePassword != null && _trustStorePassword.equals("none"))
{
_trustStorePassword = null;
}
@@ -99,7 +102,7 @@ public class SSLContextFactory {
_keyStorePath = keyStorePath;
_keyStorePassword = keyStorePassword;
- if (_keyStorePassword.equals("none"))
+ if (_keyStorePassword != null && _keyStorePassword.equals("none"))
{
_keyStorePassword = null;
}
@@ -113,29 +116,63 @@ public class SSLContextFactory {
}
}
+ public SSLContextFactory(String trustStorePath, String trustStorePassword, String trustStoreCertType,
+ KeyManager customKeyManager)
+ {
+
+ _trustStorePath = trustStorePath;
+ _trustStorePassword = trustStorePassword;
+
+ if (_trustStorePassword != null && _trustStorePassword.equals("none"))
+ {
+ _trustStorePassword = null;
+ }
+ _trustStoreCertType = trustStoreCertType;
+
+ if (_trustStorePath == null) {
+ throw new IllegalArgumentException("A TrustStore path or KeyStore path must be specified");
+ }
+ if (_trustStoreCertType == null) {
+ throw new IllegalArgumentException("Cert type must be specified");
+ }
+
+ this.customKeyManager = customKeyManager;
+ }
+
+
/**
* Builds a SSLContext appropriate for use with a server
* @return SSLContext
* @throws GeneralSecurityException
* @throws IOException
*/
+
public SSLContext buildServerContext() throws GeneralSecurityException, IOException
{
- // Create keystore
- KeyStore ks = getInitializedKeyStore(_keyStorePath,_keyStorePassword);
-
- // Set up key manager factory to use our key store
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(_keyStoreCertType);
- kmf.init(ks, _keyStorePassword.toCharArray());
-
- KeyStore ts = getInitializedKeyStore(_trustStorePath,_trustStorePassword);
+ KeyStore ts = SSLUtil.getInitializedKeyStore(_trustStorePath,_trustStorePassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(_trustStoreCertType);
tmf.init(ts);
// Initialize the SSLContext to work with our key managers.
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ if (customKeyManager != null)
+ {
+ sslContext.init(new KeyManager[]{customKeyManager},
+ tmf.getTrustManagers(), null);
+
+ }
+ else
+ {
+ // Create keystore
+ KeyStore ks = SSLUtil.getInitializedKeyStore(_keyStorePath,_keyStorePassword);
+ // Set up key manager factory to use our key store
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(_keyStoreCertType);
+ kmf.init(ks, _keyStorePassword.toCharArray());
+ sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ }
+
return sslContext;
}
@@ -147,7 +184,7 @@ public class SSLContextFactory {
*/
public SSLContext buildClientContext() throws GeneralSecurityException, IOException
{
- KeyStore ks = getInitializedKeyStore(_trustStorePath,_trustStorePassword);
+ KeyStore ks = SSLUtil.getInitializedKeyStore(_trustStorePath,_trustStorePassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(_trustStoreCertType);
tmf.init(ks);
SSLContext context = SSLContext.getInstance("TLS");
@@ -155,41 +192,4 @@ public class SSLContextFactory {
return context;
}
- private KeyStore getInitializedKeyStore(String storePath, String storePassword) throws GeneralSecurityException, IOException
- {
- KeyStore ks = KeyStore.getInstance("JKS");
- InputStream in = null;
- try
- {
- File f = new File(storePath);
- if (f.exists())
- {
- in = new FileInputStream(f);
- }
- else
- {
- in = Thread.currentThread().getContextClassLoader().getResourceAsStream(storePath);
- }
- if (in == null)
- {
- throw new IOException("Unable to load keystore resource: " + storePath);
- }
- ks.load(in, storePassword.toCharArray());
- }
- finally
- {
- if (in != null)
- {
- //noinspection EmptyCatchBlock
- try
- {
- in.close();
- }
- catch (IOException ignored)
- {
- }
- }
- }
- return ks;
- }
}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java b/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
new file mode 100644
index 0000000000..2a3aba9a95
--- /dev/null
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
@@ -0,0 +1,80 @@
+package org.apache.qpid.transport.network.security.ssl;
+
+import java.net.Socket;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+
+import org.apache.qpid.transport.util.Logger;
+
+public class QpidClientX509KeyManager extends X509ExtendedKeyManager
+{
+ private static final Logger log = Logger.get(QpidClientX509KeyManager.class);
+
+ X509ExtendedKeyManager delegate;
+ String alias;
+
+ public QpidClientX509KeyManager(String alias, String keyStorePath,
+ String keyStorePassword,String keyStoreCertType) throws Exception
+ {
+ this.alias = alias;
+ KeyStore ks = SSLUtil.getInitializedKeyStore(keyStorePath,keyStorePassword);
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyStoreCertType);
+ kmf.init(ks, keyStorePassword.toCharArray());
+ this.delegate = (X509ExtendedKeyManager)kmf.getKeyManagers()[0];
+ }
+
+ @Override
+ public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
+ {
+ log.debug("chooseClientAlias:Returning alias " + alias);
+ return alias;
+ }
+
+ @Override
+ public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
+ {
+ return delegate.chooseServerAlias(keyType, issuers, socket);
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias)
+ {
+ return delegate.getCertificateChain(alias);
+ }
+
+ @Override
+ public String[] getClientAliases(String keyType, Principal[] issuers)
+ {
+ log.debug("getClientAliases:Returning alias " + alias);
+ return new String[]{alias};
+ }
+
+ @Override
+ public PrivateKey getPrivateKey(String alias)
+ {
+ return delegate.getPrivateKey(alias);
+ }
+
+ @Override
+ public String[] getServerAliases(String keyType, Principal[] issuers)
+ {
+ return delegate.getServerAliases(keyType, issuers);
+ }
+
+ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine)
+ {
+ log.debug("chooseEngineClientAlias:Returning alias " + alias);
+ return alias;
+ }
+
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
+ {
+ return delegate.chooseEngineServerAlias(keyType, issuers, engine);
+ }
+}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java b/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java
index 130ce04adc..6c5c56a175 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java
@@ -1,5 +1,11 @@
package org.apache.qpid.transport.network.security.ssl;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
@@ -63,7 +69,7 @@ public class SSLUtil
StringBuffer id = new StringBuffer();
try
{
- Certificate cert = engine.getSession().getPeerCertificates()[0];
+ Certificate cert = engine.getSession().getLocalCertificates()[0];
Principal p = ((X509Certificate)cert).getSubjectDN();
String dn = p.getName();
@@ -101,15 +107,71 @@ public class SSLUtil
public static SSLContext createSSLContext(ConnectionSettings settings) throws Exception
{
+ SSLContextFactory sslContextFactory;
- SSLContextFactory sslContextFactory = new SSLContextFactory(settings.getTrustStorePath(),
- settings.getTrustStorePassword(),
- settings.getTrustStoreCertType(),
- settings.getKeyStorePath(),
- settings.getKeyStorePassword(),
- settings.getKeyStoreCertType());
-
+ if (settings.getCertAlias() == null)
+ {
+ sslContextFactory =
+ new SSLContextFactory(settings.getTrustStorePath(),
+ settings.getTrustStorePassword(),
+ settings.getTrustStoreCertType(),
+ settings.getKeyStorePath(),
+ settings.getKeyStorePassword(),
+ settings.getKeyStoreCertType());
+
+ } else
+ {
+ sslContextFactory =
+ new SSLContextFactory(settings.getTrustStorePath(),
+ settings.getTrustStorePassword(),
+ settings.getTrustStoreCertType(),
+ new QpidClientX509KeyManager(settings.getCertAlias(),
+ settings.getKeyStorePath(),
+ settings.getKeyStorePassword(),
+ settings.getKeyStoreCertType()));
+
+ log.debug("Using custom key manager");
+ }
+
return sslContextFactory.buildServerContext();
}
+
+ public static KeyStore getInitializedKeyStore(String storePath, String storePassword) throws GeneralSecurityException, IOException
+ {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ InputStream in = null;
+ try
+ {
+ File f = new File(storePath);
+ if (f.exists())
+ {
+ in = new FileInputStream(f);
+ }
+ else
+ {
+ in = Thread.currentThread().getContextClassLoader().getResourceAsStream(storePath);
+ }
+ if (in == null)
+ {
+ throw new IOException("Unable to load keystore resource: " + storePath);
+ }
+ ks.load(in, storePassword.toCharArray());
+ }
+ finally
+ {
+ if (in != null)
+ {
+ //noinspection EmptyCatchBlock
+ try
+ {
+ in.close();
+ }
+ catch (IOException ignored)
+ {
+ }
+ }
+ }
+ return ks;
+ }
}