在阿里云的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(&timestart_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

更多推荐