You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by jb...@apache.org on 2018/01/04 19:00:02 UTC

[1/2] activemq-artemis git commit: ARTEMIS-1548 Support CRL

Repository: activemq-artemis
Updated Branches:
  refs/heads/master 7232302f0 -> fee083a62


ARTEMIS-1548 Support CRL

Add support for CRL in client authentication


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/8c0e1e96
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/8c0e1e96
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/8c0e1e96

Branch: refs/heads/master
Commit: 8c0e1e96edd31689018fcba42fac74bea76e3b6f
Parents: 7232302
Author: raul.valdoleiros <ra...@ceiia.com>
Authored: Tue Dec 5 15:57:13 2017 +0000
Committer: Justin Bertram <jb...@apache.org>
Committed: Thu Jan 4 12:56:25 2018 -0600

----------------------------------------------------------------------
 .../remoting/impl/netty/NettyConnector.java     |   7 +-
 .../remoting/impl/netty/TransportConstants.java |   6 +
 .../core/remoting/impl/ssl/SSLSupport.java      |  77 +++++-
 .../core/remoting/impl/netty/NettyAcceptor.java |   7 +-
 examples/features/standard/pom.xml              |   2 +
 .../standard/ssl-enabled-crl-mqtt/pom.xml       | 115 +++++++++
 .../standard/ssl-enabled-crl-mqtt/readme.md     |  98 ++++++++
 .../jms/example/MqttCrlEnabledExample.java      |  83 +++++++
 .../main/resources/activemq/server0/broker.xml  |  36 +++
 .../resources/activemq/server0/keystore1.jks    | Bin 0 -> 2396 bytes
 .../resources/activemq/server0/root.crl.pem     |  12 +
 .../resources/activemq/server0/truststore.jks   | Bin 0 -> 1003 bytes
 .../src/main/resources/client_not_revoked.jks   | Bin 0 -> 2414 bytes
 .../src/main/resources/client_revoked.jks       | Bin 0 -> 2415 bytes
 .../src/main/resources/truststore.jks           | Bin 0 -> 1003 bytes
 tests/integration-tests/pom.xml                 |   9 +
 .../mqtt/imported/MQTTSecurityCRLTest.java      | 247 +++++++++++++++++++
 .../src/test/resources/client_not_revoked.jks   | Bin 0 -> 2414 bytes
 .../src/test/resources/client_revoked.jks       | Bin 0 -> 2415 bytes
 .../src/test/resources/keystore1.jks            | Bin 0 -> 2396 bytes
 .../resources/mqttCrl/client0/truststore.jks    | Bin 0 -> 1003 bytes
 .../resources/mqttCrl/client1/truststore.jks    | Bin 0 -> 1003 bytes
 .../src/test/resources/root.crl.pem             |  12 +
 .../src/test/resources/truststore.jks           | Bin 0 -> 1003 bytes
 24 files changed, 702 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
