Hello all, I've got ActiveMQ classic 5.18.4 setup to require mutual client
authentication. When I create a keystore with a single private key and an
additional certificate and it generally works great. When I instead try to
use a single key for both the client and the server I get the following
error:
ERROR | Failed to load: URL [file:/etc/activemq/activemq.xml], reason:
Error creating bean with name 'invokeStart' defined in URL
[file:/etc/activemq/activemq.xml]: Invocation of init method failed; nested
exception is java.lang.IllegalStateException: KeyStores with multiple
certificates are not supported on the base class
org.eclipse.jetty.util.ssl.SslContextFactory. (Use
org.eclipse.jetty.util.ssl.SslContextFactory$Server or
org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'invokeStart' defined in URL
[file:/etc/activemq/activemq.xml]: Invocation of init method failed; nested
exception is java.lang.IllegalStateException: KeyStores with multiple
certificates are not supported on the base class
org.eclipse.jetty.util.ssl.SslContextFactory. (Use
org.eclipse.jetty.util.ssl.SslContextFactory$Server or
org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:209)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:936)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
~[spring-context-5.3.33.jar:5.3.33]
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591)
~[spring-context-5.3.33.jar:5.3.33]
at
org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64)
~[xbean-spring-4.24.jar:4.24]
at
org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52)
~[xbean-spring-4.24.jar:4.24]
at
org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104)
~[activemq-spring-5.18.4.jar:5.18.4]
at
org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104)
[activemq-spring-5.18.4.jar:5.18.4]
at
org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67)
[activemq-spring-5.18.4.jar:5.18.4]
at
org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71)
[activemq-broker-5.18.4.jar:5.18.4]
at
org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54)
[activemq-broker-5.18.4.jar:5.18.4]
at
org.apache.activemq.console.command.StartCommand.runTask(StartCommand.java:87)
[activemq-console-5.18.4.jar:5.18.4]
at
org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63)
[activemq-console-5.18.4.jar:5.18.4]
at
org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:154)
[activemq-console-5.18.4.jar:5.18.4]
at
org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:63)
[activemq-console-5.18.4.jar:5.18.4]
at
org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:104)
[activemq-console-5.18.4.jar:5.18.4]
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method) ~[?:?]
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[?:?]
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.activemq.console.Main.runTaskClass(Main.java:262)
[activemq.jar:5.18.4]
at org.apache.activemq.console.Main.main(Main.java:115)
[activemq.jar:5.18.4]
Caused by: java.lang.IllegalStateException: KeyStores with multiple
certificates are not supported on the base class
org.eclipse.jetty.util.ssl.SslContextFactory. (Use
org.eclipse.jetty.util.ssl.SslContextFactory$Server or
org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
at
org.eclipse.jetty.util.ssl.SslContextFactory.newSniX509ExtendedKeyManager(SslContextFactory.java:1289)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.ssl.SslContextFactory.getKeyManagers(SslContextFactory.java:1271)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.ssl.SslContextFactory.load(SslContextFactory.java:373)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.ssl.SslContextFactory.doStart(SslContextFactory.java:244)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.server.SslConnectionFactory.doStart(SslConnectionFactory.java:97)
~[jetty-server-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:169)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:323)
~[jetty-server-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81)
~[jetty-server-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:234)
~[jetty-server-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at org.eclipse.jetty.server.Server.doStart(Server.java:401)
~[jetty-server-9.4.54.v20240208.jar:9.4.54.v20240208]
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73)
~[jetty-util-9.4.54.v20240208.jar:9.4.54.v20240208]
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method) ~[?:?]
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[?:?]
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at
org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:285)
~[spring-core-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.config.MethodInvokingBean.invokeWithTargetException(MethodInvokingBean.java:123)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.config.MethodInvokingFactoryBean.afterPropertiesSet(MethodInvokingFactoryBean.java:108)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
~[spring-beans-5.3.33.jar:5.3.33]
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
~[spring-beans-5.3.33.jar:5.3.33]
... 27 more
Here's my listener section for activemq:
<sslContext>
<sslContext
keyStore="/etc/activemq-secrets/amq.p12"
keyStorePassword="${TLS_KS_PWD}"
trustStore="/etc/activemq-secrets/amq.p12"
trustStorePassword="${TLS_KS_PWD}" trustStoreType="pkcs12"
keyStoreType="pkcs12"/>
</sslContext>
<transportConnectors>
<!-- DOS protection, limit concurrent connections to
1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="ssl://
0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&needClientAuth=true
"/>
</transportConnectors>
and
<bean id="SecureConnector" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="Server" />
<constructor-arg>
<bean id="handlers"
class="org.eclipse.jetty.util.ssl.SslContextFactory">
<property name="keyStorePath"
value="/etc/activemq-secrets/amq.p12" />
<property name="keyStorePassword"
value="${TLS_KS_PWD}" />
<property name="keyStoreType"
value="pkcs12" />
<property name="trustStorePath"
value="/etc/activemq-secrets/amq.p12" />
<property name="trustStorePassword"
value="${TLS_KS_PWD}" />
<property name="trustStoreType"
value="pkcs12" />
<property name="needClientAuth"
value="true" />
<property
name="endpointIdentificationAlgorithm">
<null></null>
</property>
</bean>
</constructor-arg>
<property name="port" value="8162" />
</bean>
I checked the keystore, it only has one entry:
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: broker
Creation date: May 31, 2024
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner:
Issuer: CN=enterprise-ca
Serial number: 7eeb615da33783cc236af3ee59b0290e
Valid from: Fri May 31 09:46:54 EDT 2024 until: Sat May 31 09:46:54 EDT 2025
Certificate fingerprints:
SHA1: 04:F5:37:E1:A7:FF:23:34:C3:84:F3:30:C5:6E:A6:CC:DE:58:75:07
SHA256:
9F:73:81:57:10:6A:BD:F0:ED:25:49:84:A4:0F:9A:51:F2:EF:C2:D7:5F:38:47:02:B7:EA:A6:98:4C:A5:48:62
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 9F F4 3E 45 2B 01 C8 17 BC 56 A8 5F F8 F2 7F AB ..>E+....V._....
0010: FD 14 D0 DE ....
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
#3: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
serverAuth
clientAuth
]
#4: ObjectId: 2.5.29.17 Criticality=true
SubjectAlternativeName [
DNSName: amq.openunison.svc
DNSName: amq-backup.openunison.svc
DNSName: amq.apps.192-168-2-89.nip.io
DNSName: amq.apps.192-168-2-14.nip.io
]
*******************************************
*******************************************
Thanks
Marc