2 * Routines for Multimedia Internet KEYing dissection
3 * Copyright 2007, Mikael Magnusson <mikma@users.sourceforge.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 * http://tools.ietf.org/html/rfc3830 MIKEY
28 * http://tools.ietf.org/html/rfc6043 MIKEY-TICKET (ID role required for SAKKE)
29 * http://tools.ietf.org/html/rfc6509 MIKEY-SAKKE
34 * tvbuff offset in 32-bit variable.
36 * Decode Mikey-PK and Mikey-RSA-R with NULL encryption
44 #include <epan/packet.h>
45 #include <epan/wmem/wmem.h>
46 #include <epan/prefs.h>
47 #include <epan/asn1.h>
48 #include <epan/dissectors/packet-x509af.h>
50 #define PORT_MIKEY 2269
51 static guint global_mikey_tcp_port
= PORT_MIKEY
;
53 static guint global_mikey_udp_port
= PORT_MIKEY
;
55 static const value_string on_off_vals
[] = {
62 MIKEY_TYPE_PSK_INIT
= 0,
69 MIKEY_TYPE_DHHMAC_INIT
,
70 MIKEY_TYPE_DHHMAC_RESP
,
71 MIKEY_TYPE_RSA_R_INIT
,
72 MIKEY_TYPE_RSA_R_RESP
,
73 MIKEY_TYPE_SAKKE_INIT
= 26,
77 static const value_string data_type_vals
[] = {
78 { MIKEY_TYPE_PSK_INIT
, "Pre-shared" },
79 { MIKEY_TYPE_PSK_RESP
, "PSK ver msg" },
80 { MIKEY_TYPE_PK_INIT
, "Public key" },
81 { MIKEY_TYPE_PK_RESP
, "PK ver msg" },
82 { MIKEY_TYPE_DH_INIT
, "D-H init" },
83 { MIKEY_TYPE_DH_RESP
, "D-H resp" },
84 { MIKEY_TYPE_ERROR
, "Error" },
85 { MIKEY_TYPE_DHHMAC_INIT
, "DHHMAC init" },
86 { MIKEY_TYPE_DHHMAC_RESP
, "DHHMAC resp" },
87 { MIKEY_TYPE_RSA_R_INIT
, "RSA-R I_MSG" },
88 { MIKEY_TYPE_RSA_R_RESP
, "RSA-R R_MSG" },
89 { MIKEY_TYPE_SAKKE_INIT
, "SAKKE" },
90 { MIKEY_TYPE_SAKKE_RESP
, "CS Id map Update" },
93 static value_string_ext data_type_vals_ext
= VALUE_STRING_EXT_INIT(data_type_vals
);
99 static const value_string cs_id_map_vals
[] = {
100 { CS_ID_SRTP
, "SRTP-ID" },
119 PL_TR
= 13, /* MIKEY-TICKET (6043) */
130 #define PL_HDR_TEXT "Common Header (HDR)"
131 #define PL_LAST_TEXT "Last payload"
132 #define PL_KEMAC_TEXT "Key Data Transport (KEMAC)"
133 #define PL_PKE_TEXT "Envelope Data (PKE)"
134 #define PL_DH_TEXT "DH Data (DH)"
135 #define PL_SIGN_TEXT "Signature (SIGN)"
136 #define PL_T_TEXT "Timestamp (T)"
137 #define PL_ID_TEXT "ID"
138 #define PL_CERT_TEXT "Certificate (CERT)"
139 #define PL_CHASH_TEXT "CHASH"
140 #define PL_V_TEXT "Ver msg (V)"
141 #define PL_SP_TEXT "Security Policy (SP)"
142 #define PL_RAND_TEXT "RAND"
143 #define PL_ERR_TEXT "Error (ERR)"
144 #define PL_KEY_DATA_TEXT "Key data (KEY)"
145 #define PL_IDR_TEXT "IDR"
146 #define PL_GENERAL_EXT_TEXT "General Extension (EXT)"
147 #define PL_SAKKE_TEXT "SAKKE Encapsulated Data (SAKKE)"
149 static const value_string payload_vals
[] = {
150 { PL_HDR
, PL_HDR_TEXT
},
151 { PL_LAST
, PL_LAST_TEXT
},
152 { PL_KEMAC
, PL_KEMAC_TEXT
},
153 { PL_PKE
, PL_PKE_TEXT
},
154 { PL_DH
, PL_DH_TEXT
},
155 { PL_SIGN
, PL_SIGN_TEXT
},
157 { PL_ID
, PL_ID_TEXT
},
158 { PL_CERT
, PL_CERT_TEXT
},
159 { PL_CHASH
, PL_CHASH_TEXT
},
161 { PL_SP
, PL_SP_TEXT
},
162 { PL_RAND
, PL_RAND_TEXT
},
163 { PL_ERR
, PL_ERR_TEXT
},
164 { PL_IDR
, PL_IDR_TEXT
},
165 { PL_KEY_DATA
, PL_KEY_DATA_TEXT
},
166 { PL_GENERAL_EXT
, PL_GENERAL_EXT_TEXT
},
167 { PL_SAKKE
, PL_SAKKE_TEXT
},
170 #if 0 /* First entry (PL_HDR) is -1 and there are gaps so this doesn't work */
171 static value_string_ext payload_vals_ext
= VALUE_STRING_EXT_INIT(payload_vals
);
180 static const value_string ts_type_vals
[] = {
181 { T_NTP_UTC
, "NTP-UTC" },
183 { T_COUNTER
, "COUNTER" },
193 static const value_string encr_alg_vals
[] = {
194 { ENCR_NULL
, "NULL" },
195 { ENCR_AES_CM_128
, "AES-CM-128" },
196 { ENCR_AES_KW_128
, "AES-KW-128" },
206 static const value_string oakley_vals
[] = {
207 { DH_OAKLEY_5
, "OAKLEY 5" },
208 { DH_OAKLEY_1
, "OAKLEY 1" },
209 { DH_OAKLEY_2
, "OAKLEY 2" },
218 static const value_string mac_alg_vals
[] = {
219 { MAC_NULL
, "NULL" },
220 { MAC_HMAC_SHA_1_160
, "HMAC-SHA-1-160" },
230 static const value_string pke_c_vals
[] = {
231 { PKE_C_NO_CACHE
, "No cache" },
232 { PKE_C_CACHE
, "Cache" },
233 { PKE_C_CACHE_CSB
, "Cache for CSB" },
243 static const value_string sign_s_vals
[] = {
244 { SIGN_S_PKCS1
, "RSA/PKCS#1/1.5" },
245 { SIGN_S_PSS
, "RSA/PSS" },
246 { SIGN_S_ECCSI
, "ECCSI" },
256 static const value_string id_type_vals
[] = {
257 { ID_TYPE_NAI
, "NAI" },
258 { ID_TYPE_URI
, "URI" },
259 { ID_TYPE_BYTE_STRING
, "Byte string" },
264 ID_ROLE_RESERVED
= 0,
274 static const value_string id_role_vals
[] = {
275 { ID_ROLE_RESERVED
, "Reserved" },
276 { ID_ROLE_INIT
, "Initiator (IDRi)" },
277 { ID_ROLE_RESP
, "Responder (IDRr)" },
278 { ID_ROLE_KMS
, "KMS (IDRkms)" },
279 { ID_ROLE_PSK
, "Pre-Shared Key (IDRpsk)" },
280 { ID_ROLE_APP
, "Application (IDRapp)" },
281 { ID_ROLE_INIT_KMS
, "Initiator's KMS (IDRkmsi)" },
282 { ID_ROLE_RESP_KMS
, "Responder's KMS (IDRkmsr)" },
287 CERT_TYPE_X509V3
= 0,
288 CERT_TYPE_X509V3_URL
,
289 CERT_TYPE_X509V3_SIGN
,
290 CERT_TYPE_X509V3_ENCR
293 static const value_string cert_type_vals
[] = {
294 { CERT_TYPE_X509V3
, "X.509v3" },
295 { CERT_TYPE_X509V3_URL
, "X.509v3 URL" },
296 { CERT_TYPE_X509V3_SIGN
, "X.509v3 Sign" },
297 { CERT_TYPE_X509V3_ENCR
, "X.509v3 Encr" },
301 enum srtp_policy_type_t
{
318 #define SP_TEXT_ENCR_ALG "Encryption algorithm"
319 #define SP_TEXT_ENCR_LEN "Session Encr. key length"
320 #define SP_TEXT_AUTH_ALG "Authentication algorithm"
321 #define SP_TEXT_AUTH_KEY_LEN "Session Auth. key length"
322 #define SP_TEXT_SALT_LEN "Session Salt key length"
323 #define SP_TEXT_PRF "SRTP Pseudo Random Function"
324 #define SP_TEXT_KD_RATE "Key derivation rate"
325 #define SP_TEXT_SRTP_ENCR "SRTP encryption"
326 #define SP_TEXT_SRTCP_ENCR "SRTCP encryption"
327 #define SP_TEXT_FEC "Sender's FEC order"
328 #define SP_TEXT_SRTP_AUTH "SRTP authentication"
329 #define SP_TEXT_AUTH_TAG_LEN "Authentication tag length"
330 #define SP_TEXT_SRTP_PREFIX "SRTP prefix length"
333 static const value_string srtp_policy_type_vals
[] = {
334 { SP_ENCR_ALG
, SP_TEXT_ENCR_ALG
},
335 { SP_ENCR_LEN
, SP_TEXT_ENCR_LEN
},
336 { SP_AUTH_ALG
, SP_TEXT_AUTH_ALG
},
337 { SP_AUTH_KEY_LEN
, SP_TEXT_AUTH_KEY_LEN
},
338 { SP_SALT_LEN
, SP_TEXT_SALT_LEN
},
339 { SP_PRF
, SP_TEXT_PRF
},
340 { SP_KD_RATE
, SP_TEXT_KD_RATE
},
341 { SP_SRTP_ENCR
, SP_TEXT_SRTP_ENCR
},
342 { SP_SRTCP_ENCR
, SP_TEXT_SRTCP_ENCR
},
343 { SP_FEC
, SP_TEXT_FEC
},
344 { SP_SRTP_AUTH
, SP_TEXT_SRTP_AUTH
},
345 { SP_AUTH_TAG_LEN
, SP_TEXT_AUTH_TAG_LEN
},
346 { SP_SRTP_PREFIX
, SP_TEXT_SRTP_PREFIX
},
357 static const value_string sp_encr_alg_vals
[] = {
358 { SP_ENCR_NULL
, "NULL" },
359 { SP_ENCR_AES_CM
, "AES-CM" },
360 { SP_ENCR_AES_F8
, "AES-F8" },
369 static const value_string sp_auth_alg_vals
[] = {
370 { SP_AUTH_NULL
, "NULL" },
371 { SP_AUTH_HMAC_SHA_1
, "HMAC-SHA-1" },
379 static const value_string sp_prf_vals
[] = {
380 { SP_PRF_AES_CM
, "AES-CM" },
388 static const value_string sp_fec_vals
[] = {
389 { SP_FEC_SRTP
, "FEC-SRTP" },
394 SP_PROT_TYPE_SRTP
= 0
397 static const value_string sp_prot_type_vals
[] = {
398 { SP_PROT_TYPE_SRTP
, "SRTP" },
406 static const value_string prf_func_vals
[] = {
407 { PRF_FUNC_MIKEY_1
, "MIKEY-1" },
417 static const value_string kv_vals
[] = {
419 { KV_SPI
, "SPI/MKI" },
420 { KV_INTERVAL
, "Interval" },
431 static const value_string kd_vals
[] = {
433 { KD_TGK_SALT
, "TGK+SALT" },
435 { KD_TEK_SALT
, "TEK+SALT" },
440 ERR_AUTH_FAILURE
= 0,
455 static const value_string err_vals
[] = {
456 { ERR_AUTH_FAILURE
, "Authentication failure" },
457 { ERR_INVALID_TS
, "Invalid timestamp" },
458 { ERR_INVALID_PRF
, "PRF function not supported" },
459 { ERR_INVALID_MAC
, "MAC algorithm not supported" },
460 { ERR_INVALID_EA
, "Encryption algorithm not supported" },
461 { ERR_INVALID_HA
, "Hash function not supported" },
462 { ERR_INVALID_DH
, "DH group not supported" },
463 { ERR_INVALID_ID
, "ID not supported" },
464 { ERR_INVALID_CERT
, "Certificate not supported" },
465 { ERR_INVALID_SP
, "SP type not supported" },
466 { ERR_INVALID_SPPAR
, "SP parameters not supported" },
467 { ERR_INVALID_DT
, "Data type not supported" },
468 { ERR_UNKNOWN
, "Unspecified error" },
471 static value_string_ext err_vals_ext
= VALUE_STRING_EXT_INIT(err_vals
);
474 GEN_EXT_VENDOR_ID
= 0,
478 static const value_string genext_type_vals
[] = {
479 { GEN_EXT_VENDOR_ID
, "Vendor-ID" },
480 { GEN_EXT_SDP_ID
, "SDP-IDs" },
492 POS_HDR_CS_ID_MAP_TYPE
,
500 POS_KEMAC_ENCR_DATA_LEN
,
550 POS_SP_PARAM_F_VALUE
,
575 POS_GENERAL_EXT_TYPE
,
577 POS_GENERAL_EXT_DATA
,
578 POS_GENERAL_EXT_VALUE
,
596 typedef struct tag_mikey_t
{
600 typedef int (*mikey_dissector_t
)(mikey_t
*, tvbuff_t
*, packet_info
*, proto_tree
*);
601 struct mikey_dissector_entry
{
603 mikey_dissector_t dissector
;
606 /* Forward declaration we need below */
607 void proto_reg_handoff_mikey(void);
608 static int dissect_payload(int payload
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
611 /* Initialize the protocol and registered fields */
612 static int proto_mikey
= -1;
613 static int hf_mikey
[MAX_POS
+1];
614 static int hf_mikey_sp_param
[SP_MAX
+1];
615 static int hf_mikey_pl
[PL_MAX
];
617 /* Initialize the subtree pointers */
618 static gint ett_mikey
= -1;
619 static gint ett_mikey_payload
= -1;
620 static gint ett_mikey_sp_param
= -1;
621 static gint ett_mikey_hdr_id
= -1;
622 static gint ett_mikey_enc_data
= -1;
624 static dissector_handle_t mikey_handle
;
626 static const struct mikey_dissector_entry
*
627 mikey_dissector_lookup(const struct mikey_dissector_entry
*map
, int type
)
630 for (i
= 0; map
[i
].dissector
!= NULL
; i
++) {
631 if (map
[i
].type
== type
) {
640 add_next_payload(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
642 proto_tree_add_item(tree
, hf_mikey
[POS_NEXT_PAYLOAD
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
647 dissect_payload_cs_id_srtp(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
649 tvb_ensure_bytes_exist(tvb
, 0, 9);
658 no
= tvb_get_guint8(tvb
, 0);
659 ssrc
= tvb_get_ntohl(tvb
, 1);
660 roc
= tvb_get_ntohl(tvb
, 5);
662 id_ti
= proto_tree_add_none_format(tree
, hf_mikey
[POS_ID_SRTP
], tvb
, 0, 9,
663 "SRTP ID: Policy: %d, SSRC: 0x%x, ROC: 0x%x", no
, ssrc
, roc
);
664 id_tree
= proto_item_add_subtree(id_ti
, ett_mikey_hdr_id
);
666 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_NO
], tvb
, 0, 1, ENC_BIG_ENDIAN
);
667 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_SSRC
], tvb
, 1, 4, ENC_BIG_ENDIAN
);
668 proto_tree_add_item(id_tree
, hf_mikey
[POS_ID_SRTP_ROC
], tvb
, 5, 4, ENC_BIG_ENDIAN
);
673 static const struct mikey_dissector_entry cs_id_map
[] = {
674 { CS_ID_SRTP
, dissect_payload_cs_id_srtp
},
679 dissect_payload_cs_id(int type
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
681 const struct mikey_dissector_entry
*entry
;
683 entry
= mikey_dissector_lookup(cs_id_map
, type
);
685 if (!entry
|| !entry
->dissector
) {
689 return entry
->dissector(mikey
, tvb
, pinfo
, tree
);
694 dissect_payload_hdr(mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
697 guint8 cs_id_map_type
;
701 tvb_ensure_bytes_exist(tvb
, offset
, 10);
702 mikey
->type
= tvb_get_guint8(tvb
, offset
+1);
703 ncs
= tvb_get_guint8(tvb
, offset
+8);
704 cs_id_map_type
= tvb_get_guint8(tvb
, offset
+9);
708 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_VERSION
],
709 tvb
, offset
+0, 1, ENC_BIG_ENDIAN
);
711 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_DATA_TYPE
], tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
712 parent
= proto_tree_get_parent(tree
);
713 proto_item_append_text(parent
, " Type: %s",
714 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
716 add_next_payload(tvb
, tree
, offset
+2);
718 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_V
], tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
719 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_PRF_FUNC
], tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
721 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CSB_ID
], tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
723 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CS_COUNT
], tvb
, offset
+8, 1, ENC_BIG_ENDIAN
);
724 proto_tree_add_item(tree
, hf_mikey
[POS_HDR_CS_ID_MAP_TYPE
], tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
728 for (i
=0; i
< ncs
; i
++) {
732 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
733 len
= dissect_payload_cs_id(cs_id_map_type
, mikey
, sub_tvb
, pinfo
, tree
);
745 dissect_payload_kemac(mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
753 tvb_ensure_bytes_exist(tvb
, offset
+0, 4);
754 encr_alg
= tvb_get_guint8(tvb
, offset
+1);
755 encr_length
= tvb_get_ntohs(tvb
, offset
+2);
756 tvb_ensure_bytes_exist(tvb
, offset
+4, encr_length
+1);
757 mac_alg
= tvb_get_guint8(tvb
, offset
+4+encr_length
);
761 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_ALG
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
762 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_DATA_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
763 /* TODO: Add key decode for MIKEY_TYPE_PK_INIT and MIKEY_TYPE_RSA_R_RESP with NULL encryption */
764 if ((encr_alg
== ENCR_NULL
) && (mikey
->type
== MIKEY_TYPE_PSK_INIT
) && (encr_length
> 0)) {
765 proto_item
*key_data_item
;
766 proto_tree
*key_data_tree
;
767 /* We can decode easily the Key Data if NULL encryption is used */
768 key_data_item
= proto_tree_add_item(tree
, hf_mikey_pl
[PL_KEY_DATA
], tvb
, 4, encr_length
, ENC_NA
);
769 key_data_tree
= proto_item_add_subtree(key_data_item
, ett_mikey_enc_data
);
771 sub_tvb
= tvb_new_subset(tvb
, offset
+4, encr_length
, encr_length
);
772 dissect_payload(PL_KEY_DATA
, mikey
, sub_tvb
, pinfo
, key_data_tree
);
774 /* If Key Data is encrypted, show only the encr_data */
775 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_ENCR_DATA
], tvb
, 4, encr_length
, ENC_NA
);
777 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_MAC_ALG
], tvb
, 4+encr_length
, 1, ENC_BIG_ENDIAN
);
784 case MAC_HMAC_SHA_1_160
:
791 tvb_ensure_bytes_exist(tvb
, offset
+4+encr_length
+1, mac_length
);
793 proto_tree_add_item(tree
, hf_mikey
[POS_KEMAC_MAC
], tvb
, 4+encr_length
+1, mac_length
, ENC_NA
);
796 return 4+encr_length
+1+mac_length
;
800 dissect_payload_pke(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
805 tvb_ensure_bytes_exist(tvb
, offset
+0, 3);
806 length
= tvb_get_ntohs(tvb
, offset
+1) &0x3ff;
809 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_C
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
811 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_DATA_LEN
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
814 tvb_ensure_bytes_exist(tvb
, offset
+3, length
);
816 proto_tree_add_item(tree
, hf_mikey
[POS_PKE_DATA
], tvb
, 3, length
, ENC_NA
);
822 dissect_payload_dh(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
829 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
830 dh_group
= tvb_get_guint8(tvb
, offset
+1);
846 tvb_ensure_bytes_exist(tvb
, offset
+2, dh_length
+1);
847 kv
= tvb_get_guint8(tvb
, offset
+2+dh_length
) & 0x0f;
850 proto_tree_add_item(tree
, hf_mikey
[POS_DH_GROUP
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
851 proto_tree_add_item(tree
, hf_mikey
[POS_DH_VALUE
], tvb
, 2, dh_length
, ENC_NA
);
852 proto_tree_add_item(tree
, hf_mikey
[POS_DH_RESERV
], tvb
, 2+dh_length
, 1, ENC_BIG_ENDIAN
);
853 proto_tree_add_item(tree
, hf_mikey
[POS_DH_KV
], tvb
, 2+dh_length
, 1, ENC_BIG_ENDIAN
);
860 return 2 + dh_length
+ 1;
864 dissect_payload_sign(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
869 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
870 length
= ((tvb_get_guint8(tvb
, offset
+0) & 0x0f) << 8) + tvb_get_guint8(tvb
, offset
+1);
873 proto_tree_add_item(tree
, hf_mikey
[POS_SIGN_S_TYPE
], tvb
, 0, 2, ENC_BIG_ENDIAN
);
874 proto_tree_add_uint(tree
, hf_mikey
[POS_SIGNATURE_LEN
], tvb
, 0, 2, length
);
877 tvb_ensure_bytes_exist(tvb
, offset
+2, length
);
879 proto_tree_add_item(tree
, hf_mikey
[POS_SIGNATURE
], tvb
, 2, length
, ENC_NA
);
885 dissect_payload_t(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
891 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
892 ts_type
= tvb_get_guint8(tvb
, offset
+1);
896 parent
= proto_tree_get_parent(tree
);
897 proto_item_append_text(parent
, " Type: %s", val_to_str_const(ts_type
, ts_type_vals
, "Unknown"));
898 proto_tree_add_item(tree
, hf_mikey
[POS_TS_TYPE
], tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
904 proto_tree_add_item(tree
, hf_mikey
[POS_TS_NTP
], tvb
, offset
+2, 8, ENC_TIME_NTP
|ENC_BIG_ENDIAN
);
919 dissect_payload_id(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
925 tvb_ensure_bytes_exist(tvb
, offset
+0, 4);
926 type
= tvb_get_guint8(tvb
, offset
+1);
927 length
= tvb_get_ntohs(tvb
, offset
+2);
929 proto_tree_add_item(tree
, hf_mikey
[POS_ID_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
930 proto_tree_add_item(tree
, hf_mikey
[POS_ID_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
933 tvb_ensure_bytes_exist(tvb
, offset
+4, length
);
936 proto_tree_add_item(tree
, hf_mikey
[POS_ID
], tvb
, 4, length
, ENC_ASCII
|ENC_NA
);
938 parent
= proto_tree_get_parent(tree
);
939 proto_item_append_text(parent
, " %s: %s",
940 val_to_str_const(type
, id_type_vals
, "Unknown"),
941 tvb_get_string(wmem_packet_scope(), tvb
, 4, length
));
948 dissect_payload_idr(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
954 tvb_ensure_bytes_exist(tvb
, offset
+0, 5);
955 type
= tvb_get_guint8(tvb
, offset
+2);
956 length
= tvb_get_ntohs(tvb
, offset
+3);
958 proto_tree_add_item(tree
, hf_mikey
[POS_ID_ROLE
], tvb
, 1, 1, ENC_NA
);
959 proto_tree_add_item(tree
, hf_mikey
[POS_ID_TYPE
], tvb
, 2, 1, ENC_NA
);
960 proto_tree_add_item(tree
, hf_mikey
[POS_ID_LEN
], tvb
, 3, 2, ENC_NA
);
963 tvb_ensure_bytes_exist(tvb
, offset
+5, length
);
966 proto_tree_add_item(tree
, hf_mikey
[POS_ID
], tvb
, 5, length
, ENC_ASCII
|ENC_NA
);
968 parent
= proto_tree_get_parent(tree
);
969 proto_item_append_text(parent
, " %s: %s",
970 val_to_str_const(type
, id_type_vals
, "Unknown"),
971 tvb_get_string(wmem_packet_scope(), tvb
, 5, length
));
978 dissect_payload_cert(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
986 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, TRUE
, pinfo
);
988 tvb_ensure_bytes_exist(tvb
, offset
+0, 4);
989 type
= tvb_get_guint8(tvb
, offset
+1);
990 length
= tvb_get_ntohs(tvb
, offset
+2);
992 tvb_ensure_bytes_exist(tvb
, offset
+4, length
);
996 parent
= proto_tree_get_parent(tree
);
997 proto_tree_add_item(tree
, hf_mikey
[POS_CERT_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
998 proto_tree_add_item(tree
, hf_mikey
[POS_CERT_LEN
], tvb
, 1, 2, ENC_BIG_ENDIAN
);
1000 proto_item_append_text(parent
, " Type: %s", val_to_str_const(type
, cert_type_vals
, "Unknown"));
1003 subtvb
= tvb_new_subset(tvb
, offset
+4, length
, length
);
1004 dissect_x509af_Certificate(FALSE
, subtvb
, 0, &asn1_ctx
, tree
, hf_mikey
[POS_CERTIFICATE
]);
1010 dissect_payload_v(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1016 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
1017 alg
= tvb_get_guint8(tvb
, offset
+1);
1020 proto_tree_add_item(tree
, hf_mikey
[POS_V_AUTH_ALG
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1027 case MAC_HMAC_SHA_1_160
:
1034 tvb_ensure_bytes_exist(tvb
, offset
+2, length
);
1036 proto_tree_add_item(tree
, hf_mikey
[POS_V_DATA
], tvb
, 2, length
, ENC_NA
);
1043 dissect_payload_sp_param(enum sp_prot_t proto
, tvbuff_t
*tvb
, proto_tree
*tree
)
1050 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
1051 type
= tvb_get_guint8(tvb
, offset
+0);
1052 length
= tvb_get_guint8(tvb
, offset
+1);
1053 tvb_ensure_bytes_exist(tvb
, offset
+2, length
);
1056 hfindex
= hf_mikey
[POS_SP_PARAM_F
];
1059 case SP_PROT_TYPE_SRTP
:
1060 if (type
< array_length(hf_mikey_sp_param
))
1061 hfindex
= hf_mikey_sp_param
[type
];
1066 proto_item
*param_ti
;
1067 proto_tree
*param_tree
;
1069 * All the parameters in question are either FT_BYTES,
1070 * in which case the byte order is inapplicable, or
1071 * FT_UINT8, in which case it could be given as
1072 * FT_BIG_ENDIAN as per bigger FT_UINT values, but
1073 * ENC_NA also works, as there's only one byte.
1075 param_ti
= proto_tree_add_item(tree
, hfindex
, tvb
, 2, length
, ENC_NA
);
1076 param_tree
= proto_item_add_subtree(param_ti
, ett_mikey_sp_param
);
1078 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_TYPE
], tvb
, 0, 1, ENC_BIG_ENDIAN
);
1079 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_LEN
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1080 proto_tree_add_item(param_tree
, hf_mikey
[POS_SP_PARAM_F_VALUE
], tvb
, 2, length
, ENC_NA
);
1087 dissect_payload_sp(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1093 enum sp_prot_t type
;
1095 tvb_ensure_bytes_exist(tvb
, offset
+0, 5);
1096 length
= tvb_get_ntohs(tvb
, offset
+3);
1097 no
= tvb_get_guint8(tvb
, offset
+1);
1098 type
= (enum sp_prot_t
)tvb_get_guint8(tvb
, offset
+2);
1102 parent
= proto_tree_get_parent(tree
);
1103 proto_tree_add_item(tree
, hf_mikey
[POS_SP_NO
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1104 proto_tree_add_item(tree
, hf_mikey
[POS_SP_TYPE
], tvb
, 2, 1, ENC_BIG_ENDIAN
);
1105 proto_tree_add_item(tree
, hf_mikey
[POS_SP_PARAM_LEN
], tvb
, 3, 2, ENC_BIG_ENDIAN
);
1107 proto_item_append_text(parent
, " No: %d, Type: %s", no
,
1108 val_to_str_const(type
, sp_prot_type_vals
, "Unknown"));
1111 tvb_ensure_bytes_exist(tvb
, offset
+5, length
);
1112 /* proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM], tvb, 5, length, ENC_NA); */
1117 while (sub_pos
< length
) {
1121 subtvb
= tvb_new_subset(tvb
, offset
+sub_pos
, length
-sub_pos
, length
-sub_pos
);
1122 param_len
= dissect_payload_sp_param(type
, subtvb
, tree
);
1127 sub_pos
+= param_len
;
1134 dissect_payload_rand(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1139 tvb_ensure_bytes_exist(tvb
, offset
+0, 2);
1140 length
= tvb_get_guint8(tvb
, offset
+1);
1143 proto_tree_add_item(tree
, hf_mikey
[POS_RAND_LEN
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1146 tvb_ensure_bytes_exist(tvb
, offset
+2, length
);
1149 proto_tree_add_item(tree
, hf_mikey
[POS_RAND
], tvb
, 2, length
, ENC_NA
);
1155 dissect_payload_err(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1157 tvb_ensure_bytes_exist(tvb
, 0, 4);
1162 err_no
= tvb_get_guint8(tvb
, 1);
1163 proto_tree_add_item(tree
, hf_mikey
[POS_ERR_NO
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1164 proto_tree_add_item(tree
, hf_mikey
[POS_ERR_RESERVED
], tvb
, 2, 2, ENC_NA
);
1165 parent
= proto_tree_get_parent(tree
);
1166 proto_item_append_text(parent
, ": %s", val_to_str_ext_const(err_no
, &err_vals_ext
, "Unknown"));
1173 dissect_payload_keydata(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1181 tvb_ensure_bytes_exist(tvb
, 0, 4);
1182 key_type
= tvb_get_guint8(tvb
, 1) >> 4;
1183 kv_type
= tvb_get_guint8(tvb
, 1) & 0x0f;
1184 data_len
= tvb_get_ntohs(tvb
, 2);
1186 tvb_ensure_bytes_exist(tvb
, 4, data_len
);
1191 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1192 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_KV
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1193 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
1194 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_DATA
], tvb
, 4, data_len
, ENC_NA
);
1196 parent
= proto_tree_get_parent(tree
);
1197 proto_item_append_text(parent
, " Type: %s", val_to_str_const(key_type
, kd_vals
, "Unknown"));
1202 /* Dissect SALT key */
1203 if ((key_type
== KD_TGK_SALT
) || (key_type
== KD_TEK_SALT
)) {
1205 tvb_ensure_bytes_exist(tvb
, offset
, 2);
1206 salt_len
= tvb_get_ntohs(tvb
, offset
);
1208 tvb_ensure_bytes_exist(tvb
, offset
+2, salt_len
);
1210 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_SALT_LEN
], tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1211 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_SALT
], tvb
, offset
+2, salt_len
, ENC_NA
);
1214 offset
+= 2+salt_len
;
1217 /* Dissect Key Validity */
1218 if (kv_type
== KV_INTERVAL
) {
1219 guint16 kv_from_len
;
1222 tvb_ensure_bytes_exist(tvb
, offset
, 1);
1223 kv_from_len
= tvb_get_guint8(tvb
, offset
);
1224 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_FROM_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1225 if (kv_from_len
> 0) {
1226 tvb_ensure_bytes_exist(tvb
, offset
+1, kv_from_len
);
1227 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_FROM
], tvb
, offset
+1, kv_from_len
, ENC_NA
);
1229 offset
+= 1+kv_from_len
;
1231 tvb_ensure_bytes_exist(tvb
, offset
, 1);
1232 kv_to_len
= tvb_get_guint8(tvb
, offset
);
1233 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_TO_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1234 if (kv_to_len
> 0) {
1235 tvb_ensure_bytes_exist(tvb
, offset
+1, kv_to_len
);
1236 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_TO
], tvb
, offset
+1, kv_to_len
, ENC_NA
);
1238 offset
+= 1+kv_to_len
;
1239 } else if (kv_type
== KV_SPI
) {
1242 tvb_ensure_bytes_exist(tvb
, offset
, 1);
1243 kv_spi_len
= tvb_get_guint8(tvb
, offset
);
1244 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_SPI_LEN
], tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1245 if (kv_spi_len
> 0) {
1246 tvb_ensure_bytes_exist(tvb
, offset
+1, kv_spi_len
);
1247 proto_tree_add_item(tree
, hf_mikey
[POS_KEY_KV_SPI
], tvb
, offset
+1, kv_spi_len
, ENC_NA
);
1249 offset
+= 1+kv_spi_len
;
1256 dissect_payload_general_ext(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1262 tvb_ensure_bytes_exist(tvb
, offset
+0, 4);
1263 type
= tvb_get_guint8(tvb
, offset
+1);
1264 data_len
= tvb_get_ntohs(tvb
, offset
+2);
1267 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_TYPE
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1268 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_LEN
], tvb
, 2, 2, ENC_BIG_ENDIAN
);
1271 tvb_ensure_bytes_exist(tvb
, offset
+3, data_len
);
1276 parent
= proto_tree_get_parent(tree
);
1278 /* For SDP-IDs, show a string instead of raw bytes */
1279 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_VALUE
], tvb
, 4, data_len
, ENC_ASCII
|ENC_NA
);
1281 proto_tree_add_item(tree
, hf_mikey
[POS_GENERAL_EXT_DATA
], tvb
, 4, data_len
, ENC_NA
);
1283 proto_item_append_text(parent
, " Type: %s", val_to_str_const(type
, genext_type_vals
, "Unknown"));
1285 return 4 + data_len
;
1289 dissect_payload_sakke(mikey_t
*mikey _U_
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1294 tvb_ensure_bytes_exist(tvb
, offset
+0, 5);
1295 data_len
= tvb_get_ntohs(tvb
, offset
+3);
1298 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_PARAMS
], tvb
, 1, 1, ENC_BIG_ENDIAN
);
1299 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_ID_SCHEME
], tvb
, 2, 1, ENC_BIG_ENDIAN
);
1300 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_LEN
], tvb
, 3, 2, ENC_BIG_ENDIAN
);
1303 tvb_ensure_bytes_exist(tvb
, offset
+5, data_len
);
1306 proto_tree_add_item(tree
, hf_mikey
[POS_SAKKE_DATA
], tvb
, 5, data_len
, ENC_NA
);
1308 return 5 + data_len
;
1311 static const struct mikey_dissector_entry payload_map
[] = {
1312 { PL_HDR
, dissect_payload_hdr
},
1313 { PL_KEMAC
, dissect_payload_kemac
},
1314 { PL_PKE
, dissect_payload_pke
},
1315 { PL_DH
, dissect_payload_dh
},
1316 { PL_SIGN
, dissect_payload_sign
},
1317 { PL_T
, dissect_payload_t
},
1318 { PL_ID
, dissect_payload_id
},
1319 { PL_CERT
, dissect_payload_cert
},
1320 { PL_V
, dissect_payload_v
},
1321 { PL_SP
, dissect_payload_sp
},
1322 { PL_RAND
, dissect_payload_rand
},
1323 { PL_ERR
, dissect_payload_err
},
1324 { PL_IDR
, dissect_payload_idr
},
1325 { PL_KEY_DATA
, dissect_payload_keydata
},
1326 { PL_GENERAL_EXT
, dissect_payload_general_ext
},
1327 { PL_SAKKE
, dissect_payload_sakke
},
1332 dissect_payload(int payload
, mikey_t
*mikey
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1334 const struct mikey_dissector_entry
*entry
;
1336 entry
= mikey_dissector_lookup(payload_map
, payload
);
1338 if (!entry
|| !entry
->dissector
) {
1342 return entry
->dissector(mikey
, tvb
, pinfo
, tree
);
1345 /* MIKEY dissector */
1347 dissect_mikey(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1349 proto_item
*ti
= NULL
;
1350 proto_tree
*mikey_tree
= NULL
;
1352 int next_payload_offset
;
1356 mikey
= (mikey_t
*)p_get_proto_data(pinfo
->fd
, proto_mikey
, 0);
1359 mikey
= wmem_new0(wmem_file_scope(), mikey_t
);
1361 p_add_proto_data(pinfo
->fd
, proto_mikey
, 0, mikey
);
1365 tvb_ensure_bytes_exist(tvb
, offset
, 3);
1366 next_payload_offset
= offset
+ 2;
1370 ti
= proto_tree_add_item(tree
, proto_mikey
, tvb
, 0, -1, ENC_NA
);
1371 mikey_tree
= proto_item_add_subtree(ti
, ett_mikey
);
1374 while (payload
!= 0) {
1376 proto_item
*sub_ti
= NULL
;
1377 proto_tree
*mikey_payload_tree
= NULL
;
1381 next_payload
= tvb_get_guint8(tvb
, next_payload_offset
);
1382 subtvb
= tvb_new_subset_remaining(tvb
, offset
);
1393 sub_ti
= proto_tree_add_item(mikey_tree
, hf_mikey_pl
[hf
], subtvb
, 0, -1, ENC_NA
);
1395 mikey_payload_tree
= proto_item_add_subtree(sub_ti
, ett_mikey_payload
);
1396 if ((payload
!= PL_HDR
) && (payload
!= PL_SIGN
))
1397 add_next_payload(tvb
, mikey_payload_tree
, next_payload_offset
);
1400 len
= dissect_payload(payload
, mikey
, subtvb
, pinfo
, mikey_payload_tree
);
1406 proto_item_set_len(sub_ti
, len
);
1408 if (payload
== PL_SIGN
)
1411 payload
= next_payload
;
1413 next_payload_offset
= offset
;
1417 proto_item_append_text(ti
, ": %s",
1418 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
1421 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, "/MIKEY");
1423 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Mikey: %s",
1424 val_to_str_ext_const(mikey
->type
, &data_type_vals_ext
, "Unknown"));
1426 /* Return the amount of data this dissector was able to dissect */
1427 return tvb_length(tvb
);
1431 /* Register the protocol with Wireshark */
1434 proto_register_mikey(void)
1437 /* Setup list of header fields */
1438 static hf_register_info hf
[] = {
1440 { &hf_mikey_pl
[PL_HDR
+1],
1441 { PL_HDR_TEXT
, "mikey.hdr",
1442 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1444 { &hf_mikey_pl
[PL_KEMAC
],
1445 { PL_KEMAC_TEXT
, "mikey.kemac",
1446 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1448 { &hf_mikey_pl
[PL_PKE
],
1449 { PL_PKE_TEXT
, "mikey.",
1450 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1452 { &hf_mikey_pl
[PL_DH
],
1453 { PL_DH_TEXT
, "mikey.dh",
1454 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1456 { &hf_mikey_pl
[PL_SIGN
],
1457 { PL_SIGN_TEXT
, "mikey.sign",
1458 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1460 { &hf_mikey_pl
[PL_T
],
1461 { PL_T_TEXT
, "mikey.t",
1462 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1464 { &hf_mikey_pl
[PL_ID
],
1465 { PL_ID_TEXT
, "mikey.id",
1466 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1468 { &hf_mikey_pl
[PL_CERT
],
1469 { PL_CERT_TEXT
, "mikey.cert",
1470 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1472 { &hf_mikey_pl
[PL_CHASH
],
1473 { PL_CHASH_TEXT
, "mikey.chash",
1474 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1476 { &hf_mikey_pl
[PL_V
],
1477 { PL_V_TEXT
, "mikey.v",
1478 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1480 { &hf_mikey_pl
[PL_SP
],
1481 { PL_SP_TEXT
, "mikey.sp",
1482 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1484 { &hf_mikey_pl
[PL_RAND
],
1485 { PL_RAND_TEXT
, "mikey.rand",
1486 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1488 { &hf_mikey_pl
[PL_ERR
],
1489 { PL_ERR_TEXT
, "mikey.err",
1490 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1492 { &hf_mikey_pl
[PL_IDR
],
1493 { PL_IDR_TEXT
, "mikey.idr",
1494 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1496 { &hf_mikey_pl
[PL_KEY_DATA
],
1497 { PL_KEY_DATA_TEXT
, "mikey.key",
1498 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1500 { &hf_mikey_pl
[PL_GENERAL_EXT
],
1501 { PL_GENERAL_EXT_TEXT
, "mikey.ext",
1502 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1504 { &hf_mikey_pl
[PL_SAKKE
],
1505 { PL_SAKKE_TEXT
, "mikey.sakke",
1506 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1509 /* Common Header payload (HDR) */
1510 { &hf_mikey
[POS_HDR_VERSION
],
1511 { "Version", "mikey.version",
1512 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1514 { &hf_mikey
[POS_HDR_DATA_TYPE
],
1515 { "Data Type", "mikey.type",
1516 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &data_type_vals_ext
, 0x0,
1518 { &hf_mikey
[POS_NEXT_PAYLOAD
],
1519 { "Next Payload", "mikey.next_payload",
1520 FT_UINT8
, BASE_DEC
, VALS(payload_vals
), 0x0,
1522 { &hf_mikey
[POS_HDR_V
],
1524 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), 0x80,
1526 { &hf_mikey
[POS_HDR_PRF_FUNC
],
1527 { "PRF func", "mikey.prf_func",
1528 FT_UINT8
, BASE_DEC
, VALS(prf_func_vals
), 0x7f,
1530 { &hf_mikey
[POS_HDR_CSB_ID
],
1531 { "CSB ID", "mikey.csb_id",
1532 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1534 { &hf_mikey
[POS_HDR_CS_COUNT
],
1535 { "#CS", "mikey.cs_count",
1536 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1538 { &hf_mikey
[POS_HDR_CS_ID_MAP_TYPE
],
1539 { "CS ID map type", "mikey.cs_id_map_type",
1540 FT_UINT8
, BASE_DEC
, VALS(cs_id_map_vals
), 0x0,
1544 { &hf_mikey
[POS_ID_SRTP
],
1545 { "SRTP ID", "mikey.srtp_id",
1546 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1548 { &hf_mikey
[POS_ID_SRTP_NO
],
1549 { "Policy No", "mikey.srtp_id.policy_no",
1550 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1552 { &hf_mikey
[POS_ID_SRTP_SSRC
],
1553 { "SSRC", "mikey.srtp_id.ssrc",
1554 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1556 { &hf_mikey
[POS_ID_SRTP_ROC
],
1557 { "ROC", "mikey.srtp_id.roc",
1558 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1561 /* Key Data Transport payload (KEMAC) */
1562 { &hf_mikey
[POS_KEMAC_ENCR_ALG
],
1563 { "Encr alg", "mikey.kemac.encr_alg",
1564 FT_UINT8
, BASE_DEC
, VALS(encr_alg_vals
), 0x0,
1566 { &hf_mikey
[POS_KEMAC_ENCR_DATA_LEN
],
1567 { "Key data len", "mikey.kemac.key_data_len",
1568 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1570 { &hf_mikey
[POS_KEMAC_ENCR_DATA
],
1571 { "Key data", "mikey.kemac.key_data",
1572 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1574 { &hf_mikey
[POS_KEMAC_MAC_ALG
],
1575 { "Mac alg", "mikey.kemac.mac_alg",
1576 FT_UINT8
, BASE_DEC
, VALS(mac_alg_vals
), 0x0,
1578 { &hf_mikey
[POS_KEMAC_MAC
],
1579 { "MAC", "mikey.kemac.mac",
1580 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1583 /* Envelope Data payload (PKE) */
1584 { &hf_mikey
[POS_PKE_C
],
1585 { "C", "mikey.pke.c",
1586 FT_UINT16
, BASE_DEC
, VALS(pke_c_vals
), 0xc000,
1588 { &hf_mikey
[POS_PKE_DATA_LEN
],
1589 { "Data len", "mikey.pke.len",
1590 FT_UINT16
, BASE_DEC
, NULL
, 0x3fff,
1592 { &hf_mikey
[POS_PKE_DATA
],
1593 { "Data", "mikey.pke.data",
1594 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1597 /* DH data payload (DH) */
1598 { &hf_mikey
[POS_DH_GROUP
],
1599 { "DH-Group", "mikey.dh.group",
1600 FT_UINT8
, BASE_DEC
, VALS(oakley_vals
), 0x0,
1602 { &hf_mikey
[POS_DH_VALUE
],
1603 { "DH-Value", "mikey.dh.value",
1604 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1606 { &hf_mikey
[POS_DH_RESERV
],
1607 { "Reserv", "mikey.dh.reserv",
1608 FT_UINT8
, BASE_HEX
, NULL
, 0xf0,
1610 { &hf_mikey
[POS_DH_KV
],
1611 { "KV", "mikey.dh.kv",
1612 FT_UINT8
, BASE_DEC
, VALS(kv_vals
), 0x0f,
1615 /* Signature payload (SIGN) */
1616 { &hf_mikey
[POS_SIGN_S_TYPE
],
1617 { "Signature type", "mikey.sign.type",
1618 FT_UINT16
, BASE_DEC
, VALS(sign_s_vals
), 0xf000,
1620 { &hf_mikey
[POS_SIGNATURE_LEN
],
1621 { "Signature len", "mikey.sign.len",
1622 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
1624 { &hf_mikey
[POS_SIGNATURE
],
1625 { "Signature", "mikey.sign.data",
1626 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1629 /* Timestamp payload (T) */
1630 { &hf_mikey
[POS_TS_TYPE
],
1631 { "TS type", "mikey.t.ts_type",
1632 FT_UINT8
, BASE_DEC
, VALS(ts_type_vals
), 0x0,
1634 { &hf_mikey
[POS_TS_NTP
],
1635 { "NTP timestamp", "mikey.t.ntp",
1636 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0x0,
1639 { &hf_mikey
[POS_PAYLOAD_STR
],
1640 { "Payload", "mikey.payload",
1641 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1644 /* ID payload (ID) */
1645 { &hf_mikey
[POS_ID_TYPE
],
1646 { "ID type", "mikey.id.type",
1647 FT_UINT8
, BASE_DEC
, VALS(id_type_vals
), 0x0,
1649 { &hf_mikey
[POS_ID_LEN
],
1650 { "ID len", "mikey.id.len",
1651 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1653 { &hf_mikey
[POS_ID
],
1654 { "ID", "mikey.id.data",
1655 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1658 /* Certificate payload (CERT) */
1659 { &hf_mikey
[POS_CERT_LEN
],
1660 { "Certificate len", "mikey.cert.len",
1661 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1663 { &hf_mikey
[POS_CERT_TYPE
],
1664 { "Certificate type", "mikey.cert.type",
1665 FT_UINT8
, BASE_DEC
, VALS(cert_type_vals
), 0x0,
1667 { &hf_mikey
[POS_CERTIFICATE
],
1668 { "Certificate", "mikey.cert.data",
1669 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1672 /* Ver msg payload (V) */
1673 { &hf_mikey
[POS_V_AUTH_ALG
],
1674 { "Auth alg", "mikey.v.auth_alg",
1675 FT_UINT8
, BASE_DEC
, VALS(mac_alg_vals
), 0x0,
1677 { &hf_mikey
[POS_V_DATA
],
1678 { "Ver data", "mikey.v.ver_data",
1679 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1682 /* Security Policy payload (SP) */
1683 { &hf_mikey
[POS_SP_NO
],
1684 { "Policy No", "mikey.sp.no",
1685 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1687 { &hf_mikey
[POS_SP_TYPE
],
1688 { "Protocol type", "mikey.sp.proto_type",
1689 FT_UINT8
, BASE_DEC
, VALS(sp_prot_type_vals
), 0x0,
1691 { &hf_mikey
[POS_SP_PARAM_LEN
],
1692 { "Policy param length", "mikey.sp.param_len",
1693 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1696 /* Security Policy param */
1697 { &hf_mikey
[POS_SP_PARAM_F
],
1698 { "Policy param", "mikey.sp.param",
1699 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1701 { &hf_mikey
[POS_SP_PARAM_F_TYPE
],
1702 { "Type", "mikey.sp.param.type",
1703 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1705 { &hf_mikey
[POS_SP_PARAM_F_LEN
],
1706 { "Length", "mikey.sp.param.len",
1707 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1709 { &hf_mikey
[POS_SP_PARAM_F_VALUE
],
1710 { "Value", "mikey.sp.patam.value",
1711 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1714 /* SRTP policy param */
1715 { &hf_mikey_sp_param
[SP_ENCR_ALG
],
1716 { SP_TEXT_ENCR_ALG
, "mikey.sp.encr_alg",
1717 FT_UINT8
, BASE_DEC
, VALS(sp_encr_alg_vals
), 0x0,
1719 { &hf_mikey_sp_param
[SP_ENCR_LEN
],
1720 { SP_TEXT_ENCR_LEN
, "mikey.sp.encr_len",
1721 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1723 { &hf_mikey_sp_param
[SP_AUTH_ALG
],
1724 { SP_TEXT_AUTH_ALG
, "mikey.sp.auth_alg",
1725 FT_UINT8
, BASE_DEC
, VALS(sp_auth_alg_vals
), 0x0,
1727 { &hf_mikey_sp_param
[SP_AUTH_KEY_LEN
],
1728 { SP_TEXT_AUTH_KEY_LEN
, "mikey.sp.auth_key_len",
1729 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1731 { &hf_mikey_sp_param
[SP_SALT_LEN
],
1732 { SP_TEXT_SALT_LEN
, "mikey.sp.salt_len",
1733 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1735 { &hf_mikey_sp_param
[SP_PRF
],
1736 { SP_TEXT_PRF
, "mikey.sp.prf",
1737 FT_UINT8
, BASE_DEC
, VALS(sp_prf_vals
), 0x0,
1739 { &hf_mikey_sp_param
[SP_KD_RATE
],
1740 { SP_TEXT_KD_RATE
, "mikey.sp.kd_rate",
1741 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1743 { &hf_mikey_sp_param
[SP_SRTP_ENCR
],
1744 { SP_TEXT_SRTP_ENCR
, "mikey.sp.srtp_encr",
1745 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1747 { &hf_mikey_sp_param
[SP_SRTCP_ENCR
],
1748 { SP_TEXT_SRTCP_ENCR
, "mikey.sp.srtcp_encr",
1749 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1751 { &hf_mikey_sp_param
[SP_FEC
],
1752 { SP_TEXT_FEC
, "mikey.sp.fec",
1753 FT_UINT8
, BASE_DEC
, VALS(sp_fec_vals
), 0x0,
1755 { &hf_mikey_sp_param
[SP_SRTP_AUTH
],
1756 { SP_TEXT_SRTP_AUTH
, "mikey.sp.srtp_auth",
1757 FT_UINT8
, BASE_DEC
, VALS(on_off_vals
), 0x0,
1759 { &hf_mikey_sp_param
[SP_AUTH_TAG_LEN
],
1760 { SP_TEXT_AUTH_TAG_LEN
, "mikey.sp.auth_tag_len",
1761 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1763 { &hf_mikey_sp_param
[SP_SRTP_PREFIX
],
1764 { SP_TEXT_SRTP_PREFIX
, "mikey.sp.srtp_prefix",
1765 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1768 /* RAND payload (RAND) */
1769 { &hf_mikey
[POS_RAND_LEN
],
1770 { "RAND len", "mikey.rand.len",
1771 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1773 { &hf_mikey
[POS_RAND
],
1774 { "RAND", "mikey.rand.data",
1775 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1778 /* Error payload (ERR) */
1779 { &hf_mikey
[POS_ERR_NO
],
1780 { "Error no.", "mikey.err.no",
1781 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &err_vals_ext
, 0x0,
1783 { &hf_mikey
[POS_ERR_RESERVED
],
1784 { "Reserved", "mikey.err.reserved",
1785 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1789 { &hf_mikey
[POS_ID_ROLE
],
1790 { "ID role", "mikey.id.role",
1791 FT_UINT8
, BASE_DEC
, VALS(id_role_vals
), 0x0,
1794 /* Key data sub-payload */
1795 { &hf_mikey
[POS_KEY_DATA_TYPE
],
1796 { "Type", "mikey.key.type",
1797 FT_UINT8
, BASE_DEC
, VALS(kd_vals
), 0xf0,
1799 { &hf_mikey
[POS_KEY_DATA_KV
],
1800 { "KV", "mikey.key.kv",
1801 FT_UINT8
, BASE_DEC
, VALS(kv_vals
), 0x0f,
1803 { &hf_mikey
[POS_KEY_DATA_LEN
],
1804 { "Key len", "mikey.key.data.len",
1805 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1807 { &hf_mikey
[POS_KEY_DATA
],
1808 { "Key", "mikey.key.data",
1809 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1811 { &hf_mikey
[POS_KEY_SALT_LEN
],
1812 { "Salt key len", "mikey.key.salt.len",
1813 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1815 { &hf_mikey
[POS_KEY_SALT
],
1816 { "Salt key", "mikey.key.salt",
1817 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1819 { &hf_mikey
[POS_KEY_KV_FROM_LEN
],
1820 { "Valid from len", "mikey.key.kv.from.len",
1821 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1823 { &hf_mikey
[POS_KEY_KV_FROM
],
1824 { "Valid from", "mikey.key.kv.from",
1825 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1827 { &hf_mikey
[POS_KEY_KV_TO_LEN
],
1828 { "Valid to len", "mikey.key.kv.to.len",
1829 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1831 { &hf_mikey
[POS_KEY_KV_TO
],
1832 { "Valid to", "mikey.key.kv.to",
1833 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1835 { &hf_mikey
[POS_KEY_KV_SPI_LEN
],
1836 { "Valid SPI len", "mikey.key.kv.spi.len",
1837 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1839 { &hf_mikey
[POS_KEY_KV_SPI
],
1840 { "Valid SPI", "mikey.key.kv.spi",
1841 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1844 /* General Extension payload (GENERAL_EXT) */
1845 { &hf_mikey
[POS_GENERAL_EXT_TYPE
],
1846 { "Extension type", "mikey.ext.type",
1847 FT_UINT8
, BASE_DEC
, VALS(genext_type_vals
), 0x0,
1849 { &hf_mikey
[POS_GENERAL_EXT_LEN
],
1850 { "Length", "mikey.ext.len",
1851 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1853 { &hf_mikey
[POS_GENERAL_EXT_DATA
],
1854 { "Data", "mikey.ext.data",
1855 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1857 { &hf_mikey
[POS_GENERAL_EXT_VALUE
],
1858 { "Value", "mikey.ext.value",
1859 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1863 { &hf_mikey
[POS_SAKKE_PARAMS
],
1864 { "SAKKE params", "mikey.sakke.params",
1865 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1867 { &hf_mikey
[POS_SAKKE_ID_SCHEME
],
1868 { "ID scheme", "mikey.sakke.idscheme",
1869 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1871 { &hf_mikey
[POS_SAKKE_LEN
],
1872 { "SAKKE data length", "mikey.sakke.len",
1873 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1875 { &hf_mikey
[POS_SAKKE_DATA
],
1876 { "SAKKE data", "mikey.sakke.data",
1877 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1881 { &hf_mikey[POS_SP_PARAM],
1882 { "Policy param", "mikey.policy_param",
1883 FT_BYTES, BASE_NONE, NULL, 0x0,
1886 { &hf_mikey[POS_PAYLOAD],
1887 { "Payload", "mikey.payload",
1888 FT_BYTES, BASE_HEX, NULL, 0x0,
1893 /* Setup protocol subtree array */
1894 static gint
*ett
[] = {
1897 &ett_mikey_sp_param
,
1902 module_t
*mikey_module
;
1904 /* Register the protocol name and description */
1905 proto_mikey
= proto_register_protocol("Multimedia Internet KEYing",
1908 mikey_handle
= new_register_dissector("mikey", dissect_mikey
, proto_mikey
);
1910 /* Required function calls to register the header fields and subtrees used */
1911 proto_register_field_array(proto_mikey
, hf
, array_length(hf
));
1912 proto_register_subtree_array(ett
, array_length(ett
));
1914 /* Register our configuration options */
1915 mikey_module
= prefs_register_protocol(proto_mikey
, proto_reg_handoff_mikey
);
1917 prefs_register_uint_preference(mikey_module
, "udp.port", "MIKEY UDP Port",
1918 "Set the port for MIKEY messages (if other than the default of 2269)",
1919 10, &global_mikey_udp_port
);
1921 prefs_register_uint_preference(mikey_module
, "tcp.port", "MIKEY TCP Port",
1922 "Set the port for MIKEY messages (if other than the default of 2269)",
1923 10, &global_mikey_tcp_port
);
1929 proto_reg_handoff_mikey(void)
1931 static guint mikey_tcp_port
;
1932 static guint mikey_udp_port
;
1933 static gboolean inited
= FALSE
;
1936 dissector_add_string("key_mgmt", "mikey", mikey_handle
);
1939 dissector_delete_uint("udp.port", mikey_udp_port
, mikey_handle
);
1940 dissector_delete_uint("tcp.port", mikey_tcp_port
, mikey_handle
);
1943 dissector_add_uint("udp.port", global_mikey_udp_port
, mikey_handle
);
1944 dissector_add_uint("tcp.port", global_mikey_tcp_port
, mikey_handle
);
1946 mikey_udp_port
= global_mikey_udp_port
;
1947 mikey_tcp_port
= global_mikey_tcp_port
;