index 8faa22d..5d3b82d 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
@@ -206,6 +206,8 @@ public class NettyConnector extends AbstractConnector {
 
    private String trustStorePassword;
 
+   private String crlPath;
+
    private String enabledCipherSuites;
 
    private String enabledProtocols;
@@ -338,6 +340,8 @@ public class NettyConnector extends AbstractConnector {
 
          trustStorePassword = ConfigurationHelper.getPasswordProperty(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_TRUSTSTORE_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
 
+         crlPath = ConfigurationHelper.getStringProperty(TransportConstants.CRL_PATH_PROP_NAME, TransportConstants.DEFAULT_CRL_PATH, configuration);
+
          enabledCipherSuites = ConfigurationHelper.getStringProperty(TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME, TransportConstants.DEFAULT_ENABLED_CIPHER_SUITES, configuration);
 
          enabledProtocols = ConfigurationHelper.getStringProperty(TransportConstants.ENABLED_PROTOCOLS_PROP_NAME, TransportConstants.DEFAULT_ENABLED_PROTOCOLS, configuration);
@@ -358,6 +362,7 @@ public class NettyConnector extends AbstractConnector {
          trustStoreProvider = TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER;
          trustStorePath = TransportConstants.DEFAULT_TRUSTSTORE_PATH;
          trustStorePassword = TransportConstants.DEFAULT_TRUSTSTORE_PASSWORD;
+         crlPath = TransportConstants.DEFAULT_CRL_PATH;
          enabledCipherSuites = TransportConstants.DEFAULT_ENABLED_CIPHER_SUITES;
          enabledProtocols = TransportConstants.DEFAULT_ENABLED_PROTOCOLS;
          verifyHost = TransportConstants.DEFAULT_VERIFY_HOST;
@@ -519,7 +524,7 @@ public class NettyConnector extends AbstractConnector {
                if (System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME) != null) {
                   realTrustStorePassword = System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME);
                }
-               context = SSLSupport.createContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, trustAll);
+               context = SSLSupport.createContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, trustAll, crlPath);
             }
          } catch (Exception e) {
             close();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
index 890b508..efc5eb0 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
@@ -95,6 +95,8 @@ public class TransportConstants {
 
    public static final String TRUSTSTORE_PASSWORD_PROP_NAME = "trustStorePassword";
 
+   public static final String CRL_PATH_PROP_NAME = "crlPath";
+
    public static final String ENABLED_CIPHER_SUITES_PROP_NAME = "enabledCipherSuites";
 
    public static final String ENABLED_PROTOCOLS_PROP_NAME = "enabledProtocols";
@@ -189,6 +191,8 @@ public class TransportConstants {
 
    public static final String DEFAULT_TRUSTSTORE_PASSWORD = null;
 
+   public static final String DEFAULT_CRL_PATH = null;
+
    public static final String DEFAULT_ENABLED_CIPHER_SUITES = null;
 
    public static final String DEFAULT_ENABLED_PROTOCOLS = null;
@@ -310,6 +314,7 @@ public class TransportConstants {
       allowableAcceptorKeys.add(ActiveMQDefaultConfiguration.getPropMaskPassword());
       allowableAcceptorKeys.add(ActiveMQDefaultConfiguration.getPropPasswordCodec());
       allowableAcceptorKeys.add(TransportConstants.BACKLOG_PROP_NAME);
+      allowableAcceptorKeys.add(TransportConstants.CRL_PATH_PROP_NAME);
 
       ALLOWABLE_ACCEPTOR_KEYS = Collections.unmodifiableSet(allowableAcceptorKeys);
 
@@ -356,6 +361,7 @@ public class TransportConstants {
       allowableConnectorKeys.add(TransportConstants.NETTY_CONNECT_TIMEOUT);
       allowableConnectorKeys.add(TransportConstants.USE_DEFAULT_SSL_CONTEXT_PROP_NAME);
       allowableConnectorKeys.add(TransportConstants.HANDSHAKE_TIMEOUT);
+      allowableConnectorKeys.add(TransportConstants.CRL_PATH_PROP_NAME);
 
       ALLOWABLE_CONNECTOR_KEYS = Collections.unmodifiableSet(allowableConnectorKeys);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
index b4d9dbf..03b6e08 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
@@ -16,6 +16,15 @@
  */
 package org.apache.activemq.artemis.core.remoting.impl.ssl;
 
+import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CertStore;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.util.Collection;
+import javax.net.ssl.CertPathTrustManagerParameters;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
@@ -30,11 +39,11 @@ import java.security.AccessController;
 import java.security.KeyStore;
 import java.security.PrivilegedAction;
 import java.security.SecureRandom;
-
 import org.apache.activemq.artemis.utils.ClassloadingUtil;
 
 import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
 
+
 /**
  * Please note, this class supports PKCS#11 keystores, but there are no specific tests in the ActiveMQ Artemis test-suite to
  * validate/verify this works because this requires a functioning PKCS#11 provider which is not available by default
@@ -51,7 +60,18 @@ public class SSLSupport {
                                           final String trustStorePath,
                                           final String trustStorePassword) throws Exception {
 
-      return SSLSupport.createContext(keystoreProvider, keystorePath, keystorePassword, trustStoreProvider, trustStorePath, trustStorePassword, false);
+      return SSLSupport.createContext(keystoreProvider, keystorePath, keystorePassword, trustStoreProvider, trustStorePath, trustStorePassword, false, null);
+   }
+
+   public static SSLContext createContext(final String keystoreProvider,
+                                          final String keystorePath,
+                                          final String keystorePassword,
+                                          final String trustStoreProvider,
+                                          final String trustStorePath,
+                                          final String trustStorePassword,
+                                          final String crlPath) throws Exception {
+
+      return SSLSupport.createContext(keystoreProvider, keystorePath, keystorePassword, trustStoreProvider, trustStorePath, trustStorePassword, false, crlPath);
    }
 
    public static SSLContext createContext(final String keystoreProvider,
@@ -61,9 +81,20 @@ public class SSLSupport {
                                           final String trustStorePath,
                                           final String trustStorePassword,
                                           final boolean trustAll) throws Exception {
+      return SSLSupport.createContext(keystoreProvider, keystorePath, keystorePassword, trustStoreProvider, trustStorePath, trustStorePassword, trustAll, null);
+   }
+
+   public static SSLContext createContext(final String keystoreProvider,
+                                          final String keystorePath,
+                                          final String keystorePassword,
+                                          final String trustStoreProvider,
+                                          final String trustStorePath,
+                                          final String trustStorePassword,
+                                          final boolean trustAll,
+                                          final String crlPath) throws Exception {
       SSLContext context = SSLContext.getInstance("TLS");
       KeyManager[] keyManagers = SSLSupport.loadKeyManagers(keystoreProvider, keystorePath, keystorePassword);
-      TrustManager[] trustManagers = SSLSupport.loadTrustManager(trustStoreProvider, trustStorePath, trustStorePassword, trustAll);
+      TrustManager[] trustManagers = SSLSupport.loadTrustManager(trustStoreProvider, trustStorePath, trustStorePassword, trustAll, crlPath);
       context.init(keyManagers, trustManagers, new SecureRandom());
       return context;
    }
@@ -93,18 +124,50 @@ public class SSLSupport {
    private static TrustManager[] loadTrustManager(final String trustStoreProvider,
                                                   final String trustStorePath,
                                                   final String trustStorePassword,
-                                                  final boolean trustAll) throws Exception {
+                                                  final boolean trustAll,
+                                                  final String crlPath) throws Exception {
       if (trustAll) {
          //This is useful for testing but not should be used outside of that purpose
          return InsecureTrustManagerFactory.INSTANCE.getTrustManagers();
       } else if (trustStorePath == null && (trustStoreProvider == null || !"PKCS11".equals(trustStoreProvider.toUpperCase()))) {
          return null;
       } else {
-         TrustManagerFactory trustMgrFactory;
+         TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
          KeyStore trustStore = SSLSupport.loadKeystore(trustStoreProvider, trustStorePath, trustStorePassword);
-         trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-         trustMgrFactory.init(trustStore);
+         boolean ocsp = Boolean.valueOf(Security.getProperty("ocsp.enable"));
+
+         boolean initialized = false;
+         if ((ocsp || crlPath != null) && TrustManagerFactory.getDefaultAlgorithm().equalsIgnoreCase("PKIX")) {
+            PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(trustStore, new X509CertSelector());
+            if (crlPath != null) {
+               pkixParams.setRevocationEnabled(true);
+               Collection<? extends CRL> crlList = loadCRL(crlPath);
+               if (crlList != null) {
+                  pkixParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(crlList)));
+               }
+            }
+            trustMgrFactory.init(new CertPathTrustManagerParameters(pkixParams));
+            initialized = true;
+         }
+
+         if (!initialized) {
+            trustMgrFactory.init(trustStore);
+         }
+
          return trustMgrFactory.getTrustManagers();
+
+      }
+   }
+
+   private static Collection<? extends CRL> loadCRL(String crlPath) throws Exception {
+      if (crlPath == null) {
+         return null;
+      }
+
+      URL resource = SSLSupport.validateStoreURL(crlPath);
+
+      try (InputStream is = resource.openStream()) {
+         return CertificateFactory.getInstance("X.509").generateCRLs(is);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index 6141d6c..52c5b7e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -156,6 +156,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
    private final String trustStorePassword;
 
+   private final String crlPath;
+
    private final String enabledCipherSuites;
 
    private final String enabledProtocols;
@@ -259,6 +261,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
          trustStorePassword = ConfigurationHelper.getPasswordProperty(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, TransportConstants.DEFAULT_TRUSTSTORE_PASSWORD, configuration, ActiveMQDefaultConfiguration.getPropMaskPassword(), ActiveMQDefaultConfiguration.getPropPasswordCodec());
 
+         crlPath = ConfigurationHelper.getStringProperty(TransportConstants.CRL_PATH_PROP_NAME, TransportConstants.DEFAULT_CRL_PATH, configuration);
+
          enabledCipherSuites = ConfigurationHelper.getStringProperty(TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME, TransportConstants.DEFAULT_ENABLED_CIPHER_SUITES, configuration);
 
          enabledProtocols = ConfigurationHelper.getStringProperty(TransportConstants.ENABLED_PROTOCOLS_PROP_NAME, TransportConstants.DEFAULT_ENABLED_PROTOCOLS, configuration);
@@ -273,6 +277,7 @@ public class NettyAcceptor extends AbstractAcceptor {
          trustStoreProvider = TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER;
          trustStorePath = TransportConstants.DEFAULT_TRUSTSTORE_PATH;
          trustStorePassword = TransportConstants.DEFAULT_TRUSTSTORE_PASSWORD;
+         crlPath = TransportConstants.DEFAULT_CRL_PATH;
          enabledCipherSuites = TransportConstants.DEFAULT_ENABLED_CIPHER_SUITES;
          enabledProtocols = TransportConstants.DEFAULT_ENABLED_PROTOCOLS;
          needClientAuth = TransportConstants.DEFAULT_NEED_CLIENT_AUTH;
@@ -453,7 +458,7 @@ public class NettyAcceptor extends AbstractAcceptor {
             throw new IllegalArgumentException("If \"" + TransportConstants.SSL_ENABLED_PROP_NAME +
                                                   "\" is true then \"" + TransportConstants.KEYSTORE_PATH_PROP_NAME + "\" must be non-null " +
                                                   "unless an alternative \"" + TransportConstants.KEYSTORE_PROVIDER_PROP_NAME + "\" has been specified.");
-         context = SSLSupport.createContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword);
+         context = SSLSupport.createContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword, crlPath);
       } catch (Exception e) {
          IllegalStateException ise = new IllegalStateException("Unable to create NettyAcceptor for " + host + ":" + port);
          ise.initCause(e);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/pom.xml b/examples/features/standard/pom.xml
index d254992..0d77a4e 100644
--- a/examples/features/standard/pom.xml
+++ b/examples/features/standard/pom.xml
@@ -102,6 +102,7 @@ under the License.
             <module>xa-heuristic</module>
             <module>xa-receive</module>
             <module>xa-send</module>
+            <module>ssl-enabled-crl-mqtt</module>
          </modules>
       </profile>
       <profile>
@@ -173,6 +174,7 @@ under the License.
             <module>xa-heuristic</module>
             <module>xa-receive</module>
             <module>xa-send</module>
+            <module>ssl-enabled-crl-mqtt</module>
          </modules>
       </profile>
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/pom.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/pom.xml b/examples/features/standard/ssl-enabled-crl-mqtt/pom.xml
new file mode 100644
index 0000000..1c26f0d
--- /dev/null
+++ b/examples/features/standard/ssl-enabled-crl-mqtt/pom.xml
@@ -0,0 +1,115 @@
+<?xml version='1.0'?>
+<!--
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.activemq.examples.broker</groupId>
+        <artifactId>jms-examples</artifactId>
+        <version>2.5.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>ssl-enabled-crl-mqtt</artifactId>
+    <packaging>jar</packaging>
+    <name>ActiveMQ Artemis Mqtt CRL Example</name>
+
+    <properties>
+        <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.activemq</groupId>
+            <artifactId>artemis-jms-client-all</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.fusesource.mqtt-client</groupId>
+            <artifactId>mqtt-client</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.activemq</groupId>
+                <artifactId>artemis-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>create</id>
+                        <goals>
+                            <goal>create</goal>
+                        </goals>
+                        <configuration>
+                            <ignore>${noServer}</ignore>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>start</id>
+                        <goals>
+                            <goal>cli</goal>
+                        </goals>
+                        <configuration>
+                            <ignore>${noServer}</ignore>
+                            <spawn>true</spawn>
+                            <testURI>tcp://localhost:61616</testURI>
+                            <testUser>consumer</testUser>
+                            <testPassword>activemq</testPassword>
+                            <args>
+                                <param>run</param>
+                            </args>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>runClient</id>
+                        <goals>
+                            <goal>runClient</goal>
+                        </goals>
+                        <configuration>
+                            <clientClass>org.apache.activemq.artemis.jms.example.MqttCrlEnabledExample</clientClass>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>stop</id>
+                        <goals>
+                            <goal>cli</goal>
+                        </goals>
+                        <configuration>
+                            <ignore>${noServer}</ignore>
+                            <args>
+                                <param>stop</param>
+                            </args>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.activemq.examples.broker</groupId>
+                        <artifactId>ssl-enabled-crl-mqtt</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/readme.md
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/readme.md b/examples/features/standard/ssl-enabled-crl-mqtt/readme.md
new file mode 100644
index 0000000..56be3ce
--- /dev/null
+++ b/examples/features/standard/ssl-enabled-crl-mqtt/readme.md
@@ -0,0 +1,98 @@
+# ActiveMQ Artemis MQTT CRL Example
+
+To run the example, simply type **mvn verify** from this directory, or **mvn -PnoServer verify** if you want to start and create the server manually.
+
+This example shows you how to configure 2-way SSL with CRL along with 2 different connections, one with a valid certificate and another with a revoked certificate.
+
+To configure 2-way SSL with CRL you need to configure the acceptor as follows:
+
+```
+<acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true;sslEnabled=true;keyStorePath=${data.dir}/../etc/keystore1.jks;keyStorePassword=changeit;trustStorePath=${data.dir}/../etc/truststore.jks;keyStorePassword=changeit;crlPath=${data.dir}/../etc/root.crl.pem;needClientAuth=true</acceptor>`
+```
+
+In the server-side URL, the `keystore1.jks` is the key store file holding the server's key certificate. The `truststore.jks` is the file holding the certificates which the server trusts. The `root.crl.pem` is the file holding the revoked certificates. Notice also the `sslEnabled` and `needClientAuth` parameters which enable SSL and require clients to present their own certificate respectively.
+
+The various keystore files are generated using the following commands. Keep in mind that each common name should be different and the passwords should be `changeit`.
+
+```
+openssl genrsa -out ca.key 2048
+openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
+touch certindex
+echo 01 > certserial
+echo 01 > crlnumber
+```
+
+## Create the ca.conf file:
+
+```
+[ ca ]
+default_ca = myca
+
+[ crl_ext ]
+# issuerAltName=issuer:copy #this would copy the issuer name to altname
+authorityKeyIdentifier=keyid:always
+
+[ myca ]
+dir = ./
+new_certs_dir = $dir
+unique_subject = no
+certificate = $dir/ca.crt
+database = $dir/certindex
+private_key = $dir/ca.key
+serial = $dir/certserial
+default_days = 730
+default_md = sha1
+policy = myca_policy
+x509_extensions = myca_extensions
+crlnumber = $dir/crlnumber
+default_crl_days = 730
+
+[ myca_policy ]
+commonName = supplied
+stateOrProvinceName = supplied
+countryName = optional
+emailAddress = optional
+organizationName = supplied
+organizationalUnitName = optional
+
+[ myca_extensions ]
+basicConstraints = CA:false
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always
+keyUsage = digitalSignature,keyEncipherment
+extendedKeyUsage = serverAuth, clientAuth
+crlDistributionPoints = URI:http://example.com/root.crl
+subjectAltName = @alt_names
+
+[alt_names]
+DNS.1 = example.com
+DNS.2 = *.example.com`
+```
+
+## Continue with the following commands:
+
+```
+openssl genrsa -out keystore1.key 2048
+openssl req -new -key keystore1.key -out keystore1.csr
+openssl ca -batch -config ca.conf -notext -in keystore1.csr -out keystore1.crt
+openssl genrsa -out client_revoked.key 2048
+openssl req -new -key client_revoked.key -out client_revoked.csr
+openssl ca -batch -config ca.conf -notext -in client_revoked.csr -out client_revoked.crt
+openssl genrsa -out client_not_revoked.key 2048
+openssl req -new -key client_not_revoked.key -out client_not_revoked.csr
+openssl ca -batch -config ca.conf -notext -in client_not_revoked.csr -out client_not_revoked.crt
+openssl ca -config ca.conf -gencrl -keyfile ca.key -cert ca.crt -out root.crl.pem
+openssl ca -config ca.conf -revoke client_revoked.crt -keyfile ca.key -cert ca.crt
+openssl ca -config ca.conf -gencrl -keyfile ca.key -cert ca.crt -out root.crl.pem
+
+openssl pkcs12 -export -name client_revoked -in client_revoked.crt -inkey client_revoked.key -out client_revoked.p12
+keytool -importkeystore -destkeystore client_revoked.jks -srckeystore client_revoked.p12 -srcstoretype pkcs12 -alias client_revoked
+
+openssl pkcs12 -export -name client_not_revoked -in client_not_revoked.crt -inkey client_not_revoked.key -out client_not_revoked.p12
+keytool -importkeystore -destkeystore client_not_revoked.jks -srckeystore client_not_revoked.p12 -srcstoretype pkcs12 -alias client_not_revoked
+
+openssl pkcs12 -export -name keystore1 -in keystore1.crt -inkey keystore1.key -out keystore1.p12
+keytool -importkeystore -destkeystore keystore1.jks -srckeystore keystore1.p12 -srcstoretype pkcs12 -alias keystore1
+
+keytool -import -trustcacerts -alias trust_key -file ca.crt -keystore truststore.jks
+```
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/java/org/apache/activemq/artemis/jms/example/MqttCrlEnabledExample.java
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/java/org/apache/activemq/artemis/jms/example/MqttCrlEnabledExample.java b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/java/org/apache/activemq/artemis/jms/example/MqttCrlEnabledExample.java
new file mode 100644
index 0000000..a4ddf6a
--- /dev/null
+++ b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/java/org/apache/activemq/artemis/jms/example/MqttCrlEnabledExample.java
@@ -0,0 +1,83 @@
+/*
+ * 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.activemq.artemis.jms.example;
+
+import javax.net.ssl.SSLException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport;
+import org.fusesource.mqtt.client.BlockingConnection;
+import org.fusesource.mqtt.client.MQTT;
+import org.fusesource.mqtt.client.Message;
+import org.fusesource.mqtt.client.QoS;
+import org.fusesource.mqtt.client.Topic;
+
+public class MqttCrlEnabledExample {
+
+   public static void main(final String[] args) throws Exception {
+      boolean exception = false;
+      try {
+         callBroker("truststore.jks", "changeit", "client_revoked.jks", "changeit");
+      } catch (SSLException e) {
+         exception = true;
+      }
+      if (!exception) {
+         throw new RuntimeException("The connection should be revoked");
+      }
+      callBroker("truststore.jks", "changeit", "client_not_revoked.jks", "changeit");
+   }
+
+   private static void callBroker(String truststorePath, String truststorePass, String keystorePath, String keystorePass) throws Exception {
+      BlockingConnection connection = null;
+
+      try {
+         connection = retrieveMQTTConnection("ssl://localhost:1883", truststorePath, truststorePass, keystorePath, keystorePass);
+         // Subscribe to topics
+         Topic[] topics = {new Topic("test/+/some/#", QoS.AT_MOST_ONCE)};
+         connection.subscribe(topics);
+
+         // Publish Messages
+         String payload = "This is message 1";
+
+         connection.publish("test/1/some/la", payload.getBytes(), QoS.AT_LEAST_ONCE, false);
+
+         Message message = connection.receive(5, TimeUnit.SECONDS);
+         System.out.println("Message received: " + new String(message.getPayload()));
+
+      } catch (Exception e) {
+         throw e;
+      } finally {
+         if (connection != null) {
+            connection.disconnect();
+         }
+      }
+   }
+
+   private static BlockingConnection retrieveMQTTConnection(String host, String truststorePath, String truststorePass, String keystorePath, String keystorePass) throws Exception {
+      MQTT mqtt = new MQTT();
+      mqtt.setConnectAttemptsMax(0);
+      mqtt.setReconnectAttemptsMax(0);
+      mqtt.setHost(host);
+      mqtt.setSslContext(SSLSupport.createContext("JKS", keystorePath, keystorePass, "JKS", truststorePath, truststorePass));
+      mqtt.setCleanSession(true);
+
+      BlockingConnection connection = mqtt.blockingConnection();
+      connection.connect();
+      return connection;
+   }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/broker.xml
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/broker.xml b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..9877bd5
--- /dev/null
+++ b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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.
+-->
+<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+   <core xmlns="urn:activemq:core">
+
+      <security-enabled>false</security-enabled>
+
+      <acceptors>
+         <acceptor name="netty-acceptor">tcp://localhost:61616</acceptor>
+         <acceptor name="mqtt">tcp://0.0.0.0:1883?protocols=MQTT;sslEnabled=true;keyStorePath=keystore1.jks;keyStorePassword=changeit;trustStorePath=truststore.jks;keyStorePassword=changeit;crlPath=root.crl.pem;needClientAuth=true</acceptor>
+      </acceptors>
+
+      <wildcard-addresses>
+         <routing-enabled>true</routing-enabled>
+         <delimiter>/</delimiter>
+         <any-words>#</any-words>
+         <single-word>+</single-word>
+      </wildcard-addresses>
+
+   </core>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/keystore1.jks
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/keystore1.jks b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/keystore1.jks
new file mode 100644
index 0000000..f1d8857
Binary files /dev/null and b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/keystore1.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/root.crl.pem
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/root.crl.pem b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/root.crl.pem
new file mode 100644
index 0000000..8938392
--- /dev/null
+++ b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/root.crl.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJBVTETMBEGA1UE
+CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
+MRAwDgYDVQQDDAdhc2ZnZGZnMRAwDgYJKoZIhvcNAQkBFgFhFw0xNzEyMTQxODAw
+NDVaFw0xOTEyMTQxODAwNDVaMBQwEgIBAhcNMTcxMjE0MTgwMDM2WqAOMAwwCgYD
+VR0UBAMCAQIwDQYJKoZIhvcNAQEFBQADggEBACNiLQvZayn+ULeeSTnxcOOPaIku
+1E5AGG3M6uUBalECEpstzmXQELdiZvQb2BMRb1hpm1pNJ8uITjrjeT6bf1+KGgeN
+6lRMg36AwyQm8LGiE6ry9jF1OCHqERuImQUrRKWRUbL4hT79Fmji1xm9T9CA3RmE
+hjN5oHXM5avF+pm6aU2L2bZ03DhU4Ur0rOd1DCXcGWiZc7VJEQicSrG2R8dagFO/
+w0OUFiTahbdxSguNNU5kIuSltm4kfMM7GcFMb9/kMTTz/U+nUarm7ZzZozn7p/Sb
+9FjJ39JzFwq0jTT2bK+3WEWagQs9eNWAPjb5F3ofBSUleZ1f3rdhWWCSS+A=
+-----END X509 CRL-----

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/truststore.jks
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/truststore.jks b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/truststore.jks
new file mode 100644
index 0000000..5a8d79f
Binary files /dev/null and b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/activemq/server0/truststore.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_not_revoked.jks
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_not_revoked.jks b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_not_revoked.jks
new file mode 100644
index 0000000..7e47443
Binary files /dev/null and b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_not_revoked.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_revoked.jks
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_revoked.jks b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_revoked.jks
new file mode 100644
index 0000000..8d6f480
Binary files /dev/null and b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/client_revoked.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/truststore.jks
----------------------------------------------------------------------
diff --git a/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/truststore.jks b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/truststore.jks
new file mode 100644
index 0000000..5a8d79f
Binary files /dev/null and b/examples/features/standard/ssl-enabled-crl-mqtt/src/main/resources/truststore.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 1394bae..0249033 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -481,6 +481,15 @@
                </execution>
             </executions>
          </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <configuration>
+               <nonFilteredFileExtensions>
+                  <nonFilteredFileExtension>jks</nonFilteredFileExtension>
+               </nonFilteredFileExtensions>
+            </configuration>
+         </plugin>
       </plugins>
    </build>
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/mqtt/imported/MQTTSecurityCRLTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/mqtt/imported/MQTTSecurityCRLTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/mqtt/imported/MQTTSecurityCRLTest.java
new file mode 100644
index 0000000..4f88661
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/mqtt/imported/MQTTSecurityCRLTest.java
@@ -0,0 +1,247 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.activemq.artemis.tests.integration.mqtt.imported;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.config.Configuration;
+import org.apache.activemq.artemis.core.config.WildcardConfiguration;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.fusesource.mqtt.client.BlockingConnection;
+import org.fusesource.mqtt.client.MQTT;
+import org.fusesource.mqtt.client.Message;
+import org.fusesource.mqtt.client.QoS;
+import org.fusesource.mqtt.client.Topic;
+import org.junit.Test;
+
+public class MQTTSecurityCRLTest extends ActiveMQTestBase {
+   /**
+    * These artifacts are required for testing mqtt with CRL
+    * <p>
+    * openssl genrsa -out ca.key 2048
+    * openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
+    * touch certindex
+    * echo 01 > certserial
+    * echo 01 > crlnumber
+    * <p>
+    * Create ca.conf file with
+    * <p>
+    * [ ca ]
+    * default_ca = myca
+    * <p>
+    * [ crl_ext ]
+    * # issuerAltName=issuer:copy #this would copy the issuer name to altname
+    * authorityKeyIdentifier=keyid:always
+    * <p>
+    * [ myca ]
+    * dir = ./
+    * new_certs_dir = $dir
+    * unique_subject = no
+    * certificate = $dir/ca.crt
+    * database = $dir/certindex
+    * private_key = $dir/ca.key
+    * serial = $dir/certserial
+    * default_days = 730
+    * default_md = sha1
+    * policy = myca_policy
+    * x509_extensions = myca_extensions
+    * crlnumber = $dir/crlnumber
+    * default_crl_days = 730
+    * <p>
+    * [ myca_policy ]
+    * commonName = supplied
+    * stateOrProvinceName = supplied
+    * countryName = optional
+    * emailAddress = optional
+    * organizationName = supplied
+    * organizationalUnitName = optional
+    * <p>
+    * [ myca_extensions ]
+    * basicConstraints = CA:false
+    * subjectKeyIdentifier = hash
+    * authorityKeyIdentifier = keyid:always
+    * keyUsage = digitalSignature,keyEncipherment
+    * extendedKeyUsage = serverAuth, clientAuth
+    * crlDistributionPoints = URI:http://example.com/root.crl
+    * subjectAltName = @alt_names
+    * <p>
+    * [alt_names]
+    * DNS.1 = example.com
+    * DNS.2 = *.example.com
+    * <p>
+    * Continue executing the commands:
+    * <p>
+    * openssl genrsa -out keystore1.key 2048
+    * openssl req -new -key keystore1.key -out keystore1.csr
+    * openssl ca -batch -config ca.conf -notext -in keystore1.csr -out keystore1.crt
+    * openssl genrsa -out client_revoked.key 2048
+    * openssl req -new -key client_revoked.key -out client_revoked.csr
+    * openssl ca -batch -config ca.conf -notext -in client_revoked.csr -out client_revoked.crt
+    * openssl genrsa -out client_not_revoked.key 2048
+    * openssl req -new -key client_not_revoked.key -out client_not_revoked.csr
+    * openssl ca -batch -config ca.conf -notext -in client_not_revoked.csr -out client_not_revoked.crt
+    * openssl ca -config ca.conf -gencrl -keyfile ca.key -cert ca.crt -out root.crl.pem
+    * openssl ca -config ca.conf -revoke client_revoked.crt -keyfile ca.key -cert ca.crt
+    * openssl ca -config ca.conf -gencrl -keyfile ca.key -cert ca.crt -out root.crl.pem
+    * <p>
+    * openssl pkcs12 -export -name client_revoked -in client_revoked.crt -inkey client_revoked.key -out client_revoked.p12
+    * keytool -importkeystore -destkeystore client_revoked.jks -srckeystore client_revoked.p12 -srcstoretype pkcs12 -alias client_revoked
+    * <p>
+    * openssl pkcs12 -export -name client_not_revoked -in client_not_revoked.crt -inkey client_not_revoked.key -out client_not_revoked.p12
+    * keytool -importkeystore -destkeystore client_not_revoked.jks -srckeystore client_not_revoked.p12 -srcstoretype pkcs12 -alias client_not_revoked
+    * <p>
+    * openssl pkcs12 -export -name keystore1 -in keystore1.crt -inkey keystore1.key -out keystore1.p12
+    * keytool -importkeystore -destkeystore keystore1.jks -srckeystore keystore1.p12 -srcstoretype pkcs12 -alias keystore1
+    * <p>
+    * keytool -import -trustcacerts -alias trust_key -file ca.crt -keystore truststore.jks
+    */
+
+   @Test(expected = SSLException.class)
+   public void crlRevokedTest() throws Exception {
+
+      ActiveMQServer server1 = initServer();
+      BlockingConnection connection1 = null;
+      try {
+         server1.start();
+
+         while (!server1.isStarted()) {
+            Thread.sleep(50);
+         }
+
+         connection1 = retrieveMQTTConnection("ssl://localhost:1883", "truststore.jks", "changeit", "client_revoked.jks", "changeit");
+
+         // Subscribe to topics
+         Topic[] topics = {new Topic("test/+/some/#", QoS.AT_MOST_ONCE)};
+         connection1.subscribe(topics);
+
+         // Publish Messages
+         String payload1 = "This is message 1";
+
+         connection1.publish("test/1/some/la", payload1.getBytes(), QoS.AT_LEAST_ONCE, false);
+
+         Message message1 = connection1.receive(5, TimeUnit.SECONDS);
+
+         assertEquals(payload1, new String(message1.getPayload()));
+
+      } finally {
+         if (connection1 != null) {
+            connection1.disconnect();
+         }
+         if (server1.isStarted()) {
+            server1.stop();
+         }
+      }
+   }
+
+   @Test
+   public void crlNotRevokedTest() throws Exception {
+
+      ActiveMQServer server1 = initServer();
+      BlockingConnection connection1 = null;
+      try {
+         server1.start();
+
+         while (!server1.isStarted()) {
+            Thread.sleep(50);
+         }
+
+         connection1 = retrieveMQTTConnection("ssl://localhost:1883", "truststore.jks", "changeit", "client_not_revoked.jks", "changeit");
+
+         // Subscribe to topics
+         Topic[] topics = {new Topic("test/+/some/#", QoS.AT_MOST_ONCE)};
+         connection1.subscribe(topics);
+
+         // Publish Messages
+         String payload1 = "This is message 1";
+
+         connection1.publish("test/1/some/la", payload1.getBytes(), QoS.AT_LEAST_ONCE, false);
+
+         Message message1 = connection1.receive(5, TimeUnit.SECONDS);
+
+         assertEquals(payload1, new String(message1.getPayload()));
+
+      } finally {
+         if (connection1 != null) {
+            connection1.disconnect();
+         }
+         if (server1.isStarted()) {
+            server1.stop();
+         }
+      }
+   }
+
+
+   private ActiveMQServer initServer() throws Exception {
+      Configuration configuration = createDefaultNettyConfig().setSecurityEnabled(false);
+
+      addMqttTransportConfiguration(configuration);
+      addWildCardConfiguration(configuration);
+
+      ActiveMQServer server = createServer(true, configuration);
+      return server;
+   }
+
+   private void addWildCardConfiguration(Configuration configuration) {
+      WildcardConfiguration wildcardConfiguration = new WildcardConfiguration();
+      wildcardConfiguration.setAnyWords('#');
+      wildcardConfiguration.setDelimiter('/');
+      wildcardConfiguration.setRoutingEnabled(true);
+      wildcardConfiguration.setSingleWord('+');
+
+      configuration.setWildCardConfiguration(wildcardConfiguration);
+   }
+
+   private void addMqttTransportConfiguration(Configuration configuration) throws IOException {
+      TransportConfiguration transportConfiguration = new TransportConfiguration(NettyAcceptorFactory.class.getCanonicalName(), null, "mqtt", null);
+
+      transportConfiguration.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+      transportConfiguration.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "truststore.jks");
+      transportConfiguration.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "changeit");
+      transportConfiguration.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "keystore1.jks");
+      transportConfiguration.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "changeit");
+      transportConfiguration.getParams().put(TransportConstants.CRL_PATH_PROP_NAME, "root.crl.pem");
+      transportConfiguration.getParams().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, "true");
+      transportConfiguration.getParams().put(TransportConstants.PORT_PROP_NAME, "1883");
+      transportConfiguration.getParams().put(TransportConstants.HOST_PROP_NAME, "localhost");
+      transportConfiguration.getParams().put(TransportConstants.PROTOCOLS_PROP_NAME, "MQTT");
+
+      configuration.getAcceptorConfigurations().add(transportConfiguration);
+   }
+
+   private BlockingConnection retrieveMQTTConnection(String host, String truststorePath, String truststorePass, String keystorePath, String keystorePass) throws Exception {
+      MQTT mqtt = new MQTT();
+      mqtt.setConnectAttemptsMax(1);
+      mqtt.setReconnectAttemptsMax(0);
+      mqtt.setHost(host);
+      SSLContext sslContext = SSLSupport.createContext(TransportConstants.DEFAULT_KEYSTORE_PROVIDER, keystorePath, keystorePass, TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER, truststorePath, truststorePass);
+      mqtt.setSslContext(sslContext);
+
+      BlockingConnection connection = mqtt.blockingConnection();
+      connection.connect();
+      return connection;
+   }
+
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/client_not_revoked.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/client_not_revoked.jks b/tests/integration-tests/src/test/resources/client_not_revoked.jks
new file mode 100644
index 0000000..7e47443
Binary files /dev/null and b/tests/integration-tests/src/test/resources/client_not_revoked.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/client_revoked.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/client_revoked.jks b/tests/integration-tests/src/test/resources/client_revoked.jks
new file mode 100644
index 0000000..8d6f480
Binary files /dev/null and b/tests/integration-tests/src/test/resources/client_revoked.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/keystore1.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/keystore1.jks b/tests/integration-tests/src/test/resources/keystore1.jks
new file mode 100644
index 0000000..f1d8857
Binary files /dev/null and b/tests/integration-tests/src/test/resources/keystore1.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/mqttCrl/client0/truststore.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/mqttCrl/client0/truststore.jks b/tests/integration-tests/src/test/resources/mqttCrl/client0/truststore.jks
new file mode 100644
index 0000000..5a8d79f
Binary files /dev/null and b/tests/integration-tests/src/test/resources/mqttCrl/client0/truststore.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/mqttCrl/client1/truststore.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/mqttCrl/client1/truststore.jks b/tests/integration-tests/src/test/resources/mqttCrl/client1/truststore.jks
new file mode 100644
index 0000000..5a8d79f
Binary files /dev/null and b/tests/integration-tests/src/test/resources/mqttCrl/client1/truststore.jks differ

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/root.crl.pem
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/root.crl.pem b/tests/integration-tests/src/test/resources/root.crl.pem
new file mode 100644
index 0000000..8938392
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/root.crl.pem
@@ -0,0 +1,12 @@
+-----BEGIN X509 CRL-----
+MIIB2DCBwQIBATANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJBVTETMBEGA1UE
+CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
+MRAwDgYDVQQDDAdhc2ZnZGZnMRAwDgYJKoZIhvcNAQkBFgFhFw0xNzEyMTQxODAw
+NDVaFw0xOTEyMTQxODAwNDVaMBQwEgIBAhcNMTcxMjE0MTgwMDM2WqAOMAwwCgYD
+VR0UBAMCAQIwDQYJKoZIhvcNAQEFBQADggEBACNiLQvZayn+ULeeSTnxcOOPaIku
+1E5AGG3M6uUBalECEpstzmXQELdiZvQb2BMRb1hpm1pNJ8uITjrjeT6bf1+KGgeN
+6lRMg36AwyQm8LGiE6ry9jF1OCHqERuImQUrRKWRUbL4hT79Fmji1xm9T9CA3RmE
+hjN5oHXM5avF+pm6aU2L2bZ03DhU4Ur0rOd1DCXcGWiZc7VJEQicSrG2R8dagFO/
+w0OUFiTahbdxSguNNU5kIuSltm4kfMM7GcFMb9/kMTTz/U+nUarm7ZzZozn7p/Sb
+9FjJ39JzFwq0jTT2bK+3WEWagQs9eNWAPjb5F3ofBSUleZ1f3rdhWWCSS+A=
+-----END X509 CRL-----

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/8c0e1e96/tests/integration-tests/src/test/resources/truststore.jks
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/truststore.jks b/tests/integration-tests/src/test/resources/truststore.jks
new file mode 100644
index 0000000..5a8d79f
Binary files /dev/null and b/tests/integration-tests/src/test/resources/truststore.jks differ


