Skip to content

Commit

Permalink
ikev2 contrib improvements (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
5hadawan authored and p-l- committed Sep 5, 2016
1 parent 1c7e836 commit 33420f2
Showing 1 changed file with 125 additions and 32 deletions.
157 changes: 125 additions & 32 deletions scapy/contrib/ikev2.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,96 @@
"ESN": 1, }, 0),
}

IKEv2NotifyMessageTypes = {
1 : "UNSUPPORTED_CRITICAL_PAYLOAD",
4 : "INVALID_IKE_SPI",
5 : "INVALID_MAJOR_VERSION",
7 : "INVALID_SYNTAX",
9 : "INVALID_MESSAGE_ID",
11 : "INVALID_SPI",
14 : "NO_PROPOSAL_CHOSEN",
17 : "INVALID_KE_PAYLOAD",
24 : "AUTHENTICATION_FAILED",
34 : "SINGLE_PAIR_REQUIRED",
35 : "NO_ADDITIONAL_SAS",
36 : "INTERNAL_ADDRESS_FAILURE",
37 : "FAILED_CP_REQUIRED",
38 : "TS_UNACCEPTABLE",
39 : "INVALID_SELECTORS",
40 : "UNACCEPTABLE_ADDRESSES",
41 : "UNEXPECTED_NAT_DETECTED",
42 : "USE_ASSIGNED_HoA",
43 : "TEMPORARY_FAILURE",
44 : "CHILD_SA_NOT_FOUND",
45 : "INVALID_GROUP_ID",
46 : "AUTHORIZATION_FAILED",
16384 : "INITIAL_CONTACT",
16385 : "SET_WINDOW_SIZE",
16386 : "ADDITIONAL_TS_POSSIBLE",
16387 : "IPCOMP_SUPPORTED",
16388 : "NAT_DETECTION_SOURCE_IP",
16389 : "NAT_DETECTION_DESTINATION_IP",
16390 : "COOKIE",
16391 : "USE_TRANSPORT_MODE",
16392 : "HTTP_CERT_LOOKUP_SUPPORTED",
16393 : "REKEY_SA",
16394 : "ESP_TFC_PADDING_NOT_SUPPORTED",
16395 : "NON_FIRST_FRAGMENTS_ALSO",
16396 : "MOBIKE_SUPPORTED",
16397 : "ADDITIONAL_IP4_ADDRESS",
16398 : "ADDITIONAL_IP6_ADDRESS",
16399 : "NO_ADDITIONAL_ADDRESSES",
16400 : "UPDATE_SA_ADDRESSES",
16401 : "COOKIE2",
16402 : "NO_NATS_ALLOWED",
16403 : "AUTH_LIFETIME",
16404 : "MULTIPLE_AUTH_SUPPORTED",
16405 : "ANOTHER_AUTH_FOLLOWS",
16406 : "REDIRECT_SUPPORTED",
16407 : "REDIRECT",
16408 : "REDIRECTED_FROM",
16409 : "TICKET_LT_OPAQUE",
16410 : "TICKET_REQUEST",
16411 : "TICKET_ACK",
16412 : "TICKET_NACK",
16413 : "TICKET_OPAQUE",
16414 : "LINK_ID",
16415 : "USE_WESP_MODE",
16416 : "ROHC_SUPPORTED",
16417 : "EAP_ONLY_AUTHENTICATION",
16418 : "CHILDLESS_IKEV2_SUPPORTED",
16419 : "QUICK_CRASH_DETECTION",
16420 : "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
16421 : "IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED",
16422 : "IKEV2_MESSAGE_ID_SYNC",
16423 : "IPSEC_REPLAY_COUNTER_SYNC",
16424 : "SECURE_PASSWORD_METHODS",
16425 : "PSK_PERSIST",
16426 : "PSK_CONFIRM",
16427 : "ERX_SUPPORTED",
16428 : "IFOM_CAPABILITY",
16429 : "SENDER_REQUEST_ID",
16430 : "IKEV2_FRAGMENTATION_SUPPORTED",
16431 : "SIGNATURE_HASH_ALGORITHMS",
16432 : "CLONE_IKE_SA_SUPPORTED",
16433 : "CLONE_IKE_SA"
}

IKEv2CertificateEncodings = {
1 : "PKCS #7 wrapped X.509 certificate",
2 : "PGP Certificate",
3 : "DNS Signed Key",
4 : "X.509 Certificate - Signature",
6 : "Kerberos Token",
7 : "Certificate Revocation List (CRL)",
8 : "Authority Revocation List (ARL)",
9 : "SPKI Certificate",
10 : "X.509 Certificate - Attribute",
11 : "Raw RSA Key",
12 : "Hash and URL of X.509 certificate",
13 : "Hash and URL of X.509 bundle"
}

# the name 'IKEv2TransformTypes' is actually a misnomer (since the table
# holds info for all IKEv2 Attribute types, not just transforms, but we'll
# keep it for backwards compatibility... for now at least
Expand All @@ -98,7 +188,7 @@
tmp = {}
for e in val[1]:
tmp[val[1][e]] = e
IKEv2TransformNum[val[0]] = (n,tmp, val[2])
IKEv2TransformNum[val[0]] = tmp

