Как использовать STM32 lwip / mqtt api с tls?

Я сделал решение stm32 + rtos + lwip / mqtt, и оно хорошо работает. Теперь я хочу использовать его со встроенным безопасным соединением TLS. Примеров не нашел.

lwip mqtt api поддерживает связь tls. Но такого примера нет, просто простой клиент mqtt с использованием кода LWIP MQTT Client я использовал.

Я попытался включить встраивание и некоторые параметры в cubemx, LWIP_ALTCP & LWIP_ALTCP_TLS, добавить LWIP_ALTCP_TLS_MBEDTLS в путь. Он скомпилирован. Как запустить mbedtls и добавить сертификат tls. по этой ссылке требуется немного информации x/group__altcp__api.html" rel="nofollow noreferrer">altcp tls

Есть ли у кого-нибудь опыт или рабочий пример с stm32 lwip / mqtt + tls (mbedtls) для стека stm32 lwip?

UPD. Вот мой код настройки клиента mqtt:

struct mqtt_connect_client_info_t ci;
memset(&ci, 0, sizeof(ci));
ci.client_id = "lwip_test";
ci.client_user = "";
ci.client_pass = "";
ci.keep_alive = 0;
ci.tls_config = altcp_tls_create_config_client((const u8_t*)test_cert, sizeof(test_cert));
// create client
client = mqtt_client_new();
// connect client   
mqtt_client_connect(client, &resolved, port, mqtt_on_connect, (void *)0, &ci);

Я даю сертификат CA клиента mqtt и длину. У меня ошибка в функции altcp_tls_create_config_client_common (altcp_tls_mbedtls.c) с кодом -4480 (Не удалось выделить память).

ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
if (ret != 0) {
  LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
  altcp_mbedtls_free_config(conf);
  return NULL;
}

Что я делаю не так, какие еще параметры мне следует настроить в модуле mbedtls? Я использую по умолчанию, созданный CubeMX


person Ромка Ромка    schedule 08.04.2020    source источник


Ответы (3)


Эта ветка помогла мне вместе с другими примерами в https://www.nongnu.org/lwip/2_0_x/group__mqtt.html, чтобы клиент MQTT работал с двухсторонней аутентификацией MbedTLS. Теперь я могу подписаться / опубликовать в облаке Amazon AWS.

Так что, если кому-то интересно, вот что я сделал.

  1. Сгенерируйте код из CubeMX с включенными LwIP и MbedTLS. Важно включить MBEDTLS_PLATFORM_MEMORY, MEMP_MEM_MALLOC и LWIP_ALTCP_TLS_MBEDTLS, чтобы библиотека использовала альтернативные функции calloc / free из LwIP (они задаются в функции altcp_mbedtls_mem_init()).

  2. Я также использую MBEDTLS_ENTROPY_HARDWARE_ALT, MBEDTLS_NO_PLATFORM_ENTROPY и MBEDTLS_CTR_DRBG_C, поэтому библиотека MbedTLS может использовать генератор случайных чисел ctr drbg (инициализируется функцией altcp_tls_create_config()).

  3. Если вы используете FreeRTOS со своим LwIP, как это делаю я, необходимо включить MBEDTLS_THREADING_ALT, а затем в вашем коде вызвать функцию mbedtls_threading_set_alt(), чтобы включить обработку мьютексов в библиотеке MbedTLS.

  4. Вот что я делаю в своем коде:

mqtt_client_t *client;
struct mqtt_connect_client_info_t client_info;
ip_addr_t server_ip;

/* Somewhere in the code call this to get IP address of the host */
ip_addr_t ipaddr;
err = dns_gethostbyname("host_name", &ipaddr, mqtt_resolved_cb, NULL);

/* Wait until this callback gets the IP */
static void mqtt_resolved_cb(const char *host, const ip_addr_t *ipaddr,
                             void *callback_arg)
{
  /* If resolved IP is known -> set it */
  if (ipaddr->addr != 0)
  {
    server_ip.addr = ipaddr->addr;
  }
}

/* Then call this to start MQTT client */
void mqtt_test(const ip_addr_t *ipaddr, uint16_t port,
               const uint8_t *ca_cert_str, size_t ca_cert_len,
               const uint8_t *dev_cert_str, size_t dev_cert_len,
               const uint8_t *dev_key_str, size_t dev_key_len,
               const uint8_t *dev_key_pass_str, size_t dev_key_pass_len)
{
  /* Setup an empty client info structure */
  memset(&mqtt.client_info, 0, sizeof(mqtt.client_info));

  /* Set client information */
  mqtt.client_info.client_id = "lwip_test";
  mqtt.client_info.client_user = NULL;
  mqtt.client_info.client_pass = NULL;
  mqtt.client_info.keep_alive = 0;
  mqtt.client_info.will_topic = NULL;
  mqtt.client_info.will_msg = NULL;
  mqtt.client_info.will_retain = 0;
  mqtt.client_info.will_qos = 0;

  /* Set TLS configuration */
  mqtt.client_info.tls_config = altcp_tls_create_config_client_2wayauth(
    ca_cert_str, ca_cert_len,
    dev_key_str, dev_key_len, dev_key_pass_str, dev_key_pass_len,
    dev_cert_str, dev_cert_len);

  /* Allocate memory for MQTT client */
  mqtt.client = mqtt_client_new();

  /* Connect to the server */
  if (mqtt.client != NULL)
  {
    err = mqtt_client_connect(
      mqtt.client, ipaddr, port,
      mqtt_connection_cb, 0, &mqtt.client_info);
  }
}

Затем код продолжается в стандартных обратных вызовах mqtt из приведенной выше ссылки на пример.

Спасибо, и я надеюсь, что это поможет и кому-то другому.

person Ondřej Lufinka    schedule 20.08.2020

У меня идентичная конфигурация, поэтому я могу сказать вам, что если вы отлаживаете код, вы увидите, что он выйдет из строя при попытке вызвать calloc, если ваша среда равна моей, у вас нет этой системной функции.

Я использовал calloc, реализованный в lwip, в частности в модуле altcp. Я определил через Cubemx MBEDTLS_PLATFORM_MEMORY, чтобы активировать определение ALTCP_MBEDTLS_PLATFORM_ALLOC в altcp_tls_mbedtls_mem.c, затем я смог использовать функцию altcp_mbedtls_mem_init (), которая указывает для mbedtls cal и free.

Эта функция вызывается в altcp_tls_create_config_client, поэтому, если вы собираетесь ее использовать, вам не нужно дважды вызывать altcp_mbedtls_mem_init ().

Таким образом вы сможете правильно выделить память для mbedtls.

person lcudst    schedule 16.04.2020

у вас возникла проблема с распределением памяти, вы можете попробовать увеличить размер кучи в lwipopts.h следующим образом:

#define MEM_SIZE (50 * 1024)
person Bayrem Gharsellaoui    schedule 12.11.2020