1. 序言
main_inR1_outI2()
函数是ISAKMP协商过程中==第三包的核心处理函数的入口==。这里我们主要说明main_inR1_outI2
的函数调用关系、处理流程以及对源码的注释分析,关于main_inR1_outI2
的上下文环境暂不叙述,留给后面的文章进行更新。
ISAKMP协商报文的处理流程都比较复杂,一个函数有几百行都是很常见的,因此个人学习期间难免有遗漏和理解错误的地方,请大家多多批评指正。
对于源码的学习,我并没有把每一行进行备注,而是将自己认为的关键点做了注释或者标注。
2. 函数调用关系
注意:这里我把收到对方报文后的处理流程也添加上了,主要是在学习源码过程中遇到
complete_v1_state_transition
执行了两次。第二次会检测第一次的返回值,因此不会重复的发送报文更新状态。
- process_v1_packet
- process_packet_tail
- smc->processor(md)
- main_inR1_outI2
- build_ke
- send_crypto_helper_request
- pluto_do_crypto_op
- main_inR1_outI2_continue
- main_inR1_outI2_tail
- init_pbs
- ship_KE
- ship_nonce
- nat_traversal_add_natd
- close_message
- insert_state
- complete_v1_state_transition
- main_inR1_outI2_tail
- send_crypto_helper_request
- build_ke
- main_inR1_outI2
- complete_v1_state_transition
- smc->processor(md)
- process_packet_tail
3. 第三个报文流程图
由于第三个报文的核心处理函数包含多个,不仅仅包含main_inR1_outI2
, 因此这里会将涉及的关键函数接口都添加到流程图中,方便根据函数定位对应的功能。
- 解析对端发送的SA载荷,确定对端选择的算法,并将其存储在状态/连接上
- 生成秘钥交换材料和Nonce信息
- ==构造应答报文(第四个报文)==
- 填充KE载荷和Nonce载荷。
4. main_inR1_outI2源码注释
- 解析收到的第二个报文,确定对端选择的算法,并将算法存储在状态结构上
- 申请生成交换密钥信息
1 |
|
5. build_ke源码注释
- 初始化并发送加密请求
- 生成加密材料、Nonce载荷、构建应答报文在
send_crypto_helper_request
及其以后。
- 生成加密材料、Nonce载荷、构建应答报文在
- 完成报文发送后的后续操作
1 |
|
6. send_crypto_helper_request源码注释
- 生成秘钥信息(KE信息、Nonce信息),并存储在r中;
- 执行后续处理函数:
main_inR1_outI2_continue
1 | /* |
7. send_crypto_helper_request源码注释
- 通过
main_inR1_outI2_tail
构建应答报文 - 通过
complete_v1_state_transition
完成报文的发送和后续的状态切换等。
1 | /* |
8. main_inR1_outI2_tail源码注释
- 构建ISAKMP头部信息
- 构建KE载荷
- 构建Nonce载荷
- 构建NAT-d载荷
- 载荷添加完毕,关闭应答buf, 确定ISAKMP报文长度并填充长度字段。
1 |
|
9. NAT-D载荷中哈希值说明
在NAT-D载荷中,hash值的计算公式为:
$$
HASH(CKY-I | CKY-R | IP | PORT)
$$
即分别计算发起者cookie、相应者cookie、IP、端口四个信息的哈希值。对端收到后通过计算报文信息的哈希值和报文中的NAT-D载荷的哈希值相比较,以此来确定中间是否存在NAT设备。
1 |
|