LiamBindle / MQTT-C

A portable MQTT C client for embedded systems and PCs alike.
https://liambindle.ca/MQTT-C
MIT License
766 stars 269 forks source link

Unable to connect openssl_publisher example to HiveMQ #186

Closed mpfj closed 8 months ago

mpfj commented 8 months ago

Using the MQTTC code, I can successfully connect the openssl_publisher to the "default" broker at test.mosquitto.org.

Using the mosquitto_pub tool, I can also publish a message to the HiveMQ broker using:-

mosquitto_pub -h XXXXXXXXXXXX.s2.eu.hivemq.cloud -u nano-mpfj -P XXXXXX -t "test/topic" -m "TLS works with client PEM" -p 8883 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'test/topic', ... (25 bytes))
Client (null) sending DISCONNECT

Note that there's no need to provide a CA file ... it all works fine without specify either a CA file or an key files.

So I have then commented out the "CA file" lines in openssl_publisher.[ch] and hardcoded the username and password. Try to connect to HiveMQ as follows:-

$ ./test "XXXXXXXXXXXX.s2.eu.hivemq.cloud" 8883 datetime 
./test is ready to begin publishing the time.
Press ENTER to publish the current time.
Press CTRL-D (or any other key) to exit.

error: MQTT_ERROR_SOCKET_ERROR
./test published : "The time is 2024-01-14 20:59:47"
$ 

So it appears to connect to the server but when the topic is published, the socket is closed. The username & password are correct (as proved by the mosquitto_pub tool). And not needing any certificate files is also confirmed (again by the mosquityo tool).

Can anyone shed light on what might be wrong ?

mpfj commented 8 months ago

So I've now added some extra debug and the CONNACK reply is coming back as:-

20 02 00 05

The reason code is [0x05 Connection Refused, not authorized] which is very confusing as the mosquitto test uses the same username & password but that works !!

Interestingly I don't get reason code 0x04 "Connection Refused, bad user name or password" so I'm guessing the login is correct. Does that point to a certificate issue ?

mpfj commented 8 months ago

Finally worked it out from this link

HiveMQ requires the TLS SNI extension to be used so before BIO_do_connect(), I added the following:-

res = SSL_set_tlsext_host_name(ssl, szHost);
if(res != 1)
    return FALSE;

Hope that helps someone else!!

DqVuongg commented 2 months ago

@mpfj Can you show detail where to fix this issue, i think i have the same problem with openssl and mbedtls

mpfj commented 2 months ago

This fix was done in my own application, not in the MQTT code itself. So I used to have...

BIO_set_conn_hostname(m_pBIO, szHost);
BIO_set_conn_port(m_pBIO, szPort);
BIO_do_connect(m_pBIO);

... which didn't work. But when I changed it to...

BIO_set_conn_hostname(m_pBIO, szHost);
BIO_set_conn_port(m_pBIO, szPort);
SSL_set_tlsext_host_name(ssl, szHost);
BIO_do_connect(m_pBIO);

... it worked.