MQTT PSK Implementation

I have a Mosquitto MQTT Broker set up using TLS via Pre-Shared Key. I’ve tested it by running a mosquitto client remotely and the broker itself is functioning properly. I’ve also tested MQTT on a Flexy with standard unencrypted MQTT on port 1883, based on the example BASIC code found here:
https://tools.ewonsupport.biz/mqtt/program.txt

So, what I am attempting to do now is modify the BASIC code from the example to change the port to 8883 and include the proper PSK information.

Below is what I have at the moment (only pasting in the portions of code that I’m modifying):
//######## CONFIG ###############
MQTTBrokerURL$ = “public IP address”
MQTTPort$ = “8883”
MQTTpsk_identity$ = “PSK Hint”
MQTTpsk$ = “hexadecimal PSK”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = "Hello From Flexy " + SerNum$

//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1

//######## END CONFIG ###############

Last_ConnStatus% = 0
//Configure MQTT Connection parameters

CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “PSK”, MQTTpsk$
MQTT “SETPARAM”, “PSK-IDENTITY”, MQTTpsk_identity$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log("[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0
//When receiving a message from Broker, “GOTO MQTTRECEIVEMSG”
ONMQTT “GOTO MQTTRECEIVEMSG”
ONTIMER 1, “GOTO SENDDATA”
TSET 1,30 //publish every 30 seconds
END

When I run this, I receive the error:
Operation failed (28) 38: MQTT “SETPARAM”, “PSK”, MQTTpsk$

So, my assumption is that “PSK” isn’t the proper parameter name to use here, but I haven’t been able to find any documentation about implementing TLS-PSK in BASIC. Any help would be awesome!

Hi @Rob_Cunningham,

TLS doesn’t use a PSK. It uses certificates. (Certificates can have passwords if maybe that’s what you’re referring to.)

Here is an example of setting up MQTT over TLS:

https://techforum.ewon.biz/thread-786.html

The example uses Azure. I’m not sure how you are planning on creating your certificates, but you will want to consider this post also if you are creating certificates using openssll:

https://techforum.ewon.biz/thread-985.html

Hi Kyle,

I’m definitely not an expert on this…it’s pretty far out of my wheelhouse! But, MQTT (or at least Mosquitto) definitely supports TLS-PSK. My Googling has determined that it doesn’t have a very high adoption base though, and I’m not sure if that means it’s deprecated or it’s very new and hasn’t gained wide-use as of yet. I would vastly prefer PSK if I could get it to work, because it seems much easier than having to deal with certs.

Here is the Mosquitto manual page and Authentication options are laid out near the top:

Additionally, here’s a blog post about TLS-PSK…though it’s largely over my head!:

Here is my proof-of-concept using Mosquitto’s _pub & _sub client commands:

Hi @Rob_Cunningham,

Sorry about that, you are correct. I’ve never seen it used, so I thought maybe you were getting mixed up with a certificate password. I’m not sure if this is supported by the Ewon, but I will check. In my opinion, it doesn’t look significantly easier to deal with. Setting up the certificate is just a few commands that can be copied and pasted into the terminal and then you need to transfer the cert to the client. But I am interested if this will work or not. It’s apparently less resource intensive which could possibly be a benefit if it’s also secure enough.

Thanks,

Kyle

No worries! I’m still not convinced that I’m not mixed up!

I could definitely get a cert set up, but for some reason OpenSSL was fighting me so I figured I’d try this route. It does seem a tad easier because then there’s no transfering of a cert file…just copy/paste in the identity and key. But you’re right, it wouldn’t make a whole heck of a lot of difference either way…I just find it a bit easier to wrap my head around this concept.

No, you weren’t mixed up. I was. However, I did look into it and it doesn’t appear that TLS-PSK is supported on the Ewon at this point. I’ve found that working with certificates can be intimidating at first, but once you have set it up a few times, it will be very easy. Let me know if you have any questions about the process and I can try to help.

No problem, I’m sure I can noodle my way through it!

Out of curiosity (keep in mind, I’m no software programmer), what is the limitation for supporting TLS-PSK, or any other type of feature, for that matter? Is it something that isn’t supported by BASIC as a whole, or something that eWon would need to develop the function internally and it would be included somewhere in the background? In the sample code, I see that there is a command called MQTT and then you pass different parameters to it. Is the function running in the background that defines the MQTT command something that eWon developed?

The only reason I ask is I was having trouble finding anything regarding TLS-PSK implementation with BASIC in general…though it’s very difficult to Google “BASIC” and find results pertaining to the programming language!

I honestly am not sure why it’s not supported, but I would guess that the Flexy has a minimal build of openssl and TLS-PSK wasn’t included because there wasn’t a demand at the time. I will try to find out. I don’t think it has anything to do with BASIC. The MQTT functionality is built into the Flexy with APIs for BASIC and JAVA. Here is the documentation for the BASIC commands. We have a page you should check out if you haven’t already:

We don’t have a great tutorial for setting up the Flexy with a Mosquitto Broker and creating the certificates. I think I’m going to try to create one when I have a chance!

Thanks Kyle, that is all great information! I’ll comb through it when I can find some time! Appreciate all the help!

1 Like

Good Morning, thought I’d just continue this thread instead of creating a new one.

I have my certs setup on my mosquitto broker on our remote server and have tested connection with a local client via the domain name. All is well there. But, I’m not able to connect from the eWon…I’m sure I’m missing something pretty basic.

CLS
SETSYS INF, “LOAD”
SerNum$ = “20192063”
SendTagValues% = 0
//######## CONFIG ###############
MQTTBrokerURL$ = “my.domain.com
MQTTPort$ = “8884”
MQTTCaCert$ = “/usr/mqtt/certs/ca.crt”
MQTTClientCert$ = “/usr/mqtt/certs/client.crt”
MQTTkey$ = “/usr/mqtt/certs/server.key”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = “Hello From Flexy " + SerNum$
//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1
//######## END CONFIG ###############
Last_ConnStatus% = 0
//Configure MQTT Connection parameters
CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SETPARAM”, “cafile”, MQTTCaCert$
MQTT “SETPARAM”, “certfile”, MQTTClientCert$
MQTT “SETPARAM”, “keyfile”, MQTTkey$
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log(”[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0

The first thing about our setup is that we’re using port 8884 instead of 8883 because I left our listener for TLS-PSK intact. If eWon doesn’t support a connection on Port 8884, then I can easily change this.

Also, I have the broker set up so that it doesn’t require username / password. It simply needs the cert files in order to encrypt traffic. Maybe my logic is flawed, but I wouldn’t think the username/password auth would be necessary since the CA cert is required and that wouldn’t be able to be obtained any easier than a username/password?

Using the MQTT.fx utility, I’m able to connect with the following configuration:
image

I’m also able to connect with this connection scheme:

The BASIC IDE console is report this error:
image

Any pointers is greatly appreciated!

Did you use a password when creating the certs?

Does your broker support just TLSv1.1 or 1.2 also?

Ah, yes, it did prompt for a password when creating the cert.

It supports 1.2, I just happen to have it set at v1.1 for now. I can also get that bumped up if need be.

You should be able to create the cert without a password and it will work. I haven’t done it in a while, but I know that is an option.

I was able to get the cert setup without a password and confirmed functionality with the MQTT.fx client:

I’m also no longer getting the “Operation failed (28) 46: MQTT “CONNECT”” error. Instead, when I run the script, I get nothing in the console for 10 seconds and then I get the following:
image

Afterwhich, the “Flexy not connected” line repeats every 10 seconds.

I’ve copied my BASIC init section below, apologies for how long it is…just wanted to make everything was in there in case I messed something up along the way.

CLS
SETSYS INF, “LOAD”
SerNum$ = “20192063”
SendTagValues% = 1
//######## CONFIG ###############
MQTTBrokerURL$ = “my.domain”
MQTTPort$ = “8884”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = “Hello From Flexy " + SerNum$
//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1
//######## END CONFIG ###############
Last_ConnStatus% = 0
//Configure MQTT Connection parameters
CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SETPARAM”, “CAFILE”, “/usr/mqtt/certs/ca.crt”
MQTT “SETPARAM”, “CERTFILE”, “/usr/mqtt/certs/client.crt”
MQTT “SETPARAM”, “KEYFILE”, “/usr/mqtt/certs/client.key”
MQTT “SETPARAM”, “PROTOCOLVERSION”, “3.1.1”
MQTT “SETPARAM”, “TLSVERSION”, “tlsv1.2”
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log(”[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0
//When receiving a message from Broker, “GOTO MQTTRECEIVEMSG”
ONMQTT “GOTO MQTTRECEIVEMSG”
ONTIMER 1, “GOTO SENDDATA”
TSET 1,10 //publish every 10 seconds
END
SENDDATA:
//Read MQTT Connection Status (5 = Connected, other values = Not connected)
ConnStatus% = MQTT “STATUS”
IF Last_ConnStatus% <> ConnStatus% THEN
IF ConnStatus% = 5 THEN //Connection is back online
@Log("[MQTT SCRIPT] Flexy connected to Broker")
ELSE
@Log("[MQTT SCRIPT] Flexy disconnected from Broker")
ENDIF
Last_ConnStatus% = ConnStatus%
ENDIF
//IF Connected --> Publish messages
IF ConnStatus% = 5 THEN //If connected --> Publish
IF SendTagValues% = 1 THEN
NB% = GETSYS PRG,“NBTAGS”
MsgToPublish$ = “[”
FOR i% = 0 TO NB%-1
SETSYS Tag, “load”,-i%
TagName$ = GETSYS Tag, “Name”
TagValue$ = GETSYS Tag, “TagValue”
IF i% = 0 THEN
MsgToPublish$ = MsgToPublish$ + ‘{“tag”:"’ + TagName$ + ‘",“value”:’ + TagValue$ + ‘,“time”:"’ + @GetTime$() + ‘"}’
ELSE
MsgToPublish$ = MsgToPublish$ + ‘,{“tag”:"’ + TagName$ + ‘",“value”:’ + TagValue$ + ‘,“time”:"’ + @GetTime$() + ‘"}’
ENDIF
NEXT i%
MsgToPublish$ = MsgToPublish$ + “]”
ENDIF
MQTT “PUBLISH”, TopicToPublishOn$ , MsgToPublish$, 0,0
PRINT “[MQTT SCRIPT] Message '” + MsgToPublish$ + “’ sent on topic : " + TopicToPublishOn$
ELSE //If not connected --> Save message in file
@Log(”[MQTT SCRIPT] Flexy not connected")
ENDIF
END
MQTTRECEIVEMSG:
//Executed when receiving messages from Broker
MessageQty%=Mqtt “READ” //Return the number of pending messages
IF (MessageQty%>0) Then
MsgTopic$= MQTT “MSGTOPIC”
MsgData$ = MQTT “MSGDATA”
@Log("[MQTT SCRIPT] Message ‘"+ MsgData$ + "’ received on topic " +MsgTopic$)
GOTO MQTTRECEIVEMSG
ENDIF
END
FUNCTION Log($Msg$)
LOGEVENT $Msg$ ,100
PRINT $Msg$
ENDFN
Function GetTime$()
$a$ = Time$
$GetTime$ = $a$(7 To 10) + “-” + $a$(4 To 5) + “-” + $a$(1 To 2) + " " + $a$(12 To 13)+":"+$a$(15 To 16)+":"+$a$(18 To 19)
EndFn

I’m having a hard time finding the reason why ConnStatus isn’t 5 here. You are no longer getting the BASIC error upon connection.

Can you create a full backup with eBuddy and include the Support Files so that I can see all of the logs?

That seemed strange to me as well. Backup w/ Support Files attached. Thanks!
eWON.tar (1.2 MB)

Did you test this with your Mosquitto server? Is it a local server or hosted on the internet?

Hi Kyle, yes I used the MQTT.fx client on my local machine and was able to connect to the mosquitto server. It is hosted remotely on one of our servers and I’m accessing it over the internet via domain name.

I think this is your problem:

https://techforum.ewon.biz/thread-985-post-4218.html#pid4218

The SAN “Subject Alternative Name” field on the cert does not match the domain name that the Flexy needs to connect to.

Ah, I see! I’ll dig into this and try it next! Thanks!