mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Merge pull request #10576 from s-hadinger/esp32_tls
ESP32 support for TLS MQTT using BearSSL (same as ESP8266)
This commit is contained in:
commit
16f3d30535
@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Support for BS814A-2 8-button touch buttons by Peter Franck (#10447)
|
- Support for BS814A-2 8-button touch buttons by Peter Franck (#10447)
|
||||||
- Support for up to 4 I2C SEESAW_SOIL Capacitance & Temperature sensors by Peter Franck (#10481)
|
- Support for up to 4 I2C SEESAW_SOIL Capacitance & Temperature sensors by Peter Franck (#10481)
|
||||||
- ESP8266 Support for 2MB and up linker files with 1MB and up LittleFS
|
- ESP8266 Support for 2MB and up linker files with 1MB and up LittleFS
|
||||||
|
- ESP32 support for TLS MQTT using BearSSL (same as ESP8266)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
|
- ESP32 switch from default SPIFFS to default LittleFS file system loosing current (zigbee) files
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "my_user_config.h"
|
#include "my_user_config.h"
|
||||||
#include "tasmota_configurations.h"
|
#include "tasmota_configurations.h"
|
||||||
|
|
||||||
|
#if defined(ESP8266) && defined(USE_TLS)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "StackThunk_light.h"
|
#include "StackThunk_light.h"
|
||||||
@ -145,3 +146,5 @@ void stack_thunk_light_fatal_overflow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "my_user_config.h"
|
#include "my_user_config.h"
|
||||||
#include "tasmota_configurations.h"
|
#include "tasmota_configurations.h"
|
||||||
#if defined(ESP8266) && defined(USE_TLS)
|
#if defined(USE_TLS)
|
||||||
|
|
||||||
// #define DEBUG_TLS
|
// #define DEBUG_TLS
|
||||||
// #define DEBUG_ESP_SSL
|
// #define DEBUG_ESP_SSL
|
||||||
@ -47,7 +47,9 @@ extern "C" {
|
|||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
|
#ifdef ESP8266
|
||||||
#include <include/ClientContext.h>
|
#include <include/ClientContext.h>
|
||||||
|
#endif
|
||||||
#include "c_types.h"
|
#include "c_types.h"
|
||||||
|
|
||||||
#include <core_version.h>
|
#include <core_version.h>
|
||||||
@ -57,11 +59,15 @@ extern "C" {
|
|||||||
#include "coredecls.h"
|
#include "coredecls.h"
|
||||||
#define LOG_HEAP_SIZE(a) _Log_heap_size(a)
|
#define LOG_HEAP_SIZE(a) _Log_heap_size(a)
|
||||||
void _Log_heap_size(const char *msg) {
|
void _Log_heap_size(const char *msg) {
|
||||||
|
#ifdef ESP8266
|
||||||
register uint32_t *sp asm("a1");
|
register uint32_t *sp asm("a1");
|
||||||
int freestack = 4 * (sp - g_pcont->stack);
|
int freestack = 4 * (sp - g_pcont->stack);
|
||||||
Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n",
|
Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n",
|
||||||
msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(),
|
msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(),
|
||||||
freestack, ESP.getFreeContStack());
|
freestack, ESP.getFreeContStack());
|
||||||
|
#elif defined(ESP32)
|
||||||
|
Serial.printf("> Heap %s = %d\n", msg, uxTaskGetStackHighWaterMark(nullptr));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define LOG_HEAP_SIZE(a)
|
#define LOG_HEAP_SIZE(a)
|
||||||
@ -71,6 +77,7 @@ void _Log_heap_size(const char *msg) {
|
|||||||
extern uint32_t UtcTime(void);
|
extern uint32_t UtcTime(void);
|
||||||
extern uint32_t CfgTime(void);
|
extern uint32_t CfgTime(void);
|
||||||
|
|
||||||
|
#ifdef ESP8266 // Stack thunk is not needed with ESP32
|
||||||
// Stack thunked versions of calls
|
// Stack thunked versions of calls
|
||||||
// Initially in BearSSLHelpers.h
|
// Initially in BearSSLHelpers.h
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -164,6 +171,8 @@ unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, si
|
|||||||
#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack
|
#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack
|
||||||
#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf
|
#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf
|
||||||
|
|
||||||
|
#endif // ESP8266
|
||||||
|
|
||||||
//#define DEBUG_ESP_SSL
|
//#define DEBUG_ESP_SSL
|
||||||
#ifdef DEBUG_ESP_SSL
|
#ifdef DEBUG_ESP_SSL
|
||||||
//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
|
//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__)
|
||||||
@ -201,19 +210,23 @@ void WiFiClientSecure_light::_clear() {
|
|||||||
// Constructor
|
// Constructor
|
||||||
WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() {
|
WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() {
|
||||||
_clear();
|
_clear();
|
||||||
LOG_HEAP_SIZE("StackThunk before");
|
// LOG_HEAP_SIZE("StackThunk before");
|
||||||
//stack_thunk_light_add_ref();
|
//stack_thunk_light_add_ref();
|
||||||
LOG_HEAP_SIZE("StackThunk after");
|
// LOG_HEAP_SIZE("StackThunk after");
|
||||||
// now finish the setup
|
// now finish the setup
|
||||||
setBufferSizes(recv, xmit); // reasonable minimum
|
setBufferSizes(recv, xmit); // reasonable minimum
|
||||||
allocateBuffers();
|
allocateBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFiClientSecure_light::~WiFiClientSecure_light() {
|
WiFiClientSecure_light::~WiFiClientSecure_light() {
|
||||||
|
#ifdef ESP8266
|
||||||
if (_client) {
|
if (_client) {
|
||||||
_client->unref();
|
_client->unref();
|
||||||
_client = nullptr;
|
_client = nullptr;
|
||||||
}
|
}
|
||||||
|
#elif defined(ESP32)
|
||||||
|
stop();
|
||||||
|
#endif
|
||||||
//_cipher_list = nullptr; // std::shared will free if last reference
|
//_cipher_list = nullptr; // std::shared will free if last reference
|
||||||
_freeSSL();
|
_freeSSL();
|
||||||
}
|
}
|
||||||
@ -258,6 +271,7 @@ void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) {
|
|||||||
_iobuf_out_size = xmit;
|
_iobuf_out_size = xmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) {
|
bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) {
|
||||||
bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush()
|
bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush()
|
||||||
_freeSSL();
|
_freeSSL();
|
||||||
@ -268,6 +282,17 @@ bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) {
|
|||||||
(void) _run_until(BR_SSL_SENDAPP);
|
(void) _run_until(BR_SSL_SENDAPP);
|
||||||
return WiFiClient::flush(maxWaitMs);
|
return WiFiClient::flush(maxWaitMs);
|
||||||
}
|
}
|
||||||
|
#elif defined(ESP32)
|
||||||
|
void WiFiClientSecure_light::stop(void) {
|
||||||
|
WiFiClient::stop(); // calls our virtual flush()
|
||||||
|
_freeSSL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiClientSecure_light::flush(void) {
|
||||||
|
(void) _run_until(BR_SSL_SENDAPP);
|
||||||
|
WiFiClient::flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
|
int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
|
||||||
DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port);
|
DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port);
|
||||||
@ -307,7 +332,11 @@ void WiFiClientSecure_light::_freeSSL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiClientSecure_light::_clientConnected() {
|
bool WiFiClientSecure_light::_clientConnected() {
|
||||||
|
#ifdef ESP8266
|
||||||
return (_client && _client->state() == ESTABLISHED);
|
return (_client && _client->state() == ESTABLISHED);
|
||||||
|
#elif defined(ESP32)
|
||||||
|
return WiFiClient::connected();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WiFiClientSecure_light::connected() {
|
uint8_t WiFiClientSecure_light::connected() {
|
||||||
@ -506,9 +535,15 @@ int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) {
|
if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) {
|
||||||
return (state & target) ? 0 : -1;
|
return (state & target) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
#elif defined(ESP32)
|
||||||
|
if (!_clientConnected() && !WiFiClient::available()) {
|
||||||
|
return (state & target) ? 0 : -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If there is some record data to send, do it. This takes
|
If there is some record data to send, do it. This takes
|
||||||
@ -898,12 +933,16 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
|
|||||||
do { // used to exit on Out of Memory error and keep all cleanup code at the same place
|
do { // used to exit on Out of Memory error and keep all cleanup code at the same place
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// allocate Thunk stack, move to alternate stack and initialize
|
// allocate Thunk stack, move to alternate stack and initialize
|
||||||
|
#ifdef ESP8266
|
||||||
stack_thunk_light_add_ref();
|
stack_thunk_light_add_ref();
|
||||||
|
#endif // ESP8266
|
||||||
LOG_HEAP_SIZE("Thunk allocated");
|
LOG_HEAP_SIZE("Thunk allocated");
|
||||||
DEBUG_BSSL("_connectSSL: start connection\n");
|
DEBUG_BSSL("_connectSSL: start connection\n");
|
||||||
_freeSSL();
|
_freeSSL();
|
||||||
clearLastError();
|
clearLastError();
|
||||||
|
#ifdef ESP8266
|
||||||
if (!stack_thunk_light_get_stack_bot()) break;
|
if (!stack_thunk_light_get_stack_bot()) break;
|
||||||
|
#endif // ESP8266
|
||||||
|
|
||||||
_ctx_present = true;
|
_ctx_present = true;
|
||||||
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
|
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
|
||||||
@ -964,10 +1003,12 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
LOG_HEAP_SIZE("_connectSSL.end");
|
LOG_HEAP_SIZE("_connectSSL.end");
|
||||||
|
#ifdef ESP8266
|
||||||
_max_thunkstack_use = stack_thunk_light_get_max_usage();
|
_max_thunkstack_use = stack_thunk_light_get_max_usage();
|
||||||
stack_thunk_light_del_ref();
|
stack_thunk_light_del_ref();
|
||||||
//stack_thunk_light_repaint();
|
//stack_thunk_light_repaint();
|
||||||
LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk");
|
LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk");
|
||||||
|
#endif // ESP8266
|
||||||
|
|
||||||
#ifdef USE_MQTT_TLS_CA_CERT
|
#ifdef USE_MQTT_TLS_CA_CERT
|
||||||
free(x509_minimal);
|
free(x509_minimal);
|
||||||
@ -982,7 +1023,9 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
|
|||||||
// if we arrived here, this means we had an OOM error, cleaning up
|
// if we arrived here, this means we had an OOM error, cleaning up
|
||||||
setLastError(ERR_OOM);
|
setLastError(ERR_OOM);
|
||||||
DEBUG_BSSL("_connectSSL: Out of memory\n");
|
DEBUG_BSSL("_connectSSL: Out of memory\n");
|
||||||
|
#ifdef ESP8266
|
||||||
stack_thunk_light_del_ref();
|
stack_thunk_light_del_ref();
|
||||||
|
#endif
|
||||||
#ifdef USE_MQTT_TLS_CA_CERT
|
#ifdef USE_MQTT_TLS_CA_CERT
|
||||||
free(x509_minimal);
|
free(x509_minimal);
|
||||||
#else
|
#else
|
||||||
|
@ -43,7 +43,11 @@ class WiFiClientSecure_light : public WiFiClient {
|
|||||||
|
|
||||||
uint8_t connected() override;
|
uint8_t connected() override;
|
||||||
size_t write(const uint8_t *buf, size_t size) override;
|
size_t write(const uint8_t *buf, size_t size) override;
|
||||||
|
#ifdef ESP8266
|
||||||
size_t write_P(PGM_P buf, size_t size) override;
|
size_t write_P(PGM_P buf, size_t size) override;
|
||||||
|
#else
|
||||||
|
size_t write_P(PGM_P buf, size_t size);
|
||||||
|
#endif
|
||||||
size_t write(const char *buf) {
|
size_t write(const char *buf) {
|
||||||
return write((const uint8_t*)buf, strlen(buf));
|
return write((const uint8_t*)buf, strlen(buf));
|
||||||
}
|
}
|
||||||
@ -55,11 +59,17 @@ class WiFiClientSecure_light : public WiFiClient {
|
|||||||
int available() override;
|
int available() override;
|
||||||
int read() override;
|
int read() override;
|
||||||
int peek() override;
|
int peek() override;
|
||||||
|
#ifdef ESP8266
|
||||||
size_t peekBytes(uint8_t *buffer, size_t length) override;
|
size_t peekBytes(uint8_t *buffer, size_t length) override;
|
||||||
bool flush(unsigned int maxWaitMs);
|
bool flush(unsigned int maxWaitMs);
|
||||||
bool stop(unsigned int maxWaitMs);
|
bool stop(unsigned int maxWaitMs);
|
||||||
void flush() override { (void)flush(0); }
|
void flush() override { (void)flush(0); }
|
||||||
void stop() override { (void)stop(0); }
|
void stop() override { (void)stop(0); }
|
||||||
|
#else
|
||||||
|
size_t peekBytes(uint8_t *buffer, size_t length);
|
||||||
|
void flush() override;
|
||||||
|
void stop() override;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Only check SHA1 fingerprint of public key
|
// Only check SHA1 fingerprint of public key
|
||||||
void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2,
|
void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2,
|
||||||
|
@ -679,8 +679,13 @@ void MqttReconnect(void) {
|
|||||||
if (MqttClient.connect(TasmotaGlobal.mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, TasmotaGlobal.mqtt_data, MQTT_CLEAN_SESSION)) {
|
if (MqttClient.connect(TasmotaGlobal.mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, TasmotaGlobal.mqtt_data, MQTT_CLEAN_SESSION)) {
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
if (Mqtt.mqtt_tls) {
|
if (Mqtt.mqtt_tls) {
|
||||||
|
#ifdef ESP8266
|
||||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, max ThunkStack used %d"),
|
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, max ThunkStack used %d"),
|
||||||
millis() - mqtt_connect_time, tlsClient->getMaxThunkStackUse());
|
millis() - mqtt_connect_time, tlsClient->getMaxThunkStackUse());
|
||||||
|
#elif defined(ESP32)
|
||||||
|
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, stack low mark %d"),
|
||||||
|
millis() - mqtt_connect_time, uxTaskGetStackHighWaterMark(nullptr));
|
||||||
|
#endif
|
||||||
if (!tlsClient->getMFLNStatus()) {
|
if (!tlsClient->getMFLNStatus()) {
|
||||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "MFLN not supported by TLS server"));
|
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "MFLN not supported by TLS server"));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user