快速模式第三包收尾之quick_inI2()
快速模式第三包收尾之quick_inI2()

文章目录
1. 序言
快速模式有三个报文交换,四个核心函数入口。我们已经对前三个函数处理流程对了一个简单的学习和这里,下面对第四个函数入口quick_inI2()的处理流程做一个简单的介绍。
首先需要说明的是快速模式的前两个报文是为了协商感兴趣流的相关参数(如使用的加密算法、认证算法、封装方式、感兴趣流以及生成相关的密钥信息等),而第三个报文则简单了很多:只是为了对前两个报文做认证。那么自然而然引出一个问题:为什么需要第三个报文呢?前两个报文不是已经包含HASH杂凑载荷吗? 供大家思考吧。
2. quick_inI2()处理流程图
quick_inI2()的处理流程很简单,其中最主要的便是建立出站IPsecSA。(如果IPsec处理流程都是这种精简的,该多好呀 )

3. 报文格式
quick_inR1_outI2()和quick_inI2()都是用来处理快速模式最后一个包的,报文格式完全一致。,quick_inR1_outI2()包括发送处理流程,而quick_inI2()则只为处理接收流程。

4. quick_inI2()源码
这个源码主要流程很清晰(除了建立IPsecSA),代码也很少。
/* Handle last message of Quick Mode.
* HDR*, HASH(3) -> done
* (see RFC 2409 "IKE" 5.5)
* Installs outbound IPsec SAs, routing, etc.
*/
stf_status
quick_inI2(struct msg_digest *md)
{
struct state *const st = md->st;
/* HASH(3) in *//*验证哈希报文完整性*/
CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st)
, "HASH(3)", "Quick I2");
/* Tell the kernel to establish the outbound and routing part of the new SA
* (the previous state established inbound)
* (unless the commit bit is set -- which we don't support).
* We do this before any state updating so that
* failure won't look like success.
*/
if (!install_ipsec_sa(md->pst, st, FALSE))
return STF_INTERNAL_ERROR;
{
DBG(DBG_CONTROLMORE, DBG_log("inI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
, st->st_connection->name
, st->st_connection->instance_serial
, st->st_serialno
, st->st_connection->newest_ipsec_sa
, st->st_connection->spd.eroute_owner));
}
st->st_connection->newest_ipsec_sa = st->st_serialno;
update_iv(st); /* not actually used, but tidy */
/* note (presumed) success */
{
struct gw_info *gw = st->st_connection->gw_info;
if (gw != NULL)
gw->key->last_worked_time = now();
}
/* If we have dpd delay and dpdtimeout set, then we are doing DPD
on this conn, so initialize it */
if(st->st_connection->dpd_delay && st->st_connection->dpd_timeout) {
if(dpd_init(st) != STF_OK) {
delete_ipsec_sa(st, FALSE);
return STF_FAIL;
}
}
return STF_OK;
}
4. 其他接口说明
4.1 hash载荷计算方式
快速模式虽然仅有三个报文交互,但是它们的hash杂凑载荷的计算方式却不相同:
第①包计算方式:
H
A
S
H
(
1
)
=
P
R
F
(
S
K
E
Y
I
D
−
a
,
M
s
g
I
D
∣
S
A
∣
N
i
∣
[
∣
I
D
i
∣
I
D
r
]
)
HASH(1) = PRF(SKEYID-a, MsgID | SA | Ni | [| IDi | IDr ])
HASH(1)=PRF(SKEYID−a,MsgID∣SA∣Ni∣[∣IDi∣IDr])
第②包计算方式:
H
A
S
H
(
2
)
=
P
R
F
(
S
K
E
Y
I
D
−
a
,
M
s
g
I
D
∣
N
i
∣
S
A
∣
N
r
∣
[
∣
I
D
i
∣
I
D
r
]
)
HASH(2) = PRF(SKEYID-a, MsgID | Ni | SA | Nr | [| IDi | IDr ])
HASH(2)=PRF(SKEYID−a,MsgID∣Ni∣SA∣Nr∣[∣IDi∣IDr])
第③包计算方式:
H
A
S
H
(
3
)
=
P
R
F
(
S
K
E
Y
I
D
−
a
,
0
∣
M
s
g
I
D
∣
N
i
∣
N
r
)
HASH(3) = PRF(SKEYID-a, 0 | MsgID | Ni | Nr)
HASH(3)=PRF(SKEYID−a,0∣MsgID∣Ni∣Nr)
- 第①包实现方式和第②包实现方式为同一个函数:
/* Compute HASH(1), HASH(2) of Quick Mode.
* HASH(1) is part of Quick I1 message.
* HASH(2) is part of Quick R1 message.
* Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
* (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
*/
size_t
quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
, const struct state *st, const msgid_t *msgid, bool hash2)
{
struct hmac_ctx ctx;
hmac_init_chunk(&ctx, st->st_oakley.prf_hasher, st->st_skeyid_a);/*PRF算法 + 认证秘钥*/
hmac_update(&ctx, (const void *) msgid, sizeof(msgid_t));/*填充msgid,由于认证需要msgid,而它唯一*/
if (hash2)
hmac_update_chunk(&ctx, st->st_ni); /* include Ni_b in the hash */
hmac_update(&ctx, start, roof-start);/*数据起始位置和终止位置*/
hmac_final(dest, &ctx);
return ctx.hmac_digest_len;
}
- 第③包实现方式:
/* Compute HASH(3) in Quick Mode (part of Quick I2 message).
* Used by: quick_inR1_outI2, quick_inI2
* See RFC2409 "The Internet Key Exchange (IKE)" 5.5.
* NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
* Message ID and Nonces. This is a mistake.
*/
static size_t
quick_mode_hash3(u_char *dest, struct state *st)/*第二阶段的三个报文hash值算法方式各不相同*/
{
struct hmac_ctx ctx;
hmac_init_chunk(&ctx, st->st_oakley.prf_hasher, st->st_skeyid_a);
hmac_update(&ctx, (const u_char *)"\0", 1);
hmac_update(&ctx, (u_char *) &st->st_msgid, sizeof(st->st_msgid));
hmac_update_chunk(&ctx, st->st_ni);
hmac_update_chunk(&ctx, st->st_nr);
hmac_final(dest, &ctx);
DBG_cond_dump(DBG_CRYPT, "HASH(3) computed:", dest, ctx.hmac_digest_len);
return ctx.hmac_digest_len;
}
4.2 install_ipsec_sa

