add new qloud-c-sdk component

This commit is contained in:
mculover666
2022-03-25 10:06:56 +08:00
parent 565cd29e94
commit a3ac2e56d8
166 changed files with 35027 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
option(USE_STATIC_MBEDTLS_LIBRARY "Build mbed TLS static library." ON)
option(USE_SHARED_MBEDTLS_LIBRARY "Build mbed TLS shared library." OFF)
option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF)
file(GLOB src_mbedtls
${CMAKE_CURRENT_SOURCE_DIR}/mbedtls/library/*.c
${CMAKE_CURRENT_SOURCE_DIR}/port/src/*.c
)
if(${CONFIG_EXTRACT_SRC} STREQUAL "ON")
file(GLOB inc_mbedtls ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls/include/mbedtls/*.h)
file(GLOB inc_port ${CMAKE_CURRENT_SOURCE_DIR}/port/inc/*h)
file(COPY ${src_mbedtls} DESTINATION ${PROJECT_SOURCE_DIR}/output/sdk/src/3rd/mbedtls)
file(COPY ${inc_mbedtls} DESTINATION ${PROJECT_SOURCE_DIR}/output/sdk/inc/3rd/mbedtls)
file(COPY ${inc_port} DESTINATION ${PROJECT_SOURCE_DIR}/output/sdk/inc/3rd)
endif()
add_library(mbedtls STATIC ${src_mbedtls})

View File

@@ -0,0 +1,119 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_tls_client.h
* @brief header file for tls client
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-07-12
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-07-12 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#ifndef IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_CLIENT_H_
#define IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_CLIENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qcloud_iot_platform.h"
#ifndef MAX_SIZE_OF_CLIENT_ID
#define MAX_SIZE_OF_CLIENT_ID (80)
#endif
/**
* @brief Define structure for TLS connection parameters
*
*/
typedef struct {
const char *ca_crt;
uint16_t ca_crt_len;
#ifdef AUTH_MODE_CERT
/**
* Device with certificate
*/
const char *cert_file; // public certificate file
const char *key_file; // pravite certificate file
#else
/**
* Device with PSK
*/
const char *psk; // PSK string
const char *psk_id; // PSK ID
#endif
size_t psk_length; // PSK length
unsigned int timeout_ms; // SSL handshake timeout in millisecond
} SSLConnectParams;
typedef SSLConnectParams TLSConnectParams;
/**
* @brief Tls setup and sharkhand
*
* @param[in] connect_params connect params of tls
* @param[in] host server host
* @param[in] port server port
* @return tls handle, 0 for fail
*/
uintptr_t qcloud_iot_tls_client_connect(const TLSConnectParams *connect_params, const char *host, const char *port);
/**
* @brief Disconect and free
*
* @param[in,out] handle tls handle
*/
void qcloud_iot_tls_client_disconnect(uintptr_t handle);
/**
* @brief Write msg with tls
*
* @param[in,out] handle tls handle
* @param[in] msg msg to write
* @param[in] total_len number of bytes to write
* @param[in] timeout_ms timeout millsecond
* @param[out] written_len number of bytes writtern
* @return @see IotReturnCode
*/
int qcloud_iot_tls_client_write(uintptr_t handle, unsigned char *msg, size_t total_len, uint32_t timeout_ms,
size_t *written_len);
/**
* @brief Read msg with tls
*
* @param[in,out] handle tls handle
* @param[out] msg msg buffer
* @param[in] total_len buffer len
* @param[in] timeout_ms timeout millsecond
* @param[out] read_len number of bytes read
* @return @see IotReturnCode
*/
int qcloud_iot_tls_client_read(uintptr_t handle, unsigned char *msg, size_t total_len, uint32_t timeout_ms,
size_t *read_len);
#if defined(__cplusplus)
}
#endif
#endif // IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_CLIENT_H_

View File

@@ -0,0 +1,81 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_tls_psk_config.h
* @brief set config for tls psk
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-07-12
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-07-12 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#ifndef IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_PSK_CONFIG_H
#define IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_PSK_CONFIG_H
#if defined(__cplusplus)
extern "C" {
#endif
/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_TIMING_ALT
// #define MBEDTLS_ENTROPY_HARDWARE_ALT
// #define MBEDTLS_NO_PLATFORM_ENTROPY
/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_CIPHER_PADDING_PKCS7
#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
#define MBEDTLS_CIPHER_PADDING_ZEROS
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_MD_C
#define MBEDTLS_MD5_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
#define MBEDTLS_SSL_SESSION_TICKETS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_SSL_MAX_CONTENT_LEN 3584
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
/* For testing with compat.sh */
#include "mbedtls/check_config.h"
#if defined(__cplusplus)
}
#endif
#endif // IOT_HUB_DEVICE_C_SDK_3RD_MBEDTLS_PORT_INC_QCLOUD_IOT_TLS_PSK_CONFIG_H

View File

@@ -0,0 +1,155 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_net_socket.c
* @brief implements mbedtls net socket api for tls client
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-07-09
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-07-09 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#include "qcloud_iot_platform.h"
#include "mbedtls/net_sockets.h"
/**
* @brief Convert return code from IotReturnCode to mbedtls error code
*
* @param[in] iot_return_code @see IotReturnCode
* @return mbedtls error code
*/
static int _return_code_convert(int iot_return_code)
{
switch (iot_return_code) {
case QCLOUD_ERR_TCP_UNKNOWN_HOST:
return MBEDTLS_ERR_NET_UNKNOWN_HOST;
case QCLOUD_ERR_TCP_SOCKET_FAILED:
return MBEDTLS_ERR_NET_SOCKET_FAILED;
case QCLOUD_ERR_TCP_CONNECT:
return MBEDTLS_ERR_NET_CONNECT_FAILED;
case QCLOUD_ERR_TCP_WRITE_TIMEOUT:
return MBEDTLS_ERR_SSL_WANT_WRITE;
case QCLOUD_ERR_TCP_WRITE_FAIL:
return MBEDTLS_ERR_NET_SEND_FAILED;
case QCLOUD_ERR_TCP_PEER_SHUTDOWN:
return MBEDTLS_ERR_NET_CONN_RESET;
case QCLOUD_ERR_TCP_READ_TIMEOUT:
return MBEDTLS_ERR_SSL_TIMEOUT;
case QCLOUD_ERR_TCP_NOTHING_TO_READ:
return MBEDTLS_ERR_SSL_WANT_READ;
case QCLOUD_ERR_TCP_READ_FAIL:
return MBEDTLS_ERR_NET_RECV_FAILED;
default:
return -1;
}
}
/**
* @brief Init net context
*
* @param[in,out] ctx mbedtls net context handle
*/
void mbedtls_net_init(mbedtls_net_context *ctx)
{
ctx->fd = -1;
}
/**
* @brief Initiate a TCP connection with host:port and the given protocol
*
* @param[in,out] ctx mbedtls net context handle
* @param[in] host host to connect
* @param[in] port port to connect
* @param[in] proto no use for always tcp
* @return fd > 0 for success, others for mbedtls error code
*/
int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host, const char *port, int proto)
{
ctx->fd = HAL_TCP_Connect(host, port);
return ctx->fd < 0 ? _return_code_convert(ctx->fd) : ctx->fd;
}
/**
* @brief Read at most 'len' characters
*
* @param[in] ctx mbedtls net context handle
* @param[out] buf data buffer
* @param[in] len data buffer len
* @return > 0 for data received bytes, others for mbedtls error code
*/
int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
{
int rc;
size_t rlen;
int fd = ((mbedtls_net_context *)ctx)->fd;
rc = HAL_TCP_Read(fd, buf, len, INT_MAX, &rlen);
return rc ? _return_code_convert(rc) : rlen;
}
/**
* @brief Read at most 'len' characters, blocking for at most 'timeout' ms
*
* @param[in] ctx mbedtls net context handle
* @param[out] buf data buffer
* @param[in] len data buffer len
* @param[in] timeout read timeout
* @return > 0 for data received bytes, others for mbedtls error code
*/
int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t timeout)
{
int rc;
size_t rlen;
int fd = ((mbedtls_net_context *)ctx)->fd;
rc = HAL_TCP_Read(fd, buf, len, timeout, &rlen);
return rc ? _return_code_convert(rc) : rlen;
}
/**
* @brief Write at most 'len' characters
*
* @param[in] ctx mbedtls net context handle
* @param[in] buf data buffer
* @param[in] len data buffer len
* @return > 0 for data writtern bytes, others for mbedtls error code
*/
int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len)
{
int rc;
size_t wlen;
int fd = ((mbedtls_net_context *)ctx)->fd;
rc = HAL_TCP_Write(fd, buf, len, INT_MAX, &wlen);
return rc ? _return_code_convert(rc) : wlen;
}
/**
* @brief Gracefully close the connection
*
* @param ctx mbedtls net context handle
*/
void mbedtls_net_free(mbedtls_net_context *ctx)
{
HAL_TCP_Disconnect(ctx->fd);
}

View File

@@ -0,0 +1,394 @@
/**
* @copyright
*
* Tencent is pleased to support the open source community by making IoT Hub available.
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
*
* Licensed under the MIT License(the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*
* @file qcloud_iot_tls_client.c
* @brief implements tls client with mbedtls
* @author fancyxu (fancyxu@tencent.com)
* @version 1.0
* @date 2021-07-12
*
* @par Change Log:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-07-12 <td>1.0 <td>fancyxu <td>first commit
* </table>
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "qcloud_iot_tls_client.h"
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#ifdef AUTH_MODE_KEY
/**
* @brief Only tls psk is supportted when using psk
*
*/
static const int ciphersuites[] = {MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, 0};
#endif
/**
* @brief Data structure for mbedtls SSL connection
*
*/
typedef struct {
mbedtls_net_context socket_fd;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config ssl_conf;
#ifdef AUTH_MODE_CERT
mbedtls_x509_crt ca_cert;
mbedtls_x509_crt client_cert;
#endif
mbedtls_pk_context private_key;
} TLSHandle;
#ifdef MBEDTLS_DEBUG_C
#define DEBUG_LEVEL 0
static void _ssl_debug(void *ctx, int level, const char *file, int line, const char *str)
{
Log_i("[mbedTLS]:[%s]:[%d]: %s\r\n", STRING_PTR_PRINT_SANITY_CHECK(file), line, STRING_PTR_PRINT_SANITY_CHECK(str));
}
#endif
/**
* @brief mbedtls SSL client init
*
* 1. call a series of mbedtls init functions
* 2. init and set seed for random functions
* 3. load CA file, cert files or PSK
*
* @param[in,out] tls_handle mbedtls TLS handle
* @param[in] connect_params device info for TLS connection
* @return @see IotReturnCode
*/
static int _mbedtls_tls_client_init(TLSHandle *tls_handle, const TLSConnectParams *connect_params)
{
int rc;
mbedtls_net_init(&tls_handle->socket_fd);
mbedtls_ssl_init(&tls_handle->ssl);
mbedtls_ssl_config_init(&tls_handle->ssl_conf);
mbedtls_ctr_drbg_init(&tls_handle->ctr_drbg);
mbedtls_entropy_init(&tls_handle->entropy);
#ifdef AUTH_MODE_CERT
mbedtls_x509_crt_init(&tls_handle->ca_cert);
mbedtls_x509_crt_init(&tls_handle->client_cert);
mbedtls_pk_init(&tls_handle->private_key);
#endif
#ifdef MBEDTLS_DEBUG_C
mbedtls_debug_set_threshold(DEBUG_LEVEL);
mbedtls_ssl_conf_dbg(&tls_handle->ssl_conf, _ssl_debug, NULL);
#endif
rc = mbedtls_ctr_drbg_seed(&tls_handle->ctr_drbg, mbedtls_entropy_func, &tls_handle->entropy, NULL, 0);
if (rc) {
Log_e("mbedtls_ctr_drbg_seed failed returned 0x%04x", -rc);
return QCLOUD_ERR_SSL_INIT;
}
#ifdef AUTH_MODE_CERT
if (!connect_params->cert_file || !connect_params->key_file || !connect_params->ca_crt) {
Log_d("cert_file/key_file/ca is empty!|cert_file=%s|key_file=%s|ca=%s",
STRING_PTR_PRINT_SANITY_CHECK(connect_params->cert_file),
STRING_PTR_PRINT_SANITY_CHECK(connect_params->key_file),
STRING_PTR_PRINT_SANITY_CHECK(connect_params->ca_crt));
return QCLOUD_ERR_SSL_CERT;
}
rc = mbedtls_x509_crt_parse(&tls_handle->ca_cert, (const unsigned char *)connect_params->ca_crt,
(connect_params->ca_crt_len + 1));
if (rc) {
Log_e("parse ca crt failed returned 0x%04x", -rc);
return QCLOUD_ERR_SSL_CERT;
}
rc = mbedtls_x509_crt_parse_file(&tls_handle->client_cert, connect_params->cert_file);
if (rc) {
Log_e("load client cert file failed returned 0x%04x", -rc);
return QCLOUD_ERR_SSL_CERT;
}
rc = mbedtls_pk_parse_keyfile(&tls_handle->private_key, connect_params->key_file, "");
if (rc) {
Log_e("load client key file failed returned 0x%04x", -rc);
return QCLOUD_ERR_SSL_CERT;
}
#else
if (!connect_params->psk || !connect_params->psk_id) {
Log_d("psk/psk_id is empty!");
return QCLOUD_ERR_SSL_INIT;
}
rc = mbedtls_ssl_conf_psk(&tls_handle->ssl_conf, (unsigned char *)connect_params->psk, connect_params->psk_length,
(const unsigned char *)connect_params->psk_id, strlen(connect_params->psk_id));
if (rc) {
Log_e("mbedtls_ssl_conf_psk fail 0x%04x", -rc);
return rc;
}
#endif
return QCLOUD_RET_SUCCESS;
}
/**
* @brief Free memory/resources allocated by mbedtls
*
* @param[in,out] tls_handle @see TLSHandle
*/
static void _mbedtls_tls_client_free(TLSHandle *tls_handle)
{
mbedtls_net_free(&(tls_handle->socket_fd));
#ifdef AUTH_MODE_CERT
mbedtls_x509_crt_free(&tls_handle->client_cert);
mbedtls_x509_crt_free(&tls_handle->ca_cert);
mbedtls_pk_free(&tls_handle->private_key);
#endif
mbedtls_ssl_free(&tls_handle->ssl);
mbedtls_ssl_config_free(&tls_handle->ssl_conf);
mbedtls_ctr_drbg_free(&tls_handle->ctr_drbg);
mbedtls_entropy_free(&tls_handle->entropy);
HAL_Free(tls_handle);
}
#ifdef AUTH_MODE_CERT
/**
* @brief verify server certificate
*
* mbedtls has provided similar function mbedtls_x509_crt_verify_with_profile
*/
int _mbedtls_tls_client_certificate_verify(void *hostname, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
{
return *flags;
}
#endif
/**
* @brief Tls setup and sharkhand
*
* @param[in] connect_params connect params of tls
* @param[in] host server host
* @param[in] port server port
* @return tls handle, 0 for fail
*/
uintptr_t qcloud_iot_tls_client_connect(const TLSConnectParams *connect_params, const char *host, const char *port)
{
int rc = 0;
TLSHandle *tls_handle = (TLSHandle *)HAL_Malloc(sizeof(TLSHandle));
if (!tls_handle) {
return 0;
}
rc = _mbedtls_tls_client_init(tls_handle, connect_params);
if (rc) {
goto error;
}
Log_d("Setting up the SSL/TLS structure...");
rc = mbedtls_ssl_config_defaults(&tls_handle->ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
if (rc) {
Log_e("mbedtls_ssl_config_defaults failed returned 0x%04x", -rc);
goto error;
}
mbedtls_ssl_conf_rng(&tls_handle->ssl_conf, mbedtls_ctr_drbg_random, &tls_handle->ctr_drbg);
#ifdef AUTH_MODE_CERT
mbedtls_ssl_conf_verify(&(tls_handle->ssl_conf), _mbedtls_tls_client_certificate_verify, (void *)host);
mbedtls_ssl_conf_authmode(&(tls_handle->ssl_conf), MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&tls_handle->ssl_conf, &tls_handle->ca_cert, NULL);
rc = mbedtls_ssl_conf_own_cert(&tls_handle->ssl_conf, &tls_handle->client_cert, &tls_handle->private_key);
if (rc) {
Log_e("mbedtls_ssl_conf_own_cert failed returned 0x%04x", -rc);
goto error;
}
#endif
mbedtls_ssl_conf_read_timeout(&tls_handle->ssl_conf, connect_params->timeout_ms);
rc = mbedtls_ssl_setup(&tls_handle->ssl, &tls_handle->ssl_conf);
if (rc) {
Log_e("mbedtls_ssl_setup failed returned 0x%04x", -rc);
goto error;
}
#ifdef AUTH_MODE_CERT
// Set the hostname to check against the received server certificate and sni
rc = mbedtls_ssl_set_hostname(&tls_handle->ssl, host);
if (rc) {
Log_e("mbedtls_ssl_set_hostname failed returned 0x%04x", -rc);
goto error;
}
#else
// ciphersuites selection for PSK device
if (connect_params->psk) {
mbedtls_ssl_conf_ciphersuites(&(tls_handle->ssl_conf), ciphersuites);
}
#endif
mbedtls_ssl_set_bio(&tls_handle->ssl, &tls_handle->socket_fd, mbedtls_net_send, mbedtls_net_recv,
mbedtls_net_recv_timeout);
Log_d("Performing the SSL/TLS handshake...");
Log_d("Connecting to /%s/%s...", STRING_PTR_PRINT_SANITY_CHECK(host), STRING_PTR_PRINT_SANITY_CHECK(port));
rc = mbedtls_net_connect(&tls_handle->socket_fd, host, port, MBEDTLS_NET_PROTO_TCP);
if (rc < 0) {
goto error;
}
do {
rc = mbedtls_ssl_handshake(&tls_handle->ssl);
if (rc && rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
Log_e("mbedtls_ssl_handshake failed returned 0x%04x", -rc);
#ifdef AUTH_MODE_CERT
if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
Log_e("Unable to verify the server's certificate");
}
#endif
goto error;
}
} while (rc);
rc = mbedtls_ssl_get_verify_result(&(tls_handle->ssl));
if (rc) {
Log_e("mbedtls_ssl_get_verify_result failed returned 0x%04x", -rc);
goto error;
}
mbedtls_ssl_conf_read_timeout(&tls_handle->ssl_conf, 200);
Log_d("connected with /%s/%s...", STRING_PTR_PRINT_SANITY_CHECK(host), port);
return (uintptr_t)tls_handle;
error:
_mbedtls_tls_client_free(tls_handle);
return 0;
}
/**
* @brief Disconect and free
*
* @param[in,out] handle tls handle
*/
void qcloud_iot_tls_client_disconnect(uintptr_t handle)
{
int rc = 0;
TLSHandle *tls_handle = (TLSHandle *)handle;
if (!tls_handle) {
Log_d("handle is NULL");
return;
}
do {
rc = mbedtls_ssl_close_notify(&tls_handle->ssl);
} while (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE);
_mbedtls_tls_client_free(tls_handle);
}
/**
* @brief Write msg with tls
*
* @param[in,out] handle tls handle
* @param[in] msg msg to write
* @param[in] total_len number of bytes to write
* @param[in] timeout_ms timeout millsecond
* @param[out] written_len number of bytes writtern
* @return @see IotReturnCode
*/
int qcloud_iot_tls_client_write(uintptr_t handle, unsigned char *msg, size_t total_len, uint32_t timeout_ms,
size_t *written_len)
{
Timer timer;
size_t written_so_far;
int write_rc = 0;
TLSHandle *tls_handle = (TLSHandle *)handle;
HAL_Timer_CountdownMs(&timer, (unsigned int)timeout_ms);
for (written_so_far = 0; written_so_far < total_len && !HAL_Timer_Expired(&timer); written_so_far += write_rc) {
do {
write_rc = mbedtls_ssl_write(&tls_handle->ssl, msg + written_so_far, total_len - written_so_far);
if (write_rc < 0 && write_rc != MBEDTLS_ERR_SSL_WANT_READ && write_rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
Log_e("HAL_TLS_write failed 0x%04x", -write_rc);
return QCLOUD_ERR_SSL_WRITE;
}
if (HAL_Timer_Expired(&timer)) {
break;
}
} while (write_rc <= 0);
}
*written_len = written_so_far;
if (HAL_Timer_Expired(&timer) && written_so_far != total_len) {
return QCLOUD_ERR_SSL_WRITE_TIMEOUT;
}
return QCLOUD_RET_SUCCESS;
}
/**
* @brief Read msg with tls
*
* @param[in,out] handle tls handle
* @param[out] msg msg buffer
* @param[in] total_len buffer len
* @param[in] timeout_ms timeout millsecond
* @param[out] read_len number of bytes read
* @return @see IotReturnCode
*/
int qcloud_iot_tls_client_read(uintptr_t handle, unsigned char *msg, size_t total_len, uint32_t timeout_ms,
size_t *read_len)
{
Timer timer;
int read_rc;
TLSHandle *tls_handle = (TLSHandle *)handle;
HAL_Timer_CountdownMs(&timer, timeout_ms);
*read_len = 0;
do {
read_rc = mbedtls_ssl_read(&tls_handle->ssl, msg + *read_len, total_len - *read_len);
if (read_rc <= 0 && read_rc != MBEDTLS_ERR_SSL_WANT_WRITE && read_rc != MBEDTLS_ERR_SSL_WANT_READ &&
read_rc != MBEDTLS_ERR_SSL_TIMEOUT) {
Log_e("cloud_iot_network_tls_read failed: 0x%04x", -read_rc);
return QCLOUD_ERR_SSL_READ;
}
*read_len += read_rc > 0 ? read_rc : 0;
if (HAL_Timer_Expired(&timer)) {
break;
}
} while (*read_len < total_len);
if (*read_len > 0) {
return QCLOUD_RET_SUCCESS;
}
return *read_len == 0 ? QCLOUD_ERR_SSL_NOTHING_TO_READ : QCLOUD_ERR_SSL_READ_TIMEOUT;
}
#ifdef __cplusplus
}
#endif