qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgodf...@apache.org
Subject svn commit: r1678654 - in /qpid/java/trunk: broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ broker-core/src/main/java/org/apache/qpid/server/model/ broker-core/src/main/java/org/apache/qpid/server/model/port/ broker-core/src/main/...
Date Sun, 10 May 2015 23:37:06 GMT
Author: rgodfrey
Date: Sun May 10 23:37:05 2015
New Revision: 1678654

URL: http://svn.apache.org/r1678654
Log:
QPID-6538 : [Java Broker] Allow TrustStores to be used to distribute public keys to clients

Added:
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java   (with props)
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustsStoreImpl.java
      - copied, changed from r1664896, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java   (with props)
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java   (with props)
Modified:
    qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/AttributeAnnotationValidator.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AttributeValueConverter.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectJacksonModule.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractClientAuthCapablePortWithAuthProvider.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/ClientAuthCapablePort.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemNodeCreator.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/transport/NonBlockingConnection.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractSystemMessageSource.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostPropertiesNode.java
    qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
    qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
    qpid/java/trunk/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java
    qpid/java/trunk/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java
    qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
    qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
    qpid/java/trunk/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
    qpid/java/trunk/systests/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
    qpid/java/trunk/systests/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java

Modified: qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/AttributeAnnotationValidator.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/AttributeAnnotationValidator.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/AttributeAnnotationValidator.java (original)
+++ qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/AttributeAnnotationValidator.java Sun May 10 23:37:05 2015
@@ -314,6 +314,12 @@ public class AttributeAnnotationValidato
             return true;
         }
 
+
+        if(typeUtils.isSameType(type,elementUtils.getTypeElement("java.security.cert.Certificate").asType()))
+        {
+            return true;
+        }
+
         TypeMirror erasedType = typeUtils.erasure(type);
         if(typeUtils.isSameType(erasedType, getErasure(processingEnv, "java.util.List"))
                 || typeUtils.isSameType(erasedType, getErasure(processingEnv, "java.util.Set"))

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Sun May 10 23:37:05 2015
@@ -1160,6 +1160,10 @@ public abstract class AbstractConfigured
                 try
                 {
                     returnVal = (ListenableFuture<Void>) stateChangingMethod.invoke(this);
+                    if(getState() != currentState)
+                    {
+                        notifyStateChanged(currentState, getState());
+                    }
                 }
                 catch (IllegalAccessException e)
                 {
@@ -1345,13 +1349,14 @@ public abstract class AbstractConfigured
 
     protected void notifyStateChanged(final State currentState, final State desiredState)
     {
+        List<ConfigurationChangeListener> copy;
         synchronized (_changeListeners)
         {
-            List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
-            for(ConfigurationChangeListener listener : copy)
-            {
-                listener.stateChanged(this, currentState, desiredState);
-            }
+            copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
+        }
+        for(ConfigurationChangeListener listener : copy)
+        {
+            listener.stateChanged(this, currentState, desiredState);
         }
     }
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AttributeValueConverter.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AttributeValueConverter.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AttributeValueConverter.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AttributeValueConverter.java Sun May 10 23:37:05 2015
@@ -20,6 +20,7 @@
  */
 package org.apache.qpid.server.model;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -27,6 +28,9 @@ import java.lang.reflect.ParameterizedTy
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -39,6 +43,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
+import javax.xml.bind.DatatypeConverter;
+
 import org.codehaus.jackson.map.ObjectMapper;
 
 import org.apache.qpid.server.util.ServerScopedRuntimeException;
@@ -96,6 +102,82 @@ abstract class AttributeValueConverter<T
             }
         }
     };
