MQTT publish/subscribe TLS library for Photon, Spark Core. This library based MQTT for Photon, Spark Core and TlsTcpClient(using mbedTLS 2.16.0).
- TLS_RSA_WITH_AES_[128|256]_GCM_SHA[1|256|512]
- TLS_ECDHE_ECDSA_WITH_AES_[128|256]_GCM_SHA[385|256]
- TLS_EMPTY_RENOGOTIATION_INFO_SCSV
This lightweight library source code are only 2 files. firmware -> MQTT-TLS.cpp, MQTT-TLS.h.
Application can use QOS0,1,2 and retain flag when send a publish message.
This library tested on test.mosquitto.org, iot.eclipse.org, AWS IoT Gateway, Google IoT Core, Azure IoT Hub MQTT servers.
Some sample sketches for Spark Core and Photon included(firmware/examples/).
- a1-example.ino : simple pub/sub sample.
#include "MQTT-TLS.h"
void callback(char* topic, byte* payload, unsigned int length);
#define LET_ENCRYPT_CA_PEM \
"-----BEGIN CERTIFICATE----- \r\n" \
"MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw\r\n" \
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\r\n" \
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1\r\n" \
"WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\r\n" \
"RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi\r\n" \
"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX\r\n" \
"NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf\r\n" \
"89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl\r\n" \
"Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc\r\n" \
"Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz\r\n" \
"uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB\r\n" \
"AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU\r\n" \
"BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB\r\n" \
"FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo\r\n" \
"SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js\r\n" \
"LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF\r\n" \
"BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG\r\n" \
"AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD\r\n" \
"VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB\r\n" \
"ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx\r\n" \
"A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM\r\n" \
"UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2\r\n" \
"DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1\r\n" \
"eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu\r\n" \
"OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw\r\n" \
"p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY\r\n" \
"2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0\r\n" \
"ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR\r\n" \
"PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b\r\n" \
"rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt\r\n" \
"-----END CERTIFICATE----- "
const char letencryptCaPem[] = LET_ENCRYPT_CA_PEM;
/**
* if want to use IP address,
* byte server[] = { XXX,XXX,XXX,XXX };
* MQTT client(server, 1883, callback);
* want to use domain name,
* MQTT client("www.sample.com", 1883, callback);
* iot.eclipse.org is Eclipse Open MQTT Broker: https://iot.eclipse.org/getting-started
**/
MQTT client("iot.eclipse.org", 8883, callback);
// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
if (message.equals("RED"))
RGB.color(255, 0, 0);
else if (message.equals("GREEN"))
RGB.color(0, 255, 0);
else if (message.equals("BLUE"))
RGB.color(0, 0, 255);
else
RGB.color(255, 255, 255);
delay(1000);
}
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();
void setup() {
if (millis() - lastSync > ONE_DAY_MILLIS) {
Particle.syncTime();
lastSync = millis();
}
RGB.control(true);
// enable tls. set Root CA pem file.
// if you don't use TLS, comment out this line.
client.enableTls(letencryptCaPem, sizeof(letencryptCaPem));
Serial.println("tls enable");
// connect to the server
client.connect("sparkclient");
// publish/subscribe
if (client.isConnected()) {
Serial.println("client connected");
client.publish("outTopic/message", "hello world");
client.subscribe("inTopic/message");
}
}
void loop() {
if (client.isConnected())
client.loop();
delay(200);
}
Developer could easy to change the mbedTLS options (mbedtls/config.h) for application and firmware size. This library use a lot of Flash area for encryption method and limit to user application size. Because of that's developer could enable/disable the mbedTLS option with comment out the option parameters for the Flash spaces. When enable/disable the option parameter, it's carefully check the server/application TLS connectivity and security.
Here is application firmware size(byte) and mbedTLS options on Particle Workbench(local compiler).
device | RSA/ECDSA,ECDH(default) | RSA only | remove SHA512 option |
---|---|---|---|
Argon(0.8.0.-rc27) | 90308 | 76964 | 70884 |
Photon(1.0.0) | 89492 | 76164 | 70100 |
exp.1) If application use TLS_RSA_WITH_AES_256_GCM_SHA256 certification only, developer could comment out the following ECC/SHA512 options from mbedtls/config.h for Flash spaces. MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED,MBEDTLS_ASN1_WRITE_C,MBEDTLS_ECDH_C,MBEDTLS_ECDSA_C,MBEDTLS_ECP_C,MBEDTLS_SHA512_C
exp.2) Here is the default config.h and config-mini.h application size comparison with a1-example.cpp on Particle Photon firmware version 1.0.1 build VScode local compiler.
config.h
text | data | bss | de | hex | filename |
---|---|---|---|---|---|
89492 | 168 | 11896 | 101556 | 18cb4 | a1-example.elf |
config-mini.h
text | data | bss | de | hex | filename |
---|---|---|---|---|---|
66868 | 148 | 11736 | 78752 | 133a0 | a1-example.elf |