mbedTLS(PolarSSL)简单思路和函数笔记(Client端)
2017-03-08 16:02
281 查看
转自:
OpenSSL一直以来各种被诟病,具体挑了哪些刺,本文就不深究。作为OpenSSL有很多替代,我了解到的有cyaSSL(WolfSSL)和PolorSSL。其中PolarSSL已经被ARM收购了,改名为mbedTLS。本文列举了作为一个SSL client端,应该如何使用mbedTLS。本文可以搭配我上一篇文章OpenSSL一起看;单独看也没问题
本文地址:https://segmentfault.com/a/1190000005998141
mbed TLS tutorial - Knowledge Base
ARMmbed / mbedtls / programs / ssl / ssl_client1.c
传统的socket-based的程序,依照顺序,作为client要做以下的函数调用:
改成SSL之后,mbedTLS对应上述函数,分别对应为:
当然,实际情况下,会使用更多的其他函数。具体(最简单的)流程见下文
下面是init阶段需要调用的各函数。函数的参数,在调用的时候按照上面的函数类型一个一个传入就行了
其中
经实验,mbedTLS是可以顺利适配
什么?问我怎么不适配
OpenSSL 简单思路和函数笔记
以下是伪代码,有点多,从最简单的
一些自定义的数据结构
MbedTLS初始化
MbedTLS的 connect 动作
主函数:
2016年07月18日发布
更多
OpenSSL一直以来各种被诟病,具体挑了哪些刺,本文就不深究。作为OpenSSL有很多替代,我了解到的有cyaSSL(WolfSSL)和PolorSSL。其中PolarSSL已经被ARM收购了,改名为mbedTLS。本文列举了作为一个SSL client端,应该如何使用mbedTLS。本文可以搭配我上一篇文章OpenSSL一起看;单独看也没问题
本文地址:https://segmentfault.com/a/1190000005998141
Reference
mbed TLS tutorial - Knowledge BaseARMmbed / mbedtls / programs / ssl / ssl_client1.c
mbedTLS 基本使用
与传统 socket 的对比
传统的socket-based的程序,依照顺序,作为client要做以下的函数调用:gethostbyname() socket() connect() write() read()
改成SSL之后,mbedTLS对应上述函数,分别对应为:
gethostbyname() \ socket() -+--> mbedtls_net_connect() + mbedtls_ssl_handshake() connect() / write() ----> mbedtls_ssl_write() read() ----> mbedtls_ssl_read()
当然,实际情况下,会使用更多的其他函数。具体(最简单的)流程见下文
数据结构
mbedtls_net_context:目前只有文件描述符,可以用于适配异步I/O库
mbedtls_ssl_context:保存SSL基本数据
mbedtls_ssl_config
mbedtls_ctr_drbg_context
mbedtls_entropy_context:保存熵配置
mbedtls_x509_crt:保存认证信息
Init 阶段
下面是init阶段需要调用的各函数。函数的参数,在调用的时候按照上面的函数类型一个一个传入就行了mbedtls_net_init() mbedtld_ssl_init() mbedtld_ssl_config_init() mbedtls_ctr_drbg_init() mbedtld_x509_crt_init() mbedtls_entropy_init() mebdtls_ctr_drbg_seed()
其中
mebdtls_ctr_drbg_seed()可以指定熵函数。如果回调使用默认的
mbedtls_entropy_func的话,可以传入一个初始的熵seed,也可以NULL
Connect 阶段
mbedtls_net_connect():参数是server和端口,均为字符串。server可以使域名或者IP字符串。最后一个参数使用
MBEDTLS_NET_PROTO_TCP即可。端口号不仅仅可以传入数字字符串,也可以类似于
get_addrinfo函数的
protocol参数那样,传入类似于“HTTPS”这样的可读化字符串。
mbedtls_ssl_config_defaults():
适配异步I/O库
经实验,mbedTLS是可以顺利适配libev的,Good!(libuv没有实际试过,不过应该也是OK的)
什么?问我怎么不适配
libevent? 要用libevent的话就用封装了
OpenSSL的
bufferevent去啦
姊妹篇
OpenSSL 简单思路和函数笔记
作为 client 适配 libev 调用过程
以下是伪代码,有点多,从最简单的main()入手就好:
一些自定义的数据结构
typedef struct _MBEDTLS_SESSION { mbedtls_net_context mbedNetCtx; mbedtls_ssl_context mbedSslCtx; mbedtls_ssl_config mbedSslConf; mbedtls_ctr_drbg_context mbedDrbgCtx; mbedtls_entropy_context mbedEtpyCtx; mbedtls_x509_crt mbedX509Crt; } MbedTLSSession_st; typedef struct SSL_SESSION { struct ev_io *libevWatcher; MbedTLSSession_st mbedIntf; } SSLSession_st;
MbedTLS初始化
MbedTlsClientInit(MbedTLSSession_st *session, void *entropy, size_t entropyLen) { mbedtls_net_init(&(session->mbedNetCtx)); mbedtls_ssl_init(&(session->mbedSslCtx)); mbedtls_ssl_config_init(&(session->mbedSslConf)); mbedtls_ctr_drbg_init(&(session->mbedDrbgCtx)); mbedtls_x509_crt_init(&(session->mbedX509Crt)); mbedtls_entropy_init(&(session->mbedEtpyCtx)); mbedtls_ctr_drbg_seed(&(session->mbedDrbgCtx), mbedtls_entropy_func, &(session->mbedEtpyCtx), (unsigned char *)entropy, entropyLen); }
MbedTLS的 connect 动作
AMCMbedTlsClientConnect(MbedTLSSession_st *session, const char *serverHost, int serverPort) { int callStat; char portStrBuff[16]; snprintf(portStrBuff, sizeof(portStrBuff), "%d", serverPort); callStat = mbedtls_net_connect(&(session->mbedNetCtx), serverHost, portStrBuff, MBEDTLS_NET_PROTO_TCP); _RETURN_IF_ERROR(callStat); callStat = mbedtls_ssl_config_defaults(&(session->mbedSslConf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); _RETURN_IF_ERROR(callStat); mbedtls_ssl_conf_authmode(&(session->mbedSslConf), MBEDTLS_SSL_VERIFY_OPTIONAL); mbedtls_ssl_conf_ca_chain(&(session->mbedSslConf), &(session->mbedX509Crt), NULL); mbedtls_ssl_conf_rng(&(session->mbedSslConf), mbedtls_ctr_drbg_random, &(session->mbedDrbgCtx)); //edtls_ssl_conf_dbg(&(session->mbedSslConf), NULL, NULL); mbedtls_ssl_set_bio(&(session->mbedSslCtx), &(session->mbedNetCtx), mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); callStat = mbedtls_ssl_setup(&(session->mbedSslCtx), &(session->mbedSslConf)); _RETURN_IF_ERROR(callStat); while((callStat = mbedtls_ssl_handshake(&(session->mbedSslCtx))) != 0) { if ((callStat != MBEDTLS_ERR_SSL_WANT_READ) && (callStat != MBEDTLS_ERR_SSL_WANT_WRITE)) { return callStat; } } return 0; }
主函数:
static SSLSession_st *g_session = NULL; main() { SSLSession_st session; char *pers = "hello world"; MbedTlsClientInit(&(session.mbedIntf), pers, strlen(pers)); mbedtls_ssl_write(...); // 发送请求。我用的是https://www.bing.com,所以发送的是HTTP请求 /* 下面开始配置 libev */ session.libevWatcher = malloc(sizeof(session.libevWatcher)); set_nonblock(session.mbedNetCtx.fd) ev_io_init(&(session.libevWatcher), _libev_callback, fd, EV_READ); // 在callback 调用 mbedtls_ssl_read() ev_io_start(loop, &(session.libevWatcher)); ev_loop(loop, 0); }
2016年07月18日发布
更多
相关文章推荐
- 函数模版与类模版简单实例--学习笔记
- 【狂人C】学习笔记之一个简单的乘法函数的应用
- java调用c++函数的简单笔记
- 装饰器学习笔记3:简单的函数装饰器
- JavaDay04循环题目的简单思路(菱形,日历)随机数,函数
- MySQL笔记(一个简单select的函数调用过程)
- 学习Python数据分析随手笔记【一】numpy数组的函数简单应用
- 黑马程序员--C语言自学笔记---06函数简介和简单UNIX指令
- 【图形化编程软件】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记
- PyQt4学习笔记1--- 一些简单的函数
- 【图形化编程软件】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记
- 网络编程学习笔记(udp_client函数)
- MFC学习笔记 简单绘图及相关函数
- c#学习笔记之十五 目前多线程执行函数的思路
- I2C驱动client、driver简单的匹配流程笔记(以ds1307时钟芯片参考)
- oracle 最简单的学习笔记,增删改查,PLSQL基本语法,游标,函数,存储过程的实现
- 加壳学习笔记(三)-简单的脱壳思路&调试思路
- 【图形化编程软件】 sikuli常用函数、简单事件操作 键盘操作 个人总结笔记
- 加壳学习笔记(三)-简单的脱壳思路&调试思路
- OpenCV一些函数的简单笔记