+
+    static final AttributeValueConverter<byte[]> BINARY_CONVERTER = new AttributeValueConverter<byte[]>()
+    {
+        @Override
+        byte[] convert(final Object value, final ConfiguredObject object)
+        {
+            if(value instanceof byte[])
+            {
+                return (byte[]) value;
+            }
+            else if(value == null)
+            {
+                return null;
+            }
+            else if(value instanceof String)
+            {
+                return DatatypeConverter.parseBase64Binary(AbstractConfiguredObject.interpolate(object, (String) value));
+            }
+            else
+            {
+                throw new IllegalArgumentException("Cannot convert type " + value.getClass() + " to a byte[]");
+            }
+        }
+    };
+
+
+
+
+    static final AttributeValueConverter<Certificate> CERTIFICATE_CONVERTER = new AttributeValueConverter<Certificate>()
+    {
+        private final CertificateFactory _certFactory;
+
+        {
+            try
+            {
+                _certFactory=CertificateFactory.getInstance("X.509");
+            }
+            catch (CertificateException e)
+            {
+                throw new ServerScopedRuntimeException(e);
+            }
+        }
+        @Override
+        public Certificate convert(final Object value, final ConfiguredObject object)
+        {
+            if(value instanceof Certificate)
+            {
+                return (Certificate) value;
+            }
+            else if(value instanceof byte[])
+            {
+                try(ByteArrayInputStream is = new ByteArrayInputStream((byte[])value))
+                {
+                    return _certFactory.generateCertificate(is);
+                }
+                catch (IOException | CertificateException e)
+                {
+                    throw new IllegalArgumentException(e);
+                }
+            }
+            else if(value instanceof String)
+            {
+                return convert(BINARY_CONVERTER.convert(AbstractConfiguredObject.interpolate(object, (String) value),object),object);
+            }
+            else if(value == null)
+            {
+                return null;
+            }
+            else
+            {
+                throw new IllegalArgumentException("Cannot convert type " + value.getClass() + " to a Certificate");
+            }
+        }
+    };
+
+
     static final AttributeValueConverter<Long> LONG_CONVERTER = new AttributeValueConverter<Long>()
     {
 
@@ -391,6 +473,14 @@ abstract class AttributeValueConverter<T
         {
             return (AttributeValueConverter<X>) UUID_CONVERTER;
         }
+        else if(type == byte[].class)
+        {
+            return (AttributeValueConverter<X>) BINARY_CONVERTER;
+        }
+        else if(Certificate.class.isAssignableFrom(type))
+        {
+            return (AttributeValueConverter<X>) CERTIFICATE_CONVERTER;
+        }
         else if(Enum.class.isAssignableFrom(type))
         {
             return (AttributeValueConverter<X>) new EnumConverter((Class<? extends Enum>)type);

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectJacksonModule.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectJacksonModule.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectJacksonModule.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectJacksonModule.java Sun May 10 23:37:05 2015
@@ -23,6 +23,8 @@ package org.apache.qpid.server.model;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -56,6 +58,30 @@ public class ConfiguredObjectJacksonModu
         super("ConfiguredObjectSerializer", new Version(1,0,0,null));
         addConfiguredObjectSerializer();
         addManageableAttributeTypeSerializer();
+        addCertificateSerializer();
+    }
+
+    private void addCertificateSerializer()
+    {
+        final JsonSerializer<Certificate> serializer = new JsonSerializer<Certificate>()
+        {
+            @Override
+            public void serialize(final Certificate value,
+                                  final JsonGenerator jgen,
+                                  final SerializerProvider provider)
+                    throws IOException
+            {
+                try
+                {
+                    jgen.writeBinary(value.getEncoded());
+                }
+                catch (CertificateEncodingException e)
+                {
+                    throw new IllegalArgumentException(e);
+                }
+            }
+        };
+        addSerializer(Certificate.class, serializer);
     }
 
     private void addManageableAttributeTypeSerializer()

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java Sun May 10 23:37:05 2015
@@ -21,11 +21,26 @@
 package org.apache.qpid.server.model;
 
 import java.security.GeneralSecurityException;
+import java.security.cert.Certificate;
+import java.util.List;
+
 import javax.net.ssl.TrustManager;
 
 @ManagedObject( defaultType = "FileTrustStore" )
 public interface TrustStore<X extends TrustStore<X>> extends ConfiguredObject<X>
 {
+    @ManagedAttribute( defaultValue = "false" )
+    boolean isExposedAsMessageSource();
+
+    @ManagedAttribute( defaultValue = "[]" )
+    List<VirtualHost> getIncludedVirtualHostMessageSources();
+
+    @ManagedAttribute( defaultValue = "[]" )
+    List<VirtualHost> getExcludedVirtualHostMessageSources();
+
+
     public TrustManager[] getTrustManagers() throws GeneralSecurityException;
 
+    public Certificate[] getCertificates() throws GeneralSecurityException;
+
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractClientAuthCapablePortWithAuthProvider.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractClientAuthCapablePortWithAuthProvider.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractClientAuthCapablePortWithAuthProvider.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractClientAuthCapablePortWithAuthProvider.java Sun May 10 23:37:05 2015
@@ -25,6 +25,8 @@ import org.apache.qpid.server.configurat
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.security.ManagedPeerCertificateTrustStore;
 
 abstract public class AbstractClientAuthCapablePortWithAuthProvider<X extends AbstractClientAuthCapablePortWithAuthProvider<X>> extends AbstractPortWithAuthProvider<X>
         implements ClientAuthCapablePort<X>
@@ -38,6 +40,9 @@ abstract public class AbstractClientAuth
     @ManagedAttributeField
     private boolean _wantClientAuth;
 
+    @ManagedAttributeField
+    private TrustStore<?> _clientCertRecorder;
+
     public AbstractClientAuthCapablePortWithAuthProvider(final Map<String, Object> attributes,
                                                          final Broker<?> broker)
     {
@@ -51,6 +56,12 @@ abstract public class AbstractClientAuth
     }
 
     @Override
+    public TrustStore<?> getClientCertRecorder()
+    {
+        return _clientCertRecorder;
+    }
+
+    @Override
     public boolean getWantClientAuth()
     {
         return _wantClientAuth;
@@ -73,6 +84,14 @@ abstract public class AbstractClientAuth
             throw new IllegalConfigurationException(
                     "Can't create port which requests SSL client certificates but doesn't use SSL transport.");
         }
+
+        if(useClientAuth && getClientCertRecorder() != null)
+        {
+            if(!(getClientCertRecorder() instanceof ManagedPeerCertificateTrustStore))
+            {
+                throw new IllegalConfigurationException("Only trust stores of type " + ManagedPeerCertificateTrustStore.TYPE_NAME + " may be used as the client certificate recorder");
+            }
+        }
     }
 
     @Override
@@ -98,5 +117,14 @@ abstract public class AbstractClientAuth
                 throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but doesn't use SSL transport.");
             }
         }
+
+
+        if(requiresCertificate && updated.getClientCertRecorder() != null)
+        {
+            if(!(updated.getClientCertRecorder() instanceof ManagedPeerCertificateTrustStore))
+            {
+                throw new IllegalConfigurationException("Only trust stores of type " + ManagedPeerCertificateTrustStore.TYPE_NAME + " may be used as the client certificate recorder");
+            }
+        }
     }
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPort.java Sun May 10 23:37:05 2015
@@ -31,6 +31,7 @@ import org.apache.qpid.server.model.Mana
 import org.apache.qpid.server.model.ManagedStatistic;
 import org.apache.qpid.server.model.Protocol;
 import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.model.VirtualHostAlias;
 import org.apache.qpid.server.virtualhost.VirtualHostImpl;
 
@@ -90,6 +91,9 @@ public interface AmqpPort<X extends Amqp
     @ManagedAttribute( defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
     boolean getWantClientAuth();
 
+    @ManagedAttribute
+    TrustStore<?> getClientCertRecorder();
+
     @ManagedAttribute( mandatory = true )
     AuthenticationProvider getAuthenticationProvider();
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/ClientAuthCapablePort.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/ClientAuthCapablePort.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/ClientAuthCapablePort.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/ClientAuthCapablePort.java Sun May 10 23:37:05 2015
@@ -20,6 +20,7 @@
 package org.apache.qpid.server.model.port;
 
 import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.TrustStore;
 
 
 public interface ClientAuthCapablePort<X extends Port<X>> extends Port<X>
@@ -27,4 +28,6 @@ public interface ClientAuthCapablePort<X
     boolean getNeedClientAuth();
 
     boolean getWantClientAuth();
+
+    TrustStore<?> getClientCertRecorder();
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPort.java Sun May 10 23:37:05 2015
@@ -25,9 +25,9 @@ import java.util.Set;
 import org.apache.qpid.server.model.AuthenticationProvider;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedObject;
-import org.apache.qpid.server.model.Port;
 import org.apache.qpid.server.model.Protocol;
 import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
 
 @ManagedObject( category = false, type = "HTTP")
 public interface HttpPort<X extends HttpPort<X>> extends ClientAuthCapablePort<X>
@@ -44,6 +44,9 @@ public interface HttpPort<X extends Http
     @ManagedAttribute( defaultValue = DEFAULT_AMQP_WANT_CLIENT_AUTH )
     boolean getWantClientAuth();
 
+    @ManagedAttribute
+    TrustStore<?> getClientCertRecorder();
+
     @ManagedAttribute( mandatory = true )
     AuthenticationProvider getAuthenticationProvider();
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemNodeCreator.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemNodeCreator.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemNodeCreator.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemNodeCreator.java Sun May 10 23:37:05 2015
@@ -29,8 +29,12 @@ public interface SystemNodeCreator exten
     {
         void registerSystemNode(MessageNode node);
         void removeSystemNode(MessageNode node);
+        void removeSystemNode(String name);
+
 
         VirtualHostImpl getVirtualHost();
+
+        boolean hasSystemNode(String name);
     }
 
     void register(SystemNodeRegistry registry);

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java Sun May 10 23:37:05 2015
@@ -28,8 +28,11 @@ import java.security.GeneralSecurityExce
 import java.security.KeyStore;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -52,6 +55,7 @@ import org.apache.qpid.server.model.Port
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.StateTransition;
 import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager;
 import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
 import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
@@ -73,6 +77,13 @@ public class FileTrustStoreImpl extends
     @ManagedAttributeField
     private String _password;
 
+    @ManagedAttributeField
+    private boolean _exposedAsMessageSource;
+    @ManagedAttributeField
+    private List<VirtualHost> _includedVirtualHostMessageSources;
+    @ManagedAttributeField
+    private List<VirtualHost> _excludedVirtualHostMessageSources;
+
     private final Broker<?> _broker;
 
     static
@@ -301,6 +312,35 @@ public class FileTrustStoreImpl extends
         }
     }
 
+    public Certificate[] getCertificates() throws GeneralSecurityException
+    {
+        String trustStorePassword = getPassword();
+        String trustStoreType = _trustStoreType;
+
+        try
+        {
+            URL trustStoreUrl = getUrlFromString(_storeUrl);
+
+            KeyStore ts = SSLUtil.getInitializedKeyStore(trustStoreUrl, trustStorePassword, trustStoreType);
+
+            final Collection<Certificate> certificates = new ArrayList<>();
+
+            Enumeration<String> aliases = ts.aliases();
+            while (aliases.hasMoreElements())
+            {
+                certificates.add(ts.getCertificate(aliases.nextElement()));
+            }
+
+            return certificates.toArray(new Certificate[certificates.size()]);
+
+        }
+        catch (IOException e)
+        {
+            throw new GeneralSecurityException(e);
+        }
+    }
+
+
     private static URL getUrlFromString(String urlString) throws MalformedURLException
     {
         URL url;
@@ -329,4 +369,22 @@ public class FileTrustStoreImpl extends
             _path = null;
         }
     }
+
+    @Override
+    public boolean isExposedAsMessageSource()
+    {
+        return _exposedAsMessageSource;
+    }
+
+    @Override
+    public List<VirtualHost> getIncludedVirtualHostMessageSources()
+    {
+        return _includedVirtualHostMessageSources;
+    }
+
+    @Override
+    public List<VirtualHost> getExcludedVirtualHostMessageSources()
+    {
+        return _excludedVirtualHostMessageSources;
+    }
 }

Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java?rev=1678654&view=auto
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java (added)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java Sun May 10 23:37:05 2015
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.qpid.server.security;
+
+import java.security.cert.Certificate;
+import java.util.List;
+
+import org.apache.qpid.server.model.ManagedAttribute;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.TrustStore;
+
+@ManagedObject( category = false, type = ManagedPeerCertificateTrustStore.TYPE_NAME)
+public interface ManagedPeerCertificateTrustStore<X extends ManagedPeerCertificateTrustStore<X>> extends TrustStore<X>
+{
+
+    String TYPE_NAME = "ManagedCertificateStore";
+
+
+    @ManagedAttribute( defaultValue = "true" )
+    boolean isExposedAsMessageSource();
+
+    @ManagedAttribute( oversize = true, defaultValue = "[]" )
+    List<Certificate> getStoredCertificates();
+
+    void addCertificate(Certificate cert);
+
+
+}

Propchange: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStore.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustsStoreImpl.java (from r1664896, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java)
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustsStoreImpl.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustsStoreImpl.java&p1=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java&r1=1664896&r2=1678654&rev=1678654&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustsStoreImpl.java Sun May 10 23:37:05 2015
@@ -20,32 +20,26 @@
  */
 package org.apache.qpid.server.security;
 
-import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.AccessControlException;
 import java.security.GeneralSecurityException;
 import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Callable;
 
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
-import javax.security.auth.x500.X500Principal;
+import javax.net.ssl.X509TrustManager;
 
-import org.apache.log4j.Logger;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.AbstractConfiguredObject;
@@ -53,7 +47,6 @@ import org.apache.qpid.server.model.Auth
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.IntegrityViolationException;
-import org.apache.qpid.server.model.KeyStore;
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
@@ -61,123 +54,57 @@ import org.apache.qpid.server.model.Port
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.StateTransition;
 import org.apache.qpid.server.model.TrustStore;
-import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager;
-import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
+import org.apache.qpid.transport.network.security.ssl.QpidPeersOnlyTrustManager;
 
 @ManagedObject( category = false )
