From a990643ca08f16b7c09cf4f80e89f361fd8e5b9e Mon Sep 17 00:00:00 2001 From: LordGuilly Date: Tue, 7 Nov 2023 21:58:16 +0000 Subject: [PATCH] feat(mqtt): Implement TLS encryption (certificate) Ported from https://github.com/jomjol/AI-on-the-edge-device/pull/2651 --- .../jomjol_flowcontroll/ClassFlowMQTT.cpp | 67 ++++--- .../jomjol_flowcontroll/ClassFlowMQTT.h | 9 +- .../components/jomjol_helper/sdcard_check.cpp | 6 + .../components/jomjol_mqtt/interface_mqtt.cpp | 178 ++++++++++++++---- code/components/jomjol_mqtt/interface_mqtt.h | 1 + code/main/main.cpp | 3 +- code/sdkconfig.defaults | 7 + sd-card/config/config.ini | 4 + sd-card/html/edit_config_param.html | 54 ++++++ sd-card/html/readconfigparam.js | 4 + 10 files changed, 269 insertions(+), 64 deletions(-) diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index f8568197c..9f81349f6 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -28,26 +28,23 @@ extern const char* libfive_git_branch(void); void ClassFlowMQTT::SetInitialParameter(void) { presetFlowStateHandler(true); + flowpostprocessing = NULL; + previousElement = NULL; + ListFlowControll = NULL; + disabled = false; + uri = ""; - topic = ""; - topicError = ""; - topicRate = ""; - topicTimeStamp = ""; maintopic = wlan_config.hostname; - - topicUptime = ""; - topicFreeMem = ""; - clientname = wlan_config.hostname; - - flowpostprocessing = NULL; user = ""; - password = ""; + password = ""; + TLSEncryption = false; + TLSCACertFilename = ""; + TLSClientCertFilename = ""; + TLSClientKeyFilename = ""; SetRetainFlag = false; - previousElement = NULL; - ListFlowControll = NULL; - disabled = false; - keepAlive = 25*60; + + keepAlive = 25*60; } ClassFlowMQTT::ClassFlowMQTT() @@ -93,18 +90,18 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, std::string& aktparamgraph) aktparamgraph = trim(aktparamgraph); if (aktparamgraph.size() == 0) - if (!this->GetNextParagraph(pfile, aktparamgraph)) + if (!GetNextParagraph(pfile, aktparamgraph)) return false; if (toUpper(aktparamgraph).compare("[MQTT]") != 0) // Paragraph does not fit MQTT return false; - while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) + while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph)) { splitted = ZerlegeZeile(aktparamgraph); if ((toUpper(splitted[0]) == "URI") && (splitted.size() > 1)) { - this->uri = splitted[1]; + uri = splitted[1]; } if (((toUpper(splitted[0]) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1)) @@ -114,18 +111,41 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, std::string& aktparamgraph) if ((toUpper(splitted[0]) == "CLIENTID") && (splitted.size() > 1)) { - this->clientname = splitted[1]; + clientname = splitted[1]; } if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1)) { - this->user = splitted[1]; + user = splitted[1]; } if ((toUpper(splitted[0]) == "PASSWORD") && (splitted.size() > 1)) { - this->password = splitted[1]; - } + password = splitted[1]; + } + + if ((toUpper(splitted[0]) == "TLSENCRYPTION") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + TLSEncryption = true; + else + TLSEncryption = false; + } + + if ((toUpper(splitted[0]) == "TLSCACERT") && (splitted.size() > 1)) + { + TLSCACertFilename = "/sdcard" + splitted[1]; + } + + if ((toUpper(splitted[0]) == "TLSCLIENTCERT") && (splitted.size() > 1)) + { + TLSClientCertFilename = "/sdcard" + splitted[1]; + } + + if ((toUpper(splitted[0]) == "TLSCLIENTKEY") && (splitted.size() > 1)) + { + TLSClientKeyFilename = "/sdcard" + splitted[1]; + } if ((toUpper(splitted[0]) == "RETAINMESSAGES") && (splitted.size() > 1)) { @@ -205,7 +225,8 @@ bool ClassFlowMQTT::Start(float _processingInterval) mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, _processingInterval); bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED, - LWT_DISCONNECTED, keepAlive, SetRetainFlag, (void *)&GotConnected); + LWT_DISCONNECTED, TLSEncryption, TLSCACertFilename, TLSClientCertFilename, + TLSClientKeyFilename, keepAlive, SetRetainFlag, (void *)&GotConnected); if (!MQTTConfigCheck) { return false; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h index 3a041ac4c..d4250b531 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h @@ -15,12 +15,13 @@ class ClassFlowMQTT : public ClassFlow { protected: ClassFlowPostProcessing* flowpostprocessing; - std::string uri, topic, topicError, clientname, topicRate, topicTimeStamp, topicUptime, topicFreeMem; + std::string uri, maintopic, clientname; std::string user, password; - std::string maintopic; - int keepAlive; // Seconds + bool TLSEncryption; + std::string TLSCACertFilename, TLSClientCertFilename, TLSClientKeyFilename; bool SetRetainFlag; - + int keepAlive; // Seconds + void SetInitialParameter(void); public: diff --git a/code/components/jomjol_helper/sdcard_check.cpp b/code/components/jomjol_helper/sdcard_check.cpp index 9e79155b9..2f1d60b8b 100644 --- a/code/components/jomjol_helper/sdcard_check.cpp +++ b/code/components/jomjol_helper/sdcard_check.cpp @@ -81,6 +81,12 @@ bool SDCardCheckFolderFilePresence() bRetval = false; } + /* check if folder exists: config/certs */ + if (stat("/sdcard/config/certs", &sb) != 0) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /config/certs not found"); + bRetval = false; + } + /* check if folder exists: html */ if (stat("/sdcard/html", &sb) != 0) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /html not found"); diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index 3f832e3e3..283253eaa 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -9,7 +9,13 @@ #include "cJSON.h" #include "../../include/defines.h" -static const char *TAG = "MQTT IF"; +//#define DEBUG_DETAIL_ON + +#ifdef DEBUG_DETAIL_ON +#include "esp_timer.h" +#endif + +static const char *TAG = "MQTT_IF"; std::map>* connectFunktionMap = NULL; std::map>* subscribeFunktionMap = NULL; @@ -27,6 +33,8 @@ bool mqtt_connected = false; esp_mqtt_client_handle_t client = NULL; std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic; +bool TLSEncryption; +std::string TLSCACert, TLSClientCert, TLSClientKey; int keepalive; bool SetRetainFlag; void (*callbackOnConnected)(std::string, bool) = NULL; @@ -87,7 +95,8 @@ bool MQTTPublish(std::string _key, std::string _content, int qos, bool retained_ } -static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { +static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) +{ std::string topic = ""; switch (event->event_id) { case MQTT_EVENT_BEFORE_CONNECT: @@ -164,15 +173,22 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_NOT_AUTHORIZED) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, not authorized. Check username/password (0x05)"); } + + // Log any ESP-TLS error: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/error-codes.html + if (TLSEncryption && (event->error_handle->esp_tls_last_esp_err != ESP_OK)) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, TLS error code: " + + intToHexString(event->error_handle->esp_tls_last_esp_err) + + " (More infos: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/error-codes.html"); + } #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "MQTT_EVENT_ERROR - esp_mqtt_error_codes:"); - ESP_LOGD(TAG, "error_type:%d", event->error_handle->error_type); - ESP_LOGD(TAG, "connect_return_code:%d", event->error_handle->connect_return_code); - ESP_LOGD(TAG, "esp_transport_sock_errno:%d", event->error_handle->esp_transport_sock_errno); - ESP_LOGD(TAG, "esp_tls_last_esp_err:%d", event->error_handle->esp_tls_last_esp_err); - ESP_LOGD(TAG, "esp_tls_stack_err:%d", event->error_handle->esp_tls_stack_err); - ESP_LOGD(TAG, "esp_tls_cert_verify_flags:%d", event->error_handle->esp_tls_cert_verify_flags); + ESP_LOGI(TAG, "MQTT_EVENT_ERROR - esp_mqtt_error_codes:"); + ESP_LOGI(TAG, "error_type:%d", event->error_handle->error_type); + ESP_LOGI(TAG, "connect_return_code:%d", event->error_handle->connect_return_code); + ESP_LOGI(TAG, "esp_transport_sock_errno:%d", event->error_handle->esp_transport_sock_errno); + ESP_LOGI(TAG, "esp_tls_last_esp_err:%d", event->error_handle->esp_tls_last_esp_err); + ESP_LOGI(TAG, "esp_tls_stack_err:%d", event->error_handle->esp_tls_stack_err); + ESP_LOGI(TAG, "esp_tls_cert_verify_flags:%d", event->error_handle->esp_tls_cert_verify_flags); #endif break; @@ -185,17 +201,19 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) { } -static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) { +static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) +{ ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, (int)event_id); mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data); } bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, - std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected, - int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) { - if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0)) - { + std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected, + bool _TLSEncryption, std::string _TLSCACertFilename, std::string _TLSClientCertFilename, + std::string _TLSClientKeyFilename, int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) +{ + if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0)) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init aborted! Config error (URI, MainTopic or ClientID missing)"); return false; } @@ -210,17 +228,79 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us maintopic = _maintopic; callbackOnConnected = ( void (*)(std::string, bool) )(_callbackOnConnected); - if (_user.length() && _password.length()){ + if (!_user.empty()) { user = _user; + } + + if (!_password.empty()) { password = _password; } + // TLS Encryption parameter + TLSEncryption = _TLSEncryption; + + if (TLSEncryption) { + if (uri.substr(0,8) != "mqtts://") { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "TLS: URI parameter needs to be configured with \'mqtts://\'"); + return false; + } + + if (uri.substr(uri.find_last_of(":")+1, 4) != "8883") { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "TLS: URI parameter not using default MQTT TLS port \'8883\'"); + } + + if (!_TLSCACertFilename.empty()) { // TLS parameter activated and not empty + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "TLS: CA certificate file: " + _TLSCACertFilename); + std::ifstream ifs(_TLSCACertFilename); + std::string content((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); + TLSCACert = content; + + if (TLSCACert.empty()) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "TLS: Failed to load CA certificate"); + } + } + + if (!_TLSClientCertFilename.empty()) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "TLS: Client certificate file: " + _TLSClientCertFilename); + std::ifstream cert_ifs(_TLSClientCertFilename); + std::string cert_content((std::istreambuf_iterator(cert_ifs)), (std::istreambuf_iterator())); + TLSClientCert = cert_content; + + if (TLSClientCert.empty()) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "TLS: Failed to load client certificate"); + } + } + + if (!_TLSClientKeyFilename.empty()) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "TLS: Client key file: " + _TLSClientKeyFilename); + std::ifstream key_ifs(_TLSClientKeyFilename); + std::string key_content((std::istreambuf_iterator(key_ifs)), (std::istreambuf_iterator())); + TLSClientKey = key_content; + + if (TLSClientKey.empty()) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "TLS: Failed to load client key"); + } + } + } + else { + if (uri.substr(0,7) != "mqtt://") { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "URI parameter needs to be configured with \'mqtt://\'"); + return false; + } + + if (uri.substr(uri.find_last_of(":")+1, 4) != "1883") { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI parameter not using default MQTT port \'1883\'"); + } + } + #ifdef __HIDE_PASSWORD - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + ", password: XXXXXXXX, maintopic: " - + maintopic + ", last-will-topic: " + lwt_topic + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag)); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + + ", password: ******, maintopic: " + maintopic + ", last-will-topic: " + lwt_topic + + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag)); #else - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + ", password: " + password + ", maintopic: " - + maintopic + ", last-will-topic: " + lwt_topic + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag)); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + + ", password: " + password + ", maintopic: " + maintopic + ", last-will-topic: " + lwt_topic + + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag)); #endif mqtt_configOK = true; @@ -228,7 +308,8 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us } -int MQTT_Init() { +int MQTT_Init() +{ if (mqtt_initialized) { return 0; } @@ -263,18 +344,38 @@ int MQTT_Init() { mqtt_cfg.session.keepalive = keepalive; mqtt_cfg.buffer.size = 2048; // size of MQTT send/receive buffer (Default: 1024) - if (user.length() && password.length()){ + if (!user.empty()) { mqtt_cfg.credentials.username = user.c_str(); + } + + if (!password.empty()) { mqtt_cfg.credentials.authentication.password = password.c_str(); } + if (TLSEncryption) { + if (!TLSCACert.empty()) { + mqtt_cfg.broker.verification.certificate = TLSCACert.c_str(); + mqtt_cfg.broker.verification.certificate_len = TLSCACert.length() + 1; + mqtt_cfg.broker.verification.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field + } + + if (!TLSClientCert.empty()) { + mqtt_cfg.credentials.authentication.certificate = TLSClientCert.c_str(); + mqtt_cfg.credentials.authentication.certificate_len = TLSClientCert.length() + 1; + } + + if (!TLSClientKey.empty()) { + mqtt_cfg.credentials.authentication.key = TLSClientKey.c_str(); + mqtt_cfg.credentials.authentication.key_len = TLSClientKey.length() + 1; + } + } + #ifdef DEBUG_DETAIL_ON LogFile.WriteHeapInfo("MQTT Client Init"); #endif client = esp_mqtt_client_init(&mqtt_cfg); - if (client) - { + if (client) { esp_err_t ret = esp_mqtt_client_register_event(client, esp_mqtt_ID, mqtt_event_handler, client); if (ret != ESP_OK) { @@ -287,8 +388,7 @@ int MQTT_Init() { LogFile.WriteHeapInfo("MQTT Client Start"); #endif ret = esp_mqtt_client_start(client); - if (ret != ESP_OK) - { + if (ret != ESP_OK) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Client start failed (retval=" + std::to_string(ret) + ")"); mqtt_initialized = false; return -1; @@ -299,17 +399,16 @@ int MQTT_Init() { return 1; } } - else - { + else { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init failed, no handle created"); mqtt_initialized = false; return -1; } - } -void MQTTdestroy_client(bool _disable = false) { +void MQTTdestroy_client(bool _disable = false) +{ if (client) { if (mqtt_connected) { MQTTdestroySubscribeFunction(); @@ -327,12 +426,14 @@ void MQTTdestroy_client(bool _disable = false) { } -bool getMQTTisEnabled() { +bool getMQTTisEnabled() +{ return mqtt_enabled; } -bool getMQTTisConnected() { +bool getMQTTisConnected() +{ return mqtt_connected; } @@ -388,7 +489,8 @@ bool mqtt_handler_set_fallbackvalue(std::string _topic, char* _data, int _data_l } -void MQTTconnected(){ +void MQTTconnected() +{ if (mqtt_connected) { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Connected to broker"); @@ -423,7 +525,8 @@ void MQTTconnected(){ } -void MQTTregisterConnectFunction(std::string name, std::function func){ +void MQTTregisterConnectFunction(std::string name, std::function func) +{ ESP_LOGD(TAG, "MQTTregisteronnectFunction %s\r\n", name.c_str()); if (connectFunktionMap == NULL) { connectFunktionMap = new std::map>(); @@ -442,7 +545,8 @@ void MQTTregisterConnectFunction(std::string name, std::function func){ } -void MQTTunregisterConnectFunction(std::string name){ +void MQTTunregisterConnectFunction(std::string name) +{ ESP_LOGD(TAG, "unregisterConnnectFunction %s\r\n", name.c_str()); if ((connectFunktionMap != NULL) && (connectFunktionMap->find(name) != connectFunktionMap->end())) { connectFunktionMap->erase(name); @@ -450,7 +554,8 @@ void MQTTunregisterConnectFunction(std::string name){ } -void MQTTregisterSubscribeFunction(std::string topic, std::function func){ +void MQTTregisterSubscribeFunction(std::string topic, std::function func) +{ ESP_LOGD(TAG, "registerSubscribeFunction %s", topic.c_str()); if (subscribeFunktionMap == NULL) { subscribeFunktionMap = new std::map>(); @@ -465,7 +570,8 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) { diff --git a/code/components/jomjol_mqtt/interface_mqtt.h b/code/components/jomjol_mqtt/interface_mqtt.h index 79cc09564..78e39c814 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.h +++ b/code/components/jomjol_mqtt/interface_mqtt.h @@ -11,6 +11,7 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected, + bool _TLSEncryption, std::string _TLSCACertFilename, std::string _TLSClientCertFilename, std::string _TLSClientKeyFilename, int _keepalive, bool SetRetainFlag, void *callbackOnConnected); int MQTT_Init(); void MQTTdestroy_client(bool _disable); diff --git a/code/main/main.cpp b/code/main/main.cpp index 3f6ce4f4c..97f1e7ea1 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -233,8 +233,9 @@ extern "C" void app_main(void) // Correct creation of these folders will be checked with function "SDCardCheckFolderFilePresence" // ******************************************** MakeDir("/sdcard/firmware"); // mandatory for OTA firmware update - MakeDir("/sdcard/img_tmp"); // mandatory for setting up alignment marks + MakeDir("/sdcard/img_tmp"); // mandatory for setting up alignment marker MakeDir("/sdcard/demo"); // mandatory for demo mode + MakeDir("/sdcard/config/certs"); // mandatory for TLS encryption // Check for updates // ******************************************** diff --git a/code/sdkconfig.defaults b/code/sdkconfig.defaults index ac6df4393..983f99386 100644 --- a/code/sdkconfig.defaults +++ b/code/sdkconfig.defaults @@ -60,6 +60,13 @@ CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y + + # # ADC Calibration Configurations # diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 70e885a80..ce911b00e 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -60,6 +60,10 @@ MainTopic = watermeter ClientID = watermeter ;user = undefined ;password = undefined +TLSEncryption = false +TLSCACert = /config/certs/mqtt_cacrt.pem +TLSClientCert = /config/certs/mqtt_clientcrt.pem +TLSClientKey = /config/certs/mqtt_clientkey.pem RetainMessages = false HomeassistantDiscovery = false MeterType = other diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 0e7df4a53..35363bd1a 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -892,6 +892,49 @@

