Skip to content

Commit

Permalink
feat(mosq): Added support for TLS transport using ESP-TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
david-cermak committed Oct 8, 2024
1 parent 8c4f392 commit 7c54b18
Show file tree
Hide file tree
Showing 15 changed files with 631 additions and 20 deletions.
1 change: 1 addition & 0 deletions .github/workflows/mosq__build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ jobs:
- name: Run Test
working-directory: ${{ env.TEST_DIR }}
run: |
python -m pip install pytest-embedded-serial-esp pytest-embedded-idf pytest-rerunfailures pytest-timeout pytest-ignore-test-results
unzip ci/artifacts.zip -d ci
for dir in `ls -d ci/build_*`; do
rm -rf build sdkconfig.defaults
Expand Down
1 change: 1 addition & 0 deletions ci/check_copyright_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mosquitto_component:
allowed_licenses:
- EPL-2.0
- Apache-2.0
- BSD-3-Clause

slim_modem_examples:
include:
Expand Down
16 changes: 10 additions & 6 deletions components/mosquitto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ set(m_deps_dir ${m_dir}/deps)
set(m_srcs
${m_lib_dir}/memory_mosq.c
${m_lib_dir}/util_mosq.c
${m_lib_dir}/net_mosq.c
${m_lib_dir}/will_mosq.c
${m_lib_dir}/alias_mosq.c
${m_lib_dir}/send_mosq.c
Expand Down Expand Up @@ -46,7 +45,6 @@ set(m_srcs
${m_src_dir}/mux.c
${m_src_dir}/mux_epoll.c
${m_src_dir}/mux_poll.c
${m_src_dir}/net.c
${m_src_dir}/password_mosq.c
${m_src_dir}/persist_read.c
${m_src_dir}/persist_read_v234.c
Expand All @@ -73,20 +71,26 @@ set(m_srcs
${m_src_dir}/xtreport.c)

idf_component_register(SRCS ${m_srcs}
port/callbacks.c port/config.c port/signals.c port/ifaddrs.c port/broker.c port/files.c
port/callbacks.c
port/config.c
port/signals.c
port/ifaddrs.c
port/broker.c
port/files.c
port/net__esp_tls.c
PRIV_INCLUDE_DIRS port/priv_include port/priv_include/sys ${m_dir} ${m_src_dir}
${m_incl_dir} ${m_lib_dir} ${m_deps_dir}
INCLUDE_DIRS ${m_incl_dir} port/include
PRIV_REQUIRES newlib
PRIV_REQUIRES newlib esp-tls
)

target_compile_definitions(${COMPONENT_LIB} PRIVATE "WITH_BROKER")
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

# Some mosquittos source unconditionally define `_GNU_SOURCE` which collides with IDF build system
# Some mosquitto source unconditionally define `_GNU_SOURCE` which collides with IDF build system
# producing warning: "_GNU_SOURCE" redefined
# This workarounds this issue by undefining the macro for the selected files
set(sources_that_define_gnu_source ${m_lib_dir}/net_mosq.c ${m_src_dir}/loop.c ${m_src_dir}/mux_poll.c)
set(sources_that_define_gnu_source ${m_src_dir}/loop.c ${m_src_dir}/mux_poll.c)
foreach(offending_src ${sources_that_define_gnu_source})
set_source_files_properties(${offending_src} PROPERTIES COMPILE_OPTIONS "-U_GNU_SOURCE")
endforeach()
8 changes: 4 additions & 4 deletions components/mosquitto/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# ESP32 Mosquitto Port

This is a lightweight port of the Mosquitto broker designed to run on the ESP32. It currently supports a single listener and TCP transport only.
This is a lightweight port of the Mosquitto broker designed to run on the ESP32. It currently supports a single listener with TCP transport or TLS transport based on ESP-TLS library.

## Supported Options

The Espressif port supports a limited set of options (with plans to add more in future releases). These options can be configured through a structure passed to the `mosq_broker_start()` function. For detailed information on available configuration options, refer to the [API documentation](api.md).
The Espressif port supports a limited set of options (with plans to add more in future releases). These options can be configured through a structure passed to the `mosq_broker_run()` function. For detailed information on available configuration options, refer to the [API documentation](api.md).

## API

### Starting the Broker

To start the broker, call the `mosq_broker_start()` function with a properly configured settings structure. The broker operates in the context of the calling task and does not create a separate task.
To start the broker, call the `mosq_broker_run()` function with a properly configured settings structure. The broker operates in the context of the calling task and does not create a separate task.

It's recommended to analyze the stack size needed for the task, but in general, the broker requires at least 4 kB of stack size.

```c
mosq_broker_start(&config);
mosq_broker_run(&config);
```
## Memory Footprint Considerations
Expand Down
22 changes: 19 additions & 3 deletions components/mosquitto/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

| Type | Name |
| ---: | :--- |
| int | [**mosq\_broker\_start**](#function-mosq_broker_start) (struct [**mosq\_broker\_config**](#struct-mosq_broker_config) \*config) <br>_Start mosquitto broker._ |
| int | [**mosq\_broker\_run**](#function-mosq_broker_run) (struct [**mosq\_broker\_config**](#struct-mosq_broker_config) \*config) <br>_Start mosquitto broker._ |
| void | [**mosq\_broker\_stop**](#function-mosq_broker_stop) (void) <br>_Stops running broker._ |


## Structures and Types Documentation
Expand All @@ -37,14 +38,16 @@ Variables:

- int port <br>Port number of the broker to listen to

- esp\_tls\_cfg\_server\_t \* tls_cfg <br>ESP-TLS configuration (if TLS transport used)


## Functions Documentation

### function `mosq_broker_start`
### function `mosq_broker_run`

_Start mosquitto broker._
```c
int mosq_broker_start (
int mosq_broker_run (
struct mosq_broker_config *config
)
```
Expand All @@ -63,3 +66,16 @@ This API runs the broker in the calling thread and blocks until the mosquitto ex
**Returns:**

int Exit code (0 on success)
### function `mosq_broker_stop`

_Stops running broker._
```c
void mosq_broker_stop (
void
)
```


**Note:**

After calling this API, function mosq\_broker\_run() unblocks and returns.
5 changes: 4 additions & 1 deletion components/mosquitto/examples/broker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

This example runs a TCP broker on a specified host and port.
This example runs a broker on TLS or TCP transport, specified host and port.

### How to use this example

Expand All @@ -13,6 +13,9 @@ If you enabled also the mqtt client, this example will connect to the local brok

You can connect to the ESP32 mosquitto broker using some other client using the ESP32 IPv4 address and the port specified in the project configuration menu.

> [!IMPORTANT]
> Please do not reuse the test certificates and keys used in this example. Note that these are single purpose, self-signed with common name set to `"127.0.0.1"`.
### Test version

This example is also used for testing on loopback interface only, disabling any actual connection, just using the local mqtt client to the loopback interface.
Expand Down
3 changes: 2 additions & 1 deletion components/mosquitto/examples/broker/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
idf_component_register(SRCS "broker.c"
PRIV_REQUIRES newlib nvs_flash esp_netif esp_event mqtt)
PRIV_REQUIRES newlib nvs_flash esp_netif esp_event mqtt
EMBED_TXTFILES servercert.pem serverkey.pem cacert.pem)
7 changes: 7 additions & 0 deletions components/mosquitto/examples/broker/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ menu "Example Configuration"
If enabled, it runs a local mqtt client connecting
to the same endpoint ans the broker listens to

config EXAMPLE_BROKER_WITH_TLS
bool "Use TLS"
default y
help
If enabled, the broker (and the client too, if enabled)
uses TLS transport layer

endmenu
33 changes: 30 additions & 3 deletions components/mosquitto/examples/broker/main/broker.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@

const static char *TAG = "mqtt_broker";

#if CONFIG_EXAMPLE_BROKER_WITH_TLS
extern const unsigned char servercert_start[] asm("_binary_servercert_pem_start");
extern const unsigned char servercert_end[] asm("_binary_servercert_pem_end");
extern const unsigned char serverkey_start[] asm("_binary_serverkey_pem_start");
extern const unsigned char serverkey_end[] asm("_binary_serverkey_pem_end");
extern const char cacert_start[] asm("_binary_cacert_pem_start");
extern const char cacert_end[] asm("_binary_cacert_pem_end");
#endif


#if CONFIG_EXAMPLE_BROKER_RUN_LOCAL_MQTT_CLIENT
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
Expand Down Expand Up @@ -63,7 +73,13 @@ static void mqtt_app_start(struct mosq_broker_config *config)
{
esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.hostname = "127.0.0.1",
.broker.address.transport = MQTT_TRANSPORT_OVER_TCP, // we support only TCP transport now
#if CONFIG_EXAMPLE_BROKER_WITH_TLS
.broker.address.transport = MQTT_TRANSPORT_OVER_SSL,
.broker.verification.certificate = cacert_start,
.broker.verification.certificate_len = cacert_end - cacert_start,
#else
.broker.address.transport = MQTT_TRANSPORT_OVER_TCP,
#endif
.broker.address.port = config->port,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
Expand All @@ -79,11 +95,22 @@ void app_main(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());

struct mosq_broker_config config = { .host = CONFIG_EXAMPLE_BROKER_HOST, .port = CONFIG_EXAMPLE_BROKER_PORT };
struct mosq_broker_config config = { .host = CONFIG_EXAMPLE_BROKER_HOST, .port = CONFIG_EXAMPLE_BROKER_PORT, .tls_cfg = NULL };

#if CONFIG_EXAMPLE_BROKER_RUN_LOCAL_MQTT_CLIENT
mqtt_app_start(&config);
#endif

#if CONFIG_EXAMPLE_BROKER_WITH_TLS
esp_tls_cfg_server_t tls_cfg = {
.servercert_buf = servercert_start,
.servercert_bytes = servercert_end - servercert_start,
.serverkey_buf = serverkey_start,
.serverkey_bytes = serverkey_end - serverkey_start,
};
config.tls_cfg = &tls_cfg;
#endif

// broker continues to run in this task
mosq_broker_start(&config);
mosq_broker_run(&config);
}
19 changes: 19 additions & 0 deletions components/mosquitto/examples/broker/main/cacert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDIzCCAgugAwIBAgIUXichctvCn6/6xXr0+UOBaqwkBMMwDQYJKoZIhvcNAQEL
BQAwITELMAkGA1UEBhMCQ1oxEjAQBgNVBAMMCUVzcHJlc3NpZjAeFw0yNDA3MDgx
NDE5NDNaFw0yNTA3MDgxNDE5NDNaMCExCzAJBgNVBAYTAkNaMRIwEAYDVQQDDAlF
c3ByZXNzaWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqAGUZALUS
AwWkslBH0RJcgyTTYZ6Q3xadG9rubTGN0DNt8INlguElN9eUhj7VzQZeGxRtAk3A
b4r5MpTWAAC8maDgZU97TOmAaxA04h0P2MHTGG4i1vSm2/jebhh5Ydh8nKs9DdAO
YJWfbtt3XukBe5VJcmp7OICz88LFc/fArrAnBFdmrVX+0Y2l/5KDW6ItvcXhorpz
sO5hOnPXIs4Hq5TYOJbUw6h9E8O6bxUG4AXcSWqqbLJ6PzEFSBMBnjwBQn4HCWvM
GV6w2+I1QbtOTe6yNzBa7O3yqzSYeTcdpjv/FFngo4oRN1RMiCYc1Ae3hJiIhDlN
SRB1CHPi4MblAgMBAAGjUzBRMB0GA1UdDgQWBBTdlh8T2ze2K81IrZCpUv9yhZq2
qjAfBgNVHSMEGDAWgBTdlh8T2ze2K81IrZCpUv9yhZq2qjAPBgNVHRMBAf8EBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBDTt9V3LnyBjHDi9pQa+Q8bjVYCMaOSBFE
LJj8GhkXxtfTzqO2u7vkvfz+2MaRDNpL2lePWDB0BwINT+mSYNWjD5bP2mdgJ2nK
BStzWT6MR4hiQ6u6hXy2Q8brqPN+dP4Pay8fXHe3JNadC/nSk4AC3EvVDpghCJJB
1W5az4YmJzK0F6S84AkKnXYdlYyb94RwWSevn7HYZM+xQjoJmBhQ+XnQ7o2uaEur
52igRRHQQ4xrF5JrbGAqfFVqfA8lJDYiAZCG/aNlV0VpgzyxpDxvPFvvlEYJoL63
/asgSIzYoBknZjNZnPSKcsYGa+0Bjjh7tS50bV++5sN+aW/WDRLd
-----END CERTIFICATE-----
17 changes: 17 additions & 0 deletions components/mosquitto/examples/broker/main/servercert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICvDCCAaQCFAo5BZTT6BC7rKLiWZA9mwGrEQYeMA0GCSqGSIb3DQEBCwUAMCEx
CzAJBgNVBAYTAkNaMRIwEAYDVQQDDAlFc3ByZXNzaWYwHhcNMjQwNzA4MTQxOTQ0
WhcNMjUwNzA4MTQxOTQ0WjAUMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkCVA8MY/BMZ2e95s+oNMZ2cXEF7lbUL58
I9OT5Y+0Mxy3mxsezEye0kKXgV7TqzXdWbu8VhDQONkKkeO4n/lPKhULmKQ7gIja
1aiL5Wt07S/jHBaYbMymbssCJaVcFpl+gclZ0oJJKDtJN9wYoUAAXeZkEE47rRWm
W5CZP92bn8TYar+3rjexHvZTtPhSKucsN/YoAtdC5ywRcf9lbhmjV4sMzUSAlPG4
ZY8sG1mrul1AO2c7OI4lcm+iBo7WiIwtASmqvD/Ahhye5kY00jfAiQJvRl4Da65x
m6NVVUAk3pUsKjOHI/4FisnP0kIJrfMNaiiumroFApuMl3YxEN6tAgMBAAEwDQYJ
KoZIhvcNAQELBQADggEBAD+ML2Dp2GDomHoFxyTmu9msv+8YyZy4VhRGUWnG4k8f
XV+9cBoQkiV8VUDETwjcdp0lRVmyxy8w1x4ovJ/EO5udfXom8gxMS7lZVXw1Iv09
vPHIpr9kQg2hxTpqoHSRKLRJv796kfYoPK+I43hYlhvewQko7+E8EEns46qXc4I3
wqrwNOw1gjUzyj5DhW4RCJ9sBS/FaVyliCxICoDXRFhnSXWi0HaEjzq815muN6DG
lD5ENFExpPWpvjyVPQC6tNYRlRCAGKn5qbx/YetGNX3slHJHgHAO2dyPYdiXwkhG
GwQPqXJrvu0k83h5lTeW98wwgcqFEzVHQCJhREdW4uE=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions components/mosquitto/examples/broker/main/serverkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkCVA8MY/BMZ2e
95s+oNMZ2cXEF7lbUL58I9OT5Y+0Mxy3mxsezEye0kKXgV7TqzXdWbu8VhDQONkK
keO4n/lPKhULmKQ7gIja1aiL5Wt07S/jHBaYbMymbssCJaVcFpl+gclZ0oJJKDtJ
N9wYoUAAXeZkEE47rRWmW5CZP92bn8TYar+3rjexHvZTtPhSKucsN/YoAtdC5ywR
cf9lbhmjV4sMzUSAlPG4ZY8sG1mrul1AO2c7OI4lcm+iBo7WiIwtASmqvD/Ahhye
5kY00jfAiQJvRl4Da65xm6NVVUAk3pUsKjOHI/4FisnP0kIJrfMNaiiumroFApuM
l3YxEN6tAgMBAAECggEBAIAmxohAMA6+tGV9C8vh2QpZGCgaYLT2X9qcIq9oqNwf
ElBe3NEyyqlJmrzCVVMIbwx/DiwVEQ2bW/TmBQI3+I3gUpC8r5HM2R4dzY99rHWs
17yWNRDf7wIXjIIg5w8KmOA8hRGnZCHDTI3nFgwn7dhbg6KpGnWEw2U0I8OWIYty
BX/CvsaWCtkOc1o1bUfnt91YlZlFm7VSK+jdxhnt+A5FJ06CllTaur9nf3u/sLO9
4SKtd94S/pTlIWM4x+4565fNplNuKLsrnNJHV5eiPwiMb9OZzeFa48z26No2ebHc
zA5PlrzjtQRQaSiWausgZKfLp1+lA9kNNhi6gBPt4AECgYEA2mUZErdAmm0WS+Hl
/AEJWsXzoYLGmOvToVEyUqRNffsfkbTzSHajLGzntUd/ZnQQWh5NkvOPJ3BHTszb
vwVeGIQehpwqoCvF1Nz+XhI9yAGIoSzxq0FMMcmlW0XGdK8D30qbeygBEL2FJnK5
mixWe3dZx3kujIFJ4VI8S4g/CjcCgYEAwEgT7FCk4xw6NClI3kAQ6NqqJ+qKDwFo
LQQKUep3juA7i84KwqRCVSoKVjJfkVw7MBb520MgnjAwnekyRql6ALDrSUqgXNB9
R8Sa5b19mmmBDtvh+IrhD6gmAyzXVdGU9fxMnW3iW3sx5Anl/4lx8r7ITcrM9dgd
xY7pwzownDsCgYBkTuz+OKb2hsYn4kC0x3EZfTQSabN3x1EzlcysQoTJKU9tqBPZ
o4v8uqSOEaHFV+euzJ5KsY19ysclvVfs27VFQ2GV6CJ34MMDquE2KeCwfWvYw4DY
bKxnbbuCOYEWVNBNfcH+Bfi/TJzcdPMkidrK6J2WzeUAad2aHSBOfOyfbwKBgEkK
WD8ZdzkqXNW5pQt/7Kx3e9GD34PJtgf7k+wAFAB7H0OBNkcv3F67hIevxOvTzEv9
PlZTDo3ool8p2UZMVKL0kbwalAYN0Lk1bt28eHzyfOrnDdS69Llc12u3Wekontw+
ReA7gJPdnVsRg4PpcxaR8EbUtbzhppWILzZQ4WxHAoGALs0n0pDVQlkAuDtNhA/i
7/jIo1hd3fPpWbMfcKeP+TtlpXMu/BCsR5A/u+4iSfLMy9/Ggqad4jUsdd9+myvr
j/3BzbSx7OnD+gg8ao0K2FwO33ncM1iAw3G5QCKs1waHsVen43Oe3GtQxHxxi/G0
Y4EIG5wkDz4YQOEXacvTWMo=
-----END PRIVATE KEY-----
13 changes: 12 additions & 1 deletion components/mosquitto/port/broker.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@ static void listeners__stop(void)
mosquitto__free(listensock);
}

int mosq_broker_start(struct mosq_broker_config *broker_config)
void net__set_tls_config(esp_tls_cfg_server_t *config);

void mosq_broker_stop(void)
{
run = 0;
}

int mosq_broker_run(struct mosq_broker_config *broker_config)
{

struct mosquitto__config config;
Expand All @@ -115,6 +122,10 @@ int mosq_broker_start(struct mosq_broker_config *broker_config)

config__init(&config);

if (broker_config->tls_cfg) {
net__set_tls_config(broker_config->tls_cfg);
}

db.config = &config;

rc = db__open(&config);
Expand Down
11 changes: 10 additions & 1 deletion components/mosquitto/port/include/mosq_broker.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
#pragma once
#include "mosquitto.h"
#include "esp_tls.h"

struct mosquitto__config;

Expand All @@ -17,6 +18,7 @@ struct mosquitto__config;
struct mosq_broker_config {
char *host; /*!< Address on which the broker is listening for connections */
int port; /*!< Port number of the broker to listen to */
esp_tls_cfg_server_t *tls_cfg; /*!< ESP-TLS configuration (if TLS transport used) */
};

/**
Expand All @@ -28,4 +30,11 @@ struct mosq_broker_config {
* @param config Mosquitto configuration structure
* @return int Exit code (0 on success)
*/
int mosq_broker_start(struct mosq_broker_config *config);
int mosq_broker_run(struct mosq_broker_config *config);

/**
* @brief Stops running broker
*
* @note After calling this API, function mosq_broker_run() unblocks and returns.
*/
void mosq_broker_stop(void);
Loading

0 comments on commit 7c54b18

Please sign in to comment.