Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-mikey.c
blobe62b7dad78896e011abc3e058ac8c1fd44a8a7db
1 /* packet-mikey.c
2 * Routines for Multimedia Internet KEYing dissection
3 * Copyright 2007, Mikael Magnusson <mikma@users.sourceforge.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Ref:
13 * https://tools.ietf.org/html/rfc3830 MIKEY
14 * https://tools.ietf.org/html/rfc6043 MIKEY-TICKET (ID role required for SAKKE)
15 * https://tools.ietf.org/html/rfc6509 MIKEY-SAKKE
19 * TODO
20 * tvbuff offset in 32-bit variable.
21 * Support CHASH
22 * Decode Mikey-PK and Mikey-RSA-R with NULL encryption
26 #include "config.h"
28 #include <epan/packet.h>
29 #include <epan/asn1.h>
30 #include <epan/proto_data.h>
31 #include <epan/tfs.h>
32 #include <wsutil/array.h>
33 #include "packet-x509af.h"
35 void proto_register_mikey(void);
36 void proto_reg_handoff_mikey(void);
38 #define PORT_MIKEY 2269
40 static const value_string on_off_vals[] = {
41 { 0, "Off" },
42 { 1, "On" },
43 { 0, NULL }
46 enum data_type_t {
47 MIKEY_TYPE_PSK_INIT = 0,
48 MIKEY_TYPE_PSK_RESP,
49 MIKEY_TYPE_PK_INIT,
50 MIKEY_TYPE_PK_RESP,
51 MIKEY_TYPE_DH_INIT,
52 MIKEY_TYPE_DH_RESP,
53 MIKEY_TYPE_ERROR,
54 MIKEY_TYPE_DHHMAC_INIT,
55 MIKEY_TYPE_DHHMAC_RESP,
56 MIKEY_TYPE_RSA_R_INIT,
57 MIKEY_TYPE_RSA_R_RESP,
58 MIKEY_TYPE_SAKKE_INIT = 26,
59 MIKEY_TYPE_SAKKE_RESP
62 static const value_string data_type_vals[] = {
63 { MIKEY_TYPE_PSK_INIT, "Pre-shared" },
64 { MIKEY_TYPE_PSK_RESP, "PSK ver msg" },
65 { MIKEY_TYPE_PK_INIT, "Public key" },
66 { MIKEY_TYPE_PK_RESP, "PK ver msg" },
67 { MIKEY_TYPE_DH_INIT, "D-H init" },
68 { MIKEY_TYPE_DH_RESP, "D-H resp" },
69 { MIKEY_TYPE_ERROR, "Error" },
70 { MIKEY_TYPE_DHHMAC_INIT, "DHHMAC init" },
71 { MIKEY_TYPE_DHHMAC_RESP, "DHHMAC resp" },
72 { MIKEY_TYPE_RSA_R_INIT, "RSA-R I_MSG" },
73 { MIKEY_TYPE_RSA_R_RESP, "RSA-R R_MSG" },
74 { MIKEY_TYPE_SAKKE_INIT, "SAKKE" },
75 { MIKEY_TYPE_SAKKE_RESP, "CS Id map Update" },
76 { 0, NULL }
78 static value_string_ext data_type_vals_ext = VALUE_STRING_EXT_INIT(data_type_vals);
80 enum cs_id_map_t {
81 CS_ID_SRTP = 0
84 static const value_string cs_id_map_vals[] = {
85 { CS_ID_SRTP, "SRTP-ID" },
86 { 0, NULL }
89 enum payload_t {
90 PL_HDR = -1,
91 PL_LAST,
92 PL_KEMAC,
93 PL_PKE,
94 PL_DH,
95 PL_SIGN,
96 PL_T,
97 PL_ID,
98 PL_CERT,
99 PL_CHASH,
100 PL_V,
101 PL_SP,
102 PL_RAND,
103 PL_ERR,
104 PL_TR = 13, /* MIKEY-TICKET (6043) */
105 PL_IDR,
106 PL_RANDR,
107 PL_TP,
108 PL_TICKET,
109 PL_KEY_DATA = 20,
110 PL_GENERAL_EXT,
111 PL_SAKKE = 26,
112 PL_MAX
115 #define PL_HDR_TEXT "Common Header (HDR)"
116 #define PL_LAST_TEXT "Last payload"
117 #define PL_KEMAC_TEXT "Key Data Transport (KEMAC)"
118 #define PL_PKE_TEXT "Envelope Data (PKE)"
119 #define PL_DH_TEXT "DH Data (DH)"
120 #define PL_SIGN_TEXT "Signature (SIGN)"
121 #define PL_T_TEXT "Timestamp (T)"
122 #define PL_ID_TEXT "ID"
123 #define PL_CERT_TEXT "Certificate (CERT)"
124 #define PL_CHASH_TEXT "CHASH"
125 #define PL_V_TEXT "Ver msg (V)"
126 #define PL_SP_TEXT "Security Policy (SP)"
127 #define PL_RAND_TEXT "RAND"
128 #define PL_ERR_TEXT "Error (ERR)"
129 #define PL_KEY_DATA_TEXT "Key data (KEY)"
130 #define PL_IDR_TEXT "IDR"
131 #define PL_GENERAL_EXT_TEXT "General Extension (EXT)"
132 #define PL_SAKKE_TEXT "SAKKE Encapsulated Data (SAKKE)"
134 static const value_string payload_vals[] = {
135 { PL_HDR, PL_HDR_TEXT },
136 { PL_LAST, PL_LAST_TEXT },
137 { PL_KEMAC, PL_KEMAC_TEXT },
138 { PL_PKE, PL_PKE_TEXT },
139 { PL_DH, PL_DH_TEXT },
140 { PL_SIGN, PL_SIGN_TEXT },
141 { PL_T, PL_T_TEXT },
142 { PL_ID, PL_ID_TEXT },
143 { PL_CERT, PL_CERT_TEXT },
144 { PL_CHASH, PL_CHASH_TEXT },
145 { PL_V, PL_V_TEXT },
146 { PL_SP, PL_SP_TEXT },
147 { PL_RAND, PL_RAND_TEXT },
148 { PL_ERR, PL_ERR_TEXT },
149 { PL_IDR, PL_IDR_TEXT },
150 { PL_KEY_DATA, PL_KEY_DATA_TEXT },
151 { PL_GENERAL_EXT, PL_GENERAL_EXT_TEXT },
152 { PL_SAKKE, PL_SAKKE_TEXT },
153 { 0, NULL }
155 #if 0 /* First entry (PL_HDR) is -1 and there are gaps so this doesn't work */
156 static value_string_ext payload_vals_ext = VALUE_STRING_EXT_INIT(payload_vals);
157 #endif
159 enum ts_type_t {
160 T_NTP_UTC = 0,
161 T_NTP,
162 T_COUNTER
165 static const value_string ts_type_vals[] = {
166 { T_NTP_UTC, "NTP-UTC" },
167 { T_NTP, "NTP" },
168 { T_COUNTER, "COUNTER" },
169 { 0, NULL }
172 enum encr_alg_t {
173 ENCR_NULL = 0,
174 ENCR_AES_CM_128,
175 ENCR_AES_KW_128
178 static const value_string encr_alg_vals[] = {
179 { ENCR_NULL, "NULL" },
180 { ENCR_AES_CM_128, "AES-CM-128" },
181 { ENCR_AES_KW_128, "AES-KW-128" },
182 { 0, NULL }
185 enum oakley_t {
186 DH_OAKLEY_5 = 0,
187 DH_OAKLEY_1,
188 DH_OAKLEY_2
191 static const value_string oakley_vals[] = {
192 { DH_OAKLEY_5, "OAKLEY 5" },
193 { DH_OAKLEY_1, "OAKLEY 1" },
194 { DH_OAKLEY_2, "OAKLEY 2" },
195 { 0, NULL }
198 enum mac_alg_t {
199 MAC_NULL = 0,
200 MAC_HMAC_SHA_1_160
203 static const value_string mac_alg_vals[] = {
204 { MAC_NULL, "NULL" },
205 { MAC_HMAC_SHA_1_160, "HMAC-SHA-1-160" },
206 { 0, NULL }
209 enum pke_c_t {
210 PKE_C_NO_CACHE = 0,
211 PKE_C_CACHE,
212 PKE_C_CACHE_CSB
215 static const value_string pke_c_vals[] = {
216 { PKE_C_NO_CACHE, "No cache" },
217 { PKE_C_CACHE, "Cache" },
218 { PKE_C_CACHE_CSB, "Cache for CSB" },
219 { 0, NULL }
222 enum sign_s_t {
223 SIGN_S_PKCS1 = 0,
224 SIGN_S_PSS,
225 SIGN_S_ECCSI
228 static const value_string sign_s_vals[] = {
229 { SIGN_S_PKCS1, "RSA/PKCS#1/1.5" },
230 { SIGN_S_PSS, "RSA/PSS" },
231 { SIGN_S_ECCSI, "ECCSI" },
232 { 0, NULL }
235 enum id_type_t {
236 ID_TYPE_NAI = 0,
237 ID_TYPE_URI,
238 ID_TYPE_BYTE_STRING
241 static const value_string id_type_vals[] = {
242 { ID_TYPE_NAI, "NAI" },
243 { ID_TYPE_URI, "URI" },
244 { ID_TYPE_BYTE_STRING, "Byte string" },
245 { 0, NULL }
248 enum id_role_t {
249 ID_ROLE_RESERVED = 0,
250 ID_ROLE_INIT,
251 ID_ROLE_RESP,
252 ID_ROLE_KMS,
253 ID_ROLE_PSK,
254 ID_ROLE_APP,
255 ID_ROLE_INIT_KMS,
256 ID_ROLE_RESP_KMS
259 static const value_string id_role_vals[] = {
260 { ID_ROLE_RESERVED, "Reserved" },
261 { ID_ROLE_INIT, "Initiator (IDRi)" },
262 { ID_ROLE_RESP, "Responder (IDRr)" },
263 { ID_ROLE_KMS, "KMS (IDRkms)" },
264 { ID_ROLE_PSK, "Pre-Shared Key (IDRpsk)" },
265 { ID_ROLE_APP, "Application (IDRapp)" },
266 { ID_ROLE_INIT_KMS, "Initiator's KMS (IDRkmsi)" },
267 { ID_ROLE_RESP_KMS, "Responder's KMS (IDRkmsr)" },
268 { 0, NULL }
271 enum cert_type_t {
272 CERT_TYPE_X509V3 = 0,
273 CERT_TYPE_X509V3_URL,
274 CERT_TYPE_X509V3_SIGN,
275 CERT_TYPE_X509V3_ENCR
278 static const value_string cert_type_vals[] = {
279 { CERT_TYPE_X509V3, "X.509v3" },
280 { CERT_TYPE_X509V3_URL, "X.509v3 URL" },
281 { CERT_TYPE_X509V3_SIGN, "X.509v3 Sign" },
282 { CERT_TYPE_X509V3_ENCR, "X.509v3 Encr" },
283 { 0, NULL }
286 enum srtp_policy_type_t {
287 SP_ENCR_ALG,
288 SP_ENCR_LEN,
289 SP_AUTH_ALG,
290 SP_AUTH_KEY_LEN,
291 SP_SALT_LEN,
292 SP_PRF,
293 SP_KD_RATE,
294 SP_SRTP_ENCR,
295 SP_SRTCP_ENCR,
296 SP_FEC,
297 SP_SRTP_AUTH,
298 SP_AUTH_TAG_LEN,
299 SP_SRTP_PREFIX,
300 SP_MAX
303 #define SP_TEXT_ENCR_ALG "Encryption algorithm"
304 #define SP_TEXT_ENCR_LEN "Session Encr. key length"
305 #define SP_TEXT_AUTH_ALG "Authentication algorithm"
306 #define SP_TEXT_AUTH_KEY_LEN "Session Auth. key length"
307 #define SP_TEXT_SALT_LEN "Session Salt key length"
308 #define SP_TEXT_PRF "SRTP Pseudo Random Function"
309 #define SP_TEXT_KD_RATE "Key derivation rate"
310 #define SP_TEXT_SRTP_ENCR "SRTP encryption"
311 #define SP_TEXT_SRTCP_ENCR "SRTCP encryption"
312 #define SP_TEXT_FEC "Sender's FEC order"
313 #define SP_TEXT_SRTP_AUTH "SRTP authentication"
314 #define SP_TEXT_AUTH_TAG_LEN "Authentication tag length"
315 #define SP_TEXT_SRTP_PREFIX "SRTP prefix length"
317 #if 0
318 static const value_string srtp_policy_type_vals[] = {
319 { SP_ENCR_ALG, SP_TEXT_ENCR_ALG },
320 { SP_ENCR_LEN, SP_TEXT_ENCR_LEN },
321 { SP_AUTH_ALG, SP_TEXT_AUTH_ALG },
322 { SP_AUTH_KEY_LEN, SP_TEXT_AUTH_KEY_LEN },
323 { SP_SALT_LEN, SP_TEXT_SALT_LEN },
324 { SP_PRF, SP_TEXT_PRF },
325 { SP_KD_RATE, SP_TEXT_KD_RATE },
326 { SP_SRTP_ENCR, SP_TEXT_SRTP_ENCR },
327 { SP_SRTCP_ENCR, SP_TEXT_SRTCP_ENCR },
328 { SP_FEC, SP_TEXT_FEC },
329 { SP_SRTP_AUTH, SP_TEXT_SRTP_AUTH },
330 { SP_AUTH_TAG_LEN, SP_TEXT_AUTH_TAG_LEN },
331 { SP_SRTP_PREFIX, SP_TEXT_SRTP_PREFIX },
332 { 0, NULL }
334 #endif
336 enum sp_encr_alg_t {
337 SP_ENCR_NULL = 0,
338 SP_ENCR_AES_CM,
339 SP_ENCR_AES_F8
342 static const value_string sp_encr_alg_vals[] = {
343 { SP_ENCR_NULL, "NULL" },
344 { SP_ENCR_AES_CM, "AES-CM" },
345 { SP_ENCR_AES_F8, "AES-F8" },
346 { 0, NULL }
349 enum sp_auth_alg_t {
350 SP_AUTH_NULL = 0,
351 SP_AUTH_HMAC_SHA_1
354 static const value_string sp_auth_alg_vals[] = {
355 { SP_AUTH_NULL, "NULL" },
356 { SP_AUTH_HMAC_SHA_1, "HMAC-SHA-1" },
357 { 0, NULL }
360 enum sp_prf_t {
361 SP_PRF_AES_CM = 0
364 static const value_string sp_prf_vals[] = {
365 { SP_PRF_AES_CM, "AES-CM" },
366 { 0, NULL }
369 enum sp_fec_t {
370 SP_FEC_SRTP = 0
373 static const value_string sp_fec_vals[] = {
374 { SP_FEC_SRTP, "FEC-SRTP" },
375 { 0, NULL }
378 enum sp_prot_t {
379 SP_PROT_TYPE_SRTP = 0
382 static const value_string sp_prot_type_vals[] = {
383 { SP_PROT_TYPE_SRTP, "SRTP" },
384 { 0, NULL }
387 enum prf_func_t {
388 PRF_FUNC_MIKEY_1 = 0
391 static const value_string prf_func_vals[] = {
392 { PRF_FUNC_MIKEY_1, "MIKEY-1" },
393 { 0, NULL }
396 enum kv_t {
397 KV_NULL = 0,
398 KV_SPI,
399 KV_INTERVAL
402 static const value_string kv_vals[] = {
403 { KV_NULL, "Null" },
404 { KV_SPI, "SPI/MKI" },
405 { KV_INTERVAL, "Interval" },
406 { 0, NULL }
409 enum kd_t {
410 KD_TGK = 0,
411 KD_TGK_SALT,
412 KD_TEK,
413 KD_TEK_SALT
416 static const value_string kd_vals[] = {
417 { KD_TGK, "TGK" },
418 { KD_TGK_SALT, "TGK+SALT" },
419 { KD_TEK, "TEK" },
420 { KD_TEK_SALT, "TEK+SALT" },
421 { 0, NULL }
424 enum err_t {
425 ERR_AUTH_FAILURE = 0,
426 ERR_INVALID_TS,
427 ERR_INVALID_PRF,
428 ERR_INVALID_MAC,
429 ERR_INVALID_EA,
430 ERR_INVALID_HA,
431 ERR_INVALID_DH,
432 ERR_INVALID_ID,
433 ERR_INVALID_CERT,
434 ERR_INVALID_SP,
435 ERR_INVALID_SPPAR,
436 ERR_INVALID_DT,
437 ERR_UNKNOWN
440 static const value_string err_vals[] = {
441 { ERR_AUTH_FAILURE, "Authentication failure" },
442 { ERR_INVALID_TS, "Invalid timestamp" },
443 { ERR_INVALID_PRF, "PRF function not supported" },
444 { ERR_INVALID_MAC, "MAC algorithm not supported" },
445 { ERR_INVALID_EA, "Encryption algorithm not supported" },
446 { ERR_INVALID_HA, "Hash function not supported" },
447 { ERR_INVALID_DH, "DH group not supported" },
448 { ERR_INVALID_ID, "ID not supported" },
449 { ERR_INVALID_CERT, "Certificate not supported" },
450 { ERR_INVALID_SP, "SP type not supported" },
451 { ERR_INVALID_SPPAR, "SP parameters not supported" },
452 { ERR_INVALID_DT, "Data type not supported" },
453 { ERR_UNKNOWN, "Unspecified error" },
454 { 0, NULL }
456 static value_string_ext err_vals_ext = VALUE_STRING_EXT_INIT(err_vals);
458 enum genext_t {
459 GEN_EXT_VENDOR_ID = 0,
460 GEN_EXT_SDP_ID
463 static const value_string genext_type_vals[] = {
464 { GEN_EXT_VENDOR_ID, "Vendor-ID" },
465 { GEN_EXT_SDP_ID, "SDP-IDs" },
466 { 0, NULL }
469 enum {
470 /* HDR */
471 POS_HDR_VERSION=0,
472 POS_HDR_DATA_TYPE,
473 POS_HDR_V,
474 POS_HDR_PRF_FUNC,
475 POS_HDR_CSB_ID,
476 POS_HDR_CS_COUNT,
477 POS_HDR_CS_ID_MAP_TYPE,
478 POS_ID_SRTP,
479 POS_ID_SRTP_NO,
480 POS_ID_SRTP_SSRC,
481 POS_ID_SRTP_ROC,
483 /* KEMAC */
484 POS_KEMAC_ENCR_ALG,
485 POS_KEMAC_ENCR_DATA_LEN,
486 POS_KEMAC_ENCR_DATA,
487 POS_KEMAC_MAC_ALG,
488 POS_KEMAC_MAC,
490 /* PKE */
491 POS_PKE_C,
492 POS_PKE_DATA_LEN,
493 POS_PKE_DATA,
495 /* DH */
496 POS_DH_GROUP,
497 POS_DH_VALUE,
498 POS_DH_RESERV,
499 POS_DH_KV,
501 /* SIGN */
502 POS_SIGNATURE_LEN,
503 POS_SIGNATURE,
504 POS_SIGN_S_TYPE,
506 /* T */
507 POS_TS_TYPE,
508 POS_TS_NTP,
510 /* ID/IDR */
511 POS_ID_ROLE,
512 POS_ID_TYPE,
513 POS_ID_LEN,
514 POS_ID,
516 /* CERT */
517 POS_CERT_TYPE,
518 POS_CERT_LEN,
519 POS_CERTIFICATE,
521 /* V */
522 POS_V_AUTH_ALG,
523 POS_V_DATA,
525 /* SP */
526 POS_SP_NO,
527 POS_SP_TYPE,
528 POS_SP_PARAM_LEN,
529 /* POS_SP_PARAM, */
531 /* SP param */
532 POS_SP_PARAM_F,
533 POS_SP_PARAM_F_TYPE,
534 POS_SP_PARAM_F_LEN,
535 POS_SP_PARAM_F_VALUE,
537 /* RAND */
538 POS_RAND_LEN,
539 POS_RAND,
541 /* Error */
542 POS_ERR_NO,
543 POS_ERR_RESERVED,
545 /* Key data */
546 POS_KEY_DATA_TYPE,
547 POS_KEY_DATA_KV,
548 POS_KEY_DATA_LEN,
549 POS_KEY_DATA,
550 POS_KEY_SALT_LEN,
551 POS_KEY_SALT,
552 POS_KEY_KV_FROM_LEN,
553 POS_KEY_KV_FROM,
554 POS_KEY_KV_TO_LEN,
555 POS_KEY_KV_TO,
556 POS_KEY_KV_SPI_LEN,
557 POS_KEY_KV_SPI,
559 /* General Ext. */
560 POS_GENERAL_EXT_TYPE,
561 POS_GENERAL_EXT_LEN,
562 POS_GENERAL_EXT_DATA,
563 POS_GENERAL_EXT_VALUE,
565 /* SAKKE */
566 POS_SAKKE_PARAMS,
567 POS_SAKKE_ID_SCHEME,
568 POS_SAKKE_LEN,
569 POS_SAKKE_DATA,
571 /* MIKEY */
572 POS_PAYLOAD_STR,
573 POS_NEXT_PAYLOAD,
575 /* Unused */
576 /* POS_PAYLOAD, */
578 MAX_POS
581 typedef struct tag_mikey_t {
582 uint8_t type;
583 } mikey_t;
585 typedef int (*mikey_dissector_t)(mikey_t *, tvbuff_t *, packet_info *, proto_tree *);
586 struct mikey_dissector_entry {
587 int type;
588 mikey_dissector_t dissector;
591 /* Forward declaration we need below */
592 static int dissect_payload(int payload, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
595 /* Initialize the protocol and registered fields */
596 static int proto_mikey;
597 static int hf_mikey[MAX_POS+1];
598 static int hf_mikey_sp_param[SP_MAX+1];
599 static int hf_mikey_pl[PL_MAX];
601 /* Initialize the subtree pointers */
602 static int ett_mikey;
603 static int ett_mikey_payload;
604 static int ett_mikey_sp_param;
605 static int ett_mikey_hdr_id;
606 static int ett_mikey_enc_data;
608 static dissector_handle_t mikey_handle;
610 static const struct mikey_dissector_entry *
611 mikey_dissector_lookup(const struct mikey_dissector_entry *map, int type)
613 unsigned int i;
614 for (i = 0; map[i].dissector != NULL; i++) {
615 if (map[i].type == type) {
616 return &map[i];
620 return NULL;
623 static void
624 add_next_payload(tvbuff_t *tvb, proto_tree *tree, int offset)
626 proto_tree_add_item(tree, hf_mikey[POS_NEXT_PAYLOAD], tvb, offset, 1, ENC_BIG_ENDIAN);
630 static int
631 dissect_payload_cs_id_srtp(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
633 if (tree) {
634 proto_item *id_ti;
635 proto_tree *id_tree;
636 uint8_t no;
637 uint32_t ssrc;
638 uint32_t roc;
640 no = tvb_get_uint8(tvb, 0);
641 ssrc = tvb_get_ntohl(tvb, 1);
642 roc = tvb_get_ntohl(tvb, 5);
644 id_ti = proto_tree_add_none_format(tree, hf_mikey[POS_ID_SRTP], tvb, 0, 9,
645 "SRTP ID: Policy: %d, SSRC: 0x%x, ROC: 0x%x", no, ssrc, roc);
646 id_tree = proto_item_add_subtree(id_ti, ett_mikey_hdr_id);
648 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_NO], tvb, 0, 1, ENC_BIG_ENDIAN);
649 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_SSRC], tvb, 1, 4, ENC_BIG_ENDIAN);
650 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_ROC], tvb, 5, 4, ENC_BIG_ENDIAN);
652 return 9;
655 static const struct mikey_dissector_entry cs_id_map[] = {
656 { CS_ID_SRTP, dissect_payload_cs_id_srtp },
657 { 0, NULL }
660 static int
661 dissect_payload_cs_id(int type, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
663 const struct mikey_dissector_entry *entry;
665 entry = mikey_dissector_lookup(cs_id_map, type);
667 if (!entry || !entry->dissector) {
668 return 0;
671 return entry->dissector(mikey, tvb, pinfo, tree);
675 static int
676 dissect_payload_hdr(mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
678 int offset = 0;
679 uint8_t cs_id_map_type;
680 uint8_t ncs;
681 int i;
683 tvb_ensure_bytes_exist(tvb, offset, 10);
684 mikey->type = tvb_get_uint8(tvb, offset+1);
685 ncs = tvb_get_uint8(tvb, offset+8);
686 cs_id_map_type = tvb_get_uint8(tvb, offset+9);
688 if (tree) {
689 proto_item* parent;
690 proto_tree_add_item(tree, hf_mikey[POS_HDR_VERSION],
691 tvb, offset+0, 1, ENC_BIG_ENDIAN);
693 proto_tree_add_item(tree, hf_mikey[POS_HDR_DATA_TYPE], tvb, offset+1, 1, ENC_BIG_ENDIAN);
694 parent = proto_tree_get_parent(tree);
695 proto_item_append_text(parent, " Type: %s",
696 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
698 add_next_payload(tvb, tree, offset+2);
700 proto_tree_add_item(tree, hf_mikey[POS_HDR_V], tvb, offset+3, 1, ENC_BIG_ENDIAN);
701 proto_tree_add_item(tree, hf_mikey[POS_HDR_PRF_FUNC], tvb, offset+3, 1, ENC_BIG_ENDIAN);
703 proto_tree_add_item(tree, hf_mikey[POS_HDR_CSB_ID], tvb, offset+4, 4, ENC_BIG_ENDIAN);
705 proto_tree_add_item(tree, hf_mikey[POS_HDR_CS_COUNT], tvb, offset+8, 1, ENC_BIG_ENDIAN);
706 proto_tree_add_item(tree, hf_mikey[POS_HDR_CS_ID_MAP_TYPE], tvb, offset+9, 1, ENC_BIG_ENDIAN);
709 offset += 10;
710 for (i=0; i < ncs; i++) {
711 tvbuff_t *sub_tvb;
712 int len;
714 sub_tvb = tvb_new_subset_remaining(tvb, offset);
715 len = dissect_payload_cs_id(cs_id_map_type, mikey, sub_tvb, pinfo, tree);
717 if (len < 0)
718 return 0;
720 offset += len;
723 return offset;
726 static int
727 dissect_payload_kemac(mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
729 int offset = 0;
730 uint8_t encr_alg;
731 uint16_t encr_length;
732 uint16_t mac_length;
733 uint8_t mac_alg;
735 encr_alg = tvb_get_uint8(tvb, offset+1);
736 encr_length = tvb_get_ntohs(tvb, offset+2);
737 tvb_ensure_bytes_exist(tvb, offset+4, encr_length+1);
738 mac_alg = tvb_get_uint8(tvb, offset+4+encr_length);
740 if (tree) {
741 tvbuff_t *sub_tvb;
742 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_ALG], tvb, 1, 1, ENC_BIG_ENDIAN);
743 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_DATA_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
744 /* TODO: Add key decode for MIKEY_TYPE_PK_INIT and MIKEY_TYPE_RSA_R_RESP with NULL encryption */
745 if ((encr_alg == ENCR_NULL) && (mikey->type == MIKEY_TYPE_PSK_INIT) && (encr_length > 0)) {
746 proto_item *key_data_item;
747 proto_tree *key_data_tree;
748 /* We can decode easily the Key Data if NULL encryption is used */
749 key_data_item = proto_tree_add_item(tree, hf_mikey_pl[PL_KEY_DATA], tvb, 4, encr_length, ENC_NA);
750 key_data_tree = proto_item_add_subtree(key_data_item, ett_mikey_enc_data);
752 sub_tvb = tvb_new_subset_length(tvb, offset+4, encr_length);
753 dissect_payload(PL_KEY_DATA, mikey, sub_tvb, pinfo, key_data_tree);
754 } else {
755 /* If Key Data is encrypted, show only the encr_data */
756 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_DATA], tvb, 4, encr_length, ENC_NA);
758 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_MAC_ALG], tvb, 4+encr_length, 1, ENC_BIG_ENDIAN);
761 switch (mac_alg) {
762 case MAC_NULL:
763 mac_length = 0;
764 break;
765 case MAC_HMAC_SHA_1_160:
766 mac_length = 160/8;
767 break;
768 default:
769 return 0;
772 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_MAC], tvb, 4+encr_length+1, mac_length, ENC_NA);
774 return 4+encr_length+1+mac_length;
777 static int
778 dissect_payload_pke(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
780 int offset = 0;
781 uint16_t length;
783 length = tvb_get_ntohs(tvb, offset+1) &0x3ff;
785 if (tree) {
786 proto_tree_add_item(tree, hf_mikey[POS_PKE_C], tvb, 1, 2, ENC_BIG_ENDIAN);
788 proto_tree_add_item(tree, hf_mikey[POS_PKE_DATA_LEN], tvb, 1, 2, ENC_BIG_ENDIAN);
791 proto_tree_add_item(tree, hf_mikey[POS_PKE_DATA], tvb, 3, length, ENC_NA);
792 return 3 + length;
795 static int
796 dissect_payload_dh(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
798 int offset = 0;
799 uint8_t dh_group;
800 int dh_length;
801 uint8_t kv;
803 dh_group = tvb_get_uint8(tvb, offset+1);
805 switch (dh_group) {
806 case DH_OAKLEY_5:
807 dh_length = 1536/8;
808 break;
809 case DH_OAKLEY_1:
810 dh_length = 768/8;
811 break;
812 case DH_OAKLEY_2:
813 dh_length = 1024/8;
814 break;
815 default:
816 return 0;
819 kv = tvb_get_uint8(tvb, offset+2+dh_length) & 0x0f;
821 if (tree) {
822 proto_tree_add_item(tree, hf_mikey[POS_DH_GROUP], tvb, 1, 1, ENC_BIG_ENDIAN);
823 proto_tree_add_item(tree, hf_mikey[POS_DH_VALUE], tvb, 2, dh_length, ENC_NA);
824 proto_tree_add_item(tree, hf_mikey[POS_DH_RESERV], tvb, 2+dh_length, 1, ENC_BIG_ENDIAN);
825 proto_tree_add_item(tree, hf_mikey[POS_DH_KV], tvb, 2+dh_length, 1, ENC_BIG_ENDIAN);
828 if (kv != 0) {
829 return 0;
832 return 2 + dh_length + 1;
835 static int
836 dissect_payload_sign(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
838 int offset = 0;
839 uint16_t length;
841 length = ((tvb_get_uint8(tvb, offset+0) & 0x0f) << 8) + tvb_get_uint8(tvb, offset+1);
843 if (tree) {
844 proto_tree_add_item(tree, hf_mikey[POS_SIGN_S_TYPE], tvb, 0, 2, ENC_BIG_ENDIAN);
845 proto_tree_add_uint(tree, hf_mikey[POS_SIGNATURE_LEN], tvb, 0, 2, length);
848 proto_tree_add_item(tree, hf_mikey[POS_SIGNATURE], tvb, 2, length, ENC_NA);
849 return 2 + length;
852 static int
853 dissect_payload_t(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
855 uint8_t ts_type;
856 int offset = 0;
857 int len = 0;
859 ts_type = tvb_get_uint8(tvb, offset+1);
861 if (tree) {
862 proto_tree *parent;
863 parent = proto_tree_get_parent(tree);
864 proto_item_append_text(parent, " Type: %s", val_to_str_const(ts_type, ts_type_vals, "Unknown"));
865 proto_tree_add_item(tree, hf_mikey[POS_TS_TYPE], tvb, offset+1, 1, ENC_BIG_ENDIAN);
868 switch (ts_type) {
869 case T_NTP:
870 case T_NTP_UTC:
871 proto_tree_add_item(tree, hf_mikey[POS_TS_NTP], tvb, offset+2, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
872 len = 10;
873 break;
874 case T_COUNTER:
875 len = 6;
876 break;
877 default:
878 len = 0;
879 break;
882 return len;
885 static int
886 dissect_payload_id(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
888 int offset = 0;
889 uint8_t type;
890 uint16_t length;
892 type = tvb_get_uint8(tvb, offset+1);
893 length = tvb_get_ntohs(tvb, offset+2);
894 if (tree) {
895 proto_tree_add_item(tree, hf_mikey[POS_ID_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
896 proto_tree_add_item(tree, hf_mikey[POS_ID_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
899 if (tree) {
900 proto_item* parent;
901 const uint8_t* pos_id;
902 proto_tree_add_item_ret_string(tree, hf_mikey[POS_ID], tvb, 4, length, ENC_ASCII|ENC_NA, pinfo->pool, &pos_id);
904 parent = proto_tree_get_parent(tree);
905 proto_item_append_text(parent, " %s: %s", val_to_str_const(type, id_type_vals, "Unknown"), pos_id);
908 return 4 + length;
911 static int
912 dissect_payload_idr(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
914 int offset = 0;
915 uint8_t type;
916 uint16_t length;
918 type = tvb_get_uint8(tvb, offset+2);
919 length = tvb_get_ntohs(tvb, offset+3);
920 if (tree) {
921 proto_tree_add_item(tree, hf_mikey[POS_ID_ROLE], tvb, 1, 1, ENC_BIG_ENDIAN);
922 proto_tree_add_item(tree, hf_mikey[POS_ID_TYPE], tvb, 2, 1, ENC_BIG_ENDIAN);
923 proto_tree_add_item(tree, hf_mikey[POS_ID_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
926 if (tree) {
927 proto_item *parent;
928 const uint8_t* pos_id;
929 proto_tree_add_item_ret_string(tree, hf_mikey[POS_ID], tvb, 5, length, ENC_ASCII|ENC_NA, pinfo->pool, &pos_id);
931 parent = proto_tree_get_parent(tree);
932 proto_item_append_text(parent, " %s: %s", val_to_str_const(type, id_type_vals, "Unknown"), pos_id);
935 return 5 + length;
938 static int
939 dissect_payload_cert(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
941 int offset = 0;
942 uint8_t type;
943 uint16_t length;
944 tvbuff_t *subtvb;
945 asn1_ctx_t asn1_ctx;
947 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
949 type = tvb_get_uint8(tvb, offset+1);
950 length = tvb_get_ntohs(tvb, offset+2);
952 tvb_ensure_bytes_exist(tvb, offset+4, length);
954 if (tree) {
955 proto_item *parent;
956 parent = proto_tree_get_parent(tree);
957 proto_tree_add_item(tree, hf_mikey[POS_CERT_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
958 proto_tree_add_item(tree, hf_mikey[POS_CERT_LEN], tvb, 1, 2, ENC_BIG_ENDIAN);
960 proto_item_append_text(parent, " Type: %s", val_to_str_const(type, cert_type_vals, "Unknown"));
963 subtvb = tvb_new_subset_length(tvb, offset+4, length);
964 dissect_x509af_Certificate(false, subtvb, 0, &asn1_ctx, tree, hf_mikey[POS_CERTIFICATE]);
966 return 4 + length;
969 static int
970 dissect_payload_v(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
972 int offset = 0;
973 uint16_t length;
974 uint8_t alg;
976 alg = tvb_get_uint8(tvb, offset+1);
978 proto_tree_add_item(tree, hf_mikey[POS_V_AUTH_ALG], tvb, 1, 1, ENC_BIG_ENDIAN);
980 switch (alg) {
981 case MAC_NULL:
982 length = 0;
983 break;
984 case MAC_HMAC_SHA_1_160:
985 length = 160/8;
986 break;
987 default:
988 return 0;
991 proto_tree_add_item(tree, hf_mikey[POS_V_DATA], tvb, 2, length, ENC_NA);
993 return 2 + length;
996 static int
997 dissect_payload_sp_param(enum sp_prot_t proto, tvbuff_t *tvb, proto_tree *tree)
999 int offset = 0;
1000 uint8_t type;
1001 uint8_t length;
1002 int hfindex;
1004 type = tvb_get_uint8(tvb, offset+0);
1005 length = tvb_get_uint8(tvb, offset+1);
1007 /* Default */
1008 hfindex = hf_mikey[POS_SP_PARAM_F];
1010 switch(proto) {
1011 case SP_PROT_TYPE_SRTP:
1012 if (type < array_length(hf_mikey_sp_param))
1013 hfindex = hf_mikey_sp_param[type];
1014 break;
1017 if (tree) {
1018 proto_item *param_ti;
1019 proto_tree *param_tree;
1021 * All the parameters in question are either FT_BYTES,
1022 * in which case the byte order is inapplicable, or
1023 * FT_UINT8, in which case it could be given as
1024 * FT_BIG_ENDIAN as per bigger FT_UINT values, but
1025 * ENC_NA also works, as there's only one byte.
1027 param_ti = proto_tree_add_item(tree, hfindex, tvb, 2, length, ENC_NA);
1028 param_tree = proto_item_add_subtree(param_ti, ett_mikey_sp_param);
1030 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_TYPE], tvb, 0, 1, ENC_BIG_ENDIAN);
1031 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_LEN], tvb, 1, 1, ENC_BIG_ENDIAN);
1032 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_VALUE], tvb, 2, length, ENC_NA);
1035 return 2+length;
1038 static int
1039 dissect_payload_sp(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1041 int offset = 0;
1042 uint16_t length;
1043 int sub_pos;
1044 uint8_t no;
1045 enum sp_prot_t type;
1047 length = tvb_get_ntohs(tvb, offset+3);
1048 no = tvb_get_uint8(tvb, offset+1);
1049 type = (enum sp_prot_t)tvb_get_uint8(tvb, offset+2);
1051 if (tree) {
1052 proto_item *parent;
1053 parent = proto_tree_get_parent(tree);
1054 proto_tree_add_item(tree, hf_mikey[POS_SP_NO], tvb, 1, 1, ENC_BIG_ENDIAN);
1055 proto_tree_add_item(tree, hf_mikey[POS_SP_TYPE], tvb, 2, 1, ENC_BIG_ENDIAN);
1056 proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
1058 proto_item_append_text(parent, " No: %d, Type: %s", no,
1059 val_to_str_const(type, sp_prot_type_vals, "Unknown"));
1062 tvb_ensure_bytes_exist(tvb, offset+5, length);
1063 /* proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM], tvb, 5, length, ENC_NA); */
1065 offset += 5;
1066 sub_pos = 0;
1068 while (sub_pos < length) {
1069 int param_len;
1070 tvbuff_t *subtvb;
1072 subtvb = tvb_new_subset_length(tvb, offset+sub_pos, length-sub_pos);
1073 param_len = dissect_payload_sp_param(type, subtvb, tree);
1075 if (param_len < 0)
1076 return 0;
1078 sub_pos += param_len;
1081 return 5 + length;
1084 static int
1085 dissect_payload_rand(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1087 int offset = 0;
1088 uint16_t length;
1090 length = tvb_get_uint8(tvb, offset+1);
1092 proto_tree_add_item(tree, hf_mikey[POS_RAND_LEN], tvb, 1, 1, ENC_BIG_ENDIAN);
1093 proto_tree_add_item(tree, hf_mikey[POS_RAND], tvb, 2, length, ENC_NA);
1095 return 2 + length;
1098 static int
1099 dissect_payload_err(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1101 if (tree) {
1102 proto_item *parent;
1103 uint8_t err_no;
1104 err_no = tvb_get_uint8(tvb, 1);
1105 proto_tree_add_item(tree, hf_mikey[POS_ERR_NO], tvb, 1, 1, ENC_BIG_ENDIAN);
1106 proto_tree_add_item(tree, hf_mikey[POS_ERR_RESERVED], tvb, 2, 2, ENC_NA);
1107 parent = proto_tree_get_parent(tree);
1108 proto_item_append_text(parent, ": %s", val_to_str_ext_const(err_no, &err_vals_ext, "Unknown"));
1111 return 4;
1114 static int
1115 dissect_payload_keydata(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1117 uint16_t offset;
1118 uint16_t data_len;
1119 uint8_t key_type;
1120 uint8_t kv_type;
1122 offset = 0;
1123 key_type = tvb_get_uint8(tvb, 1) >> 4;
1124 kv_type = tvb_get_uint8(tvb, 1) & 0x0f;
1125 data_len = tvb_get_ntohs(tvb, 2);
1127 offset += 4;
1129 if (tree) {
1130 proto_item *parent;
1131 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
1132 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_KV], tvb, 1, 1, ENC_BIG_ENDIAN);
1133 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
1134 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA], tvb, 4, data_len, ENC_NA);
1136 parent = proto_tree_get_parent(tree);
1137 proto_item_append_text(parent, " Type: %s", val_to_str_const(key_type, kd_vals, "Unknown"));
1140 offset += data_len;
1142 /* Dissect SALT key */
1143 if ((key_type == KD_TGK_SALT) || (key_type == KD_TEK_SALT)) {
1144 uint16_t salt_len;
1145 salt_len = tvb_get_ntohs(tvb, offset);
1146 if (salt_len > 0) {
1147 proto_tree_add_item(tree, hf_mikey[POS_KEY_SALT_LEN], tvb, offset, 2, ENC_BIG_ENDIAN);
1148 proto_tree_add_item(tree, hf_mikey[POS_KEY_SALT], tvb, offset+2, salt_len, ENC_NA);
1150 offset += 2+salt_len;
1153 /* Dissect Key Validity */
1154 if (kv_type == KV_INTERVAL) {
1155 uint16_t kv_from_len;
1156 uint16_t kv_to_len;
1158 kv_from_len = tvb_get_uint8(tvb, offset);
1159 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_FROM_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1160 if (kv_from_len > 0) {
1161 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_FROM], tvb, offset+1, kv_from_len, ENC_NA);
1163 offset += 1+kv_from_len;
1165 kv_to_len = tvb_get_uint8(tvb, offset);
1166 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_TO_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1167 if (kv_to_len > 0) {
1168 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_TO], tvb, offset+1, kv_to_len, ENC_NA);
1170 offset += 1+kv_to_len;
1171 } else if (kv_type == KV_SPI) {
1172 uint16_t kv_spi_len;
1174 kv_spi_len = tvb_get_uint8(tvb, offset);
1175 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_SPI_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1176 if (kv_spi_len > 0) {
1177 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_SPI], tvb, offset+1, kv_spi_len, ENC_NA);
1179 offset += 1+kv_spi_len;
1182 return offset;
1185 static int
1186 dissect_payload_general_ext(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1188 int offset = 0;
1189 uint8_t type;
1190 uint16_t data_len;
1192 type = tvb_get_uint8(tvb, offset+1);
1193 data_len = tvb_get_ntohs(tvb, offset+2);
1195 if (tree) {
1196 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
1197 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
1200 if (tree) {
1201 proto_item *parent;
1203 parent = proto_tree_get_parent(tree);
1204 if (type == 1) {
1205 /* For SDP-IDs, show a string instead of raw bytes */
1206 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_VALUE], tvb, 4, data_len, ENC_ASCII);
1207 } else {
1208 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_DATA], tvb, 4, data_len, ENC_NA);
1210 proto_item_append_text(parent, " Type: %s", val_to_str_const(type, genext_type_vals, "Unknown"));
1212 return 4 + data_len;
1215 static int
1216 dissect_payload_sakke(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1218 int offset = 0;
1219 uint16_t data_len;
1221 data_len = tvb_get_ntohs(tvb, offset+3);
1223 if (tree) {
1224 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_PARAMS], tvb, 1, 1, ENC_BIG_ENDIAN);
1225 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_ID_SCHEME], tvb, 2, 1, ENC_BIG_ENDIAN);
1226 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
1229 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_DATA], tvb, 5, data_len, ENC_NA);
1230 return 5 + data_len;
1233 static const struct mikey_dissector_entry payload_map[] = {
1234 { PL_HDR, dissect_payload_hdr },
1235 { PL_KEMAC, dissect_payload_kemac },
1236 { PL_PKE, dissect_payload_pke },
1237 { PL_DH, dissect_payload_dh },
1238 { PL_SIGN, dissect_payload_sign },
1239 { PL_T, dissect_payload_t },
1240 { PL_ID, dissect_payload_id },
1241 { PL_CERT, dissect_payload_cert },
1242 { PL_V, dissect_payload_v },
1243 { PL_SP, dissect_payload_sp },
1244 { PL_RAND, dissect_payload_rand },
1245 { PL_ERR, dissect_payload_err },
1246 { PL_IDR, dissect_payload_idr },
1247 { PL_KEY_DATA, dissect_payload_keydata },
1248 { PL_GENERAL_EXT, dissect_payload_general_ext },
1249 { PL_SAKKE, dissect_payload_sakke },
1250 { 0, NULL }
1253 static int
1254 dissect_payload(int payload, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1256 const struct mikey_dissector_entry *entry;
1258 entry = mikey_dissector_lookup(payload_map, payload);
1260 if (!entry || !entry->dissector) {
1261 return 0;
1264 return entry->dissector(mikey, tvb, pinfo, tree);
1267 /* MIKEY dissector */
1268 static int
1269 dissect_mikey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1271 proto_item *ti = NULL;
1272 proto_tree *mikey_tree = NULL;
1273 int offset = 0;
1274 int next_payload_offset;
1275 int payload;
1276 mikey_t *mikey;
1278 mikey = (mikey_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mikey, 0);
1280 if (!mikey) {
1281 mikey = wmem_new0(wmem_file_scope(), mikey_t);
1282 mikey->type = -1;
1283 p_add_proto_data(wmem_file_scope(), pinfo, proto_mikey, 0, mikey);
1287 tvb_ensure_bytes_exist(tvb, offset, 3);
1288 next_payload_offset = offset + 2;
1289 payload = -1;
1291 if (tree) {
1292 ti = proto_tree_add_item(tree, proto_mikey, tvb, 0, -1, ENC_NA);
1293 mikey_tree = proto_item_add_subtree(ti, ett_mikey);
1296 while (payload != 0) {
1297 int len;
1298 proto_item *sub_ti = NULL;
1299 proto_tree *mikey_payload_tree = NULL;
1300 int next_payload;
1301 tvbuff_t *subtvb;
1303 next_payload = tvb_get_uint8(tvb, next_payload_offset);
1304 subtvb = tvb_new_subset_remaining(tvb, offset);
1306 if (mikey_tree) {
1307 int hf = payload;
1309 if (hf >= PL_MAX)
1310 return -1;
1312 if (hf == -1)
1313 hf = 0;
1315 if (hf_mikey_pl[hf] == 0)
1316 return -1;
1318 sub_ti = proto_tree_add_item(mikey_tree, hf_mikey_pl[hf], subtvb, 0, -1, ENC_NA);
1320 mikey_payload_tree = proto_item_add_subtree(sub_ti, ett_mikey_payload);
1321 if ((payload != PL_HDR) && (payload != PL_SIGN))
1322 add_next_payload(tvb, mikey_payload_tree, next_payload_offset);
1325 len = dissect_payload(payload, mikey, subtvb, pinfo, mikey_payload_tree);
1326 if (len <= 0) {
1327 /* protocol violation or invalid data, stop dissecting
1328 * but accept the data retrieved so far */
1329 return tvb_captured_length(tvb);
1332 if (sub_ti)
1333 proto_item_set_len(sub_ti, len);
1335 if (payload == PL_SIGN)
1336 break;
1338 payload = next_payload;
1339 offset += len;
1340 next_payload_offset = offset;
1343 if (ti) {
1344 proto_item_append_text(ti, ": %s",
1345 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
1348 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/MIKEY");
1350 col_append_fstr(pinfo->cinfo, COL_INFO, ", Mikey: %s",
1351 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
1353 /* Return the amount of data this dissector was able to dissect */
1354 return tvb_captured_length(tvb);
1358 /* Register the protocol with Wireshark */
1360 void
1361 proto_register_mikey(void)
1364 /* Setup list of header fields */
1365 static hf_register_info hf[] = {
1366 /* Payload types */
1367 { &hf_mikey_pl[PL_HDR+1],
1368 { PL_HDR_TEXT, "mikey.hdr",
1369 FT_NONE, BASE_NONE, NULL, 0x0,
1370 NULL, HFILL }},
1371 { &hf_mikey_pl[PL_KEMAC],
1372 { PL_KEMAC_TEXT, "mikey.kemac",
1373 FT_NONE, BASE_NONE, NULL, 0x0,
1374 NULL, HFILL }},
1375 { &hf_mikey_pl[PL_PKE],
1376 { PL_PKE_TEXT, "mikey.pke",
1377 FT_NONE, BASE_NONE, NULL, 0x0,
1378 NULL, HFILL }},
1379 { &hf_mikey_pl[PL_DH],
1380 { PL_DH_TEXT, "mikey.dh",
1381 FT_NONE, BASE_NONE, NULL, 0x0,
1382 NULL, HFILL }},
1383 { &hf_mikey_pl[PL_SIGN],
1384 { PL_SIGN_TEXT, "mikey.sign",
1385 FT_NONE, BASE_NONE, NULL, 0x0,
1386 NULL, HFILL }},
1387 { &hf_mikey_pl[PL_T],
1388 { PL_T_TEXT, "mikey.t",
1389 FT_NONE, BASE_NONE, NULL, 0x0,
1390 NULL, HFILL }},
1391 { &hf_mikey_pl[PL_ID],
1392 { PL_ID_TEXT, "mikey.id",
1393 FT_NONE, BASE_NONE, NULL, 0x0,
1394 NULL, HFILL }},
1395 { &hf_mikey_pl[PL_CERT],
1396 { PL_CERT_TEXT, "mikey.cert",
1397 FT_NONE, BASE_NONE, NULL, 0x0,
1398 NULL, HFILL }},
1399 { &hf_mikey_pl[PL_CHASH],
1400 { PL_CHASH_TEXT, "mikey.chash",
1401 FT_NONE, BASE_NONE, NULL, 0x0,
1402 NULL, HFILL }},
1403 { &hf_mikey_pl[PL_V],
1404 { PL_V_TEXT, "mikey.v",
1405 FT_NONE, BASE_NONE, NULL, 0x0,
1406 NULL, HFILL }},
1407 { &hf_mikey_pl[PL_SP],
1408 { PL_SP_TEXT, "mikey.sp",
1409 FT_NONE, BASE_NONE, NULL, 0x0,
1410 NULL, HFILL }},
1411 { &hf_mikey_pl[PL_RAND],
1412 { PL_RAND_TEXT, "mikey.rand",
1413 FT_NONE, BASE_NONE, NULL, 0x0,
1414 NULL, HFILL }},
1415 { &hf_mikey_pl[PL_ERR],
1416 { PL_ERR_TEXT, "mikey.err",
1417 FT_NONE, BASE_NONE, NULL, 0x0,
1418 NULL, HFILL }},
1419 { &hf_mikey_pl[PL_IDR],
1420 { PL_IDR_TEXT, "mikey.idr",
1421 FT_NONE, BASE_NONE, NULL, 0x0,
1422 NULL, HFILL }},
1423 { &hf_mikey_pl[PL_KEY_DATA],
1424 { PL_KEY_DATA_TEXT, "mikey.key",
1425 FT_NONE, BASE_NONE, NULL, 0x0,
1426 NULL, HFILL }},
1427 { &hf_mikey_pl[PL_GENERAL_EXT],
1428 { PL_GENERAL_EXT_TEXT, "mikey.ext",
1429 FT_NONE, BASE_NONE, NULL, 0x0,
1430 NULL, HFILL }},
1431 { &hf_mikey_pl[PL_SAKKE],
1432 { PL_SAKKE_TEXT, "mikey.sakke",
1433 FT_NONE, BASE_NONE, NULL, 0x0,
1434 NULL, HFILL }},
1436 /* Common Header payload (HDR) */
1437 { &hf_mikey[POS_HDR_VERSION],
1438 { "Version", "mikey.version",
1439 FT_UINT8, BASE_DEC, NULL, 0x0,
1440 NULL, HFILL }},
1441 { &hf_mikey[POS_HDR_DATA_TYPE],
1442 { "Data Type", "mikey.type",
1443 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &data_type_vals_ext, 0x0,
1444 NULL, HFILL }},
1445 { &hf_mikey[POS_NEXT_PAYLOAD],
1446 { "Next Payload", "mikey.next_payload",
1447 FT_UINT8, BASE_DEC, VALS(payload_vals), 0x0,
1448 NULL, HFILL }},
1449 { &hf_mikey[POS_HDR_V],
1450 { "V", "mikey.v.set",
1451 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
1452 NULL, HFILL }},
1453 { &hf_mikey[POS_HDR_PRF_FUNC],
1454 { "PRF func", "mikey.prf_func",
1455 FT_UINT8, BASE_DEC, VALS(prf_func_vals), 0x7f,
1456 NULL, HFILL }},
1457 { &hf_mikey[POS_HDR_CSB_ID],
1458 { "CSB ID", "mikey.csb_id",
1459 FT_UINT32, BASE_HEX, NULL, 0x0,
1460 NULL, HFILL }},
1461 { &hf_mikey[POS_HDR_CS_COUNT],
1462 { "#CS", "mikey.cs_count",
1463 FT_UINT8, BASE_DEC, NULL, 0x0,
1464 NULL, HFILL }},
1465 { &hf_mikey[POS_HDR_CS_ID_MAP_TYPE],
1466 { "CS ID map type", "mikey.cs_id_map_type",
1467 FT_UINT8, BASE_DEC, VALS(cs_id_map_vals), 0x0,
1468 NULL, HFILL }},
1470 /* SRTP ID */
1471 { &hf_mikey[POS_ID_SRTP],
1472 { "SRTP ID", "mikey.srtp_id",
1473 FT_NONE, BASE_NONE, NULL, 0x0,
1474 NULL, HFILL }},
1475 { &hf_mikey[POS_ID_SRTP_NO],
1476 { "Policy No", "mikey.srtp_id.policy_no",
1477 FT_UINT8, BASE_DEC, NULL, 0x0,
1478 NULL, HFILL }},
1479 { &hf_mikey[POS_ID_SRTP_SSRC],
1480 { "SSRC", "mikey.srtp_id.ssrc",
1481 FT_UINT32, BASE_HEX, NULL, 0x0,
1482 NULL, HFILL }},
1483 { &hf_mikey[POS_ID_SRTP_ROC],
1484 { "ROC", "mikey.srtp_id.roc",
1485 FT_UINT32, BASE_HEX, NULL, 0x0,
1486 NULL, HFILL }},
1488 /* Key Data Transport payload (KEMAC) */
1489 { &hf_mikey[POS_KEMAC_ENCR_ALG],
1490 { "Encr alg", "mikey.kemac.encr_alg",
1491 FT_UINT8, BASE_DEC, VALS(encr_alg_vals), 0x0,
1492 NULL, HFILL }},
1493 { &hf_mikey[POS_KEMAC_ENCR_DATA_LEN],
1494 { "Key data len", "mikey.kemac.key_data_len",
1495 FT_UINT16, BASE_DEC, NULL, 0x0,
1496 NULL, HFILL }},
1497 { &hf_mikey[POS_KEMAC_ENCR_DATA],
1498 { "Key data", "mikey.kemac.key_data",
1499 FT_BYTES, BASE_NONE, NULL, 0x0,
1500 NULL, HFILL }},
1501 { &hf_mikey[POS_KEMAC_MAC_ALG],
1502 { "Mac alg", "mikey.kemac.mac_alg",
1503 FT_UINT8, BASE_DEC, VALS(mac_alg_vals), 0x0,
1504 NULL, HFILL }},
1505 { &hf_mikey[POS_KEMAC_MAC],
1506 { "MAC", "mikey.kemac.mac",
1507 FT_BYTES, BASE_NONE, NULL, 0x0,
1508 NULL, HFILL }},
1510 /* Envelope Data payload (PKE) */
1511 { &hf_mikey[POS_PKE_C],
1512 { "C", "mikey.pke.c",
1513 FT_UINT16, BASE_DEC, VALS(pke_c_vals), 0xc000,
1514 NULL, HFILL }},
1515 { &hf_mikey[POS_PKE_DATA_LEN],
1516 { "Data len", "mikey.pke.len",
1517 FT_UINT16, BASE_DEC, NULL, 0x3fff,
1518 NULL, HFILL }},
1519 { &hf_mikey[POS_PKE_DATA],
1520 { "Data", "mikey.pke.data",
1521 FT_BYTES, BASE_NONE, NULL, 0x0,
1522 NULL, HFILL }},
1524 /* DH data payload (DH) */
1525 { &hf_mikey[POS_DH_GROUP],
1526 { "DH-Group", "mikey.dh.group",
1527 FT_UINT8, BASE_DEC, VALS(oakley_vals), 0x0,
1528 NULL, HFILL }},
1529 { &hf_mikey[POS_DH_VALUE],
1530 { "DH-Value", "mikey.dh.value",
1531 FT_BYTES, BASE_NONE, NULL, 0x0,
1532 NULL, HFILL }},
1533 { &hf_mikey[POS_DH_RESERV],
1534 { "Reserv", "mikey.dh.reserv",
1535 FT_UINT8, BASE_HEX, NULL, 0xf0,
1536 NULL, HFILL }},
1537 { &hf_mikey[POS_DH_KV],
1538 { "KV", "mikey.dh.kv",
1539 FT_UINT8, BASE_DEC, VALS(kv_vals), 0x0f,
1540 NULL, HFILL }},
1542 /* Signature payload (SIGN) */
1543 { &hf_mikey[POS_SIGN_S_TYPE],
1544 { "Signature type", "mikey.sign.type",
1545 FT_UINT16, BASE_DEC, VALS(sign_s_vals), 0xf000,
1546 NULL, HFILL }},
1547 { &hf_mikey[POS_SIGNATURE_LEN],
1548 { "Signature len", "mikey.sign.len",
1549 FT_UINT16, BASE_DEC, NULL, 0x0fff,
1550 NULL, HFILL }},
1551 { &hf_mikey[POS_SIGNATURE],
1552 { "Signature", "mikey.sign.data",
1553 FT_BYTES, BASE_NONE, NULL, 0x0,
1554 NULL, HFILL }},
1556 /* Timestamp payload (T) */
1557 { &hf_mikey[POS_TS_TYPE],
1558 { "TS type", "mikey.t.ts_type",
1559 FT_UINT8, BASE_DEC, VALS(ts_type_vals), 0x0,
1560 NULL, HFILL }},
1561 { &hf_mikey[POS_TS_NTP],
1562 { "NTP timestamp", "mikey.t.ntp",
1563 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
1564 NULL, HFILL }},
1566 { &hf_mikey[POS_PAYLOAD_STR],
1567 { "Payload", "mikey.payload",
1568 FT_STRING, BASE_NONE, NULL, 0x0,
1569 NULL, HFILL }},
1571 /* ID payload (ID) */
1572 { &hf_mikey[POS_ID_TYPE],
1573 { "ID type", "mikey.id.type",
1574 FT_UINT8, BASE_DEC, VALS(id_type_vals), 0x0,
1575 NULL, HFILL }},
1576 { &hf_mikey[POS_ID_LEN],
1577 { "ID len", "mikey.id.len",
1578 FT_UINT16, BASE_DEC, NULL, 0x0,
1579 NULL, HFILL }},
1580 { &hf_mikey[POS_ID],
1581 { "ID", "mikey.id.data",
1582 FT_STRING, BASE_NONE, NULL, 0x0,
1583 NULL, HFILL }},
1585 /* Certificate payload (CERT) */
1586 { &hf_mikey[POS_CERT_LEN],
1587 { "Certificate len", "mikey.cert.len",
1588 FT_UINT16, BASE_DEC, NULL, 0x0,
1589 NULL, HFILL }},
1590 { &hf_mikey[POS_CERT_TYPE],
1591 { "Certificate type", "mikey.cert.type",
1592 FT_UINT8, BASE_DEC, VALS(cert_type_vals), 0x0,
1593 NULL, HFILL }},
1594 { &hf_mikey[POS_CERTIFICATE],
1595 { "Certificate", "mikey.cert.data",
1596 FT_BYTES, BASE_NONE, NULL, 0x0,
1597 NULL, HFILL }},
1599 /* Ver msg payload (V) */
1600 { &hf_mikey[POS_V_AUTH_ALG],
1601 { "Auth alg", "mikey.v.auth_alg",
1602 FT_UINT8, BASE_DEC, VALS(mac_alg_vals), 0x0,
1603 NULL, HFILL }},
1604 { &hf_mikey[POS_V_DATA],
1605 { "Ver data", "mikey.v.ver_data",
1606 FT_BYTES, BASE_NONE, NULL, 0x0,
1607 NULL, HFILL }},
1609 /* Security Policy payload (SP) */
1610 { &hf_mikey[POS_SP_NO],
1611 { "Policy No", "mikey.sp.no",
1612 FT_UINT8, BASE_DEC, NULL, 0x0,
1613 NULL, HFILL }},
1614 { &hf_mikey[POS_SP_TYPE],
1615 { "Protocol type", "mikey.sp.proto_type",
1616 FT_UINT8, BASE_DEC, VALS(sp_prot_type_vals), 0x0,
1617 NULL, HFILL }},
1618 { &hf_mikey[POS_SP_PARAM_LEN],
1619 { "Policy param length", "mikey.sp.param_len",
1620 FT_UINT16, BASE_DEC, NULL, 0x0,
1621 NULL, HFILL }},
1623 /* Security Policy param */
1624 { &hf_mikey[POS_SP_PARAM_F],
1625 { "Policy param", "mikey.sp.param",
1626 FT_BYTES, BASE_NONE, NULL, 0x0,
1627 NULL, HFILL }},
1628 { &hf_mikey[POS_SP_PARAM_F_TYPE],
1629 { "Type", "mikey.sp.param.type",
1630 FT_UINT8, BASE_DEC, NULL, 0x0,
1631 NULL, HFILL }},
1632 { &hf_mikey[POS_SP_PARAM_F_LEN],
1633 { "Length", "mikey.sp.param.len",
1634 FT_UINT8, BASE_DEC, NULL, 0x0,
1635 NULL, HFILL }},
1636 { &hf_mikey[POS_SP_PARAM_F_VALUE],
1637 { "Value", "mikey.sp.patam.value",
1638 FT_BYTES, BASE_NONE, NULL, 0x0,
1639 NULL, HFILL }},
1641 /* SRTP policy param */
1642 { &hf_mikey_sp_param[SP_ENCR_ALG],
1643 { SP_TEXT_ENCR_ALG, "mikey.sp.encr_alg",
1644 FT_UINT8, BASE_DEC, VALS(sp_encr_alg_vals), 0x0,
1645 NULL, HFILL }},
1646 { &hf_mikey_sp_param[SP_ENCR_LEN],
1647 { SP_TEXT_ENCR_LEN, "mikey.sp.encr_len",
1648 FT_UINT8, BASE_DEC, NULL, 0x0,
1649 NULL, HFILL }},
1650 { &hf_mikey_sp_param[SP_AUTH_ALG],
1651 { SP_TEXT_AUTH_ALG, "mikey.sp.auth_alg",
1652 FT_UINT8, BASE_DEC, VALS(sp_auth_alg_vals), 0x0,
1653 NULL, HFILL }},
1654 { &hf_mikey_sp_param[SP_AUTH_KEY_LEN],
1655 { SP_TEXT_AUTH_KEY_LEN, "mikey.sp.auth_key_len",
1656 FT_UINT8, BASE_DEC, NULL, 0x0,
1657 NULL, HFILL }},
1658 { &hf_mikey_sp_param[SP_SALT_LEN],
1659 { SP_TEXT_SALT_LEN, "mikey.sp.salt_len",
1660 FT_UINT8, BASE_DEC, NULL, 0x0,
1661 NULL, HFILL }},
1662 { &hf_mikey_sp_param[SP_PRF],
1663 { SP_TEXT_PRF, "mikey.sp.prf",
1664 FT_UINT8, BASE_DEC, VALS(sp_prf_vals), 0x0,
1665 NULL, HFILL }},
1666 { &hf_mikey_sp_param[SP_KD_RATE],
1667 { SP_TEXT_KD_RATE, "mikey.sp.kd_rate",
1668 FT_UINT8, BASE_DEC, NULL, 0x0,
1669 NULL, HFILL }},
1670 { &hf_mikey_sp_param[SP_SRTP_ENCR],
1671 { SP_TEXT_SRTP_ENCR, "mikey.sp.srtp_encr",
1672 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1673 NULL, HFILL }},
1674 { &hf_mikey_sp_param[SP_SRTCP_ENCR],
1675 { SP_TEXT_SRTCP_ENCR, "mikey.sp.srtcp_encr",
1676 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1677 NULL, HFILL }},
1678 { &hf_mikey_sp_param[SP_FEC],
1679 { SP_TEXT_FEC, "mikey.sp.fec",
1680 FT_UINT8, BASE_DEC, VALS(sp_fec_vals), 0x0,
1681 NULL, HFILL }},
1682 { &hf_mikey_sp_param[SP_SRTP_AUTH],
1683 { SP_TEXT_SRTP_AUTH, "mikey.sp.srtp_auth",
1684 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1685 NULL, HFILL }},
1686 { &hf_mikey_sp_param[SP_AUTH_TAG_LEN],
1687 { SP_TEXT_AUTH_TAG_LEN, "mikey.sp.auth_tag_len",
1688 FT_UINT8, BASE_DEC, NULL, 0x0,
1689 NULL, HFILL }},
1690 { &hf_mikey_sp_param[SP_SRTP_PREFIX],
1691 { SP_TEXT_SRTP_PREFIX, "mikey.sp.srtp_prefix",
1692 FT_UINT8, BASE_DEC, NULL, 0x0,
1693 NULL, HFILL }},
1695 /* RAND payload (RAND) */
1696 { &hf_mikey[POS_RAND_LEN],
1697 { "RAND len", "mikey.rand.len",
1698 FT_UINT8, BASE_DEC, NULL, 0x0,
1699 NULL, HFILL }},
1700 { &hf_mikey[POS_RAND],
1701 { "RAND", "mikey.rand.data",
1702 FT_BYTES, BASE_NONE, NULL, 0x0,
1703 NULL, HFILL }},
1705 /* Error payload (ERR) */
1706 { &hf_mikey[POS_ERR_NO],
1707 { "Error no.", "mikey.err.no",
1708 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &err_vals_ext, 0x0,
1709 NULL, HFILL }},
1710 { &hf_mikey[POS_ERR_RESERVED],
1711 { "Reserved", "mikey.err.reserved",
1712 FT_BYTES, BASE_NONE, NULL, 0x0,
1713 NULL, HFILL }},
1715 /* IDR */
1716 { &hf_mikey[POS_ID_ROLE],
1717 { "ID role", "mikey.id.role",
1718 FT_UINT8, BASE_DEC, VALS(id_role_vals), 0x0,
1719 NULL, HFILL }},
1721 /* Key data sub-payload */
1722 { &hf_mikey[POS_KEY_DATA_TYPE],
1723 { "Type", "mikey.key.type",
1724 FT_UINT8, BASE_DEC, VALS(kd_vals), 0xf0,
1725 NULL, HFILL }},
1726 { &hf_mikey[POS_KEY_DATA_KV],
1727 { "KV", "mikey.key.kv",
1728 FT_UINT8, BASE_DEC, VALS(kv_vals), 0x0f,
1729 NULL, HFILL }},
1730 { &hf_mikey[POS_KEY_DATA_LEN],
1731 { "Key len", "mikey.key.data.len",
1732 FT_UINT16, BASE_DEC, NULL, 0x0,
1733 NULL, HFILL }},
1734 { &hf_mikey[POS_KEY_DATA],
1735 { "Key", "mikey.key.data",
1736 FT_BYTES, BASE_NONE, NULL, 0x0,
1737 NULL, HFILL }},
1738 { &hf_mikey[POS_KEY_SALT_LEN],
1739 { "Salt key len", "mikey.key.salt.len",
1740 FT_UINT16, BASE_DEC, NULL, 0x0,
1741 NULL, HFILL }},
1742 { &hf_mikey[POS_KEY_SALT],
1743 { "Salt key", "mikey.key.salt",
1744 FT_BYTES, BASE_NONE, NULL, 0x0,
1745 NULL, HFILL }},
1746 { &hf_mikey[POS_KEY_KV_FROM_LEN],
1747 { "Valid from len", "mikey.key.kv.from.len",
1748 FT_UINT8, BASE_DEC, NULL, 0x0,
1749 NULL, HFILL }},
1750 { &hf_mikey[POS_KEY_KV_FROM],
1751 { "Valid from", "mikey.key.kv.from",
1752 FT_BYTES, BASE_NONE, NULL, 0x0,
1753 NULL, HFILL }},
1754 { &hf_mikey[POS_KEY_KV_TO_LEN],
1755 { "Valid to len", "mikey.key.kv.to.len",
1756 FT_UINT8, BASE_DEC, NULL, 0x0,
1757 NULL, HFILL }},
1758 { &hf_mikey[POS_KEY_KV_TO],
1759 { "Valid to", "mikey.key.kv.to",
1760 FT_BYTES, BASE_NONE, NULL, 0x0,
1761 NULL, HFILL }},
1762 { &hf_mikey[POS_KEY_KV_SPI_LEN],
1763 { "Valid SPI len", "mikey.key.kv.spi.len",
1764 FT_UINT8, BASE_DEC, NULL, 0x0,
1765 NULL, HFILL }},
1766 { &hf_mikey[POS_KEY_KV_SPI],
1767 { "Valid SPI", "mikey.key.kv.spi",
1768 FT_BYTES, BASE_NONE, NULL, 0x0,
1769 NULL, HFILL }},
1771 /* General Extension payload (GENERAL_EXT) */
1772 { &hf_mikey[POS_GENERAL_EXT_TYPE],
1773 { "Extension type", "mikey.ext.type",
1774 FT_UINT8, BASE_DEC, VALS(genext_type_vals), 0x0,
1775 NULL, HFILL }},
1776 { &hf_mikey[POS_GENERAL_EXT_LEN],
1777 { "Length", "mikey.ext.len",
1778 FT_UINT16, BASE_DEC, NULL, 0x0,
1779 NULL, HFILL }},
1780 { &hf_mikey[POS_GENERAL_EXT_DATA],
1781 { "Data", "mikey.ext.data",
1782 FT_BYTES, BASE_NONE, NULL, 0x0,
1783 NULL, HFILL }},
1784 { &hf_mikey[POS_GENERAL_EXT_VALUE],
1785 { "Value", "mikey.ext.value",
1786 FT_STRING, BASE_NONE, NULL, 0x0,
1787 NULL, HFILL }},
1789 /* SAKKE */
1790 { &hf_mikey[POS_SAKKE_PARAMS],
1791 { "SAKKE params", "mikey.sakke.params",
1792 FT_UINT8, BASE_DEC, NULL, 0x0,
1793 NULL, HFILL }},
1794 { &hf_mikey[POS_SAKKE_ID_SCHEME],
1795 { "ID scheme", "mikey.sakke.idscheme",
1796 FT_UINT8, BASE_DEC, NULL, 0x0,
1797 NULL, HFILL }},
1798 { &hf_mikey[POS_SAKKE_LEN],
1799 { "SAKKE data length", "mikey.sakke.len",
1800 FT_UINT16, BASE_DEC, NULL, 0x0,
1801 NULL, HFILL }},
1802 { &hf_mikey[POS_SAKKE_DATA],
1803 { "SAKKE data", "mikey.sakke.data",
1804 FT_BYTES, BASE_NONE, NULL, 0x0,
1805 NULL, HFILL }},
1808 { &hf_mikey[POS_SP_PARAM],
1809 { "Policy param", "mikey.policy_param",
1810 FT_BYTES, BASE_NONE, NULL, 0x0,
1811 NULL, HFILL }},
1813 { &hf_mikey[POS_PAYLOAD],
1814 { "Payload", "mikey.payload",
1815 FT_BYTES, BASE_HEX, NULL, 0x0,
1816 NULL, HFILL }},
1820 /* Setup protocol subtree array */
1821 static int *ett[] = {
1822 &ett_mikey,
1823 &ett_mikey_payload,
1824 &ett_mikey_sp_param,
1825 &ett_mikey_hdr_id,
1826 &ett_mikey_enc_data
1829 /* Register the protocol name and description */
1830 proto_mikey = proto_register_protocol("Multimedia Internet KEYing", "MIKEY", "mikey");
1832 mikey_handle = register_dissector("mikey", dissect_mikey, proto_mikey);
1834 /* Required function calls to register the header fields and subtrees used */
1835 proto_register_field_array(proto_mikey, hf, array_length(hf));
1836 proto_register_subtree_array(ett, array_length(ett));
1840 void
1841 proto_reg_handoff_mikey(void)
1843 dissector_add_string("key_mgmt", "mikey", mikey_handle);
1844 dissector_add_uint_with_preference("tcp.port", PORT_MIKEY, mikey_handle);
1845 dissector_add_uint_with_preference("udp.port", PORT_MIKEY, mikey_handle);
1846 dissector_add_string("media_type", "application/mikey", mikey_handle);
1849 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1851 * Local variables:
1852 * c-basic-offset: 8
1853 * tab-width: 8
1854 * indent-tabs-mode: t
1855 * End:
1857 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1858 * :indentSize=8:tabSize=8:noTabs=false: