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