IKEv2Transforms = {}
for n in IKEv2TransformTypes:
Expand Down Expand Up @@ -166,35 +256,15 @@ def post_build(self, p, pay):


class IKEv2_Key_Length_Attribute(IntField):
# We only support the fixed-length Key Length attribute (the only
# one currently defined)
# We only support the fixed-length Key Length attribute (the only one currently defined)
def __init__(self, name):
IntField.__init__(self, name, "0x800E0000")

def i2h(self, pkt, x):
return IntField.i2h(self, pkt, x & 0xFFFF)

def h2i(self, pkt, x):
return IntField.h2i(self, pkt, struct.pack("!I", 0x800E0000 | int(x, 0)))
IntField.__init__(self, name, 0x800E0000)


class IKEv2_Transform_ID(ShortField):
def i2h(self, pkt, x):
if pkt == None:
return None
else:
map = IKEv2TransformNum[pkt.transform_type][1]
return map[x]
return IntField.i2h(self, pkt, x & 0xFFFF)

def h2i(self, pkt, x):
if pkt == None:
return None
else:
map = IKEv2TransformNum[pkt.transform_type][1]
for k in keys(map):
if map[k] == x:
return k
return None
return IntField.h2i(self, pkt, x if x !=None else 0 | 0x800E0000)

class IKEv2_payload_Transform(IKEv2_class):
name = "IKE Transform"
Expand All @@ -204,7 +274,7 @@ class IKEv2_payload_Transform(IKEv2_class):
ShortField("length",8),
ByteEnumField("transform_type",None,IKEv2Transforms),
ByteField("res2",0),
IKEv2_Transform_ID("transform_id", 0),
MultiEnumField("transform_id",None,IKEv2TransformNum,depends_on=lambda pkt:pkt.transform_type,fmt="H"),
ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8),
]

Expand Down Expand Up @@ -279,8 +349,12 @@ class IKEv2_payload_Notify(IKEv2_class):
fields_desc = [
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
StrLenField("load","",length_from=lambda x:x.length-4),
FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+8),
ByteEnumField("proto",None,{0:"Reserved",1:"IKE",2:"AH", 3:"ESP"}),
FieldLenField("SPIsize",None,"SPI","B"),
ShortEnumField("type",0,IKEv2NotifyMessageTypes),
StrLenField("SPI","",length_from=lambda x:x.SPIsize),
StrLenField("load","",length_from=lambda x:x.length-8),
]

class IKEv2_payload_KE(IKEv2_class):
Expand All @@ -289,9 +363,10 @@ class IKEv2_payload_KE(IKEv2_class):
fields_desc = [
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+6),
FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+8),
ShortEnumField("group", 0, IKEv2TransformTypes['GroupDesc'][1]),
StrLenField("load","",length_from=lambda x:x.length-6),
ShortField("res2", 0),
StrLenField("load","",length_from=lambda x:x.length-8),
]

class IKEv2_payload_IDi(IKEv2_class):
Expand All @@ -301,7 +376,7 @@ class IKEv2_payload_IDi(IKEv2_class):
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
ByteEnumField("IDtype",1,{1:"IPv4_addr", 2:"FQDN", 3:"Email_addr", 5:"IPv6_addr", 11:"Key"}),
ByteEnumField("ProtoID",0,{0:"Unused"}),
ShortEnumField("Port",0,{0:"Unused"}),
# IPField("IdentData","127.0.0.1"),
Expand All @@ -315,7 +390,7 @@ class IKEv2_payload_IDr(IKEv2_class):
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
ByteEnumField("IDtype",1,{1:"IPv4_addr", 2:"FQDN", 3:"Email_addr", 5:"IPv6_addr", 11:"Key"}),
ByteEnumField("ProtoID",0,{0:"Unused"}),
ShortEnumField("Port",0,{0:"Unused"}),
# IPField("IdentData","127.0.0.1"),
Expand All @@ -334,7 +409,25 @@ class IKEv2_payload_Encrypted(IKEv2_class):
StrLenField("load","",length_from=lambda x:x.length-4),
]

class IKEv2_payload_CERTREQ(IKEv2_class):
name = "IKEv2 Certificate Request"
fields_desc = [
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"cert_data","H",adjust=lambda pkt,x:x+5),
ByteEnumField("cert_type",0,IKEv2CertificateEncodings),
StrLenField("cert_data","",length_from=lambda x:x.length-5),
]

class IKEv2_payload_CERT(IKEv2_class):
name = "IKEv2 Certificate"
fields_desc = [
ByteEnumField("next_payload",None,IKEv2_payload_type),
ByteField("res",0),
FieldLenField("length",None,"cert_data","H",adjust=lambda pkt,x:x+5),
ByteEnumField("cert_type",0,IKEv2CertificateEncodings),
StrLenField("cert_data","",length_from=lambda x:x.length-5),
]

IKEv2_payload_type_overload = {}
for i, payloadname in enumerate(IKEv2_payload_type):
Expand Down

0 comments on commit 33420f2

Please sign in to comment.