Configuration

$TOOLTIP_MQTT_password + + + TLS Encryption + + + + + $TOOLTIP_MQTT_TLSEncryption + + + + + CA Certificate + + + + + $TOOLTIP_MQTT_TLSCACert + + + + + Client Certificate + + + + + $TOOLTIP_MQTT_TLSClientCert + + + + + Client Key + + + + + $TOOLTIP_MQTT_TLSClientKey + + Retain Messages @@ -2282,6 +2325,10 @@

Configuration

WriteParameter(param, category, "MQTT", "ClientID", false); WriteParameter(param, category, "MQTT", "user", true); WriteParameter(param, category, "MQTT", "password", true); + WriteParameter(param, category, "MQTT", "TLSEncryption", false); + WriteParameter(param, category, "MQTT", "TLSCACert", false); + WriteParameter(param, category, "MQTT", "TLSClientCert", false); + WriteParameter(param, category, "MQTT", "TLSClientKey", false); WriteParameter(param, category, "MQTT", "RetainMessages", false); WriteParameter(param, category, "MQTT", "HomeassistantDiscovery", false); WriteParameter(param, category, "MQTT", "MeterType", false); @@ -2323,6 +2370,9 @@

Configuration

WriteParameter(param, category, "System", "CPUFrequency", false); WriteModelFiles(); + + // Visualize subparameter of a parameter + setEnabled("MQTT_TLSEncryption_parameter", document.getElementById("MQTT_TLSEncryption_value1").value == "true" ? true : false); } @@ -2416,6 +2466,10 @@