[2/2] activemq-artemis git commit: This closes #1715

Posted by jb...@apache.org.
This closes #1715


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

Branch: refs/heads/master
Commit: fee083a621fefd9ceb31d8bbf2021a717125967d
Parents: 7232302 8c0e1e9
Author: Justin Bertram <jb...@apache.org>
Authored: Thu Jan 4 12:56:49 2018 -0600
Committer: Justin Bertram <jb...@apache.org>
Committed: Thu Jan 4 12:56:49 2018 -0600

----------------------------------------------------------------------
 .../remoting/impl/netty/NettyConnector.java     |   7 +-
 .../remoting/impl/netty/TransportConstants.java |   6 +
 .../core/remoting/impl/ssl/SSLSupport.java      |  77 +++++-
 .../core/remoting/impl/netty/NettyAcceptor.java |   7 +-
 examples/features/standard/pom.xml              |   2 +
 .../standard/ssl-enabled-crl-mqtt/pom.xml       | 115 +++++++++
 .../standard/ssl-enabled-crl-mqtt/readme.md     |  98 ++++++++
 .../jms/example/MqttCrlEnabledExample.java      |  83 +++++++
 .../main/resources/activemq/server0/broker.xml  |  36 +++
 .../resources/activemq/server0/keystore1.jks    | Bin 0 -> 2396 bytes
 .../resources/activemq/server0/root.crl.pem     |  12 +
 .../resources/activemq/server0/truststore.jks   | Bin 0 -> 1003 bytes
 .../src/main/resources/client_not_revoked.jks   | Bin 0 -> 2414 bytes
 .../src/main/resources/client_revoked.jks       | Bin 0 -> 2415 bytes
 .../src/main/resources/truststore.jks           | Bin 0 -> 1003 bytes
 tests/integration-tests/pom.xml                 |   9 +
 .../mqtt/imported/MQTTSecurityCRLTest.java      | 247 +++++++++++++++++++
 .../src/test/resources/client_not_revoked.jks   | Bin 0 -> 2414 bytes
 .../src/test/resources/client_revoked.jks       | Bin 0 -> 2415 bytes
 .../src/test/resources/keystore1.jks            | Bin 0 -> 2396 bytes
 .../resources/mqttCrl/client0/truststore.jks    | Bin 0 -> 1003 bytes
 .../resources/mqttCrl/client1/truststore.jks    | Bin 0 -> 1003 bytes
 .../src/test/resources/root.crl.pem             |  12 +
 .../src/test/resources/truststore.jks           | Bin 0 -> 1003 bytes
 24 files changed, 702 insertions(+), 9 deletions(-)
----------------------------------------------------------------------