-public class NonJavaTrustStoreImpl
-        extends AbstractConfiguredObject<NonJavaTrustStoreImpl> implements NonJavaTrustStore<NonJavaTrustStoreImpl>
+public class ManagedPeerCertificateTrustsStoreImpl
+        extends AbstractConfiguredObject<ManagedPeerCertificateTrustsStoreImpl> implements ManagedPeerCertificateTrustStore<ManagedPeerCertificateTrustsStoreImpl>
 {
-    private static final Logger LOGGER = Logger.getLogger(NonJavaTrustStoreImpl.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(ManagedPeerCertificateTrustsStoreImpl.class);
 
     private final Broker<?> _broker;
 
-    @ManagedAttributeField( afterSet = "updateTrustManagers" )
-    private String _certificatesUrl;
+    @ManagedAttributeField
+    private boolean _exposedAsMessageSource;
+    @ManagedAttributeField
+    private List<VirtualHost> _includedVirtualHostMessageSources;
+    @ManagedAttributeField
+    private List<VirtualHost> _excludedVirtualHostMessageSources;
 
     private volatile TrustManager[] _trustManagers = new TrustManager[0];
 
-
-
-    static
-    {
-        Handler.register();
-    }
-
-    private X509Certificate[] _certificates;
+    @ManagedAttributeField( afterSet = "updateTrustManagers")
+    private final List<Certificate> _storedCertificates = new ArrayList<>();
 
     @ManagedObjectFactoryConstructor
-    public NonJavaTrustStoreImpl(final Map<String, Object> attributes, Broker<?> broker)
+    public ManagedPeerCertificateTrustsStoreImpl(final Map<String, Object> attributes, Broker<?> broker)
     {
         super(parentsMap(broker), attributes);
         _broker = broker;
     }
 
     @Override
-    public String getCertificatesUrl()
-    {
-        return _certificatesUrl;
-    }
-
-
-    @Override
-    public List<Map<CertificateDetails,Object>> getCertificateDetails()
-    {
-        List<Map<CertificateDetails,Object>> certificateDetails = new ArrayList<>();
-        if(_certificates != null)
-        {
-            for (X509Certificate certificate : _certificates)
-            {
-                Map<CertificateDetails, Object> details = new EnumMap<>(CertificateDetails.class);
-
-                details.put(CertificateDetails.SUBJECT_NAME, getNameFromCertificate(certificate));
-                details.put(CertificateDetails.ISSUER_NAME, certificate.getIssuerX500Principal().getName());
-                details.put(CertificateDetails.VALID_START, certificate.getNotBefore());
-                details.put(CertificateDetails.VALID_END, certificate.getNotAfter());
-                certificateDetails.add(details);
-            }
-        }
-        return certificateDetails;
-    }
-
-    private String getNameFromCertificate(final X509Certificate certificate)
+    public TrustManager[] getTrustManagers()
     {
-        String name;
-        X500Principal subjectX500Principal = certificate.getSubjectX500Principal();
-        name = getCommonNameFromPrincipal(subjectX500Principal);
-
-        return name;
-    }
-
-    private String getCommonNameFromPrincipal(final X500Principal subjectX500Principal)
-    {
-        String name;
-        String dn = subjectX500Principal.getName();
-        try
-        {
-            LdapName ldapDN = new LdapName(dn);
-            name = dn;
-            for (Rdn rdn : ldapDN.getRdns())
-            {
-                if (rdn.getType().equalsIgnoreCase("CN"))
-                {
-                    name = String.valueOf(rdn.getValue());
-                    break;
-                }
-            }
-
-        }
-        catch (InvalidNameException e)
-        {
-            LOGGER.error("Error getting subject name from certificate");
-            name =  null;
-        }
-        return name;
-    }
-
-
-    @Override
-    public TrustManager[] getTrustManagers() throws GeneralSecurityException
-    {
-
         return _trustManagers;
     }
 
     @Override
-    public void onValidate()
+    public Certificate[] getCertificates()
     {
-        super.onValidate();
-        validateTrustStoreAttributes(this);
+        return _storedCertificates.toArray(new Certificate[_storedCertificates.size()]);
     }
 
     @StateTransition(currentState = {State.ACTIVE, State.ERRORED}, desiredState = State.DELETED)
-    protected void doDelete()
+    protected ListenableFuture<Void> doDelete()
     {
         // verify that it is not in use
         String storeName = getName();
 
-        Collection<Port<?>> ports = new ArrayList<Port<?>>(_broker.getPorts());
+        Collection<Port<?>> ports = new ArrayList<>(_broker.getPorts());
         for (Port port : ports)
         {
             Collection<TrustStore> trustStores = port.getTrustStores();
@@ -215,85 +142,78 @@ public class NonJavaTrustStoreImpl
         }
         deleted();
         setState(State.DELETED);
+        return Futures.immediateFuture(null);
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected void doActivate()
+    protected ListenableFuture<Void> doActivate()
     {
         setState(State.ACTIVE);
+        return Futures.immediateFuture(null);
     }
 
-    @Override
-    protected void authoriseSetDesiredState(State desiredState) throws AccessControlException
-    {
-        if (desiredState == State.DELETED)
-        {
-            if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.DELETE))
-            {
-                throw new AccessControlException("Deletion of key store is denied");
-            }
-        }
-    }
-
-    @Override
-    protected void authoriseSetAttributes(ConfiguredObject<?> modified, Set<String> attributes)
-            throws AccessControlException
-    {
-        if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.UPDATE))
-        {
-            throw new AccessControlException("Setting key store attributes is denied");
-        }
-    }
 
     @Override
     protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
     {
         super.validateChange(proxyForValidation, changedAttributes);
-        NonJavaTrustStore changedStore = (NonJavaTrustStore) proxyForValidation;
+        ManagedPeerCertificateTrustStore<?> changedStore = (ManagedPeerCertificateTrustStore) proxyForValidation;
         if (changedAttributes.contains(NAME) && !getName().equals(changedStore.getName()))
         {
             throw new IllegalConfigurationException("Changing the key store name is not allowed");
         }
-        validateTrustStoreAttributes(changedStore);
     }
 
-    private void validateTrustStoreAttributes(NonJavaTrustStore<?> keyStore)
-    {
-        try
-        {
-            readCertificates(getUrlFromString(keyStore.getCertificatesUrl()));
-        }
-        catch (IOException | GeneralSecurityException e)
-        {
-            throw new IllegalArgumentException("Cannot validate certificate(s):" + e, e);
-        }
-    }
 
     @SuppressWarnings("unused")
     private void updateTrustManagers()
     {
         try
         {
-            if (_certificatesUrl != null)
+            java.security.KeyStore inMemoryKeyStore =
+                    java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
+
+            inMemoryKeyStore.load(null, null);
+            int i = 1;
+            for (Certificate cert : _storedCertificates)
             {
-                X509Certificate[] certs = readCertificates(getUrlFromString(_certificatesUrl));
-                java.security.KeyStore inMemoryKeyStore = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
+                inMemoryKeyStore.setCertificateEntry(String.valueOf(i++), cert);
+            }
 
-                inMemoryKeyStore.load(null, null);
-                int i = 1;
-                for(Certificate cert : certs)
-                {
-                    inMemoryKeyStore.setCertificateEntry(String.valueOf(i++), cert);
-                }
 
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(inMemoryKeyStore);
 
+            final Collection<TrustManager> trustManagersCol = new ArrayList<TrustManager>();
+            final QpidMultipleTrustManager mulTrustManager = new QpidMultipleTrustManager();
+            TrustManager[] delegateManagers = tmf.getTrustManagers();
+            for (TrustManager tm : delegateManagers)
+            {
+                if (tm instanceof X509TrustManager)
+                {
+                    // 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(inMemoryKeyStore, (X509TrustManager) tm));
 
-                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                tmf.init(inMemoryKeyStore);
-                _trustManagers = tmf.getTrustManagers();
-                _certificates = certs;
+                }
+                else
+                {
+                    trustManagersCol.add(tm);
+                }
+            }
+            if (! mulTrustManager.isEmpty())
+            {
+                trustManagersCol.add(mulTrustManager);
             }
 
+            if (trustManagersCol.isEmpty())
+            {
+                _trustManagers = null;
+            }
+            else
+            {
+                _trustManagers = trustManagersCol.toArray(new TrustManager[trustManagersCol.size()]);
+            }
         }
         catch (IOException | GeneralSecurityException e)
         {
@@ -301,43 +221,65 @@ public class NonJavaTrustStoreImpl
         }
     }
 
-    private URL getUrlFromString(String urlString) throws MalformedURLException
+
+    @Override
+    public boolean isExposedAsMessageSource()
     {
-        URL url;
+        return _exposedAsMessageSource;
+    }
 
-        try
-        {
-            url = new URL(urlString);
-        }
-        catch (MalformedURLException e)
-        {
-            File file = new File(urlString);
-            url = file.toURI().toURL();
+    @Override
+    public List<VirtualHost> getIncludedVirtualHostMessageSources()
+    {
+        return _includedVirtualHostMessageSources;
+    }
 
-        }
-        return url;
+    @Override
+    public List<VirtualHost> getExcludedVirtualHostMessageSources()
+    {
+        return _excludedVirtualHostMessageSources;
     }
 
