You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ra...@apache.org on 2010/03/22 23:38:31 UTC
svn commit: r926380 - in /qpid/trunk/qpid/java:
client/src/main/java/org/apache/qpid/client/
common/src/main/java/org/apache/qpid/ssl/
common/src/main/java/org/apache/qpid/transport/network/security/ssl/
systests/src/main/java/org/apache/qpid/client/ssl/
Author: rajith
Date: Mon Mar 22 22:38:31 2010
New Revision: 926380
URL: http://svn.apache.org/viewvc?rev=926380&view=rev
Log:
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.
Added:
qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTestConnection_0_10.java
qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
Modified:
qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java
qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java
Modified: qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java?rev=926380&r1=926379&r2=926380&view=diff
==============================================================================
--- qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java (original)
+++ qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java Mon Mar 22 22:38:31 2010
@@ -398,4 +398,9 @@ public class AMQConnectionDelegate_0_10
}
return 0;
}
+
+ protected org.apache.qpid.transport.Connection getQpidConnection()
+ {
+ return _qpidConnection;
+ }
}
Added: qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTestConnection_0_10.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTestConnection_0_10.java?rev=926380&view=auto
==============================================================================
--- qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTestConnection_0_10.java (added)
+++ qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTestConnection_0_10.java Mon Mar 22 22:38:31 2010
@@ -0,0 +1,16 @@
+package org.apache.qpid.client;
+
+import org.apache.qpid.transport.Connection;
+
+public class AMQTestConnection_0_10 extends AMQConnection
+{
+ public AMQTestConnection_0_10(String url) throws Exception
+ {
+ super(url);
+ }
+
+ public Connection getConnection()
+ {
+ return((AMQConnectionDelegate_0_10)_delegate).getQpidConnection();
+ }
+}
Modified: qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java?rev=926380&r1=926379&r2=926380&view=diff
==============================================================================
--- qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java (original)
+++ qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/ssl/SSLContextFactory.java Mon Mar 22 22:38:31 2010
@@ -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;
- }
}
Added: qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java?rev=926380&view=auto
==============================================================================
--- qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java (added)
+++ qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java Mon Mar 22 22:38:31 2010
@@ -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);
+ }
+}
Modified: qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java?rev=926380&r1=926379&r2=926380&view=diff
==============================================================================
--- qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java (original)
+++ qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/SSLUtil.java Mon Mar 22 22:38:31 2010
@@ -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;
+ }
}
Modified: qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java?rev=926380&r1=926379&r2=926380&view=diff
==============================================================================
--- qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java (original)
+++ qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java Mon Mar 22 22:38:31 2010
@@ -6,10 +6,27 @@ import java.io.PrintStream;
import javax.jms.Session;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQTestConnection_0_10;
import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.transport.Connection;
public class SSLTest extends QpidTestCase
{
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ System.setProperty("javax.net.debug", "ssl");
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ System.setProperty("javax.net.debug", "");
+ super.tearDown();
+ }
+
public void testCreateSSLContextFromConnectionURLParams()
{
if (Boolean.getBoolean("profile.use_ssl"))
@@ -52,6 +69,32 @@ public class SSLTest extends QpidTestCas
}
}
}
+
+ public void testMultipleCertsInSingleStore() throws Exception
+ {
+ if (Boolean.getBoolean("profile.use_ssl"))
+ {
+ String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" +
+ System.getProperty("test.port.ssl") +
+ "?ssl='true'&ssl_cert_alias='app1''";
+
+ AMQTestConnection_0_10 con = new AMQTestConnection_0_10(url);
+ Connection transportCon = con.getConnection();
+ String userID = transportCon.getSecurityLayer().getUserID();
+ assertEquals("The correct certificate was not choosen","app1@acme.org",userID);
+ con.close();
+
+ url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" +
+ System.getProperty("test.port.ssl") +
+ "?ssl='true'&ssl_cert_alias='app2''";
+
+ con = new AMQTestConnection_0_10(url);
+ transportCon = con.getConnection();
+ userID = transportCon.getSecurityLayer().getUserID();
+ assertEquals("The correct certificate was not choosen","app2@acme.org",userID);
+ con.close();
+ }
+ }
public void testVerifyHostName()
{
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org