ikev2.py revision 7b3e970663abd72697e17b70aba9943ae0dad404
1770bb9f5f4acc0c59e3a200849c189d6616e2417Phil#!/usr/bin/env python
2770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
3770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# http://trac.secdev.org/scapy/ticket/353
4770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
5770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# scapy.contrib.description = IKEv2
6770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# scapy.contrib.status = loads
7770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
8770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.all import *
9770bb9f5f4acc0c59e3a200849c189d6616e2417Philimport logging
10770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
11770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
12770bb9f5f4acc0c59e3a200849c189d6616e2417Phil## Modified from the original ISAKMP code by Yaron Sheffer <yaronf.ietf@gmail.com>, June 2010.
13770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
14770bb9f5f4acc0c59e3a200849c189d6616e2417Philimport struct
15770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.packet import *
16770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.fields import *
17770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.ansmachine import *
18770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.layers.inet import IP,UDP
19770bb9f5f4acc0c59e3a200849c189d6616e2417Philfrom scapy.sendrecv import sr
20770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
21770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# see http://www.iana.org/assignments/ikev2-parameters for details
22770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2AttributeTypes= { "Encryption":    (1, { "DES-IV64"  : 1,
23770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "DES" : 2,
24770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "3DES" : 3,
25770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "RC5" : 4,
26770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "IDEA" : 5,
27770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "CAST" : 6,
28770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Blowfish" : 7,
29770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "3IDEA" : 8,
30770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "DES-IV32" : 9,
31770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CBC" : 12,
32770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CTR" : 13,
33770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CCM-8" : 14,
34770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CCM-12" : 15,
35770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CCM-16" : 16,
36770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-GCM-8ICV" : 18,
37770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-GCM-12ICV" : 19,
38770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-GCM-16ICV" : 20,
39770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Camellia-CBC" : 23,
40770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Camellia-CTR" : 24,
41770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Camellia-CCM-8ICV" : 25,
42770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Camellia-CCM-12ICV" : 26,
43770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "Camellia-CCM-16ICV" : 27,
44770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                        }, 0),
45770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                         "PRF":            (2, {"PRF_HMAC_MD5":1,
46770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_HMAC_SHA1":2,
47770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_HMAC_TIGER":3,
48770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_AES128_XCBC":4,
49770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_HMAC_SHA2_256":5,
50770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_HMAC_SHA2_384":6,
51770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_HMAC_SHA2_512":7,
52770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "PRF_AES128_CMAC":8,
53770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                       }, 0),
54770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                         "Integrity":    (3, { "HMAC-MD5-96": 1,
55770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "HMAC-SHA1-96": 2,
56770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "DES-MAC": 3,
57770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "KPDK-MD5": 4,
58770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-XCBC-96": 5,
59770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "HMAC-MD5-128": 6,
60770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "HMAC-SHA1-160": 7,
61770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-CMAC-96": 8,
62770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-128-GMAC": 9,
63770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-192-GMAC": 10,
64770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "AES-256-GMAC": 11,
65770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "SHA2-256-128": 12,
66770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "SHA2-384-192": 13,
67770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "SHA2-512-256": 14,
68770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                        }, 0),
69770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                         "GroupDesc":     (4, { "768MODPgr"  : 1,
70770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "1024MODPgr" : 2,
71770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "1536MODPgr" : 5,
72770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "2048MODPgr" : 14,
73770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "3072MODPgr" : 15,
74770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "4096MODPgr" : 16,
75770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "6144MODPgr" : 17,
76770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "8192MODPgr" : 18,
77770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "256randECPgr" : 19,
78770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "384randECPgr" : 20,
79770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "521randECPgr" : 21,
80770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "1024MODP160POSgr"  : 22,
81770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "2048MODP224POSgr"  : 23,
82770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "2048MODP256POSgr"  : 24,
83770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "192randECPgr" : 25,
84770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                "224randECPgr" : 26,
85770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                        }, 0),
86770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                         "Extended Sequence Number":       (5, {"No ESN":     0,
87770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                                 "ESN":   1,  }, 0),
88770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                         }
89770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
90770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# the name 'IKEv2TransformTypes' is actually a misnomer (since the table
91770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# holds info for all IKEv2 Attribute types, not just transforms, but we'll
92770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# keep it for backwards compatibility... for now at least
93770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2TransformTypes = IKEv2AttributeTypes
94770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
95770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2TransformNum = {}
96770bb9f5f4acc0c59e3a200849c189d6616e2417Philfor n in IKEv2TransformTypes:
97770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    val = IKEv2TransformTypes[n]
98770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    tmp = {}
99770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    for e in val[1]:
100770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        tmp[val[1][e]] = e
101770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    IKEv2TransformNum[val[0]] = (n,tmp, val[2])
102770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
103770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2Transforms = {}
104770bb9f5f4acc0c59e3a200849c189d6616e2417Philfor n in IKEv2TransformTypes:
105770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	IKEv2Transforms[IKEv2TransformTypes[n][0]]=n
106770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
107770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(n)
108770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(e)
109770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(tmp)
110770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(val)
111770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
112770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# Note: Transform and Proposal can only be used inside the SA payload
113770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_payload_type = ["None", "", "Proposal", "Transform"]
114770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
115770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_payload_type.extend([""] * 29)
116770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_payload_type.extend(["SA","KE","IDi","IDr", "CERT","CERTREQ","AUTH","Nonce","Notify","Delete",
117770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                       "VendorID","TSi","TSr","Encrypted","CP","EAP"])
118770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
119770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_exchange_type = [""] * 34
120770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_exchange_type.extend(["IKE_SA_INIT","IKE_AUTH","CREATE_CHILD_SA",
121770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                        "INFORMATIONAL", "IKE_SESSION_RESUME"])
122770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
123770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
124770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_class(Packet):
125770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    def guess_payload_class(self, payload):
126770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        np = self.next_payload
127770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        logging.debug("For IKEv2_class np=%d" % np)
128770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        if np == 0:
1297b3e970663abd72697e17b70aba9943ae0dad404Phil            return conf.raw_layer
130770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        elif np < len(IKEv2_payload_type):
131770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            pt = IKEv2_payload_type[np]
132770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            logging.debug(globals().get("IKEv2_payload_%s" % pt, IKEv2_payload))
133770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            return globals().get("IKEv2_payload_%s" % pt, IKEv2_payload)
134770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        else:
135770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            return IKEv2_payload
136770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
137770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
138770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2(IKEv2_class): # rfc4306
139770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2"
140770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
141770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrFixedLenField("init_SPI","",8),
142770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrFixedLenField("resp_SPI","",8),
143770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",0,IKEv2_payload_type),
144770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        XByteField("version",0x20), # IKEv2, right?
145770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("exch_type",0,IKEv2_exchange_type),
146770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FlagsField("flags",0, 8, ["res0","res1","res2","Initiator","Version","Response","res6","res7"]),
147770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        IntField("id",0),
148770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        IntField("length",None)
149770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
150770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
151770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    def guess_payload_class(self, payload):
152770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        if self.flags & 1:
1537b3e970663abd72697e17b70aba9943ae0dad404Phil            return conf.raw_layer
154770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        return IKEv2_class.guess_payload_class(self, payload)
155770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
156770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    def answers(self, other):
157770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        if isinstance(other, IKEv2):
158770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            if other.init_SPI == self.init_SPI:
159770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                return 1
160770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        return 0
161770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    def post_build(self, p, pay):
162770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        p += pay
163770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        if self.length is None:
164770bb9f5f4acc0c59e3a200849c189d6616e2417Phil            p = p[:24]+struct.pack("!I",len(p))+p[28:]
165770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        return p
166770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
167770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
168770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_Key_Length_Attribute(IntField):
169770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	# We only support the fixed-length Key Length attribute (the only one currently defined)
170770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	name="key length"
171770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	def __init__(self, name):
172770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		IntField.__init__(self, name, "0x800E0000")
173770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
174770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	def i2h(self, pkt, x):
175770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		return IntField.i2h(self, pkt, x & 0xFFFF)
176770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
177770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	def h2i(self, pkt, x):
178770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		return IntField.h2i(self, pkt, struct.pack("!I", 0x800E0000 | int(x, 0)))
179770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
180770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
181770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_Transform_ID(ShortField):
182770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	def i2h(self, pkt, x):
183770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		if pkt == None:
184770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			return None
185770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		else:
186770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			map = IKEv2TransformNum[pkt.transform_type][1]
187770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			return map[x]
188770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
189770bb9f5f4acc0c59e3a200849c189d6616e2417Phil	def h2i(self, pkt, x):
190770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		if pkt == None:
191770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			return None
192770bb9f5f4acc0c59e3a200849c189d6616e2417Phil		else:
193770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			map = IKEv2TransformNum[pkt.transform_type][1]
194770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			for k in keys(map):
195770bb9f5f4acc0c59e3a200849c189d6616e2417Phil				if map[k] == x:
196770bb9f5f4acc0c59e3a200849c189d6616e2417Phil					return k
197770bb9f5f4acc0c59e3a200849c189d6616e2417Phil			return None
198770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
199770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Transform(IKEv2_class):
200770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKE Transform"
201770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
202770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,{0:"last", 3:"Transform"}),
203770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
204770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ShortField("length",8),
205770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("transform_type",None,IKEv2Transforms),
206770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res2",0),
207770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        IKEv2_Transform_ID("transform_id", 0),
208770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8),
209770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    ]
210770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
211770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Proposal(IKEv2_class):
212770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Proposal"
213770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
214770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,{0:"last", 2:"Proposal"}),
215770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
216770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
217770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("proposal",1),
218770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("proto",1,{1:"IKEv2"}),
219770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("SPIsize",None,"SPI","B"),
220770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("trans_nb",None),
221770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("SPI","",length_from=lambda x:x.SPIsize),
2227b3e970663abd72697e17b70aba9943ae0dad404Phil        PacketLenField("trans",conf.raw_layer(),IKEv2_payload_Transform,length_from=lambda x:x.length-8),
223770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
224770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
225770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
226770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload(IKEv2_class):
227770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Payload"
228770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
229770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
230770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FlagsField("flags",0, 8, ["critical","res1","res2","res3","res4","res5","res6","res7"]),
231770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
232770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-4),
233770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
234770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
235770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
236770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_VendorID(IKEv2_class):
237770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Vendor ID"
238770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":43 }}
239770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
240770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
241770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
242770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
243770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("vendorID","",length_from=lambda x:x.length-4),
244770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
245770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
246770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Delete(IKEv2_class):
247770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Vendor ID"
248770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":42 }}
249770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
250770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
251770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
252770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
253770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("vendorID","",length_from=lambda x:x.length-4),
254770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
255770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
256770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_SA(IKEv2_class):
257770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 SA"
258770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":33 }}
259770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
260770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
261770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
262770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+4),
2637b3e970663abd72697e17b70aba9943ae0dad404Phil        PacketLenField("prop",conf.raw_layer(),IKEv2_payload_Proposal,length_from=lambda x:x.length-4),
264770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
265770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
266770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Nonce(IKEv2_class):
267770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Nonce"
268770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":40 }}
269770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
270770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
271770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
272770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
273770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-4),
274770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
275770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
276770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Notify(IKEv2_class):
277770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Notify"
278770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":41 }}
279770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
280770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
281770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
282770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
283770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-4),
284770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
285770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
286770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_KE(IKEv2_class):
287770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Key Exchange"
288770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":34 }}
289770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
290770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
291770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
292770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+6),
293770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ShortEnumField("group", 0, IKEv2TransformTypes['GroupDesc'][1]),
294770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-6),
295770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
296770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
297770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_IDi(IKEv2_class):
298770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Identification - Initiator"
299770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":35 }}
300770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
301770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
302770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
303770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
304770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
305770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("ProtoID",0,{0:"Unused"}),
306770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ShortEnumField("Port",0,{0:"Unused"}),
307770bb9f5f4acc0c59e3a200849c189d6616e2417Phil#        IPField("IdentData","127.0.0.1"),
308770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-8),
309770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
310770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
311770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_IDr(IKEv2_class):
312770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Identification - Responder"
313770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":36 }}
314770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
315770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
316770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
317770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
318770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
319770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("ProtoID",0,{0:"Unused"}),
320770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ShortEnumField("Port",0,{0:"Unused"}),
321770bb9f5f4acc0c59e3a200849c189d6616e2417Phil#        IPField("IdentData","127.0.0.1"),
322770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-8),
323770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
324770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
325770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
326770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
327770bb9f5f4acc0c59e3a200849c189d6616e2417Philclass IKEv2_payload_Encrypted(IKEv2_class):
328770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2 Encrypted and Authenticated"
329770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    overload_fields = { IKEv2: { "next_payload":46 }}
330770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    fields_desc = [
331770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteEnumField("next_payload",None,IKEv2_payload_type),
332770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ByteField("res",0),
333770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
334770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        StrLenField("load","",length_from=lambda x:x.length-4),
335770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        ]
336770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
337770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
338770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
339770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_payload_type_overload = {}
340770bb9f5f4acc0c59e3a200849c189d6616e2417Philfor i in range(len(IKEv2_payload_type)):
341770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    name = "IKEv2_payload_%s" % IKEv2_payload_type[i]
342770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    if name in globals():
343770bb9f5f4acc0c59e3a200849c189d6616e2417Phil        IKEv2_payload_type_overload[globals()[name]] = {"next_payload":i}
344770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
345770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(i)
346770bb9f5f4acc0c59e3a200849c189d6616e2417Phildel(name)
347770bb9f5f4acc0c59e3a200849c189d6616e2417PhilIKEv2_class.overload_fields = IKEv2_payload_type_overload.copy()
348770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
349770bb9f5f4acc0c59e3a200849c189d6616e2417Philsplit_layers(UDP, ISAKMP, sport=500)
350770bb9f5f4acc0c59e3a200849c189d6616e2417Philsplit_layers(UDP, ISAKMP, dport=500)
351770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
352770bb9f5f4acc0c59e3a200849c189d6616e2417Philbind_layers( UDP,           IKEv2,        dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2
353770bb9f5f4acc0c59e3a200849c189d6616e2417Philbind_layers( UDP,           IKEv2,        dport=4500, sport=4500)
354770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
355770bb9f5f4acc0c59e3a200849c189d6616e2417Phildef ikev2scan(ip):
356770bb9f5f4acc0c59e3a200849c189d6616e2417Phil    return sr(IP(dst=ip)/UDP()/IKEv2(init_SPI=RandString(8),
357770bb9f5f4acc0c59e3a200849c189d6616e2417Phil                                      exch_type=34)/IKEv2_payload_SA(prop=IKEv2_payload_Proposal()))
358770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
359770bb9f5f4acc0c59e3a200849c189d6616e2417Phil# conf.debug_dissector = 1
360770bb9f5f4acc0c59e3a200849c189d6616e2417Phil
3615e2a4c735bd6211f5473df2b51e0558d318eeec6Philif __name__ == "__main__":
3625e2a4c735bd6211f5473df2b51e0558d318eeec6Phil    interact(mydict=globals(), mybanner="IKEv2 alpha-level protocol implementation")
363