This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3135:在 TLS 1.2 连接到 AWS MQTT 代理的情况下通过 Wi-Fi 传输的证书错误、但不是以太网传输的证书错误

Guru**** 2943400 points

Other Parts Discussed in Thread: CC3135, CC3220SF, UNIFLASH

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1642404/cc3135-certificate-errors-over-wi-fi-but-not-ethernet-on-cc3135-with-tls-1-2-connecting-to-aws-mqtt-broker

器件型号: CC3135
《Thread 中讨论的其他器件: CC3220SFUNIFLASH》

大家好、我正在开发一个使用 CC3135 用于商业用途的物联网网关、该网关处于测试的最终阶段。 设备必须与端口 8883 上具有 QoS 1 的 AWS MQTT 代理安全通信、以接收指令并发布事件。 我正在使用 TLS 版本 1.2、CC3135 与服务包 sp_4.4.1.3_3.1.0.5_3.1.0.19 一起刷写。 当我在自己的代理上进行测试时、连接的设备没有任何问题。 但是、在切换安全证书以将网关连接到客户自己的代理后、成功的通信只通过以太网而不是 Wi-Fi 建立。 尝试通过 Wi-Fi 进行通信时、我间歇性地收到与证书验证问题或建立通信尝试失败有关的错误代码 456,688 和 458(但不是通过以太网)。

我已经尝试了不同的技术来传递证书给经纪人,但我没有运气。 我必须发送 AmazonCA1 作为 CA、以及客户端证书和私钥。 我已经尝试以 PEM 格式、DER 格式、这是两者的混合形式发送证书、我在 PEM 中发送一些证书、在 DER 中发送其他证书、甚至使用 OpenSSL 转换证书。 各种组合改变了上述三种错误代码中的错误代码、但没有最终的成功。 该设备的逻辑不会对以太网和 Wi-Fi 连接做出重大区分、因此我真的不知道为什么它可以与一个连接配合使用、而不能与另一个连接配合使用。 当前代码以字符串形式发送证书、其结构如下:

“----- BEGIN CERTIFICATE----- “\r\n“
“...\r\n“
“...\r\n“
“...\r\n“
“----- END CERTIFICATE----- \r\n“;

但我愿意接受任何可能导致成功沟通的变化。 我仔细阅读了论坛上各位同事提出的一些主题、但我没有找到符合所述情况的解决办法。 我感谢任何指导。