Configuration

ReadParameter(param, "MQTT", "ClientID", false); ReadParameter(param, "MQTT", "user", true); ReadParameter(param, "MQTT", "password", true); + ReadParameter(param, "MQTT", "TLSEncryption", false); + ReadParameter(param, "MQTT", "TLSCACert", false); + ReadParameter(param, "MQTT", "TLSClientCert", false); + ReadParameter(param, "MQTT", "TLSClientKey", false); ReadParameter(param, "MQTT", "RetainMessages", false); ReadParameter(param, "MQTT", "HomeassistantDiscovery", false); ReadParameter(param, "MQTT", "MeterType", false); diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index b813907c4..deb4d3289 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -188,6 +188,10 @@ function ParseConfig() { ParamAddSingleValueWithPreset(param, catname, "ClientID", true, "watermeter"); ParamAddSingleValueWithPreset(param, catname, "user", false, "undefined"); ParamAddSingleValueWithPreset(param, catname, "password", false, "undefined"); + ParamAddSingleValueWithPreset(param, catname, "TLSEncryption", false, "false"); + ParamAddSingleValueWithPreset(param, catname, "TLSCACert", true, "/config/certs/mqtt_ca.crt"); + ParamAddSingleValueWithPreset(param, catname, "TLSClientCert", true, "/config/certs/mqtt_client.crt"); + ParamAddSingleValueWithPreset(param, catname, "TLSClientKey", true, "/config/certs/mqtt_client.key"); ParamAddSingleValueWithPreset(param, catname, "RetainMessages", true, "false"); ParamAddSingleValueWithPreset(param, catname, "HomeassistantDiscovery", true, "false"); ParamAddSingleValueWithPreset(param, catname, "MeterType", true, "other");