pluto实现分析

pluto实现分析(1)
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
1. 前言
pluto是著名的VPN开源项目freeswan及其后续项目中的一个重要组成部分,实现了IKEv1(RFC2409),原始的fresswan只是实现IKE的基本功能,但不包括很多其他扩展功能,都需要打补丁实现,freeswan停止开发后,继续扩展出两个不同的分支,openswan和strongswan,前者综合各种功能的补丁,IKE功能比较全面;后者功能相对少点,但重要特点就是支持了IKEv2(RFC4306),因此两者各有优势。目前国内做IPSec VPN的基本都是基于这实现的,好象没听说一家国内公司敢拍胸脯说自己的VPN产品是全部是自己写的代码,所作的最大改动就是增加硬件加密卡的支持了。目前国内IKEv2使用的可能性应该还不大,因为即使是上面要制定的国内的VPN标准其实还是根据IKEv1来走的,会不会升级到IKEv2还是未知数。
本文主要是解析openswan-2.4.7中的pluto的实现过程,代码基本都是在programs/pluto目录下。
2. IKEv1概述
2.1 概述
IKEv1在RFC2409中定义,用于定义自动建立IPSec SA的协商处理过程,该RFC只是定义数据的交换过程,而具体的数据格式的定义则是在RFC2408中定义的。
IKEv1协商过程分两个阶段,第一个阶段分两种模式,一种是主模式(main mode),是用于正常情况下的协商处理,交换数据回合比较多,速度较慢,这个模式是IKE的具体实现中必须实现的;另一种的野蛮模式(Aggressive Mode),这种模式的数据交换回合比较少,速度较快,但有不安全因素,通常用于已经建立过的IPSec连接中断后的重新建立处理,而且不是在具体实现中必须实现的。第一阶段的处理目的是建立一个ISAKMP SA,为下一阶段的协商建立安全通道。
IKEv1的第二阶段只有一种模式:快速模式(quick mode),通过这个阶段的数据协商,最终建立起IPSec SA。
对于扩展认证EAP(XAUTH),是在第一阶段结束,第二阶段开始前处理的。
在进行协商时,肯定是要用到非对称加密算法或DH交换来协商对称加密密钥的,使用非对称加密算法时可以使用RSA,或者是本质相同的相同的;另外也可以使用共享密钥方式进行对称密钥的协商,协商算法可使用DH。按不同的密钥处理方法,IKEv1的协商过程也有区别。
2.2 第一阶段: (以下各类是独立,HDR*表示数据包是加密的)

1) Authenticated With Signatures
主模式:
Initiator                          Responder
-----------                        -----------
HDR, SA                -->
                    <--             HDR, SA
HDR, KE, Ni            -->
                    <--          HDR, KE, Nr
HDR*, IDii, [ CERT, ] SIG_I     -->
             <--  HDR*, IDir, [ CERT, ] SIG_R
野蛮模式:
Initiator                          Responder
-----------                        -----------
HDR, SA, KE, Ni, IDii  -->
                      <--    HDR, SA, KE, Nr,
                              IDir, [ CERT, ]
                          SIG_RHDR, [ CERT, ] 
SIG_I                  -->
2) Authenticated With Public Key Encryption
主模式:
Initiator                        Responder
-----------                      -----------
HDR, SA               -->
                  <--           HDR, SA
                       HDR, KE, [ HASH(1), ]
                         PubKey_r,
PubKey_r           -->
HDR, KE, PubKey_i,
                    <--        PubKey_i
HDR*, HASH_I            -->
                      <--    HDR*, HASH_R
野蛮模式:
Initiator                        Responder
-----------                      -----------
HDR, SA, [ HASH(1),] KE,
Pubkey_r,
Pubkey_r         -->
                  HDR, SA, KE, PubKey_i,
            <--         PubKey_i, HASH_R
HDR, HASH_I           -->
3) Authenticated With a Revised Mode of Public Key Encryption
主模式:
Initiator                        Responder
-----------                      -----------
HDR, SA             -->
                         <--    HDR, SA
                         HDR, [ HASH(1), ]
                          Pubkey_r,
                            Ke_i,
                           Ke_i,
[<Ke_i]       -->
HDR, PubKey_i,
Ke_r,
                <--          Ke_r,
HDR*, HASH_I          -->
                <--             HDR*, HASH_R
野蛮模式:
Initiator                        Responder
-----------                      -----------
HDR, SA, [ HASH(1),]
Pubkey_r,
Ke_i, Ke_i
[, Ke_i ]      -->
                     HDR, SA, PubKey_i,
                     Ke_r, Ke_r,
                <--                HASH_R
HDR, HASH_I          -->
 
4) Authenticated With a Pre-Shared Key
主模式:
Initiator                        Responder
----------                       -----------
HDR, SA             -->
                <--                HDR, SA
HDR, KE, Ni           -->
                <--              HDR, KE, Nr
HDR*, IDii, HASH_I         -->
                <--         HDR*, IDir, HASH_R
