marvinroger / async-mqtt-client

📶 An Arduino for ESP8266 asynchronous MQTT client implementation
MIT License
844 stars 267 forks source link

Crash on .connect() using fingerprint #267

Open aypopa opened 3 years ago

aypopa commented 3 years ago

Hi, after a year+ of flawless service from async-mqtt-client on my ESP8266 boards I tried to add some nice security layer. Using Arduino IDE and the bug-fixed version of ESPAsyncTCP from Phil Bowles I was able to make it work... mostly. It works well while no fingerprint is defined, but adding a fingerprint results in regular fatal exceptions (exception 3, reason 2). This happens in ~20% of all connect attempts if the fingerprint is correct (which bugs me the most), or in ~70% cases if not. Did someone else encounter this?

My testing code:

#include <ESP8266WiFi.h>
#include <AsyncMqttClient.h>

#define WIFI_SSID "XXXXXX"
#define WIFI_PASSWORD "XXXXXXXX"
#define MQTT_SLL true
#define MQTT_FPRINT true
#define MQTT_HOST IPAddress(XXX, XXX, XXX, XXX)
#define MQTT_PORT XXXX
#define MQTT_USER "XXXXX"
#define MQTT_PASS "XXXXX"

uint8_t MQTT_FINGERPRINT[20] = {0x48, 0xed, 0x5d, 0xd4, 0x98, 0x0b, 0xcb, 0x16, 0x43, 0xaf, 0xfe, 0x4d, 0x08, 0x51, 0x8f, 0x25, 0xcd, 0xf1, 0x5e, 0x80};                                                                                               

AsyncMqttClient mqttClient;

void mqttCallback(char* tpc_ch, char* pay_ch, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {  
    Serial.print(F("  Message: "));
    Serial.print(String(pay_ch).substring(0,len));
    Serial.print(F(",  topic: "));
    Serial.println(tpc_ch);
}

void onMqttConnect(bool sessionPresent) {   
  Serial.println(F(" ok!"));
  mqttClient.subscribe("aypopa15268/mytest/SSL", 2);
  mqttClient.publish("aypopa15268/mytest/SSL", 0, false, "ssl_test_ok");
}

void setup()   {
  Serial.begin(115200);delay(500);Serial.println();

/*****************   WIFI   ******************/
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to WiFi: ");Serial.print(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println(F(" ok!"));

/*****************   MQTT   ********************/
  mqttClient.onConnect(onMqttConnect);
  mqttClient.onMessage(mqttCallback);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);
  mqttClient.setCredentials(MQTT_USER, MQTT_PASS);
  mqttClient.setSecure(MQTT_SLL);
  if(MQTT_FPRINT) mqttClient.addServerFingerprint(MQTT_FINGERPRINT);

  Serial.print(F("Connecting to MQTT: "));
  Serial.print(MQTT_HOST);Serial.print(":");Serial.print(MQTT_PORT);Serial.print("...");
  mqttClient.connect();
  }

void loop() {     
}

Thanks!

bertmelis commented 3 years ago

Do you have a backtrace, decoded?

aypopa commented 3 years ago

Sure:

Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
PC: 0x4021dfb6: basic_read at ssl/tls1.c line 1368
EXCVADDR: 0x0003aaaa

Decoding stack results
0x4021e2fc: basic_read at ssl/tls1.c line 1607
0x40202ab0: std::_Function_handler ::_M_invoke(const std::_Any_data &, void *, AsyncClient *) at c:\users\michal\documents\arduinodata\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2073
0x40100125: std::function ::operator()(void*, AsyncClient*) const at c:\users\michal\documents\arduinodata\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2465
0x40201395: tcp_ssl_read at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\tcp_axtls.c line 381
0x4021bdb4: mem_free at core/mem.c line 237
0x4020597c: AsyncClient::_recv(std::shared_ptr &, tcp_pcb*, pbuf*, long) at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\ESPAsyncTCP.cpp line 609
0x40213e58: tcp_free_acked_segments at core/tcp_in.c line 1109
0x40205ba0: AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, long) at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\ESPAsyncTCP.cpp line 733
0x40205c30: AsyncClient::_s_sent(void*, tcp_pcb*, unsigned short) at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\ESPAsyncTCP.cpp line 749
0x402155c4: tcp_input at core/tcp_in.c line 501
0x40100a3c: malloc(size_t) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x4021b03a: ip4_input at core/ipv4/ip4.c line 1467
0x40100a07: free(void*) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 398
0x40212239: ethernet_input_LWIP2 at netif/ethernet.c line 188
0x40212058: esp2glue_ethernet_input at glue-lwip/lwip-git.c line 469
0x4023d4ae: ethernet_input at glue-esp/lwip-esp.c line 365
0x4023d4bf: ethernet_input at glue-esp/lwip-esp.c line 373
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x40211c19: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40100a3c: malloc(size_t) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x40211ea6: new_linkoutput at glue-lwip/lwip-git.c line 260
0x402122c4: ethernet_output at netif/ethernet.c line 312
0x40100a3c: malloc(size_t) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc\umm_malloc.cpp line 552
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x40206bd9: __preloop_update_frequency() at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 91
0x40205c40: AsyncClient::_s_connected(void*, void*, long) at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\ESPAsyncTCP.cpp line 751
0x402053a0: AsyncClient::connect(IPAddress, unsigned short, bool) at C:\Users\Michal\Documents\Arduino\libraries\ESPAsyncTCP-master\src\ESPAsyncTCP.cpp line 267
0x402065ca: Print::print(unsigned long, int) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\Print.cpp line 168
0x40205fe0: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x40202c4d: AsyncMqttClient::connect() at C:\Users\Michal\Documents\Arduino\libraries\async-mqtt-client-master\src\AsyncMqttClient.cpp line 694
0x40206440: Print::print(char const*) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\Print.cpp line 130
0x401001f8: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x40100219: esp_schedule() at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 125
0x40206d55: loop_wrapper() at C:\Users\Michal\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 199
bastianhjaeger commented 2 years ago

@aypopa How did you solve the issue with the missing ssl.h file?

I am constantly getting compiling issues:

Compiling .pio/build/proj001_release/src/main.cpp.o
In file included from .pio/libdeps/proj001_release/AsyncMqttClient/src/AsyncMqttClient.hpp:22,
                 from .pio/libdeps/proj001_release/AsyncMqttClient/src/AsyncMqttClient.h:4,
                 from src/ConnectionInterface.h:9,
                 from src/ConnectionInterface.cpp:1:
.pio/libdeps/proj001_release/ESP AsyncTCP/src/tcp_axtls.h:44:10: fatal error: include/ssl.h: No such file or directory
   44 | #include "include/ssl.h"
      |          ^~~~~~~~~~~~~~~

I repored this on the original ESPAsyncTCP but without luck. The version you mentioned did not seem to fix this issue, right?

bertmelis commented 2 years ago

Ssl.h is part of the Arduino core but was removed. So unless you downgrade the Arduino core (I have to check the version) TLS is not supported anymore.