We’re looking to set up an RFID reader to send MQTT messages to a HiveMQ Cloud broker.
For the reader to use a TLS connection, the specific following files are required:
- Device Certificate as ca.crt
- Device Private Key as client.key
- CA Certificate as client.crt
To easily test this connection, I’ve been using MQTT-SPY as it accepts the same inputs when the TLS mode is set to ‘CA certificate & client certificate/key’
I initially ran the suggested command from the pinned FAQ post (replacing the URL with my own):
openssl s_client -connect 4ad85b7fade04d07911be2ac1da2f5e4.s2.eu.hivemq.cloud:8883 -showcerts < /dev/null 2> /dev/null | sed -n '/BEGIN/,/END/p' > server.pem
but got the following error:
The system cannot find the path specified.
I then followed this blog post to generate the server.pem, client key and client certificate. When generating these files, on both commands I entered the same company and personal data requested, although I’m not certain if they should’ve been different (perhaps HiveMQ details when creating server.pem?).
Afterwards, I converted those files with openssl so they match the format I require. To do this, I ran the following commands:
openssl x509 -outform der -in server.pem -out ca.crt
openssl rsa -outform der -in mqtt-client-key.pem -out client.key
openssl x509 -outform der -in mqtt-client-cert.pem -out client.crt
This is likely where I am going wrong. Specifically I don’t think I should be converting the server.pem into a CA certificate. I initially tried to get an official CA certificate from gogetssl, but the CSR requires a domain name which my RFID reader won’t have.
Is it even possible to authenticate a HiveMQ connection without an official CA certificate? Throughout these guides I haven’t seen any mention of requesting a certificate from a CA, so I’m hoping that’s not the case.
Regardless, the connection always fails irrespective of TLS connection mode. Here’s the log output:
2022-02-10 15:26:05,977 WARN [MQTT Con: Stephen163429166] [MqttConnectionResultHandler ] - Connecting to HiveMQ Private Connection failed
MqttException (0) - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:664)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alert.createSSLException(Unknown Source)
at sun.security.ssl.TransportContext.fatal(Unknown Source)
at sun.security.ssl.TransportContext.fatal(Unknown Source)
at sun.security.ssl.TransportContext.fatal(Unknown Source)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(Unknown Source)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(Unknown Source)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(Unknown Source)
at sun.security.ssl.SSLHandshake.consume(Unknown Source)
at sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
at sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
at sun.security.ssl.TransportContext.dispatch(Unknown Source)
at sun.security.ssl.SSLTransport.decode(Unknown Source)
at sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:93)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650)
... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 15 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 21 more
I’ve also tried using just the CA certificate to secure the connection but that also fails to connect.
Communication with the broker using MQTT-CLI was successful, as shown below, but curiously the messages aren’t appearing when connected to the HiveMQ websocket client
I’ve been troubleshooting this for a good while now and I’m not sure what to try next, so any help with this would be greatly appreciated.