-
Notifications
You must be signed in to change notification settings - Fork 921
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ARTEMIS-2704]: Provide a SPI to manage and cache SSLContext.
* Adding a new SPI to allow for SSLContext reuse accross the broker. * Providing a default behaviour similar to the existing one. [ARTEMIS-2718]: Take advantage of ARTEMIS-2704 to cache SSLContexts. * Adding a cache for SSLContexts and reusing them accross acceptors and connectors. Issue: https://issues.apache.org/jira/browse/ARTEMIS-2704 Issue: https://issues.apache.org/jira/browse/ARTEMIS-2718
- Loading branch information
1 parent
79fef2f
commit a88815d
Showing
10 changed files
with
319 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
...ain/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingSSLContextFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright 2020 The Apache Software Foundation. | ||
* | ||
* Licensed 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.core.remoting.impl.ssl; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import javax.net.ssl.SSLContext; | ||
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; | ||
import org.apache.activemq.artemis.utils.ConfigurationHelper; | ||
|
||
/** | ||
* SSLContextFactory providing a cache of SSLContext. | ||
* Since SSLContext should be reused instead of recreated and are thread safe. | ||
* To activate it uou need to allow this Service to be discovered by having a | ||
* <code>META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory</code> | ||
* file with <code> org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory</code> | ||
* as value. | ||
*/ | ||
public class CachingSSLContextFactory extends DefaultSSLContextFactory { | ||
|
||
private static final Map<String, SSLContext> SSL_CONTEXTS = Collections.synchronizedMap(new HashMap<>()); | ||
|
||
@Override | ||
public void clearSSLContexts() { | ||
SSL_CONTEXTS.clear(); | ||
} | ||
|
||
@Override | ||
public SSLContext getSSLContext(Map<String, Object> configuration, | ||
String keystoreProvider, String keystorePath, String keystorePassword, | ||
String truststoreProvider, String truststorePath, String truststorePassword, | ||
String crlPath, String trustManagerFactoryPlugin, boolean trustAll) throws Exception { | ||
String sslContextName = getSSLContextName(configuration, keystorePath, keystoreProvider, truststorePath, truststoreProvider); | ||
if (!SSL_CONTEXTS.containsKey(sslContextName)) { | ||
SSL_CONTEXTS.put(sslContextName, createSSLContext(configuration, | ||
keystoreProvider, keystorePath, keystorePassword, | ||
truststoreProvider, truststorePath, truststorePassword, | ||
crlPath, trustManagerFactoryPlugin, trustAll)); | ||
} | ||
return SSL_CONTEXTS.get(sslContextName); | ||
} | ||
|
||
/** | ||
* Obtain the sslContextName : | ||
* - if available the 'sslContext' from the configuration | ||
* - otherwise if available the keyStorePath + '_' + keystoreProvider | ||
* - otherwise the truststorePath + '_' + truststoreProvider. | ||
* @param configuration | ||
* @param keyStorePath | ||
* @param keystoreProvider | ||
* @param truststorePath | ||
* @param truststoreProvider | ||
* @return the ley associated to the SSLContext. | ||
*/ | ||
protected String getSSLContextName(Map<String, Object> configuration, String keyStorePath, String keystoreProvider, String truststorePath, String truststoreProvider) { | ||
String sslContextName = ConfigurationHelper.getStringProperty(TransportConstants.SSL_CONTEXT_PROP_NAME, null, configuration); | ||
if (sslContextName == null) { | ||
if (keyStorePath != null) { | ||
return keyStorePath + '_' + keystoreProvider; | ||
} | ||
return truststorePath + '_' + truststoreProvider; | ||
} | ||
return sslContextName; | ||
} | ||
|
||
@Override | ||
public int getPriority() { | ||
return 10; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...ain/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultSSLContextFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright 2020 The Apache Software Foundation. | ||
* | ||
* Licensed 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.core.remoting.impl.ssl; | ||
|
||
import java.util.Map; | ||
import javax.net.ssl.SSLContext; | ||
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; | ||
import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory; | ||
import org.apache.activemq.artemis.utils.ConfigurationHelper; | ||
|
||
/** | ||
* Simple SSLContextFactory for use in NettyConnector and NettyAcceptor. | ||
*/ | ||
public class DefaultSSLContextFactory implements SSLContextFactory { | ||
|
||
|
||
@Override | ||
public SSLContext getSSLContext(Map<String, Object> configuration, | ||
String keystoreProvider, String keystorePath, String keystorePassword, | ||
String truststoreProvider, String truststorePath, String truststorePassword, | ||
String crlPath, String trustManagerFactoryPlugin, boolean trustAll) throws Exception { | ||
return createSSLContext(configuration, | ||
keystoreProvider, keystorePath, keystorePassword, | ||
truststoreProvider, truststorePath, truststorePassword, | ||
crlPath, trustManagerFactoryPlugin, trustAll); | ||
} | ||
|
||
protected SSLContext createSSLContext(Map<String, Object> configuration, | ||
String keystoreProvider, String keystorePath, String keystorePassword, | ||
String truststoreProvider, String truststorePath, String truststorePassword, | ||
String crlPath, String trustManagerFactoryPlugin, boolean trustAll) throws Exception { | ||
if (log.isDebugEnabled()) { | ||
final StringBuilder builder = new StringBuilder(); | ||
configuration.forEach((k, v) -> builder.append("\r\n").append(k).append("=").append(v)); | ||
log.debugf("Creating SSL context with configuration %s", builder.toString()); | ||
} | ||
boolean useDefaultSslContext = ConfigurationHelper.getBooleanProperty(TransportConstants.USE_DEFAULT_SSL_CONTEXT_PROP_NAME, TransportConstants.DEFAULT_USE_DEFAULT_SSL_CONTEXT, configuration); | ||
if (useDefaultSslContext) { | ||
return SSLContext.getDefault(); | ||
} | ||
return new SSLSupport() | ||
.setKeystoreProvider(keystoreProvider) | ||
.setKeystorePath(keystorePath) | ||
.setKeystorePassword(keystorePassword) | ||
.setTruststoreProvider(truststoreProvider) | ||
.setTruststorePath(truststorePath) | ||
.setTruststorePassword(truststorePassword) | ||
.setTrustAll(trustAll) | ||
.setCrlPath(crlPath) | ||
.setTrustManagerFactoryPlugin(trustManagerFactoryPlugin) | ||
.createContext(); | ||
} | ||
@Override | ||
public int getPriority() { | ||
return 5; | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
...nt/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright 2020 The Apache Software Foundation. | ||
* | ||
* Licensed 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.spi.core.remoting.ssl; | ||
|
||
import java.util.Map; | ||
import javax.net.ssl.SSLContext; | ||
import org.jboss.logging.Logger; | ||
|
||
/** | ||
* Service interface to create a SSLContext for a configuration. | ||
* This is NOT used by OpenSSL. | ||
* To create and use your own implementation you need to create a file | ||
* <code>META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory</code> | ||
* in your jar and fill it with the full qualified name of your implementation. | ||
*/ | ||
public interface SSLContextFactory extends Comparable<SSLContextFactory> { | ||
Logger log = Logger.getLogger(SSLContextFactory.class); | ||
|
||
/** | ||
* Obtain a SSLContext from the configuration. | ||
* @param configuration | ||
* @param keystoreProvider | ||
* @param keystorePath | ||
* @param keystorePassword | ||
* @param truststoreProvider | ||
* @param truststorePath | ||
* @param truststorePassword | ||
* @param crlPath | ||
* @param trustManagerFactoryPlugin | ||
* @param trustAll | ||
* @return a SSLContext instance. | ||
* @throws Exception | ||
*/ | ||
SSLContext getSSLContext(Map<String, Object> configuration, | ||
String keystoreProvider, String keystorePath, String keystorePassword, | ||
String truststoreProvider, String truststorePath, String truststorePassword, | ||
String crlPath, String trustManagerFactoryPlugin, boolean trustAll) throws Exception; | ||
|
||
default void clearSSLContexts() { | ||
} | ||
|
||
/** | ||
* The priority for the SSLContextFactory when resolving the service to get the implementation. | ||
* This is used when selecting the implementation when several implementations are loaded. | ||
* The highest priority implementation will be used. | ||
* @return the priority. | ||
*/ | ||
int getPriority(); | ||
|
||
@Override | ||
default int compareTo(SSLContextFactory other) { | ||
return this.getPriority() - other.getPriority(); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...ain/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactoryProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright 2020 The Apache Software Foundation. | ||
* | ||
* Licensed 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.spi.core.remoting.ssl; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.ServiceLoader; | ||
|
||
/** | ||
* Provider that loads the SSLContextFactory services and return the one with the highest priority. | ||
* This is only used to provide SSLContext, so it doesn't support OpenSSL. | ||
*/ | ||
public class SSLContextFactoryProvider { | ||
private static final SSLContextFactory factory; | ||
static { | ||
ServiceLoader<SSLContextFactory> loader = ServiceLoader.load(SSLContextFactory.class, Thread.currentThread().getContextClassLoader()); | ||
final List<SSLContextFactory> factories = new ArrayList<>(); | ||
loader.forEach(factories::add); | ||
Collections.sort(factories); | ||
factory = factories.get(factories.size() - 1); | ||
} | ||
/** | ||
* @return the SSLContextFactory with the higher priority. | ||
*/ | ||
public static SSLContextFactory getSSLContextFactory() { | ||
return factory; | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
...ces/META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultSSLContextFactory |
Oops, something went wrong.