在阿里云的sdk 里面提取 在ubuntu 中编译通过
因为阿里云的物联网sdk使用 freertos,而且嵌套了很多信息,导致我觉得不够明了
将 mbedtls 部分单独提取出来,做个记录,以后移植到别的系统也方便
1.封装内存申请释放函数,给mbedtls的函数 mbedtls_platform_set_calloc_free(mbed_malloc,mbed_free) 进行调用
static void *mbed_malloc(size_t n,size_t size)
{
return malloc(n*size);
}
static void mbed_free(void *ptr)
{
free(ptr);
}
2.封装随机函数
int mbed_rand(void *handle,uint8_t *output, size_t output_len)
{
uint32_t idx = 0, bytes = 0, rand_num = 0;
time_t timestart_ms;
time(×tart_ms);
srand((unsigned int)(timestart_ms) + rand());
for (idx = 0; idx < output_len;) {
if (output_len - idx < 4) {
bytes = output_len - idx;
} else {
bytes = 4;
}
rand_num = rand();
while (bytes-- > 0) {
output[idx++] = (uint8_t)(rand_num >> bytes * 8);
}
}
return 0;
}
3.封装tls里面的tcp读写函数
int mbedtls_send(void *ctx,const unsigned char *buf,size_t len )
{
int fd=((core_network_handle_t*)ctx)->fd;
return send(fd,buf,len,0);
}
int mbedtls_recv( void *ctx,unsigned char *buf,size_t len )
{
//mbedtls_recv_timeout()
int fd=((core_network_handle_t*)ctx)->fd;
return recv(fd,buf,len,0);
};
4.定义mbedtls和 network 的结构体
typedef struct {
mbedtls_ssl_context ssl_ctx;
mbedtls_ssl_config ssl_config;
mbedtls_x509_crt x509_server_cert;
}MBEDTLS_TLS_HANDLE;
typedef struct {
int fd;
} core_network_handle_t;
5.在程序里面初始化代码
int res = 0,len;
MBEDTLS_TLS_HANDLE mbedtls;
core_network_handle_t network_handle;
memset(&network_handle,0,sizeof(network_handle));
//清零ssl_ctx
mbedtls_ssl_init(&mbedtls.ssl_ctx);
//清零ssl_config
mbedtls_ssl_config_init(&mbedtls.ssl_config);
mbedtls_platform_set_calloc_free(mbed_malloc,mbed_free);
mbedtls_ssl_conf_max_frag_len(&mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_NONE);
//初始化 ssl_config
res = mbedtls_ssl_config_defaults(&mbedtls.ssl_config, MBEDTLS_SSL_IS_CLIENT,MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
printf("res=%d\n",res);
mbedtls_ssl_conf_max_version(&mbedtls.ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3,MBEDTLS_SSL_MINOR_VERSION_3);
mbedtls_ssl_conf_min_version(&mbedtls.ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3,MBEDTLS_SSL_MINOR_VERSION_3);
//设置握手超时时间
mbedtls_ssl_conf_handshake_timeout(&mbedtls.ssl_config, (MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2),(MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2 * 4));
//设置随机参数
mbedtls_ssl_conf_rng(&mbedtls.ssl_config, mbed_rand, NULL);
//应该是设置 调试 监控的 暂时不用
//mbedtls_ssl_conf_dbg(&adapter_handle->mbedtls.ssl_config, _core_mbedtls_debug, stdout);
//清零 x509_server_cert
mbedtls_x509_crt_init(&mbedtls.x509_server_cert);
//计算密钥
res = mbedtls_x509_crt_parse(&mbedtls.x509_server_cert,(const uint8_t *)ali_ca_cert, (size_t)(strlen(ali_ca_cert)+1));
printf("x509=%d\n",res);
//将密钥记录到 ssl 里面
mbedtls_ssl_conf_ca_chain(&mbedtls.ssl_config, &mbedtls.x509_server_cert, NULL);
mbedtls_ssl_conf_ca_chain(&mbedtls.ssl_config, &mbedtls.x509_server_cert, NULL);
res = mbedtls_ssl_setup(&mbedtls.ssl_ctx, &mbedtls.ssl_config);
printf("mbedtls_ssl_setup=%d\n",res);
//获得tcp的fd,就是普通的tcp连接代码,封装起来,阻塞模式(还没有做非阻塞模式的测试)
network_handle.fd=GetSocketfd(IP_ADDR,PORT);
//设置tcp socket ,send,rec,rec_timeout
mbedtls_ssl_set_bio(&mbedtls.ssl_ctx, &network_handle, mbedtls_send,mbedtls_recv, NULL);
mbedtls_ssl_conf_read_timeout(&mbedtls.ssl_config, 5000);
//开始握手,在mbedtls_ssl_handshake函数里面输出握手状态
res = mbedtls_ssl_handshake(&mbedtls.ssl_ctx);
printf("handshake:%d\n",res);
6.在mbedtls_ssl_handshake 代码里面 插入打印状态的代码 printf("ssl_state:%d\n",ssl->state);,可以看到输出,应该是 握手状态的变化,最后打印 handshake:0 代表握手成功
ssl_state:0
ssl_state:1
ssl_state:2
ssl_state:3
ssl_state:4
ssl_state:5
ssl_state:6
ssl_state:7
ssl_state:8
ssl_state:9
ssl_state:10
ssl_state:11
ssl_state:17
ssl_state:12
ssl_state:13
ssl_state:14
ssl_state:15
handshake:0