Question

I'm trying to set up ActiveMQ for mutual authentication, that the client will need a certificate in order to pass messages to the broker. I created a keystore and a truststore on the broker and exported a certificate that was copied to the client. On the client side I did the same, although I am using NMS so I am only using the exported certificate, which I added to the broker's truststore. I also added the certificate's to the other's Local Computer Trusted Root Certificates.
The broker's configuration has this:

<transportConnectors>  
  <transportConnector name="ssl" uri="ssl://0.0.0.0:61616"/>  
</transportConnectors>  
<sslContext>  
  <sslContext keyStore="file:${activemq.base}/conf/keystore.jks"  
    keyStorePassword="ksPass"  
    trustStore="file:${activemq.base}/conf/shared.ks"  
    trustStorePassword="ksPass"/>  
</sslContext>  
<plugins>  
 <jaasCertificateAuthenticationPlugin configuration="CertLogin" />  
</plugins>  

amq service wrapper.conf has
wrapper.java.additional.8=-Djava.security.auth.login.config="%ACTIVEMQ_CONF%/login.config"

${activemq.base}/conf/login.config

CertLogin {
 org.apache.activemq.jaas.TextFileCertificateLoginModule required
 debug=true
 org.apache.activemq.jaas.textfiledn.user="users.properties"
 org.apache.activemq.jaas.textfiledn.group="groups.properties";
};  

${activemq.base}/conf/users.properties has

user=CN=nms.client.170,\ OU=IT,\ O=MyOrg,\ L=Oslo,\ S=Oslo,\ C=NO  

${activemq.base}/conf/groups.properties has

admins=system  
users=system,user    

In the NMS client's appSettings I use this to connect:

< add key="jms.uri" value="ssl://brokeraddress.in.hosts:61616?needClientAuth=true&amp;wantClientAuth=true&amp;transport.clientCertSubject=nms.client.170&amp;transport.clientCertPassword=ksClientPw&amp;transport.clientCertFilename=C:\TestClient\client170.crt" />    

If I don't have the jaasCertificateAuthenticationPlugin in the broker I can connect via ssl, but with it (which is what I had in mind) I get an error, it fails in Apache.NMS.ActiveMQ.Connection
// Send the connection and see if an ack/nak is returned.
Response response = transport.Request(this.info, this.RequestTimeout);

Gets an ExeptionResponse: "java.lang.SecurityException: Unable to authenticate transport without SSL certificate."

The trace shows:

10:19:16,479 INFO  Client.MyTrace - BrokerUri set = ssl://brokeraddress.in.hosts:61616?transport.clientcertpassword=ksClient&transport.clientcertsubject=nms.client.170&needclientauth=true&wantclientauth=true&transport.clientcertfilename=C:\TestClient\client170.crt  
10:19:16,492 DEBUG Client.MyTrace - SetProperties called with target: ConnectionFactory, and prefix: connection.  
10:19:16,492 DEBUG Client.MyTrace - SetProperties called with target: ConnectionFactory, and prefix: nms.  
10:19:16,495 INFO  Client.MyTrace - Connecting to: ssl://brokeraddress.in.hosts:61616/?transport.clientcertpassword=ksClient&transport.clientcertsubject=nms.client.170&needclientauth=true&wantclientauth=true&transport.clientcertfilename=C:\TestClient\client170.crt  
10:19:16,497 DEBUG Client.MyTrace - Searching Assembly: Apache.NMS.ActiveMQ for factory of the id: ssl  
10:19:16,549 DEBUG Client.MyTrace - Found the Factory of type Apache.NMS.ActiveMQ.Transport.Tcp.SslTransportFactory for id: ssl  
10:19:16,552 DEBUG Client.MyTrace - Opening socket to: brokeraddress.in.hosts on port: 61616  
10:19:16,554 DEBUG Client.MyTrace - Connected to brokeraddress.in.hosts:61616 using InterNetwork protocol.  
10:19:16,562 DEBUG Client.MyTrace - Creating new instance of the SSL Transport.  
10:19:16,564 DEBUG Client.MyTrace - Creating Inactivity Monitor: 1  
10:19:16,677 DEBUG Client.MyTrace - Authorizing as Client for Server: brokeraddress.in.hosts  
10:19:16,679 DEBUG Client.MyTrace - Attempting to load Client Certificate from file := C:\TestClient\client170.crt  
10:19:16,682 DEBUG Client.MyTrace - Loaded Client Certificate := [Subject]  CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO [Issuer]  CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,684 DEBUG Client.MyTrace - Client is selecting a local certificate from 1 possibilities.  
10:19:16,684 DEBUG Client.MyTrace - Client has selected certificate with Subject = CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,969 DEBUG Client.MyTrace - ValidateServerCertificate: Issued By CN=brokeraddress.in.hosts, OU=DataCom, O=MyOrg, L=Oslo, S=Oslo, C=NO  
10:19:16,969 DEBUG Client.MyTrace - Server is Authenticated = True  
10:19:16,970 DEBUG Client.MyTrace - Server is Encrypted = True  
10:19:16,978 DEBUG Client.MyTrace - InactivityMonitor[1]: Read Check time interval: 30000  
10:19:16,978 DEBUG Client.MyTrace - InactivityMonitor[1]: Initial Delay time interval: 10000  
10:19:16,985 DEBUG Client.MyTrace - InactivityMonitor[1]: Write Check time interval: 10000  
10:19:19,017 DEBUG Client.MyTrace - Exception received in the Inactivity Monitor: Unable to read beyond the end of the stream.  
10:19:19,019 DEBUG Client.MyTrace - InactivityMonitor[1].Runner: Task Runner Shut Down  
10:19:19,019 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  
10:19:19,032 DEBUG Client.MyTrace - Connection[ID:EJPB-56409-635193299565662525-1:0]: Async exception with no exception listener: System.IO.EndOfStreamException: Unable to read beyond the end of the stream.  
 System.IO.BinaryRe.FillBuffer(Int32 numBytes)  
 System.IO.BinaryRe.ReadInt32()  
 Apache.NMS.Util.EnBinaryReader.ReadInt32() in c:\dev\NMS\src\main\csharp\Util\EndianBinaryReader.cs:line 135  
 Apache.NMS.ActiveMenWire.OpenWireFormat.Unmarshal(BinaryReader dis) in c:\dev\NMS.ActiveMQ\src\main\csharp\OpenWire\OpenWireFormat.cs:line 228  
 Apache.NMS.ActiveMansport.Tcp.TcpTransport.ReadLoop() in c:\dev\NMS.ActiveMQ\src\main\csharp\Transport\Tcp\TcpTransport.cs:line 295  
