快速模式第三包收尾之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_saout_structout_generic等系列,能恶心死人,全文基本都用这几个接口在封装报文和解封装报文,可以说这些基本函数是看openswan源码的接口。

后面计划继续更新几个函数接口实现,也是以前学习整理过程中遗留的坑,先填几个然后在更新学习其他流程。

快速模式第三包收尾之quick_inI2()的更多相关文章

  1. 快速模式第三包:quick_inR1_outI2()

    快速模式第三包:quick_inR1_outI2() 文章目录 快速模式第三包:quick_inR1_outI2() 1. 序言 2. quick_inR1_outI2()的处理流程 3. 快速模式第 ...

  2. openswan中ISAKMP交互过程关键函数接口

    1. ISAKMP交互过程中关键函数接口 下面分别说明不同的阶段和模式下的函数接口以及对应的报文. 2. 第一阶段(Phase I)主模式函数接口 发送端 响应端 main_outI1 主模式第一包 ...

  3. IPsec 9个包分析(主模式+快速模式)

    第一阶段:ISAKMP协商阶段 1.1 第一包 包1:发起端协商SA,使用的是UDP协议,端口号是500,上层协议是ISAKMP,该协议提供的是一个框架,里面的负载Next payload类似模块,可 ...

  4. iPhone 6 被盗记录二【写在315前夕:苹果售后福州直信创邺在没有三包的情况下帮小偷翻新、助力小偷换机销赃!无视王法。让人震惊,痛心,憎恨!消费者很受伤很无奈】

    投诉公司: 北京直信创邺数码科技有限公司  标题: 写在315前夕:苹果售后在没有三包的情况下帮小偷翻新.助力小偷换机销赃!无视王法.让人震惊,痛心,憎恨!消费者很受伤很无奈 期望: 还我手机,或者赔 ...

  5. Python自动化 【第十六篇】:JavaScript作用域和Dom收尾

    本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...

  6. Java清除:收尾和垃圾收集

    垃圾收收集器(GC)只知道释放由new关键字分配的内存,所以不知道如何释放对象的"特殊"内存.为了解决这个问题,Java提供了一个名为:finalize()的方法,可为我们的类定义 ...

  7. (八)java垃圾回收和收尾

    垃圾回收机制:当一个对象不再被引用时,或者说当一个对象的引用不存在时,我们就认为该对象不再被需要,它所占用的内存就会被释放掉.     垃圾回收只是在程序执行过程中偶尔发生,java不同的运行时刻会产 ...

  8. python能够执行,但编译第三包遇到 python.h no such file or directory

    python能够执行,但编译第三包遇到 python.h no such file or directory 这个问题是由于没有安装python-devel, 安装此包就能够解决次问题,在Linux下 ...

  9. 数据结构20:KMP算法(快速模式匹配算法)详解

    通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...

随机推荐

  1. noip模拟31[time·game·cover]

    noip模拟31 solutions 我就觉得这些考试题是越考越难,我是也越考越完蛋,已经完完全全的接近爆零了 只有20pts,说真的这还是我第一次挂掉30pts,本来我还有50pts嘞 所以这次考试 ...

  2. 缩减Azure上Linux虚拟机系统盘容量

    [话在前头] 这么些年微软 Azure 创建虚拟机一直不能修改系统盘大小,但很多时候实际又用不了这么大的操作系统磁盘.微软自己甚至还针对 Windows 服务器镜像推出一个 smalldisk 的镜像 ...

  3. 涨姿势啦!Java程序员装X必备词汇之对象标记Mark Word!

    大家好,我是庆哥Java,一个专注于干货分享的Java自学者! 写在前面 如果你已经知道什么是Mark Word,那我也希望你都好好阅读下本篇文章,因为你有可能发现不一样的切入点来帮助你更加深入的了解 ...

  4. centos linux下配置固定ip,方便xshell连接

    如何给centos linux设置固定ip地址,设置Linux系统的固定IP地址 首先wmware打开虚拟机 打开xshell6连接虚拟机(比较方便,这里默认设置过Linux的ip,只是不固定,每次打 ...

  5. 微信小程序测试点

    一.测试范围 1.权限测试 需要检查以下几种情况下微信用户访问的权限 1)未授权微信登录小程序 未授权时,一般使用一些业务功能的时候,都会弹出提醒:先授权再操作对应功能.or在提交数据到后台的时候,会 ...

  6. 谈谈网络协议 - 数据链路层( Data Link)

    数据链路层( Data Link) 链路:从1个节点到相邻节点的一段物理线路(有线或无线),中间没有其他交换节点 案例 上图可以看出,总共由5条链路组成: 第1条:计算机0 => 路由器0,使用 ...

  7. 基于Gitea搭建属于自己的Git服务

    作者:IT王小二 博客:https://itwxe.com 一.搭建环境和前提 搭建环境: 操作系统:CentOS7.6 Docker版本:docker-ce-18.09.9 Lsky Pro版本:1 ...

  8. Golang语言系列-13-常用内置包

    常用内置包 net/http包 http请求和响应 http服务端 main.go文件 package main import ( "fmt" "io/ioutil&qu ...

  9. kali虚拟机安装VMTools、更新源、安装docker、配置sqli-labs

    一.安装VMTools: 传送门:关于安装VMTools 跟其他版本的虚拟机安装VMTools没什么区别,也得连网(我是kali用dhcp开nat模式) 之后按照上面的链接根据博主的步骤一步一步来即可 ...

  10. 不同JDK版本的流异常处理

    1.JDK7以前的流异常try-catch处理 public static void main(String[] args) { FileInputStream fis = null; try { f ...