`
liuzhaomin
  • 浏览: 198682 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

openssl框架闲谈--总论 -- 转载

阅读更多

接触openssl已经有一段时间了,我读过很多源码,感觉不错的也就那么几个,linux内核是其中之 一,openssl也是其中之一。openssl说白了不是什么功能性的东西,而是提供了一个支撑性的底层框架,本质上和linux内核一样,但是和 apache有区别,apache明确的实现了一个功能,就是web服务器,而openssl中我认为最重要的就是它提供的BIO框架和EVP框架,与其 说openssl是一个ssl的实现不如说ssl只不过是openssl框架的一个demo,本质上openssl提供了一套抽象的IO接口,这就是 BIO,还有一套很容易使用的加密解密接口,这就是EVP,最后证实ssl这个协议使用了上述两类接口,如果从这个意义上讲的话,apache其实也是这 样的,在构建顶层的web服务器之前首先实现了一套apr通用框架,甚至memcahce使用的libevent也是这样,这就是说很多的成功的开源的代 码与其说是一种专用的程序倒不如说包含有一套通用的框架,而这个带代码的原始意义最后退化成了使用这个通用框架的一个实例,最起码我看好的几个开源项目都 是这样。策略和机制分离,可扩展性十分棒,用起来十分灵活。 
     openssl总的来说由三部分组成,一个是BIO,一个是EVP,还有一个就是构建于二者之上的ssl实现。研究这套代码实现给我们可以带来很多的启 示,其中最重要的我想就是IO的意义,还是先拿linux内核来说事吧,其实多任务操作系统提供给用户n台冯诺依曼机器,不但将逻辑抽象给了用户,而且将 大部分cpu指令也抽象给了用户,唯独不包括IO指令,因为外设不是多任务的,外设无法自己处理好多个任务的互斥关系,所有的多个任务共享一个外设,因此 操作系统内核必须进行管理,这就是操作系统内核提供的IO系统调用的作用,也就是说IO指令必须通过系统调用进入操作系统内核之后让内核帮忙处理。以上就 是io的意义,对于openssl提供BIO接口其实意义和上面的差不多,不同的是在原始的io指令发送给操作系统之前提供了用户处理的机会,也就是说用 户可以过滤发送给内核的io系统调用的消息,比如加密,分段等等。如果按照网络的观点,协议栈提供一幅和io截然不同的图景,虽然协议栈最终也要将数据给 了网卡和电缆,但是网卡作为一个外设的意义被更抽象的物理层和链路层取代了,人们不再认为发送网络数据就是共享网卡外设或者电缆,而更多讨论以太网 csma/cd模型,或者ppp链路规程之类的抽象的概念,因此对于网络数据的io,协议栈将一切都抽象了,一切都抽象成了分层的模型,这就是分层模型的 重大意义,人们可以在共享的网卡和电缆上发送不共享的数据,一切井井有条。不像普通的打印机数据发送,网络数据的发送方式截然不同,如果你想发送数据给打 印机,那么首先你必须首先得到打印机的文件描述符,如果另一个用户也要发送数据给打印机,那么操作系统内核的文件系统模块此时将协调它们的顺序,如果网络 数据的话,协议栈就搞定了一切,在用户层不需要类似的文件描述符的概念,而相同意义的概念就是套接字,需要一个ip地址和一个端口号,这就是协议栈的功 能,然后协议栈会将数据一直传输到最底层的物理层,这种方式看起来要比文件的方式更加直观,因此unix/linux中没有将网卡抽象成设备文件,毕竟协 议栈完成了相同的功能。当然套接字接口还是和文件接口相统一的,但是这仅仅是为了操作的统一和方便,普通的设备将通过打开一个设备文件的方式得到文件描述 符,而套接字的方式完全按照协议栈的要求,需要提供一个ip地址和一个端口号以及协议族。在openssl中,你既可以通过普通io的方式也就是说设备文 件的方式扩展传统io模型,也可以使用网络协议栈的方式扩展io模型,实际上openssl框架将二者统一成为一体。 
首先,如果使用普通的设备文件方式的io,那么我们只需要BIO就可以了,因为BIO是链式的,所以你可以随意进行io过滤,如果想扩展网络协议栈,鲁迅 式的废话就是同样只需要BIO就可以了,但是条件是最下面的BIO必须是一个套接字,因为我们要在应用层扩展并且只能在应用层扩展,那么就必然要在套接字 之上扩展,ssl就是在普通套接字之上加入了安全保护功能。BIO统一了两种方式,其实目前为止也就这两种io的方式,一种是以可以抽象为设备文件的设备 为载体的IO,这种IO又可细分为块设备和字符设备的IO,对于块设备往往通过文件系统来访问;另一种以网络协议栈方式进行的网络IO,协议栈实现几乎一 切流程,整个协议栈的分层模型和文件系统/设备驱动的分层模型类似,openssl的BIO可以包容这二者的任何一种,并且还可以混合它们,本质上BIO 可以组合成通向世界任何一个地方的管道。 
对于EVP,它提供了很多易用的加密解密接口函数,openssl本身已经自带了很多加密解密算法,利用这套EVP接口,你甚至可以轻松实现自己的加密解 密算法。EVP接口中封装了算法的流程,具体的算法由不同的策略来填充,这一点上所有优秀的东西几乎是一致的。 
     openssl导出的接口是十分容易使用的,基本都是一看声明就知道其用处。以下这个例子读取并且解析一个证书: 
X509 * cert = NULL; 
BIO *pbio = BIO_new_file((const char*)strPath, "r"); 
cert = PEM_read_bio_X509(pbio,NULL,NULL,NULL);

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics