Openssl状态机的实现

一、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的交互参数含义如下。

v:版本号

kx: 密钥协商算法

rid:会话id

rticket:会话ticket

cask:客户端鉴权证书请求

coffer:客户端鉴权

ntick:服务端是否发生session ticket

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

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

Configure Apache Virtual Hosts - CentOS 7

Difficulty: 2 Time: 15 minutes Want to host websites on your server? Using Apach...

3774
来自专栏雨尘分享

TCP 看我就够了

3535
来自专栏Kotlin入门系列

win7基础 cmd 查看当前已经启动的服务列表

5586
来自专栏杨建荣的学习笔记

探究AWR 第二篇(r3笔记第93天)

在探究awr第一篇中介绍了awr的一些基本操作 http://blog.itpub.net/23718752/viewspace-1123134/ 在这一篇中,...

3187
来自专栏逸鹏说道

★Kali信息收集★8.Nmap :端口扫描

突然发现,微信一次最多推送8篇 参数:(Zenmap是Nmap图形化工具,不想打指令的可以直接使用) 详细:https://nmap.org/man/zh/in...

5454
来自专栏FreeBuf

EE 4GEE Mini本地提权漏洞(CVE-2018-14327)分析

我在前段时间从买了一个4G调制解调器。这是一个便携式4G WiFi移动宽带调制解调器。有一天,我查看了安装在电脑上的用于故障排除的服务,我看到了一个奇怪的服务,...

873
来自专栏吴伟祥

Linux命令缩写英文对照记忆(〇) 转

1112
来自专栏Hadoop实操

如何在CDH启用Kerberos的情况下安装及使用Sentry(二)

使用beeline连接HiveServer2,创建columnread角色并授权test表s1列的读权限,将columnread角色授权给fayson_r用户组

1.4K8
来自专栏FreeBuf

SniffAir:无线渗透测试框架

SniffAir是一个开源的无线安全框架,可帮助你轻松解析被动收集的无线数据并发起复杂的无线渗透测试。此外,它还可以处理大型的或多个pcap文件,执行交叉检查和...

962
来自专栏帘卷西风的专栏

关于cocos2dx客户端程序的自动更新解决方案

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

1861

扫码关注云+社区

领取腾讯云代金券