I'm using Arduino IDE v2.1.1 and Arduino MKR wifi 1010. Everything works fine and at this moment I have a need to protect the wifi connection with ssl certificate. I have generated the ssl certificate using the openssl tool and now I have following files that needs to be set in the controller:
ca.cer
client.cer
client.key
how can I set these three files to the MKR wifi 1010 to enable the SSL certificate protected communication? I couldn't find the tutorial or example on the internet.
Hi @semyuelshekh. The most convenient way to install an SSL certificate on your MKR WiFi 1010 is using the Upload SSL Root Certificates feature of Arduino IDE:
The way this feature works is you provide a domain name of the site you want to connect to and the tool downloads the root certificate from that domain then uploads it to the MKR WiFi 1010.
If for some reason you need to upload certificate files directly, this can not be done via the IDE's Upload SSL Root Certificates. It can be done using the Arduino Firmware Uploader command line tool provided by Arduino:
@ptillisch@sterretje , let me explain how I do that at the moment. I do have a valid self-signed CA certificate and I'm trying to establish a SSL / TLS connection using the CA sertificate only. This is my code which doesn't work unfortunately:
#include <WiFiNINA.h>
#include <ArduinoJson.h>
#include <ArduinoMqttClient.h>
#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include "secrets.h"
char wifiSsid[] = SECRET_WiFi_SSID;
char wifiPass[] = SECRET_WiFi_PASS;
char mqttUserId[] = MQTT_USERID;
char mqttPass[] = MQTT_PASS;
int status = WL_IDLE_STATUS;
const char* rootCAcertificate = \
"-----BEGIN CERTIFICATE-----\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"-----END CERTIFICATE-----\n";
bool dev_debug_mode = IS_DEBUG;
WiFiClient wifiClient; // Used for the TCP socket connection
BearSSLClient bearSslClient(wifiClient); // Used for SSL/TLS connection, integrates with ECCX08
MqttClient mqttClient(bearSslClient); // Used for MQTT protocol usage
const char mqttBroker[] = MQTT_BROKER_HOST;
int mqttPort = 8883;
const char deviceRegisterTopic[] = "device/register";
//set interval for sending the Observation (the measurement from the sensor) messages (milliseconds)
const long interval = 3000;
unsigned long previousMillis = 0;
bool deviceIsRegistered = false;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (dev_debug_mode && !Serial) {
; // wait for serial port to connect. Needed for native USB port only - development mode. It has to be removed when releasing to live!!!
}
// Check the crypto chip module presence (needed for BearSSL)
if (!ECCX08.begin()) {
Serial.println("No ECCX08 present!");
while (1);
}
bearSslClient.setEccSlot(0, rootCAcertificate); // inserting a certificate into the slot 0 (zero)
// ================ SSL SETUP ================
// Set a callback to get the current time
// (used to validate the servers certificate)
ArduinoBearSSL.onGetTime(getTime);
// attempt to connect to the Wifi network
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to network: ");
Serial.println(wifiSsid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(wifiSsid, wifiPass);
Serial.print("Attempt status: ");
Serial.println(status);
if(status != WL_CONNECTED) {
// waiting 10 seconds before trying to connect if it is needed:
delay(10000);
}
}
// WiFi network connection established! sending some messages to the console
Serial.println("You're connected to the network");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(mqttBroker);
Serial.println(mqttPort);
mqttClient.setId(mqttUserId);
// adding first level of proptection using MQTT broker username and password
mqttClient.setUsernamePassword(mqttUserId, mqttPass);
delay(30000);
while (!mqttClient.connect(mqttBroker, mqttPort)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
delay(10000);
}
// MQTT broker connection established! sending some messages to the console
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
void loop() {
// call poll() regularly to allow the library to send MQTT keep alive which
// avoids being disconnected by the broker
mqttClient.poll();
// if this current device is not registered yet, registering the device for the first time
if(!deviceIsRegistered) {
Serial.print("Sending Device Register message to topic: ");
Serial.println(deviceRegisterTopic);
// DO SOMETHING
}
unsigned long currentMillis = millis();
// sending the actual measurement data to the FHIR Server with some time interval, like few seconds. To be defined later.
if (currentMillis - previousMillis >= interval) {
// save the last time a message was sent
previousMillis = currentMillis;
Serial.println();
}
}
// ================================== Auxiliary functions ===================================
unsigned long getTime() {
Serial.print("Current WiFi time:");
Serial.println(WiFi.getTime());
// Get the current time from the WiFi module
return WiFi.getTime();
}
in the code above, I'm using the BearSSLClient and the certificate is set manually (I prefer this way as it is more transparent for me) bearSslClient.setEccSlot(0, certificate); - this is how the certificate is set. Also I do the following call: ArduinoBearSSL.onGetTime(getTime); - to get the proper time. The CA certificate is validated using the openssl tool. It is a valid self-signed root certificate. Please, any help is much appreciated. I'm really confused as it should work since the certificate is a valid self-signed certificate and it is confirmed and verified using the openssl tool. When something should work but it doesnt work and I don't have any details except the -2 error message it makes me feel completely crazy ((((
there is another code, which I have found on the internet, related to the mutual TLS communication, it doesn't work as well ((((
// Instruct the SSL client to use the chosen ECCX08 slot for picking the private key
// and set the hardcoded certificate as accompanying public certificate.
ssl_client.setEccSlot(
keySlot,
CLIENT_PUBLIC_CERT);
br_x509_certificate x509cert = {
CLIENT_CERT,
sizeof(CLIENT_CERT) - 1
};
// Set the X509 certificate
ssl_client.setEccCert(x509cert);
ssl_client.setKey(CLIENT_KEY, CLIENT_CERT);
it looks like what I need, because the mosquitto mqtt broker that I'm using supports mutual SSL / TLS communications, however the code doesn't work. Also I have no idea what CLIENT_PUBLIC_CERT is? Any thoughts?
what I'm trying to accomplish, is shown below as pseudo code (another microcontroller):
#include <PubSubClient.h>
#include "WiFiClientSecure.h"
WiFiClientSecure client;
PubSubClient mqtt_client(client);
client.setCACert(CA_cert); //Root CA certificate
client.setCertificate(ESP_CA_cert); //for client verification if the require_certificate is set to true in the mosquitto broker config
client.setPrivateKey(ESP_RSA_key); //for client verification if the require_certificate is set to true in the mosquitto broker config
mqtt_client.setServer(mqtt_server, port);
it is about connecting to a mosquitto MQTT broker using mutual TLS and using three certificates: