Skip to content

Commit b48f8c1

Browse files
Niekmcspr
authored andcommitted
MQTT rewrite with SSL fixes (#1751, #1829)
* MQTT rewrite with SSL fixes - Added Arduino MQTT library support (actively maintained) - Added support for BearSSL (core >= 2.5) - BearSSL validation: insecure, fingerprinting and CA validation - AxTLS validation: insecure and fingerprinting - Support MFLN in order to reduce heap usage * Better header incl, fix building w/ no NTP_SUPPORT * Clean up code, use DEBUG_MSG_P * Fix compile error
1 parent fa9ff7d commit b48f8c1

10 files changed

Lines changed: 336 additions & 156 deletions

File tree

code/espurna/config/dependencies.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
// Configuration settings are in the general.h file
66
//------------------------------------------------------------------------------
77

8+
#if defined(ASYNC_TCP_SSL_ENABLED) && SECURE_CLIENT == SECURE_CLIENT_NONE
9+
#undef SECURE_CLIENT
10+
#define SECURE_CLIENT SECURE_CLIENT_AXTLS
11+
#endif
12+
813
#if DEBUG_TELNET_SUPPORT
914
#undef TELNET_SUPPORT
1015
#define TELNET_SUPPORT 1
@@ -55,10 +60,10 @@
5560
#define MQTT_SUPPORT 1 // If Home Assistant enabled enable MQTT
5661
#endif
5762

58-
#ifndef ASYNC_TCP_SSL_ENABLED
63+
#if SECURE_CLIENT != SECURE_CLIENT_AXTLS
5964
#if THINGSPEAK_USE_SSL && THINGSPEAK_USE_ASYNC
6065
#undef THINGSPEAK_SUPPORT
61-
#define THINGSPEAK_SUPPORT 0 // Thingspeak in ASYNC mode requires ASYNC_TCP_SSL_ENABLED
66+
#define THINGSPEAK_SUPPORT 0 // Thingspeak in ASYNC mode requires SECURE_CLIENT_AXTLS
6267
#endif
6368
#endif
6469

code/espurna/config/general.h

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@
567567
#endif
568568

569569
// This is not working at the moment!!
570-
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core 2.4.0
570+
// Requires SECURE_CLIENT = SECURE_CLIENT_AXTLS and ESP8266 Arduino Core 2.4.0
571571
#ifndef WEB_SSL_ENABLED
572572
#define WEB_SSL_ENABLED 0 // Use HTTPS web interface
573573
#endif
@@ -839,26 +839,28 @@
839839
#endif
840840

841841

842-
#ifndef MQTT_USE_ASYNC
843-
#define MQTT_USE_ASYNC 1 // Use AysncMQTTClient (1) or PubSubClient (0)
842+
#ifndef MQTT_LIBRARY
843+
#define MQTT_LIBRARY MQTT_ASYNC // Choose between: MQTT_ASYNC (AysncMQTTClient), MQTT_PUBSUB (PubSubClient), MQTT_ARDUINO (Arduino-MQTT)
844844
#endif
845845

846846
// MQTT OVER SSL
847847
// Using MQTT over SSL works pretty well but generates problems with the web interface.
848848
// It could be a good idea to use it in conjuntion with WEB_SUPPORT=0.
849-
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core 2.4.0.
849+
// Requires SECURE_CLIENT = SECURE_CLIENT_AXTLS or SECURE_CLIENT_BEARSSL and ESP8266 Arduino Core >= 2.4.0.
850850
//
851-
// You can use SSL with MQTT_USE_ASYNC=1 (AsyncMqttClient library)
851+
// You can use SSL with MQTT_LIBRARY=ASYNC (AsyncMqttClient library)
852852
// but you might experience hiccups on the web interface, so my recommendation is:
853853
// WEB_SUPPORT=0
854854
//
855-
// If you use SSL with MQTT_USE_ASYNC=0 (PubSubClient library)
855+
// If you use SSL with MQTT_LIBRARY=PUBSUB (PubSubClient library) or MQTT_LIBRARY=ARDUINO (Arduino-MQTT library)
856856
// you will have to disable all the modules that use ESPAsyncTCP, that is:
857-
// ALEXA_SUPPORT=0, INFLUXDB_SUPPORT=0, TELNET_SUPPORT=0, THINGSPEAK_SUPPORT=0 and WEB_SUPPORT=0
857+
// ALEXA_SUPPORT=0, INFLUXDB_SUPPORT=0, TELNET_SUPPORT=0, THINGSPEAK_SUPPORT=0, DEBUG_TELNET_SUPPORT=0 and WEB_SUPPORT=0
858858
//
859-
// You will need the fingerprint for your MQTT server, example for CloudMQTT:
860-
// $ echo -n | openssl s_client -connect m11.cloudmqtt.com:24055 > cloudmqtt.pem
861-
// $ openssl x509 -noout -in cloudmqtt.pem -fingerprint -sha1
859+
// You will need the fingerprint of your MQTT server, in order to prevent MITS attacks.
860+
// To get a certificate fingerprint, run the following command:
861+
// $ echo -n | openssl s_client -connect mqtt.googleapis.com:8883 2>&1 | openssl x509 -noout -fingerprint -sha1 | cut -d\= -f2
862+
// Note that this fingerprint changes with e.g. LetsEncrypt renewals or when the CSR changes.
863+
// It's also possible to leave the fingerprint empty, the certificate is then always trusted.
862864

863865
#ifndef MQTT_SSL_ENABLED
864866
#define MQTT_SSL_ENABLED 0 // By default MQTT over SSL will not be enabled
@@ -868,6 +870,20 @@
868870
#define MQTT_SSL_FINGERPRINT "" // SSL fingerprint of the server
869871
#endif
870872

873+
#ifndef MQTT_SECURE_CLIENT_CHECK
874+
#define MQTT_SECURE_CLIENT_CHECK SECURE_CLIENT_CHECK // Use global verification setting by default
875+
#endif
876+
877+
#ifndef MQTT_SECURE_CLIENT_MFLN
878+
#define MQTT_SECURE_CLIENT_MFLN SECURE_CLIENT_MFLN // Use global MFLN setting by default
879+
#endif
880+
881+
#ifndef MQTT_SECURE_CLIENT_INCLUDE_CA
882+
#define MQTT_SECURE_CLIENT_INCLUDE_CA 0 // Use user-provided CA. Only PROGMEM PEM option is supported.
883+
// When enabled, current implementation includes "static/mqtt_secure_client_ca.h" with
884+
// const char _mqtt_client_ca[] PROGMEM = "...PEM data...";
885+
// By default, using LetsEncrypt X3 root in "static/letsencrypt_isrgroot_pem.h"
886+
#endif
871887

872888
#ifndef MQTT_ENABLED
873889
#define MQTT_ENABLED 0 // Do not enable MQTT connection by default
@@ -986,7 +1002,9 @@
9861002
#define MQTT_TOPIC_DATETIME "datetime"
9871003
#define MQTT_TOPIC_FREEHEAP "freeheap"
9881004
#define MQTT_TOPIC_VCC "vcc"
1005+
#ifndef MQTT_TOPIC_STATUS
9891006
#define MQTT_TOPIC_STATUS "status"
1007+
#endif
9901008
#define MQTT_TOPIC_MAC "mac"
9911009
#define MQTT_TOPIC_RSSI "rssi"
9921010
#define MQTT_TOPIC_MESSAGE_ID "id"
@@ -1031,7 +1049,9 @@
10311049

10321050

10331051
#define MQTT_STATUS_ONLINE "1" // Value for the device ON message
1052+
#ifndef MQTT_STATUS_OFFLINE
10341053
#define MQTT_STATUS_OFFLINE "0" // Value for the device OFF message (will)
1054+
#endif
10351055

10361056
#define MQTT_ACTION_RESET "reboot" // RESET MQTT topic particle
10371057

@@ -1283,7 +1303,7 @@
12831303
// THINGSPEAK OVER SSL
12841304
// Using THINGSPEAK over SSL works well but generates problems with the web interface,
12851305
// so you should compile it with WEB_SUPPORT to 0.
1286-
// When THINGSPEAK_USE_ASYNC is 1, requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core 2.4.0.
1306+
// When THINGSPEAK_USE_ASYNC is 1, requires SECURE_CLIENT = SECURE_CLIENT_AXTLS and ESP8266 Arduino Core >= 2.4.0.
12871307
#define THINGSPEAK_USE_SSL 0 // Use secure connection
12881308

12891309
#define THINGSPEAK_FINGERPRINT "78 60 18 44 81 35 BF DF 77 84 D4 0A 22 0D 9B 4E 6C DC 57 2C"

code/espurna/config/prototypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ using mqtt_callback_f = std::function<void(unsigned int, const char *, char *)>;
172172
String mqttMagnitude(char * topic);
173173
#endif
174174

175+
#if MQTT_SECURE_CLIENT_INCLUDE_CA
176+
#include "static/mqtt_secure_client_ca.h" // Assumes this header file defines a _mqtt_client_ca[] PROGMEM = "...PEM data..."
177+
#else
178+
#include "static/letsencrypt_isrgroot_pem.h" // Default to LetsEncrypt X3 certificate
179+
#define _mqtt_client_ca _ssl_letsencrypt_isrg_x3_ca
180+
#endif // MQTT_SECURE_CLIENT_INCLUDE_CA
181+
175182
// -----------------------------------------------------------------------------
176183
// OTA
177184
// -----------------------------------------------------------------------------

code/espurna/config/types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@
152152
#define MQTT_DISCONNECT_EVENT 1
153153
#define MQTT_MESSAGE_EVENT 2
154154

155+
#define MQTT_ASYNC 0
156+
#define MQTT_ARDUINO 1
157+
#define MQTT_PUBSUB 2
158+
159+
155160
//------------------------------------------------------------------------------
156161
// LED
157162
//------------------------------------------------------------------------------
@@ -353,6 +358,7 @@
353358
//------------------------------------------------------------------------------
354359
// Telnet server
355360
//------------------------------------------------------------------------------
361+
356362
#define TELNET_SERVER_ASYNC 0
357363
#define TELNET_SERVER_WIFISERVER 1
358364

0 commit comments

Comments
 (0)