-    public static X509Certificate[] readCertificates(URL certFile)
-            throws IOException, GeneralSecurityException
+    @Override
+    public List<Certificate> getStoredCertificates()
     {
-        List<X509Certificate> crt = new ArrayList<>();
-        try (InputStream is = certFile.openStream())
-        {
-            do
-            {
-                CertificateFactory cf = CertificateFactory.getInstance("X.509");
-                crt.add( (X509Certificate) cf.generateCertificate(is));
-            } while(is.available() != 0);
-        }
-        catch(CertificateException e)
-        {
-            if(crt.isEmpty())
-            {
-                throw e;
-            }
-        }
-        return crt.toArray(new X509Certificate[crt.size()]);
+        return _storedCertificates;
     }
 
+    @Override
+    public void addCertificate(final Certificate cert)
+    {
+        final Map<String, Object> updateMap = new HashMap<>();
+
+        doAfter(doOnConfigThread(new Callable<ListenableFuture<Void>>()
+                                    {
+                                        @Override
+                                        public ListenableFuture<Void> call() throws Exception
+                                        {
+                                            Set<Certificate> certs = new HashSet<>(_storedCertificates);
+                                            if(certs.add(cert))
+                                            {
+                                                updateMap.put("storedCertificates", new ArrayList<>(certs));
+                                            }
+                                            return Futures.immediateFuture(null);
+                                        }
+                                    }),
+                 new Callable<ListenableFuture<Void>>()
+                    {
+                        @Override
+                        public ListenableFuture<Void> call() throws Exception
+                        {
+                            if(updateMap.isEmpty())
+                            {
+                                return Futures.immediateFuture(null);
+                            }
+                            else
+                            {
+                                return setAttributesAsync(updateMap);
+                            }
+                        }
+
+                    });
+
+    }
 }

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java Sun May 10 23:37:05 2015
@@ -62,6 +62,7 @@ import org.apache.qpid.server.model.Port
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.StateTransition;
 import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager;
 import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
 
@@ -75,6 +76,12 @@ public class NonJavaTrustStoreImpl
 
     @ManagedAttributeField( afterSet = "updateTrustManagers" )
     private String _certificatesUrl;
+    @ManagedAttributeField
+    private boolean _exposedAsMessageSource;
+    @ManagedAttributeField
+    private List<VirtualHost> _includedVirtualHostMessageSources;
+    @ManagedAttributeField
+    private List<VirtualHost> _excludedVirtualHostMessageSources;
 
     private volatile TrustManager[] _trustManagers = new TrustManager[0];
 
@@ -165,6 +172,19 @@ public class NonJavaTrustStoreImpl
     }
 
     @Override
+    public Certificate[] getCertificates() throws GeneralSecurityException
+    {
+        try
+        {
+            return readCertificates(getUrlFromString(getCertificatesUrl()));
+        }
+        catch (IOException e)
+        {
+            throw new GeneralSecurityException(e);
+        }
+    }
+
+    @Override
     public void onValidate()
     {
         super.onValidate();
@@ -320,4 +340,21 @@ public class NonJavaTrustStoreImpl
         return crt.toArray(new X509Certificate[crt.size()]);
     }
 
