MQTT TLS certificate pinning - incorrect hashes

Hi

I’m a virgin OH user, and this is virgin post, so be gentle :wink:

  • but let me know if this is misplaced post or if i need to provide further info.
  • Platform information:
    • Openhabian running on RPi 3b+
    • openHAB version: 2.5 M1
    • Mosquitto 3.1 broker
    • MQTT binding version: 2.4
  • Issue of the topic: please be detailed explaining your issue
    I have a functioning MQTT network with TLS already setup, but the OH MQTT binding doesn’t connect to the broker using certificate authentication. I connects fine if i use user/password, but I’d like it to use certificates.
    So I’m assuming its an issue with the hash’es that i need to use in the binding configuration?
    It does pin some sort of hash, when i try to connect, but the format is wrong (no hashname - only hash value). I can’t identify the hash value from any of the certificates or keys either, so i do not know where these are being pinned from? I have tried using SHA-1, SHA-256 & SHA-512 hashnames in front of the auto-pinned hash values, but no joy.
    I have the CA cert. in the ca_certificates folder, I have the broker certificate & .key under certs folder in /etc/mosquitto. I have tried entering certificate and public key hashes from both the CA certificate and the broker certificate, but neither lets me connect the openhab binding to the broker.
    I have extracted the public keys using windows cert GUI and used online hashing tools to get the public keys hashes (all provide the same hashes for the keys), and used the certificate hashes provided by certutil.exe in windows.
    I’m obviously doing something wrong, so if someone could advise me to which certificate and public hash key I need to use, and how to obtain the hashes, I’d be grateful.

Best regards
Z

I don’t think the binding supports certificate authentication.

When I first tested the MQTT 2 binding I wasn’t able to get it to use TLS reliably (it would work until the next time I restart OH). There may be a bug that has been fixed since then to fix it. I’m pretty sure I filed an issue.

If this is possible, I suspect you are the only person who has tried doing it until now. Before OH 2.4 all we had was the MQTT 1.x binding which does not support TLS or certificates at all. Most of us have had our MQTT already set up without certs before that.

First off, thanks for taking the time to help :slightly_smiling_face:
When trawling the community looking for answers I’ve stumbled on your replies and help to others alot - you really add a lot of value to this community, and I greatly respect that!

Blockquote I don’t think the binding supports certificate authentication.
Ok? In the docs and in the paper UI there is the option of setting “Certificate hash” and “public key hash” - I figured they must be for certificate authentication, if not so, what are they for??

Reading the descriptions in PaperUI:

  • When certificate pinning and SSL are turned on, OH will disconnect from the broker if it presents a different certificate than the pinned one.

If this and SSL is set: After the next connection has been successfully established, the certificate is pinned. The connection will be refused if another certificate is used. Clear certificate to allow a new certificate for the next connection attempt. This option can increase security.

  • The hash is used with certificate pinning to help verify that the brokers certificate hasn’t changed

If certificatepin is set this hash is used to verify the connection. Clear to allow a new certificate pinning on the next connection attempt. If empty will be filled automatically by the next successful connection. An example input would be SHA-256:83F9171E06A313118889F7D79302BD1B7A2042EE0CFD029ABF8DD06FFA6CD9D3.

  • The same goes for the public key stuff. This is all related to SSL, not authentication, and these settings will cause OH to refuse to connect if the broker’s certificates have changed.

If this and SSL is set: After the next connection has been successfully established, the public key of the broker is pinned. The connection will be refused if another public key is used. Clear publickey to allow a new public key for the next connection attempt. This option can increase security.

If publickeypin is set this hash is used to verify the connection. Clear to allow a new public key pinning on the next connection attempt. If empty will be filled automatically by the next successful connection. An example input would be SHA-256:83F9171E06A313118889F7D79302BD1B7A2042EE0CFD029ABF8DD06FFA6CD9D3

