884 lines
26 KiB
C
884 lines
26 KiB
C
#include "sock_api.h"
|
|
#include "net_sock.h"
|
|
|
|
#if 1
|
|
#define log_info(x, ...) printf("\n\n>>>>>>[uchttp_debug]" x " ", ## __VA_ARGS__)
|
|
#else
|
|
#define log_info(...)
|
|
#endif
|
|
|
|
struct http_table {
|
|
int id;
|
|
u8 mode; //0 = http, 1 = https
|
|
u8 is_used; //0 = 未使用, 1 =已使用
|
|
};
|
|
|
|
/*ssl_tsl*/
|
|
struct secure_param {
|
|
char *CaPtr;
|
|
char *CliPtr;
|
|
char *KeyPtr;
|
|
int TimeOut;
|
|
};
|
|
|
|
typedef enum net_tcp_state {
|
|
NET_TCP_CONN_STATE_NONE = 1u,
|
|
NET_TCP_CONN_STATE_FREE = 2u,
|
|
|
|
NET_TCP_CONN_STATE_CLOSED = 10u,
|
|
|
|
NET_TCP_CONN_STATE_LISTEN = 20u,
|
|
|
|
NET_TCP_CONN_STATE_SYNC_RXD = 30u,
|
|
NET_TCP_CONN_STATE_SYNC_RXD_PASSIVE = 31u,
|
|
NET_TCP_CONN_STATE_SYNC_RXD_ACTIVE = 32u,
|
|
|
|
NET_TCP_CONN_STATE_SYNC_TXD = 35u,
|
|
|
|
NET_TCP_CONN_STATE_CONN = 40u,
|
|
|
|
NET_TCP_CONN_STATE_FIN_WAIT_1 = 50u,
|
|
NET_TCP_CONN_STATE_FIN_WAIT_2 = 51u,
|
|
NET_TCP_CONN_STATE_CLOSING = 52u,
|
|
NET_TCP_CONN_STATE_TIME_WAIT = 53u,
|
|
|
|
NET_TCP_CONN_STATE_CLOSE_WAIT = 55u,
|
|
NET_TCP_CONN_STATE_LAST_ACK = 56u,
|
|
|
|
NET_TCP_CONN_STATE_CLOSING_DATA_AVAIL = 59u
|
|
} NET_TCP_CONN_STATE;
|
|
|
|
typedef struct net_app_sock_secure_mutual_cfg {
|
|
NET_SOCK_SECURE_CERT_KEY_FMT Fmt;
|
|
CPU_CHAR *CertPtr;
|
|
CPU_INT32U CertSize;
|
|
CPU_BOOLEAN CertChained;
|
|
CPU_CHAR *KeyPtr;
|
|
CPU_INT32U KeySize;
|
|
/*增加参数设置*/
|
|
CPU_CHAR *CliPtr;
|
|
CPU_INT32U CliSize;
|
|
} NET_APP_SOCK_SECURE_MUTUAL_CFG;
|
|
|
|
typedef struct net_app_sock_secure_cfg {
|
|
CPU_CHAR *CommonName;
|
|
NET_SOCK_SECURE_TRUST_FNCT TrustCallback;
|
|
NET_APP_SOCK_SECURE_MUTUAL_CFG *MutualAuthPtr;
|
|
void *UserDataPtr; //增加
|
|
} NET_APP_SOCK_SECURE_CFG;
|
|
|
|
typedef unsigned int NET_TCP_CONN_ID;
|
|
typedef CPU_INT16U NET_TCP_TIMEOUT_SEC;
|
|
|
|
#define HTTP_TABLES_SIZE 128
|
|
static struct http_table http_tables[HTTP_TABLES_SIZE] = {0};
|
|
|
|
/********************************https安全传输*******************************************/
|
|
#include "http_cli.h"
|
|
#include <stdlib.h>
|
|
#include "generic/ascii.h"
|
|
#include "fs/fs.h"
|
|
|
|
#include "mbedtls/mbedtls_config.h"
|
|
#include "mbedtls/net.h"
|
|
#include "mbedtls/ssl.h"
|
|
#include "mbedtls/entropy.h"
|
|
#include "mbedtls/ctr_drbg.h"
|
|
#include "mbedtls/error.h"
|
|
#include "mbedtls/certs.h"
|
|
|
|
struct mbedtls_ctx {
|
|
mbedtls_x509_crt cacert;
|
|
mbedtls_x509_crt clicert;
|
|
mbedtls_pk_context pkey;
|
|
mbedtls_ssl_context ssl;
|
|
mbedtls_net_context server_fd;
|
|
mbedtls_entropy_context entropy;
|
|
mbedtls_ctr_drbg_context ctr_drbg;
|
|
mbedtls_ssl_config conf;
|
|
const char *pers;
|
|
mbedtls_ssl_session saved_session;
|
|
};
|
|
|
|
#ifdef HTTPIN_DEBUG_EN
|
|
#define httpin_debug printf
|
|
#define httpin_debug_pbuf put_buf
|
|
#else
|
|
#define httpin_debug printf
|
|
#define httpin_debug_pbuf put_buf
|
|
#endif
|
|
|
|
#define HTTPIN_DEBUG_ERROR_EN
|
|
#ifdef HTTPIN_DEBUG_ERROR_EN
|
|
#define httpin_err_debug printf
|
|
#define httpin_err_debug_pbuf put_buf
|
|
#else
|
|
#define httpin_err_debug printf
|
|
#define httpin_err_debug_pbuf put_buf
|
|
#endif
|
|
/********************************https安全传输*******************************************/
|
|
|
|
static void table_add(const int id, const u8 mode)
|
|
{
|
|
int i;
|
|
for (i = 0; i < HTTP_TABLES_SIZE; i++) {
|
|
if (http_tables[i].is_used == 0) {
|
|
break;
|
|
}
|
|
}
|
|
http_tables[i].id = id;
|
|
http_tables[i].mode = mode;
|
|
http_tables[i].is_used = 1;
|
|
}
|
|
|
|
static void table_delete(const int id)
|
|
{
|
|
int i;
|
|
for (i = 0; i < HTTP_TABLES_SIZE; i++) {
|
|
if (http_tables[i].id == id) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
http_tables[i].is_used = 0;
|
|
}
|
|
|
|
const static struct http_table *table_find(const int id)
|
|
{
|
|
int i;
|
|
for (i = 0; i < HTTP_TABLES_SIZE; i++) {
|
|
if (http_tables[i].id == id) {
|
|
return &http_tables[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* extern int httpin_sock_cb(enum sock_api_msg_type type, void *priv); */
|
|
|
|
static void my_debug(void *ctx, int level,
|
|
const char *file, int line,
|
|
const char *str)
|
|
{
|
|
mbedtls_printf("%s", str);
|
|
}
|
|
|
|
static void *ssl_connect(char *hostname, char *port, int to_ms, void *ctx, char *server_name);
|
|
static int ssl_write(void *hdl, const void *buf, u32_t len, int flag);
|
|
static int ssl_read(void *hdl, void *buf, u32_t len, int flag);
|
|
static void ssl_close_notify(void *hdl);
|
|
|
|
NET_SOCK_RTN_CODE NetSock_TxDataTo(NET_SOCK_ID sock_id,
|
|
void *p_data,
|
|
CPU_INT16U data_len,
|
|
NET_SOCK_API_FLAGS flags,
|
|
NET_SOCK_ADDR *p_addr_remote,
|
|
NET_SOCK_ADDR_LEN addr_len,
|
|
NET_ERR *p_err)
|
|
{
|
|
ssize_t rtn_code;
|
|
const struct http_table *tablePtr = NULL;
|
|
|
|
tablePtr = table_find(sock_id);
|
|
if (tablePtr == NULL && !(tablePtr->is_used)) {
|
|
log_info("%s %d-> table_find\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (tablePtr->mode) {
|
|
rtn_code = ssl_write((void *)sock_id, p_data, data_len, 0);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
} else {
|
|
rtn_code = (ssize_t)sock_sendto((void *)sock_id, p_data, data_len, 0, (struct sockaddr *)p_addr_remote, addr_len);
|
|
if (rtn_code <= 0) {
|
|
log_info("%s %d-> sock_sendto: %d\n", __FUNCTION__, __LINE__, (int)rtn_code);
|
|
*p_err = NET_SOCK_ERR_INVALID_TYPE;
|
|
}
|
|
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
}
|
|
|
|
return (rtn_code);
|
|
}
|
|
|
|
NET_SOCK_RTN_CODE NetSock_RxDataFrom(NET_SOCK_ID sock_id,
|
|
void *p_data_buf,
|
|
CPU_INT16U data_buf_len,
|
|
NET_SOCK_API_FLAGS flags,
|
|
NET_SOCK_ADDR *p_addr_remote,
|
|
NET_SOCK_ADDR_LEN *p_addr_len,
|
|
void *p_ip_opts_buf,
|
|
CPU_INT08U ip_opts_buf_len,
|
|
CPU_INT08U *p_ip_opts_len,
|
|
NET_ERR *p_err)
|
|
{
|
|
ssize_t rtn_code;
|
|
const struct http_table *tablePtr = NULL;
|
|
|
|
tablePtr = table_find(sock_id);
|
|
if (tablePtr == NULL && !(tablePtr->is_used)) {
|
|
log_info("%s %d-> table_find\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (tablePtr->mode) {
|
|
rtn_code = ssl_read((void *)sock_id, (void *)p_data_buf, (size_t)data_buf_len, 0);
|
|
if (rtn_code < 0) {
|
|
rtn_code = 0;
|
|
}
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
} else {
|
|
struct sockaddr_in dest_addr;
|
|
socklen_t dest_len = sizeof(dest_addr);
|
|
|
|
rtn_code = sock_recvfrom((void *)sock_id, (void *)p_data_buf, (size_t)data_buf_len, 0, (struct sockaddr *)&dest_addr, &dest_len);
|
|
if (rtn_code == -1) {
|
|
log_info("%s %d-> sock_recvfrom: %d\n", __FUNCTION__, __LINE__, (int)rtn_code);
|
|
}
|
|
/* log_info("NetSock_RxDataFrom data: \n%s\n", p_data_buf); */
|
|
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
}
|
|
|
|
return (rtn_code);
|
|
}
|
|
|
|
/*todo*/
|
|
NET_SOCK_RTN_CODE NetSock_OptGet(NET_SOCK_ID sock_id,
|
|
NET_SOCK_PROTOCOL level,
|
|
NET_SOCK_OPT_NAME opt_name,
|
|
void *p_opt_val,
|
|
NET_SOCK_OPT_LEN *p_opt_len,
|
|
NET_ERR *p_err)
|
|
{
|
|
const struct http_table *tablePtr = NULL;
|
|
|
|
tablePtr = table_find(sock_id);
|
|
if (tablePtr == NULL && !(tablePtr->is_used)) {
|
|
log_info("%s %d-> table_find\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (tablePtr->mode) {
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return (0);
|
|
} else {
|
|
int rtn_code;
|
|
rtn_code = sock_getsockopt((void *)sock_id, (int)level, (int)opt_name, (void *)p_opt_val, (socklen_t *)p_opt_len);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return (rtn_code);
|
|
}
|
|
}
|
|
|
|
/*todo*/
|
|
NET_SOCK_RTN_CODE NetSock_OptSet(NET_SOCK_ID sock_id,
|
|
NET_SOCK_PROTOCOL level,
|
|
NET_SOCK_OPT_NAME opt_name,
|
|
const void *p_opt_val,
|
|
NET_SOCK_OPT_LEN opt_len,
|
|
NET_ERR *p_err)
|
|
{
|
|
const struct http_table *tablePtr = NULL;
|
|
tablePtr = table_find(sock_id);
|
|
if (tablePtr == NULL && !(tablePtr->is_used)) {
|
|
log_info("%s %d-> table_find\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (tablePtr->mode) {
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return 0;
|
|
} else {
|
|
int opt_name_ch;
|
|
int opt = 1;
|
|
int rtn_code;
|
|
|
|
switch (opt_name) {
|
|
case NET_SOCK_OPT_TCP_NO_DELAY :
|
|
opt_name_ch = 0x01;
|
|
break;
|
|
|
|
case NET_SOCK_OPT_SOCK_KEEP_ALIVE :
|
|
opt_name_ch = 0x02;
|
|
break;
|
|
|
|
case NET_SOCK_OPT_TCP_KEEP_IDLE :
|
|
opt_name_ch = 0x03;
|
|
break;
|
|
|
|
case NET_SOCK_OPT_TCP_KEEP_INTVL :
|
|
opt_name_ch = 0x04;
|
|
break;
|
|
|
|
case NET_SOCK_OPT_TCP_KEEP_CNT :
|
|
opt_name_ch = 0x05;
|
|
break;
|
|
|
|
default:
|
|
log_info("not defined");
|
|
return 1;
|
|
break;
|
|
}
|
|
|
|
rtn_code = sock_setsockopt((void *)sock_id, (int)level, opt_name_ch, &opt, sizeof(opt));
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return (rtn_code);
|
|
}
|
|
|
|
}
|
|
|
|
NET_SOCK_RTN_CODE NetSock_Close(NET_SOCK_ID sock_id,
|
|
NET_ERR *p_err)
|
|
{
|
|
const struct http_table *tablePtr = NULL;
|
|
tablePtr = table_find(sock_id);
|
|
if (tablePtr == NULL && !(tablePtr->is_used)) {
|
|
log_info("%s %d-> table_find\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (tablePtr->mode) {
|
|
ssl_close_notify((void *)sock_id);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
} else {
|
|
int rtn_code;
|
|
sock_unreg((void *)sock_id);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
}
|
|
|
|
table_delete((unsigned int)sock_id);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*todo*/
|
|
NET_CONN_ID NetSock_GetConnTransportID(NET_SOCK_ID sock_id,
|
|
NET_ERR *p_err)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
printf("NetSock_GetConnTransportID : %d", sock_id);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return sock_id;
|
|
}
|
|
|
|
/* NET_SOCK_RTN_CODE NetSock_Sel (NET_SOCK_QTY sock_nbr_max, */
|
|
/* NET_SOCK_DESC *p_sock_desc_rd, */
|
|
/* NET_SOCK_DESC *p_sock_desc_wr, */
|
|
/* NET_SOCK_DESC *p_sock_desc_err, */
|
|
/* NET_SOCK_TIMEOUT *p_timeout, */
|
|
/* NET_ERR *p_err) */
|
|
/* { */
|
|
/* log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__); */
|
|
/* int rtn_code; */
|
|
/* rtn_code = (int)sock_select(sock_cli, (struct fd_set*)p_sock_desc_rd, (struct fd_set*)p_sock_desc_wr, NULL, NULL); */
|
|
/* printf("rtn_code : %d", rtn_code); */
|
|
/* *p_err = NET_SOCK_ERR_NONE; */
|
|
/* return (rtn_code); */
|
|
/* } */
|
|
|
|
/*todo*/
|
|
CPU_BOOLEAN NetSock_CfgBlock(NET_SOCK_ID sock_id,
|
|
CPU_INT08U block,
|
|
NET_ERR *p_err)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
*p_err = NET_SOCK_ERR_NONE;
|
|
return 0;
|
|
}
|
|
|
|
/*todo*/
|
|
CPU_BOOLEAN NetTCP_ConnCfgMSL_Timeout(NET_TCP_CONN_ID conn_id_tcp,
|
|
NET_TCP_TIMEOUT_SEC msl_timeout_sec,
|
|
NET_ERR *p_err)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
/* log_info("NetTCP_ConnCfgMSL_Timeout : %d", conn_id_tcp); */
|
|
*p_err = NET_TCP_ERR_NONE;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
NET_IP_ADDR_FAMILY NetApp_ClientStreamOpenByHostname(unsigned int *p_sock_id,
|
|
CPU_CHAR *p_remote_host_name,
|
|
NET_PORT_NBR remote_port_nbr,
|
|
NET_SOCK_ADDR *p_sock_addr,
|
|
NET_APP_SOCK_SECURE_CFG *p_secure_cfg,
|
|
CPU_INT32U req_timeout_ms,
|
|
NET_ERR *p_err)
|
|
{
|
|
struct hostent *hent = NULL;
|
|
struct secure_param param = {0};
|
|
|
|
#ifdef HTTP_CLI_C_EN
|
|
httpcli_ctx *ctx = p_secure_cfg->UserDataPtr;
|
|
#endif
|
|
|
|
NET_APP_SOCK_SECURE_MUTUAL_CFG *MuturalParam = p_secure_cfg->MutualAuthPtr;
|
|
static int use_ssl_tsl = 0;
|
|
|
|
if (MuturalParam && MuturalParam->CertChained == DEF_YES && !use_ssl_tsl) {
|
|
/*设置证书,key路径*/
|
|
param.CaPtr = MuturalParam->CertPtr;
|
|
param.CliPtr = MuturalParam->CliPtr;
|
|
param.KeyPtr = MuturalParam->KeyPtr;
|
|
if (req_timeout_ms == 0) {
|
|
param.TimeOut = 60;
|
|
} else {
|
|
param.TimeOut = req_timeout_ms;
|
|
}
|
|
use_ssl_tsl = 1;
|
|
}
|
|
|
|
|
|
#ifdef HTTP_CLI_C_EN
|
|
if (ctx && ctx->mode == MODE_HTTPS && !use_ssl_tsl) {
|
|
/*设置证书,key路径*/
|
|
param.CaPtr = ctx->cas_pem_path;
|
|
param.CliPtr = ctx->cas_pem_path;
|
|
param.KeyPtr = ctx->cas_pem_path;
|
|
|
|
if (ctx->timeout_millsec == 0) {
|
|
param.TimeOut = 60;
|
|
} else {
|
|
param.TimeOut = ctx->timeout_millsec;
|
|
}
|
|
|
|
use_ssl_tsl = 1;
|
|
}
|
|
#endif
|
|
|
|
if (use_ssl_tsl) {
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
use_ssl_tsl = 0;
|
|
char tmp_buf[128];
|
|
struct sockaddr_in dest;
|
|
struct mbedtls_ctx *tls_ctx = NULL;
|
|
char host[16] = {0};
|
|
char pA[16];
|
|
|
|
NET_IP_ADDR_FAMILY addr_rtn = NET_IP_ADDR_FAMILY_UNKNOWN;
|
|
|
|
hent = gethostbyname(p_remote_host_name);
|
|
if (NULL == hent) {
|
|
log_info("gethostbyname fail! \n");
|
|
*p_err = NET_APP_ERR_FAULT;
|
|
return addr_rtn;
|
|
}
|
|
|
|
memset(&dest, 0, sizeof(dest));
|
|
dest.sin_family = AF_INET;
|
|
|
|
if (remote_port_nbr == 80) {
|
|
dest.sin_port = htons(443);
|
|
sprintf(pA, "%d", 443);
|
|
} else {
|
|
dest.sin_port = htons(remote_port_nbr);
|
|
sprintf(pA, "%d", remote_port_nbr);
|
|
}
|
|
|
|
memcpy(&dest.sin_addr, hent->h_addr, sizeof(struct in_addr));
|
|
|
|
tls_ctx = ssl_connect(inet_ntoa_r(dest.sin_addr.s_addr, host, sizeof(host)), pA, param.TimeOut, ¶m, p_remote_host_name);
|
|
|
|
if (tls_ctx == NULL) {
|
|
*p_err = NET_ERR_FAULT_NULL_PTR;
|
|
} else {
|
|
*p_sock_id = (unsigned int)tls_ctx;
|
|
*p_err = NET_APP_ERR_NONE;
|
|
addr_rtn = NET_IP_ADDR_FAMILY_IPv4;
|
|
table_add((unsigned int)tls_ctx, 1);
|
|
}
|
|
return addr_rtn ;
|
|
}
|
|
|
|
/******************************************http 连接************************************************/
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
void *sock_cli = NULL;
|
|
struct sockaddr_in remote_dest;
|
|
struct sockaddr_in local;
|
|
|
|
log_info("remote_host_name : %s\n", p_remote_host_name);
|
|
log_info("remote_port_nbr : %d", remote_port_nbr);
|
|
hent = gethostbyname((char *)p_remote_host_name);
|
|
|
|
memset(&remote_dest, 0, sizeof(remote_dest));
|
|
|
|
/*目的sockaddr*/
|
|
remote_dest.sin_family = AF_INET;
|
|
remote_dest.sin_port = htons(remote_port_nbr);
|
|
memcpy(&remote_dest.sin_addr, hent->h_addr, sizeof(struct in_addr));
|
|
|
|
log_info("remote_dest ip %s", inet_ntoa(remote_dest.sin_addr.s_addr));
|
|
|
|
sock_cli = sock_reg(AF_INET, SOCK_STREAM, 0, NULL, NULL);
|
|
if (sock_cli == NULL) {
|
|
log_info("sock_reg err!!!");
|
|
*p_err = NET_APP_ERR_FAULT;
|
|
goto EXIT;
|
|
return -1;
|
|
}
|
|
|
|
if (0 != sock_set_reuseaddr(sock_cli)) {
|
|
log_info("sock_set_reuseaddr err!!!");
|
|
*p_err = NET_APP_ERR_FAULT;
|
|
goto EXIT;
|
|
return -1;
|
|
}
|
|
|
|
/*本地sockaddr*/
|
|
local.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
local.sin_port = htons(0);
|
|
local.sin_family = AF_INET;
|
|
|
|
if (0 != sock_bind(sock_cli, (struct sockaddr *)&local, sizeof(struct sockaddr_in))) {
|
|
log_info("%s sock_bind fail\n", __FILE__);
|
|
*p_err = NET_APP_ERR_FAULT;
|
|
goto EXIT;
|
|
}
|
|
|
|
if (0 != sock_connect(sock_cli, (struct sockaddr *)&remote_dest, sizeof(struct sockaddr_in))) {
|
|
log_info("sock_connect fail.\n");
|
|
*p_err = NET_APP_ERR_FAULT;
|
|
goto EXIT;
|
|
}
|
|
|
|
*p_sock_id = (unsigned int)sock_cli;
|
|
table_add((unsigned int)sock_cli, 0);
|
|
|
|
*p_err = NET_APP_ERR_NONE;
|
|
|
|
return 0;
|
|
|
|
EXIT:
|
|
sock_unreg(sock_cli);
|
|
return -1;
|
|
}
|
|
|
|
/*todo*/
|
|
NET_TCP_CONN_STATE NetTCP_ConnStateGet(NET_TCP_CONN_ID conn_id)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
NET_TCP_CONN_STATE state;
|
|
|
|
state = NET_TCP_CONN_STATE_FREE;
|
|
return (state);
|
|
}
|
|
|
|
/*todo*/
|
|
/* NET_SOCK_ID NetSock_Open (NET_SOCK_PROTOCOL_FAMILY protocol_family, */
|
|
/* NET_SOCK_TYPE sock_type, */
|
|
/* NET_SOCK_PROTOCOL protocol, */
|
|
/* NET_ERR *p_err) */
|
|
/* { */
|
|
/* log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__); */
|
|
/* return 0; */
|
|
/* } */
|
|
|
|
static void *ssl_connect(char *hostname, char *port, int to_ms, void *ctx, char *server_name)
|
|
{
|
|
int ret;
|
|
uint32_t flags;
|
|
unsigned char *buf = NULL;
|
|
struct secure_param *param = (struct secure_param *)ctx;
|
|
|
|
if (!hostname) {
|
|
return NULL;
|
|
}
|
|
|
|
struct mbedtls_ctx *tls_ctx = calloc(1, sizeof(struct mbedtls_ctx));
|
|
if (tls_ctx == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
tls_ctx->pers = "https";
|
|
|
|
/*
|
|
* 0. Initialize the RNG and the session data
|
|
*/
|
|
mbedtls_net_init(&tls_ctx->server_fd);
|
|
/* mbedtls_net_set_cb(&tls_ctx->server_fd, httpin_sock_cb, ctx); */
|
|
mbedtls_net_set_timeout(&tls_ctx->server_fd, to_ms, to_ms);
|
|
|
|
mbedtls_ssl_init(&tls_ctx->ssl);
|
|
mbedtls_ssl_config_init(&tls_ctx->conf);
|
|
|
|
mbedtls_x509_crt_init(&tls_ctx->cacert);
|
|
mbedtls_x509_crt_init(&tls_ctx->clicert);
|
|
mbedtls_pk_init(&(tls_ctx->pkey));
|
|
|
|
mbedtls_ctr_drbg_init(&tls_ctx->ctr_drbg);
|
|
mbedtls_entropy_init(&tls_ctx->entropy);
|
|
|
|
#ifdef MBEDTLS_SSL_EXPORT_KEYS
|
|
/* mbedtls_ssl_conf_export_keys_cb(&tls_ctx->conf, mbedtls_ssl_export_keys, (void *)(&tls_ctx->conf)); */
|
|
#endif
|
|
|
|
if ((ret = mbedtls_ctr_drbg_seed(&tls_ctx->ctr_drbg, mbedtls_entropy_func, &tls_ctx->entropy,
|
|
(const unsigned char *) tls_ctx->pers,
|
|
strlen(tls_ctx->pers))) != 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
buf = malloc(4 * 1024);
|
|
if (!buf) {
|
|
goto exit;
|
|
}
|
|
|
|
void *cacert_fd = fopen(param->CaPtr, "r");
|
|
if (cacert_fd) {
|
|
log_d("LOAD CA\n");
|
|
|
|
int cacert_len = fread(buf, 1, 4 * 1024, cacert_fd);
|
|
|
|
printf("cacert_len=>%d\n", cacert_len);
|
|
|
|
fclose(cacert_fd);
|
|
|
|
buf[cacert_len] = '\0';
|
|
ret = mbedtls_x509_crt_parse(&tls_ctx->cacert, buf, cacert_len + 1);
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
|
|
goto exit;
|
|
}
|
|
} else {
|
|
ret = mbedtls_x509_crt_parse(&tls_ctx->cacert, (unsigned char *)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len);
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
/* void *clicert_fd = fopen(ctx->cli_pem_path, "r"); */
|
|
void *clicert_fd = fopen(param->CliPtr, "r");
|
|
if (clicert_fd) {
|
|
log_d("LOAD PEM\n");
|
|
|
|
int clicert_len = fread(buf, 1, 4 * 1024, clicert_fd);
|
|
|
|
printf("clicert_len=>%d\n", clicert_len);
|
|
|
|
fclose(clicert_fd);
|
|
|
|
buf[clicert_len] = '\0';
|
|
|
|
ret = mbedtls_x509_crt_parse(&tls_ctx->clicert, buf, clicert_len + 1);
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
|
|
goto exit;
|
|
}
|
|
} else {
|
|
/* log_w("open cli pem fail\n"); */
|
|
}
|
|
|
|
/* void *pkey_fd = fopen(ctx->pkey_path, "r"); */
|
|
void *pkey_fd = fopen(param->KeyPtr, "r");
|
|
if (pkey_fd) {
|
|
log_d("LOAD KEY\n");
|
|
|
|
int pkey_len = fread(buf, 1, 4 * 1024, pkey_fd);
|
|
|
|
printf("pkey_len=>%d\n", pkey_len);
|
|
|
|
fclose(pkey_fd);
|
|
|
|
buf[pkey_len] = '\0';
|
|
|
|
ret = mbedtls_pk_parse_key(&tls_ctx->pkey, buf, pkey_len + 1, NULL, 0);
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
|
|
goto exit;
|
|
}
|
|
} else {
|
|
/* log_w("open pkey fail\n"); */
|
|
}
|
|
|
|
free(buf);
|
|
buf = NULL;
|
|
|
|
/*
|
|
* 1. Start the connection
|
|
*/
|
|
mbedtls_printf(" . Connecting to tcp/%s/%s...\r\n", hostname, port);
|
|
|
|
if ((ret = mbedtls_net_connect(&tls_ctx->server_fd, hostname,
|
|
port, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_net_connect returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
/*
|
|
* 2. Setup stuff
|
|
*/
|
|
/* mbedtls_printf(" . Setting up the SSL/TLS structure...\r\n"); */
|
|
if ((ret = mbedtls_ssl_config_defaults(&tls_ctx->conf,
|
|
MBEDTLS_SSL_IS_CLIENT,
|
|
MBEDTLS_SSL_TRANSPORT_STREAM,
|
|
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
/* OPTIONAL is not optimal for security,
|
|
* but makes interop easier in this simplified example */
|
|
mbedtls_ssl_conf_authmode(&tls_ctx->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
|
mbedtls_ssl_conf_ca_chain(&tls_ctx->conf, &tls_ctx->cacert, NULL);
|
|
mbedtls_ssl_conf_rng(&tls_ctx->conf, mbedtls_ctr_drbg_random, &tls_ctx->ctr_drbg);
|
|
mbedtls_ssl_conf_dbg(&tls_ctx->conf, my_debug, 0);
|
|
|
|
|
|
if (pkey_fd && clicert_fd) {
|
|
ret = mbedtls_ssl_conf_own_cert(&(tls_ctx->conf), &(tls_ctx->clicert), &(tls_ctx->pkey));
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
const char *alpnProtocols[] = { "x-amzn-http-ca", NULL };
|
|
ret = mbedtls_ssl_conf_alpn_protocols(&(tls_ctx->conf), alpnProtocols);
|
|
if (ret < 0) {
|
|
mbedtls_printf(" failed\n ! returne_ssl_conf_alpn_protocols returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
if ((ret = mbedtls_ssl_setup(&tls_ctx->ssl, &tls_ctx->conf)) != 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
if ((ret = mbedtls_ssl_set_hostname(&tls_ctx->ssl, server_name)) != 0) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_ssl_set_bio(&tls_ctx->ssl, &tls_ctx->server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
|
|
|
/*
|
|
* 4. Handshake
|
|
*/
|
|
/* mbedtls_printf(" . Performing the SSL/TLS handshake...\r\n"); */
|
|
|
|
while ((ret = mbedtls_ssl_handshake(&tls_ctx->ssl)) != 0) {
|
|
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
|
mbedtls_printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 5. Verify the server certificate
|
|
*/
|
|
/* mbedtls_printf(" . Verifying peer X.509 certificate...\r\n"); */
|
|
|
|
/* In real life, we probably want to bail out when ret != 0 */
|
|
if ((flags = mbedtls_ssl_get_verify_result(&tls_ctx->ssl)) != 0) {
|
|
char vrfy_buf[512];
|
|
|
|
/* mbedtls_printf(" failed\r\n"); */
|
|
|
|
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
|
|
|
|
/* mbedtls_printf("%s\r\n", vrfy_buf); */
|
|
} else {
|
|
mbedtls_printf(" ok\r\n");
|
|
}
|
|
|
|
return tls_ctx;
|
|
|
|
exit:
|
|
|
|
#ifdef MBEDTLS_ERROR_C
|
|
if (ret != 0) {
|
|
char error_buf[100];
|
|
mbedtls_strerror(ret, error_buf, 100);
|
|
mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf);
|
|
}
|
|
#endif
|
|
|
|
mbedtls_net_free(&tls_ctx->server_fd);
|
|
mbedtls_x509_crt_free(&tls_ctx->cacert);
|
|
mbedtls_ssl_free(&tls_ctx->ssl);
|
|
mbedtls_ssl_config_free(&tls_ctx->conf);
|
|
mbedtls_ctr_drbg_free(&tls_ctx->ctr_drbg);
|
|
mbedtls_entropy_free(&tls_ctx->entropy);
|
|
|
|
free(tls_ctx);
|
|
if (buf) {
|
|
free(buf);
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
static int ssl_write(void *hdl, const void *buf, u32_t len, int flag)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
struct mbedtls_ctx *tls_ctx = (struct mbedtls_ctx *)hdl;
|
|
int ret;
|
|
int remain_len = len;
|
|
int payload = 0;
|
|
int offset = 0;
|
|
|
|
while (remain_len) {
|
|
if (remain_len >= MBEDTLS_SSL_MAX_CONTENT_LEN) {
|
|
payload = MBEDTLS_SSL_MAX_CONTENT_LEN;
|
|
remain_len -= MBEDTLS_SSL_MAX_CONTENT_LEN;
|
|
} else {
|
|
payload = remain_len;
|
|
remain_len = 0;
|
|
}
|
|
|
|
ret = mbedtls_ssl_write(&tls_ctx->ssl, (unsigned char *)buf + offset, payload);
|
|
|
|
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
|
return 0;
|
|
}
|
|
|
|
if (ret < 0) {
|
|
httpin_err_debug("https_ssl_write fail:%d \n", ret);
|
|
return ret;
|
|
}
|
|
offset += payload;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int ssl_read(void *hdl, void *buf, u32_t len, int flag)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
struct mbedtls_ctx *tls_ctx = (struct mbedtls_ctx *)hdl;
|
|
|
|
if (flag != 0) {
|
|
return -1;
|
|
}
|
|
|
|
int ret = mbedtls_ssl_read(&tls_ctx->ssl, (unsigned char *)buf, len);
|
|
printf("mbedtls_ssl_read : %d", ret);
|
|
|
|
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
|
return 0;
|
|
}
|
|
if (ret < 0) {
|
|
httpin_err_debug("https_ssl_read fail:0x%x \n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ssl_close_notify(void *hdl)
|
|
{
|
|
log_info(">>>>>>>>>>>>>>>>>>>>>>>>>%s, %d", __FUNCTION__, __LINE__);
|
|
struct mbedtls_ctx *tls_ctx = (struct mbedtls_ctx *)hdl;
|
|
|
|
mbedtls_ssl_close_notify(&tls_ctx->ssl);
|
|
mbedtls_net_free(&tls_ctx->server_fd);
|
|
mbedtls_x509_crt_free(&tls_ctx->cacert);
|
|
mbedtls_ssl_free(&tls_ctx->ssl);
|
|
mbedtls_ssl_config_free(&tls_ctx->conf);
|
|
mbedtls_ctr_drbg_free(&tls_ctx->ctr_drbg);
|
|
mbedtls_entropy_free(&tls_ctx->entropy);
|
|
free(tls_ctx);
|
|
}
|
|
|