ESP-IDF中使用X.509证书进行MQTT通信时连接失败排查
问题:ESP-IDF MQTTs连接第三方云平台失败排查
背景
我开发了一个需通过MQTTs连接第三方云平台的应用,第三方提供了Linux环境下的证书生成流程:
证书生成流程
- 生成带*SubjectAltName(SAN)*扩展的CSR(证书签名请求),需准备
req.cnf文件,内容如下:
ts = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext [ req_distinguished_name ] countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) organizationName = Organization Name (eg, company) commonName = Common Name (e.g. server FQDN) [ req_ext ] subjectAltName = @alt_names [alt_names] URI.1=<Add SAN’>
- 执行以下命令生成
placeholder.csr和private.key:
openssl req -out placeholder.csr -newkey rsa:2048 -nodes -keyout private.key -config req.cnf
- 使用第三方提供的
ca.crt公钥证书,执行curl命令获取第三方签名的证书:
curl -o placeholder.crt -F csrFile=@placeholder.csr --cacert $CERT_HOME/ca.crt https://CADomainName/getCert
ESP-IDF代码配置
我将这些证书文件硬编码为代码中的字符串,相关配置代码如下:
void mqtt_app_start(void) { const esp_mqtt_client_config_t mqtt_cfg = { .broker = { .address.uri = "mqtts://sample.domain.name", .verification.certificate = (const char *)ca_cert }, .credentials = { .authentication.certificate = (const char *)signed_crt, .authentication.key = (const char *)client_key_pem }, }; }
其中ca_cert为第三方提供的公钥证书,signed_crt是签名后的placeholder.crt,client_key_pem是私钥。我对placeholder.crt和私钥做了处理:移除元数据,仅保留证书头尾包裹的内容,格式示例:
-----BEGIN CERTIFICATE---- . . . -----END CERTIFICATE------
运行错误日志
运行代码时出现以下错误:
E (3632) mqtt_client: esp_mqtt_handle_transport_read_error: transport_read(): EOF E (3632) mqtt_client: esp_mqtt_handle_transport_read_error: transport_read() error: errno=119 I (3642) mqtt: MQTT_EVENT_ERROR I (3642) mqtt: Last error code reported from esp-tls: 0x8008 I (3652) mqtt: Last tls stack error number: 0x0 I (3652) mqtt: Last captured errno : 0 (Success) E (3662) mqtt_client: esp_mqtt_connect: mqtt_message_receive() returned -2 E (3672) mqtt_client: MQTT connect failed I (3672) mqtt: MQTT_EVENT_DISCONNECTED
疑问
请问出现该问题的原因是什么?
内容的提问来源于stack exchange,提问作者rdkulk
相关产品推荐
相关产品推荐