+    @Override
+    public boolean isExposedAsMessageSource()
+    {
+        return _exposedAsMessageSource;
+    }
+
+    @Override
+    public List<VirtualHost> getIncludedVirtualHostMessageSources()
+    {
+        return _includedVirtualHostMessageSources;
+    }
+
+    @Override
+    public List<VirtualHost> getExcludedVirtualHostMessageSources()
+    {
+        return _excludedVirtualHostMessageSources;
+    }
 }

Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java?rev=1678654&view=auto
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java (added)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java Sun May 10 23:37:05 2015
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.qpid.server.security;
+
+import java.security.GeneralSecurityException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.server.consumer.ConsumerImpl;
+import org.apache.qpid.server.consumer.ConsumerTarget;
+import org.apache.qpid.server.filter.FilterManager;
+import org.apache.qpid.server.message.MessageSource;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.message.internal.InternalMessage;
+import org.apache.qpid.server.message.internal.InternalMessageHeader;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.virtualhost.AbstractSystemMessageSource;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+
+public class TrustStoreMessageSource extends AbstractSystemMessageSource implements MessageSource
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(TrustStoreMessageSource.class);
+
+    private final TrustStore<?> _trustStore;
+    private final AtomicReference<Set<Certificate>> _certCache = new AtomicReference<>();
+    private final VirtualHost<?, ?, ?> _virtualHost;
+
+
+    public TrustStoreMessageSource(final TrustStore<?> trustStore, final VirtualHostImpl virtualHost)
+    {
+        super(getSourceNameFromTrustStore(trustStore), virtualHost);
+        _virtualHost = virtualHost;
+        _trustStore = trustStore;
+        _trustStore.addChangeListener(new ConfigurationChangeListener()
+        {
+            @Override
+            public void stateChanged(final ConfiguredObject<?> object, final State oldState, final State newState)
+            {
+                if (newState == State.ACTIVE)
+                {
+                    updateCertCache();
+                }
+            }
+
+            @Override
+            public void childAdded(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+            {
+
+            }
+
+            @Override
+            public void childRemoved(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+            {
+
+            }
+
+            @Override
+            public void attributeSet(final ConfiguredObject<?> object,
+                                     final String attributeName,
+                                     final Object oldAttributeValue,
+                                     final Object newAttributeValue)
+            {
+                updateCertCache();
+            }
+        });
+        if(_trustStore.getState() == State.ACTIVE)
+        {
+            updateCertCache();
+        }
+    }
+
+    @Override
+    public Consumer addConsumer(final ConsumerTarget target,
+                                final FilterManager filters,
+                                final Class<? extends ServerMessage> messageClass,
+                                final String consumerName,
+                                final EnumSet<ConsumerImpl.Option> options)
+            throws ExistingExclusiveConsumer, ExistingConsumerPreventsExclusive,
+                   ConsumerAccessRefused
+    {
+        final Consumer consumer = super.addConsumer(target, filters, messageClass, consumerName, options);
+        consumer.send(createMessage());
+        target.queueEmpty();
+        return consumer;
+    }
+
+    private void updateCertCache()
+    {
+        _certCache.set(populateCertCache());
+        if(!getConsumers().isEmpty())
+        {
+            sendMessageToConsumers();
+        }
+    }
+
+    private void sendMessageToConsumers()
+    {
+        InternalMessage message = createMessage();
+
+        for(Consumer c : new ArrayList<>(getConsumers()))
+        {
+            c.send(message);
+        }
+
+    }
+
+    private InternalMessage createMessage()
+    {
+        List<Object> messageList = new ArrayList<>();
+        for (Certificate cert : _certCache.get())
+        {
+            try
+            {
+                messageList.add(cert.getEncoded());
+            }
+            catch (CertificateEncodingException e)
+            {
+                LOGGER.error("Could not encode certificate of type " + cert.getType(), e);
+            }
+        }
+        InternalMessageHeader header = new InternalMessageHeader(Collections.<String,Object>emptyMap(),
+                                                                 null, 0l, null, null, UUID.randomUUID().toString(),
+                                                                 null, null, (byte)4, System.currentTimeMillis(),
+                                                                 null, null);
+        return InternalMessage.createListMessage(_virtualHost.getMessageStore(), header, messageList);
+    }
+
+    private Set<Certificate> populateCertCache()
+    {
+        try
+        {
+            Set<Certificate> certCache = new HashSet<>();
+            for(Certificate cert : _trustStore.getCertificates())
+            {
+                certCache.add(cert);
+            }
+            return certCache;
+        }
+        catch (GeneralSecurityException e)
+        {
+            LOGGER.error("Cannot read trust managers from truststore " + _trustStore.getName(), e);
+            return Collections.emptySet();
+        }
+    }
+
+
+    public static String getSourceNameFromTrustStore(final TrustStore<?> trustStore)
+    {
+        return "$certificates/" + trustStore.getName();
+    }
+
+}

Propchange: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java?rev=1678654&view=auto
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java (added)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java Sun May 10 23:37:05 2015
@@ -0,0 +1,173 @@
+/*
+ *
+ * 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.qpid.server.security;
+
+import java.util.Collection;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.plugin.PluggableService;
+import org.apache.qpid.server.plugin.SystemNodeCreator;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+
+@PluggableService
+public class TrustStoreMessageSourceCreator implements SystemNodeCreator
+{
+
+    @Override
+    public String getType()
+    {
+        return "TRUSTSTORE-MESSAGE-SOURCE";
+    }
+
+    @Override
+    public void register(final SystemNodeRegistry registry)
+    {
+        final VirtualHostImpl<?,?,?> vhost = registry.getVirtualHost();
+        VirtualHostNode<?> virtualHostNode = vhost.getParent(VirtualHostNode.class);
+        final Broker<?> broker = virtualHostNode.getParent(Broker.class);
+
+        final Collection<TrustStore> trustStores = broker.getChildren(TrustStore.class);
+
+        final TrustStoreChangeListener trustStoreChangeListener = new TrustStoreChangeListener(registry);
+
+        for(final TrustStore trustStore : trustStores)
+        {
+            updateTrustStoreSourceRegistration(registry, trustStore);
+            trustStore.addChangeListener(trustStoreChangeListener);
+        }
+        broker.addChangeListener(new ConfigurationChangeListener()
+        {
+            @Override
+            public void stateChanged(final ConfiguredObject<?> object, final State oldState, final State newState)
+            {
+            }
+
+            @Override
+            public void childAdded(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+            {
+                if (child instanceof TrustStore)
+                {
+                    TrustStore<?> trustStore = (TrustStore<?>) child;
+
+                    updateTrustStoreSourceRegistration(registry, trustStore);
+                    trustStore.addChangeListener(trustStoreChangeListener);
+                }
+            }
+
+            @Override
+            public void childRemoved(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+            {
+
+                if (child instanceof TrustStore)
+                {
+                    TrustStore<?> trustStore = (TrustStore<?>) child;
+
+                    trustStore.removeChangeListener(trustStoreChangeListener);
+                    registry.removeSystemNode(TrustStoreMessageSource.getSourceNameFromTrustStore(trustStore));
+                }
+            }
+
+            @Override
+            public void attributeSet(final ConfiguredObject<?> object,
+                                     final String attributeName,
+                                     final Object oldAttributeValue,
+                                     final Object newAttributeValue)
+            {
+
+            }
+        });
+    }
+
+
+    private boolean isTrustStoreExposedAsMessageSource(VirtualHost<?,?,?> virtualHost, final TrustStore trustStore)
+    {
+        return trustStore.getState() == State.ACTIVE && trustStore.isExposedAsMessageSource()
+               && (trustStore.getIncludedVirtualHostMessageSources().contains(virtualHost)
+                   || (trustStore.getIncludedVirtualHostMessageSources().isEmpty()
+                       && !trustStore.getExcludedVirtualHostMessageSources().contains(virtualHost)));
+    }
+
+
+    private void updateTrustStoreSourceRegistration(SystemNodeRegistry registry, TrustStore<?> trustStore)
+    {
+        final String sourceName = TrustStoreMessageSource.getSourceNameFromTrustStore(trustStore);
+        if(isTrustStoreExposedAsMessageSource(registry.getVirtualHost(), trustStore) )
+        {
+            if(!registry.hasSystemNode(sourceName))
+            {
+
+                registry.registerSystemNode(new TrustStoreMessageSource(trustStore, registry.getVirtualHost()));
+
+            }
+        }
+        else
+        {
+            registry.removeSystemNode(sourceName);
+        }
+    }
+
+    private class TrustStoreChangeListener implements ConfigurationChangeListener
+    {
+
+        private final SystemNodeRegistry _registry;
+
+        public TrustStoreChangeListener(SystemNodeRegistry registry)
+        {
+            _registry = registry;
+        }
+
+        @Override
+        public void stateChanged(final ConfiguredObject<?> object,
+                                 final State oldState,
+                                 final State newState)
+        {
+            updateTrustStoreSourceRegistration(_registry, (TrustStore<?>)object);
+        }
+
+
+        @Override
+        public void childAdded(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+        {
+
+        }
+
+        @Override
+        public void childRemoved(final ConfiguredObject<?> object, final ConfiguredObject<?> child)
+        {
+
+        }
+
+        @Override
+        public void attributeSet(final ConfiguredObject<?> object,
+                                 final String attributeName,
+                                 final Object oldAttributeValue,
+                                 final Object newAttributeValue)
+        {
+            updateTrustStoreSourceRegistration(_registry, (TrustStore<?>)object);
+        }
+    }
+}

Propchange: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/TrustStoreMessageSourceCreator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java Sun May 10 23:37:05 2015
@@ -369,7 +369,7 @@ public class BrokerStoreUpgraderAndRecov
         {
             Map<String,Object> attributes = new HashMap<>();
             attributes.put("name", String.valueOf(seqNo));
-            attributes.put("logLevel", level.name());
+            attributes.put("level", level.name());
             attributes.put("loggerName", loggerName);
             attributes.put("type", "NameAndLevel");
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/transport/NonBlockingConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/transport/NonBlockingConnection.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/transport/NonBlockingConnection.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/transport/NonBlockingConnection.java Sun May 10 23:37:05 2015
@@ -25,6 +25,7 @@ import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
 import java.security.Principal;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -85,6 +86,7 @@ public class NonBlockingConnection imple
     private SSLEngineResult _status;
     private volatile boolean _fullyWritten = true;
     private boolean _workDone;
+    private Certificate _peerCertificate;
 
 
     public NonBlockingConnection(SocketChannel socketChannel,
@@ -200,26 +202,44 @@ public class NonBlockingConnection imple
     @Override
     public Principal getPeerPrincipal()
     {
+        checkPeerPrincipal();
+        return _principal;
+    }
+
+    @Override
+    public Certificate getPeerCertificate()
+    {
+        checkPeerPrincipal();
+        return _peerCertificate;
+    }
+
+    private void checkPeerPrincipal()
+    {
         synchronized (_peerPrincipalLock)
         {
-            if(!_principalChecked)
+            if (!_principalChecked)
             {
                 if (_sslEngine != null)
                 {
                     try
                     {
                         _principal = _sslEngine.getSession().getPeerPrincipal();
+                        final Certificate[] peerCertificates =
+                                _sslEngine.getSession().getPeerCertificates();
+                        if (peerCertificates != null && peerCertificates.length > 0)
+                        {
+                            _peerCertificate = peerCertificates[0];
+                        }
                     }
                     catch (SSLPeerUnverifiedException e)
                     {
-                        return null;
+                        _principal = null;
+                        _peerCertificate = null;
                     }
                 }
 
                 _principalChecked = true;
             }
-
-            return _principal;
         }
     }
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractSystemMessageSource.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractSystemMessageSource.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractSystemMessageSource.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractSystemMessageSource.java Sun May 10 23:37:05 2015
@@ -86,8 +86,6 @@ public abstract class AbstractSystemMess
         return MessageDurability.NEVER;
     }
 
-    protected abstract InternalMessage createMessage();
-
     @Override
     public Consumer addConsumer(final ConsumerTarget target,
                                     final FilterManager filters,
@@ -108,7 +106,7 @@ public abstract class AbstractSystemMess
     }
 
     @Override
-    public Collection<? extends ConsumerImpl> getConsumers()
+    public Collection<Consumer> getConsumers()
     {
         return new ArrayList<>(_consumers.values());
     }
@@ -131,7 +129,7 @@ public abstract class AbstractSystemMess
         return true;
     }
 
-    class Consumer implements ConsumerImpl
+    protected class Consumer implements ConsumerImpl
     {
 
         private final long _id = ConsumerImpl.CONSUMER_NUMBER_GENERATOR.getAndIncrement();
@@ -271,7 +269,7 @@ public abstract class AbstractSystemMess
         }
 
 
-        void send(final InternalMessage response)
+        public void send(final InternalMessage response)
         {
             _target.getSendLock();
             try

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java Sun May 10 23:37:05 2015
@@ -1152,11 +1152,24 @@ public abstract class AbstractVirtualHos
         }
 
         @Override
+        public void removeSystemNode(final String name)
+        {
+            _systemNodeDestinations.remove(name);
+            _systemNodeSources.remove(name);
+        }
+
+        @Override
         public VirtualHostImpl getVirtualHost()
         {
             return AbstractVirtualHost.this;
         }
 
+        @Override
+        public boolean hasSystemNode(final String name)
+        {
+            return _systemNodeSources.containsKey(name) || _systemNodeDestinations.containsKey(name);
+        }
+
     }
 
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostPropertiesNode.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostPropertiesNode.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostPropertiesNode.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostPropertiesNode.java Sun May 10 23:37:05 2015
@@ -60,7 +60,6 @@ public class VirtualHostPropertiesNode e
         return consumer;
     }
 
-    @Override
     protected InternalMessage createMessage()
     {
 

Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java Sun May 10 23:37:05 2015
@@ -52,6 +52,7 @@ import org.apache.qpid.server.protocol.A
 import org.apache.qpid.server.protocol.AMQSessionModel;
 import org.apache.qpid.server.protocol.SessionModelListener;
 import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.ManagedPeerCertificateTrustStore;
 import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 import org.apache.qpid.server.stats.StatisticsCounter;
 import org.apache.qpid.server.util.Action;
@@ -673,7 +674,12 @@ public class ServerConnection extends Co
 
     public Principal getPeerPrincipal()
     {
-        return getNetworkConnection().getPeerPrincipal();
+        Principal peerPrincipal = getNetworkConnection().getPeerPrincipal();
+        if(peerPrincipal != null && getPort().getClientCertRecorder() != null)
+        {
+            ((ManagedPeerCertificateTrustStore)(getPort().getClientCertRecorder())).addCertificate(getNetworkConnection().getPeerCertificate());
+        }
+        return peerPrincipal;
     }
 
     @Override

Modified: qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/InternalTestProtocolSession.java Sun May 10 23:37:05 2015
@@ -24,6 +24,7 @@ import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.security.Principal;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -320,6 +321,12 @@ public class InternalTestProtocolSession
         {
             return null;
         }
+
+        @Override
+        public Certificate getPeerCertificate()
+        {
+            return null;
+        }
 
         @Override
         public int getMaxReadIdle()

Modified: qpid/java/trunk/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java (original)
+++ qpid/java/trunk/broker-plugins/websocket/src/main/java/org/apache/qpid/server/transport/websocket/WebSocketProvider.java Sun May 10 23:37:05 2015
@@ -25,6 +25,7 @@ import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.security.Principal;
+import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
 import java.util.Set;
@@ -133,7 +134,8 @@ class WebSocketProvider implements Accep
             public WebSocket doWebSocketConnect(final HttpServletRequest request, final String protocol)
             {
 
-                Principal principal = null;
+                Certificate certificate = null;
+
                 if(Collections.list(request.getAttributeNames()).contains(X509_CERTIFICATES))
                 {
                     X509Certificate[] certificates =
@@ -141,13 +143,13 @@ class WebSocketProvider implements Accep
                     if(certificates != null && certificates.length != 0)
                     {
 
-                        principal = certificates[0].getSubjectDN();
+                        certificate = certificates[0];
                     }
                 }
 
                 SocketAddress remoteAddress = new InetSocketAddress(request.getRemoteHost(), request.getRemotePort());
                 SocketAddress localAddress = new InetSocketAddress(request.getLocalName(), request.getLocalPort());
-                return AMQP_WEBSOCKET_SUBPROTOCOL.equals(protocol) ? new AmqpWebSocket(_transport, localAddress, remoteAddress, principal) : null;
+                return AMQP_WEBSOCKET_SUBPROTOCOL.equals(protocol) ? new AmqpWebSocket(_transport, localAddress, remoteAddress, certificate) : null;
             }
         };
 
@@ -197,7 +199,7 @@ class WebSocketProvider implements Accep
     {
         private final SocketAddress _localAddress;
         private final SocketAddress _remoteAddress;
-        private final Principal _userPrincipal;
+        private final Certificate _userCertificate;
         private Connection _connection;
         private final Transport _transport;
         private ProtocolEngine _engine;
@@ -205,12 +207,12 @@ class WebSocketProvider implements Accep
         private AmqpWebSocket(final Transport transport,
                               final SocketAddress localAddress,
                               final SocketAddress remoteAddress,
-                              final Principal userPrincipal)
+                              final Certificate userCertificate)
         {
             _transport = transport;
             _localAddress = localAddress;
             _remoteAddress = remoteAddress;
-            _userPrincipal = userPrincipal;
+            _userCertificate = userCertificate;
         }
 
         @Override
@@ -228,7 +230,7 @@ class WebSocketProvider implements Accep
 
             final ConnectionWrapper connectionWrapper =
                     new ConnectionWrapper(connection, _localAddress, _remoteAddress);
-            connectionWrapper.setPeerPrincipal(_userPrincipal);
+            connectionWrapper.setPeerCertificate(_userCertificate);
             _engine.setNetworkConnection(connectionWrapper, connectionWrapper.getSender());
 
         }
@@ -245,7 +247,7 @@ class WebSocketProvider implements Accep
         private final WebSocket.Connection _connection;
         private final SocketAddress _localAddress;
         private final SocketAddress _remoteAddress;
-        private Principal _principal;
+        private Certificate _certificate;
         private int _maxWriteIdle;
         private int _maxReadIdle;
 
@@ -322,7 +324,13 @@ class WebSocketProvider implements Accep
         @Override
         public Principal getPeerPrincipal()
         {
-            return _principal;
+            return _certificate instanceof X509Certificate ? ((X509Certificate)_certificate).getSubjectDN() : null;
+        }
+
+        @Override
+        public Certificate getPeerCertificate()
+        {
+            return _certificate;
         }
 
         @Override
@@ -337,9 +345,9 @@ class WebSocketProvider implements Accep
             return _maxWriteIdle;
         }
 
-        void setPeerPrincipal(final Principal peerPrincipal)
+        void setPeerCertificate(final Certificate certificate)
         {
-            _principal = peerPrincipal;
+            _certificate = certificate;
         }
     }
 }

Modified: qpid/java/trunk/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java (original)
+++ qpid/java/trunk/client/src/test/java/org/apache/qpid/client/transport/TestNetworkConnection.java Sun May 10 23:37:05 2015
@@ -26,6 +26,7 @@ import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.security.Principal;
+import java.security.cert.Certificate;
 
 import org.apache.qpid.protocol.ProtocolEngineFactory;
 import org.apache.qpid.ssl.SSLContextFactory;
@@ -79,6 +80,12 @@ public class TestNetworkConnection imple
     {
         return null;
     }
+
+    @Override
+    public Certificate getPeerCertificate()
+    {
+        return null;
+    }
 
     @Override
     public int getMaxReadIdle()

Modified: qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java (original)
+++ qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java Sun May 10 23:37:05 2015
@@ -22,6 +22,7 @@ package org.apache.qpid.transport.networ
 
 import java.net.SocketAddress;
 import java.security.Principal;
+import java.security.cert.Certificate;
 
 import org.apache.qpid.transport.ByteBufferSender;
 
@@ -49,6 +50,8 @@ public interface NetworkConnection
 
     Principal getPeerPrincipal();
 
+    Certificate getPeerCertificate();
+
     int getMaxReadIdle();
 
     int getMaxWriteIdle();

Modified: qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java (original)
+++ qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java Sun May 10 23:37:05 2015
@@ -23,6 +23,7 @@ package org.apache.qpid.transport.networ
 import java.net.Socket;
 import java.net.SocketAddress;
 import java.security.Principal;
+import java.security.cert.Certificate;
 
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSocket;
@@ -47,6 +48,7 @@ public class IoNetworkConnection impleme
     private Principal _principal;
     private boolean _principalChecked;
     private final Object _lock = new Object();
+    private Certificate _certificate;
 
     public IoNetworkConnection(Socket socket, ByteBufferReceiver delegate,
             int sendBufferSize, int receiveBufferSize, long timeout, Ticker ticker)
@@ -118,6 +120,12 @@ public class IoNetworkConnection impleme
                     try
                     {
                         _principal = ((SSLSocket) _socket).getSession().getPeerPrincipal();
+                        final Certificate[] certs =
+                                ((SSLSocket) _socket).getSession().getPeerCertificates();
+                        if(certs != null && certs.length != 0)
+                        {
+                            _certificate = certs[0];
+                        }
                     }
                     catch(SSLPeerUnverifiedException e)
                     {
@@ -133,6 +141,19 @@ public class IoNetworkConnection impleme
     }
 
     @Override
+    public Certificate getPeerCertificate()
+    {
+        synchronized (_lock)
+        {
+            if(!_principalChecked)
+            {
+                getPeerPrincipal();
+            }
+        }
+        return _certificate;
+    }
+
+    @Override
     public int getMaxReadIdle()
     {
         return _maxReadIdle;

Modified: qpid/java/trunk/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java (original)
+++ qpid/java/trunk/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java Sun May 10 23:37:05 2015
@@ -23,6 +23,7 @@ package org.apache.qpid.transport.networ
 
 import java.net.SocketAddress;
 import java.security.Principal;
+import java.security.cert.Certificate;
 
 import junit.framework.TestCase;
 
@@ -235,6 +236,12 @@ public class IdleTimeoutTickerTest exten
     {
         return null;
     }
+
+    @Override
+    public Certificate getPeerCertificate()
+    {
+        return null;
+    }
 
     @Override
     public int getMaxReadIdle()

Modified: qpid/java/trunk/systests/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java (original)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java Sun May 10 23:37:05 2015
@@ -29,6 +29,7 @@ import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.security.Principal;
+import java.security.cert.Certificate;
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -280,6 +281,12 @@ public class MultiVersionProtocolEngineF
         {
             return null;
         }
+
+        @Override
+        public Certificate getPeerCertificate()
+        {
+            return null;
+        }
 
         @Override
         public int getMaxReadIdle()

Modified: qpid/java/trunk/systests/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java?rev=1678654&r1=1678653&r2=1678654&view=diff
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java (original)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java Sun May 10 23:37:05 2015
@@ -26,6 +26,7 @@ import java.net.SocketAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.security.Principal;
+import java.security.cert.Certificate;
 
 import org.apache.qpid.client.AMQConnection;
 import org.apache.qpid.client.protocol.AMQProtocolHandler;
@@ -153,6 +154,12 @@ public class AMQProtocolSessionTest exte
         {
             return null;
         }
+
+        @Override
+        public Certificate getPeerCertificate()
+        {
+            return null;
+        }
 
         @Override
         public int getMaxReadIdle()



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message