199 lines
6.2 KiB
C
199 lines
6.2 KiB
C
#include "qcloud.h"
|
|
|
|
#if (QCLOUD_CFG_TLS_EN > 0u)
|
|
|
|
#if (QCLOUD_CFG_AUTH_MODE == QCLOUD_AUTH_MODE_CERT)
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_init_with_cert(qcloud_tls_opt_t *tls_opt, qcloud_device_t *device)
|
|
{
|
|
if (!device->cert_path || !device->priv_key_path) {
|
|
QCLOUD_LOG_E("cert file or key file is empty!");
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_INVAL);
|
|
}
|
|
|
|
QCLOUD_LOG_D("cert path: %s", device->cert_path);
|
|
QCLOUD_LOG_D("priv key path: %s", device->priv_key_path);
|
|
|
|
tls_opt->cert_path = device->cert_path;
|
|
tls_opt->priv_key_path = device->priv_key_path;
|
|
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_SUCCESS);
|
|
}
|
|
#else
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_psk_id_generate(qcloud_tls_opt_t *tls_opt, qcloud_device_t *device)
|
|
{
|
|
int psk_id_len = 0;
|
|
|
|
memset(tls_opt->psk_id, 0, sizeof(tls_opt->psk_id));
|
|
|
|
psk_id_len = osal_snprintf(tls_opt->psk_id, QCLOUD_MQTT_DEVICE_CLIENT_ID_MAX, "%s%s", device->product_id, device->device_name);
|
|
if (psk_id_len < 0 || psk_id_len >= QCLOUD_MQTT_DEVICE_CLIENT_ID_MAX) {
|
|
QCLOUD_LOG_E("psk id generate failed");
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_DEV_INFO);
|
|
}
|
|
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_SUCCESS);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_psk_generate(qcloud_tls_opt_t *tls_opt, qcloud_device_t *device)
|
|
{
|
|
size_t key_len = 0, decoded_psk_len;
|
|
|
|
if (!device->key) {
|
|
QCLOUD_LOG_E("device key NULL!");
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_INVAL);
|
|
}
|
|
|
|
memset(tls_opt->psk, 0, sizeof(tls_opt->psk));
|
|
|
|
key_len = strlen(device->key);
|
|
if (qcloud_utils_base64_decode(tls_opt->psk, sizeof(tls_opt->psk), &decoded_psk_len,
|
|
(const unsigned char *)device->key, key_len) != 0) {
|
|
QCLOUD_LOG_E("psk decode failed!");
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_INVAL);
|
|
}
|
|
|
|
tls_opt->psk_len = decoded_psk_len;
|
|
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_SUCCESS);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_init_with_key(qcloud_tls_opt_t *tls_opt, qcloud_device_t *device)
|
|
{
|
|
QCLOUD_FUNC_EXIT_RC_IF_NOT(qcloud_tls_psk_generate(tls_opt, device), QCLOUD_ERR_SUCCESS, QCLOUD_ERR_FAILURE);
|
|
QCLOUD_FUNC_EXIT_RC_IF_NOT(qcloud_tls_psk_id_generate(tls_opt, device), QCLOUD_ERR_SUCCESS, QCLOUD_ERR_FAILURE);
|
|
|
|
QCLOUD_FUNC_EXIT_RC(QCLOUD_ERR_SUCCESS);
|
|
}
|
|
|
|
#endif
|
|
|
|
__QCLOUD_INTERNAL__ qcloud_err_t qcloud_tls_init(qcloud_tls_opt_t *tls_opt, qcloud_device_t *device)
|
|
{
|
|
#if (QCLOUD_CFG_AUTH_MODE == QCLOUD_AUTH_MODE_CERT)
|
|
QCLOUD_FUNC_EXIT_RC_IF_NOT(qcloud_tls_init_with_cert(tls_opt, device), QCLOUD_ERR_SUCCESS, QCLOUD_ERR_FAILURE);
|
|
#else
|
|
QCLOUD_FUNC_EXIT_RC_IF_NOT(qcloud_tls_init_with_key(tls_opt, device), QCLOUD_ERR_SUCCESS, QCLOUD_ERR_FAILURE);
|
|
#endif
|
|
|
|
tls_opt->ca_cert = qcloud_ca_cert;
|
|
tls_opt->ca_cert_len = strlen(tls_opt->ca_cert);
|
|
tls_opt->handle = NULL;
|
|
tls_opt->timeout = QCLOUD_TLS_HANDSHAKE_TIMEOUT;
|
|
|
|
return QCLOUD_ERR_SUCCESS;
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_connect(qcloud_network_t *network)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
network->tls_opt.handle = osal_tls_connect(&(network->tls_opt), network->host, network->port);
|
|
if (network->tls_opt.handle) {
|
|
return QCLOUD_ERR_SUCCESS;
|
|
}
|
|
|
|
return QCLOUD_ERR_FAILURE;
|
|
}
|
|
|
|
__QCLOUD_STATIC__ void qcloud_tls_disconnect(qcloud_network_t *network)
|
|
{
|
|
if (!network || !network->tls_opt.handle) {
|
|
return;
|
|
}
|
|
|
|
osal_tls_disconnect(network->tls_opt.handle);
|
|
network->tls_opt.handle = NULL;
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_read(qcloud_network_t *network, void *buf, size_t len, uint32_t timeout, size_t *read_len)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
return osal_tls_read(network->tls_opt.handle, buf, len, timeout, read_len);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_tls_write(qcloud_network_t *network, const void *buf, size_t len, uint32_t timeout, size_t *write_len)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
return osal_tls_write(network->tls_opt.handle, buf, len, timeout, write_len);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ int qcloud_tls_is_connected(qcloud_network_t *network)
|
|
{
|
|
return network->tls_opt.handle != NULL;
|
|
}
|
|
|
|
__QCLOUD_INTERNAL__ qcloud_err_t qcloud_network_tls_init(qcloud_network_t *network)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
network->connect = qcloud_tls_connect;
|
|
network->read = qcloud_tls_read;
|
|
network->write = qcloud_tls_write;
|
|
network->disconnect = qcloud_tls_disconnect;
|
|
|
|
network->is_connected = qcloud_tls_is_connected;
|
|
|
|
return QCLOUD_ERR_SUCCESS;
|
|
}
|
|
|
|
__QCLOUD_INTERNAL__ qcloud_err_t qcloud_dtls_connect(qcloud_network_t *network)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
network->tls_opt.handle = osal_dtls_connect(&(network->tls_opt), network->host, network->port);
|
|
if (network->tls_opt.handle != 0) {
|
|
return QCLOUD_ERR_SUCCESS;
|
|
}
|
|
|
|
return QCLOUD_ERR_FAILURE;
|
|
}
|
|
|
|
__QCLOUD_STATIC__ void qcloud_dtls_disconnect(qcloud_network_t *network)
|
|
{
|
|
if (!network || !network->tls_opt.handle) {
|
|
return;
|
|
}
|
|
|
|
osal_dtls_disconnect(network->tls_opt.handle);
|
|
network->tls_opt.handle = NULL;
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_dtls_read(qcloud_network_t *network, void *buf, size_t len, uint32_t timeout, size_t *read_len)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
return osal_dtls_read(network->tls_opt.handle, buf, len, timeout, read_len);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ qcloud_err_t qcloud_dtls_write(qcloud_network_t *network, const void *buf, size_t len, uint32_t timeout, size_t *write_len)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
return osal_dtls_write(network->tls_opt.handle, buf, len, write_len);
|
|
}
|
|
|
|
__QCLOUD_STATIC__ int qcloud_dtls_is_connected(qcloud_network_t *network)
|
|
{
|
|
return network->tls_opt.handle != NULL;
|
|
}
|
|
|
|
__QCLOUD_INTERNAL__ qcloud_err_t qcloud_network_dtls_init(qcloud_network_t *network)
|
|
{
|
|
QCLOUD_POINTER_SANITY_CHECK(network, QCLOUD_ERR_INVAL);
|
|
|
|
network->connect = qcloud_dtls_connect;
|
|
network->read = qcloud_dtls_read;
|
|
network->write = qcloud_dtls_write;
|
|
network->disconnect = qcloud_dtls_disconnect;
|
|
|
|
network->is_connected = qcloud_dtls_is_connected;
|
|
|
|
return QCLOUD_ERR_SUCCESS;
|
|
}
|
|
|
|
#endif
|
|
|