尊敬的 Charles:
我们已在未加密的情况下设置了 MQTT 客户端、并且运行正常。 但是、在添加 SSL/TLS 时、完全不起作用。 MQTTClient_connect 返回-2021、但在更详细地调试时、 结果表明 SlNetIfNDK_sockStartSec 无法创建安全套接字、因为它无法检索证书。
出于安全原因、证书和密钥不存储在文件系统中、而是作为固件内的数组、由 SlNetif_loadSecObj 将它们传递到 SlNet:
MQTTClient_Handle mc;
MQTTClient_Params mp;
MQTTClient_ConnParams mcp;
// Virtual file names of the certificates
char *msf[3] = { "ca.pem", "cert.pem", "key.pem" };
//Certificates
const uint8_t sc_sec_ca[] = "-----BEGIN CERTIFICATE-----\n"
"MIIDbTCCAlWgAwIBAgIQOJS41HdZ0aBH554ITPDjmzANBgkqhkiG9w0BAQsFADBJ\n"
...
"3v1WIFze0MYF6XK6IQ6ia6o=\n"
"-----END CERTIFICATE-----";
const uint16_t sc_sec_ca_l = sizeof(sc_sec_ca);
const uint8_t sc_sec_pk[] = "-----BEGIN PRIVATE KEY-----\n"
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMgIYvGyxtmoyK\n"
...
"zVBWLpomdgRuAVM6Zgs8MfaK4zoD/c8KwI5A4iOqCpZseCAu9ohTNMTnB9VeVSkb\n"
"TMZFwZa3TMRvDY7uZVGzEQB2\n"
"-----END PRIVATE KEY-----";
const uint16_t sc_sec_pk_l = sizeof(sc_sec_pk);
uint8_t sc_sec_pc[] = "-----BEGIN CERTIFICATE-----\n"
"MIIFZDCCBEygAwIBAgITEwAAAAxYaQk7gSlDEgAAAAAADDANBgkqhkiG9w0BAQsF\n"
...
"pJ1Ek8d73ZDgO4IAkyhJC0UtwcuMFS51TeSov+THh6A+ewMi34DINw==\n"
"-----END CERTIFICATE-----";
const uint16_t sc_sec_pc_l = sizeof(sc_sec_pc);
// Pass credentials to SlNet
e = SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_CERTIFICATE, msf[0], strlen(msf[0]), sc_sec_ca, sc_sec_ca_l, SLNETIF_ID_1);
e = SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_CERTIFICATE, msf[1], strlen(msf[1]), sc_sec_pc, sc_sec_pc_l, SLNETIF_ID_1);
e = SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_RSA_PRIVATE_KEY, msf[2], strlen(msf[2]), sc_sec_pk, sc_sec_pk_l, SLNETIF_ID_1);
mcp.netconnFlags = MQTTCLIENT_NETCONN_URL | MQTTCLIENT_NETCONN_SEC | MQTTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION | MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION;
mcp.serverAddr = "...";
mcp.port = 8883;
mcp.method = SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2;
mcp.cipher = SLNETSOCK_SEC_CIPHER_FULL_LIST;
mcp.nFiles = 3;
mcp.secureFiles = msf;
mp.clientId = mac;
mp.connParams = &mcp;
mp.mqttMode31 = false;
mp.blockingSend = true;
MQTTClient_subscribe(mc, msp, 1);
// ... code to run client ...
MQTTClient_connect(mc);
如果仅传递 CA 证书并将.files 设置为1或传递全部3个文件、则 MQTTClient_connect 将始终返回-2021。
SlNetIf_loadSecObj 始终返回0、在调试视图中可以看到它正确地存储了信息。 正确意味着它将文件名存储为文件名、并将数据缓冲区存储如下: 
这似乎很明显、但查看错误发生的位置时、并不是: 
上图显示了 lookupObj 函数、此函数由 SlNetIfNDK_sockStartSec 调用以获取证书。 在这里,你可以看到名称和 buf 是反相的,所以 lookupObj 在将名称与名称进行比较时不会找到任何东西。
我注意到、过去有一个亚马逊的"插件"、它应该在非常类似的根证书、客户端证书和密钥中工作。 此 SDK 不再提供下载。 这仅仅是因为亚马逊已经改变了他们的东西,所以它不会再与他们工作了吗? 如果是、确认我们无意使用该代码连接到亚马逊、而只是将其与我们的实施进行比较、您能否提供该链接?
如果您对此问题有任何其他建议或想法、请随时发表评论!
此致
彼得