chore: migrate project into clean repository

This commit is contained in:
yuuux
2026-08-13 16:50:52 +08:00
commit d1d25a09e7
27405 changed files with 9422808 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
if (CONFIG_MODULE_ZE_TLS)
set(PRJ_PATH ${CMAKE_HOME_DIRECTORY})
set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB_RECURSE LIB_SRCS "*.c")
listenai_library_named(http_ssl)
listenai_library_sources(${LIB_SRCS})
listenai_include_directories(
${LIB_PATH}/include
${PRJ_PATH}/../../../modules/mbedtls/mbedtls/include
)
option(MBEDTLS_API_DEBUG "ze_tls: mbedtls api debug" OFF)
if (MBEDTLS_API_DEBUG)
target_compile_definitions(${LISTENAI_CURRENT_LIBRARY}
PRIVATE MBEDTLS_API_DEBUG
PRIVATE MBEDTLS_DEBUG_LEVEL=0
)
endif()
target_compile_definitions(${LISTENAI_CURRENT_LIBRARY}
PRIVATE MBEDTLS_CONNECT_TIMEOUT_MS=3000
PRIVATE TLS_DEBUG_LEVEL=3
PRIVATE TLS_RECV_TIMOUT_DEFAULT=9*60*1000
)
endif()

View File

@@ -0,0 +1,7 @@
menu "SSL/TLS transport layer configuration"
config MODULE_ZE_TLS
bool "ze_tls support"
default n
endmenu

View File

@@ -0,0 +1,106 @@
#ifndef _ZE_TLS_H_
#define _ZE_TLS_H_
#include <mbedtls/debug.h>
#include <mbedtls/x509_crt.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/ssl.h>
// #include <mbedtls/net.h>
#include <mbedtls/net_sockets.h>
#include "lwip/sockets.h"
#include <stdio.h>
// #include <fcntl.h>
/**
* Server certificate(CA/CRL/KEY) container
*/
typedef struct {
char *pCa; /* ca pointer */
unsigned int nCa; /* ca length */
char *pCert; /* cert pointer */
unsigned int nCert; /* cert length */
char *pKey; /* key pointer */
unsigned int nKey; /* key length */
} security_server;
/**
* Client certificate(CA) container
*/
typedef struct {
char *pCa; /* ca pointer */
unsigned int nCa; /* ca length */
security_server certs;
} security_client;
/**
* Container for certificate and Public key container.
*/
typedef union {
struct {
mbedtls_x509_crt ca; /* CA used for verify server crt */
mbedtls_x509_crt cert; /* crt for oneself */
mbedtls_pk_context key; /* key for oneself */
} cli_cert;
struct {
mbedtls_x509_crt cert;
mbedtls_pk_context key; /* Public key container */
} srv_cert;
} crt_context;
/**
* mbedtls wrapper context structure
*
* The structure ensures that mbedtls api works properly and is dynamically created by
* api (mbedtls_init_context). It contains all the info needed in the tls process.
*/
typedef struct
{
int is_client;
crt_context cert;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
} mbedtls_context;
typedef mbedtls_net_context mbedtls_sock;
#if defined (MBEDTLS_SSL_CLI_C)
#define MBEDTLS_CLIENT
#endif
#if defined (MBEDTLS_SSL_SRV_C)
#define MBEDTLS_SERVER
#endif
#define MBEDTLS_SSL_CLIENT_VERIFY_LEVEL MBEDTLS_SSL_VERIFY_OPTIONAL
#define MBEDTLS_SSL_SERVER_VERIFY_LEVEL MBEDTLS_SSL_VERIFY_NONE
mbedtls_sock* mbedtls_socket(int nonblock);
mbedtls_context* mbedtls_init_context(int client);
void mbedtls_deinit_context(mbedtls_context *context);
int mbedtls_closesocket(mbedtls_sock* fd);
int mbedtls_config_context(mbedtls_context *context, void *param, int verify);
int mbedtls_handshake(mbedtls_context *context, mbedtls_sock* fd);
int mbedtls_send(mbedtls_context *context,char *buf, int len);
void mbedtls_set_recv_timeout(mbedtls_context *context, int timeout_ms);
int mbedtls_recv(mbedtls_context *context, char *buf, int len);
int mbedtls_recv_pending(mbedtls_context *context);
int mbedtls_connect(mbedtls_context *context, mbedtls_sock* fd, struct sockaddr *name, int namelen, char *hostname);
int mbedtls_accept(mbedtls_context *context, mbedtls_sock *local_fd, mbedtls_sock *remote_fd);
#endif

