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 <[email protected]> Authored: Tue Dec 5 15:57:13 2017 +0000 Committer: Justin Bertram <[email protected]> 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
