2 * Routines for the Internet Security Association and Key Management Protocol
3 * (ISAKMP) (RFC 2408) and the Internet IP Security Domain of Interpretation
4 * for ISAKMP (RFC 2407)
5 * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
7 * Added routines for the Internet Key Exchange (IKEv2) Protocol
8 * (draft-ietf-ipsec-ikev2-17.txt)
9 * Shoichi Sakane <sakane@tanu.org>
11 * Added routines for RFC3947 Negotiation of NAT-Traversal in the IKE
14 * 04/2009 Added routines for decryption of IKEv2 Encrypted Payload
15 * Naoyoshi Ueda <piyomaru3141@gmail.com>
19 * Wireshark - Network traffic analyzer
20 * By Gerald Combs <gerald@wireshark.org>
21 * Copyright 1998 Gerald Combs
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 * IKEv2 http://www.ietf.org/rfc/rfc4306.txt?number=4306
39 * http://www.iana.org/assignments/ikev2-parameters
53 #include <epan/strutil.h>
54 #include <wsutil/file_util.h>
58 #include <epan/proto.h>
59 #include <epan/packet.h>
60 #include <epan/ipproto.h>
61 #include <epan/asn1.h>
62 #include <epan/reassemble.h>
63 #include <epan/dissectors/packet-x509if.h>
64 #include <epan/dissectors/packet-x509af.h>
65 #include <epan/dissectors/packet-isakmp.h>
66 #include <epan/prefs.h>
67 #include <epan/expert.h>
69 #define isakmp_min(a, b) ((a<b) ? a : b)
71 #define ARLEN(a) (sizeof(a)/sizeof(a[0]))
73 static int proto_isakmp = -1;
74 static int hf_isakmp_certificate_authority = -1;
75 static int hf_isakmp_v2_certificate_authority = -1;
76 static int hf_isakmp_nat_keepalive = -1;
77 static int hf_isakmp_nat_hash = -1;
78 static int hf_isakmp_nat_original_address_ipv6 = -1;
79 static int hf_isakmp_nat_original_address_ipv4 = -1;
81 static int hf_isakmp_icookie = -1;
82 static int hf_isakmp_rcookie = -1;
83 static int hf_isakmp_nextpayload = -1;
84 static int hf_isakmp_version = -1;
85 static int hf_isakmp_exchangetype = -1;
86 static int hf_isakmp_flags = -1;
87 static int hf_isakmp_flag_e = -1;
88 static int hf_isakmp_flag_c = -1;
89 static int hf_isakmp_flag_a = -1;
90 static int hf_isakmp_flag_i = -1;
91 static int hf_isakmp_flag_v = -1;
92 static int hf_isakmp_flag_r = -1;
93 static int hf_isakmp_messageid = -1;
94 static int hf_isakmp_length = -1;
95 static int hf_isakmp_payloadlen = -1;
96 static int hf_isakmp_doi = -1;
97 static int hf_isakmp_sa_situation = -1;
98 static int hf_isakmp_prop_number = -1;
99 static int hf_isakmp_spisize = -1;
100 static int hf_isakmp_prop_transforms = -1;
101 static int hf_isakmp_trans_number = -1;
102 static int hf_isakmp_trans_id = -1;
103 static int hf_isakmp_id_type_v1 = -1;
104 static int hf_isakmp_id_type_v2 = -1;
105 static int hf_isakmp_protoid = -1;
106 static int hf_isakmp_id_port = -1;
107 static int hf_isakmp_cert_encoding = -1;
108 static int hf_isakmp_certreq_type = -1;
109 static int hf_isakmp_certificate = -1;
110 static int hf_isakmp_notify_msgtype = -1;
111 static int hf_isakmp_num_spis = -1;
113 static int hf_isakmp_fragments = -1;
114 static int hf_isakmp_fragment = -1;
115 static int hf_isakmp_fragment_overlap = -1;
116 static int hf_isakmp_fragment_overlap_conflicts = -1;
117 static int hf_isakmp_fragment_multiple_tails = -1;
118 static int hf_isakmp_fragment_too_long_fragment = -1;
119 static int hf_isakmp_fragment_error = -1;
120 static int hf_isakmp_reassembled_in = -1;
121 static int hf_isakmp_reassembled_length = -1;
123 static int hf_isakmp_cisco_frag_packetid = -1;
124 static int hf_isakmp_cisco_frag_seq = -1;
125 static int hf_isakmp_cisco_frag_last = -1;
127 static int hf_isakmp_cfg_type_v1 = -1;
128 static int hf_isakmp_cfg_identifier = -1;
129 static int hf_isakmp_cfg_type_v2 = -1;
130 static int hf_isakmp_cfg_attr_type_v1 = -1;
131 static int hf_isakmp_cfg_attr_type_v2 = -1;
132 static int hf_isakmp_cfg_attr_length = -1;
133 static int hf_isakmp_cfg_attr_value = -1;
135 static int hf_isakmp_cfg_attr_internal_ip4_address = -1;
136 static int hf_isakmp_cfg_attr_internal_ip4_netmask = -1;
137 static int hf_isakmp_cfg_attr_internal_ip4_dns = -1;
138 static int hf_isakmp_cfg_attr_internal_ip4_nbns = -1;
139 static int hf_isakmp_cfg_attr_internal_address_expiry = -1;
140 static int hf_isakmp_cfg_attr_internal_ip4_dhcp = -1;
141 static int hf_isakmp_cfg_attr_application_version = -1;
142 static int hf_isakmp_cfg_attr_internal_ip6_address = -1;
143 static int hf_isakmp_cfg_attr_internal_ip6_netmask = -1;
144 static int hf_isakmp_cfg_attr_internal_ip6_dns = -1;
145 static int hf_isakmp_cfg_attr_internal_ip6_nbns = -1;
146 static int hf_isakmp_cfg_attr_internal_ip6_dhcp = -1;
147 static int hf_isakmp_cfg_attr_internal_ip4_subnet_ip = -1;
148 static int hf_isakmp_cfg_attr_internal_ip4_subnet_netmask = -1;
149 static int hf_isakmp_cfg_attr_xauth_type = -1;
150 static int hf_isakmp_cfg_attr_xauth_user_name = -1;
151 static int hf_isakmp_cfg_attr_xauth_user_password = -1;
152 static int hf_isakmp_cfg_attr_xauth_passcode = -1;
153 static int hf_isakmp_cfg_attr_xauth_message = -1;
154 static int hf_isakmp_cfg_attr_xauth_challenge = -1;
155 static int hf_isakmp_cfg_attr_xauth_domain = -1;
156 static int hf_isakmp_cfg_attr_xauth_status = -1;
157 static int hf_isakmp_cfg_attr_xauth_next_pin = -1;
158 static int hf_isakmp_cfg_attr_xauth_answer = -1;
159 static int hf_isakmp_cfg_attr_unity_banner = -1;
161 static gint ett_isakmp = -1;
162 static gint ett_isakmp_flags = -1;
163 static gint ett_isakmp_payload = -1;
164 static gint ett_isakmp_fragment = -1;
165 static gint ett_isakmp_fragments = -1;
166 static gint ett_isakmp_cfg_attr = -1;
167 #ifdef HAVE_LIBGCRYPT
168 /* For decrypted IKEv2 Encrypted payload*/
169 static gint ett_isakmp_decrypted_data = -1;
170 static gint ett_isakmp_decrypted_payloads = -1;
171 #endif /* HAVE_LIBGCRYPT */
173 static dissector_handle_t eap_handle = NULL;
175 static GHashTable *isakmp_fragment_table = NULL;
176 static GHashTable *isakmp_reassembled_table = NULL;
178 static const fragment_items isakmp_frag_items = {
179 /* Fragment subtrees */
180 &ett_isakmp_fragment,
181 &ett_isakmp_fragments,
182 /* Fragment fields */
183 &hf_isakmp_fragments,
185 &hf_isakmp_fragment_overlap,
186 &hf_isakmp_fragment_overlap_conflicts,
187 &hf_isakmp_fragment_multiple_tails,
188 &hf_isakmp_fragment_too_long_fragment,
189 &hf_isakmp_fragment_error,
190 /* Reassembled in field */
191 &hf_isakmp_reassembled_in,
192 /* Reassembled length field */
193 &hf_isakmp_reassembled_length,
197 /* IKE port number assigned by IANA */
198 #define UDP_PORT_ISAKMP 500
199 #define TCP_PORT_ISAKMP 500
204 * RFC3554 for ID_LIST
206 * RFC4595 for ID_FC_NAME
208 #define IKE_ID_IPV4_ADDR 1
209 #define IKE_ID_FQDN 2
210 #define IKE_ID_USER_FQDN 3
211 #define IKE_ID_IPV4_ADDR_SUBNET 4
212 #define IKE_ID_IPV6_ADDR 5
213 #define IKE_ID_IPV6_ADDR_SUBNET 6
214 #define IKE_ID_IPV4_ADDR_RANGE 7
215 #define IKE_ID_IPV6_ADDR_RANGE 8
216 #define IKE_ID_DER_ASN1_DN 9
217 #define IKE_ID_DER_ASN1_GN 10
218 #define IKE_ID_KEY_ID 11
219 #define IKE_ID_LIST 12
220 #define IKE_ID_FC_NAME 12
221 #define IKE_ID_RFC822_ADDR 3
223 * Traffic Selector Type
224 * Not in use for IKEv1
226 #define IKEV2_TS_IPV4_ADDR_RANGE 7
227 #define IKEV2_TS_IPV6_ADDR_RANGE 8
230 * Configuration Payload Attribute Types
231 * draft-ietf-ipsec-isakmp-mode-cfg-05.txt for IKEv1
232 * draft-ietf-ipsec-isakmp-xauth-06.txt and draft-beaulieu-ike-xauth-02.txt for XAUTH
234 * RFC-ietf-ipsecme-ikev2-ipv6-config-03.txt for INTERNAL_IP6_LINK and INTERNAL_IP6_PREFIX
236 #define INTERNAL_IP4_ADDRESS 1
237 #define INTERNAL_IP4_NETMASK 2
238 #define INTERNAL_IP4_DNS 3
239 #define INTERNAL_IP4_NBNS 4
240 #define INTERNAL_ADDRESS_EXPIRY 5
241 #define INTERNAL_IP4_DHCP 6
242 #define APPLICATION_VERSION 7
243 #define INTERNAL_IP6_ADDRESS 8
244 #define INTERNAL_IP6_NETMASK 9
245 #define INTERNAL_IP6_DNS 10
246 #define INTERNAL_IP6_NBNS 11
247 #define INTERNAL_IP6_DHCP 12
248 #define INTERNAL_IP4_SUBNET 13
249 #define SUPPORTED_ATTRIBUTES 14
250 #define INTERNAL_IP6_SUBNET 15
251 #define MIP6_HOME_PREFIX 16
252 #define INTERNAL_IP6_LINK 17
253 #define INTERNAL_IP6_PREFIX 18
254 /* checkpoint configuration attributes */
255 #define CHKPT_DEF_DOMAIN 16387
256 #define CHKPT_MAC_ADDRESS 16388
257 #define CHKPT_MARCIPAN_REASON_CODE 16389
258 #define CHKPT_UNKNOWN1 16400
259 #define CHKPT_UNKNOWN2 16401
260 #define CHKPT_UNKNOWN3 16402
261 /* XAUTH configuration attributes */
262 #define XAUTH_TYPE 16520
263 #define XAUTH_USER_NAME 16521
264 #define XAUTH_USER_PASSWORD 16522
265 #define XAUTH_PASSCODE 16523
266 #define XAUTH_MESSAGE 16524
267 #define XAUTH_CHALLENGE 16525
268 #define XAUTH_DOMAIN 16526
269 #define XAUTH_STATUS 16527
270 #define XAUTH_NEXT_PIN 16528
271 #define XAUTH_ANSWER 16529
272 /* unity (CISCO) configuration attributes */
273 #define UNITY_BANNER 28672
274 #define UNITY_SAVE_PASSWD 28673
275 #define UNITY_DEF_DOMAIN 28674
276 #define UNITY_SPLIT_DOMAIN 28675
277 #define UNITY_SPLIT_INCLUDE 28676
278 #define UNITY_NATT_PORT 28677
279 #define UNITY_SPLIT_EXCLUDE 28678
280 #define UNITY_PFS 28679
281 #define UNITY_FW_TYPE 28680
282 #define UNITY_BACKUP_SERVERS 28681
283 #define UNITY_DDNS_HOSTNAME 28682
285 static const value_string frag_last_vals[] = {
286 { 0, "More fragments" },
287 { 1, "Last fragment" },
291 static const value_string vs_proto[] = {
300 static const range_string vs_v1_cfgtype[] = {
302 { 1,1, "ISAKMP_CFG_REQUEST" },
303 { 2,2, "ISAKMP_CFG_REPLY" },
304 { 3,3, "ISAKMP_CFG_SET" },
305 { 4,4, "ISAKMP_CFG_ACK" },
306 { 5,127, "Future use" },
307 { 128,256, "Private Use" },
312 static const range_string vs_v2_cfgtype[] = {
314 { 1,1, "CFG_REQUEST" },
315 { 2,2, "CFG_REPLY" },
318 { 5,127, "Future use" },
319 { 128,256, "Private Use" },
323 static const range_string vs_v1_cfgattr[] = {
325 { 1,1, "INTERNAL_IP4_ADDRESS" },
326 { 2,2, "INTERNAL_IP4_NETMASK" },
327 { 3,3, "INTERNAL_IP4_DNS" },
328 { 4,4, "INTERNAL_IP4_NBNS" },
329 { 5,5, "INTERNAL_ADDRESS_EXPIREY" },
330 { 6,6, "INTERNAL_IP4_DHCP" },
331 { 7,7, "APPLICATION_VERSION" },
332 { 8,8, "INTERNAL_IP6_ADDRESS" },
333 { 9,9, "INTERNAL_IP6_NETMASK" },
334 { 10,10, "INTERNAL_IP6_DNS" },
335 { 11,11, "INTERNAL_IP6_NBNS" },
336 { 12,12, "INTERNAL_IP6_DHCP" },
337 { 13,13, "INTERNAL_IP4_SUBNET" },
338 { 14,14, "SUPPORTED_ATTRIBUTES" },
339 { 15,16383, "FUTURE USE"},
340 { 16384,16386, "PRIVATE USE"},
341 { 16387,16387, "CHKPT_DEF_DOMAIN" },
342 { 16388,16388, "CHKPT_MAC_ADDRESS" },
343 { 16389,16389, "CHKPT_MARCIPAN_REASON_CODE" },
344 { 16400,16400, "CHKPT_UNKNOWN1" },
345 { 16401,16401, "CHKPT_UNKNOWN2" },
346 { 16402,16402, "CHKPT_UNKNOWN3" },
347 { 16403,16519, "PRIVATE USE"},
348 { 16520,16520, "XAUTH_TYPE" },
349 { 16521,16521, "XAUTH_USER_NAME" },
350 { 16522,16522, "XAUTH_USER_PASSWORD" },
351 { 16523,16523, "XAUTH_PASSCODE" },
352 { 16524,16524, "XAUTH_MESSAGE" },
353 { 16525,16525, "XAUTH_CHALLANGE" },
354 { 16526,16526, "XAUTH_DOMAIN" },
355 { 16527,16527, "XAUTH_STATUS" },
356 { 16528,16528, "XAUTH_NEXT_PIN" },
357 { 16529,16529, "XAUTH_ANSWER" },
358 { 16530,28671, "PRIVATE USE"},
359 { 28672,28672, "UNITY_BANNER" },
360 { 28673,28673, "UNITY_SAVE_PASSWD" },
361 { 28674,28674, "UNITY_DEF_DOMAIN" },
362 { 28675,28675, "UNITY_SPLIT_DOMAIN" },
363 { 28676,28676, "UNITY_SPLIT_INCLUDE" },
364 { 28677,28677, "UNITY_NATT_PORT" },
365 { 28678,28678, "UNITY_SPLIT_EXCLUDE" },
366 { 28679,28679, "UNITY_PFS" },
367 { 28680,28680, "UNITY_FW_TYPE" },
368 { 28681,28681, "UNITY_BACKUP_SERVERS" },
369 { 28682,28682, "UNITY_DDNS_HOSTNAME" },
370 { 28683,32767, "PRIVATE USE"},
374 static const range_string vs_v2_cfgattr[] = {
376 { 1,1, "INTERNAL_IP4_ADDRESS" },
377 { 2,2, "INTERNAL_IP4_NETMASK" },
378 { 3,3, "INTERNAL_IP4_DNS" },
379 { 4,4, "INTERNAL_IP4_NBNS" },
380 { 5,5, "INTERNAL_ADDRESS_EXPIREY" },
381 { 6,6, "INTERNAL_IP4_DHCP" },
382 { 7,7, "APPLICATION_VERSION" },
383 { 8,8, "INTERNAL_IP6_ADDRESS" },
385 { 10,10, "INTERNAL_IP6_DNS" },
386 { 11,11, "INTERNAL_IP6_NBNS" },
387 { 12,12, "INTERNAL_IP6_DHCP" },
388 { 13,13, "INTERNAL_IP4_SUBNET" },
389 { 14,14, "SUPPORTED_ATTRIBUTES" },
390 { 15,15, "INTERNAL_IP6_SUBNET" },
391 { 16,16, "MIP6_HOME_PREFIX" },
392 { 17,17, "INTERNAL_IP6_LINK" },
393 { 18,18, "INTERNAL_IP6_PREFIX" },
394 { 19,16383, "RESERVED TO IANA"},
395 { 16384,32767, "PRIVATE USE"},
399 static const range_string cfgattr_xauth_type[] = {
401 { 1,1, "RADIUS-CHAP" },
404 { 4,32767, "Future use" },
405 { 32768,65535, "Private use" },
409 static const value_string cfgattr_xauth_status[] = {
415 static const range_string vs_v1_id_type[] = {
417 { IKE_ID_IPV4_ADDR,IKE_ID_IPV4_ADDR, "IPV4_ADDR" },
418 { IKE_ID_FQDN,IKE_ID_FQDN, "FQDN" },
419 { IKE_ID_USER_FQDN,IKE_ID_USER_FQDN, "USER_FQDN" },
420 { IKE_ID_IPV4_ADDR_SUBNET,IKE_ID_IPV4_ADDR_SUBNET, "IPV4_ADDR_SUBNET" },
421 { IKE_ID_IPV6_ADDR,IKE_ID_IPV6_ADDR, "IPV6_ADDR" },
422 { IKE_ID_IPV6_ADDR_SUBNET,IKE_ID_IPV6_ADDR_SUBNET, "IPV6_ADDR_SUBNET" },
423 { IKE_ID_IPV4_ADDR_RANGE,IKE_ID_IPV4_ADDR_RANGE, "IPV4_ADDR_RANGE" },
424 { IKE_ID_IPV6_ADDR_RANGE,IKE_ID_IPV6_ADDR_RANGE, "IPV6_ADDR_RANGE" },
425 { IKE_ID_DER_ASN1_DN,IKE_ID_DER_ASN1_DN, "DER_ASN1_DN" },
426 { IKE_ID_DER_ASN1_GN,IKE_ID_DER_ASN1_GN, "DER_ASN1_GN" },
427 { IKE_ID_KEY_ID,IKE_ID_KEY_ID, "KEY_ID" },
428 { IKE_ID_LIST,IKE_ID_LIST, "KEY_LIST" },
429 { 13,248, "Future use" },
430 { 249,255, "Private Use" },
433 static const range_string vs_v2_id_type[] = {
435 { IKE_ID_IPV4_ADDR,IKE_ID_IPV4_ADDR, "IPV4_ADDR" },
436 { IKE_ID_FQDN,IKE_ID_FQDN, "FQDN" },
437 { IKE_ID_RFC822_ADDR,IKE_ID_RFC822_ADDR, "ID_RFC822_ADDR" },
438 { 4,4, "Unassigned" },
439 { IKE_ID_IPV6_ADDR,IKE_ID_IPV6_ADDR, "IPV6_ADDR" },
440 { 6,8, "Unassigned" },
441 { IKE_ID_DER_ASN1_DN,IKE_ID_DER_ASN1_DN, "DER_ASN1_DN" },
442 { IKE_ID_DER_ASN1_GN,IKE_ID_DER_ASN1_GN, "DER_ASN1_GN" },
443 { IKE_ID_KEY_ID,IKE_ID_KEY_ID, "KEY_ID" },
444 { IKE_ID_FC_NAME,IKE_ID_FC_NAME, "KEY_LIST" },
445 { 13,200, "Future use" },
446 { 201,255, "Private Use" },
449 #define COOKIE_SIZE 8
451 typedef struct isakmp_hdr {
466 static const true_false_string flag_e = {
470 static const true_false_string flag_c = {
474 static const true_false_string flag_a = {
478 static const true_false_string flag_i = {
482 static const true_false_string flag_v = {
483 "A higher version enabled",
486 static const true_false_string flag_r = {
491 #define ISAKMP_HDR_SIZE (sizeof(struct isakmp_hdr) + (2 * COOKIE_SIZE))
493 #define ENC_DES_CBC 1
494 #define ENC_IDEA_CBC 2
495 #define ENC_BLOWFISH_CBC 3
496 #define ENC_RC5_R16_B64_CBC 4
497 #define ENC_3DES_CBC 5
498 #define ENC_CAST_CBC 6
499 #define ENC_AES_CBC 7
504 #define HMAC_SHA2_256 4
505 #define HMAC_SHA2_384 5
506 #define HMAC_SHA2_512 6
508 #ifdef HAVE_LIBGCRYPT
511 #define AGGRESSIVE_MODE 4
512 #define MAX_KEY_SIZE 256
513 #define MAX_DIGEST_SIZE 64
514 #define MAX_OAKLEY_KEY_LEN 32
516 typedef struct decrypt_key {
517 guchar secret[MAX_KEY_SIZE];
521 typedef struct iv_data {
522 guchar iv[MAX_DIGEST_SIZE];
527 typedef struct decrypt_data {
537 guchar secret[MAX_KEY_SIZE];
540 gchar last_cbc[MAX_DIGEST_SIZE];
542 gchar last_p1_cbc[MAX_DIGEST_SIZE];
543 guint last_p1_cbc_len;
544 guint32 last_message_id;
547 static GHashTable *isakmp_hash = NULL;
548 #if GLIB_CHECK_VERSION(2,10,0)
550 static GMemChunk *isakmp_key_data = NULL;
551 static GMemChunk *isakmp_decrypt_data = NULL;
553 static FILE *log_f = NULL;
554 static const char *pluto_log_path = "insert pluto log path here";
556 /* Specifications of encryption algorithms for IKEv2 decryption */
557 typedef struct _ikev2_encr_alg_spec {
559 /* Length of encryption key */
561 /* Block size of the cipher */
563 /* Length of initialization vector */
565 /* Encryption algorithm ID to be passed to gcry_cipher_open() */
567 /* Cipher mode to be passed to gcry_cipher_open() */
569 } ikev2_encr_alg_spec_t;
571 #define IKEV2_ENCR_NULL 1
572 #define IKEV2_ENCR_3DES 2
573 #define IKEV2_ENCR_AES_CBC_128 3
574 #define IKEV2_ENCR_AES_CBC_192 4
575 #define IKEV2_ENCR_AES_CBC_256 5
577 static ikev2_encr_alg_spec_t ikev2_encr_algs[] = {
578 {IKEV2_ENCR_NULL, 0, 1, 0, GCRY_CIPHER_NONE, GCRY_CIPHER_MODE_NONE},
579 {IKEV2_ENCR_3DES, 24, 8, 8, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC},
580 {IKEV2_ENCR_AES_CBC_128, 16, 16, 16, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC},
581 {IKEV2_ENCR_AES_CBC_192, 24, 16, 16, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC},
582 {IKEV2_ENCR_AES_CBC_256, 32, 16, 16, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC},
587 * Specifications of authentication algorithms for
588 * decryption and/or ICD (Integrity Checksum Data) checking of IKEv2
590 typedef struct _ikev2_auth_alg_spec {
592 /* Output length of the hash algorithm */
594 /* Length of the hash key */
596 /* Actual ICD length after truncation */
598 /* Hash algorithm ID to be passed to gcry_md_open() */
600 /* Flags to be passed to gcry_md_open() */
602 } ikev2_auth_alg_spec_t;
604 #define IKEV2_AUTH_NONE 1
605 #define IKEV2_AUTH_HMAC_MD5_96 2
606 #define IKEV2_AUTH_HMAC_SHA1_96 3
607 #define IKEV2_AUTH_ANY_96BITS 4
608 #define IKEV2_AUTH_ANY_128BITS 5
609 #define IKEV2_AUTH_ANY_160BITS 6
610 #define IKEV2_AUTH_ANY_192BITS 7
611 #define IKEV2_AUTH_ANY_256BITS 8
613 static ikev2_auth_alg_spec_t ikev2_auth_algs[] = {
614 {IKEV2_AUTH_NONE, 0, 0, 0, GCRY_MD_NONE, 0},
615 {IKEV2_AUTH_HMAC_MD5_96, 16, 16, 12, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC},
616 {IKEV2_AUTH_HMAC_SHA1_96, 20, 20, 12, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC},
617 {IKEV2_AUTH_ANY_96BITS, 0, 0, 12, 0, 0},
618 {IKEV2_AUTH_ANY_128BITS, 0, 0, 16, 0, 0},
619 {IKEV2_AUTH_ANY_160BITS, 0, 0, 20, 0, 0},
620 {IKEV2_AUTH_ANY_192BITS, 0, 0, 24, 0, 0},
621 {IKEV2_AUTH_ANY_256BITS, 0, 0, 32, 0, 0},
625 typedef struct _ikev2_decrypt_data {
628 ikev2_encr_alg_spec_t *encr_spec;
629 ikev2_auth_alg_spec_t *auth_spec;
630 } ikev2_decrypt_data_t;
632 typedef struct _ikev2_uat_data_key {
637 } ikev2_uat_data_key_t;
639 typedef struct _ikev2_uat_data {
640 ikev2_uat_data_key_t key;
651 ikev2_encr_alg_spec_t *encr_spec;
652 ikev2_auth_alg_spec_t *auth_spec;
655 static ikev2_uat_data_t* ikev2_uat_data = NULL;
656 static guint num_ikev2_uat_data = 0;
657 static uat_t* ikev2_uat;
659 static GHashTable *ikev2_key_hash = NULL;
661 #define IKEV2_ENCR_3DES_STR "3DES [RFC2451]"
662 static const value_string vs_ikev2_encr_algs[] = {
663 {IKEV2_ENCR_3DES, IKEV2_ENCR_3DES_STR},
664 {IKEV2_ENCR_AES_CBC_128, "AES-CBC-128 [RFC3602]"},
665 {IKEV2_ENCR_AES_CBC_192, "AES-CBC-192 [RFC3602]"},
666 {IKEV2_ENCR_AES_CBC_256, "AES-CBC-256 [RFC3602]"},
667 {IKEV2_ENCR_NULL, "NULL [RFC2410]"},
671 #define IKEV2_AUTH_HMAC_SHA1_96_STR "HMAC_SHA1_96 [RFC2404]"
672 static const value_string vs_ikev2_auth_algs[] = {
673 {IKEV2_AUTH_HMAC_MD5_96, "HMAC_MD5_96 [RFC2403]"},
674 {IKEV2_AUTH_HMAC_SHA1_96, IKEV2_AUTH_HMAC_SHA1_96_STR},
675 {IKEV2_AUTH_NONE, "NONE [RFC4306]"},
676 {IKEV2_AUTH_ANY_96BITS, "ANY 96-bits of Authentication [No Checking]"},
677 {IKEV2_AUTH_ANY_128BITS, "ANY 128-bits of Authentication [No Checking]"},
678 {IKEV2_AUTH_ANY_160BITS, "ANY 160-bits of Authentication [No Checking]"},
679 {IKEV2_AUTH_ANY_192BITS, "ANY 192-bits of Authentication [No Checking]"},
680 {IKEV2_AUTH_ANY_256BITS, "ANY 256-bits of Authentication [No Checking]"},
684 ikev2_encr_alg_spec_t* ikev2_decrypt_find_encr_spec(guint num) {
685 ikev2_encr_alg_spec_t *e;
687 for (e = ikev2_encr_algs; e->number != 0; e++) {
688 if (e->number == num) {
695 ikev2_auth_alg_spec_t* ikev2_decrypt_find_auth_spec(guint num) {
696 ikev2_auth_alg_spec_t *a;
698 for (a = ikev2_auth_algs; a->number != 0; a++) {
699 if (a->number == num) {
707 scan_pluto_log(void) {
708 #define MAX_PLUTO_LINE 500
709 decrypt_data_t *decr;
710 gchar line[MAX_PLUTO_LINE];
711 guint8 i_cookie[COOKIE_SIZE], *ic_key;
712 gboolean got_cookie = FALSE;
713 guchar secret[MAX_KEY_SIZE];
714 guint secret_len = 0;
715 gchar *icookie_pfx = "| ICOOKIE: ";
716 gchar *enc_key_pfx = "| enc key: ";
718 gint icpfx_len = (gint) strlen(icookie_pfx);
719 gint ec_len = (gint) strlen(enc_key_pfx);
722 unsigned long hexval;
724 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
727 while (fgets(line, MAX_PLUTO_LINE, log_f)) {
728 if (strncmp(line, icookie_pfx, icpfx_len) == 0) {
730 pos = line + icpfx_len;
731 for (i = 0; i < COOKIE_SIZE; i++) {
732 hexval = strtoul(pos, &endpos, 16);
735 i_cookie[i] = (guint8) hexval;
738 if (i == COOKIE_SIZE)
740 } else if (strncmp(line, enc_key_pfx, ec_len) == 0) {
742 for (; secret_len < MAX_KEY_SIZE; secret_len++) {
743 hexval = strtoul(pos, &endpos, 16);
746 secret[secret_len] = (guint8) hexval;
749 } else if (got_cookie && secret_len > 1) {
750 decr = (decrypt_data_t*) g_hash_table_lookup(isakmp_hash, i_cookie);
753 #if GLIB_CHECK_VERSION(2,10,0)
754 ic_key = g_slice_alloc(COOKIE_SIZE);
755 decr = g_slice_alloc(sizeof(decrypt_data_t));
757 ic_key = g_mem_chunk_alloc(isakmp_key_data);
758 decr = g_mem_chunk_alloc(isakmp_decrypt_data);
760 memcpy(ic_key, i_cookie, COOKIE_SIZE);
761 memset(decr, 0, sizeof(decrypt_data_t));
763 g_hash_table_insert(isakmp_hash, ic_key, decr);
766 memcpy(decr->secret, secret, secret_len);
767 decr->secret_len = secret_len;
774 set_transform_vals(decrypt_data_t *decr, int ike_p1, guint16 type, guint32 val) {
781 decr->encr_alg = val;
784 decr->hash_alg = val;
798 decrypt_payload(tvbuff_t *tvb, packet_info *pinfo, const guint8 *buf, guint buf_len, isakmp_hdr_t *hdr) {
799 decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
800 gchar *decrypted_data = NULL;
801 gint gcry_md_algo, gcry_cipher_algo;
803 gcry_cipher_hd_t decr_ctx;
805 iv_data_t *ivd = NULL;
807 guchar iv[MAX_DIGEST_SIZE];
809 guint32 message_id, cbc_block_size, digest_size;
812 decr->is_psk == FALSE ||
817 switch(decr->encr_alg) {
819 gcry_cipher_algo = GCRY_CIPHER_3DES;
822 gcry_cipher_algo = GCRY_CIPHER_DES;
828 if (decr->secret_len < gcry_cipher_get_algo_keylen(gcry_cipher_algo))
830 cbc_block_size = (guint32) gcry_cipher_get_algo_blklen(gcry_cipher_algo);
832 switch(decr->hash_alg) {
834 gcry_md_algo = GCRY_MD_MD5;
837 gcry_md_algo = GCRY_MD_SHA1;
843 digest_size = gcry_md_get_algo_dlen(gcry_md_algo);
845 for (ivl = g_list_first(decr->iv_list); ivl != NULL; ivl = g_list_next(ivl)) {
846 ivd = (iv_data_t *) ivl->data;
847 if (ivd->frame_num == pinfo->fd->num) {
848 iv_len = ivd->iv_len;
849 memcpy(iv, ivd->iv, iv_len);
854 * Set our initialization vector as follows:
855 * - If the IV list is empty, assume we have the first packet in a phase 1
856 * exchange. The IV is built from DH values.
857 * - If our message ID changes, assume we're entering a new mode. The IV
858 * is built from the message ID and the last phase 1 CBC.
859 * - Otherwise, use the last CBC.
862 if (gcry_md_open(&md_ctx, gcry_md_algo, 0) != GPG_ERR_NO_ERROR)
864 if (decr->iv_list == NULL) {
866 ivd = g_malloc(sizeof(iv_data_t));
867 ivd->frame_num = pinfo->fd->num;
868 ivd->iv_len = digest_size;
869 decr->last_message_id = hdr->message_id;
870 gcry_md_reset(md_ctx);
871 gcry_md_write(md_ctx, decr->gi, decr->gi_len);
872 gcry_md_write(md_ctx, decr->gr, decr->gr_len);
873 gcry_md_final(md_ctx);
874 memcpy(ivd->iv, gcry_md_read(md_ctx, gcry_md_algo), digest_size);
875 decr->iv_list = g_list_append(decr->iv_list, ivd);
876 iv_len = ivd->iv_len;
877 memcpy(iv, ivd->iv, iv_len);
878 } else if (decr->last_cbc_len >= cbc_block_size) {
879 ivd = g_malloc(sizeof(iv_data_t));
880 ivd->frame_num = pinfo->fd->num;
881 if (hdr->message_id != decr->last_message_id) {
882 if (decr->last_p1_cbc_len == 0) {
883 memcpy(decr->last_p1_cbc, decr->last_cbc, cbc_block_size);
884 decr->last_p1_cbc_len = cbc_block_size;
886 ivd->iv_len = digest_size;
887 decr->last_message_id = hdr->message_id;
888 message_id = g_htonl(decr->last_message_id);
889 gcry_md_reset(md_ctx);
890 gcry_md_write(md_ctx, decr->last_p1_cbc, cbc_block_size);
891 gcry_md_write(md_ctx, &message_id, sizeof(message_id));
892 memcpy(ivd->iv, gcry_md_read(md_ctx, gcry_md_algo), digest_size);
894 ivd->iv_len = cbc_block_size;
895 memcpy(ivd->iv, decr->last_cbc, ivd->iv_len);
897 decr->iv_list = g_list_append(decr->iv_list, ivd);
898 iv_len = ivd->iv_len;
899 memcpy(iv, ivd->iv, iv_len);
901 gcry_md_close(md_ctx);
904 if (ivd == NULL) return NULL;
906 if (gcry_cipher_open(&decr_ctx, gcry_cipher_algo, GCRY_CIPHER_MODE_CBC, 0) != GPG_ERR_NO_ERROR)
908 if (iv_len > cbc_block_size)
909 iv_len = cbc_block_size; /* gcry warns otherwise */
910 if (gcry_cipher_setiv(decr_ctx, iv, iv_len))
912 if (gcry_cipher_setkey(decr_ctx, decr->secret, decr->secret_len))
915 decrypted_data = g_malloc(buf_len);
917 if (gcry_cipher_decrypt(decr_ctx, decrypted_data, buf_len, buf, buf_len) != GPG_ERR_NO_ERROR) {
918 g_free(decrypted_data);
921 gcry_cipher_close(decr_ctx);
923 encr_tvb = tvb_new_child_real_data(tvb, decrypted_data, buf_len, buf_len);
925 /* Add the decrypted data to the data source list. */
926 add_new_data_source(pinfo, encr_tvb, "Decrypted IKE");
928 /* Fill in the next IV */
929 if (tvb_length(tvb) > cbc_block_size) {
930 decr->last_cbc_len = cbc_block_size;
931 memcpy(decr->last_cbc, buf + buf_len - cbc_block_size, cbc_block_size);
933 decr->last_cbc_len = 0;
939 #endif /* HAVE_LIBGCRYPT */
941 static const char* vid_to_str(tvbuff_t *, int, int);
942 static proto_tree *dissect_payload_header(tvbuff_t *, int, int, int, guint8,
943 guint8 *, guint16 *, proto_tree *);
945 static void dissect_sa(tvbuff_t *, int, int, proto_tree *,
946 proto_tree *, packet_info *, int, int, guint8);
947 static void dissect_proposal(tvbuff_t *, int, int, proto_tree *,
948 proto_tree *, packet_info *, int, int, guint8);
949 static void dissect_transform(tvbuff_t *, int, int, proto_tree *,
950 proto_tree *, packet_info *, int, int, guint8);
951 static void dissect_transform2(tvbuff_t *, int, int, proto_tree *,
952 proto_tree *, packet_info *, int, int, guint8);
953 static void dissect_key_exch(tvbuff_t *, int, int, proto_tree *,
954 proto_tree *, packet_info *, int, int, guint8);
955 static void dissect_id(tvbuff_t *, int, int, proto_tree *,
956 proto_tree *, packet_info *, int, int, guint8);
957 static void dissect_cert(tvbuff_t *, int, int, proto_tree *,
958 proto_tree *, packet_info *, int, int, guint8);
959 static void dissect_certreq_v1(tvbuff_t *, int, int, proto_tree *,
960 proto_tree *, packet_info *, int, int, guint8);
961 static void dissect_certreq_v2(tvbuff_t *, int, int, proto_tree *,
962 proto_tree *, packet_info *, int, int, guint8);
963 static void dissect_hash(tvbuff_t *, int, int, proto_tree *,
964 proto_tree *, packet_info *, int, int, guint8);
965 static void dissect_auth(tvbuff_t *, int, int, proto_tree *,
966 proto_tree *, packet_info *, int, int, guint8);
967 static void dissect_sig(tvbuff_t *, int, int, proto_tree *,
968 proto_tree *, packet_info *, int, int, guint8);
969 static void dissect_nonce(tvbuff_t *, int, int, proto_tree *,
970 proto_tree *, packet_info *, int, int, guint8);
971 static void dissect_notif(tvbuff_t *, int, int, proto_tree *,
972 proto_tree *, packet_info *, int, int, guint8);
973 static void dissect_delete(tvbuff_t *, int, int, proto_tree *,
974 proto_tree *, packet_info *, int, int, guint8);
975 static void dissect_vid(tvbuff_t *, int, int, proto_tree *,
976 proto_tree *, packet_info *, int, int, guint8);
977 static void dissect_config(tvbuff_t *, int, int, proto_tree *,
978 proto_tree *, packet_info *, int, int, guint8);
979 static void dissect_nat_discovery(tvbuff_t *, int, int, proto_tree *,
980 proto_tree *, packet_info *, int, int, guint8);
981 static void dissect_nat_original_address(tvbuff_t *, int, int, proto_tree *,
982 proto_tree *, packet_info *, int, int, guint8);
983 static void dissect_ts(tvbuff_t *, int, int, proto_tree *,
984 proto_tree *, packet_info *, int, int, guint8);
985 static void dissect_enc(tvbuff_t *, int, int, proto_tree *,
986 proto_tree *, packet_info *, int, int, guint8);
987 static void dissect_eap(tvbuff_t *, int, int, proto_tree *,
988 proto_tree *, packet_info *, int, int, guint8);
989 static void dissect_cisco_fragmentation(tvbuff_t *, int, int, proto_tree *,
990 proto_tree *, packet_info *, int, int, guint8);
992 static const char *payloadtype2str(int, guint8);
993 static const char *exchtype2str(int, guint8);
994 static const char *doitype2str(guint32);
995 static const char *msgtype2str(int, guint16);
996 static const char *situation2str(guint32);
997 static const char *v1_attrval2str(int, guint16, guint32);
998 static const char *v2_attrval2str(guint16);
999 static const char *v2_tstype2str(guint8);
1000 static const char *v2_auth2str(guint8);
1001 static const char *certtype2str(int, guint8);
1003 static gboolean get_num(tvbuff_t *, int, guint16, guint32 *);
1005 #define LOAD_TYPE_NONE 0 /* payload type for None */
1006 #define LOAD_TYPE_PROPOSAL 2 /* payload type for Proposal */
1007 #define LOAD_TYPE_TRANSFORM 3 /* payload type for Transform */
1009 struct payload_func {
1012 void (*func)(tvbuff_t *, int, int, proto_tree *, proto_tree *, packet_info *,
1016 static struct payload_func v1_plfunc[] = {
1017 { 0, "NONE", NULL },
1018 { 1, "Security Association", dissect_sa },
1019 { 2, "Proposal", dissect_proposal },
1020 { 3, "Transform", dissect_transform },
1021 { 4, "Key Exchange", dissect_key_exch },
1022 { 5, "Identification", dissect_id },
1023 { 6, "Certificate", dissect_cert },
1024 { 7, "Certificate Request", dissect_certreq_v1},
1025 { 8, "Hash", dissect_hash },
1026 { 9, "Signature", dissect_sig },
1027 { 10, "Nonce", dissect_nonce },
1028 { 11, "Notification", dissect_notif },
1029 { 12, "Delete", dissect_delete },
1030 { 13, "Vendor ID", dissect_vid },
1031 { 14, "Attrib", dissect_config },
1032 { 15, "NAT-Discovery", dissect_nat_discovery }, /* draft-ietf-ipsec-nat-t-ike-04 */
1033 { 16, "NAT-Original Address", dissect_nat_original_address }, /* draft-ietf-ipsec-nat-t-ike */
1034 { 20, "NAT-D (RFC 3947)", dissect_nat_discovery },
1035 { 21, "NAT-OA (RFC 3947)", dissect_nat_original_address },
1036 { 130, "NAT-D (draft-ietf-ipsec-nat-t-ike-01 to 03)", dissect_nat_discovery },
1037 { 131, "NAT-OA (draft-ietf-ipsec-nat-t-ike-01 to 04)", dissect_nat_original_address },
1038 { 132, "Cisco-Fragmentation", dissect_cisco_fragmentation },
1041 static struct payload_func v2_plfunc[] = {
1042 { 0, "NONE", NULL },
1043 { 2, "Proposal", dissect_proposal },
1044 { 3, "Transform", dissect_transform2 },
1045 { 33, "Security Association", dissect_sa },
1046 { 34, "Key Exchange", dissect_key_exch },
1047 { 35, "Identification - I", dissect_id },
1048 { 36, "Identification - R", dissect_id },
1049 { 37, "Certificate", dissect_cert },
1050 { 38, "Certificate Request", dissect_certreq_v2},
1051 { 39, "Authentication", dissect_auth },
1052 { 40, "Nonce", dissect_nonce },
1053 { 41, "Notification", dissect_notif },
1054 { 42, "Delete", dissect_delete },
1055 { 43, "Vendor ID", dissect_vid },
1056 { 44, "Traffic Selector - I", dissect_ts },
1057 { 45, "Traffic Selector - R", dissect_ts },
1058 { 46, "Encrypted", dissect_enc },
1059 { 47, "Configuration", dissect_config },
1060 { 48, "Extensible Authentication", dissect_eap },
1063 static struct payload_func * getpayload_func(guint8, int);
1066 #define VID_MS_LEN 20
1067 #define VID_CISCO_FRAG_LEN 20
1069 static const guint8 VID_CISCO_FRAG[VID_CISCO_FRAG_LEN] = {0x40, 0x48, 0xB7, 0xD5, 0x6E, 0xBC, 0xE8, 0x85, 0x25, 0xE7, 0xDE, 0x7F, 0x00, 0xD6, 0xC2, 0xD3, 0x80, 0x00, 0x00, 0x00};
1071 static const guint8 VID_MS_W2K_WXP[VID_MS_LEN] = {0x1E, 0x2B, 0x51, 0x69, 0x5, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61, 0x0, 0x0, 0x0, 0x2}; /* according to http://www.microsoft.com/technet/treeview/default.asp?url=/technet/columns/cableguy/cg0602.asp */
1073 #define VID_CP_LEN 20
1074 static const guint8 VID_CP[VID_CP_LEN] = {0xF4, 0xED, 0x19, 0xE0, 0xC1, 0x14, 0xEB, 0x51, 0x6F, 0xAA, 0xAC, 0x0E, 0xE3, 0x7D, 0xAF, 0x28, 0x7, 0xB4, 0x38, 0x1F};
1076 static const guint8 VID_CYBERGUARD[VID_LEN] = {0x9A, 0xA1, 0xF3, 0xB4, 0x34, 0x72, 0xA4, 0x5D, 0x5F, 0x50, 0x6A, 0xEB, 0x26, 0xC, 0xF2, 0x14};
1078 static const guint8 VID_rfc3947[VID_LEN] = {0x4a, 0x13, 0x1c, 0x81, 0x07, 0x03, 0x58, 0x45, 0x5c, 0x57, 0x28, 0xf2, 0x0e, 0x95, 0x45, 0x2f}; /* RFC 3947 Negotiation of NAT-Traversal in the IKE*/
1080 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_0[VID_LEN] = {0xfB, 0xF4, 0x76, 0x14, 0x98, 0x40, 0x31, 0xFA, 0x8E, 0x3B, 0xB6, 0x19, 0x80, 0x89, 0xB2, 0x23}; /* Ssh Communications Security IPSEC Express version 1.1.0 */
1082 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_1[VID_LEN] = {0x19, 0x52, 0xDC, 0x91, 0xAC, 0x20, 0xF6, 0x46, 0xFB, 0x01, 0xCF, 0x42, 0xA3, 0x3A, 0xEE, 0x30}; /* Ssh Communications Security IPSEC Express version 1.1.1 */
1084 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_2[VID_LEN] = {0xE8, 0xBF, 0xFA, 0x64, 0x3E, 0x5C, 0x8F, 0x2C, 0xD1, 0x0F, 0xDA, 0x73, 0x70, 0xB6, 0xEB, 0xE5}; /* Ssh Communications Security IPSEC Express version 1.1.2 */
1086 static const guint8 VID_SSH_IPSEC_EXPRESS_1_2_1[VID_LEN] = {0xC1, 0x11, 0x1B, 0x2D, 0xEE, 0x8C, 0xBC, 0x3D, 0x62, 0x05, 0x73, 0xEC, 0x57, 0xAA, 0xB9, 0xCB}; /* Ssh Communications Security IPSEC Express version 1.2.1 */
1088 static const guint8 VID_SSH_IPSEC_EXPRESS_1_2_2[VID_LEN] = {0x09, 0xEC, 0x27, 0xBF, 0xBC, 0x09, 0xC7, 0x58, 0x23, 0xCF, 0xEC, 0xBF, 0xFE, 0x56, 0x5A, 0x2E}; /* Ssh Communications Security IPSEC Express version 1.2.2 */
1090 static const guint8 VID_SSH_IPSEC_EXPRESS_2_0_0[VID_LEN] = {0x7F, 0x21, 0xA5, 0x96, 0xE4, 0xE3, 0x18, 0xF0, 0xB2, 0xF4, 0x94, 0x4C, 0x23, 0x84, 0xCB, 0x84}; /* SSH Communications Security IPSEC Express version 2.0.0 */
1092 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_0[VID_LEN] = {0x28, 0x36, 0xD1, 0xFD, 0x28, 0x07, 0xBC, 0x9E, 0x5A, 0xE3, 0x07, 0x86, 0x32, 0x04, 0x51, 0xEC}; /* SSH Communications Security IPSEC Express version 2.1.0 */
1094 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_1[VID_LEN] = {0xA6, 0x8D, 0xE7, 0x56, 0xA9, 0xC5, 0x22, 0x9B, 0xAE, 0x66, 0x49, 0x80, 0x40, 0x95, 0x1A, 0xD5}; /* SSH Communications Security IPSEC Express version 2.1.1 */
1096 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_2[VID_LEN] = {0x3F, 0x23, 0x72, 0x86, 0x7E, 0x23, 0x7C, 0x1C, 0xD8, 0x25, 0x0A, 0x75, 0x55, 0x9C, 0xAE, 0x20}; /* SSH Communications Security IPSEC Express version 2.1.2 */
1098 static const guint8 VID_SSH_IPSEC_EXPRESS_3_0_0[VID_LEN] = {0x0E, 0x58, 0xD5, 0x77, 0x4D, 0xF6, 0x02, 0x00, 0x7D, 0x0B, 0x02, 0x44, 0x36, 0x60, 0xF7, 0xEB}; /* SSH Communications Security IPSEC Express version 3.0.0 */
1100 static const guint8 VID_SSH_IPSEC_EXPRESS_3_0_1[VID_LEN] = {0xF5, 0xCE, 0x31, 0xEB, 0xC2, 0x10, 0xF4, 0x43, 0x50, 0xCF, 0x71, 0x26, 0x5B, 0x57, 0x38, 0x0F}; /* SSH Communications Security IPSEC Express version 3.0.1 */
1102 static const guint8 VID_SSH_IPSEC_EXPRESS_4_0_0[VID_LEN] = {0xF6, 0x42, 0x60, 0xAF, 0x2E, 0x27, 0x42, 0xDA, 0xDD, 0xD5, 0x69, 0x87, 0x06, 0x8A, 0x99, 0xA0}; /* SSH Communications Security IPSEC Express version 4.0.0 */
1104 static const guint8 VID_SSH_IPSEC_EXPRESS_4_0_1[VID_LEN] = {0x7A, 0x54, 0xD3, 0xBD, 0xB3, 0xB1, 0xE6, 0xD9, 0x23, 0x89, 0x20, 0x64, 0xBE, 0x2D, 0x98, 0x1C}; /* SSH Communications Security IPSEC Express version 4.0.1 */
1106 static const guint8 VID_SSH_IPSEC_EXPRESS_4_1_0[VID_LEN] = {0x9A, 0xA1, 0xF3, 0xB4, 0x34, 0x72, 0xA4, 0x5D, 0x5F, 0x50, 0x6A, 0xEB, 0x26, 0x0C, 0xF2, 0x14}; /* SSH Communications Security IPSEC Express version 4.1.0 */
1108 static const guint8 VID_SSH_IPSEC_EXPRESS_4_1_1[VID_LEN] = {0x89, 0xF7, 0xB7, 0x60, 0xD8, 0x6B, 0x01, 0x2A, 0xCF, 0x26, 0x33, 0x82, 0x39, 0x4D, 0x96, 0x2F}; /* SSH Communications Security IPSEC Express version 4.1.1 */
1110 static const guint8 VID_SSH_IPSEC_EXPRESS_5_0[VID_LEN] = {0xB0, 0x37, 0xA2, 0x1A, 0xCE, 0xCC, 0xB5, 0x57, 0x0F, 0x60, 0x25, 0x46, 0xF9, 0x7B, 0xDE, 0x8C}; /* SSH Communications Security IPSEC Express version 5.0 */
1112 static const guint8 VID_SSH_IPSEC_EXPRESS_5_0_0[VID_LEN] = {0x2B, 0x2D, 0xAD, 0x97, 0xC4, 0xD1, 0x40, 0x93, 0x00, 0x53, 0x28, 0x7F, 0x99, 0x68, 0x50, 0xB0}; /* SSH Communications Security IPSEC Express version 5.0.0 */
1114 static const guint8 VID_SSH_IPSEC_EXPRESS_5_1_0[VID_LEN] = {0x45, 0xE1, 0x7F, 0x3A, 0xBE, 0x93, 0x94, 0x4C, 0xB2, 0x02, 0x91, 0x0C, 0x59, 0xEF, 0x80, 0x6B}; /* SSH Communications Security IPSEC Express version 5.1.0 */
1116 static const guint8 VID_SSH_IPSEC_EXPRESS_5_1_1[VID_LEN] = {0x59, 0x25, 0x85, 0x9F, 0x73, 0x77, 0xED, 0x78, 0x16, 0xD2, 0xFB, 0x81, 0xC0, 0x1F, 0xA5, 0x51}; /* SSH Communications Security IPSEC Express version 5.1.1 */
1118 static const guint8 VID_SSH_SENTINEL[VID_LEN] = {0x05, 0x41, 0x82, 0xA0, 0x7C, 0x7A, 0xE2, 0x06, 0xF9, 0xD2, 0xCF, 0x9D, 0x24, 0x32, 0xC4, 0x82}; /* SSH Sentinel */
1120 static const guint8 VID_SSH_SENTINEL_1_1[VID_LEN] = {0xB9, 0x16, 0x23, 0xE6, 0x93, 0xCA, 0x18, 0xA5, 0x4C, 0x6A, 0x27, 0x78, 0x55, 0x23, 0x05, 0xE8}; /* SSH Sentinel 1.1 */
1122 static const guint8 VID_SSH_SENTINEL_1_2[VID_LEN] = {0x54, 0x30, 0x88, 0x8D, 0xE0, 0x1A, 0x31, 0xA6, 0xFA, 0x8F, 0x60, 0x22, 0x4E, 0x44, 0x99, 0x58}; /* SSH Sentinel 1.2 */
1124 static const guint8 VID_SSH_SENTINEL_1_3[VID_LEN] = {0x7E, 0xE5, 0xCB, 0x85, 0xF7, 0x1C, 0xE2, 0x59, 0xC9, 0x4A, 0x5C, 0x73, 0x1E, 0xE4, 0xE7, 0x52}; /* SSH Sentinel 1.3 */
1126 static const guint8 VID_SSH_QUICKSEC_0_9_0[VID_LEN] = {0x37, 0xEB, 0xA0, 0xC4, 0x13, 0x61, 0x84, 0xE7, 0xDA, 0xF8, 0x56, 0x2A, 0x77, 0x06, 0x0B, 0x4A}; /* SSH Communications Security QuickSec 0.9.0 */
1128 static const guint8 VID_SSH_QUICKSEC_1_1_0[VID_LEN] = {0x5D, 0x72, 0x92, 0x5E, 0x55, 0x94, 0x8A, 0x96, 0x61, 0xA7, 0xFC, 0x48, 0xFD, 0xEC, 0x7F, 0xF9}; /* SSH Communications Security QuickSec 1.1.0 */
1130 static const guint8 VID_SSH_QUICKSEC_1_1_1[VID_LEN] = {0x77, 0x7F, 0xBF, 0x4C, 0x5A, 0xF6, 0xD1, 0xCD, 0xD4, 0xB8, 0x95, 0xA0, 0x5B, 0xF8, 0x25, 0x94}; /* SSH Communications Security QuickSec 1.1.1 */
1132 static const guint8 VID_SSH_QUICKSEC_1_1_2[VID_LEN] = {0x2C, 0xDF, 0x08, 0xE7, 0x12, 0xED, 0xE8, 0xA5, 0x97, 0x87, 0x61, 0x26, 0x7C, 0xD1, 0x9B, 0x91}; /* SSH Communications Security QuickSec 1.1.2 */
1134 static const guint8 VID_SSH_QUICKSEC_1_1_3[VID_LEN] = {0x59, 0xE4, 0x54, 0xA8, 0xC2, 0xCF, 0x02, 0xA3, 0x49, 0x59, 0x12, 0x1F, 0x18, 0x90, 0xBC, 0x87}; /* SSH Communications Security QuickSec 1.1.3 */
1136 static const guint8 VID_draft_huttunen_ipsec_esp_in_udp_01[VID_LEN] = {0x50, 0x76, 0x0F, 0x62, 0x4C, 0x63, 0xE5, 0xC5, 0x3E, 0xEA, 0x38, 0x6C, 0x68, 0x5C, 0xA0, 0x83}; /* draft-huttunen-ipsec-esp-in-udp-01.txt */
1138 static const guint8 VID_draft_stenberg_ipsec_nat_traversal_01[VID_LEN] = {0x27, 0xBA, 0xB5, 0xDC, 0x01, 0xEA, 0x07, 0x60, 0xEA, 0x4E, 0x31, 0x90, 0xAC, 0x27, 0xC0, 0xD0}; /* draft-stenberg-ipsec-nat-traversal-01 */
1140 static const guint8 VID_draft_stenberg_ipsec_nat_traversal_02[VID_LEN]= {0x61, 0x05, 0xC4, 0x22, 0xE7, 0x68, 0x47, 0xE4, 0x3F, 0x96, 0x84, 0x80, 0x12, 0x92, 0xAE, 0xCD}; /* draft-stenberg-ipsec-nat-traversal-02 */
1142 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_00[VID_LEN]= {0x44, 0x85, 0x15, 0x2D, 0x18, 0xB6, 0xBB, 0xCD, 0x0B, 0xE8, 0xA8, 0x46, 0x95, 0x79, 0xDD, 0xCC}; /* draft-ietf-ipsec-nat-t-ike-00 */
1144 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_01[VID_LEN]= {0x16, 0xf6, 0xca, 0x16, 0xe4, 0xa4, 0x06, 0x6d, 0x83, 0x82, 0x1a, 0x0f, 0x0a, 0xea, 0xa8, 0x62 }; /* "draft-ietf-ipsec-nat-t-ike-01" */
1146 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_02a[VID_LEN]= {0xCD, 0x60, 0x46, 0x43, 0x35, 0xDF, 0x21, 0xF8, 0x7C, 0xFD, 0xB2, 0xFC, 0x68, 0xB6, 0xA4, 0x48}; /* draft-ietf-ipsec-nat-t-ike-02 */
1148 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_02b[VID_LEN]= {0x90, 0xCB, 0x80, 0x91, 0x3E, 0xBB, 0x69, 0x6E, 0x08, 0x63, 0x81, 0xB5, 0xEC, 0x42, 0x7B, 0x1F}; /* draft-ietf-ipsec-nat-t-ike-02 */
1150 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_03[VID_LEN] = {0x7D, 0x94, 0x19, 0xA6, 0x53, 0x10, 0xCA, 0x6F, 0x2C, 0x17, 0x9D, 0x92, 0x15, 0x52, 0x9d, 0x56}; /* according to http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-03.txt */
1152 static const guint8 VID_draft_beaulieu_ike_xauth_02[VID_LEN]= {0x09, 0x00, 0x26, 0x89, 0xDF, 0xD6, 0xB7, 0x12, 0x80, 0xA2, 0x24, 0xDE, 0xC3, 0x3B, 0x81, 0xE5}; /* draft-beaulieu-ike-xauth-02.txt */
1155 static const guint8 VID_rfc3706_dpd[VID_LEN]= {0xAF, 0xCA,0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, 0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57, 0x01, 0x00}; /* RFC 3706 */
1157 static const guint8 VID_IKE_CHALLENGE_RESPONSE_1[VID_LEN]= {0xBA, 0x29, 0x04, 0x99, 0xC2, 0x4E, 0x84, 0xE5, 0x3A, 0x1D, 0x83, 0xA0, 0x5E, 0x5F, 0x00, 0xC9}; /* IKE Challenge/Response for Authenticated Cryptographic Keys */
1159 static const guint8 VID_IKE_CHALLENGE_RESPONSE_2[VID_LEN]= {0x0D, 0x33, 0x61, 0x1A, 0x5D, 0x52, 0x1B, 0x5E, 0x3C, 0x9C, 0x03, 0xD2, 0xFC, 0x10, 0x7E, 0x12}; /* IKE Challenge/Response for Authenticated Cryptographic Keys */
1161 static const guint8 VID_IKE_CHALLENGE_RESPONSE_REV_1[VID_LEN]= {0xAD, 0x32, 0x51, 0x04, 0x2C, 0xDC, 0x46, 0x52, 0xC9, 0xE0, 0x73, 0x4C, 0xE5, 0xDE, 0x4C, 0x7D}; /* IKE Challenge/Response for Authenticated Cryptographic Keys (Revised) */
1163 static const guint8 VID_IKE_CHALLENGE_RESPONSE_REV_2[VID_LEN]= {0x01, 0x3F, 0x11, 0x82, 0x3F, 0x96, 0x6F, 0xA9, 0x19, 0x00, 0xF0, 0x24, 0xBA, 0x66, 0xA8, 0x6B}; /* IKE Challenge/Response for Authenticated Cryptographic Keys (Revised) */
1165 static const guint8 VID_MS_L2TP_IPSEC_VPN_CLIENT[VID_LEN]= {0x40, 0x48, 0xB7, 0xD5, 0x6E, 0xBC, 0xE8, 0x85, 0x25, 0xE7, 0xDE, 0x7F, 0x00, 0xD6, 0xC2, 0xD3}; /* Microsoft L2TP/IPSec VPN Client */
1167 static const guint8 VID_GSS_API_1[VID_LEN]= {0xB4, 0x6D, 0x89, 0x14, 0xF3, 0xAA, 0xA3, 0xF2, 0xFE, 0xDE, 0xB7, 0xC7, 0xDB, 0x29, 0x43, 0xCA}; /* A GSS-API Authentication Method for IKE */
1169 static const guint8 VID_GSS_API_2[VID_LEN]= {0xAD, 0x2C, 0x0D, 0xD0, 0xB9, 0xC3, 0x20, 0x83, 0xCC, 0xBA, 0x25, 0xB8, 0x86, 0x1E, 0xC4, 0x55}; /* A GSS-API Authentication Method for IKE */
1171 static const guint8 VID_GSSAPI[VID_LEN]= {0x62, 0x1B, 0x04, 0xBB, 0x09, 0x88, 0x2A, 0xC1, 0xE1, 0x59, 0x35, 0xFE, 0xFA, 0x24, 0xAE, 0xEE}; /* GSSAPI */
1173 static const guint8 VID_MS_NT5_ISAKMPOAKLEY[VID_LEN]= {0x1E, 0x2B, 0x51, 0x69, 0x05, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61}; /* MS NT5 ISAKMPOAKLEY */
1175 static const guint8 VID_CISCO_UNITY[VID_LEN]= {0x12, 0xF5, 0xF2, 0x8C, 0x45, 0x71, 0x68, 0xA9, 0x70, 0x2D, 0x9F, 0xE2, 0x74, 0xCC, 0x02, 0xD4}; /* CISCO-UNITY */
1177 static const guint8 VID_CISCO_UNITY_10[VID_LEN]= {0x12, 0xF5, 0xF2, 0x8C, 0x45, 0x71, 0x68, 0xA9, 0x70, 0x2D, 0x9F, 0xE2, 0x74, 0xCC, 0x01, 0x00}; /* CISCO-UNITY 1.0 */
1179 static const guint8 VID_CISCO_CONCENTRATOR[VID_LEN]= {0x1F, 0x07, 0xF7, 0x0E, 0xAA, 0x65, 0x14, 0xD3, 0xB0, 0xFA, 0x96, 0x54, 0x2A, 0x50, 0x01, 0x00}; /* CISCO-CONCENTRATOR */
1182 static const guint8 VID_draft_ietf_ipsec_antireplay_00[VID_LEN_8]= {0x32, 0x5D, 0xF2, 0x9A, 0x23, 0x19, 0xF2, 0xDD}; /* draft-ietf-ipsec-antireplay-00.txt */
1184 static const guint8 VID_draft_ietf_ipsec_heartbeats_00[VID_LEN_8]= {0x8D, 0xB7, 0xA4, 0x18, 0x11, 0x22, 0x16, 0x60}; /* draft-ietf-ipsec-heartbeats-00.txt */
1187 * Seen in Netscreen. Suppose to be ASCII HeartBeat_Notify - but I don't know the rest yet. I suspect it then proceeds with
1188 * 8k10, which means every 8K (?), and version 1.0 of the protocol (?). I won't add it to the code, until I know what it really
1189 * means. ykaul-at-bezeqint.net
1191 static const guint8 VID_HeartBeat_Notify[VID_LEN] _U_ = {0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x5f, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79};
1194 dissect_payloads(tvbuff_t *tvb, proto_tree *tree, proto_tree *parent_tree,
1195 int isakmp_version, guint8 initial_payload, int offset, int length,
1198 guint8 payload, next_payload;
1199 guint16 payload_length;
1201 struct payload_func * f;
1203 for (payload = initial_payload; length > 0; payload = next_payload) {
1204 if (payload == LOAD_TYPE_NONE) {
1206 * What? There's more stuff in this chunk of data, but the
1207 * previous payload had a "next payload" type of None?
1209 proto_tree_add_text(tree, tvb, offset, length,
1211 tvb_bytes_to_str(tvb, offset, length));
1214 ntree = dissect_payload_header(tvb, offset, length, isakmp_version,
1215 payload, &next_payload, &payload_length, tree);
1218 if (payload_length >= 4) { /* XXX = > 4? */
1219 tvb_ensure_bytes_exist(tvb, offset + 4, payload_length - 4);
1220 if ((f = getpayload_func(payload, isakmp_version)) != NULL && f->func != NULL)
1221 (*f->func)(tvb, offset + 4, payload_length - 4, ntree, parent_tree,
1222 pinfo, isakmp_version, -1, next_payload);
1224 proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4,
1228 else if (payload_length > length) {
1229 proto_tree_add_text(ntree, tvb, 0, 0,
1230 "Payload (bogus, length is %u, greater than remaining length %d",
1231 payload_length, length);
1235 proto_tree_add_text(ntree, tvb, 0, 0,
1236 "Payload (bogus, length is %u, must be at least 4)",
1240 offset += payload_length;
1241 length -= payload_length;
1246 isakmp_dissect_payloads(tvbuff_t *tvb, proto_tree *tree, int isakmp_version,
1247 guint8 initial_payload, int offset, int length,
1250 dissect_payloads(tvb, tree, tree, isakmp_version, initial_payload, offset, length,
1254 static struct payload_func *
1255 getpayload_func(guint8 payload, int isakmp_version)
1257 struct payload_func *f = 0;
1260 if (isakmp_version == 1) {
1262 len = ARLEN(v1_plfunc);
1263 } else if (isakmp_version == 2) {
1265 len = ARLEN(v2_plfunc);
1268 for (i = 0; i < len; i++) {
1269 if (f[i].type == payload)
1276 dissect_isakmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1278 int offset = 0, len;
1281 proto_tree * isakmp_tree = NULL;
1283 #ifdef HAVE_LIBGCRYPT
1284 guint8 i_cookie[COOKIE_SIZE], *ic_key;
1285 decrypt_data_t *decr = NULL;
1287 proto_tree *decr_tree;
1289 void *pd_save = NULL;
1290 gboolean pd_changed = FALSE;
1291 #endif /* HAVE_LIBGCRYPT */
1293 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISAKMP");
1294 col_clear(pinfo->cinfo, COL_INFO);
1297 ti = proto_tree_add_item(tree, proto_isakmp, tvb, offset, -1, FALSE);
1298 isakmp_tree = proto_item_add_subtree(ti, ett_isakmp);
1301 /* RFC3948 2.3 NAT Keepalive packet:
1302 * 1 byte payload with the value 0xff.
1304 if( (tvb_length(tvb)==1) && (tvb_get_guint8(tvb, offset)==0xff) ){
1305 col_set_str(pinfo->cinfo, COL_INFO, "NAT Keepalive");
1306 proto_tree_add_item(isakmp_tree, hf_isakmp_nat_keepalive, tvb, offset, 1, FALSE);
1310 hdr.length = tvb_get_ntohl(tvb, offset + ISAKMP_HDR_SIZE - 4);
1311 hdr.exch_type = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1 + 1);
1312 hdr.version = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1);
1313 isakmp_version = hi_nibble(hdr.version); /* save the version */
1314 hdr.flags = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1 + 1 + 1);
1315 if (check_col(pinfo->cinfo, COL_INFO))
1316 col_add_str(pinfo->cinfo, COL_INFO,
1317 exchtype2str(isakmp_version, hdr.exch_type));
1319 #ifdef HAVE_LIBGCRYPT
1320 if (isakmp_version == 1) {
1321 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
1323 tvb_memcpy(tvb, i_cookie, offset, COOKIE_SIZE);
1324 decr = (decrypt_data_t*) g_hash_table_lookup(isakmp_hash, i_cookie);
1327 #if GLIB_CHECK_VERSION(2,10,0)
1328 ic_key = g_slice_alloc(COOKIE_SIZE);
1329 decr = g_slice_alloc(sizeof(decrypt_data_t));
1331 ic_key = g_mem_chunk_alloc(isakmp_key_data);
1332 decr = g_mem_chunk_alloc(isakmp_decrypt_data);
1334 memcpy(ic_key, i_cookie, COOKIE_SIZE);
1335 memset(decr, 0, sizeof(decrypt_data_t));
1336 SET_ADDRESS(&decr->initiator, AT_NONE, 0, NULL);
1338 g_hash_table_insert(isakmp_hash, ic_key, decr);
1341 if (ADDRESSES_EQUAL(&decr->initiator, &null_addr)) {
1342 /* XXX - We assume that we're seeing the second packet in an exchange here.
1343 * Is there a way to verify this? */
1344 SE_COPY_ADDRESS(&decr->initiator, &pinfo->src);
1347 pd_save = pinfo->private_data;
1348 pinfo->private_data = decr;
1350 } else if (isakmp_version == 2) {
1351 ikev2_uat_data_key_t hash_key;
1352 ikev2_uat_data_t *ike_sa_data = NULL;
1353 ikev2_decrypt_data_t *ikev2_dec_data;
1354 guchar spii[COOKIE_SIZE], spir[COOKIE_SIZE];
1356 tvb_memcpy(tvb, spii, offset, COOKIE_SIZE);
1357 tvb_memcpy(tvb, spir, offset + COOKIE_SIZE, COOKIE_SIZE);
1358 hash_key.spii = spii;
1359 hash_key.spir = spir;
1360 hash_key.spii_len = COOKIE_SIZE;
1361 hash_key.spir_len = COOKIE_SIZE;
1363 ike_sa_data = g_hash_table_lookup(ikev2_key_hash, &hash_key);
1365 guint8 initiator_flag;
1366 initiator_flag = hdr.flags & I_FLAG;
1367 ikev2_dec_data = ep_alloc(sizeof(ikev2_decrypt_data_t));
1368 ikev2_dec_data->encr_key = initiator_flag ? ike_sa_data->sk_ei : ike_sa_data->sk_er;
1369 ikev2_dec_data->auth_key = initiator_flag ? ike_sa_data->sk_ai : ike_sa_data->sk_ar;
1370 ikev2_dec_data->encr_spec = ike_sa_data->encr_spec;
1371 ikev2_dec_data->auth_spec = ike_sa_data->auth_spec;
1373 pd_save = pinfo->private_data;
1374 pinfo->private_data = ikev2_dec_data;
1378 #endif /* HAVE_LIBGCRYPT */
1381 proto_tree_add_item(isakmp_tree, hf_isakmp_icookie, tvb, offset, COOKIE_SIZE, FALSE);
1382 offset += COOKIE_SIZE;
1384 proto_tree_add_item(isakmp_tree, hf_isakmp_rcookie, tvb, offset, COOKIE_SIZE, FALSE);
1385 offset += COOKIE_SIZE;
1387 hdr.next_payload = tvb_get_guint8(tvb, offset);
1388 proto_tree_add_uint_format(isakmp_tree, hf_isakmp_nextpayload, tvb, offset,
1389 1, hdr.next_payload,
1390 "Next payload: %s (%u)",
1391 payloadtype2str(isakmp_version, hdr.next_payload),
1395 proto_tree_add_uint_format(isakmp_tree, hf_isakmp_version, tvb, offset,
1396 1, hdr.version, "Version: %u.%u",
1397 hi_nibble(hdr.version), lo_nibble(hdr.version));
1400 hdr.exch_type = tvb_get_guint8(tvb, offset);
1401 proto_tree_add_uint_format(isakmp_tree, hf_isakmp_exchangetype, tvb, offset,
1403 "Exchange type: %s (%u)",
1404 exchtype2str(isakmp_version, hdr.exch_type),
1412 fti = proto_tree_add_item(isakmp_tree, hf_isakmp_flags, tvb, offset, 1, FALSE);
1413 ftree = proto_item_add_subtree(fti, ett_isakmp_flags);
1415 if (isakmp_version == 1) {
1416 proto_tree_add_item(ftree, hf_isakmp_flag_e, tvb, offset, 1, FALSE);
1418 proto_tree_add_item(ftree, hf_isakmp_flag_c, tvb, offset, 1, FALSE);
1420 proto_tree_add_item(ftree, hf_isakmp_flag_a, tvb, offset, 1, FALSE);
1422 } else if (isakmp_version == 2) {
1423 proto_tree_add_item(ftree, hf_isakmp_flag_i, tvb, offset, 1, FALSE);
1425 proto_tree_add_item(ftree, hf_isakmp_flag_v, tvb, offset, 1, FALSE);
1427 proto_tree_add_item(ftree, hf_isakmp_flag_r, tvb, offset, 1, FALSE);
1433 hdr.message_id = tvb_get_ntohl(tvb, offset);
1434 proto_tree_add_item(isakmp_tree, hf_isakmp_messageid, tvb, offset, 4, FALSE);
1437 if (hdr.length < ISAKMP_HDR_SIZE) {
1438 proto_tree_add_uint_format(isakmp_tree, hf_isakmp_length, tvb, offset, 4,
1439 hdr.length, "Length: (bogus, length is %u, should be at least %lu)",
1440 hdr.length, (unsigned long)ISAKMP_HDR_SIZE);
1441 #ifdef HAVE_LIBGCRYPT
1442 if (pd_changed) pinfo->private_data = pd_save;
1443 #endif /* HAVE_LIBGCRYPT */
1447 len = hdr.length - ISAKMP_HDR_SIZE;
1450 proto_tree_add_uint_format(isakmp_tree, hf_isakmp_length, tvb, offset, 4,
1451 hdr.length, "Length: (bogus, length is %u, which is too large)",
1453 #ifdef HAVE_LIBGCRYPT
1454 if (pd_changed) pinfo->private_data = pd_save;
1455 #endif /* HAVE_LIBGCRYPT */
1459 proto_tree_add_item(isakmp_tree, hf_isakmp_length, tvb, offset, 4, FALSE);
1462 if (hdr.flags & E_FLAG) {
1463 if (len && isakmp_tree) {
1464 ti = proto_tree_add_text(isakmp_tree, tvb, offset, len,
1465 "Encrypted payload (%d byte%s)",
1466 len, plurality(len, "", "s"));
1467 #ifdef HAVE_LIBGCRYPT
1470 decr_tvb = decrypt_payload(tvb, pinfo, tvb_get_ptr(tvb, offset, len), len, &hdr);
1472 decr_tree = proto_item_add_subtree(ti, ett_isakmp);
1473 dissect_payloads(decr_tvb, decr_tree, tree, isakmp_version,
1474 hdr.next_payload, 0, tvb_length(decr_tvb), pinfo);
1477 #endif /* HAVE_LIBGCRYPT */
1480 dissect_payloads(tvb, isakmp_tree, tree, isakmp_version, hdr.next_payload,
1481 offset, len, pinfo);
1483 #ifdef HAVE_LIBGCRYPT
1484 if (pd_changed) pinfo->private_data = pd_save;
1485 #endif /* HAVE_LIBGCRYPT */
1489 dissect_payload_header(tvbuff_t *tvb, int offset, int length,
1490 int isakmp_version, guint8 payload, guint8 *next_payload_p,
1491 guint16 *payload_length_p, proto_tree *tree)
1493 guint8 next_payload;
1494 guint16 payload_length;
1499 proto_tree_add_text(tree, tvb, offset, length,
1500 "Not enough room in payload for all transforms");
1503 next_payload = tvb_get_guint8(tvb, offset);
1504 payload_length = tvb_get_ntohs(tvb, offset + 2);
1506 /* This is ugly, but the code is too inflexible to handle this at the
1507 * proper place (dissect_vid)
1509 if (payload == 13) { /* Vendor ID */
1510 ti = proto_tree_add_text(tree, tvb, offset, payload_length,
1511 "%s: %s", payloadtype2str(isakmp_version, payload),
1512 vid_to_str(tvb, offset + 4, payload_length - 4));
1514 ti = proto_tree_add_text(tree, tvb, offset, payload_length,
1515 "%s payload", payloadtype2str(isakmp_version, payload));
1517 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
1519 proto_tree_add_uint_format(ntree, hf_isakmp_nextpayload, tvb, offset, 1,
1520 next_payload, "Next payload: %s (%u)",
1521 payloadtype2str(isakmp_version, next_payload),
1523 if (isakmp_version == 2) {
1524 proto_tree_add_text(ntree, tvb, offset + 1, 1, "%s",
1525 decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 1), 0x80,
1526 8, "Critical", "Not critical"));
1528 proto_tree_add_item(ntree, hf_isakmp_payloadlen, tvb, offset + 2, 2, FALSE);
1530 *next_payload_p = next_payload;
1531 *payload_length_p = payload_length;
1536 dissect_sa(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1537 proto_tree *p _U_, packet_info *pinfo, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
1543 proto_tree_add_text(tree, tvb, offset, length,
1544 "DOI %s (length is %u, should be >= 4)",
1545 tvb_bytes_to_str(tvb, offset, length), length);
1548 if (isakmp_version == 1) {
1549 doi = tvb_get_ntohl(tvb, offset);
1550 proto_tree_add_uint_format(tree, hf_isakmp_doi, tvb, offset, 4,
1551 doi, "Domain of interpretation: %s (%u)",
1552 doitype2str(doi), doi);
1559 proto_tree_add_bytes_format(tree, hf_isakmp_sa_situation, tvb, offset, length,
1560 tvb_get_ptr(tvb, offset, length),
1561 "Situation: %s (length is %u, should be >= 4)",
1562 tvb_bytes_to_str(tvb, offset, length), length);
1565 situation = tvb_get_ntohl(tvb, offset);
1566 proto_tree_add_bytes_format(tree, hf_isakmp_sa_situation, tvb, offset, 4,
1567 tvb_get_ptr(tvb, offset, 4), "Situation: %s (%u)",
1568 situation2str(situation), situation);
1572 dissect_payloads(tvb, tree, tree, isakmp_version, LOAD_TYPE_PROPOSAL, offset,
1576 proto_tree_add_item(tree, hf_isakmp_sa_situation, tvb, offset, length, FALSE);
1578 } else if (isakmp_version == 2) {
1579 dissect_payloads(tvb, tree, tree, isakmp_version, LOAD_TYPE_PROPOSAL, offset,
1585 dissect_proposal(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1586 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
1590 guint8 num_transforms;
1591 guint8 next_payload;
1592 guint16 payload_length;
1594 guint8 proposal_num;
1596 proposal_num = tvb_get_guint8(tvb, offset);
1598 proto_item_append_text(tree, " # %d", proposal_num);
1600 proto_tree_add_item(tree, hf_isakmp_prop_number, tvb, offset, 1, FALSE);
1604 protocol_id = tvb_get_guint8(tvb, offset);
1605 proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
1606 protocol_id, "Protocol ID: %s (%u)",
1607 val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
1611 spi_size = tvb_get_guint8(tvb, offset);
1612 proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
1616 num_transforms = tvb_get_guint8(tvb, offset);
1617 proto_tree_add_item(tree, hf_isakmp_prop_transforms, tvb, offset, 1, FALSE);
1622 proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
1623 tvb_bytes_to_str(tvb, offset, spi_size));
1628 while (num_transforms > 0) {
1629 ntree = dissect_payload_header(tvb, offset, length, isakmp_version,
1630 LOAD_TYPE_TRANSFORM, &next_payload, &payload_length, tree);
1633 if (length < payload_length) {
1634 proto_tree_add_text(tree, tvb, offset + 4, length,
1635 "Not enough room in payload for all transforms");
1638 if (payload_length >= 4) {
1639 if (isakmp_version == 1)
1640 dissect_transform(tvb, offset + 4, payload_length - 4, ntree,
1641 ntree, pinfo, isakmp_version, protocol_id, 0);
1642 else if (isakmp_version == 2)
1643 dissect_transform2(tvb, offset + 4, payload_length - 4, ntree,
1644 ntree, pinfo, isakmp_version, protocol_id, 0);
1647 proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4, "Payload");
1648 offset += payload_length;
1649 length -= payload_length;
1655 dissect_transform(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1656 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
1657 int protocol_id, guint8 inner_payload _U_)
1659 static const value_string vs_v1_attr[] = {
1660 { 1, "Encryption-Algorithm" },
1661 { 2, "Hash-Algorithm" },
1662 { 3, "Authentication-Method" },
1663 { 4, "Group-Description" },
1664 { 5, "Group-Type" },
1665 { 6, "Group-Prime" },
1666 { 7, "Group-Generator-One" },
1667 { 8, "Group-Generator-Two" },
1668 { 9, "Group-Curve-A" },
1669 { 10, "Group-Curve-B" },
1670 { 11, "Life-Type" },
1671 { 12, "Life-Duration" },
1673 { 14, "Key-Length" },
1674 { 15, "Field-Size" },
1675 { 16, "Group-Order" },
1679 static const value_string vs_v2_sttr[] = {
1680 { 1, "SA-Life-Type" },
1681 { 2, "SA-Life-Duration" },
1682 { 3, "Group-Description" },
1683 { 4, "Encapsulation-Mode" },
1684 { 5, "Authentication-Algorithm" },
1685 { 6, "Key-Length" },
1686 { 7, "Key-Rounds" },
1687 { 8, "Compress-Dictionary-Size" },
1688 { 9, "Compress-Private-Algorithm" },
1689 { 10, "ECN Tunnel" },
1693 static const value_string vs_v1_trans_isakmp[] = {
1699 static const value_string vs_v1_trans_ah[] = {
1711 static const value_string vs_v1_trans_esp[] = {
1728 static const value_string vs_v1_trans_ipcomp[] = {
1737 guint8 transform_id;
1738 guint8 transform_num;
1739 #ifdef HAVE_LIBGCRYPT
1740 decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
1741 #endif /* HAVE_LIBGCRYPT */
1743 transform_num = tvb_get_guint8(tvb, offset);
1744 proto_item_append_text(tree," # %d",transform_num);
1745 proto_tree_add_item(tree, hf_isakmp_trans_number, tvb, offset, 1, FALSE);
1749 transform_id = tvb_get_guint8(tvb, offset);
1750 switch (protocol_id) {
1752 proto_tree_add_item(tree, hf_isakmp_trans_id, tvb, offset, 1, FALSE);
1754 case 1: /* ISAKMP */
1755 proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1756 transform_id, "Transform ID: %s (%u)",
1757 val_to_str(transform_id, vs_v1_trans_isakmp, "UNKNOWN-TRANS-TYPE"), transform_id);
1760 proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1761 transform_id, "Transform ID: %s (%u)",
1762 val_to_str(transform_id, vs_v1_trans_ah, "UNKNOWN-AH-TRANS-TYPE"), transform_id);
1765 proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1766 transform_id, "Transform ID: %s (%u)",
1767 val_to_str(transform_id, vs_v1_trans_esp, "UNKNOWN-ESP-TRANS-TYPE"), transform_id);
1769 case 4: /* IPCOMP */
1770 proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1771 transform_id, "Transform ID: %s (%u)",
1772 val_to_str(transform_id, vs_v1_trans_ipcomp, "UNKNOWN-IPCOMP-TRANS-TYPE"), transform_id);
1781 guint16 aft = tvb_get_ntohs(tvb, offset);
1782 guint16 type = aft & 0x7fff;
1787 /* XXX - Add header fields */
1788 if (protocol_id == 1 && transform_id == 1) {
1790 str = val_to_str(type, vs_v1_attr, "UNKNOWN-ATTRIBUTE-TYPE");
1793 str = val_to_str(type, vs_v2_sttr, "UNKNOWN-ATTRIBUTE-TYPE");
1797 val = tvb_get_ntohs(tvb, offset + 2);
1798 proto_tree_add_text(tree, tvb, offset, 4,
1801 v1_attrval2str(ike_phase1, type, val), val);
1802 #ifdef HAVE_LIBGCRYPT
1803 set_transform_vals(decr, ike_phase1, type, val);
1809 len = tvb_get_ntohs(tvb, offset + 2);
1811 if (!get_num(tvb, offset + 4, len, &val)) {
1812 proto_tree_add_text(tree, tvb, offset, pack_len,
1813 "%s (%u): <too big (%u bytes)>",
1816 proto_tree_add_text(tree, tvb, offset, pack_len,
1819 v1_attrval2str(ike_phase1, type, val), val);
1820 #ifdef HAVE_LIBGCRYPT
1821 set_transform_vals(decr, ike_phase1, type, val);
1830 /* For Transform Type 1 (Encryption Algorithm), defined Transform IDs */
1832 v2_tid2encstr(guint16 tid)
1834 static const value_string vs_v2_trans_enc[] = {
1836 { 1, "ENCR_DES_IV64" },
1842 { 7, "ENCR_BLOWFISH" },
1843 { 8, "ENCR_3IDEA" },
1844 { 9, "ENCR_DES_IV32" },
1846 { 11, "ENCR_NULL" },
1847 { 12, "ENCR_AES_CBC" },
1848 { 13, "ENCR_AES_CTR" }, /* [RFC3686] */
1849 { 14, "ENCR_AES-CCM_8" }, /* [RFC4309] */
1850 { 15, "ENCR-AES-CCM_12" }, /* [RFC4309] */
1851 { 16, "ENCR-AES-CCM_16" }, /* [RFC4309] */
1852 { 17, "UNASSIGNED" },
1853 { 18, "AES-GCM with a 8 octet ICV" }, /* [RFC4106] */
1854 { 19, "AES-GCM with a 12 octet ICV" }, /* [RFC4106] */
1855 { 20, "AES-GCM with a 16 octet ICV" }, /* [RFC4106] */
1856 { 21, "ENCR_NULL_AUTH_AES_GMAC" }, /* [RFC4543] */
1858 * 22-1023 RESERVED TO IANA [RFC4306]
1859 * 1024-65535 PRIVATE USE [RFC4306]
1864 return val_to_str(tid, vs_v2_trans_enc, "UNKNOWN-ENC-ALG");
1867 /* For Transform Type 2 (Pseudo-random Function), defined Transform IDs */
1869 v2_tid2prfstr(guint16 tid)
1871 static const value_string vs_v2_trans_prf[] = {
1873 { 1, "PRF_HMAC_MD5" },
1874 { 2, "PRF_HMAC_SHA1" },
1875 { 3, "PRF_HMAC_TIGER" },
1876 { 4, "PRF_AES128_CBC" },
1877 { 5, "RESERVED TO IANA" }, /* [RFC4306] */
1878 { 6, "RESERVED TO IANA" }, /* [RFC4306] */
1879 { 7, "RESERVED TO IANA" }, /* [RFC4306] */
1880 { 8, "PRF_AES128_CMAC6" }, /* [RFC4615] */
1882 9-1023 RESERVED TO IANA [RFC4306]
1883 1024-65535 PRIVATE USE [RFC4306]
1887 return val_to_str(tid, vs_v2_trans_prf, "UNKNOWN-PRF");
1890 /* For Transform Type 3 (Integrity Algorithm), defined Transform IDs */
1892 v2_tid2iastr(guint16 tid)
1894 static const value_string vs_v2_trans_integrity[] = {
1896 { 1, "AUTH_HMAC_MD5_96" },
1897 { 2, "AUTH_HMAC_SHA1_96" },
1898 { 3, "AUTH_DES_MAC" },
1899 { 4, "AUTH_KPDK_MD5" },
1900 { 5, "AUTH_AES_XCBC_96" },
1901 { 6, "AUTH_HMAC_MD5_128" }, /* [RFC-maino-fcsp-02.txt] */
1902 { 7, "AUTH_HMAC_SHA1_160" }, /* [RFC-maino-fcsp-02.txt] */
1903 { 8, "AUTH_AES_CMAC_96" }, /* [RFC4494] */
1904 { 9, "AUTH_AES_128_GMAC" }, /* [RFC4543] */
1905 { 10, "AUTH_AES_192_GMAC" }, /* [RFC4543] */
1906 { 11, "AUTH_AES_256_GMAC" }, /* [RFC4543] */
1908 12-1023 RESERVED TO IANA [RFC4306]
1909 1024-65535 PRIVATE USE [RFC4306]
1913 return val_to_str(tid, vs_v2_trans_integrity, "UNKNOWN-INTEGRITY-ALG");
1916 /* For Transform Type 4 (Diffie-Hellman Group), defined Transform IDs */
1918 v2_tid2dhstr(guint16 tid)
1920 static const value_string vs_v2_trans_dhgroup[] = {
1922 { 1, "Group 1 - 768 Bit MODP" },
1923 { 2, "Group 2 - 1024 Bit MODP" },
1926 { 5, "group 5 - 1536 Bit MODP" },
1927 /* 6-13 RESERVED TO IANA [RFC4306] */
1928 { 14, "2048-bit MODP Group" },
1929 { 15, "3072-bit MODP Group" },
1930 { 16, "4096-bit MODP Group" },
1931 { 17, "6144-bit MODP Group" },
1932 { 18, "8192-bit MODP Group" },
1933 { 19, "256-bit random ECP group" }, /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1934 { 20, "384-bit random ECP group" }, /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1935 { 21, "521-bit random ECP group" }, /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1937 22-1023 RESERVED TO IANA [RFC4306]
1938 1024-65535 PRIVATE USE [RFC4306]
1943 if ((tid >= 6 && tid <= 13) || (tid >= 22 && tid <= 1023))
1944 return "RESERVED TO IANA";
1946 return "PRIVATE USE";
1947 return val_to_str(tid, vs_v2_trans_dhgroup, "UNKNOWN-DH-GROUP");
1950 /* For Transform Type 5 (Extended Sequence Numbers), defined Transform */
1952 v2_tid2esnstr(guint16 tid)
1954 static const value_string vs_v2_trans_esn[] = {
1955 { 0, "No Extended Sequence Numbers" },
1956 { 1, "Extended Sequence Numbers" },
1960 return val_to_str(tid, vs_v2_trans_esn, "UNKNOWN-ESN-TYPE");
1966 const char *(*func)(guint16);
1968 { 0, "RESERVED", NULL, },
1969 { 1, "Encryption Algorithm (ENCR)", v2_tid2encstr },
1970 { 2, "Pseudo-random Function (PRF)", v2_tid2prfstr },
1971 { 3, "Integrity Algorithm (INTEG)", v2_tid2iastr },
1972 { 4, "Diffie-Hellman Group (D-H)", v2_tid2dhstr },
1973 { 5, "Extended Sequence Numbers (ESN)", v2_tid2esnstr },
1977 v2_trans2str(guint8 type)
1979 if (type < ARLEN(v2_tid_func)) return v2_tid_func[type].str;
1980 if (type < 240) return "RESERVED TO IANA";
1981 return "PRIVATE USE";
1985 v2_tid2str(guint8 type, guint16 tid)
1987 if (type < ARLEN(v2_tid_func) && v2_tid_func[type].func != NULL) {
1988 return (v2_tid_func[type].func)(tid);
1994 v2_aft2str(guint16 aft)
1996 if (aft < 14 || (aft > 14 && aft < 18)) return "RESERVED";
1997 if (aft == 14) return "Key Length (in bits)";
1998 if (aft >= 18 && aft < 16384) return "RESERVED TO IANA";
1999 return "PRIVATE USE";
2003 dissect_transform2(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2004 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2006 guint8 transform_type;
2007 guint16 transform_id;
2009 transform_type = tvb_get_guint8(tvb, offset);
2010 proto_tree_add_text(tree, tvb, offset, 1,
2011 "Transform type: %s (%u)", v2_trans2str(transform_type), transform_type);
2015 transform_id = tvb_get_ntohs(tvb, offset);
2016 proto_tree_add_text(tree, tvb, offset, 2,
2017 "Transform ID: %s (%u)", v2_tid2str(transform_type, transform_id),
2024 guint16 aft = tvb_get_ntohs(tvb, offset);
2025 guint16 type = aft & 0x7fff;
2030 str = v2_aft2str(type);
2033 val = tvb_get_ntohs(tvb, offset + 2);
2034 proto_tree_add_text(tree, tvb, offset, 4,
2037 v2_attrval2str(type), val);
2042 len = tvb_get_ntohs(tvb, offset + 2);
2044 if (!get_num(tvb, offset + 4, len, &val)) {
2045 proto_tree_add_text(tree, tvb, offset, pack_len,
2046 "%s (%u): <too big (%u bytes)>",
2049 proto_tree_add_text(tree, tvb, offset, pack_len,
2052 v2_attrval2str(type), val);
2061 dissect_key_exch(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2062 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2065 #ifdef HAVE_LIBGCRYPT
2066 decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
2067 #endif /* HAVE_LIBGCRYPT */
2069 if (isakmp_version == 2) {
2070 dhgroup = tvb_get_ntohs(tvb, offset);
2071 proto_tree_add_text(tree, tvb, offset, 2,
2072 "DH Group #: %u", dhgroup);
2077 proto_tree_add_text(tree, tvb, offset, length, "Key Exchange Data (%d bytes / %d bits)",
2078 length, length * 8);
2080 #ifdef HAVE_LIBGCRYPT
2081 if (decr && decr->gi_len == 0 && ADDRESSES_EQUAL(&decr->initiator, &pinfo->src)) {
2082 decr->gi = g_malloc(length);
2083 tvb_memcpy(tvb, decr->gi, offset, length);
2084 decr->gi_len = length;
2085 } else if (decr && decr->gr_len == 0 && !ADDRESSES_EQUAL(&decr->initiator, &pinfo->src)) {
2086 decr->gr = g_malloc(length);
2087 tvb_memcpy(tvb, decr->gr, offset, length);
2088 decr->gr_len = length;
2090 #endif /* HAVE_LIBGCRYPT */
2094 dissect_id(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2095 proto_tree *p _U_, packet_info *pinfo, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2100 asn1_ctx_t asn1_ctx;
2101 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2103 id_type = tvb_get_guint8(tvb, offset);
2104 if(isakmp_version == 1)
2106 proto_tree_add_item(tree, hf_isakmp_id_type_v1, tvb, offset, 1, FALSE);
2107 }else if(isakmp_version == 2)
2109 proto_tree_add_item(tree, hf_isakmp_id_type_v2, tvb, offset, 1, FALSE);
2114 protocol_id = tvb_get_guint8(tvb, offset);
2115 if (protocol_id == 0) {
2116 proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2117 protocol_id, "Protocol ID: Unused");
2119 proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2120 protocol_id, "Protocol ID: %s (%u)",
2121 ipprotostr(protocol_id), protocol_id);
2126 port = tvb_get_ntohs(tvb, offset);
2128 proto_tree_add_uint_format(tree, hf_isakmp_id_port, tvb, offset, 2,
2129 port, "Port: Unused");
2131 proto_tree_add_item(tree, hf_isakmp_id_port, tvb, offset, 2, FALSE);
2136 * It shows strings of all types though some of types are not
2137 * supported in IKEv2 specification actually.
2140 case IKE_ID_IPV4_ADDR:
2141 proto_tree_add_text(tree, tvb, offset, length,
2142 "Identification data: %s",
2143 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2146 case IKE_ID_USER_FQDN:
2147 proto_tree_add_text(tree, tvb, offset, length,
2148 "Identification data: %.*s", length,
2149 tvb_get_ptr(tvb, offset, length));
2151 case IKE_ID_IPV4_ADDR_SUBNET:
2152 case IKE_ID_IPV4_ADDR_RANGE:
2153 proto_tree_add_text(tree, tvb, offset, length,
2154 "Identification data: %s/%s",
2155 ip_to_str(tvb_get_ptr(tvb, offset, 4)),
2156 ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
2158 case IKE_ID_IPV6_ADDR:
2159 proto_tree_add_text(tree, tvb, offset, length,
2160 "Identification data: %s",
2161 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)));
2163 case IKE_ID_IPV6_ADDR_SUBNET:
2164 case IKE_ID_IPV6_ADDR_RANGE:
2165 proto_tree_add_text(tree, tvb, offset, length,
2166 "Identification data: %s/%s",
2167 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)),
2168 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+16, 16)));
2170 case IKE_ID_DER_ASN1_DN:
2171 dissect_x509if_Name(FALSE, tvb, offset, &asn1_ctx, tree,
2172 hf_isakmp_certificate_authority);
2175 proto_tree_add_text(tree, tvb, offset, length, "Identification Data");
2181 dissect_cert(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2182 proto_tree *p _U_, packet_info *pinfo, int isakmp_version,
2183 int unused _U_, guint8 inner_payload _U_)
2186 asn1_ctx_t asn1_ctx;
2187 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
2189 cert_enc = tvb_get_guint8(tvb, offset);
2190 proto_tree_add_uint_format(tree, hf_isakmp_cert_encoding, tvb, offset, 1,
2191 cert_enc, "Certificate encoding: %u - %s",
2192 cert_enc, certtype2str(isakmp_version, cert_enc));
2196 dissect_x509af_Certificate(FALSE, tvb, offset, &asn1_ctx, tree, hf_isakmp_certificate);
2200 dissect_certreq_v1(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2201 proto_tree *p _U_, packet_info *pinfo, int isakmp_version,
2202 int unused _U_, guint8 inner_payload _U_)
2205 asn1_ctx_t asn1_ctx;
2206 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2208 cert_type = tvb_get_guint8(tvb, offset);
2209 proto_tree_add_uint_format(tree, hf_isakmp_certreq_type, tvb, offset, 1,
2210 cert_type, "Certificate type: %u - %s",
2211 cert_type, certtype2str(isakmp_version, cert_type));
2216 if (cert_type == 4){
2217 dissect_x509if_Name(FALSE, tvb, offset, &asn1_ctx, tree, hf_isakmp_certificate_authority);
2219 proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority");
2223 proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority (empty)");
2227 dissect_certreq_v2(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2228 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version,
2229 int unused _U_, guint8 inner_payload _U_)
2233 cert_type = tvb_get_guint8(tvb, offset);
2234 proto_tree_add_text(tree, tvb, offset, 1,
2235 "Certificate type: %u - %s",
2236 cert_type, certtype2str(isakmp_version, cert_type));
2240 /* this is a list of 20 byte SHA-1 hashes */
2241 while (length > 0) {
2242 proto_tree_add_item(tree, hf_isakmp_v2_certificate_authority, tvb, offset, 20, FALSE);
2249 dissect_hash(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2250 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2251 int unused _U_, guint8 inner_payload _U_)
2253 proto_tree_add_text(tree, tvb, offset, length, "Hash Data");
2257 dissect_auth(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2258 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2259 int unused _U_, guint8 inner_payload _U_)
2263 auth = tvb_get_guint8(tvb, offset);
2264 proto_tree_add_text(tree, tvb, offset, 1,
2265 "Auth Method: %s (%u)", v2_auth2str(auth), auth);
2269 proto_tree_add_text(tree, tvb, offset, length, "Authentication Data");
2273 dissect_sig(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2274 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2276 proto_tree_add_text(tree, tvb, offset, length, "Signature Data");
2280 dissect_cisco_fragmentation(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2281 proto_tree *ptree, packet_info *pinfo, int isakmp_version _U_,
2282 int unused _U_, guint8 inner_payload _U_)
2285 guint8 seq; /* Packet sequence number, starting from 1 */
2291 proto_tree_add_item(tree, hf_isakmp_cisco_frag_packetid, tvb, offset, 2, FALSE);
2293 seq = tvb_get_guint8(tvb, offset);
2294 proto_tree_add_item(tree, hf_isakmp_cisco_frag_seq, tvb, offset, 1, FALSE);
2296 last = tvb_get_guint8(tvb, offset);
2297 proto_tree_add_item(tree, hf_isakmp_cisco_frag_last, tvb, offset, 1, FALSE);
2301 /* Start Reassembly stuff for Cisco IKE fragmentation */
2303 gboolean save_fragmented;
2304 tvbuff_t *defrag_isakmp_tvb = NULL;
2305 fragment_data *frag_msg = NULL;
2307 save_fragmented = pinfo->fragmented;
2308 pinfo->fragmented = TRUE;
2309 frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
2310 12345, /*FIXME: Fragmented packet id, guint16, somehow get CKY here */
2311 isakmp_fragment_table, /* list of message fragments */
2312 isakmp_reassembled_table, /* list of reassembled messages */
2313 seq-1, /* fragment sequence number, starting from 0 */
2314 tvb_length_remaining(tvb, offset), /* fragment length - to the end */
2315 last); /* More fragments? */
2316 defrag_isakmp_tvb = process_reassembled_data(tvb, offset, pinfo,
2317 "Reassembled ISAKMP", frag_msg, &isakmp_frag_items,
2320 if (defrag_isakmp_tvb) { /* take it all */
2321 dissect_isakmp(defrag_isakmp_tvb, pinfo, ptree);
2323 if (check_col(pinfo->cinfo, COL_INFO))
2324 col_append_fstr(pinfo->cinfo, COL_INFO,
2325 " (%sMessage fragment %u%s)",
2326 (frag_msg ? "Reassembled + " : ""),
2327 seq, (last ? " - last" : ""));
2328 pinfo->fragmented = save_fragmented;
2330 /* End Reassembly stuff for Cisco IKE fragmentation */
2335 dissect_nonce(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2336 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2337 int unused _U_, guint8 inner_payload _U_)
2339 proto_tree_add_text(tree, tvb, offset, length, "Nonce Data");
2343 v2_ipcomptype2str(guint8 type)
2345 static const value_string vs_v2_ipcomptype[] = {
2347 { 1, "IPCOMP_OUI" },
2348 { 2, "IPCOMP_DEFLATE" },
2349 { 3, "IPCOMP_LZS" },
2350 { 4, "IPCOMP_LZJH" },
2354 if (type >= 5 && type <= 240)
2355 return "RESERVED TO IANA";
2357 return "PRIVATE USE";
2358 return val_to_str(type, vs_v2_ipcomptype, "UNKNOWN-IPCOMP-TYPE");
2362 dissect_notif(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2363 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2371 if (isakmp_version == 1) {
2372 doi = tvb_get_ntohl(tvb, offset);
2373 proto_tree_add_uint_format(tree, hf_isakmp_doi, tvb, offset, 4,
2374 doi, "Domain of interpretation: %s (%u)",
2375 doitype2str(doi), doi);
2380 protocol_id = tvb_get_guint8(tvb, offset);
2381 proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2382 protocol_id, "Protocol ID: %s (%u)",
2383 val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
2387 spi_size = tvb_get_guint8(tvb, offset);
2388 proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
2392 msgtype = tvb_get_ntohs(tvb, offset);
2393 proto_tree_add_uint_format(tree, hf_isakmp_notify_msgtype, tvb, offset, 2,
2394 msgtype, "Message type: %s (%u)",
2395 msgtype2str(isakmp_version, msgtype), msgtype);
2400 proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
2401 tvb_bytes_to_str(tvb, offset, spi_size));
2407 proto_tree_add_text(tree, tvb, offset, length, "Notification Data");
2409 /* notification data */
2410 if (isakmp_version == 2 && msgtype == 16387) {
2411 /* IPCOMP_SUPPORTED */
2412 proto_tree_add_text(tree, tvb, offset, 2,
2413 "IPComp CPI (%u)", tvb_get_ntohs(tvb, offset));
2414 ipcomptype = tvb_get_guint8(tvb, offset + 2);
2415 proto_tree_add_text(tree, tvb, offset + 2, 1,
2416 "Transform ID: %s (%u)",
2417 v2_ipcomptype2str(ipcomptype), ipcomptype);
2425 dissect_delete(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2426 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2427 int unused _U_, guint8 inner_payload _U_)
2435 if (isakmp_version == 1) {
2436 doi = tvb_get_ntohl(tvb, offset);
2437 proto_tree_add_text(tree, tvb, offset, 4,
2438 "Domain of Interpretation: %s (%u)",
2439 doitype2str(doi), doi);
2444 protocol_id = tvb_get_guint8(tvb, offset);
2445 proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2446 protocol_id, "Protocol ID: %s (%u)",
2447 val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
2451 spi_size = tvb_get_guint8(tvb, offset);
2452 proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
2456 num_spis = tvb_get_ntohs(tvb, offset);
2457 proto_tree_add_item(tree, hf_isakmp_num_spis, tvb, offset, 2, FALSE);
2461 for (i = 0; i < num_spis; ++i) {
2462 if (length < spi_size) {
2463 proto_tree_add_text(tree, tvb, offset, length,
2464 "Not enough room in payload for all SPI's");
2467 proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
2468 tvb_bytes_to_str(tvb, offset, spi_size));
2475 vid_to_str(tvbuff_t* tvb, int offset, int length)
2477 const char * vendorstring;
2478 const guint8 * pVID;
2480 pVID = tvb_get_ptr(tvb, offset, length);
2482 if (length == VID_CISCO_FRAG_LEN
2483 && memcmp(pVID, VID_CISCO_FRAG, length) == 0)
2484 vendorstring = "Cisco Fragmentation";
2486 if (length == VID_MS_LEN
2487 && memcmp(pVID, VID_MS_W2K_WXP, length) == 0)
2488 vendorstring = "Microsoft Win2K/WinXP";
2490 if (memcmp(pVID, VID_CP, isakmp_min(VID_CP_LEN, length)) == 0)
2491 vendorstring = "Check Point";
2493 if (memcmp(pVID, VID_CYBERGUARD, isakmp_min(VID_LEN, length)) == 0)
2494 vendorstring = "Cyber Guard";
2496 if (memcmp(pVID, VID_rfc3947, isakmp_min(VID_LEN, length)) == 0)
2497 vendorstring = "RFC 3947 Negotiation of NAT-Traversal in the IKE";
2499 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_1_1_0, isakmp_min(VID_LEN, length)) == 0)
2500 vendorstring = "Ssh Communications Security IPSEC Express version 1.1.0";
2502 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_1_1_1, isakmp_min(VID_LEN, length)) == 0)
2503 vendorstring = "Ssh Communications Security IPSEC Express version 1.1.1";
2505 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_1_1_2, isakmp_min(VID_LEN, length)) == 0)
2506 vendorstring = "Ssh Communications Security IPSEC Express version 1.1.2";
2508 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_1_2_1, isakmp_min(VID_LEN, length)) == 0)
2509 vendorstring = "Ssh Communications Security IPSEC Express version 1.2.1";
2511 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_1_2_2, isakmp_min(VID_LEN, length)) == 0)
2512 vendorstring = "Ssh Communications Security IPSEC Express version 1.2.2";
2514 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_2_0_0, isakmp_min(VID_LEN, length)) == 0)
2515 vendorstring = "Ssh Communications Security IPSEC Express version 2.0.0";
2517 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_2_1_0, isakmp_min(VID_LEN, length)) == 0)
2518 vendorstring = "Ssh Communications Security IPSEC Express version 2.1.0";
2520 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_2_1_1, isakmp_min(VID_LEN, length)) == 0)
2521 vendorstring = "Ssh Communications Security IPSEC Express version 2.1.1";
2523 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_2_1_2, isakmp_min(VID_LEN, length)) == 0)
2524 vendorstring = "Ssh Communications Security IPSEC Express version 2.1.2";
2526 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_3_0_0, isakmp_min(VID_LEN, length)) == 0)
2527 vendorstring = "Ssh Communications Security IPSEC Express version 3.0.0";
2529 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_3_0_1, isakmp_min(VID_LEN, length)) == 0)
2530 vendorstring = "Ssh Communications Security IPSEC Express version 3.0.1";
2532 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_4_0_0, isakmp_min(VID_LEN, length)) == 0)
2533 vendorstring = "Ssh Communications Security IPSEC Express version 4.0.0";
2535 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_4_0_1, isakmp_min(VID_LEN, length)) == 0)
2536 vendorstring = "Ssh Communications Security IPSEC Express version 4.0.1";
2538 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_4_1_0, isakmp_min(VID_LEN, length)) == 0)
2539 vendorstring = "Ssh Communications Security IPSEC Express version 4.1.0";
2541 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_4_1_1, isakmp_min(VID_LEN, length)) == 0)
2542 vendorstring = "Ssh Communications Security IPSEC Express version 4.1.1";
2544 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_5_0, isakmp_min(VID_LEN, length)) == 0)
2545 vendorstring = "Ssh Communications Security IPSEC Express version 5.0";
2547 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_5_0_0, isakmp_min(VID_LEN, length)) == 0)
2548 vendorstring = "Ssh Communications Security IPSEC Express version 5.0.0";
2550 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_5_1_0, isakmp_min(VID_LEN, length)) == 0)
2551 vendorstring = "Ssh Communications Security IPSEC Express version 5.1.0";
2553 if (memcmp(pVID, VID_SSH_IPSEC_EXPRESS_5_1_1, isakmp_min(VID_LEN, length)) == 0)
2554 vendorstring = "Ssh Communications Security IPSEC Express version 5.1.1";
2556 if (memcmp(pVID, VID_SSH_SENTINEL, isakmp_min(VID_LEN, length)) == 0)
2557 vendorstring = "SSH Sentinel";
2559 if (memcmp(pVID, VID_SSH_SENTINEL_1_1, isakmp_min(VID_LEN, length)) == 0)
2560 vendorstring = "SSH Sentinel 1.1";
2562 if (memcmp(pVID, VID_SSH_SENTINEL_1_2, isakmp_min(VID_LEN, length)) == 0)
2563 vendorstring = "SSH Sentinel 1.2";
2565 if (memcmp(pVID, VID_SSH_SENTINEL_1_3, isakmp_min(VID_LEN, length)) == 0)
2566 vendorstring = "SSH Sentinel 1.3";
2568 if (memcmp(pVID, VID_SSH_QUICKSEC_0_9_0, isakmp_min(VID_LEN, length)) == 0)
2569 vendorstring = "SSH Communications Security QuickSec 0.9.0";
2571 if (memcmp(pVID, VID_SSH_QUICKSEC_1_1_0, isakmp_min(VID_LEN, length)) == 0)
2572 vendorstring = "SSH Communications Security QuickSec 1.1.0";
2574 if (memcmp(pVID, VID_SSH_QUICKSEC_1_1_1, isakmp_min(VID_LEN, length)) == 0)
2575 vendorstring = "SSH Communications Security QuickSec 1.1.1";
2577 if (memcmp(pVID, VID_SSH_QUICKSEC_1_1_2, isakmp_min(VID_LEN, length)) == 0)
2578 vendorstring = "SSH Communications Security QuickSec 1.1.2";
2580 if (memcmp(pVID, VID_SSH_QUICKSEC_1_1_3, isakmp_min(VID_LEN, length)) == 0)
2581 vendorstring = "SSH Communications Security QuickSec 1.1.3";
2583 if (memcmp(pVID, VID_draft_huttunen_ipsec_esp_in_udp_01, isakmp_min(VID_LEN, length)) == 0)
2584 vendorstring = "draft-huttunen-ipsec-esp-in-udp-01.txt";
2586 if (memcmp(pVID, VID_draft_stenberg_ipsec_nat_traversal_01, isakmp_min(VID_LEN, length)) == 0)
2587 vendorstring = "draft-stenberg-ipsec-nat-traversal-01";
2589 if (memcmp(pVID, VID_draft_stenberg_ipsec_nat_traversal_02, isakmp_min(VID_LEN, length)) == 0)
2590 vendorstring = "draft-stenberg-ipsec-nat-traversal-02";
2592 if (memcmp(pVID, VID_draft_ietf_ipsec_nat_t_ike_00, isakmp_min(VID_LEN, length)) == 0)
2593 vendorstring = "draft-ietf-ipsec-nat-t-ike-00";
2595 if (memcmp(pVID, VID_draft_ietf_ipsec_nat_t_ike_01, isakmp_min(VID_LEN, length)) == 0)
2596 vendorstring = "draft-ietf-ipsec-nat-t-ike-01";
2598 if (memcmp(pVID, VID_draft_ietf_ipsec_nat_t_ike_02a, isakmp_min(VID_LEN, length)) == 0)
2599 vendorstring = "draft-ietf-ipsec-nat-t-ike-02";
2601 if (memcmp(pVID, VID_draft_ietf_ipsec_nat_t_ike_02b, isakmp_min(VID_LEN, length)) == 0)
2602 vendorstring = "draft-ietf-ipsec-nat-t-ike-02\\n"; /* \n intentional */
2604 if (memcmp(pVID, VID_draft_ietf_ipsec_nat_t_ike_03, isakmp_min(VID_LEN, length)) == 0)
2605 vendorstring = "draft-ietf-ipsec-nat-t-ike-03";
2607 if (memcmp(pVID, VID_draft_beaulieu_ike_xauth_02, isakmp_min(VID_LEN, length)) == 0)
2608 vendorstring = "draft-beaulieu-ike-xauth-02.txt";
2610 if (memcmp(pVID, VID_rfc3706_dpd, isakmp_min(VID_LEN, length)) == 0)
2611 vendorstring = "RFC 3706 Detecting Dead IKE Peers (DPD)";
2613 if (memcmp(pVID, VID_IKE_CHALLENGE_RESPONSE_1, isakmp_min(VID_LEN, length)) == 0)
2614 vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys";
2616 if (memcmp(pVID, VID_IKE_CHALLENGE_RESPONSE_2, isakmp_min(VID_LEN, length)) == 0)
2617 vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys";
2619 if (memcmp(pVID, VID_IKE_CHALLENGE_RESPONSE_REV_1, isakmp_min(VID_LEN, length)) == 0)
2620 vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys (Revised)";
2622 if (memcmp(pVID, VID_IKE_CHALLENGE_RESPONSE_REV_2, isakmp_min(VID_LEN, length)) == 0)
2623 vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys (Revised)";
2625 if (memcmp(pVID, VID_MS_L2TP_IPSEC_VPN_CLIENT, isakmp_min(VID_LEN, length)) == 0)
2626 vendorstring = "Microsoft L2TP/IPSec VPN Client";
2628 if (memcmp(pVID, VID_GSS_API_1, isakmp_min(VID_LEN, length)) == 0)
2629 vendorstring = "A GSS-API Authentication Method for IKE";
2631 if (memcmp(pVID, VID_GSS_API_2, isakmp_min(VID_LEN, length)) == 0)
2632 vendorstring = "A GSS-API Authentication Method for IKE";
2634 if (memcmp(pVID, VID_GSSAPI, isakmp_min(VID_LEN, length)) == 0)
2635 vendorstring = "GSSAPI";
2637 if (memcmp(pVID, VID_MS_NT5_ISAKMPOAKLEY, isakmp_min(VID_LEN, length)) == 0)
2638 vendorstring = "MS NT5 ISAKMPOAKLEY";
2640 if (memcmp(pVID, VID_CISCO_CONCENTRATOR, isakmp_min(VID_LEN, length)) == 0)
2641 vendorstring = "CISCO-CONCENTRATOR";
2643 if (memcmp(pVID, VID_CISCO_UNITY_10, isakmp_min(VID_LEN, length)) == 0)
2644 vendorstring = "CISCO-UNITY-1.0";
2646 if (memcmp(pVID, VID_CISCO_UNITY, isakmp_min(VID_LEN, length)) == 0)
2647 vendorstring = "CISCO-UNITY";
2649 if (memcmp(pVID, VID_draft_ietf_ipsec_antireplay_00, isakmp_min(VID_LEN_8, length)) == 0)
2650 vendorstring = "draft-ietf-ipsec-antireplay-00.txt";
2652 if (memcmp(pVID, VID_draft_ietf_ipsec_heartbeats_00, isakmp_min(VID_LEN_8, length)) == 0)
2653 vendorstring = "draft-ietf-ipsec-heartbeats-00.txt";
2655 vendorstring = tvb_bytes_to_str(tvb, offset, length);
2657 return vendorstring;
2661 dissect_vid(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2662 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2663 int unused _U_, guint8 inner_payload _U_)
2665 guint32 CPproduct, CPversion;
2666 const guint8 * pVID;
2670 pVID = tvb_get_ptr(tvb, offset, length);
2671 pt = proto_tree_add_text(tree, tvb, offset, length, "Vendor ID: %s",
2672 vid_to_str(tvb, offset, length));
2674 if (memcmp(pVID, VID_CP, isakmp_min(VID_CP_LEN, length)) == 0)
2676 offset += VID_CP_LEN;
2677 CPproduct = tvb_get_ntohl(tvb, offset);
2678 ntree = proto_item_add_subtree(pt, ett_isakmp_payload);
2679 pt = proto_tree_add_text(ntree, tvb, offset, sizeof(CPproduct), "Check Point Product: ");
2680 switch (CPproduct) {
2681 case 1: proto_item_append_text(pt, "VPN-1");
2683 case 2: proto_item_append_text(pt, "SecuRemote/SecureClient");
2685 default: proto_item_append_text(pt, "Unknown CP product!");
2688 offset += sizeof(CPproduct);
2689 CPversion = tvb_get_ntohl(tvb, offset);
2690 pt = proto_tree_add_text(ntree, tvb, offset, sizeof(CPversion), "Version: ");
2691 switch (CPversion) {
2692 case 2: proto_item_append_text(pt, "4.1");
2694 case 3: proto_item_append_text(pt, "4.1 SP-1");
2696 case 4002: proto_item_append_text(pt, "4.1 (SP-2 or above)");
2698 case 5000: proto_item_append_text(pt, "NG");
2700 case 5001: proto_item_append_text(pt, "NG Feature Pack 1");
2702 case 5002: proto_item_append_text(pt, "NG Feature Pack 2");
2704 case 5003: proto_item_append_text(pt, "NG Feature Pack 3");
2706 case 5004: proto_item_append_text(pt, "NG with Application Intelligence");
2708 case 5005: proto_item_append_text(pt, "NG with Application Intelligence R55");
2710 default: proto_item_append_text(pt, " Unknown CP version!");
2713 offset += sizeof(CPversion);
2714 proto_tree_add_text(ntree, tvb, offset, length - VID_CP_LEN - sizeof(CPproduct) - sizeof(CPversion),"Check Point Vendor ID parameters");
2717 /* Returns the number of bytes consumed by this option. */
2719 dissect_config_attribute(tvbuff_t *tvb, proto_tree *cfg_attr_type_tree, int offset, int isakmp_version)
2721 guint optlen, cfg_attr_type, len = 0;
2723 proto_item *cfg_attr_type_item;
2724 proto_tree *sub_cfg_attr_type_tree = NULL;
2726 cfg_attr_type = tvb_get_ntohs(tvb, offset);
2727 optlen = tvb_get_ntohs(tvb, offset+2);
2731 if (cfg_attr_type & 0x8000) {
2732 cfg_attr_type = cfg_attr_type & 0x7fff;
2737 if (isakmp_version == 1) {
2738 cfg_attr_type_item = proto_tree_add_text(cfg_attr_type_tree, tvb, offset, 2+len+optlen, "Attribute Type: (t=%d,l=%d) %s", cfg_attr_type, optlen, rval_to_str(cfg_attr_type,vs_v1_cfgattr,"Unknown Attribute Type (%02d)") );
2739 sub_cfg_attr_type_tree = proto_item_add_subtree(cfg_attr_type_item, ett_isakmp_cfg_attr);
2740 proto_tree_add_uint(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_type_v1, tvb, offset, 2, cfg_attr_type);
2741 } else if (isakmp_version == 2) {
2742 cfg_attr_type_item = proto_tree_add_text(cfg_attr_type_tree, tvb, offset, 2+len+optlen, "Attribute Type: (t=%d,l=%d) %s", cfg_attr_type, optlen, rval_to_str(cfg_attr_type,vs_v2_cfgattr,"Unknown Attribute Type (%02d)") );
2743 sub_cfg_attr_type_tree = proto_item_add_subtree(cfg_attr_type_item, ett_isakmp_cfg_attr);
2744 proto_tree_add_uint(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_type_v2, tvb, offset, 2, cfg_attr_type);
2749 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_length, tvb, offset, 2, FALSE);
2754 proto_tree_add_text(sub_cfg_attr_type_tree, tvb, offset, 0,"Attribut value is empty");
2757 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_value, tvb, offset, optlen, FALSE);
2758 switch (cfg_attr_type) {
2759 case INTERNAL_IP4_ADDRESS: /* 1 */
2760 offset_end = offset + optlen;
2764 while (offset_end-offset > 0)
2766 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_address, tvb, offset, 4, FALSE);
2772 case INTERNAL_IP4_NETMASK: /* 2 */
2773 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_netmask, tvb, offset, 4, FALSE);
2775 case INTERNAL_IP4_DNS: /* 3 */
2776 offset_end = offset + optlen;
2780 while (offset_end-offset > 0)
2782 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_dns, tvb, offset, 4, FALSE);
2788 case INTERNAL_IP4_NBNS: /* 4 */
2789 offset_end = offset + optlen;
2793 while (offset_end-offset > 0)
2795 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_nbns, tvb, offset, 4, FALSE);
2801 case INTERNAL_ADDRESS_EXPIRY: /* 5 */
2802 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_address_expiry, tvb, offset, 4, FALSE);
2804 case INTERNAL_IP4_DHCP: /* 6 */
2805 offset_end = offset + optlen;
2809 while (offset_end-offset > 0)
2811 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_dhcp, tvb, offset, 4, FALSE);
2817 case APPLICATION_VERSION: /* 7 */
2818 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_application_version, tvb, offset, optlen, FALSE);
2820 case INTERNAL_IP6_ADDRESS: /* 8 */
2821 offset_end = offset + optlen;
2825 while (offset_end-offset > 0)
2827 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_address, tvb, offset, 16, FALSE);
2833 case INTERNAL_IP6_NETMASK: /* 9 Only in IKEv1 */
2834 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_netmask, tvb, offset, 18, FALSE);
2836 case INTERNAL_IP6_DNS: /* 10 */
2837 offset_end = offset + optlen;
2841 while (offset_end-offset > 0)
2843 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_dns, tvb, offset, 16, FALSE);
2849 case INTERNAL_IP6_NBNS: /* 11 */
2850 offset_end = offset + optlen;
2854 while (offset_end-offset > 0)
2856 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_nbns, tvb, offset, 16, FALSE);
2862 case INTERNAL_IP6_DHCP: /* 12 */
2863 offset_end = offset + optlen;
2867 while (offset_end-offset > 0)
2869 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_dhcp, tvb, offset, 16, FALSE);
2875 case INTERNAL_IP4_SUBNET: /* 13 */
2876 offset_end = offset + optlen;
2880 while (offset_end-offset > 0)
2882 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_subnet_ip, tvb, offset, 4, FALSE);
2883 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_subnet_netmask, tvb, offset, 4, FALSE);
2890 SUPPORTED_ATTRIBUTES (14) a variable 0 or multiples of 2
2891 INTERNAL_IP6_SUBNET (15) a variable 0 or 17 octets ( This attribute is made up of two fields:
2892 the first is a sixteen-octet IPv6 address and the second is a one-octet prefix-length )
2894 case XAUTH_TYPE: /* 16520 */
2895 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_type, tvb, offset, optlen, FALSE);
2897 case XAUTH_USER_NAME: /* 16521 */
2898 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_user_name, tvb, offset, optlen, FALSE);
2900 case XAUTH_USER_PASSWORD: /* 16522 */
2901 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_user_password, tvb, offset, optlen, FALSE);
2903 case XAUTH_PASSCODE: /* 16523 */
2904 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_passcode, tvb, offset, optlen, FALSE);
2906 case XAUTH_MESSAGE: /* 16524 */
2907 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_message, tvb, offset, optlen, FALSE);
2909 case XAUTH_CHALLENGE: /* 16525 */
2910 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_challenge, tvb, offset, optlen, FALSE);
2912 case XAUTH_DOMAIN: /* 16526 */
2913 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_domain, tvb, offset, optlen, FALSE);
2915 case XAUTH_STATUS: /* 16527 */
2916 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_status, tvb, offset, optlen, FALSE);
2918 case XAUTH_NEXT_PIN: /* 16528 */
2919 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_next_pin, tvb, offset, optlen, FALSE);
2921 case XAUTH_ANSWER: /* 16527 */
2922 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_answer, tvb, offset, optlen, FALSE);
2925 case UNITY_BANNER: /* 28672 */
2926 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_unity_banner, tvb, offset, optlen, FALSE);
2928 /* TODO: Support other UNITY Attributs ! */
2930 /* No Default Action */
2934 return 2+len+optlen;
2937 dissect_config(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2938 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version,
2939 int unused _U_, guint8 inner_payload _U_)
2942 offset_end = offset + length;
2943 if (isakmp_version == 1) {
2945 proto_tree_add_item(tree, hf_isakmp_cfg_type_v1,tvb, offset, 1, FALSE);
2948 proto_tree_add_item(tree, hf_isakmp_cfg_identifier,tvb, offset, 1, FALSE);
2951 } else if (isakmp_version == 2) {
2953 proto_tree_add_item(tree, hf_isakmp_cfg_type_v2,tvb, offset, 1, FALSE);
2958 while(offset < offset_end) {
2959 offset += dissect_config_attribute(tvb, tree, offset, isakmp_version);
2964 dissect_nat_discovery(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2965 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2967 proto_tree_add_item(tree, hf_isakmp_nat_hash, tvb, offset, length, FALSE);
2971 dissect_nat_original_address(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2972 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2976 id_type = tvb_get_guint8(tvb, offset);
2977 if(isakmp_version == 1)
2979 proto_tree_add_item(tree, hf_isakmp_id_type_v1, tvb, offset, 1, FALSE);
2980 }else if(isakmp_version == 2)
2982 proto_tree_add_item(tree, hf_isakmp_id_type_v2, tvb, offset, 1, FALSE);
2987 offset += 3; /* reserved */
2991 case IKE_ID_IPV4_ADDR:
2992 proto_tree_add_item(tree, hf_isakmp_nat_original_address_ipv4, tvb, offset, 4, FALSE);
2995 case IKE_ID_IPV6_ADDR:
2996 proto_tree_add_item(tree, hf_isakmp_nat_original_address_ipv6, tvb, offset, 16, FALSE);
3005 dissect_ts(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
3006 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
3008 guint8 num, tstype, protocol_id, addrlen;
3011 proto_tree_add_text(tree, tvb, offset, length, "Traffic Selector");
3013 num = tvb_get_guint8(tvb, offset);
3014 proto_item_append_text(tree," # %d", num);
3015 proto_tree_add_text(tree, tvb, offset, 1,
3016 "Number of TSs: %u", num);
3020 while (length > 0) {
3021 tstype = tvb_get_guint8(tvb, offset);
3022 proto_tree_add_text(tree, tvb, offset, 1,
3024 v2_tstype2str(tstype), tstype);
3026 case IKEV2_TS_IPV4_ADDR_RANGE:
3029 case IKEV2_TS_IPV6_ADDR_RANGE:
3033 proto_item_append_text(tree, "unknown TS data (aborted decoding): 0x%s",
3034 tvb_bytes_to_str(tvb, offset, length));
3039 * XXX should the remaining of the length check be done here ?
3040 * it seems other routines don't check the length.
3042 if (length < (8 + addrlen * 2)) {
3043 proto_tree_add_text(tree, tvb, offset, length,
3044 "Length mismatch (%u)", length);
3050 protocol_id = tvb_get_guint8(tvb, offset);
3051 proto_tree_add_text(tree, tvb, offset, 1,
3052 "Protocol ID: (%u)", protocol_id);
3056 len = tvb_get_ntohs(tvb, offset);
3057 proto_tree_add_text(tree, tvb, offset, 2,
3058 "Selector Length: %u", len);
3062 port = tvb_get_ntohs(tvb, offset);
3063 proto_tree_add_text(tree, tvb, offset, 2,
3064 "Start Port: (%u)", port);
3068 port = tvb_get_ntohs(tvb, offset);
3069 proto_tree_add_text(tree, tvb, offset, 2,
3070 "End Port: (%u)", port);
3075 case IKEV2_TS_IPV4_ADDR_RANGE:
3076 proto_tree_add_text(tree, tvb, offset, length,
3077 "Starting Address: %s",
3078 ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
3081 proto_tree_add_text(tree, tvb, offset, length,
3082 "Ending Address: %s",
3083 ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
3087 case IKEV2_TS_IPV6_ADDR_RANGE:
3088 proto_tree_add_text(tree, tvb, offset, length,
3089 "Starting Address: %s",
3090 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, addrlen)));
3093 proto_tree_add_text(tree, tvb, offset, length,
3094 "Ending Address: %s",
3095 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, addrlen)));
3104 dissect_enc(tvbuff_t *tvb,
3109 #ifdef HAVE_LIBGCRYPT
3112 packet_info *pinfo _U_,
3114 int isakmp_version _U_,
3116 #ifdef HAVE_LIBGCRYPT
3117 guint8 inner_payload)
3119 guint8 inner_payload _U_)
3122 #ifdef HAVE_LIBGCRYPT
3123 ikev2_decrypt_data_t *key_info = NULL;
3124 gint iv_len, encr_data_len, icd_len, encr_key_len, decr_data_len, md_len;
3126 guchar *iv = NULL, *encr_data = NULL, *decr_data = NULL, *entire_message = NULL, *md = NULL;
3127 gcry_cipher_hd_t cipher_hd;
3129 gcry_error_t err = 0;
3130 proto_item *item = NULL, *icd_item = NULL, *encr_data_item = NULL, *padlen_item = NULL;
3131 tvbuff_t *decr_tvb = NULL;
3133 proto_tree *decr_tree = NULL, *decr_payloads_tree = NULL;
3136 if (pinfo->private_data) {
3137 key_info = (ikev2_decrypt_data_t*)(pinfo->private_data);
3138 encr_key_len = key_info->encr_spec->key_len;
3139 iv_len = key_info->encr_spec->iv_len;
3140 icd_len = key_info->auth_spec->trunc_len;
3141 encr_data_len = length - iv_len - icd_len;
3144 * Zero or negative length of encrypted data shows that the user specified
3145 * wrong encryption algorithm and/or authentication algorithm.
3147 if (encr_data_len <= 0) {
3148 item = proto_tree_add_text(tree, tvb, offset, length, "Not enough data for IV, Encrypted data and ICD.");
3149 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Not enough data in IKEv2 Encrypted payload");
3150 PROTO_ITEM_SET_GENERATED(item);
3155 * Add the IV to the tree and store it in a packet scope buffer for later decryption
3156 * if the specified encryption algorithm uses IV.
3159 proto_tree_add_text(tree, tvb, offset, iv_len, "Initialization Vector (%d bytes): 0x%s",
3160 iv_len, tvb_bytes_to_str(tvb, offset, iv_len));
3161 iv = ep_tvb_memdup(tvb, offset, iv_len);
3167 * Add the encrypted portion to the tree and store it in a packet scope buffer for later decryption.
3169 encr_data_item = proto_tree_add_text(tree, tvb, offset, encr_data_len, "Encrypted Data (%d bytes)", encr_data_len);
3170 encr_data = ep_tvb_memdup(tvb, offset, encr_data_len);
3171 offset += encr_data_len;
3174 * Add the ICD (Integrity Checksum Data) to the tree before decryption to ensure
3175 * the ICD be displayed even if the decryption fails.
3178 icd_item = proto_tree_add_text(tree, tvb, offset, icd_len, "Integrity Checksum Data (%d bytes) ", icd_len);
3181 * Recalculate ICD value if the specified authentication algorithm allows it.
3183 if (key_info->auth_spec->gcry_alg) {
3184 err = gcry_md_open(&md_hd, key_info->auth_spec->gcry_alg, key_info->auth_spec->gcry_flag);
3186 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %d: gcry_md_open failed: %s",
3187 key_info->auth_spec->gcry_alg, gcry_strerror(err)));
3189 err = gcry_md_setkey(md_hd, key_info->auth_key, key_info->auth_spec->key_len);
3191 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %s, key length %u: gcry_md_setkey failed: %s",
3192 gcry_md_algo_name(key_info->auth_spec->gcry_alg), key_info->auth_spec->key_len, gcry_strerror(err)));
3195 /* Calculate hash over the bytes from the beginning of the ISAKMP header to the right before the ICD. */
3196 entire_message = ep_tvb_memdup(tvb, 0, offset);
3197 gcry_md_write(md_hd, entire_message, offset);
3198 md = gcry_md_read(md_hd, 0);
3199 md_len = gcry_md_get_algo_dlen(key_info->auth_spec->gcry_alg);
3200 if (md_len < icd_len) {
3201 gcry_md_close(md_hd);
3202 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %s: gcry_md_get_algo_dlen returned %d which is smaller than icd length %d",
3203 gcry_md_algo_name(key_info->auth_spec->gcry_alg), md_len, icd_len));
3205 if (tvb_memeql(tvb, offset, md, icd_len) == 0) {
3206 proto_item_append_text(icd_item, "[correct]");
3208 proto_item_append_text(icd_item, "[incorrect, should be %s]", bytes_to_str(md, icd_len));
3209 expert_add_info_format(pinfo, icd_item, PI_CHECKSUM, PI_WARN, "IKEv2 Integrity Checksum Data is incorrect");
3211 gcry_md_close(md_hd);
3213 proto_item_append_text(icd_item, "[not validated]");
3219 * Confirm encrypted data length is multiple of block size.
3221 if (encr_data_len % key_info->encr_spec->block_len != 0) {
3222 proto_item_append_text(encr_data_item, "[Invalid length, should be a multiple of block size (%u)]",
3223 key_info->encr_spec->block_len);
3224 expert_add_info_format(pinfo, encr_data_item, PI_MALFORMED, PI_WARN, "Encrypted data length isn't a multiple of block size");
3229 * Allocate buffer for decrypted data.
3231 decr_data = (guchar*)g_malloc(encr_data_len);
3232 decr_data_len = encr_data_len;
3235 * If the cipher is NULL, just copy the encrypted data to the decrypted data buffer.
3236 * And otherwise perform decryption with libgcrypt.
3238 if (key_info->encr_spec->number == IKEV2_ENCR_NULL) {
3239 memcpy(decr_data, encr_data, decr_data_len);
3241 err = gcry_cipher_open(&cipher_hd, key_info->encr_spec->gcry_alg, key_info->encr_spec->gcry_mode, 0);
3244 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, mode %d: gcry_cipher_open failed: %s",
3245 key_info->encr_spec->gcry_alg, key_info->encr_spec->gcry_mode, gcry_strerror(err)));
3247 err = gcry_cipher_setkey(cipher_hd, key_info->encr_key, key_info->encr_spec->key_len);
3250 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, key length %d: gcry_cipher_setkey failed: %s",
3251 key_info->encr_spec->gcry_alg, key_info->encr_spec->key_len, gcry_strerror(err)));
3253 err = gcry_cipher_setiv(cipher_hd, iv, iv_len);
3256 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, iv length %d: gcry_cipher_setiv failed: %s",
3257 key_info->encr_spec->gcry_alg, iv_len, gcry_strerror(err)));
3259 err = gcry_cipher_decrypt(cipher_hd, decr_data, decr_data_len, encr_data, encr_data_len);
3262 REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d: gcry_cipher_decrypt failed: %s",
3263 key_info->encr_spec->gcry_alg, gcry_strerror(err)));
3265 gcry_cipher_close(cipher_hd);
3269 decr_tvb = tvb_new_real_data(decr_data, decr_data_len, decr_data_len);
3270 tvb_set_free_cb(decr_tvb, g_free);
3271 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
3272 add_new_data_source(pinfo, decr_tvb, "Decrypted Data");
3273 item = proto_tree_add_text(tree, decr_tvb, 0, decr_data_len, "Decrypted Data (%d bytes)", decr_data_len);
3274 /* Move the ICD item to the bottom of the tree. */
3276 proto_tree_move_item(tree, item, icd_item);
3278 decr_tree = proto_item_add_subtree(item, ett_isakmp_decrypted_data);
3280 pad_len = tvb_get_guint8(decr_tvb, decr_data_len - 1);
3281 payloads_len = decr_data_len - 1 - pad_len;
3283 if (payloads_len > 0) {
3284 item = proto_tree_add_text(decr_tree, decr_tvb, 0, payloads_len, "Contained Payloads (total %d bytes)", payloads_len);
3285 decr_payloads_tree = proto_item_add_subtree(item, ett_isakmp_decrypted_payloads);
3288 padlen_item = proto_tree_add_text(decr_tree, decr_tvb, payloads_len + pad_len, 1, "Pad Length: %d", pad_len);
3290 if (payloads_len < 0) {
3291 proto_item_append_text(padlen_item, " [too long]");
3292 expert_add_info_format(pinfo, padlen_item, PI_MALFORMED, PI_WARN, "Pad length is too big");
3294 item = proto_tree_add_text(decr_tree, decr_tvb, payloads_len, pad_len, "Padding (%d bytes)", pad_len);
3295 proto_tree_move_item(decr_tree, item, padlen_item);
3300 * We dissect the inner payloads at last in order to ensure displaying Padding, Pad Length and ICD
3301 * even if the dissection fails. This may occur when the user specify wrong encryption key.
3303 if (decr_payloads_tree) {
3304 dissect_payloads(decr_tvb, decr_payloads_tree, decr_tree, isakmp_version, inner_payload, 0, payloads_len, pinfo);
3307 #endif /* HAVE_LIBGCRYPT */
3308 proto_tree_add_text(tree, tvb, offset, 4, "Initialization Vector: 0x%s",
3309 tvb_bytes_to_str(tvb, offset, 4));
3310 proto_tree_add_text(tree, tvb, offset + 4, length, "Encrypted Data");
3311 #ifdef HAVE_LIBGCRYPT
3313 #endif /* HAVE_LIBGCRYPT */
3317 dissect_eap(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
3318 proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
3320 tvbuff_t *eap_tvb = NULL;
3322 eap_tvb = tvb_new_subset(tvb, offset,length, length );
3323 if ((eap_tvb != NULL)&& eap_handle != NULL){
3324 call_dissector(eap_handle, eap_tvb, pinfo, tree);
3326 proto_tree_add_text(tree, tvb, offset, length, "EAP Message");
3331 payloadtype2str(int isakmp_version, guint8 type)
3333 struct payload_func *f;
3335 if ((f = getpayload_func(type, isakmp_version)) != NULL)
3338 if (isakmp_version == 1) {
3341 return "Private USE";
3342 } else if (isakmp_version == 2) {
3344 return "PRIVATE USE";
3346 return "RESERVED TO IANA";
3349 return "UNKNOWN-ISAKMP-VERSION";
3353 exchtype2str(int isakmp_version, guint8 type)
3355 static const value_string vs_v1_exchange[] = {
3358 { 2, "Identity Protection (Main Mode)" },
3359 { 3, "Authentication Only" },
3360 { 4, "Aggressive" },
3361 { 5, "Informational" },
3362 { 6, "Transaction (Config Mode)" },
3363 { 32, "Quick Mode" },
3364 { 33, "New Group Mode" },
3368 static const value_string vs_v2_exchange[] = {
3369 { 34, "IKE_SA_INIT" },
3370 { 35, "IKE_AUTH " },
3371 { 36, "CREATE_CHILD_SA" },
3372 { 37, "INFORMATIONAL" },
3376 if (isakmp_version == 1) {
3377 if (type > 6 && type < 32)
3378 return "ISAKMP Future Use";
3379 if (type > 33 && type < 240)
3380 return "DOI Specific Use";
3381 return val_to_str(type, vs_v1_exchange, "Private Use");
3382 } else if (isakmp_version == 2) {
3385 if (type > 37 && type < 240)
3386 return "Reserved for IKEv2+";
3387 return val_to_str(type, vs_v2_exchange, "Reserved for private use");
3389 return "UNKNOWN-ISAKMP-VERSION";
3393 doitype2str(guint32 type)
3395 if (type == 1) return "IPSEC";
3396 return "Unknown DOI Type";
3400 msgtype2str(int isakmp_version, guint16 type)
3402 static const value_string vs_v1_notifmsg[] = {
3404 { 1, "INVALID-PAYLOAD-TYPE" },
3405 { 2, "DOI-NOT-SUPPORTED" },
3406 { 3, "SITUATION-NOT-SUPPORTED" },
3407 { 4, "INVALID-COOKIE" },
3408 { 5, "INVALID-MAJOR-VERSION" },
3409 { 6, "INVALID-MINOR-VERSION" },
3410 { 7, "INVALID-EXCHANGE-TYPE" },
3411 { 8, "INVALID-FLAGS" },
3412 { 9, "INVALID-MESSAGE-ID" },
3413 { 10, "INVALID-PROTOCOL-ID" },
3414 { 11, "INVALID-SPI" },
3415 { 12, "INVALID-TRANSFORM-ID" },
3416 { 13, "ATTRIBUTES-NOT-SUPPORTED" },
3417 { 14, "NO-PROPOSAL-CHOSEN" },
3418 { 15, "BAD-PROPOSAL-SYNTAX" },
3419 { 16, "PAYLOAD-MALFORMED" },
3420 { 17, "INVALID-KEY-INFORMATION" },
3421 { 18, "INVALID-ID-INFORMATION" },
3422 { 19, "INVALID-CERT-ENCODING" },
3423 { 20, "INVALID-CERTIFICATE" },
3424 { 21, "CERT-TYPE-UNSUPPORTED" },
3425 { 22, "INVALID-CERT-AUTHORITY" },
3426 { 23, "INVALID-HASH-INFORMATION" },
3427 { 24, "AUTHENTICATION-FAILED" },
3428 { 25, "INVALID-SIGNATURE" },
3429 { 26, "ADDRESS-NOTIFICATION" },
3430 { 27, "NOTIFY-SA-LIFETIME" },
3431 { 28, "CERTIFICATE-UNAVAILABLE" },
3432 { 29, "UNSUPPORTED-EXCHANGE-TYPE" },
3433 { 30, "UNEQUAL-PAYLOAD-LENGTHS" },
3434 { 8192, "RESERVED" },
3435 { 16384, "CONNECTED" },
3436 { 24576, "RESPONDER-LIFETIME" },
3437 { 24577, "REPLAY-STATUS" },
3438 { 24578, "INITIAL-CONTACT" },
3442 static const value_string vs_v2_notifmsg[] = {
3444 { 4, "INVALID_IKE_SPI" },
3445 { 5, "INVALID_MAJOR_VERSION" },
3446 { 7, "INVALID_SYNTAX" },
3447 { 9, "INVALID_MESSAGE_ID" },
3448 { 11, "INVALID_SPI" },
3449 { 14, "NO_PROPOSAL_CHOSEN" },
3450 { 17, "INVALID_KE_PAYLOAD" },
3451 { 24, "AUTHENTICATION_FAILED" },
3452 { 34, "SINGLE_PAIR_REQUIRED" },
3453 { 35, "NO_ADDITIONAL_SAS" },
3454 { 36, "INTERNAL_ADDRESS_FAILURE" },
3455 { 37, "FAILED_CP_REQUIRED" },
3456 { 38, "TS_UNACCEPTABLE" },
3457 { 39, "INVALID_SELECTORS" },
3458 { 40, "UNACCEPTABLE_ADDRESSES" },
3459 { 41, "UNEXPECTED_NAT_DETECTED" },
3460 { 16384, "INITIAL_CONTACT" },
3461 { 16385, "SET_WINDOW_SIZE" },
3462 { 16386, "ADDITIONAL_TS_POSSIBLE" },
3463 { 16387, "IPCOMP_SUPPORTED" },
3464 { 16388, "NAT_DETECTION_SOURCE_IP" },
3465 { 16389, "NAT_DETECTION_DESTINATION_IP" },
3466 { 16390, "COOKIE" },
3467 { 16391, "USE_TRANSPORT_MODE" },
3468 { 16392, "HTTP_CERT_LOOKUP_SUPPORTED" },
3469 { 16393, "REKEY_SA" },
3470 { 16394, "ESP_TFC_PADDING_NOT_SUPPORTED" },
3471 { 16395, "NON_FIRST_FRAGMENTS_ALSO" },
3472 { 16396, "MOBIKE_SUPPORTED" },
3473 { 16397, "ADDITIONAL_IP4_ADDRESS" },
3474 { 16398, "ADDITIONAL_IP6_ADDRESS" },
3475 { 16399, "NO_ADDITIONAL_ADDRESSES" },
3476 { 16400, "UPDATE_SA_ADDRESSES" },
3477 { 16401, "COOKIE2" },
3478 { 16402, "NO_NATS_ALLOWED" },
3482 if (isakmp_version == 1) {
3483 if (type > 30 && type < 8192)
3484 return "RESERVED (Future Use)";
3485 if (type > 8192 && type < 16384)
3486 return "Private Use";
3487 if (type > 16384 && type < 24576)
3488 return "RESERVED (Future Use) - status";
3489 if (type > 24578 && type < 32768)
3490 return "DOI-specific codes";
3491 if (type > 32767 && type < 40960)
3492 return "Private Use - status";
3493 if (type > 40959 && type < 65535)
3494 return "RESERVED (Future Use) - status (2)";
3495 return val_to_str(type, vs_v1_notifmsg, "UNKNOWN-NOTIFY-MESSAGE-TYPE");
3496 } else if (isakmp_version == 2) {
3497 if (type >= 42 && type <= 8191)
3498 return "RESERVED TO IANA - Error types";
3499 if (type >= 16403 && type <= 40959)
3500 return "RESERVED TO IANA - STATUS TYPES";
3501 if (type >= 8192 && type <= 16383)
3502 return "Private Use - Errors";
3504 return "Private Use - STATUS TYPES";
3505 return val_to_str(type, vs_v2_notifmsg, "UNKNOWN-NOTIFY-MESSAGE-TYPE");
3507 return "UNKNOWN-ISAKMP-VERSION";
3511 situation2str(guint32 type)
3514 #define SIT_MSG_NUM 1024
3515 #define SIT_IDENTITY 0x01
3516 #define SIT_SECRECY 0x02
3517 #define SIT_INTEGRITY 0x04
3519 static char msg[SIT_MSG_NUM];
3521 const char * sep = "";
3524 if (type & SIT_IDENTITY) {
3525 ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sIDENTITY", sep);
3526 if (ret >= SIT_MSG_NUM-n) {
3533 if (type & SIT_SECRECY) {
3534 if (n >= SIT_MSG_NUM) {
3538 ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sSECRECY", sep);
3539 if (ret >= SIT_MSG_NUM-n) {
3546 if (type & SIT_INTEGRITY) {
3547 if (n >= SIT_MSG_NUM) {
3551 ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sINTEGRITY", sep);
3552 if (ret >= SIT_MSG_NUM-n) {
3564 v2_attrval2str(guint16 att_type)
3568 return "Key-Length";
3570 return "UNKNOWN-ATTRIBUTE-TYPE";
3575 v1_attrval2str(int ike_p1, guint16 att_type, guint32 value)
3577 static const value_string vs_v1_attrval_lttype[] = {
3584 static const value_string vs_v1_attrval_encap[] = {
3588 { 3, "UDP-Encapsulated-Tunnel" }, /* http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-05.txt */
3589 { 4, "UDP-Encapsulated-Transport" }, /* http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-05.txt */
3590 { 61440, "Check Point IPSec UDP Encapsulation" },
3591 { 61443, "UDP-Encapsulated-Tunnel (draft)" },
3592 { 61444, "UDP-Encapsulated-Transport (draft)" },
3596 static const value_string vs_v1_attrval_auth[] = {
3602 { 5, "HMAC-SHA2-256" },
3603 { 6, "HMAC-SHA2-384" },
3604 { 7, "HMAC-SHA2-512" },
3608 static const value_string vs_v1_attrval_enc[] = {
3610 { ENC_DES_CBC, "DES-CBC" },
3611 { ENC_IDEA_CBC, "IDEA-CBC" },
3612 { ENC_BLOWFISH_CBC, "BLOWFISH-CBC" },
3613 { ENC_RC5_R16_B64_CBC, "RC5-R16-B64-CBC" },
3614 { ENC_3DES_CBC, "3DES-CBC" },
3615 { ENC_CAST_CBC, "CAST-CBC" },
3616 { ENC_AES_CBC, "AES-CBC" },
3620 static const value_string vs_v1_attrval_hash[] = {
3622 { HMAC_MD5, "MD5" },
3623 { HMAC_SHA, "SHA" },
3624 { HMAC_TIGER, "TIGER" },
3625 { HMAC_SHA2_256, "SHA2-256" },
3626 { HMAC_SHA2_384, "SHA2-384" },
3627 { HMAC_SHA2_512, "SHA2-512" },
3631 static const value_string vs_v1_attrval_authmeth[] = {
3637 { 5, "RSA-Revised-ENC" },
3638 { 6, "Encryption with El-Gamal" },
3639 { 7, "Revised encryption with El-Gamal" },
3640 { 8, "ECDSA signatures" },
3641 { 9, "AES-XCBC-MAC" },
3642 { 64221, "HybridInitRSA" },
3643 { 64222, "HybridRespRSA" },
3644 { 64223, "HybridInitDSS" },
3645 { 64224, "HybridRespDSS" },
3646 { 65001, "XAUTHInitPreShared" },
3647 { 65002, "XAUTHRespPreShared" },
3648 { 65003, "XAUTHInitDSS" },
3649 { 65004, "XAUTHRespDSS" },
3650 { 65005, "XAUTHInitRSA" },
3651 { 65006, "XAUTHRespRSA" },
3652 { 65007, "XAUTHInitRSAEncryption" },
3653 { 65008, "XAUTHRespRSAEncryption" },
3654 { 65009, "XAUTHInitRSARevisedEncryption" },
3655 { 65010, "XAUTHRespRSARevisedEncryption" },
3659 static const value_string vs_v1_attrval_grpdesc[] = {
3660 { 0, "UNDEFINED - 0" },
3661 { 1, "Default 768-bit MODP group" },
3662 { 2, "Alternate 1024-bit MODP group" },
3663 { 3, "EC2N group on GP[2^155] group" },
3664 { 4, "EC2N group on GP[2^185] group" },
3665 { 5, "1536 bit MODP group" },
3666 { 6, "EC2N group over GF[2^163]" },
3667 { 7, "EC2N group over GF[2^163]" },
3668 { 8, "EC2N group over GF[2^283]" },
3669 { 9, "EC2N group over GF[2^283]" },
3670 { 10, "EC2N group over GF[2^409]" },
3671 { 11, "EC2N group over GF[2^409]" },
3672 { 12, "EC2N group over GF[2^571]" },
3673 { 13, "EC2N group over GF[2^571]" },
3674 { 14, "2048 bit MODP group" },
3675 { 15, "3072 bit MODP group" },
3676 { 16, "4096 bit MODP group" },
3677 { 17, "6144 bit MODP group" },
3678 { 18, "8192 bit MODP group" },
3679 { 19, "256-bit random curve group" },
3680 { 20, "384-bit random curve group" },
3681 { 21, "521-bit random curve group" },
3682 { 22, "192-bit random curve group" },
3683 { 23, "EC2N group over GF[2^163]" },
3684 { 24, "224-bit random curve group" },
3685 { 25, "EC2N group over GF[2^233]" },
3686 { 26, "EC2N group over GF[2^233]" },
3690 static const value_string vs_v1_attrval_grptype[] = {
3691 { 0, "UNDEFINED - 0" },
3698 static const value_string vs_v1_attrval_lifetype[] = {
3699 { 0, "UNDEFINED - 0" },
3705 if (value == 0) return "RESERVED";
3710 return val_to_str(value, vs_v1_attrval_lttype, "UNKNOWN-LIFETIME-TYPE");
3712 return "Duration-Value";
3714 return "Group-Value";
3716 return val_to_str(value, vs_v1_attrval_encap, "UNKNOWN-ENCAPSULATION-VALUE");
3718 return val_to_str(value, vs_v1_attrval_auth, "UNKNOWN-AUTHENTICATION-VALUE");
3720 return "Key-Length";
3722 return "Key-Rounds";
3724 return "Compress-Dictionary-size";
3726 return "Compress Private Algorithm";
3728 return "UNKNOWN-ATTRIBUTE-TYPE";
3734 return val_to_str(value, vs_v1_attrval_enc, "UNKNOWN-ENCRYPTION-ALG");
3736 return val_to_str(value, vs_v1_attrval_hash, "UNKNOWN-HASH-ALG");
3738 return val_to_str(value, vs_v1_attrval_authmeth, "UNKNOWN-AUTH-METHOD");
3740 return val_to_str(value, vs_v1_attrval_grpdesc, "UNKNOWN-GROUP-DESCRIPTION");
3747 return "Group-Value";
3749 return val_to_str(value, vs_v1_attrval_grptype, "UNKNOWN-GROUP-TYPE");
3751 return val_to_str(value, vs_v1_attrval_lifetype, "UNKNOWN-LIFE-TYPE");
3753 return "Duration-Value";
3757 return "Key-Length";
3759 return "Field-Size";
3761 return "UNKNOWN-ATTRIBUTE-TYPE";
3766 v2_tstype2str(guint8 type)
3768 static const value_string vs_v2_tstype[] = {
3769 { IKEV2_TS_IPV4_ADDR_RANGE, "TS_IPV4_ADDR_RANGE" },
3770 { IKEV2_TS_IPV6_ADDR_RANGE, "TS_IPV6_ADDR_RANGE" },
3776 if (type >= 9 && type <= 240)
3777 return "RESERVED TO IANA";
3779 return "PRIVATE USE";
3780 return val_to_str(type, vs_v2_tstype, "UNKNOWN-TS-TYPE");
3784 v2_auth2str(guint8 type)
3786 static const value_string vs_v2_authmeth[] = {
3787 { 0, "RESERVED TO IANA" },
3788 { 1, "RSA Digital Signature" },
3789 { 2, "Shared Key Message Integrity Code" },
3790 { 3, "DSS Digital Signature" },
3794 if (type >= 4 && type <= 200)
3795 return "RESERVED TO IANA";
3797 return "PRIVATE USE";
3798 return val_to_str(type, vs_v2_authmeth, "UNKNOWN-AUTHMETHOD-TYPE");
3802 cfgattr2str(int isakmp_version, guint16 ident)
3804 static const value_string vs_v1_cfgattr[] = {
3806 { 1, "INTERNAL_IP4_ADDRESS" },
3807 { 2, "INTERNAL_IP4_NETMASK" },
3808 { 3, "INTERNAL_IP4_DNS" },
3809 { 4, "INTERNAL_IP4_NBNS" },
3810 { 5, "INTERNAL_ADDRESS_EXPIREY" },
3811 { 6, "INTERNAL_IP4_DHCP" },
3812 { 7, "APPLICATION_VERSION" },
3813 { 8, "INTERNAL_IP6_ADDRESS" },
3814 { 9, "INTERNAL_IP6_NETMASK" },
3815 { 10, "INTERNAL_IP6_DNS" },
3816 { 11, "INTERNAL_IP6_NBNS" },
3817 { 12, "INTERNAL_IP6_DHCP" },
3818 { 13, "INTERNAL_IP4_SUBNET" },
3819 { 14, "SUPPORTED_ATTRIBUTES" },
3820 { 16520, "XAUTH_TYPE" },
3821 { 16521, "XAUTH_USER_NAME" },
3822 { 16522, "XAUTH_USER_PASSWORD" },
3823 { 16523, "XAUTH_PASSCODE" },
3824 { 16524, "XAUTH_MESSAGE" },
3825 { 16525, "XAUTH_CHALLANGE" },
3826 { 16526, "XAUTH_DOMAIN" },
3827 { 16527, "XAUTH_STATUS" },
3828 { 16528, "XAUTH_NEXT_PIN" },
3829 { 16529, "XAUTH_ANSWER" },
3833 static const value_string vs_v2_cfgattr[] = {
3835 { 1, "INTERNAL_IP4_ADDRESS" },
3836 { 2, "INTERNAL_IP4_NETMASK" },
3837 { 3, "INTERNAL_IP4_DNS" },
3838 { 4, "INTERNAL_IP4_NBNS" },
3839 { 5, "INTERNAL_ADDRESS_EXPIREY" },
3840 { 6, "INTERNAL_IP4_DHCP" },
3841 { 7, "APPLICATION_VERSION" },
3842 { 8, "INTERNAL_IP6_ADDRESS" },
3844 { 10, "INTERNAL_IP6_DNS" },
3845 { 11, "INTERNAL_IP6_NBNS" },
3846 { 12, "INTERNAL_IP6_DHCP" },
3847 { 13, "INTERNAL_IP4_SUBNET" },
3848 { 14, "SUPPORTED_ATTRIBUTES" },
3849 { 15, "INTERNAL_IP6_SUBNET" },
3853 if (isakmp_version == 1) {
3854 if (ident >= 15 && ident <= 16383)
3855 return "Future use";
3856 if (ident >= 16384 && ident <= 16519)
3857 return "PRIVATE USE";
3858 if (ident >= 16530 && ident <= 32767)
3859 return "PRIVATE USE";
3860 return val_to_str(ident, vs_v1_cfgattr, "UNKNOWN-CFG-ATTRIBUTE");
3861 } else if (isakmp_version == 2) {
3862 if (ident >= 16 && ident <= 16383)
3863 return "RESERVED TO IANA";
3864 if (ident >= 16384 && ident <= 32767)
3865 return "PRIVATE USE";
3866 return val_to_str(ident, vs_v2_cfgattr, "UNKNOWN-CFG-ATTRIBUTE");
3868 return "UNKNOWN-ISAKMP-VERSION";
3872 certtype2str(int isakmp_version, guint8 type)
3874 static const value_string vs_v1_certtype[] = {
3876 { 1, "PKCS #7 wrapped X.509 certificate" },
3877 { 2, "PGP Certificate" },
3878 { 3, "DNS Signed Key" },
3879 { 4, "X.509 Certificate - Signature" },
3880 { 5, "X.509 Certificate - Key Exchange" },
3881 { 6, "Kerberos Tokens" },
3882 { 7, "Certificate Revocation List (CRL)" },
3883 { 8, "Authority Revocation List (ARL)" },
3884 { 9, "SPKI Certificate" },
3885 { 10, "X.509 Certificate - Attribute" },
3889 static const value_string vs_v2_certtype[] = {
3891 { 1, "PKCS #7 wrapped X.509 certificate" },
3892 { 2, "PGP Certificate" },
3893 { 3, "DNS Signed Key" },
3894 { 4, "X.509 Certificate - Signature" },
3895 { 5, "*undefined by any document*" },
3896 { 6, "Kerberos Tokens" },
3897 { 7, "Certificate Revocation List (CRL)" },
3898 { 8, "Authority Revocation List (ARL)" },
3899 { 9, "SPKI Certificate" },
3900 { 10, "X.509 Certificate - Attribute" },
3901 { 11, "Raw RSA Key" },
3902 { 12, "Hash and URL of X.509 certificate" },
3903 { 13, "Hash and URL of X.509 bundle" },
3907 if (isakmp_version == 1)
3908 return val_to_str(type, vs_v1_certtype, "RESERVED");
3909 else if (isakmp_version == 2) {
3910 if (type >= 14 && type <= 200)
3911 return "RESERVED to IANA";
3913 return "PRIVATE USE";
3914 return val_to_str(type, vs_v2_certtype, "RESERVED");
3916 return "UNKNOWN-ISAKMP-VERSION";
3920 get_num(tvbuff_t *tvb, int offset, guint16 len, guint32 *num_p)
3924 *num_p = tvb_get_guint8(tvb, offset);
3927 *num_p = tvb_get_ntohs(tvb, offset);
3930 *num_p = tvb_get_ntoh24(tvb, offset);
3933 *num_p = tvb_get_ntohl(tvb, offset);
3943 * Protocol initialization
3946 #ifdef HAVE_LIBGCRYPT
3948 isakmp_hash_func(gconstpointer c) {
3949 guint8 *i_cookie = (guint8 *) c;
3950 guint val = 0, keychunk, i;
3952 /* XOR our icookie down to the size of a guint */
3953 for (i = 0; i < COOKIE_SIZE - (COOKIE_SIZE % sizeof(keychunk)); i += sizeof(keychunk)) {
3954 memcpy(&keychunk, &i_cookie[i], sizeof(keychunk));
3962 isakmp_equal_func(gconstpointer ic1, gconstpointer ic2) {
3964 if (memcmp(ic1, ic2, COOKIE_SIZE) == 0)
3970 static guint ikev2_key_hash_func(gconstpointer k) {
3971 const ikev2_uat_data_key_t *key = (const ikev2_uat_data_key_t*)k;
3972 guint hash = 0, keychunk, i;
3974 /* XOR our icookie down to the size of a guint */
3975 for (i = 0; i < key->spii_len - (key->spii_len % sizeof(keychunk)); i += sizeof(keychunk)) {
3976 memcpy(&keychunk, &key->spii[i], sizeof(keychunk));
3979 for (i = 0; i < key->spir_len - (key->spir_len % sizeof(keychunk)); i += sizeof(keychunk)) {
3980 memcpy(&keychunk, &key->spir[i], sizeof(keychunk));
3987 static gint ikev2_key_equal_func(gconstpointer k1, gconstpointer k2) {
3988 const ikev2_uat_data_key_t *key1 = k1, *key2 = k2;
3989 if (key1->spii_len != key2->spii_len) return 0;
3990 if (key1->spir_len != key2->spir_len) return 0;
3991 if (memcmp(key1->spii, key2->spii, key1->spii_len) != 0) return 0;
3992 if (memcmp(key1->spir, key2->spir, key1->spir_len) != 0) return 0;
3996 #endif /* HAVE_LIBGCRYPT */
3998 #ifdef HAVE_LIBGCRYPT
3999 #if GLIB_CHECK_VERSION(2,10,0)
4001 free_cookie(gpointer key_arg, gpointer value, gpointer user_data _U_)
4003 guint8 *ic_key = key_arg;
4004 decrypt_data_t *decr = value;
4006 g_slice_free1(COOKIE_SIZE, ic_key);
4007 g_slice_free1(sizeof(decrypt_data_t), decr);
4014 isakmp_init_protocol(void) {
4015 #ifdef HAVE_LIBGCRYPT
4017 #endif /* HAVE_LIBGCRYPT */
4018 fragment_table_init(&isakmp_fragment_table);
4019 reassembled_table_init(&isakmp_reassembled_table);
4021 #ifdef HAVE_LIBGCRYPT
4023 #if GLIB_CHECK_VERSION(2,10,0)
4024 g_hash_table_foreach_remove(isakmp_hash, free_cookie, NULL);
4026 g_hash_table_destroy(isakmp_hash);
4028 #if GLIB_CHECK_VERSION(2,10,0)
4030 if (isakmp_key_data)
4031 g_mem_chunk_destroy(isakmp_key_data);
4032 if (isakmp_decrypt_data)
4033 g_mem_chunk_destroy(isakmp_decrypt_data);
4035 isakmp_key_data = g_mem_chunk_new("isakmp_key_data",
4036 COOKIE_SIZE, 5 * COOKIE_SIZE,
4038 isakmp_decrypt_data = g_mem_chunk_new("isakmp_decrypt_data",
4039 sizeof(decrypt_data_t), 5 * sizeof(decrypt_data_t),
4042 isakmp_hash = g_hash_table_new(isakmp_hash_func, isakmp_equal_func);
4045 log_f = ws_fopen(pluto_log_path, "r");
4049 if (ikev2_key_hash) {
4050 g_hash_table_destroy(ikev2_key_hash);
4053 ikev2_key_hash = g_hash_table_new(ikev2_key_hash_func, ikev2_key_equal_func);
4054 for (i = 0; i < num_ikev2_uat_data; i++) {
4055 g_hash_table_insert(ikev2_key_hash, &(ikev2_uat_data[i].key), &(ikev2_uat_data[i]));
4057 #endif /* HAVE_LIBGCRYPT */
4061 isakmp_prefs_apply_cb(void) {
4062 #ifdef HAVE_LIBGCRYPT
4063 isakmp_init_protocol();
4064 #endif /* HAVE_LIBGCRYPT */
4067 #ifdef HAVE_LIBGCRYPT
4068 UAT_BUFFER_CB_DEF(ikev2_users, spii, ikev2_uat_data_t, key.spii, key.spii_len)
4069 UAT_BUFFER_CB_DEF(ikev2_users, spir, ikev2_uat_data_t, key.spir, key.spir_len)
4070 UAT_BUFFER_CB_DEF(ikev2_users, sk_ei, ikev2_uat_data_t, sk_ei, sk_ei_len)
4071 UAT_BUFFER_CB_DEF(ikev2_users, sk_er, ikev2_uat_data_t, sk_er, sk_er_len)
4072 UAT_VS_DEF(ikev2_users, encr_alg, ikev2_uat_data_t, IKEV2_ENCR_3DES, IKEV2_ENCR_3DES_STR)
4073 UAT_BUFFER_CB_DEF(ikev2_users, sk_ai, ikev2_uat_data_t, sk_ai, sk_ai_len)
4074 UAT_BUFFER_CB_DEF(ikev2_users, sk_ar, ikev2_uat_data_t, sk_ar, sk_ar_len)
4075 UAT_VS_DEF(ikev2_users, auth_alg, ikev2_uat_data_t, IKEV2_AUTH_HMAC_SHA1_96, IKEV2_AUTH_HMAC_SHA1_96_STR)
4077 static void ikev2_uat_data_update_cb(void* p, const char** err) {
4078 ikev2_uat_data_t *ud = p;
4080 if (ud->key.spii_len != COOKIE_SIZE) {
4081 *err = ep_strdup_printf("Length of Initiator's SPI must be %d octets (%d hex characters).", COOKIE_SIZE, COOKIE_SIZE * 2);
4085 if (ud->key.spir_len != COOKIE_SIZE) {
4086 *err = ep_strdup_printf("Length of Responder's SPI must be %d octets (%d hex characters).", COOKIE_SIZE, COOKIE_SIZE * 2);
4090 if ((ud->encr_spec = ikev2_decrypt_find_encr_spec(ud->encr_alg)) == NULL) {
4091 REPORT_DISSECTOR_BUG("Couldn't get IKEv2 encryption algorithm spec.");
4094 if ((ud->auth_spec = ikev2_decrypt_find_auth_spec(ud->auth_alg)) == NULL) {
4095 REPORT_DISSECTOR_BUG("Couldn't get IKEv2 authentication algorithm spec.");
4098 if (ud->sk_ei_len != ud->encr_spec->key_len) {
4099 *err = ep_strdup_printf("Length of SK_ei (%u octets) does not match the key length (%u octets) of the selected encryption algorithm.",
4100 ud->sk_ei_len, ud->encr_spec->key_len);
4104 if (ud->sk_er_len != ud->encr_spec->key_len) {
4105 *err = ep_strdup_printf("Length of SK_er (%u octets) does not match the key length (%u octets) of the selected encryption algorithm.",
4106 ud->sk_er_len, ud->encr_spec->key_len);
4110 if (ud->sk_ai_len != ud->auth_spec->key_len) {
4111 *err = ep_strdup_printf("Length of SK_ai (%u octets) does not match the key length (%u octets) of the selected integrity algorithm.",
4112 ud->sk_ai_len, ud->auth_spec->key_len);
4116 if (ud->sk_ar_len != ud->auth_spec->key_len) {
4117 *err = ep_strdup_printf("Length of SK_ar (%u octets) does not match the key length (%u octets) of the selected integrity algorithm.",
4118 ud->sk_ar_len, ud->auth_spec->key_len);
4122 #endif /* HAVE_LIBGCRYPT */
4125 proto_register_isakmp(void)
4127 module_t *isakmp_module;
4129 static hf_register_info hf[] = {
4130 { &hf_isakmp_icookie,
4131 { "Initiator cookie", "isakmp.icookie",
4132 FT_BYTES, BASE_NONE, NULL, 0x0,
4133 "ISAKMP Initiator Cookie", HFILL }},
4134 { &hf_isakmp_rcookie,
4135 { "Responder cookie", "isakmp.rcookie",
4136 FT_BYTES, BASE_NONE, NULL, 0x0,
4137 "ISAKMP Responder Cookie", HFILL }},
4138 { &hf_isakmp_nextpayload,
4139 { "Next payload", "isakmp.nextpayload",
4140 FT_UINT8, BASE_DEC, NULL, 0x0,
4141 "ISAKMP Next Payload", HFILL }},
4142 { &hf_isakmp_version,
4143 { "Version", "isakmp.version",
4144 FT_UINT8, BASE_HEX, NULL, 0x0,
4145 "ISAKMP Version (major + minor)", HFILL }},
4146 { &hf_isakmp_exchangetype,
4147 { "Exchange type", "isakmp.exchangetype",
4148 FT_UINT8, BASE_DEC, NULL, 0x0,
4149 "ISAKMP Exchange Type", HFILL }},
4151 { "Flags", "isakmp.flags",
4152 FT_UINT8, BASE_HEX, NULL, 0x0,
4153 "ISAKMP Flags", HFILL }},
4154 { &hf_isakmp_flag_e,
4155 { "Encryption", "isakmp.flag_e",
4156 FT_BOOLEAN, 8, TFS(&flag_e), E_FLAG,
4157 "Encryption Bit", HFILL }},
4158 { &hf_isakmp_flag_c,
4159 { "Commit", "isakmp.flag_c",
4160 FT_BOOLEAN, 8, TFS(&flag_c), C_FLAG,
4161 "Commit Bit", HFILL }},
4162 { &hf_isakmp_flag_a,
4163 { "Authentication", "isakmp.flag_a",
4164 FT_BOOLEAN, 8, TFS(&flag_a), A_FLAG,
4165 "Authentication Bit", HFILL }},
4166 { &hf_isakmp_flag_i,
4167 { "Initiator", "isakmp.flag_i",
4168 FT_BOOLEAN, 8, TFS(&flag_i), I_FLAG,
4169 "Initiator Bit", HFILL }},
4170 { &hf_isakmp_flag_v,
4171 { "Version", "isakmp.flag_v",
4172 FT_BOOLEAN, 8, TFS(&flag_v), V_FLAG,
4173 "Version Bit", HFILL }},
4174 { &hf_isakmp_flag_r,
4175 { "Response", "isakmp.flag_r",
4176 FT_BOOLEAN, 8, TFS(&flag_r), R_FLAG,
4177 "Response Bit", HFILL }},
4178 { &hf_isakmp_messageid,
4179 { "Message ID", "isakmp.messageid",
4180 FT_UINT32, BASE_HEX, NULL, 0x0,
4181 "ISAKMP Message ID", HFILL }},
4182 { &hf_isakmp_length,
4183 { "Length", "isakmp.length",
4184 FT_UINT32, BASE_DEC, NULL, 0x0,
4185 "ISAKMP Length", HFILL }},
4186 { &hf_isakmp_payloadlen,
4187 { "Payload length", "isakmp.payloadlength",
4188 FT_UINT16, BASE_DEC, NULL, 0x0,
4189 "ISAKMP Payload Length", HFILL }},
4191 { "Domain of interpretation", "isakmp.doi",
4192 FT_UINT32, BASE_DEC, NULL, 0x0,
4193 "ISAKMP Domain of Interpretation", HFILL }},
4194 { &hf_isakmp_sa_situation,
4195 { "Situation", "isakmp.sa.situation",
4196 FT_BYTES, BASE_NONE, NULL, 0x0,
4197 "ISAKMP SA Situation", HFILL }},
4198 { &hf_isakmp_prop_number,
4199 { "Proposal number", "isakmp.prop.number",
4200 FT_UINT8, BASE_DEC, NULL, 0x0,
4201 "ISAKMP Proposal Number", HFILL }},
4202 { &hf_isakmp_spisize,
4203 { "SPI Size", "isakmp.spisize",
4204 FT_UINT8, BASE_DEC, NULL, 0x0,
4205 "ISAKMP SPI Size", HFILL }},
4206 { &hf_isakmp_prop_transforms,
4207 { "Proposal transforms", "isakmp.prop.transforms",
4208 FT_UINT8, BASE_DEC, NULL, 0x0,
4209 "ISAKMP Proposal Transforms", HFILL }},
4210 { &hf_isakmp_trans_number,
4211 { "Transform number", "isakmp.trans.number",
4212 FT_UINT8, BASE_DEC, NULL, 0x0,
4213 "ISAKMP Transform Number", HFILL }},
4214 { &hf_isakmp_trans_id,
4215 { "Transform ID", "isakmp.trans.id",
4216 FT_UINT8, BASE_DEC, NULL, 0x0,
4217 "ISAKMP Transform ID", HFILL }},
4218 { &hf_isakmp_id_type_v1,
4219 { "ID type", "isakmp.id.type",
4220 FT_UINT8, BASE_DEC, RVALS(&vs_v1_id_type), 0x0,
4221 "ISAKMP (v1) ID Type", HFILL }},
4222 { &hf_isakmp_id_type_v2,
4223 { "ID type", "isakmp.id.type",
4224 FT_UINT8, BASE_DEC, RVALS(&vs_v2_id_type), 0x0,
4225 "ISAKMP (v2) ID Type", HFILL }},
4226 { &hf_isakmp_protoid,
4227 { "Protocol ID", "isakmp.protoid",
4228 FT_UINT8, BASE_DEC, NULL, 0x0,
4229 "ISAKMP Protocol ID", HFILL }},
4230 { &hf_isakmp_id_port,
4231 { "Port", "isakmp.id.port",
4232 FT_UINT16, BASE_DEC, NULL, 0x0,
4233 "ISAKMP ID Port", HFILL }},
4234 { &hf_isakmp_cert_encoding,
4235 { "Port", "isakmp.cert.encoding",
4236 FT_UINT8, BASE_DEC, NULL, 0x0,
4237 "ISAKMP Certificate Encoding", HFILL }},
4238 { &hf_isakmp_certificate,
4239 { "Certificate", "isakmp.certificate",
4240 FT_NONE, BASE_NONE, NULL, 0x0,
4241 "ISAKMP Certificate Encoding", HFILL }},
4242 { &hf_isakmp_certreq_type,
4243 { "Port", "isakmp.certreq.type",
4244 FT_UINT8, BASE_DEC, NULL, 0x0,
4245 "ISAKMP Certificate Request Type", HFILL }},
4246 { &hf_isakmp_notify_msgtype,
4247 { "Port", "isakmp.notify.msgtype",
4248 FT_UINT8, BASE_DEC, NULL, 0x0,
4249 "ISAKMP Notify Message Type", HFILL }},
4250 { &hf_isakmp_num_spis,
4251 { "Port", "isakmp.spinum",
4252 FT_UINT16, BASE_DEC, NULL, 0x0,
4253 "ISAKMP Number of SPIs", HFILL }},
4254 { &hf_isakmp_cisco_frag_packetid,
4255 { "Frag ID", "isakmp.frag.packetid",
4256 FT_UINT16, BASE_HEX, NULL, 0x0,
4257 "ISAKMP fragment packet-id", HFILL }},
4258 { &hf_isakmp_cisco_frag_seq,
4259 { "Frag seq", "isakmp.frag.packetid",
4260 FT_UINT8, BASE_DEC, NULL, 0x0,
4261 "ISAKMP fragment number", HFILL }},
4262 { &hf_isakmp_cisco_frag_last,
4263 { "Frag last", "isakmp.frag.last",
4264 FT_UINT8, BASE_DEC, VALS(frag_last_vals), 0x0,
4265 "ISAKMP last fragment", HFILL }},
4266 { &hf_isakmp_fragments,
4267 {"Message fragments", "isakmp.fragments",
4268 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4269 { &hf_isakmp_fragment,
4270 {"Message fragment", "isakmp.fragment",
4271 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4272 { &hf_isakmp_fragment_overlap,
4273 {"Message fragment overlap", "isakmp.fragment.overlap",
4274 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4275 { &hf_isakmp_fragment_overlap_conflicts,
4276 {"Message fragment overlapping with conflicting data",
4277 "isakmp.fragment.overlap.conflicts",
4278 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4279 { &hf_isakmp_fragment_multiple_tails,
4280 {"Message has multiple tail fragments",
4281 "isakmp.fragment.multiple_tails",
4282 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4283 { &hf_isakmp_fragment_too_long_fragment,
4284 {"Message fragment too long", "isakmp.fragment.too_long_fragment",
4285 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4286 { &hf_isakmp_fragment_error,
4287 {"Message defragmentation error", "isakmp.fragment.error",
4288 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4289 { &hf_isakmp_reassembled_in,
4290 {"Reassembled in", "isakmp.reassembled.in",
4291 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4292 { &hf_isakmp_reassembled_length,
4293 {"Reassembled ISAKMP length", "isakmp.reassembled.length",
4294 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4295 { &hf_isakmp_certificate_authority,
4296 { "Certificate Authority Distinguished Name", "ike.cert_authority_dn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
4298 { &hf_isakmp_v2_certificate_authority,
4299 { "Certificate Authority", "ike.cert_authority", FT_BYTES, BASE_NONE, NULL, 0x0, "SHA-1 hash of the Certificate Authority", HFILL }
4301 { &hf_isakmp_nat_keepalive,
4302 { "NAT Keepalive", "ike.nat_keepalive", FT_NONE, BASE_NONE, NULL, 0x0, "NAT Keepalive packet", HFILL }
4304 { &hf_isakmp_nat_hash,
4305 { "HASH of the address and port", "ike.nat_hash",
4306 FT_BYTES, BASE_NONE, NULL, 0x00,
4308 { &hf_isakmp_nat_original_address_ipv4,
4309 { "NAT Original IPv4 Address", "ike.nat_original_address_ipv4",
4310 FT_IPv4, BASE_NONE, NULL, 0x00,
4312 { &hf_isakmp_nat_original_address_ipv6,
4313 { "NAT Original IPv6 Address", "ike.nat_original_address_ipv6",
4314 FT_IPv6, BASE_NONE, NULL, 0x00,
4317 { &hf_isakmp_cfg_type_v1,
4318 { "Type", "isakmp.cfg.type_v1",
4319 FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v1_cfgtype), 0x0,
4320 "ISAKMP (v1) Config Type", HFILL }},
4321 { &hf_isakmp_cfg_identifier,
4322 { "Identifier", "isakmp.cfg.identifier",
4323 FT_UINT16, BASE_DEC, NULL, 0x0,
4324 "ISAKMP (v1) Config Identifier", HFILL }},
4325 { &hf_isakmp_cfg_type_v2,
4326 { "Type", "isakmp.cfg.type_v2",
4327 FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v2_cfgtype), 0x0,
4328 "ISAKMP (v2) Config Type", HFILL }},
4329 /* Attributes Type */
4330 { &hf_isakmp_cfg_attr_type_v1,
4331 { "Type", "isakmp.cfg.attr.type_v1",
4332 FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v1_cfgattr), 0x00,
4333 "ISAKMP (v1) Config Attribute type", HFILL }},
4334 { &hf_isakmp_cfg_attr_type_v2,
4335 { "Type", "isakmp.cfg.attr.type_v2",
4336 FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v2_cfgattr), 0x00,
4337 "ISAKMP (v2) Config Attribute type", HFILL }},
4338 { &hf_isakmp_cfg_attr_length,
4339 { "Length", "isakmp.cfg.attr.length",
4340 FT_UINT16, BASE_DEC, NULL, 0x00,
4341 "ISAKMP Config Attribute length", HFILL }},
4342 { &hf_isakmp_cfg_attr_value,
4343 { "Value", "isakmp.cfg.attr.value",
4344 FT_BYTES, BASE_NONE, NULL, 0x00,
4345 "ISAKMP Config Attribute value", HFILL }},
4346 { &hf_isakmp_cfg_attr_internal_ip4_address,
4347 { "INTERNAL IP4 ADDRESS", "isakmp.cfg.attr.internal_ip4_address",
4348 FT_IPv4, BASE_NONE, NULL, 0x00,
4349 " An IPv4 address on the internal network", HFILL }},
4350 { &hf_isakmp_cfg_attr_internal_ip4_netmask,
4351 { "INTERNAL IP4 NETMASK", "isakmp.cfg.attr.internal_ip4_netmask",
4352 FT_IPv4, BASE_NONE, NULL, 0x00,
4353 "The internal network's netmask", HFILL }},
4354 { &hf_isakmp_cfg_attr_internal_ip4_dns,
4355 { "INTERNAL IP4 DNS", "isakmp.cfg.attr.internal_ip4_dns",
4356 FT_IPv4, BASE_NONE, NULL, 0x00,
4357 "An IPv4 address of a DNS server within the network", HFILL }},
4358 { &hf_isakmp_cfg_attr_internal_ip4_nbns,
4359 { "INTERNAL IP4 NBNS", "isakmp.cfg.attr.internal_ip4_nbns",
4360 FT_IPv4, BASE_NONE, NULL, 0x00,
4361 "An IPv4 address of a NetBios Name Server (WINS) within the network", HFILL }},
4362 { &hf_isakmp_cfg_attr_internal_address_expiry,
4363 { "INTERNAL ADDRESS EXPIRY (Secs)", "isakmp.cfg.attr.internal_address_expiry",
4364 FT_UINT32, BASE_DEC, NULL, 0x00,
4365 "Specifies the number of seconds that the host can use the internal IP address", HFILL }},
4366 { &hf_isakmp_cfg_attr_internal_ip4_dhcp,
4367 { "INTERNAL IP4 DHCP", "isakmp.cfg.attr.internal_ip4_dhcp",
4368 FT_IPv4, BASE_NONE, NULL, 0x00,
4369 "the host to send any internal DHCP requests to the address", HFILL }},
4370 { &hf_isakmp_cfg_attr_application_version,
4371 { "APPLICATION VERSION", "isakmp.cfg.attr.application_version",
4372 FT_STRING, BASE_NONE, NULL, 0x00,
4373 "The version or application information of the IPsec host", HFILL }},
4374 { &hf_isakmp_cfg_attr_internal_ip6_address,
4375 { "INTERNAL IP6 ADDRESS", "isakmp.cfg.attr.internal_ip6_address",
4376 FT_IPv4, BASE_NONE, NULL, 0x00,
4377 " An IPv6 address on the internal network", HFILL }},
4378 { &hf_isakmp_cfg_attr_internal_ip6_netmask,
4379 { "INTERNAL IP4 NETMASK", "isakmp.cfg.attr.internal_ip6_netmask",
4380 FT_IPv6, BASE_NONE, NULL, 0x00,
4381 "The internal network's netmask", HFILL }},
4382 { &hf_isakmp_cfg_attr_internal_ip6_dns,
4383 { "INTERNAL IP6 DNS", "isakmp.cfg.attr.internal_ip6_dns",
4384 FT_IPv6, BASE_NONE, NULL, 0x00,
4385 "An IPv6 address of a DNS server within the network", HFILL }},
4386 { &hf_isakmp_cfg_attr_internal_ip6_nbns,
4387 { "INTERNAL IP6 NBNS", "isakmp.cfg.attr.internal_ip6_nbns",
4388 FT_IPv6, BASE_NONE, NULL, 0x00,
4389 "An IPv6 address of a NetBios Name Server (WINS) within the network", HFILL }},
4390 { &hf_isakmp_cfg_attr_internal_ip6_dhcp,
4391 { "INTERNAL IP6 DHCP", "isakmp.cfg.attr.internal_ip6_dhcp",
4392 FT_IPv6, BASE_NONE, NULL, 0x00,
4393 "the host to send any internal DHCP requests to the address", HFILL }},
4394 { &hf_isakmp_cfg_attr_internal_ip4_subnet_ip,
4395 { "INTERNAL IP4 SUBNET (IP)", "isakmp.cfg.attr.internal_ip4_subnet_ip",
4396 FT_IPv4, BASE_NONE, NULL, 0x00,
4397 "The protected sub-networks that this edge-device protects (IP)", HFILL }},
4398 { &hf_isakmp_cfg_attr_internal_ip4_subnet_netmask,
4399 { "INTERNAL IP4 SUBNET (NETMASK)", "isakmp.cfg.attr.internal_ip4_subnet_netmask",
4400 FT_IPv4, BASE_NONE, NULL, 0x00,
4401 "The protected sub-networks that this edge-device protects (IP)", HFILL }},
4402 { &hf_isakmp_cfg_attr_xauth_type,
4403 { "XAUTH TYPE", "isakmp.cfg.attr.xauth.type",
4404 FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&cfgattr_xauth_type), 0x00,
4405 "The type of extended authentication requested", HFILL }},
4407 { &hf_isakmp_cfg_attr_xauth_user_name,
4408 { "XAUTH USER NAME", "isakmp.cfg.attr.xauth.user_name",
4409 FT_STRING, BASE_NONE, NULL, 0x00,
4410 "The user name", HFILL }},
4412 { &hf_isakmp_cfg_attr_xauth_user_password,
4413 { "XAUTH USER PASSWORD", "isakmp.cfg.attr.xauth.user_password",
4414 FT_STRING, BASE_NONE, NULL, 0x00,
4415 "The user's password", HFILL }},
4416 { &hf_isakmp_cfg_attr_xauth_passcode,
4417 { "XAUTH PASSCODE", "isakmp.cfg.attr.xauth.passcode",
4418 FT_STRING, BASE_NONE, NULL, 0x00,
4419 "A token card's passcode", HFILL }},
4420 { &hf_isakmp_cfg_attr_xauth_message,
4421 { "XAUTH MESSAGE", "isakmp.cfg.attr.xauth.message",
4422 FT_STRING, BASE_NONE, NULL, 0x00,
4423 "A textual message from an edge device to an IPSec host", HFILL }},
4424 { &hf_isakmp_cfg_attr_xauth_challenge,
4425 { "XAUTH CHALLENGE", "isakmp.cfg.attr.xauth.challenge",
4426 FT_STRING, BASE_NONE, NULL, 0x00,
4427 "A challenge string sent from the edge device to the IPSec host for it to include in its calculation of a password", HFILL }},
4429 { &hf_isakmp_cfg_attr_xauth_domain,
4430 { "XAUTH DOMAIN", "isakmp.cfg.attr.xauth.domain",
4431 FT_STRING, BASE_NONE, NULL, 0x00,
4432 "The domain to be authenticated in", HFILL }},
4433 { &hf_isakmp_cfg_attr_xauth_status,
4434 { "XAUTH STATUS", "isakmp.cfg.attr.xauth.status",
4435 FT_UINT16, BASE_DEC, VALS(cfgattr_xauth_status), 0x00,
4436 "A variable that is used to denote authentication success or failure", HFILL }},
4437 { &hf_isakmp_cfg_attr_xauth_next_pin,
4438 { "XAUTH TYPE", "isakmp.cfg.attr.xauth.next_pin",
4439 FT_STRING, BASE_NONE, NULL, 0x00,
4440 "A variable which is used when the edge device is requesting that the user choose a new pin number", HFILL }},
4441 { &hf_isakmp_cfg_attr_xauth_answer,
4442 { "XAUTH ANSWER", "isakmp.cfg.attr.xauth.answer",
4443 FT_STRING, BASE_NONE, NULL, 0x00,
4444 "A variable length ASCII string used to send input to the edge device", HFILL }},
4445 { &hf_isakmp_cfg_attr_unity_banner,
4446 { "UNITY BANNER", "isakmp.cfg.attr.unity.banner",
4447 FT_STRING, BASE_NONE, NULL, 0x00,
4452 static gint *ett[] = {
4455 &ett_isakmp_payload,
4456 &ett_isakmp_fragment,
4457 &ett_isakmp_fragments,
4458 &ett_isakmp_cfg_attr,
4459 #ifdef HAVE_LIBGCRYPT
4460 &ett_isakmp_decrypted_data,
4461 &ett_isakmp_decrypted_payloads
4462 #endif /* HAVE_LIBGCRYPT */
4464 #ifdef HAVE_LIBGCRYPT
4465 static uat_field_t ikev2_uat_flds[] = {
4466 UAT_FLD_BUFFER(ikev2_users, spii, "Initiator's SPI", "Initiator's SPI value of the IKE_SA"),
4467 UAT_FLD_BUFFER(ikev2_users, spir, "Responder's SPI", "Responder's SPI value of the IKE_SA"),
4468 UAT_FLD_BUFFER(ikev2_users, sk_ei, "SK_ei", "Key used to encrypt/decrypt IKEv2 packets from initiator to responder"),
4469 UAT_FLD_BUFFER(ikev2_users, sk_er, "SK_er", "Key used to encrypt/decrypt IKEv2 packets from responder to initiator"),
4470 UAT_FLD_VS(ikev2_users, encr_alg, "Encryption algorithm", vs_ikev2_encr_algs, "Encryption algorithm of IKE_SA"),
4471 UAT_FLD_BUFFER(ikev2_users, sk_ai, "SK_ai", "Key used to calculate Integrity Checksum Data for IKEv2 packets from initiator to responder"),
4472 UAT_FLD_BUFFER(ikev2_users, sk_ar, "SK_ar", "Key used to calculate Integrity Checksum Data for IKEv2 packets from responder to initiator"),
4473 UAT_FLD_VS(ikev2_users, auth_alg, "Integrity algorithm", vs_ikev2_auth_algs, "Integrity algorithm of IKE_SA"),
4476 #endif /* HAVE_LIBGCRYPT */
4477 proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol",
4478 "ISAKMP", "isakmp");
4479 proto_register_field_array(proto_isakmp, hf, array_length(hf));
4480 proto_register_subtree_array(ett, array_length(ett));
4481 register_init_routine(&isakmp_init_protocol);
4483 register_dissector("isakmp", dissect_isakmp, proto_isakmp);
4485 isakmp_module = prefs_register_protocol(proto_isakmp, isakmp_prefs_apply_cb);
4486 #ifdef HAVE_LIBGCRYPT
4487 prefs_register_string_preference(isakmp_module, "log",
4489 "Path to a pluto log file containing DH secret information",
4492 ikev2_uat = uat_new("IKEv2 Decryption Table",
4493 sizeof(ikev2_uat_data_t),
4494 "ikev2_decryption_table",
4496 (void*)&ikev2_uat_data,
4497 &num_ikev2_uat_data,
4499 "ChIKEv2DecryptionSection",
4501 ikev2_uat_data_update_cb,
4505 prefs_register_uat_preference(isakmp_module,
4506 "ikev2_decryption_table",
4507 "IKEv2 Decryption Table",
4508 "Table of IKE_SA security parameters for decryption of IKEv2 packets",
4511 #endif /* HAVE_LIBGCRYPT */
4515 proto_reg_handoff_isakmp(void)
4517 dissector_handle_t isakmp_handle;
4519 isakmp_handle = find_dissector("isakmp");
4520 eap_handle = find_dissector("eap");
4521 dissector_add("udp.port", UDP_PORT_ISAKMP, isakmp_handle);
4522 dissector_add("tcp.port", TCP_PORT_ISAKMP, isakmp_handle);