5. 小结
IPsec协商流程之主模式+快速模式学习跨度比较久(3个月多),协商流程却是很复杂,而且只是看原理性知识,很多功能都没有敢去涉及,如证书认证、out_sa、 DPD、建立IPsecSA、NAT-T等等。学习期间最主要的体会是:openswan封装了很多很多接口,常用接口需要好好学习,否则在看代码时很困难。就拿out_sa 、out_struct、out_generic等系列,能恶心死人,全文基本都用这几个接口在封装报文和解封装报文,可以说这些基本函数是看openswan源码的接口。
后面计划继续更新几个函数接口实现,也是以前学习整理过程中遗留的坑,先填几个然后在更新学习其他流程。
快速模式第三包收尾之quick_inI2()的更多相关文章
- 快速模式第三包:quick_inR1_outI2()
快速模式第三包:quick_inR1_outI2() 文章目录 快速模式第三包:quick_inR1_outI2() 1. 序言 2. quick_inR1_outI2()的处理流程 3. 快速模式第 ...
- openswan中ISAKMP交互过程关键函数接口
1. ISAKMP交互过程中关键函数接口 下面分别说明不同的阶段和模式下的函数接口以及对应的报文. 2. 第一阶段(Phase I)主模式函数接口 发送端 响应端 main_outI1 主模式第一包 ...
- IPsec 9个包分析(主模式+快速模式)
第一阶段:ISAKMP协商阶段 1.1 第一包 包1:发起端协商SA,使用的是UDP协议,端口号是500,上层协议是ISAKMP,该协议提供的是一个框架,里面的负载Next payload类似模块,可 ...
- iPhone 6 被盗记录二【写在315前夕:苹果售后福州直信创邺在没有三包的情况下帮小偷翻新、助力小偷换机销赃!无视王法。让人震惊,痛心,憎恨!消费者很受伤很无奈】
投诉公司: 北京直信创邺数码科技有限公司 标题: 写在315前夕:苹果售后在没有三包的情况下帮小偷翻新.助力小偷换机销赃!无视王法.让人震惊,痛心,憎恨!消费者很受伤很无奈 期望: 还我手机,或者赔 ...
- Python自动化 【第十六篇】:JavaScript作用域和Dom收尾
本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...
- Java清除:收尾和垃圾收集
垃圾收收集器(GC)只知道释放由new关键字分配的内存,所以不知道如何释放对象的"特殊"内存.为了解决这个问题,Java提供了一个名为:finalize()的方法,可为我们的类定义 ...
- (八)java垃圾回收和收尾
垃圾回收机制:当一个对象不再被引用时,或者说当一个对象的引用不存在时,我们就认为该对象不再被需要,它所占用的内存就会被释放掉. 垃圾回收只是在程序执行过程中偶尔发生,java不同的运行时刻会产 ...
- python能够执行,但编译第三包遇到 python.h no such file or directory
python能够执行,但编译第三包遇到 python.h no such file or directory 这个问题是由于没有安装python-devel, 安装此包就能够解决次问题,在Linux下 ...
- 数据结构20:KMP算法(快速模式匹配算法)详解
通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...
随机推荐
- 电脑软件安装过程文档.BA
MD 01-打印并阅读-电脑软件安装过程文档.BAT-即此批处理脚本文档MD 02-阅读-电脑软件安装经验教训文档.DOCX-MD 03-制作-杏雨梨云USB维护系统2019中秋版之国庆更新-可启动U ...
- linux命令打基础
目录 一.shell概述 二.linux命令分类 三.linux命令行 3.1 格式 3.2 编辑Linux命令行 四.Linux基础命令 4.1 pwd:查看当前的工作目录 4.2 cd:切换工作目 ...
- ABC165C题解
题目 看题目的时候一脸懵,直到看见数据范围 \[N \le 10,\; M \le 10,\; Q \le 50 \] 之后才意识到问题的严重性. 毕竟数据如此的小,我们完全可以用阶乘复杂度算法卡过去 ...
- Python实现三次密码验证
需求:Python实现三次密码验证,每次验证结果需要提示,三次验证不通过需要单独提示 代码如下: user = '张无忌' password = '12345678' confirm_flag = F ...
- JUC学习笔记(四)
JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...
- 被字节跳动、小米、美团面试官问的AndroidFramework难倒了? 这里有23道面试真题,助力成为offer收割机!
目录 1.Android中多进程通信的方式有哪些?a.进程通信你用过哪些?原理是什么?(字节跳动.小米)2.描述下Binder机制原理?(东方头条)3.Binder线程池的工作过程是什么样?(东方头条 ...
- Maven 手动安装JAR包到本地maven仓库后,但在项目中依旧报错找不到JAR包解决方法
本博客包含的内容: ①手动安装jar包到本地仓库: ②解决Missing artifact org.source.fastdfs:fastdfs:jar问题 .personSunflowerP { b ...
- excel的导入与导出---通用版
excel的导入与导出---通用版 web项目关于导入导出的业务场景很常见,最近我就又遇到了这个业务场景.这次将最近半个月做的导入导出总结一下 使用的pom如下,主要还是阿里巴巴的easyexcel依 ...
- EasyExcel导入导出
maven依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <dependency> & ...
- Do you want to continue? [Y/n] Abort.
当出现这个后命令终止,无法选择 y这时候 ,在输入命令时候提前加入 -y udo apt install sysv-rc-conf -y