此致
Omelio

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    首先、  sp_4.4.1.3_3.1.0.5_3.1.0.19 很旧、所以我强烈建议升级到最新版本。

    第二、当您说它通过以太网工作时、证书取自什么? 相同的 cc3135 文件系统? 使用的是什么网络堆栈? 我尝试了解 Wi-Fi 用例与以太网用例的架构和数据流。

    当你说它与你自己的经纪人合作时,这是安全的吗? 您使用了哪些证书? 您拥有的签名证书? 您使用了什么目录?

    此致、

    Shlomi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您发送编修。我们会重新检视您的建议。

    1 — 我认为有必要首先说明我们的系统使用 MSP432 MCU、它连接到 CC3135 以在器件中集成 Wi-Fi 功能。

    2-关于您提到的服务包、我一直在使用较新的版本进行一些测试、但它们并不能完全正常工作、但既然您提到我使用的服务有多过时、我将继续使用 sp_4.13.0.2_3.7.0.1_3.1.0.26 进行测试、这是我在对应于 CC3x35 系列的 SDK 中找到的最新版本。

    3-作为网络堆栈,我们使用 NDK 堆栈,主要使用 SlNetIf、SlNetSock 和 SlNetUtils 库中的函数。 例如、要添加我们使用的 Wi-Fi 网络接口、请执行以下操作:

    SlNetIf_add (SLNETIF_ID_2、“CC31xx“、(const If_Config_*)&SlNetIfConfigWifi、5);

    4 — 安全证书以 PEM 格式数组的形式写入、并使用以下命令加载到 NWP 中:

    SlNetIf_loadSecObj (SLNETIF_SEC_OBJ_TYPE_CATEL、MSF[2]、strlen (MSF[2])、SC_sec_ca、SC_sec_ca_l、 SLNETIF_ID_2);

    在我们的代理中、对于以太网连接、我们直接以 PEM 格式传递所有证书(CA,客户端证书和私钥);而对于 Wi-Fi、我们以 DER 格式发送 CA 和客户端证书、并将私钥保留在 PEM 中。 在运行时调用函数时发生了这种 PEM_TO_DER 转换。 这在使用 SP 19 的 Wi-Fi 和以太网上都能正常工作。  

    迁移到 AWS 代理时、我们采用了同样的方法、该方法适用于以太网、但不适用于 Wi-Fi。 但是、在遇到重复的问题后、我们尝试通过 OpenSSL 事先发送 PEM、DER、混合或生成 DER 中的所有证书、并直接将这些证书传递给文件系统、从而绕过 PEM_TO_DER 函数。 我们没有取得成功。

    5 — 我们自己的 MQTT 代理受到安全保护、并基于私有 CA(自签名)、客户端证书和私钥将 TLS 与相同的身份验证系统一起使用。

    其他有用信息:

    在我尝试解决问题的调试和测试过程中、我使用了 CC3220SF LAUNCHXL 板、其中包含通过 TLS 进行安全 MQTT 连接的示例代码、该代码位于此处:

    dev.ti.com/.../node

    目的是尽可能简单地实现成功的身份验证、并检测一个体系结构与另一个体系结构之间的变化以解决问题。 我成功地复制了 Mosquitto 经纪商上的示例代码,然后对其进行了调整,以连接到我们的私人经纪商,它也能正常工作。 但是,当尝试连接到 AWS 代理时,无论我如何发送证书,问题都会再次出现。 它很有趣,因为当我修改从私有代理到 AWS 的代码时,唯一改变的是服务器地址和安全证书。 其他一切都是相同的。 在一种情况下它是有效的,在另一种情况下它不是。  

    除了使用 SlNetIf_loadSecObj 加载证书之外、我还测试了一个名为 WriteCertFile 的函数、该函数将证书写入 CC3220SF 微控制器的外部串行闪存 (SFLASH)。 这一策略与 Mosquitto 和私人经纪商合作,但不与 AWS 合作。

    这是我在尝试使用 CC3220SF 连接到 AWS 代理时遇到的错误:

    [SL-MBEDTLS::error]失败! 我理解、mbedtls_ssl_handshake 返回–0x7880、与 TLS 握手失败相关、因为 AWS IoT 服务器拒绝客户端证书或无法验证信任链。

    我希望这些信息有助于阐明系统行为和架构。 如果你需要任何其他的东西或任何疑问仍然存在,请不要犹豫,立即问我,我将尝试提供一切必要的,直到我们找到解决办法。

    此致、

    Omelio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    SLA 的链接已断开、但据我所知、您是否在 Wi-Fi 用例中使用内部 TLS 堆栈或 mbedtls 堆栈?

    此致、

    Shlomi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Shlomi:

    我们将 CC3135 的内部 TLS 堆栈用于 Wi-Fi 用例。

    我还想向您更新有关 Service Pack 使用情况的信息。 我们更新了 CC3135、以使用 sp_4.13.0.2_3.7.0.1_3.1.0.26 并保持相同的行为模式。 它可以正确连接到我们的代理、但不能通过 Wi-Fi 连接到 AWS 代理(它确实通过以太网工作)。

    在使用 CC3220SF 的测试中、我们使用了 mbedtls、因为我们尝试不对 TI Academy 示例中的任何内容进行任何更改。 在任何情况下,它也不起作用,如我在上一条消息中发送的日志所示。

    抱歉、链接已断开。 我将再次发送给这里—我认为这次它应该正常工作:

    dev.ti.com/.../node

    再次感谢您的帮助。 如果您需要任何其他信息,请不要犹豫,再次与我联系。

    此致、

    Omelio

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    再次大家好、Shlomi。

    我认为更新我们在 CC3220SF 上运行的测试的相关信息会很有用。 如前所述、在本例中、我们试图通过尽可能少的更改来实现 TI Academy 提供的示例、因此我们决定坚持使用 mbedtls。

    我会向您发送我在尝试将 CC3220SF 连接到客户端的 AWS 代理时获得的详细日志、以便您可以看到确切的程序流程。 请注意、一切都会顺利进行、直到握手阶段失败并返回错误 0x7880。

    此代码以.per 格式发送所有证书(CA,客户端证书和私钥)、因为这对我们自己的代理来说很有用。 它还使用具有 QoS 0 和 TLS 版本 1.2 的 MQTT 3.1.1、但未配置任何 Will。 如您所见、我们尽可能简化了它、但没有取得任何成功。

    我一直在关注论坛上类似帖子的建议、尤其是这里讨论的那些建议:

    e2e.ti.com/.../cc3230sf-cc3230sf-mqtt-errors-–688-–457-–456-migrating-from-hivemq-one-way-tls-to-aws-iot-core-mutual-tls-production-certificate-storage-questions

    这种情况与我们的情况非常相似、即使在日志结构中也是如此。 幸运的是、我们的同事能够通过更改 QoS 和取消遗嘱来解决他们的问题、但我们在遵循这些相同的建议之后还没有获得同样的运气。

    需要指出的是、我们使用以太网和 Wi-Fi 的原始器件 (MSP432 + CC3135) 通过以太网成功连接到客户端的 AWS 代理、而不会出现任何问题、同时具有这些相同的证书(在这种情况下为 PEM 格式)并采用 QoS 1 进行配置。 我们使用 CC3220SF 通过 Wi-Fi 尝试了这些相同的参数、但也没有运气。

    再次感谢您的支持。

    此致、
    Omelio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Shlomi、我有个好消息。

    我们继续根据 TI Academy 提供的示例代码使用 CC3220SF 在 AWS 上连接到客户端的 MQTT 代理、并取得了积极的结果、成功建立了连接。 我们遇到麻烦的步骤是握手、但我们通过应用以下更改解决了握手问题:

    1 — 将标志 MQTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION 添加到 MQTT 连接参数中。

    2-在辅助模块 slneifwifi.c 中、我们检测到一个已启用并显然强制使用 TLS 版本 1.3 的标志、因此我们将其禁用。

    //之前:
    define SUPPORT_TLS1_3 (1)

    //之后:
    define SUPPORT_TLS1_3 (0)

    3-修改 ConfigClientSocket 函数、通过以下方式强制绑定客户端证书和私钥:mbedtls_ssl_conf_own_cert(&pTlsScock->conf,&pTlsScock->srvcert,&pTlsScock->pkey)

    //之前:
    if(( ret = mbedtls_ssl_setup(&pTlsScock->ssl,&pTlsScock->conf )!= 0)...

    //之后:
    //绑定客户端证书和私钥
    ret = mbedtls_ssl_conf_own_cert (&pTlsSock->conf、&pTlsScock->srvcert、&pTlsScock->pkey);
    如果 (ret !=0){
    mbedtls_error(“mbedtls_ssl_conf_own_cert 失败:%d、ret);
    返回 SLNETSOCK_ERR_SOCKCONNECT_FAILED;
    }

    if(( ret = mbedtls_ssl_setup(&pTlsScock->ssl,&pTlsScock->conf )!= 0)...

    现在、器件证书及其私钥会与配置相关联、然后再使用 mbedtls_ssl_setup 进行设置、这允许握手发送客户端证书和 AWS IoT 来接受相互身份验证。

    实施这些更改后、CC3220SF 能够在 AWS 上正确连接到客户端的代理并执行预期的交互。 我们仍然使用 mbedTLS 并使用 WriteCertFile 函数将证书写入 CC3220SF 闪存。 我附加了函数定义和获得的成功日志:

    int32_t WriteCertFile (const char *文件名、const unsigned char *数据、uint32_t len)

    int32_t 文件句柄;
    int32_t;
    uint32_t 标志;
    SlFsFileInfo_t fileInfo;

    //检查文件是否已存在(可选,显示通知)
    if (sl_FsGetInfo (const unsigned char *) fileName、0、&fileInfo)== 0){
    LOG_INFO(“文件%s 已存在。 覆盖。\n“,文件名);
    }

    //设置标志:创建、覆盖、无签名、失效防护、最大大小
    flags = SL_FS_create | SL_FS_OVERWRITE | SL_FS_CREATE_NOSIGNATURE | SL_FS_CREATE_FAILSAFE;
    flags |= SL_FS_CREATE_MAX_SIZE (len);

    //打开(或创建)文件。 令牌 NULL、因为我们没有使用安全性
    fileHandle = sl_FsOpen ((unsigned char *) filename、flags、NULL);
    if (fileHandle < 0){
    LOG_ERROR(“创建/打开%s 时出错 sl_FsOpen:%d\n“、文件名、fileHandle);
    返回–1;
    }

    //编写完整内容
    RET = sl_FsWrite (fileHandle、0、(unsigned char *) data、len);
    if (ret !=(int32_t) len){
    LOG_ERROR(“写入%s 时出错 sl_FsWrite 返回了%d\n“、文件名、ret);
    sl_FsClose (fileHandle、NULL、NULL、0);//退出前关闭
    返回–1;
    }

    //关闭文件
    RET = sl_FsClose (fileHandle、NULL、NULL、0);
    如果 (RET < 0){
    LOG_ERROR(“关闭%s 时出错 错误%d\n“、文件名、ret);
    返回–1;
    }

    Log_info(“文件%s 写入成功。\n“,文件名);
    返回 0;
    }


    现在来不是那么好的消息。 当我们尝试在 CC3135 上复制 CC3220SF 的更改时、我们并不那么幸运。 我已经提到、CC3135 使用内部 TLS 栈、根据我一直在研究的内容、它不支持 mbedTLS(如果我猜错了,如果您可以纠正我并说明如何在该器件上正确实现它,我会很感激)。

    此外、我发现将证书加载到证书上的唯一方法是通过 SlNetIf_loadSecObj 函数、并且尝试使用 WriteCertFile 会在逻辑上损坏 NWP 文件系统。 另一方面、由于 CC3135 具有与基于 mbedTLS 的 Academy 示例代码结构完全不同的逻辑、因此我在 CC3135 中找不到对 CC3220SF 所做更改的“等效“元素。

    也就是说、我找不到任何因不强制使用错误 TLS 版本而禁用的 support_TLS1_3 标志、或者找不到任何可以强制绑定客户端证书和私钥的 ConfigClientSocket 函数。 基本上、CC3135 的 slneiffive.c 文件符合预期、与 CC3220SF 的 slneifwi.c 文件无关。

    这正是我们现在遇到的问题。

    我将介绍所有这些信息、以便您全面了解情况、更容易确定问题所在、从而提出可能的解决方案。 我再次感谢您的支持。

    此致、
    Omelio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    为了大致说明 AWS、它是一个完整的物联网基础设施、而不仅仅是开放的 MQTT 代理、因此确实需要完全身份验证。 这就是您需要设置证书和匹配密钥的原因。 至于 TLS1.3、AWS 当然支持它、但并不强制要求它。 如果 mbedtls 库未使用 TLS1.3 进行编译,但在 TLS 期间声明,AWS 将开始使用 TLS1.3 并失败。

    对于 CC3135、内部 TLS 堆栈不是 mbedtls。 它仅为 TLS1.2。 这就是为什么我们有外部 TLS1.3 示例,所以我们打开一个常规套接字并在上面使用 mbedtls ,这样我们就可以使 TLS1.3 正常工作。

    现在,使用 mbedtls 或内部堆栈,可以使用 SlNetIfWifi_loadSecObj () 来刷写文件。 也可以使用 Uniflash 等外部工具来刷写它。 区别在于 TLS 堆栈的证书的实际设置。

    使用 mbedtls,您可以通过 SlNetIfWifi_sockstartSec () 执行此操作,它调用 SetSockOpt (),它最终调用 mbedtls_xxx 方法,将文件内容“复制“到 mbedtls。 对于内部栈、您只需传递文件的名称、NWP 就知道要打开并使用文件。 这是在相同的 SlNetIfWifi_sockstartSec () 中完成的 ,但它应该调用 sl_SetSockOpt ()。 因此、 不应定义 sl_SetSockOpt。

    此致、

    Shlomi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Shlomi、感谢您提供的信息。

    我回来会更详细地介绍一下情况、并取得一些进展。 我一直使用监听器分析‑物联网网关器件与 AWS 上客户端的 MQTT 代理之间的 Wi-Fi 流量。

    如前所述、我们的器件使用 TLS 1.2 和内部 CC3135 协议栈进行‑Wi-Fi 连接(对于 MSP432 直接连接的以太网)。 我仍然无法在网关和 AWS 代理之间成功实现握手。

    以下是我运行的一些测试的详细信息:

    场景 1:使用 Wi‑Fi 连接的 MQTT 句柄调用 MQTTClient_connect 时、如果我以.der 格式提供私钥、则会收到错误 458。 TCP 握手成功完成、但 TLS 握手甚至无法开始。 下面是来自程序的调试日志和显示网关和 AWS 代理之间交换的捕获。

    场景 2:使用.PEM 格式的私钥调用 MQTTClient_connect 时、我们可以看到 TLS 1.2 流量。 克服了前面的障碍、器件启动 TLS 握手、从代理收到积极响应、但当服务器请求客户端证书并且器件显然从未发送证书时、该过程停止。 通信已关闭、因此我收到错误 688。 同样、我会附加本例中的日志和监听器捕获结果。



    我尝试了其他几种方法但没有成功、包括使用不同的密码套件、标志、QoS (0 和 1) 或禁用 will 消息。 在任何情况下,我都无法超越这一点。

    我想强调一下安全证书是正确的、它们适用于不同的应用、包括 CC3220SF(使用 mbedTLS)和我们自己的物联网网关器件(在通过以太网连接时)。 因此、我真的不知道是什么原因导致 CC3135 问题或者如何解决这个问题、我已经没时间了。

    我使用以下序列将安全证书加载到 CC3135 NWP 中:


    E = SlNetIf_loadSecObj (SLNETIF_SEC_OBJ_TYPE_RSA_PRIVATE_KEY、MSF_WIFI[0]、strlen (MSF_WIFI[0])、SC_sec_pk、SC_sec_pk_l SLNETIF_ID_2);
    E = SlNetIf_loadSecObj (SLNETIF_SEC_obj_type_certificate、MSF_WIFI[1]、strlen (MSF_WIFI[1])、aws_client_cert_der、aws_client_cert_der_len、 SLNETIF_ID_2);
    E = SlNetIf_loadSecObj (SLNETIF_SEC_OBJ_TYPE_CATEL、MSF_WIFI[2]、strlen (MSF_WIFI[2])、AmazonRootCA1_der、AmazonRootCA1_der_len、 SLNETIF_ID_2);

    以下是我用于为‑Wi-Fi 连接配置 MQTT 句柄的参数:


    mcp_wifi.netconnFlags = MQTCLIENT_NETCONN_URL | MQTCLIENT_NETCONN_SEC | MQTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION | MQTCLIENT_NETCONN_SKIP_CRECAT_VERIFICAT_VERIFY;
    mcp_wifi.serverAddr = a1kshpxbz3o3ld-ats.iot.us-west-2.amazonaws.com“;
    mcp_wifi.port = 8883;
    mcp_wifi.method = SLNETSOCK_SEC_METHOD_TLSV1_2;
    mcp_wifi.cipher = SLNETSOCK_SEC_cipher_full_list;
    mcp_wifi.nFiles = 4;
    mcp_wifi.secureFiles = MSF_WIFI;

    mp_wifi.clientId = mem_alloc (strlen (Mac));
    sprintf (mp_wifi.clientId、“%s“、mac);
    MP_WIFI.connParams =&mcp_wifi;
    MP_WIFI.mqttMode31 = FALSE;
    MP_WIFI.blockingSend = true;

    然后我调用:

    MC_WIFI = MQTTClient_create (mqt_cb、&MP_wifi);

    最终用于:

    E = MQTTClient_connect (MC_wifi);

    然后我得到错误 458(如果私钥在.der 中)或错误 688(如果私钥在.PEM 中)。

    再次感谢您抽出宝贵的时间、我期待您的答复。

    此致、

    Omelio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    很抱歉晚回复。

    似乎握手失败是因为错误的证书在主机中转换为–688 错误 (ASN_NO_SIGNER)。

    我知道您提到所有证书都很好、但我认为、如果证书不是为了响应证书请求而发出的、则 AWS 的身份验证链由于根 CA 的原因而失败。

    AWS 在一段时间前更改了该链、尽管链中仍有 Amazon Root CA 1、但它不是根证书、而只是具有根 CA 功能的中间证书。 例如、使用 mbedTLS 时、即使根 CA 是中间 CA、但不是内部 TLS 栈、也可以验证。

    连接到 AWS 时的最新捕获显示、根 CA 是 Starfield Class 2 认证机构、因此我认为您需要使用它。 如果你喜欢,我也可以看看嗅探器,看看链条的样子。

    顺便说一句,通过论坛搜索,有一些关于这一点的指示。 例如、查看  CC3220SF:SL_ERROR_BSD_ESEC_ASN_NO_SIGNER_E(–688) 

    此致、

    Shlomi