ArduinoMqttClient using TLS

Hi,

I have been trying to use the TLS option of the ArduinoMqttClient library with no luck.

I am trying to connect to a broker with a TLS layer activated. Also, username, password, and Client ID authentication are activated. I can connect using the non-secure port (i.e. 1883). I can connect using a Desktop Tool (MQTTX) and TLS by providing (in PEM format) the broker cert, client cert, and client private key. The client cert and the private key are generated by me using OpenSSL. The broker cert is provided to me by the broker company. So, there are no problems on the broker side and the TLS connection when the client correctly consumes the certs.

Now, the problem is that I'm trying to do the same from an Arduino Sketch using ArduinoMqttClient library and Nano 33 IoT board. I learned that I have to flash the certs on the WiFiNINA chip using either the IDE or the cmd tool (arduino_fwuploader). I managed to get the fwuploader and prepared the certs and issued the following command:

 .\arduino-fwuploader.exe certificates flash --url arduino.cc:443 --file "C:\Users\Adel\Desktop\nano certs\broker.pem" --file "C:\Users\Adel\Desktop\nano certs\client_certificate.pem" --file "C:\Users\Adel\Desktop\nano certs\client_private.pem" -b arduino:samd:nano_33_iot -a COM12

As you can see I'm flashing three certs (Broker, Client Cert, and Client Key). However, the tool was able to flash the broker and client certs but not the client key, and the following response is what I got:

Error during certificates flashing: failed to parse certificate: x509: malformed tbs certificate

I then tried to only upload the two working certs and used the WiFiSimpleSender example while applying the comments for TLS:

// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate 
//    flashed in the WiFi module 

and the mqtt connection failed with rc = -2. which is expected since the certs are not complete.

Any help regarding the flashing of the client's private key or any advice on how can I achieve the TLS MQTT connection using Arduino (Even if it requires using other boards of libraries) is highly appreciated.

Did you generate a cert or a Certificate Signing Request? AWS IoT will generate a cert and key for you; they act as the Certificate Authority so they can verify your client creds. Similarly, Mosquitto takes a CSR to generate a cert.

If you can borrow an ESP32 board, it's easy to use those creds with WiFiClientSecure and ArduinoMqttClient to "see if it works". (Hint: use raw strings.) Properly securing the private key is harder.

As for the arduino-fwuploader, I don't have any experience with it, but it does not appear to support the private key. For that matter, neither does NINA for mutual TLS, with the mainline firmware.

1 Like

I'm a newbie when it comes to whole TLS thing. So, I'm gonna share with you the steps I used to generate the certs.

  1. I generated a self-signed X.509 certificate (root_ca.crt) and its corresponding private key (root_ca.key). I uploaded this root_ca.crt to the broker (which is a paid-version mosquito [cedalo]).
  2. I generated a new RSA private key (client.key) and a certificate signing request (client.csr)
  3. Used the CA's private key and certificate to sign the CSR, resulting in a signed certificate (client.crt).

In summary, a self-signed cert is shared with the broker, a broker cert is provided to me. From the self-signed cert, I generated a client cert and private key. I hope this answers your question.

As for the esp32, I found a code that uses TLS to connect to MQTT and uses the same certs as I used above and it worked, but weirdly, the code consumes almost 75% of the flash memory and it only connects to mqtt and publishes a simple message.

I have a sketch that before I added MQTT

Sketch uses 992177 bytes (75%) of program storage space.
Maximum is 1310720 bytes.

Then adding ArduinoMqttClient

Sketch uses 1004617 bytes (76%) of program storage space.

and the certs

Sketch uses 1007549 bytes (76%) of program storage space.

So I ended up in the same place (percentage-wise at least), but started pretty close to there. I guess it was already using all the dependencies like Client