View File

@@ -0,0 +1,28 @@
#ifndef _ZE__TRANSPORT_SSL_H_
#define _ZE__TRANSPORT_SSL_H_
#include "ze_tls.h"
typedef struct ze_transport_ssl
{
security_client m_client_param;
mbedtls_context *m_context;
mbedtls_sock m_httpc_net_fd;
} ze_transport_ssl_t;
int ze_transport_ssl_connect(ze_transport_ssl_t *handle, int s, const struct sockaddr *name, int namelen, char *hostname);
void ze_transport_ssl_set_recvtimeout(ze_transport_ssl_t *handle, int timeout_ms);
int ze_transport_ssl_negotiate(ze_transport_ssl_t *handle, int s, char *hostname);
int ze_transport_ssl_send(ze_transport_ssl_t *handle, int s, char *buf, int len, int flags);
int ze_transport_ssl_recv(ze_transport_ssl_t *handle, int s, char *buf, int len, int flags);
int ze_transport_ssl_recv_pending(ze_transport_ssl_t *handle, int s);
int ze_transport_ssl_close(ze_transport_ssl_t *handle, int s);
#endif

View File

@@ -0,0 +1,632 @@
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include "ze_tls.h"
#include <unistd.h>
#include <mbedtls/platform.h>
#include "log_print.h"
#include "rtos_al.h"
// #define MBEDTLS_API_DEBUG
#define __FILENAME(f) strrchr(f, '/')
#if defined(MBEDTLS_API_DEBUG)
#define DEBUG_PREFIX "[mbedtls] "
#define MBEDTLS_DEBUG_ERR 0
#define MBEDTLS_DEBUG_INF 1
// #define MBEDTLS_DEBUG_LEVEL 0
// #define MBEDTLS_CONNECT_TIMEOUT_MS (3000)
#define mbedtls_err(msg...) \
do{ \
if (MBEDTLS_DEBUG_LEVEL >= MBEDTLS_DEBUG_ERR) { \
logDbg(DEBUG_PREFIX "err %s:%04d:", __FILENAME(__FILE__), __LINE__); \
logDbg(msg); \
} \
}while(0)
#define mbedtls_inf(msg...) \
do{ \
if (MBEDTLS_DEBUG_LEVEL >= MBEDTLS_DEBUG_INF) { \
logDbg(DEBUG_PREFIX "%s:%04d:", __FILENAME(__FILE__), __LINE__); \
logDbg(msg); \
} \
}while(0)
#define mbedtls_dbg(level, msg...) mbedtls_##level(msg)
#else
#define mbedtls_dbg(level, msg...)
#endif
// #ifndef fcntl
// #define fcntl lwip_fcntl
// #endif
// #define TLS_DEBUG_LEVEL 3
// #define TLS_RECV_TIMOUT_DEFAULT (9*60*1000) /* 9 min */
static const char pers[] = "custom tls";
static void mbedtls_debug(void *ctx, int level,const char *file,
int line, const char *str)
{
logDbg("%s:%04d: %s", __FILENAME(file), line, str);
}
/**
* @brief Create and Initializes the mbedtls context
*
* @param client: service to be init
* @retval The pointer of tls context if success or NULL otherwise.
*/
mbedtls_context* mbedtls_init_context(int client)
{
mbedtls_context *pContext = NULL;
if ((pContext = mbedtls_calloc(1, sizeof(*pContext))) == NULL) {
mbedtls_dbg(err, "Malloc mem failed.\n");
return (void *)NULL;
}
mbedtls_dbg(inf, "Init tls context.\n");
memset(pContext, 0, sizeof(*pContext));
pContext->is_client = client;
mbedtls_ssl_init(&(pContext->ssl));
mbedtls_ssl_config_init(&(pContext->conf));
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
mbedtls_x509_crt_init(&(pContext->cert.cli_cert.ca));
mbedtls_x509_crt_init(&(pContext->cert.cli_cert.cert));
mbedtls_pk_init(&(pContext->cert.cli_cert.key));
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER) {
mbedtls_x509_crt_init(&(pContext->cert.srv_cert.cert));
mbedtls_pk_init(&(pContext->cert.srv_cert.key));
}
#endif
mbedtls_ctr_drbg_init(&(pContext->ctr_drbg));
mbedtls_entropy_init(&(pContext->entropy));
mbedtls_dbg(inf, "Init ok.\n");
#if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold(TLS_DEBUG_LEVEL);
#endif
return pContext;
}
/**
* @brief Config the mbedtls context
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param param: pointer to a security_client/security_server structure from user.
* @param verify: level of check cert
* @retval 0 if success or -1 otherwise.
*/
int mbedtls_config_context(mbedtls_context *context, void *param, int verify)
{
int ret = 0;
#if defined(MBEDTLS_SSL_CLI_C)
security_client *client = NULL;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
security_server *server = NULL;
#endif
mbedtls_dbg(inf, "Config start..\n");
if (context == NULL || param == NULL)
return -1;
mbedtls_context *pContext = (mbedtls_context *)context;
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT)
client = (security_client *)param;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER)
server = (security_server *)param;
#endif
#if defined(MBEDTLS_SSL_CLI_C)
/* Load the certificates and private RSA key */
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
if ((ret = mbedtls_x509_crt_parse(&(pContext->cert.cli_cert.ca),
(const unsigned char *)(client->pCa),
client->nCa)) != 0) {
mbedtls_dbg(err, "mbedtls_x509_crt_parse failed..(%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
if (client->certs.pCert != NULL && client->certs.pCa != NULL && client->certs.pKey != NULL) {
/* Tls client parse own crl*/
if ((ret = mbedtls_x509_crt_parse(&(pContext->cert.cli_cert.cert),
(const unsigned char *)(client->certs.pCert),
client->certs.nCert)) != 0) {
mbedtls_dbg(err, "mbedtls_x509_crt_parse failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
if ((ret = mbedtls_x509_crt_parse(&(pContext->cert.cli_cert.ca),
(const unsigned char *)(client->certs.pCa),
client->certs.nCa)) != 0) {
mbedtls_dbg(err, "mbedtls_x509_crt_parse failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#ifdef MBEDTLS_V3
if ((ret = mbedtls_pk_parse_key(&(pContext->cert.cli_cert.key),
(const unsigned char *)(client->certs.pKey),
client->certs.nKey, NULL, 0, mbedtls_ctr_drbg_random, &(pContext->ctr_drbg))) != 0) {
mbedtls_dbg(err, "mbedtls_pk_parse_key failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#else
if ((ret = mbedtls_pk_parse_key(&(pContext->cert.cli_cert.key),
(const unsigned char *)(client->certs.pKey),
client->certs.nKey, NULL, 0)) != 0) {
mbedtls_dbg(err, "mbedtls_pk_parse_key failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#endif
}
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER) {
if ((ret = mbedtls_x509_crt_parse(&(pContext->cert.srv_cert.cert),
(const unsigned char *)(server->pCert),
server->nCert)) != 0) {
mbedtls_dbg(err, "mbedtls_x509_crt_parse failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
if ((ret = mbedtls_x509_crt_parse(&(pContext->cert.srv_cert.cert),
(const unsigned char *)(server->pCa),
server->nCa)) != 0) {
mbedtls_dbg(err, "mbedtls_x509_crt_parse failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#ifdef MBEDTLS_V3
if ((ret = mbedtls_pk_parse_key(&(pContext->cert.srv_cert.key),
(const unsigned char *)(server->pKey),
server->nKey, NULL, 0, mbedtls_ctr_drbg_random, &(pContext->ctr_drbg))) != 0) {
mbedtls_dbg(err, "mbedtls_pk_parse_key failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#else
if ((ret = mbedtls_pk_parse_key(&(pContext->cert.srv_cert.key),
(const unsigned char *)(server->pKey),
server->nKey, NULL, 0)) != 0) {
mbedtls_dbg(err, "mbedtls_pk_parse_key failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#endif
}
#endif
if ((ret = mbedtls_ctr_drbg_seed(&(pContext->ctr_drbg), mbedtls_entropy_func,
&(pContext->entropy),
(const unsigned char *) pers,
strlen(pers))) != 0) {
mbedtls_dbg(err, "mbedtls_ctr_drbg_seed failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
if ((ret = mbedtls_ssl_config_defaults(&(pContext->conf), MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
return -1;
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER) {
if ((ret = mbedtls_ssl_config_defaults(&(pContext->conf), MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
return -1;
}
#endif
mbedtls_ssl_conf_authmode(&(pContext->conf), verify);
mbedtls_ssl_conf_read_timeout(&(pContext->conf), TLS_RECV_TIMOUT_DEFAULT); /* recv timeout 9 min */
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
mbedtls_ssl_conf_ca_chain(&(pContext->conf), &(pContext->cert.cli_cert.ca), NULL);
if (client->certs.pCert != NULL && client->certs.pKey != NULL) {
if ((ret = mbedtls_ssl_conf_own_cert(&(pContext->conf), &(pContext->cert.cli_cert.cert),
&(pContext->cert.cli_cert.key))) != 0) {
mbedtls_dbg(err, "mbedtls_ssl_conf_own_cert failed (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
}
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER) {
mbedtls_ssl_conf_ca_chain(&(pContext->conf), pContext->cert.srv_cert.cert.next, NULL);
if ((ret = mbedtls_ssl_conf_own_cert(&(pContext->conf), &(pContext->cert.srv_cert.cert),
&(pContext->cert.srv_cert.key))) != 0) {
mbedtls_dbg(err, "mbedtls_ssl_conf_own_cert failed (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
}
#endif
mbedtls_ssl_conf_rng(&(pContext->conf), mbedtls_ctr_drbg_random, &(pContext->ctr_drbg));
mbedtls_ssl_conf_dbg(&(pContext->conf), mbedtls_debug, stdout );
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
// mbedtls_ssl_conf_max_frag_len(&(pContext->conf), MBEDTLS_SSL_MAX_FRAG_LEN_4096);
}
#endif
if ((ret = mbedtls_ssl_setup( &(pContext->ssl), &(pContext->conf))) != 0) {
mbedtls_dbg(err, "mbedtls_ssl_setup failed.. (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
mbedtls_dbg(inf, "Config ok..\n");
return 0;
}
#if defined(MBEDTLS_SSL_CLI_C)
static int mbedtls_get_noblock(mbedtls_net_context *ctx)
{
if (ctx == NULL) {
mbedtls_dbg(err, "Ctx is NULL.\n");
return -1;
}
if ((fcntl(ctx->fd, F_GETFL, 0) & O_NONBLOCK) != O_NONBLOCK)
return( 0 );
return 1;
}
/**
* @brief Connect a netconn to a specific remote server with the given sockaddr, socket.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @note The member (context->net_fd.cli_fd)of param context must be inited.
* @param fd: pointer to local socket.
* @param name: pointer to server address of socket.
* @param namelen: length of the sockaddr structure.
* @param hostname: pointer to server's name.
* @retval 0 if success or -1 otherwise.
*/
int mbedtls_connect(mbedtls_context *context, mbedtls_sock *fd, struct sockaddr *name,
int namelen, char *hostname)
{
int is_block = 0;
int ret = 0;
mbedtls_dbg(inf, "Connect start..\n");
mbedtls_context *pContext = (mbedtls_context *)context;
struct sockaddr *ServerAddress = (struct sockaddr *)name;
mbedtls_net_context *net_fd = (mbedtls_net_context *) fd;
if (!pContext || net_fd < 0 || !ServerAddress) {
mbedtls_dbg(err, "Connect invalid arg..\n");
return -1;
}
if (hostname != NULL) {
if ((ret = mbedtls_ssl_set_hostname(&(pContext->ssl), hostname)) != 0)
{
mbedtls_dbg(err, "mbedtls_ssl_set_hostname returned (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
}
if ((is_block = mbedtls_get_noblock(net_fd)) == 0)
mbedtls_net_set_nonblock(net_fd);
if ((ret = connect(net_fd->fd, ServerAddress, namelen)) != 0) {
struct timeval con_timeout;
fd_set fdset;
con_timeout.tv_sec = 0;
con_timeout.tv_usec = MBEDTLS_CONNECT_TIMEOUT_MS * 1000;
FD_ZERO(&fdset);
FD_SET(net_fd->fd, &fdset);
ret = select(net_fd->fd + 1, NULL, &fdset, NULL, &con_timeout);
if (ret <= 0) {
mbedtls_dbg(err, "tls connect %d socket timeout %d\n", net_fd->fd, ret);
return -1;
} else {
mbedtls_dbg(inf, "Connect ok %d..\n", ret);
return 0;
}
}
return ret;
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
/**
* @brief Accept a new connection on a TCP listening netconn.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param local_fd: (input) pointer to a mbedtls_sock structure that is local socket.
*
* @param remote_fd: (output) pointer to a mbedtls_sock structure that is remote socket.
*
* @retval 0 if a new connection has been received or -1
* otherwise
*/
int mbedtls_accept(mbedtls_context *context, mbedtls_sock *local_fd, mbedtls_sock *remote_fd)
{
int ret = 0;
mbedtls_context *pContext = (mbedtls_context *)context;
mbedtls_net_context *client = (mbedtls_net_context *) local_fd;
mbedtls_net_context *server = (mbedtls_net_context *) remote_fd;
if (!pContext || !client || !server)
return -1;
mbedtls_net_free(remote_fd);
mbedtls_ssl_session_reset(&(pContext->ssl));
/* Wait until a client connects */
mbedtls_dbg(inf, "Waiting for a remote connection.\n");
if ((ret = mbedtls_net_accept(server, client, NULL, 0, NULL)) != 0) {
mbedtls_dbg(err, "Failed mbedtls_net_accept returned (%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
return -1;
}
return ret;
}
#endif
/**
* @brief DeInitialize the mbedtls context
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @retval
*/
void mbedtls_deinit_context(mbedtls_context *context)
{
mbedtls_dbg(inf, "Deinit context.\n");
mbedtls_context *pContext = (mbedtls_context *)context;
if (!pContext)
return;
mbedtls_ssl_close_notify(&(pContext->ssl));
#if defined(MBEDTLS_SSL_CLI_C)
if (pContext->is_client == MBEDTLS_SSL_IS_CLIENT) {
mbedtls_x509_crt_free(&(pContext->cert.cli_cert.ca));
mbedtls_x509_crt_free(&(pContext->cert.cli_cert.cert));
mbedtls_pk_free(&(pContext->cert.cli_cert.key));
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (pContext->is_client == MBEDTLS_SSL_IS_SERVER) {
mbedtls_x509_crt_free(&(pContext->cert.srv_cert.cert));
mbedtls_pk_free(&(pContext->cert.srv_cert.key));
}
#endif
mbedtls_ssl_free(&(pContext->ssl));
mbedtls_ssl_config_free(&(pContext->conf));
mbedtls_ctr_drbg_free(&(pContext->ctr_drbg));
mbedtls_entropy_free(&(pContext->entropy));
mbedtls_free(pContext);
}
/**
* @brief Perform the SSL handshake
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param fd: pointer to a mbedtls_sock structure created by mbedtls_socket
*
* @note If the user resorts to idle line detection wake up, the Address parameter
* is useless and ignored by the initialization function.
* @retval 0 if a new connection has been established or -1
* otherwise
*/
int mbedtls_handshake(mbedtls_context *context, mbedtls_sock* fd)
{
int ret = 0;
mbedtls_net_context *net_fd = fd;
mbedtls_context *pContext = (mbedtls_context *)context;
if (!pContext || !net_fd) {
mbedtls_dbg(err, "handshake invalid arg..\n");
return -1;
}
mbedtls_ssl_set_bio(&(pContext->ssl), net_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
while ((ret = mbedtls_ssl_handshake(&(pContext->ssl))) != 0) {
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
mbedtls_dbg(err, "mbedtls_ssl_handshake failed.(%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
goto exit;
}
rtos_delay(10);
}
/* In real life, we probably want to bail out when ret != 0 */
if ((ret = mbedtls_ssl_get_verify_result(&(pContext->ssl))) != 0) {
#define MBEDTLS_VRFY_BUF_SIZE 512
char *vrfy_buf = mbedtls_calloc(1, MBEDTLS_VRFY_BUF_SIZE);
if (!vrfy_buf) {
mbedtls_dbg(err, "Malloc vrfy buf failed.\n");
} else {
mbedtls_x509_crt_verify_info( vrfy_buf, MBEDTLS_VRFY_BUF_SIZE, "! ", ret);
mbedtls_dbg(err, " %s\n", vrfy_buf);
mbedtls_free(vrfy_buf);
}
if ((MBEDTLS_X509_BADCERT_NOT_TRUSTED == ret && pContext->is_client == MBEDTLS_SSL_IS_CLIENT) ||
(MBEDTLS_X509_BADCERT_SKIP_VERIFY == ret && pContext->is_client == MBEDTLS_SSL_IS_SERVER)) {
/* In real life, we would have used MBEDTLS_SSL_VERIFY_REQUIRED so that the
* handshake would not succeed if the peer's cert is bad. Even if we used
* MBEDTLS_SSL_VERIFY_OPTIONAL, we would bail out here if ret != 0 */
ret = 0;
} else {
mbedtls_dbg(err, "Verify failed(%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
ret = -1;
}
}
if (ret == 0) {
mbedtls_dbg(inf, "Handshake ok(%s).\n", mbedtls_ssl_get_ciphersuite(&(pContext->ssl)));
return 0;
}
exit:
return ret;
}
/**
* @brief Send application data to a specific remote server/client.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param buf: pointer to the application buffer that contains the data to send
* @param len: length of the application data to send
* @retval >0 if data was sent, any other is error
*/
int mbedtls_send(mbedtls_context *context,char *buf, int len)
{
int ret = 0;
mbedtls_context *pContext = (mbedtls_context *)context;
while ((ret = mbedtls_ssl_write(&(pContext->ssl), (const unsigned char *)buf, len)) <= 0) {
if ( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
mbedtls_dbg(err,"mbedtls_ssl_write failed,(%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
goto exit;
}
rtos_delay(10);
}
return ret;
exit:
return -1;
}
/**
* @brief Set/Change the recive timeout for server/client.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param timeout_ms: timeout time, millisecond.
* @retval void.
*/
void mbedtls_set_recv_timeout(mbedtls_context *context, int timeout_ms)
{
mbedtls_context *pContext = (mbedtls_context *)context;
mbedtls_ssl_conf_read_timeout(&(pContext->conf), timeout_ms); /* recv timeout 9 min */
}
/**
* @brief Receive data from a TLS client/server.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @param buf: pointer where stored when received data
* @param len: length of the buf
* @retval >0 if receive data(==0, notify close or eof), any other is error
*/
int mbedtls_recv(mbedtls_context *context, char *buf, int len)
{
int ret = 0;
mbedtls_context *pContext = (mbedtls_context *)context;
memset(buf, 0, len);
mbedtls_dbg(inf,"recv.\n");
do {
ret = mbedtls_ssl_read(&(pContext->ssl), (unsigned char *)buf, len);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
rtos_delay(10);
} while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
mbedtls_dbg(inf,"\nconnection was closed gracefully\n");
return 0;
}
if (ret < 0) {
mbedtls_dbg(err, "mbedtls_ssl_read failed,(%s0x%04x)\n", ret > 0 ? "":"-", ret > 0 ? ret:-ret);
goto exit;;
}
if (ret == 0) {
mbedtls_dbg(inf,"\nEOF\n");
return 0;
}
exit:
return ret;
}
/**
* @brief Calling this, the application return length data left in
* tls layer.
*
* @param context: pointer to a mbedtls_context structure that contains
* the configuration information for tls handshake
* @retval length of data left
*/
int mbedtls_recv_pending(mbedtls_context *context)
{
int ret = 0;
mbedtls_context *pContext = (mbedtls_context *)context;
ret = mbedtls_ssl_get_bytes_avail(&(pContext->ssl));
mbedtls_dbg(inf, "recv pending:%d(bytes).\n", ret);
return ret;
}
/**
* @brief alloc net context
*
* @param nonblock: 1 is set sock nonblock or 0 otherwise
* @retval return net context pointer if success or NULL otherwise
*/
mbedtls_sock* mbedtls_socket(int nonblock)
{
int sock = 0;
mbedtls_sock* net_fd = NULL;
int ret = 0, val = 1;
if ((net_fd = mbedtls_calloc(1, sizeof(*net_fd))) == NULL) {
mbedtls_dbg(err, "Malloc mem failed.\n");
goto fail;
}
mbedtls_net_init(net_fd);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
mbedtls_dbg(err, "socket() return %d.\n", sock);
goto fail;
}
net_fd->fd = sock;
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int));
if (ret != 0) {
mbedtls_dbg(err, "setsockopt(SO_REUSEADDR) failed.\n");
close(sock);
net_fd->fd = -1;
goto fail;
}
if (nonblock > 0)
mbedtls_net_set_nonblock(net_fd);
return net_fd;
fail:
return NULL;
}
/**
* @brief free net context
*
* @param fd: pointer to a mbedtls_sock structure that contains
* socket id
* @retval
*/
int mbedtls_closesocket(mbedtls_sock *fd)
{
mbedtls_net_free(fd);
mbedtls_free(fd);
return 0;
}

View File

@@ -0,0 +1,101 @@
#include "ze_transport_ssl.h"
#include <string.h>
#include <mbedtls/platform.h>
extern const char mbedtls_test_cas_pem[];
extern const size_t mbedtls_test_cas_pem_len;
#define HTTPC_CUSTOM_CAS_PEM mbedtls_test_cas_pem
#define HTTPC_CUSTOM_CAS_PEM_LEN mbedtls_test_cas_pem_len
// static security_client client_param;
// mbedtls_context *g_pContext = NULL;
// mbedtls_sock g_httpc_net_fd = {.fd = -1};
int ze_transport_ssl_connect(ze_transport_ssl_t *handle, int s, const struct sockaddr *name, int namelen, char *hostname)
{
int ret = 0;
// HC_DBG(("Https:connect.."));
struct sockaddr *ServerAddress = (struct sockaddr *)name;
int net_fd = s;
/* Init client context */
mbedtls_context *pContext = (mbedtls_context *)mbedtls_init_context(0);
if (!pContext || !ServerAddress)
return -1;
handle->m_context = pContext;
handle->m_httpc_net_fd.fd = -1;
memset(&(handle->m_client_param), 0, sizeof(security_client));
// HC_DBG(("https: config defaults certs.."));
handle->m_client_param.pCa = (char *)HTTPC_CUSTOM_CAS_PEM;
handle->m_client_param.nCa = HTTPC_CUSTOM_CAS_PEM_LEN;
int verify_mode = MBEDTLS_SSL_VERIFY_NONE;
if ((ret = mbedtls_config_context(pContext, (void *)&(handle->m_client_param), verify_mode)) != 0) {
// HC_ERR(("https: config failed.."));
mbedtls_deinit_context(handle->m_context);
handle->m_context = NULL;
return -1;
}
if ((ret = mbedtls_connect(pContext, (mbedtls_sock *)&net_fd, ServerAddress, namelen, hostname)) != 0) {
// HC_ERR(("https: connect failed.."));
mbedtls_deinit_context(handle->m_context);
handle->m_context = NULL;
return -1;
}
// HC_DBG(("Https:connect ok.."));
return ret;
}
void ze_transport_ssl_set_recvtimeout(ze_transport_ssl_t *handle, int timeout_ms)
{
if (handle->m_context && timeout_ms > 0) {
mbedtls_set_recv_timeout(handle->m_context, timeout_ms);
}
}
int ze_transport_ssl_negotiate(ze_transport_ssl_t *handle, int s, char *hostname)
{
int ret = 0;
handle->m_httpc_net_fd.fd = s;
// HC_DBG(("Https:negotiate.."));
if ((ret = mbedtls_handshake(handle->m_context, &(handle->m_httpc_net_fd))) != 0)
return -1;
// HC_DBG(("Https:negotiate ok.."));
return 0;
}
int ze_transport_ssl_send(ze_transport_ssl_t *handle, int s, char *buf, int len, int flags)
{
int ret = 0;
// HC_DBG(("Https:send %d..", len));
if ((ret = mbedtls_send(handle->m_context, buf, len)) < 0)
return -1;
return ret;
}
int ze_transport_ssl_recv(ze_transport_ssl_t *handle, int s, char *buf, int len, int flags)
{
return mbedtls_recv(handle->m_context, buf, len);
}
int ze_transport_ssl_recv_pending(ze_transport_ssl_t *handle, int s)
{
int ret = 0;
ret = mbedtls_recv_pending(handle->m_context);
// HC_DBG(("Https:recv pending : %d (bytes)..", ret));
return ret;
}
int ze_transport_ssl_close(ze_transport_ssl_t *handle, int s)
{
// HC_DBG(("Https:close.."));
mbedtls_deinit_context(handle->m_context);
s = -1;
handle->m_httpc_net_fd.fd = -1;
return 0;
}