野蛮模式:
            Initiator                        Responder
-----------                      -----------
HDR, SA, KE, Ni, IDii     -->
                <-- HDR, SA, KE, Nr, IDir, HASH_R
HDR, HASH_I          -->
 
2.3 第二阶段
快速模式:
Initiator                        Responder
-----------                      -----------
HDR*, HASH(1), SA, Ni
[, KE ] [, IDci, IDcr ] -->
                 <--    HDR*, HASH(2), SA, Nr
                      [, KE ] [, IDci, IDcr ]
HDR*, HASH(3)          -->
 
如果有多个SA和密钥可使用下面的数据交换方法:
Initiator                        Responder
-----------                      -----------
HDR*, HASH(1), SA0, SA1, Ni,
[, KE ] [, IDci, IDcr ]     -->
                <--  HDR*, HASH(2), SA0, SA1, Nr,
                     [, KE ] [, IDci, IDcr ]
HDR*, HASH(3)         -->
HASH(1) = prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr )
HASH(2) = prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr )
HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b)
 
2.4 新组模式(New Group Mode)
新组模式不是必须实现的, 是用来定义DH交换的私有组的, 必须在ISAKMP SA建立前使用, 也就是在第一阶段后, 第二阶段前。
Initiator                        Responder
-----------                      -----------
HDR*, HASH(1), SA        -->
                  <--       HDR*, HASH(2), SA
                    HASH(1) = prf(SKEYID_a, M-ID | SA)
                 HASH(2) = prf(SKEYID_a, M-ID | SA)
 

3. 源文件概述
programs/pluto目录下编译后会生成3个执行文件:pluto, whack, _pluto_adns。其中pluto是基本程序,提供IKEv1服务,打开UDP500和4500端口监听网卡数据,打开UNIX域套接口监听whack的输入,并和内核进行PFKEY/netlink通信;whack是控制程序,通过UNIX域套接口和pluto通信;_pluto_adns
进行异步DNS处理。
各个C程序大致功能如下:
ac.c:X509证书相关支持处理
adns.c:异步DNS辅助处理
asn1.c:简单的ASN.1解析器
certs.c:证书处理
connections.c:连接处理
cookie.c:cookie处理
crypto.c:加密
crypt_dh.c:DH算法
crypt_ke.c:密钥交换KE处理
crypt_utils.c:加密相关函数
db_ops.c:数据库操作
defs.c:一些辅助函数集合
demux.c:数据包解析
dnskey.c:从DNS获取公钥的处理
dpd.c:DPD处理
dsa.c:DSA签名
elgamal.c:ElGamal公开密钥加密
fetch.c:动态获取X.509的证书吊销列表CRL
foodgroups.c:策略组控制
gcryptfix.c:进行gcrypt处理
id.c:端点ID处理
ikeping.c:ping IKE包
ikev1_aggr.c:野蛮模式处理
ikev1_quick.c:快速模式处理
ike_alg.c:IKE算法处理
ike_alginit.c:IKE算法初始化
ike_alg_aes.c:AES加密算法
ike_alg_blowfish.c:blowfish加密算法
ike_alg_serpent.c:serpent加密算法
ike_alg_sha2.c:SHA2哈希算法
ike_alg_twofish.c:twofish加密算法
ipsec_doi.c:IKE模式转换处理
kernel.c:内核接口
kernel_netlink.c:和内核的netlink接口
kernel_noklips.c:noklips模式下的内核接口
kernel_pfkey.c:和内核的pfkey接口
keys.c:密钥处理
lex.c:配置文件语法分析器
log.c:日志处理
md2.c:MD2哈希算法
md5.c:MD5哈希算法
nat_traversal.c:NAT穿越支持
ocsp.c:在线证书状态协议支持
oid.c:常见的一些对象的ID定义
pem.c:PEM格式证书处理
pending.c:连接的相关信息处理
pgp.c:PGP证书处理
pkcs.c:PKCS#1和PKCS#7数据结构支持
plutoalg.c:pluto算法处理
plutomain.c:主函数
pluto_constants.c:pluto常数
pluto_crypt.c:pluto加密算法处理
primegen.c:生成素数
rcv_info.c:接收数据
rcv_whack.c:接收whack输入信息
rnd.c:随机数
server.c:IKE服务
sha1.c:SHA1哈希算法
smallprime.c:小素数处理
smartcard.c:smartcard支持
spdb.c:安全策略数据库处理
spdb_print.c:安全策略输出
spdb_struct.c:安全策略结构
state.c:状态处理
stubs.c:某些功能的stub
sysdep_linux.c:和linux相关的相关处理
timer.c:定时器
vendor.c:VPN功能提供者信息
virtual.c:虚拟IP支持
whack.c:whack控制
whackinit.c:whack初始化
whacklib.c:whack相关库函数
x509.c:X509证书支持
x509keys.c:X509密钥
xauth.c:扩展认证处理
...... 待续 ......
此条目发表在network分类目录,贴了, 标签。将固定链接加入收藏夹。