pluto实现分析(1)
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
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处理。
进行异步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:扩展认证处理
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:扩展认证处理
...... 待续 ......