前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Openssl状态机的实现

Openssl状态机的实现

原创
作者头像
mariolu
修改2018-11-21 19:51:12
2.2K0
修改2018-11-21 19:51:12
举报
文章被收录于专栏:CDN及云技术分享

一、Openssl为什么需要状态机

Openssl是通过“握手“建立加密信道,在该信道双方的身份都是合法的,并且传输数据都是密文传输。Openssl握手通过客户端和服务端互相交换信息计算出secret。计算出密钥的方式有很多种。这中间可能需要几个RTT来回。状态机需要针对约定好的加密算法按照一定的步骤执行。所以需要状态机保存握手过程中的参数。

二、状态机是什么

简单地说,状态机保存Ssl握手需要一些消息处理函数,和算法函数来解析消息,执行加解密操作。要么是发送处理好的消息流,要么是接收对方的消息流。所以一个状态机是在读写函数不断切换。消息状态机如果不按正常的流程走,就形成了状态机的异常或者遭受到了安全攻击。以下的状态机模型是基于最新的openssl 1.1.1版本得出。

2.1、消息流状态机

消息流状态机由MSG_FLOW_UNINITED到读写多次来回切换到MSG_FLOW_FINISHED状态。为什么这里MSG_FLOW_FINISHED(4)有可能会重新执行新的读写操作?当前的代码是没有实现MSG_FLOW_FINISHED入口。当然消息状态异常也有个状态MSG_FLOW_ERROR。遇到这种状态SSL握手失败,并且该SSL连接不会再进入握手流程。

MSG_FLOW_UNINITED(1) MSG_FLOW_FINISHED(4)

| |

+-------------------------------+

v

MSG_FLOW_WRITING(写状态机)(2) <---> MSG_FLOW_READING(读状态机)(3)

|

V

MSG_FLOW_FINISHED(4)

|

V

[SUCCESS](5)

2.2、写状态机

写的状态机是由消息流状态机调用,写状态机调用结束后有两种返回状态:SUB_STATE_FINISHED或者SUB_STATE_END_HANDSHAKE。SUB_STATE_FINISHED表明此次写状态机调用结束,写状态机完成必要的状态迁移或者发送操作,控制权转交给消息流状态机,由消息流状态机决定下个操作。SUB_STATE_END_HANDSHAKE则向消息流状态机表示握手已经完满成功。

WRITE_STATE_TRANSITION决定ssl握手的下一步状态。WRITE_STATE_PRE_WORK和WRITE_STATE_POST_WORK则会根据ssl握手的当前状态,进行相对应的操作。也就是一个switch-case操作。也可能对BIO进行必要的操作(比如清空buffer)。这里的BIO是什么?BIO和EVP是openssl两个重要系列的函数。BIO或者EVP只不过是一些底层的支撑接口,没有任何的现实意义,正是SSL使用了BIO和EVP 的机制提供了一个已经成型的安全套接字的实现策略。其实想象一下,安全套接字有两层含义,一层就是安全,这个由EVP接口实现了,另外一层含义就是套接 字,也就是说它必须是一个套接字,必须在操作的网络协议栈上进行IO,这一层含义是在BIO接口体现的,这个意义上,SSL正是通过组合BIO和EVP来 实现安全套接字的。

+-> WRITE_STATE_TRANSITION ------> [SUB_STATE_FINISHED]

| |

| v

| WRITE_STATE_PRE_WORK -----> [SUB_STATE_END_HANDSHAKE]

| |

| v

| WRITE_STATE_SEND

| |

| v

| WRITE_STATE_POST_WORK

| |

+-------------+

2.3、读状态机

READ_STATE_HEADER <--+<-------------+

| | |

| | |

READ_STATE_BODY-----+-->READ_STATE_POST_PROCESS

| |

+---------------------------------+

v

[SUB_STATE_FINISHED]

READ_STATE_HEADER:根据读到的消息头(type)去决定ssl握手的状态。并且决定之后怎么处理该消息。

READ_STATE_BODY:读取消息的剩余部分,接着处理

READ_STATE_POST_PROCESS:由于阻塞block的消息,有可能需要在当前SSL握手状态继续重试读取消息。

三、Openssl握手状态

这些消息流状态机、写状态机、读状态机共同完成了TLS握手过程。WRITE_STATE_TRANSITION(READ_WRITE_TRANSITION)完成了以下状态的迁移。

图1、openssl状态
图1、openssl状态

图1的交互参数含义如下。

v:版本号

kx: 密钥协商算法

rid:会话id

rticket:会话ticket

cask:客户端鉴权证书请求

coffer:客户端鉴权

ntick:服务端是否发生session ticket

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Openssl为什么需要状态机
  • 二、状态机是什么
    • 2.1、消息流状态机
      • 2.2、写状态机
        • 2.3、读状态机
        • 三、Openssl握手状态
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档