pluto实现分析(1)——前言、IKEv1概述、源文件概述

本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn:  [email protected]
来源: 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_R
        HDR, [ 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,
          [
                                         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:扩展认证处理

...... 待续 ......

http://blog.chinaunix.net/uid-127037-id-2919599.html


你可能感兴趣的:(ipsec与openswan)