10:19:19,035 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: MutexTransport  
10:19:19,035 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: WireFormatNegotiator  
10:19:19,036 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: InactivityMonitor  
10:19:19,036 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  
10:19:19,037 DEBUG Client.MyTrace - TransportFilter disposing of next Transport: SslTransport  
10:19:19,071 INFO  Client.MyTrace - Connection[ID:SUSSDEV2-56409-635193299565662525-1:0]: Closing Connection Now.  
10:19:19,073 DEBUG Client.MyTrace - Connection[ID:SUSSDEV2-56409-635193299565662525-1:0]: Disposing of the Transport.  
10:19:19,073 DEBUG Client.MyTrace - InactivityMonitor[1]: Stopped Monitor Threads.  

and in the broker it says:

INFO | jvm 1 | 10:18:20 | WARN | Failed to add Connection ID:EJPB-56409-635193299565662525-1:0, reason: java.lang.SecurityException: Unable to authenticate transport without SSL certificate.  
INFO | jvm 1 | 10:18:22 | INFO | Stopping tcp://192.168.5.170:56408 because Failed with SecurityException: Unable to authenticate transport without SSL certificate.  

Ok, what am I missing? It says "transport without SSL certificate", but it selects it during the client's connection and it is in both the broker's truststore and Root Certs.

Using NMS 1.6.0 and activeMQ 5.8.0.
I also tried a simple client in java with the same result.

Exception in thread "main" javax.jms.JMSException: Unable to authenticate transport without SSL certificate.  
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:49)  
    at org.apache.activemq.ActiveMQConnection.syncSendPacket  (ActiveMQConnection.java:1295)  
    at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent  (ActiveMQConnection.java:1392)  
    at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:504)  
    at com.atest.jms.Client.main(Client.java:69)  
Caused by: java.lang.SecurityException: Unable to authenticate transport without SSL certificate.  
    at org.apache.activemq.security.JaasCertificateAuthenticationBroker.addConnection(JaasCertificateAuthenticationBroker.java:74)  
    at org.apache.activemq.broker.MutableBrokerFilter.addConnection(MutableBrokerFilter.java:91)  
    at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:766)  
    at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:79)  
    at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)  
    at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:329)  
    at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:184)  
    at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)  
    at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)  
    at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:288)  
    at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)  
    at org.apache.activemq.transport.tcp.SslTransport.doConsume(SslTransport.java:91)  
    at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:214)  
    at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)  
    at java.lang.Thread.run(Unknown Source)    

Anyone has any ideas? Thanks.

Edit nov 12th

Ok, I tried again. I see I hadn't added to the broker's transportConnector ssl:

<transportConnector name="ssl" uri="ssl://0.0.0.0:61616?needClientAuth=true"/>  

I tried the java client and it could send, but I'm still getting error for the NMS client (same config):

15:28:14,044 ERROR Test_DataCom.MyTrace - Exception: A call to SSPI failed, see inner exception.
15:28:14,045 ERROR Test_DataCom.MyTrace - Inner exception: An unknown error occurred while processing the certificate
15:28:14,045 ERROR Test_DataCom.MyTrace - Authentication failed - closing the connection.  

and at the broker I get null cert chain

INFO | jvm 1 | 15:28:13 | ERROR | Could not accept connection from tcp://192.168.50.170:61978: javax.net.ssl.SSLHandshakeException: null cert chain

I have the certs in each other's truststore and Local Computer Trusted Root CA... what more is needed? Where should it find the cert chain for self signed certs if not there?

Was it helpful?

Solution

OK, I seem to have it now. After re-reading this comment I exported the client cert and key to a PKCS file and imported it to Current User Certification Store in Windows.
C:\> keytool -v -importkeystore -srckeystore client-keystore.jks -srcalias client -destkeystore client.p12 -deststoretype PKCS12

Then I used this url-encoded connection:
<add key="jms.uri" value="ssl://brokeraddress.in.hosts:61616?needClientAuth=true&amp;wantClientAuth=true&amp;transport.clientCertSubject=CN%3Dnms.client.170%2C+OU%3DIT%2C+O%3DMyOrg%2C+L%3DOslo%2C+S%3DOslo%2C+C%3DNO" />

I also had
${activemq.base}/conf/users.properties: user=CN=nms.client.170,\ OU=IT,\ O=MyOrg,\ L=Oslo,\ S=Oslo,\ C=NO, trying to escape the spaces, I removed those and corrected S to ST, just as keytool reports the Owner line. I checked, and that gives error otherwise.

Corrected ${activemq.base}/conf/users.properties:
user=CN=nms.client.170, OU=IT, O=MyOrg, L=Oslo, ST=Oslo, C=NO

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top