I’m running MQTT 2.5 M1 and these descriptions may have been added after 2.4. But the tl;dr is this is just a way for OH to detect that the SSL/TLS certificates on the broker have changed. They have nothing to do with using a cert to authenticate OH with the broker.

Confirmation bias 1, me 0

Really appreciate the clarification! :+1:
Good day to you!

I attach my question to this post, that seems less or more, related.
I’m trying to configure connection between my OH instance and Mosquitto with secure connection, they’re 2 docker container on the same host, and I know it may sound useless, but it’s just for learning purpose:
I created all the necessary certificates, configured Mosquitto container:

mqtt:
container_name: Mosquitto
image: eclipse-mosquitto
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/log:/mosquitto/log
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/certs:/mosquitto/certs
- ./mosquitto/ca_certificates:/mosquitto/ca_certificates
- /etc/localtime:/etc/localtime:ro
ports:
- “8883:8883”
- “9001:9001”

mosquitto.conf:

Password and ACL
password_file /mosquitto/config/conf.d/userpass.pw
acl_file /mosquitto/config/conf.d/useracl.acl
allow_anonymous false
Port to use for the default listener.
port 8883
Security
cafile /mosquitto/ca_certificates/ca.crt
keyfile /mosquitto/certs/server.key
certfile /mosquitto/certs/server.crt
tls_version tlsv1.2
require_certificate false

Configured the MQTT broker settings in OH and everything works fine until you restart OH container.
I noticed that when certificate pinning is active, in the MQTT Broker settings of OH, and you restart the container, it won’t connect anymore, until you blank the certificate hash.
Once the hash is blanked the connection will work again, but the strange thing is that the new hash is the same as the old one.

The logs report this:
java.security.NoSuchAlgorithmException: Algorithm is missing

I found this post:


but it’s not clear why with cert pinning enabled the connection will fail

This looks like something that needs an issue filed to correct. Please follow How to file an Issue and file an issue at the openhab-addons repo.

Just in case anyone stumples upon this thread I have after almost 2 years figured out what was MY mistake in MY config - that is to say, this may not apply to you:
It turned out when I made certificates for my MQTT broker (Mosquitto), the COMMON NAME on my server certificate did not match the connection description on my client certificates - here is the reference (under " Problems I Encountered and Notes" section", pt.1): Mosquitto SSL Configuration -MQTT TLS Security

To solve this, when making a certificate for the broker i use my FQDN of the device running the broker for the common name on my broker certificate, and match that with the connection name on my client’s configuration when specifying the broker connection, as also seen in above reference.

Hope this helps someone in the future.

1 Like

This does not seem to solve it. The fact that it works during setup and breaks only after a restart suggests that it’s really got nothing to do with something fixed as common-name mismatch.

The exception is actually generated as part of the binding in handler/BrokerHandler.java#L161 and handler/BrokerHandler.java#L179. This seems to happen when the certificate hash that is stored in the config can’t be split. My theory is that this stored config is for some reason non-persistent across restarts. I’m not a JAVA developer so my knowledge is really limited. @Kai, would you be able to maybe land a hand so this bug can be squashed after more than two years and after it continues in OH3?

Adding to my post above, I believe I have a workaround. The bug is that the code stores the hashes in the config without the “SHA-256:” part, but expects it when it recalls it, so just add that prefix to whatever is in the hash text field:

  • Start with a disabled pinning and a cleared fingerprint field

  • Enable pinning, save the form and reload the page. you should have the hash populated in the hash box.

  • Edit the hash and prefix it with SHA-256:, then save the form i.e.:
    3276DA19794E43BD42DDEA202DB16636F4DE031CA948BE81C567617F289FF792
    becomes
    SHA-256:3276DA19794E43BD42DDEA202DB16636F4DE031CA948BE81C567617F289FF792

Fixing the issue is probably either removing the split, or figuring out why the hash type is not stored in the config in the 1st place as it’s supposed to.

1 Like

Thanks for you workaround an issue 7382 on Github.

1 Like