mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-5008 - certificate revocation list support
This commit is contained in:
parent
af13292916
commit
0fd174b928
|
@ -21,17 +21,18 @@ import java.net.MalformedURLException;
|
|||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.*;
|
||||
|
||||
import org.apache.activemq.broker.SslContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Extends the SslContext so that it's easier to configure from spring.
|
||||
|
@ -42,6 +43,8 @@ import org.apache.activemq.broker.SslContext;
|
|||
*/
|
||||
public class SpringSslContext extends SslContext {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(SpringSslContext.class);
|
||||
|
||||
private String keyStoreType="jks";
|
||||
private String trustStoreType="jks";
|
||||
|
||||
|
@ -56,6 +59,8 @@ public class SpringSslContext extends SslContext {
|
|||
private String keyStorePassword;
|
||||
private String trustStorePassword;
|
||||
|
||||
private String crlPath;
|
||||
|
||||
/**
|
||||
* JSR-250 callback wrapper; converts checked exceptions to runtime exceptions
|
||||
*
|
||||
|
@ -92,9 +97,23 @@ public class SpringSslContext extends SslContext {
|
|||
if( ks ==null ) {
|
||||
return new ArrayList<TrustManager>(0);
|
||||
}
|
||||
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(trustStoreAlgorithm);
|
||||
tmf.init(ks);
|
||||
if (crlPath != null) {
|
||||
if (trustStoreAlgorithm.equalsIgnoreCase("PKIX")) {
|
||||
Collection<? extends CRL> crlList = loadCRL();
|
||||
|
||||
if (crlList != null) {
|
||||
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(ks, null);
|
||||
pkixParams.setRevocationEnabled(true);
|
||||
pkixParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(crlList)));
|
||||
tmf.init(new CertPathTrustManagerParameters(pkixParams));
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Revocation checking is only supported with 'trustStoreAlgorithm=\"PKIX\"'. Ignoring CRL: " + crlPath);
|
||||
}
|
||||
} else {
|
||||
tmf.init(ks);
|
||||
}
|
||||
return Arrays.asList(tmf.getTrustManagers());
|
||||
}
|
||||
|
||||
|
@ -219,4 +238,25 @@ public class SpringSslContext extends SslContext {
|
|||
this.secureRandomAlgorithm = secureRandomAlgorithm;
|
||||
}
|
||||
|
||||
public String getCrlPath() {
|
||||
return crlPath;
|
||||
}
|
||||
|
||||
public void setCrlPath(String crlPath) {
|
||||
this.crlPath = crlPath;
|
||||
}
|
||||
|
||||
private Collection<? extends CRL> loadCRL() throws Exception {
|
||||
if (crlPath == null) {
|
||||
return null;
|
||||
}
|
||||
Resource resource = Utils.resourceFromString(crlPath);
|
||||
InputStream is = resource.getInputStream();
|
||||
try {
|
||||
return CertificateFactory.getInstance("X.509").generateCRLs(is);
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* 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.security;
|
||||
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.jms.*;
|
||||
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
public class CRLTest {
|
||||
|
||||
BrokerService broker;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
broker = BrokerFactory.createBroker("xbean:src/test/resources/org/apache/activemq/security/activemq-revoke.xml");
|
||||
broker.waitUntilStarted();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
broker.stop();
|
||||
broker.waitUntilStopped();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCRL() throws Exception {
|
||||
System.setProperty("javax.net.ssl.trustStore", "src/test/resources/org/apache/activemq/security/client.ts");
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", "password");
|
||||
System.setProperty("javax.net.ssl.trustStoreType", "jks");
|
||||
System.setProperty("javax.net.ssl.keyStore", "src/test/resources/org/apache/activemq/security/activemq-revoke.jks");
|
||||
System.setProperty("javax.net.ssl.keyStorePassword", "password");
|
||||
System.setProperty("javax.net.ssl.keyStoreType", "jks");
|
||||
|
||||
|
||||
boolean failed = false;
|
||||
try {
|
||||
basicSendReceive("ssl://localhost:61617");
|
||||
} catch (Exception e) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
assertTrue("Send should have failed", failed);
|
||||
}
|
||||
|
||||
public void basicSendReceive(String uri) throws Exception {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(uri);
|
||||
Connection connection = factory.createConnection();
|
||||
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
connection.start();
|
||||
|
||||
String body = "hello world!";
|
||||
Queue destination = session.createQueue("TEST");
|
||||
MessageProducer producer = session.createProducer(destination);
|
||||
producer.send(session.createTextMessage(body));
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(destination);
|
||||
Message received = consumer.receive(2000);
|
||||
TestCase.assertEquals(body, ((TextMessage)received).getText());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN X509 CRL-----
|
||||
MIIBRzCBsQIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJBVTETMBEGA1UE
|
||||
CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
|
||||
MREwDwYDVQQDEwhhY3RpdmVtcRcNMTUwMzI3MTMwMjIwWhcNMTUwNDI2MTMwMjIw
|
||||
WjAUMBICAQEXDTE1MDMyNzEzMDEzM1qgDzANMAsGA1UdFAQEAgIQATANBgkqhkiG
|
||||
9w0BAQUFAAOBgQBLvpTwNFdjODFkJR1okloK5Qka6+Lzc5AwtqbYBlhQA1wCSpfB
|
||||
qzrUh43D97r88+w03mh1FI1PSKACXikHAgm2KZEiZrObIXYwdhJ7t1oSdGM6gPPS
|
||||
VQmgnvgbte3Mm8F4BoVhidp1gSe+f8RdRZYv1A+olREcz+lU7LxOIN6CpQ==
|
||||
-----END X509 CRL-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN X509 CRL-----
|
||||
MIIBWzCBxQIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJBVTETMBEGA1UE
|
||||
CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
|
||||
MREwDwYDVQQDEwhhY3RpdmVtcRcNMTUwMzMwMDk1ODI5WhcNMTUwNDI5MDk1ODI5
|
||||
WjAoMBICAQEXDTE1MDMyNzEzMDEzM1owEgIBAhcNMTUwMzMwMDk1MzU3WqAPMA0w
|
||||
CwYDVR0UBAQCAhAFMA0GCSqGSIb3DQEBBQUAA4GBADniQGR0r4x2zc33ozVkKpcm
|
||||
RUMD0JWMYzACvBEkP84ymms3x4jZzvaSgnkLtenktlOAWfAF4RSAqKS+2Vk1jaZm
|
||||
1drV1cGWnftHsLjvv9e226ROLQgZ+Wey0B3OyeiCubHVoZeyGEERoM4ZVrCxd5Oe
|
||||
Lfj+PMhnHGKD9c1MP1rR
|
||||
-----END X509 CRL-----
|
Binary file not shown.
|
@ -0,0 +1,43 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<!-- START SNIPPET: example -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:amq="http://activemq.apache.org/schema/core"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
|
||||
|
||||
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="broker1" useJmx="false" persistent="false">
|
||||
|
||||
<sslContext>
|
||||
<sslContext keyStore="org/apache/activemq/security/broker1.ks"
|
||||
keyStorePassword="password"
|
||||
trustStore="org/apache/activemq/security/activemq-revoke.jks"
|
||||
trustStorePassword="password"
|
||||
crlPath="org/apache/activemq/security/activemq-revoke.crl"/>
|
||||
</sslContext>
|
||||
|
||||
<!-- The transport connectors ActiveMQ will listen to -->
|
||||
<transportConnectors>
|
||||
<transportConnector name="ssl" uri="ssl://0.0.0.0:61617?transport.closeAsync=false&wantClientAuth=true&needClientAuth=true"/>
|
||||
</transportConnectors>
|
||||
|
||||
</broker>
|
||||
|
||||
</beans>
|
||||
<!-- END SNIPPET: example -->
|
|
@ -72,6 +72,7 @@ if [ -z "$ACTIVEMQ_QUEUEMANAGERURL" ]; then
|
|||
fi
|
||||
|
||||
# Set additional JSE arguments
|
||||
#ACTIVEMQ_SSL_OPTS="-Dcom.sun.security.enableCRLDP=true -Docsp.enable=true -Docsp.responderURL=http://ocsp.example.net:80"
|
||||
ACTIVEMQ_SSL_OPTS=""
|
||||
|
||||
# Uncomment to enable remote debugging
|
||||
|
|
Loading…
Reference in New Issue