Skip to content

Commit

Permalink
Solidify from url (#439)
Browse files Browse the repository at this point in the history
* Update changelogs

* Fix compile warning (arendst#21411)

* Remove non IDF5 code

* Enabled watchdog for ESP32 and variants (arendst#21414)

* Drop support of old insecure fingerprint algorithm (deprecated since v8.4.0) (arendst#21416)

* Revert "Enabled watchdog for ESP32 and variants (arendst#21414)" (arendst#21417)

This reverts commit e4ea62c.

* Update changelogs

* Fix Domoticz re-subscribe on MQTT reconnect. Regression from v13.4.0.3 (arendst#21281)

* embed solidify external Berry files from url

* typo

* clang install in gitpod Dockerfile

* clang install with sudo

* try python3.12

* try BLE in var globs

* solidify first

* use full workspace for clang

---------

Co-authored-by: Theo Arends <11044339+arendst@users.noreply.github.com>
Co-authored-by: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Co-authored-by: Staars <baars@klinikum-brandenburg.de>
  • Loading branch information
4 people authored May 17, 2024
1 parent 1518566 commit aebf4d1
Show file tree
Hide file tree
Showing 20 changed files with 176 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .gitpod.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM gitpod/workspace-python-3.11
FROM gitpod/workspace-full

USER gitpod
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ All notable changes to this project will be documented in this file.
### Breaking Changed

### Changed
- ESP32 compiler option from `target-align` to `no-target-align` (#21407)

### Fixed
- Domoticz re-subscribe on MQTT reconnect. Regression from v13.4.0.3 (#21281)

### Removed

- Support of old insecure fingerprint algorithm. Deprecated since v8.4.0 (#21417)

## [Released]

Expand Down
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
### Breaking Changed

### Changed
- ESP32 compiler option from `target-align` to `no-target-align` [#21407](https://github.com/arendst/Tasmota/issues/21407)

### Fixed
- Domoticz re-subscribe on MQTT reconnect. Regression from v13.4.0.3 [#21281](https://github.com/arendst/Tasmota/issues/21281)

### Removed
- Support of old insecure fingerprint algorithm. Deprecated since v8.4.0 [#21417](https://github.com/arendst/Tasmota/issues/21417)
57 changes: 0 additions & 57 deletions lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,25 +813,6 @@ extern "C" {
// Return 0 on validation success, !0 on validation error
static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) {
br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx;
// **** Start patch Castellucci
/*
br_sha1_context sha1_context;
pubkeyfingerprint_pubkey_fingerprint(&sha1_context, xc->ctx.pkey.key.rsa);
br_sha1_out(&sha1_context, xc->pubkey_recv_fingerprint); // copy to fingerprint
if (!xc->fingerprint_all) {
if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) {
return 0;
}
if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) {
return 0;
}
return 1; // no match, error
} else {
// Default (no validation at all) or no errors in prior checks = success.
return 0;
}
*/
// set fingerprint status byte to zero
// FIXME: find a better way to pass this information
xc->pubkey_recv_fingerprint[20] = 0;
Expand All @@ -844,45 +825,7 @@ extern "C" {
if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) {
return 0;
}

#ifndef USE_MQTT_TLS_DROP_OLD_FINGERPRINT
// No match under new algorithm, do some basic checking on the key.
//
// RSA keys normally have an e value of 65537, which is three bytes long.
// Other e values are suspicious, but if the modulus is a standard size
// (multiple of 512 bits/64 bytes), any public exponent up to eight bytes
// long will be allowed.
//
// A legitimate key could possibly be marked as bad by this check, but
// the user would have had to really worked at making a strange key.
if (!(xc->ctx.pkey.key.rsa.elen == 3
&& xc->ctx.pkey.key.rsa.e[0] == 1
&& xc->ctx.pkey.key.rsa.e[1] == 0
&& xc->ctx.pkey.key.rsa.e[2] == 1)) {
if (xc->ctx.pkey.key.rsa.nlen & 63 != 0 || xc->ctx.pkey.key.rsa.elen > 8) {
return 2; // suspicious key, return error
}
}

// try the old algorithm and potentially mark for update
pubkeyfingerprint_pubkey_fingerprint(xc, true);
if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) {
xc->pubkey_recv_fingerprint[20] |= 1; // mark for update
}
if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) {
xc->pubkey_recv_fingerprint[20] |= 2; // mark for update
}
if (!xc->pubkey_recv_fingerprint[20]) {
return 1; // not marked for update because no match, error
}

// the old fingerprint format matched, recompute new one for update
pubkeyfingerprint_pubkey_fingerprint(xc, false);

return 0;
#else // USE_TLS_OLD_FINGERPRINT_COMPAT
return 1; // no match, error
#endif // USE_TLS_OLD_FINGERPRINT_COMPAT
} else {
// Default (no validation at all) or no errors in prior checks = success.
return 0;
Expand Down
2 changes: 1 addition & 1 deletion lib/libesp32/berry_tasmota/solidify_all.be
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var globs = "path,ctypes_bytes_dyn,tasmota,ccronexpr,gpio,light,webclient,load,M
"lv_clock,lv_clock_icon,lv_signal_arcs,lv_signal_bars,lv_wifi_arcs_icon,lv_wifi_arcs,"
"lv_wifi_bars_icon,lv_wifi_bars,"
"_lvgl,"
"int64"
"int64,BLE"

for g:string2.split(globs, ",")
global.(g) = nil
Expand Down
140 changes: 140 additions & 0 deletions pio-tools/solidify-from-url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Little convenience script to solidify external berry files as embedded

Import("env")

import os
import sys
from genericpath import exists
from os.path import join
import subprocess
from colorama import Fore, Back, Style
import requests
import re

IS_WINDOWS = sys.platform.startswith("win")

def ensureBerry():
BERRY_GEN_DIR = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry")
os.chdir(BERRY_GEN_DIR)
BERRY_EXECUTABLE = join(BERRY_GEN_DIR,"berry")
if IS_WINDOWS:
berry_executable = join(BERRY_GEN_DIR,"berry.exe")
else:
if os.path.exists(BERRY_EXECUTABLE) == False:
print("Will compile Berry executable")
make_cmd = "make"
subprocess.call(make_cmd, shell=False)

if os.path.exists(BERRY_EXECUTABLE):
return BERRY_EXECUTABLE
else:
return None

def addEntryToModtab(source):
code = source.decode("utf-8")
class_name = None
is_module = False

pattern = (r'''(?<=module\()[^"].*''') # module??
result = re.findall(pattern,code)
if len(result) > 0:
class_name = result[0].replace("'","").replace('"','').replace(")","")
print(class_name+" is a module")
is_module = True
else: # just a class
pattern = (r'(?<=#@ solidify:).*')
result = re.findall(pattern,code)
if len(result) > 0:
class_name = result[0].split(",")[0]
print(class_name+" is a class")
if class_name == None:
print("Could not find class name - is '#@ solidify:' used in Berry file??")
print(Fore.RED + "Aborting build process!!")
quit()
MODTAB_PATH = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry","default","be_modtab.c")
with open(MODTAB_PATH, 'r') as file:
code = file.read() # reuse code var for modtab file
if is_module:
nmodule = f" &be_native_module({class_name}),"
if code.find(nmodule) == -1:
code = code.replace(
"&be_native_module(string),",
f'&be_native_module(string),\n{nmodule}'
)
enmodule = f"be_extern_native_module({class_name});"
if code.find(enmodule) == -1:
code = code.replace(
"be_extern_native_module(string);",
f'be_extern_native_module(string);\n{enmodule}'
)
else:
nclass = f" &be_native_class({class_name}),"
if code.find(nclass) == -1:
code = code.replace(
"&be_native_class(tasmota),",
f'&be_native_class(tasmota),\n{nclass}'
)
enclass = f"be_extern_native_class({class_name});"
if code.find(enclass) == -1:
code = code.replace(
"be_extern_native_class(tasmota);",
f'be_extern_native_class(tasmota);\n{enclass}'
)

with open(MODTAB_PATH, 'w') as file:
file.write(code)


def addHeaderFile(name):
print("Will solidify ",name)
name = name.split(".")[0]
data = f"""
/********************************************************************
* {name} module
*
*******************************************************************/
#include "solidify/solidified_{name}.h"
"""
file_name = f"be_{name}_lib.c"
file_path = join(BERRY_SOLIDIFY_DIR,"src",file_name)
open(file_path,"w").write(data)

def prepareBerryFiles(files):
embedded_dir = join("src","embedded")
for file in files:
if "http" and "://" in file:
response = requests.get(file.split(" ")[0])
if response.ok:
target = join(embedded_dir,file.split(os.path.sep)[-1])
if len(file.split(" ")) > 1:
target = join(embedded_dir,file.split(" ")[1])
print("Renaming",(file.split(os.path.sep)[-1]).split(" ")[0],"to",file.split(" ")[1])
open(target, "wb").write(response.content)
addHeaderFile(file.split(os.path.sep)[-1])
addEntryToModtab(response.content)
else:
print(Fore.RED + "Failed to download: ",file)
continue
# maybe later ...
# if os.path.isdir(file):
# continue
# else:
# shutil.copy(file, embedded_dir)
return True

try:
files = env.GetProjectOption("custom_berry_solidify")
except:
print("Nothing more to solidify")
else:

BERRY_EXECUTABLE = ensureBerry()

BERRY_SOLIDIFY_DIR = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry_tasmota")
os.chdir(BERRY_SOLIDIFY_DIR)

if prepareBerryFiles(files.splitlines()):
solidify_command = BERRY_EXECUTABLE
solidify_flags = " -s -g solidify_all.be"
print("Start solidification for 'berry_tasmota':")
subprocess.call(solidify_command + solidify_flags, shell=True)
1 change: 1 addition & 0 deletions platformio_tasmota32.ini
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ lib_ignore =
Preferences
ArduinoOTA
extra_scripts = pre:pio-tools/add_c_flags.py
pre:pio-tools/solidify-from-url.py
pre:pio-tools/gen-berry-structures.py
post:pio-tools/post_esp32.py
${esp_defaults.extra_scripts}
Expand Down
17 changes: 0 additions & 17 deletions tasmota/my_user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,6 @@

#define MQTT_HOST "" // [MqttHost]

// XXX temporary - leave for a few releases so people compiling in
// fingerprints have a chance to update their configuration files
#if !defined(USE_MQTT_TLS_DROP_OLD_FINGERPRINT) && defined(MQTT_FINGERPRINT1) || defined(MQTT_FINGERPRINT2)
#error "The old TLS fingerprint format is being removed.\n\
Please ensure your TLS fingerprint(s) are using the new version, then add\n\
\n\
#define USE_MQTT_TLS_DROP_OLD_FINGERPRINT\n\
\n\
to your user_config_override.h file.\n\
\n\
An online tool to calculate TLS fingerprints is available here at:\n\
https://rya.nc/tasmota-fingerprint.html"
#endif

#define MQTT_FINGERPRINT1 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // [MqttFingerprint1] (auto-learn)
#define MQTT_FINGERPRINT2 0xDA,0x39,0xA3,0xEE,0x5E,0x6B,0x4B,0x0D,0x32,0x55,0xBF,0xEF,0x95,0x60,0x18,0x90,0xAF,0xD8,0x07,0x09 // [MqttFingerprint2] (invalid - value from sha1(""))
#define MQTT_PORT 1883 // [MqttPort] MQTT port (10123 on CloudMQTT)
Expand Down Expand Up @@ -462,9 +448,6 @@ An online tool to calculate TLS fingerprints is available here at:\n\
// #define USE_MQTT_AWS_IOT // [Deprecated] Enable MQTT for AWS IoT - requires a private key (+11.9k code, +0.4k mem)
// Note: you need to generate a private key + certificate per device and update 'tasmota/tasmota_aws_iot.cpp'
// Full documentation here: https://github.com/arendst/Tasmota/wiki/AWS-IoT
#define USE_MQTT_TLS_DROP_OLD_FINGERPRINT // If you use fingerprint (i.e. not CA) validation, the algorithm changed to a more secure one.
// Any valid fingerprint with the old algo will be automatically updated to the new algo.
// Enable this if you want to disable the old algo check, which should be more secure
// for USE_4K_RSA (support for 4096 bits certificates, instead of 2048), you need to uncommend `-DUSE_4K_RSA` in `build_flags` from `platform.ini` or `platform_override.ini`

// -- MQTT - TLS - Azure IoT & IoT Central ---------
Expand Down
6 changes: 3 additions & 3 deletions tasmota/tasmota_support/settings.ino
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ bool RtcRebootValid(void) {

extern "C" {
#include "spi_flash.h"
#if ESP_IDF_VERSION_MAJOR >= 5
#include "spi_flash_mmap.h"
#endif
#ifdef ESP32
#include "spi_flash_mmap.h"
#endif // ESP32
}

#ifdef ESP8266
Expand Down
4 changes: 0 additions & 4 deletions tasmota/tasmota_support/support_a_i2c.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ bool I2cBegin(int sda, int scl, uint32_t frequency) {
Wire.begin(sda, scl);
#endif
#ifdef ESP32
#if ESP_IDF_VERSION_MAJOR > 3 // Core 2.x uses a different I2C library
static bool reinit = false;
if (reinit) { Wire.end(); }
#endif // ESP_IDF_VERSION_MAJOR > 3
result = Wire.begin(sda, scl, frequency);
#if ESP_IDF_VERSION_MAJOR > 3 // Core 2.x uses a different I2C library
reinit = result;
#endif // ESP_IDF_VERSION_MAJOR > 3
#endif
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus1 %d"), result);
return result;
Expand Down
4 changes: 1 addition & 3 deletions tasmota/tasmota_support/support_command.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2674,11 +2674,9 @@ void CmndWifi(void) {
break;
}
#ifdef ESP32
#if ESP_IDF_VERSION_MAJOR >= 5
case 6: // Wifi 6 = BGNAX
option = 4;
#endif // ESP_IDF_VERSION_MAJOR
#endif // ESP32/ESP8266
#endif // ESP32
case 4: // Wifi 4 = BGN
case 3: // Wifi 3 = BG
case 2: // Wifi 2 = B
Expand Down
10 changes: 2 additions & 8 deletions tasmota/tasmota_support/support_crash_recorder.ino
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,8 @@ void CrashDumpClear(void)
// esp_err_t IRAM_ATTR esp_backtrace_print(int depth)

#include "freertos/xtensa_api.h"
#if ESP_IDF_VERSION_MAJOR >= 5
#include "esp_debug_helpers.h"
#include "esp_cpu_utils.h"
#elif ESP_IDF_VERSION_MAJOR >= 4
#include "esp_debug_helpers.h"
#else // IDF 3.x
#include "esp_panic.h"
#endif
#include "esp_debug_helpers.h"
#include "esp_cpu_utils.h"
extern "C" {
// esp-idf 3.x
void __real_panicHandler(XtExcFrame *frame);
Expand Down
18 changes: 3 additions & 15 deletions tasmota/tasmota_support/support_esp32.ino
Original file line number Diff line number Diff line change
Expand Up @@ -577,12 +577,8 @@ uint32_t ESP_getMaxAllocPsram(void) {
}

extern "C" {
#if ESP_IDF_VERSION_MAJOR >= 5
// bool IRAM_ATTR __attribute__((pure)) esp_psram_is_initialized(void)
bool esp_psram_is_initialized(void);
#else
bool esp_spiram_is_initialized(void);
#endif
// bool IRAM_ATTR __attribute__((pure)) esp_psram_is_initialized(void)
bool esp_psram_is_initialized(void);
}

// this function is a replacement for `psramFound()`.
Expand Down Expand Up @@ -748,11 +744,7 @@ typedef struct {
bool rev3 = (chip_revision >= 300);
// bool single_core = (1 == ESP.getChipCores());
bool single_core = (1 == chip_info.cores);

uint32_t pkg_version = 0;
#if (ESP_IDF_VERSION_MAJOR >= 5)
pkg_version = bootloader_common_get_chip_ver_pkg();
#endif
uint32_t pkg_version = bootloader_common_get_chip_ver_pkg();

switch (chip_model) {
case 0:
Expand Down Expand Up @@ -931,11 +923,7 @@ String GetDeviceHardwareRevision(void) {

esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
#if ESP_IDF_VERSION_MAJOR >= 5
uint32_t chip_revision = chip_info.revision; // 16-bit chip revision number (in format MXX; where M - wafer major version, XX - wafer minor version)
#else
uint32_t chip_revision = chip_info.full_revision; // 16-bit chip revision number (in format MXX; where M - wafer major version, XX - wafer minor version)
#endif
char revision[16];
snprintf_P(revision, sizeof(revision), PSTR(" v%d.%d"), chip_revision / 100, chip_revision % 100);
result += revision; // ESP32-C3 v0.3
Expand Down
Loading

0 comments on commit aebf4d1

Please sign in to comment.