如何将STM32 lwip/mqt-api与tls一起使用



我制作了stm32+rtos+lwip/mqtt解决方案,效果很好。现在我想将它与嵌入式tls安全连接一起使用。我没有找到任何例子。

lwip-mqt-api支持tls通信。但没有这样的例子,只是使用代码LWIP mqtt客户端i使用的简单mqtt客户端。

我尝试在cubemx、LWIP_ALTCP&LWIP_ALTCP_TLS,将LWIP_ALTCP_TLS_MBEDTLS添加到路径。它编译了。如何初始化mbedtls并添加tls证书。此链接需要一些信息altcp-tls-

有人对stm32 lwip堆栈的stm32 lwip/mqtt+tls(mbedtls(有什么经验或工作示例吗?

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);

我给mqtt客户端ca证书和长度。我在中出错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 生成

这个线程与中的其他示例一起帮助了我https://www.nongnu.org/lwip/2_0_x/group__mqtt.html以使MQTT客户端使用MbedTLS双向身份验证。我现在可以订阅/发布到亚马逊AWS云。

如果有人感兴趣,下面是我所做的。

  1. 在启用LwIP和MbedTLS的情况下从CubeMX生成代码。重要的是启用MBEDTLS_PLATFORM_MEMORY、MEMP_MEM_MALLOC和LWIP_ALTCP_TLS_MBEDTLS,以便库使用LWIP中的可选calloc/free函数(它们在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. 如果像我一样在LwIP中使用FreeRTOS,则有必要启用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回调。

谢谢,我希望这也能帮助到其他人。

我有一个相同的配置,所以我可以告诉你,如果你调试代码,你会发现它在尝试调用calloc时会崩溃,如果你的环境与我的环境相同,你就没有这个系统函数。

我所做的是使用在lwip中实现的calloc,特别是在altcp模块中。我通过cubemx MBEDTLS_PLATFORM_MEMORY进行了定义,为了激活ALTCP_tls_MBEDTLS_mem.c中的定义ALTCP_MBEDTLS_PLATFORM_ALLOC,我可以使用altcp_mbedtls_mem_init((函数,指定mbedtls使用altcpcalloc和free。

这个函数被调用到altcp_tls_create_config_client中,所以如果要使用它,就不必调用altcp_mbedtls_mem_init((两次。

通过这种方式,您应该能够正确地为mbedtl分配内存。

如果您似乎有内存分配问题,可以尝试增加lwipopts.h中的堆内存大小,如下所示:

#define MEM_SIZE (50 * 1024)

最新更新