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 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * http://tools.ietf.org/html/rfc3830 MIKEY
26 * http://tools.ietf.org/html/rfc6043 MIKEY-TICKET (ID role required for SAKKE)
27 * http://tools.ietf.org/html/rfc6509 MIKEY-SAKKE
32 * tvbuff offset in 32-bit variable.
34 * Decode Mikey-PK and Mikey-RSA-R with NULL encryption
40 #include <epan/packet.h>
41 #include <epan/prefs.h>
42 #include <epan/asn1.h>
43 #include "packet-x509af.h"
45 void proto_register_mikey(void);
46 void proto_reg_handoff_mikey(void);
48 #define PORT_MIKEY 2269
49 static guint global_mikey_tcp_port = PORT_MIKEY;
51 static guint global_mikey_udp_port = PORT_MIKEY;
53 static const value_string on_off_vals[] = {
60 MIKEY_TYPE_PSK_INIT = 0,
67 MIKEY_TYPE_DHHMAC_INIT,
68 MIKEY_TYPE_DHHMAC_RESP,
69 MIKEY_TYPE_RSA_R_INIT,
70 MIKEY_TYPE_RSA_R_RESP,
71 MIKEY_TYPE_SAKKE_INIT = 26,
75 static const value_string data_type_vals[] = {
76 { MIKEY_TYPE_PSK_INIT, "Pre-shared" },
77 { MIKEY_TYPE_PSK_RESP, "PSK ver msg" },
78 { MIKEY_TYPE_PK_INIT, "Public key" },
79 { MIKEY_TYPE_PK_RESP, "PK ver msg" },
80 { MIKEY_TYPE_DH_INIT, "D-H init" },
81 { MIKEY_TYPE_DH_RESP, "D-H resp" },
82 { MIKEY_TYPE_ERROR, "Error" },
83 { MIKEY_TYPE_DHHMAC_INIT, "DHHMAC init" },
84 { MIKEY_TYPE_DHHMAC_RESP, "DHHMAC resp" },
85 { MIKEY_TYPE_RSA_R_INIT, "RSA-R I_MSG" },
86 { MIKEY_TYPE_RSA_R_RESP, "RSA-R R_MSG" },
87 { MIKEY_TYPE_SAKKE_INIT, "SAKKE" },
88 { MIKEY_TYPE_SAKKE_RESP, "CS Id map Update" },
91 static value_string_ext data_type_vals_ext = VALUE_STRING_EXT_INIT(data_type_vals);
97 static const value_string cs_id_map_vals[] = {
98 { CS_ID_SRTP, "SRTP-ID" },
117 PL_TR = 13, /* MIKEY-TICKET (6043) */
128 #define PL_HDR_TEXT "Common Header (HDR)"
129 #define PL_LAST_TEXT "Last payload"
130 #define PL_KEMAC_TEXT "Key Data Transport (KEMAC)"
131 #define PL_PKE_TEXT "Envelope Data (PKE)"
132 #define PL_DH_TEXT "DH Data (DH)"
133 #define PL_SIGN_TEXT "Signature (SIGN)"
134 #define PL_T_TEXT "Timestamp (T)"
135 #define PL_ID_TEXT "ID"
136 #define PL_CERT_TEXT "Certificate (CERT)"
137 #define PL_CHASH_TEXT "CHASH"
138 #define PL_V_TEXT "Ver msg (V)"
139 #define PL_SP_TEXT "Security Policy (SP)"
140 #define PL_RAND_TEXT "RAND"
141 #define PL_ERR_TEXT "Error (ERR)"
142 #define PL_KEY_DATA_TEXT "Key data (KEY)"
143 #define PL_IDR_TEXT "IDR"
144 #define PL_GENERAL_EXT_TEXT "General Extension (EXT)"
145 #define PL_SAKKE_TEXT "SAKKE Encapsulated Data (SAKKE)"
147 static const value_string payload_vals[] = {
148 { PL_HDR, PL_HDR_TEXT },
149 { PL_LAST, PL_LAST_TEXT },
150 { PL_KEMAC, PL_KEMAC_TEXT },
151 { PL_PKE, PL_PKE_TEXT },
152 { PL_DH, PL_DH_TEXT },
153 { PL_SIGN, PL_SIGN_TEXT },
155 { PL_ID, PL_ID_TEXT },
156 { PL_CERT, PL_CERT_TEXT },
157 { PL_CHASH, PL_CHASH_TEXT },
159 { PL_SP, PL_SP_TEXT },
160 { PL_RAND, PL_RAND_TEXT },
161 { PL_ERR, PL_ERR_TEXT },
162 { PL_IDR, PL_IDR_TEXT },
163 { PL_KEY_DATA, PL_KEY_DATA_TEXT },
164 { PL_GENERAL_EXT, PL_GENERAL_EXT_TEXT },
165 { PL_SAKKE, PL_SAKKE_TEXT },
168 #if 0 /* First entry (PL_HDR) is -1 and there are gaps so this doesn't work */
169 static value_string_ext payload_vals_ext = VALUE_STRING_EXT_INIT(payload_vals);
178 static const value_string ts_type_vals[] = {
179 { T_NTP_UTC, "NTP-UTC" },
181 { T_COUNTER, "COUNTER" },
191 static const value_string encr_alg_vals[] = {
192 { ENCR_NULL, "NULL" },
193 { ENCR_AES_CM_128, "AES-CM-128" },
194 { ENCR_AES_KW_128, "AES-KW-128" },
204 static const value_string oakley_vals[] = {
205 { DH_OAKLEY_5, "OAKLEY 5" },
206 { DH_OAKLEY_1, "OAKLEY 1" },
207 { DH_OAKLEY_2, "OAKLEY 2" },
216 static const value_string mac_alg_vals[] = {
217 { MAC_NULL, "NULL" },
218 { MAC_HMAC_SHA_1_160, "HMAC-SHA-1-160" },
228 static const value_string pke_c_vals[] = {
229 { PKE_C_NO_CACHE, "No cache" },
230 { PKE_C_CACHE, "Cache" },
231 { PKE_C_CACHE_CSB, "Cache for CSB" },
241 static const value_string sign_s_vals[] = {
242 { SIGN_S_PKCS1, "RSA/PKCS#1/1.5" },
243 { SIGN_S_PSS, "RSA/PSS" },
244 { SIGN_S_ECCSI, "ECCSI" },
254 static const value_string id_type_vals[] = {
255 { ID_TYPE_NAI, "NAI" },
256 { ID_TYPE_URI, "URI" },
257 { ID_TYPE_BYTE_STRING, "Byte string" },
262 ID_ROLE_RESERVED = 0,
272 static const value_string id_role_vals[] = {
273 { ID_ROLE_RESERVED, "Reserved" },
274 { ID_ROLE_INIT, "Initiator (IDRi)" },
275 { ID_ROLE_RESP, "Responder (IDRr)" },
276 { ID_ROLE_KMS, "KMS (IDRkms)" },
277 { ID_ROLE_PSK, "Pre-Shared Key (IDRpsk)" },
278 { ID_ROLE_APP, "Application (IDRapp)" },
279 { ID_ROLE_INIT_KMS, "Initiator's KMS (IDRkmsi)" },
280 { ID_ROLE_RESP_KMS, "Responder's KMS (IDRkmsr)" },
285 CERT_TYPE_X509V3 = 0,
286 CERT_TYPE_X509V3_URL,
287 CERT_TYPE_X509V3_SIGN,
288 CERT_TYPE_X509V3_ENCR
291 static const value_string cert_type_vals[] = {
292 { CERT_TYPE_X509V3, "X.509v3" },
293 { CERT_TYPE_X509V3_URL, "X.509v3 URL" },
294 { CERT_TYPE_X509V3_SIGN, "X.509v3 Sign" },
295 { CERT_TYPE_X509V3_ENCR, "X.509v3 Encr" },
299 enum srtp_policy_type_t {
316 #define SP_TEXT_ENCR_ALG "Encryption algorithm"
317 #define SP_TEXT_ENCR_LEN "Session Encr. key length"
318 #define SP_TEXT_AUTH_ALG "Authentication algorithm"
319 #define SP_TEXT_AUTH_KEY_LEN "Session Auth. key length"
320 #define SP_TEXT_SALT_LEN "Session Salt key length"
321 #define SP_TEXT_PRF "SRTP Pseudo Random Function"
322 #define SP_TEXT_KD_RATE "Key derivation rate"
323 #define SP_TEXT_SRTP_ENCR "SRTP encryption"
324 #define SP_TEXT_SRTCP_ENCR "SRTCP encryption"
325 #define SP_TEXT_FEC "Sender's FEC order"
326 #define SP_TEXT_SRTP_AUTH "SRTP authentication"
327 #define SP_TEXT_AUTH_TAG_LEN "Authentication tag length"
328 #define SP_TEXT_SRTP_PREFIX "SRTP prefix length"
331 static const value_string srtp_policy_type_vals[] = {
332 { SP_ENCR_ALG, SP_TEXT_ENCR_ALG },
333 { SP_ENCR_LEN, SP_TEXT_ENCR_LEN },
334 { SP_AUTH_ALG, SP_TEXT_AUTH_ALG },
335 { SP_AUTH_KEY_LEN, SP_TEXT_AUTH_KEY_LEN },
336 { SP_SALT_LEN, SP_TEXT_SALT_LEN },
337 { SP_PRF, SP_TEXT_PRF },
338 { SP_KD_RATE, SP_TEXT_KD_RATE },
339 { SP_SRTP_ENCR, SP_TEXT_SRTP_ENCR },
340 { SP_SRTCP_ENCR, SP_TEXT_SRTCP_ENCR },
341 { SP_FEC, SP_TEXT_FEC },
342 { SP_SRTP_AUTH, SP_TEXT_SRTP_AUTH },
343 { SP_AUTH_TAG_LEN, SP_TEXT_AUTH_TAG_LEN },
344 { SP_SRTP_PREFIX, SP_TEXT_SRTP_PREFIX },
355 static const value_string sp_encr_alg_vals[] = {
356 { SP_ENCR_NULL, "NULL" },
357 { SP_ENCR_AES_CM, "AES-CM" },
358 { SP_ENCR_AES_F8, "AES-F8" },
367 static const value_string sp_auth_alg_vals[] = {
368 { SP_AUTH_NULL, "NULL" },
369 { SP_AUTH_HMAC_SHA_1, "HMAC-SHA-1" },
377 static const value_string sp_prf_vals[] = {
378 { SP_PRF_AES_CM, "AES-CM" },
386 static const value_string sp_fec_vals[] = {
387 { SP_FEC_SRTP, "FEC-SRTP" },
392 SP_PROT_TYPE_SRTP = 0
395 static const value_string sp_prot_type_vals[] = {
396 { SP_PROT_TYPE_SRTP, "SRTP" },
404 static const value_string prf_func_vals[] = {
405 { PRF_FUNC_MIKEY_1, "MIKEY-1" },
415 static const value_string kv_vals[] = {
417 { KV_SPI, "SPI/MKI" },
418 { KV_INTERVAL, "Interval" },
429 static const value_string kd_vals[] = {
431 { KD_TGK_SALT, "TGK+SALT" },
433 { KD_TEK_SALT, "TEK+SALT" },
438 ERR_AUTH_FAILURE = 0,
453 static const value_string err_vals[] = {
454 { ERR_AUTH_FAILURE, "Authentication failure" },
455 { ERR_INVALID_TS, "Invalid timestamp" },
456 { ERR_INVALID_PRF, "PRF function not supported" },
457 { ERR_INVALID_MAC, "MAC algorithm not supported" },
458 { ERR_INVALID_EA, "Encryption algorithm not supported" },
459 { ERR_INVALID_HA, "Hash function not supported" },
460 { ERR_INVALID_DH, "DH group not supported" },
461 { ERR_INVALID_ID, "ID not supported" },
462 { ERR_INVALID_CERT, "Certificate not supported" },
463 { ERR_INVALID_SP, "SP type not supported" },
464 { ERR_INVALID_SPPAR, "SP parameters not supported" },
465 { ERR_INVALID_DT, "Data type not supported" },
466 { ERR_UNKNOWN, "Unspecified error" },
469 static value_string_ext err_vals_ext = VALUE_STRING_EXT_INIT(err_vals);
472 GEN_EXT_VENDOR_ID = 0,
476 static const value_string genext_type_vals[] = {
477 { GEN_EXT_VENDOR_ID, "Vendor-ID" },
478 { GEN_EXT_SDP_ID, "SDP-IDs" },
490 POS_HDR_CS_ID_MAP_TYPE,
498 POS_KEMAC_ENCR_DATA_LEN,
548 POS_SP_PARAM_F_VALUE,
573 POS_GENERAL_EXT_TYPE,
575 POS_GENERAL_EXT_DATA,
576 POS_GENERAL_EXT_VALUE,
594 typedef struct tag_mikey_t {
598 typedef int (*mikey_dissector_t)(mikey_t *, tvbuff_t *, packet_info *, proto_tree *);
599 struct mikey_dissector_entry {
601 mikey_dissector_t dissector;
604 /* Forward declaration we need below */
605 static int dissect_payload(int payload, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
608 /* Initialize the protocol and registered fields */
609 static int proto_mikey = -1;
610 static int hf_mikey[MAX_POS+1];
611 static int hf_mikey_sp_param[SP_MAX+1];
612 static int hf_mikey_pl[PL_MAX];
614 /* Initialize the subtree pointers */
615 static gint ett_mikey = -1;
616 static gint ett_mikey_payload = -1;
617 static gint ett_mikey_sp_param = -1;
618 static gint ett_mikey_hdr_id = -1;
619 static gint ett_mikey_enc_data = -1;
621 static dissector_handle_t mikey_handle;
623 static const struct mikey_dissector_entry *
624 mikey_dissector_lookup(const struct mikey_dissector_entry *map, int type)
627 for (i = 0; map[i].dissector != NULL; i++) {
628 if (map[i].type == type) {
637 add_next_payload(tvbuff_t *tvb, proto_tree *tree, int offset)
639 proto_tree_add_item(tree, hf_mikey[POS_NEXT_PAYLOAD], tvb, offset, 1, ENC_BIG_ENDIAN);
644 dissect_payload_cs_id_srtp(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
653 no = tvb_get_guint8(tvb, 0);
654 ssrc = tvb_get_ntohl(tvb, 1);
655 roc = tvb_get_ntohl(tvb, 5);
657 id_ti = proto_tree_add_none_format(tree, hf_mikey[POS_ID_SRTP], tvb, 0, 9,
658 "SRTP ID: Policy: %d, SSRC: 0x%x, ROC: 0x%x", no, ssrc, roc);
659 id_tree = proto_item_add_subtree(id_ti, ett_mikey_hdr_id);
661 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_NO], tvb, 0, 1, ENC_BIG_ENDIAN);
662 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_SSRC], tvb, 1, 4, ENC_BIG_ENDIAN);
663 proto_tree_add_item(id_tree, hf_mikey[POS_ID_SRTP_ROC], tvb, 5, 4, ENC_BIG_ENDIAN);
668 static const struct mikey_dissector_entry cs_id_map[] = {
669 { CS_ID_SRTP, dissect_payload_cs_id_srtp },
674 dissect_payload_cs_id(int type, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
676 const struct mikey_dissector_entry *entry;
678 entry = mikey_dissector_lookup(cs_id_map, type);
680 if (!entry || !entry->dissector) {
684 return entry->dissector(mikey, tvb, pinfo, tree);
689 dissect_payload_hdr(mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
692 guint8 cs_id_map_type;
696 tvb_ensure_bytes_exist(tvb, offset, 10);
697 mikey->type = tvb_get_guint8(tvb, offset+1);
698 ncs = tvb_get_guint8(tvb, offset+8);
699 cs_id_map_type = tvb_get_guint8(tvb, offset+9);
703 proto_tree_add_item(tree, hf_mikey[POS_HDR_VERSION],
704 tvb, offset+0, 1, ENC_BIG_ENDIAN);
706 proto_tree_add_item(tree, hf_mikey[POS_HDR_DATA_TYPE], tvb, offset+1, 1, ENC_BIG_ENDIAN);
707 parent = proto_tree_get_parent(tree);
708 proto_item_append_text(parent, " Type: %s",
709 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
711 add_next_payload(tvb, tree, offset+2);
713 proto_tree_add_item(tree, hf_mikey[POS_HDR_V], tvb, offset+3, 1, ENC_BIG_ENDIAN);
714 proto_tree_add_item(tree, hf_mikey[POS_HDR_PRF_FUNC], tvb, offset+3, 1, ENC_BIG_ENDIAN);
716 proto_tree_add_item(tree, hf_mikey[POS_HDR_CSB_ID], tvb, offset+4, 4, ENC_BIG_ENDIAN);
718 proto_tree_add_item(tree, hf_mikey[POS_HDR_CS_COUNT], tvb, offset+8, 1, ENC_BIG_ENDIAN);
719 proto_tree_add_item(tree, hf_mikey[POS_HDR_CS_ID_MAP_TYPE], tvb, offset+9, 1, ENC_BIG_ENDIAN);
723 for (i=0; i < ncs; i++) {
727 sub_tvb = tvb_new_subset_remaining(tvb, offset);
728 len = dissect_payload_cs_id(cs_id_map_type, mikey, sub_tvb, pinfo, tree);
740 dissect_payload_kemac(mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
748 encr_alg = tvb_get_guint8(tvb, offset+1);
749 encr_length = tvb_get_ntohs(tvb, offset+2);
750 tvb_ensure_bytes_exist(tvb, offset+4, encr_length+1);
751 mac_alg = tvb_get_guint8(tvb, offset+4+encr_length);
755 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_ALG], tvb, 1, 1, ENC_BIG_ENDIAN);
756 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_DATA_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
757 /* TODO: Add key decode for MIKEY_TYPE_PK_INIT and MIKEY_TYPE_RSA_R_RESP with NULL encryption */
758 if ((encr_alg == ENCR_NULL) && (mikey->type == MIKEY_TYPE_PSK_INIT) && (encr_length > 0)) {
759 proto_item *key_data_item;
760 proto_tree *key_data_tree;
761 /* We can decode easily the Key Data if NULL encryption is used */
762 key_data_item = proto_tree_add_item(tree, hf_mikey_pl[PL_KEY_DATA], tvb, 4, encr_length, ENC_NA);
763 key_data_tree = proto_item_add_subtree(key_data_item, ett_mikey_enc_data);
765 sub_tvb = tvb_new_subset_length(tvb, offset+4, encr_length);
766 dissect_payload(PL_KEY_DATA, mikey, sub_tvb, pinfo, key_data_tree);
768 /* If Key Data is encrypted, show only the encr_data */
769 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_ENCR_DATA], tvb, 4, encr_length, ENC_NA);
771 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_MAC_ALG], tvb, 4+encr_length, 1, ENC_BIG_ENDIAN);
778 case MAC_HMAC_SHA_1_160:
785 proto_tree_add_item(tree, hf_mikey[POS_KEMAC_MAC], tvb, 4+encr_length+1, mac_length, ENC_NA);
787 return 4+encr_length+1+mac_length;
791 dissect_payload_pke(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
796 length = tvb_get_ntohs(tvb, offset+1) &0x3ff;
799 proto_tree_add_item(tree, hf_mikey[POS_PKE_C], tvb, 1, 2, ENC_BIG_ENDIAN);
801 proto_tree_add_item(tree, hf_mikey[POS_PKE_DATA_LEN], tvb, 1, 2, ENC_BIG_ENDIAN);
804 proto_tree_add_item(tree, hf_mikey[POS_PKE_DATA], tvb, 3, length, ENC_NA);
809 dissect_payload_dh(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
816 dh_group = tvb_get_guint8(tvb, offset+1);
832 kv = tvb_get_guint8(tvb, offset+2+dh_length) & 0x0f;
835 proto_tree_add_item(tree, hf_mikey[POS_DH_GROUP], tvb, 1, 1, ENC_BIG_ENDIAN);
836 proto_tree_add_item(tree, hf_mikey[POS_DH_VALUE], tvb, 2, dh_length, ENC_NA);
837 proto_tree_add_item(tree, hf_mikey[POS_DH_RESERV], tvb, 2+dh_length, 1, ENC_BIG_ENDIAN);
838 proto_tree_add_item(tree, hf_mikey[POS_DH_KV], tvb, 2+dh_length, 1, ENC_BIG_ENDIAN);
845 return 2 + dh_length + 1;
849 dissect_payload_sign(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
854 length = ((tvb_get_guint8(tvb, offset+0) & 0x0f) << 8) + tvb_get_guint8(tvb, offset+1);
857 proto_tree_add_item(tree, hf_mikey[POS_SIGN_S_TYPE], tvb, 0, 2, ENC_BIG_ENDIAN);
858 proto_tree_add_uint(tree, hf_mikey[POS_SIGNATURE_LEN], tvb, 0, 2, length);
861 proto_tree_add_item(tree, hf_mikey[POS_SIGNATURE], tvb, 2, length, ENC_NA);
866 dissect_payload_t(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
872 ts_type = tvb_get_guint8(tvb, offset+1);
876 parent = proto_tree_get_parent(tree);
877 proto_item_append_text(parent, " Type: %s", val_to_str_const(ts_type, ts_type_vals, "Unknown"));
878 proto_tree_add_item(tree, hf_mikey[POS_TS_TYPE], tvb, offset+1, 1, ENC_BIG_ENDIAN);
884 proto_tree_add_item(tree, hf_mikey[POS_TS_NTP], tvb, offset+2, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
899 dissect_payload_id(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
905 type = tvb_get_guint8(tvb, offset+1);
906 length = tvb_get_ntohs(tvb, offset+2);
908 proto_tree_add_item(tree, hf_mikey[POS_ID_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
909 proto_tree_add_item(tree, hf_mikey[POS_ID_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
914 proto_tree_add_item(tree, hf_mikey[POS_ID], tvb, 4, length, ENC_ASCII|ENC_NA);
916 parent = proto_tree_get_parent(tree);
917 proto_item_append_text(parent, " %s: %s",
918 val_to_str_const(type, id_type_vals, "Unknown"),
919 tvb_get_string_enc(wmem_packet_scope(), tvb, 4, length, ENC_ASCII));
926 dissect_payload_idr(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
932 type = tvb_get_guint8(tvb, offset+2);
933 length = tvb_get_ntohs(tvb, offset+3);
935 proto_tree_add_item(tree, hf_mikey[POS_ID_ROLE], tvb, 1, 1, ENC_BIG_ENDIAN);
936 proto_tree_add_item(tree, hf_mikey[POS_ID_TYPE], tvb, 2, 1, ENC_BIG_ENDIAN);
937 proto_tree_add_item(tree, hf_mikey[POS_ID_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
942 proto_tree_add_item(tree, hf_mikey[POS_ID], tvb, 5, length, ENC_ASCII|ENC_NA);
944 parent = proto_tree_get_parent(tree);
945 proto_item_append_text(parent, " %s: %s",
946 val_to_str_const(type, id_type_vals, "Unknown"),
947 tvb_get_string_enc(wmem_packet_scope(), tvb, 5, length, ENC_ASCII));
954 dissect_payload_cert(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
962 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
964 type = tvb_get_guint8(tvb, offset+1);
965 length = tvb_get_ntohs(tvb, offset+2);
967 tvb_ensure_bytes_exist(tvb, offset+4, length);
971 parent = proto_tree_get_parent(tree);
972 proto_tree_add_item(tree, hf_mikey[POS_CERT_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
973 proto_tree_add_item(tree, hf_mikey[POS_CERT_LEN], tvb, 1, 2, ENC_BIG_ENDIAN);
975 proto_item_append_text(parent, " Type: %s", val_to_str_const(type, cert_type_vals, "Unknown"));
978 subtvb = tvb_new_subset_length(tvb, offset+4, length);
979 dissect_x509af_Certificate(FALSE, subtvb, 0, &asn1_ctx, tree, hf_mikey[POS_CERTIFICATE]);
985 dissect_payload_v(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
991 alg = tvb_get_guint8(tvb, offset+1);
993 proto_tree_add_item(tree, hf_mikey[POS_V_AUTH_ALG], tvb, 1, 1, ENC_BIG_ENDIAN);
999 case MAC_HMAC_SHA_1_160:
1006 proto_tree_add_item(tree, hf_mikey[POS_V_DATA], tvb, 2, length, ENC_NA);
1012 dissect_payload_sp_param(enum sp_prot_t proto, tvbuff_t *tvb, proto_tree *tree)
1019 type = tvb_get_guint8(tvb, offset+0);
1020 length = tvb_get_guint8(tvb, offset+1);
1023 hfindex = hf_mikey[POS_SP_PARAM_F];
1026 case SP_PROT_TYPE_SRTP:
1027 if (type < array_length(hf_mikey_sp_param))
1028 hfindex = hf_mikey_sp_param[type];
1033 proto_item *param_ti;
1034 proto_tree *param_tree;
1036 * All the parameters in question are either FT_BYTES,
1037 * in which case the byte order is inapplicable, or
1038 * FT_UINT8, in which case it could be given as
1039 * FT_BIG_ENDIAN as per bigger FT_UINT values, but
1040 * ENC_NA also works, as there's only one byte.
1042 param_ti = proto_tree_add_item(tree, hfindex, tvb, 2, length, ENC_NA);
1043 param_tree = proto_item_add_subtree(param_ti, ett_mikey_sp_param);
1045 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_TYPE], tvb, 0, 1, ENC_BIG_ENDIAN);
1046 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_LEN], tvb, 1, 1, ENC_BIG_ENDIAN);
1047 proto_tree_add_item(param_tree, hf_mikey[POS_SP_PARAM_F_VALUE], tvb, 2, length, ENC_NA);
1054 dissect_payload_sp(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1060 enum sp_prot_t type;
1062 length = tvb_get_ntohs(tvb, offset+3);
1063 no = tvb_get_guint8(tvb, offset+1);
1064 type = (enum sp_prot_t)tvb_get_guint8(tvb, offset+2);
1068 parent = proto_tree_get_parent(tree);
1069 proto_tree_add_item(tree, hf_mikey[POS_SP_NO], tvb, 1, 1, ENC_BIG_ENDIAN);
1070 proto_tree_add_item(tree, hf_mikey[POS_SP_TYPE], tvb, 2, 1, ENC_BIG_ENDIAN);
1071 proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
1073 proto_item_append_text(parent, " No: %d, Type: %s", no,
1074 val_to_str_const(type, sp_prot_type_vals, "Unknown"));
1077 tvb_ensure_bytes_exist(tvb, offset+5, length);
1078 /* proto_tree_add_item(tree, hf_mikey[POS_SP_PARAM], tvb, 5, length, ENC_NA); */
1083 while (sub_pos < length) {
1087 subtvb = tvb_new_subset_length(tvb, offset+sub_pos, length-sub_pos);
1088 param_len = dissect_payload_sp_param(type, subtvb, tree);
1093 sub_pos += param_len;
1100 dissect_payload_rand(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1105 length = tvb_get_guint8(tvb, offset+1);
1107 proto_tree_add_item(tree, hf_mikey[POS_RAND_LEN], tvb, 1, 1, ENC_BIG_ENDIAN);
1108 proto_tree_add_item(tree, hf_mikey[POS_RAND], tvb, 2, length, ENC_NA);
1114 dissect_payload_err(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1119 err_no = tvb_get_guint8(tvb, 1);
1120 proto_tree_add_item(tree, hf_mikey[POS_ERR_NO], tvb, 1, 1, ENC_BIG_ENDIAN);
1121 proto_tree_add_item(tree, hf_mikey[POS_ERR_RESERVED], tvb, 2, 2, ENC_NA);
1122 parent = proto_tree_get_parent(tree);
1123 proto_item_append_text(parent, ": %s", val_to_str_ext_const(err_no, &err_vals_ext, "Unknown"));
1130 dissect_payload_keydata(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1138 key_type = tvb_get_guint8(tvb, 1) >> 4;
1139 kv_type = tvb_get_guint8(tvb, 1) & 0x0f;
1140 data_len = tvb_get_ntohs(tvb, 2);
1146 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
1147 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_KV], tvb, 1, 1, ENC_BIG_ENDIAN);
1148 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
1149 proto_tree_add_item(tree, hf_mikey[POS_KEY_DATA], tvb, 4, data_len, ENC_NA);
1151 parent = proto_tree_get_parent(tree);
1152 proto_item_append_text(parent, " Type: %s", val_to_str_const(key_type, kd_vals, "Unknown"));
1157 /* Dissect SALT key */
1158 if ((key_type == KD_TGK_SALT) || (key_type == KD_TEK_SALT)) {
1160 salt_len = tvb_get_ntohs(tvb, offset);
1162 proto_tree_add_item(tree, hf_mikey[POS_KEY_SALT_LEN], tvb, offset, 2, ENC_BIG_ENDIAN);
1163 proto_tree_add_item(tree, hf_mikey[POS_KEY_SALT], tvb, offset+2, salt_len, ENC_NA);
1165 offset += 2+salt_len;
1168 /* Dissect Key Validity */
1169 if (kv_type == KV_INTERVAL) {
1170 guint16 kv_from_len;
1173 kv_from_len = tvb_get_guint8(tvb, offset);
1174 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_FROM_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1175 if (kv_from_len > 0) {
1176 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_FROM], tvb, offset+1, kv_from_len, ENC_NA);
1178 offset += 1+kv_from_len;
1180 kv_to_len = tvb_get_guint8(tvb, offset);
1181 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_TO_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1182 if (kv_to_len > 0) {
1183 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_TO], tvb, offset+1, kv_to_len, ENC_NA);
1185 offset += 1+kv_to_len;
1186 } else if (kv_type == KV_SPI) {
1189 kv_spi_len = tvb_get_guint8(tvb, offset);
1190 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_SPI_LEN], tvb, offset, 1, ENC_BIG_ENDIAN);
1191 if (kv_spi_len > 0) {
1192 proto_tree_add_item(tree, hf_mikey[POS_KEY_KV_SPI], tvb, offset+1, kv_spi_len, ENC_NA);
1194 offset += 1+kv_spi_len;
1201 dissect_payload_general_ext(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1207 type = tvb_get_guint8(tvb, offset+1);
1208 data_len = tvb_get_ntohs(tvb, offset+2);
1211 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_TYPE], tvb, 1, 1, ENC_BIG_ENDIAN);
1212 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_LEN], tvb, 2, 2, ENC_BIG_ENDIAN);
1218 parent = proto_tree_get_parent(tree);
1220 /* For SDP-IDs, show a string instead of raw bytes */
1221 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_VALUE], tvb, 4, data_len, ENC_ASCII|ENC_NA);
1223 proto_tree_add_item(tree, hf_mikey[POS_GENERAL_EXT_DATA], tvb, 4, data_len, ENC_NA);
1225 proto_item_append_text(parent, " Type: %s", val_to_str_const(type, genext_type_vals, "Unknown"));
1227 return 4 + data_len;
1231 dissect_payload_sakke(mikey_t *mikey _U_, tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1236 data_len = tvb_get_ntohs(tvb, offset+3);
1239 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_PARAMS], tvb, 1, 1, ENC_BIG_ENDIAN);
1240 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_ID_SCHEME], tvb, 2, 1, ENC_BIG_ENDIAN);
1241 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_LEN], tvb, 3, 2, ENC_BIG_ENDIAN);
1244 proto_tree_add_item(tree, hf_mikey[POS_SAKKE_DATA], tvb, 5, data_len, ENC_NA);
1245 return 5 + data_len;
1248 static const struct mikey_dissector_entry payload_map[] = {
1249 { PL_HDR, dissect_payload_hdr },
1250 { PL_KEMAC, dissect_payload_kemac },
1251 { PL_PKE, dissect_payload_pke },
1252 { PL_DH, dissect_payload_dh },
1253 { PL_SIGN, dissect_payload_sign },
1254 { PL_T, dissect_payload_t },
1255 { PL_ID, dissect_payload_id },
1256 { PL_CERT, dissect_payload_cert },
1257 { PL_V, dissect_payload_v },
1258 { PL_SP, dissect_payload_sp },
1259 { PL_RAND, dissect_payload_rand },
1260 { PL_ERR, dissect_payload_err },
1261 { PL_IDR, dissect_payload_idr },
1262 { PL_KEY_DATA, dissect_payload_keydata },
1263 { PL_GENERAL_EXT, dissect_payload_general_ext },
1264 { PL_SAKKE, dissect_payload_sakke },
1269 dissect_payload(int payload, mikey_t *mikey, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1271 const struct mikey_dissector_entry *entry;
1273 entry = mikey_dissector_lookup(payload_map, payload);
1275 if (!entry || !entry->dissector) {
1279 return entry->dissector(mikey, tvb, pinfo, tree);
1282 /* MIKEY dissector */
1284 dissect_mikey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1286 proto_item *ti = NULL;
1287 proto_tree *mikey_tree = NULL;
1289 int next_payload_offset;
1293 mikey = (mikey_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mikey, 0);
1296 mikey = wmem_new0(wmem_file_scope(), mikey_t);
1298 p_add_proto_data(wmem_file_scope(), pinfo, proto_mikey, 0, mikey);
1302 tvb_ensure_bytes_exist(tvb, offset, 3);
1303 next_payload_offset = offset + 2;
1307 ti = proto_tree_add_item(tree, proto_mikey, tvb, 0, -1, ENC_NA);
1308 mikey_tree = proto_item_add_subtree(ti, ett_mikey);
1311 while (payload != 0) {
1313 proto_item *sub_ti = NULL;
1314 proto_tree *mikey_payload_tree = NULL;
1318 next_payload = tvb_get_guint8(tvb, next_payload_offset);
1319 subtvb = tvb_new_subset_remaining(tvb, offset);
1330 sub_ti = proto_tree_add_item(mikey_tree, hf_mikey_pl[hf], subtvb, 0, -1, ENC_NA);
1332 mikey_payload_tree = proto_item_add_subtree(sub_ti, ett_mikey_payload);
1333 if ((payload != PL_HDR) && (payload != PL_SIGN))
1334 add_next_payload(tvb, mikey_payload_tree, next_payload_offset);
1337 len = dissect_payload(payload, mikey, subtvb, pinfo, mikey_payload_tree);
1339 /* protocol violation or invalid data, stop dissecting
1340 * but accept the data retrieved so far */
1341 return tvb_captured_length(tvb);
1345 proto_item_set_len(sub_ti, len);
1347 if (payload == PL_SIGN)
1350 payload = next_payload;
1352 next_payload_offset = offset;
1356 proto_item_append_text(ti, ": %s",
1357 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
1360 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/MIKEY");
1362 col_append_fstr(pinfo->cinfo, COL_INFO, ", Mikey: %s",
1363 val_to_str_ext_const(mikey->type, &data_type_vals_ext, "Unknown"));
1365 /* Return the amount of data this dissector was able to dissect */
1366 return tvb_captured_length(tvb);
1370 /* Register the protocol with Wireshark */
1373 proto_register_mikey(void)
1376 /* Setup list of header fields */
1377 static hf_register_info hf[] = {
1379 { &hf_mikey_pl[PL_HDR+1],
1380 { PL_HDR_TEXT, "mikey.hdr",
1381 FT_NONE, BASE_NONE, NULL, 0x0,
1383 { &hf_mikey_pl[PL_KEMAC],
1384 { PL_KEMAC_TEXT, "mikey.kemac",
1385 FT_NONE, BASE_NONE, NULL, 0x0,
1387 { &hf_mikey_pl[PL_PKE],
1388 { PL_PKE_TEXT, "mikey.pke",
1389 FT_NONE, BASE_NONE, NULL, 0x0,
1391 { &hf_mikey_pl[PL_DH],
1392 { PL_DH_TEXT, "mikey.dh",
1393 FT_NONE, BASE_NONE, NULL, 0x0,
1395 { &hf_mikey_pl[PL_SIGN],
1396 { PL_SIGN_TEXT, "mikey.sign",
1397 FT_NONE, BASE_NONE, NULL, 0x0,
1399 { &hf_mikey_pl[PL_T],
1400 { PL_T_TEXT, "mikey.t",
1401 FT_NONE, BASE_NONE, NULL, 0x0,
1403 { &hf_mikey_pl[PL_ID],
1404 { PL_ID_TEXT, "mikey.id",
1405 FT_NONE, BASE_NONE, NULL, 0x0,
1407 { &hf_mikey_pl[PL_CERT],
1408 { PL_CERT_TEXT, "mikey.cert",
1409 FT_NONE, BASE_NONE, NULL, 0x0,
1411 { &hf_mikey_pl[PL_CHASH],
1412 { PL_CHASH_TEXT, "mikey.chash",
1413 FT_NONE, BASE_NONE, NULL, 0x0,
1415 { &hf_mikey_pl[PL_V],
1416 { PL_V_TEXT, "mikey.v",
1417 FT_NONE, BASE_NONE, NULL, 0x0,
1419 { &hf_mikey_pl[PL_SP],
1420 { PL_SP_TEXT, "mikey.sp",
1421 FT_NONE, BASE_NONE, NULL, 0x0,
1423 { &hf_mikey_pl[PL_RAND],
1424 { PL_RAND_TEXT, "mikey.rand",
1425 FT_NONE, BASE_NONE, NULL, 0x0,
1427 { &hf_mikey_pl[PL_ERR],
1428 { PL_ERR_TEXT, "mikey.err",
1429 FT_NONE, BASE_NONE, NULL, 0x0,
1431 { &hf_mikey_pl[PL_IDR],
1432 { PL_IDR_TEXT, "mikey.idr",
1433 FT_NONE, BASE_NONE, NULL, 0x0,
1435 { &hf_mikey_pl[PL_KEY_DATA],
1436 { PL_KEY_DATA_TEXT, "mikey.key",
1437 FT_NONE, BASE_NONE, NULL, 0x0,
1439 { &hf_mikey_pl[PL_GENERAL_EXT],
1440 { PL_GENERAL_EXT_TEXT, "mikey.ext",
1441 FT_NONE, BASE_NONE, NULL, 0x0,
1443 { &hf_mikey_pl[PL_SAKKE],
1444 { PL_SAKKE_TEXT, "mikey.sakke",
1445 FT_NONE, BASE_NONE, NULL, 0x0,
1448 /* Common Header payload (HDR) */
1449 { &hf_mikey[POS_HDR_VERSION],
1450 { "Version", "mikey.version",
1451 FT_UINT8, BASE_DEC, NULL, 0x0,
1453 { &hf_mikey[POS_HDR_DATA_TYPE],
1454 { "Data Type", "mikey.type",
1455 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &data_type_vals_ext, 0x0,
1457 { &hf_mikey[POS_NEXT_PAYLOAD],
1458 { "Next Payload", "mikey.next_payload",
1459 FT_UINT8, BASE_DEC, VALS(payload_vals), 0x0,
1461 { &hf_mikey[POS_HDR_V],
1463 FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80,
1465 { &hf_mikey[POS_HDR_PRF_FUNC],
1466 { "PRF func", "mikey.prf_func",
1467 FT_UINT8, BASE_DEC, VALS(prf_func_vals), 0x7f,
1469 { &hf_mikey[POS_HDR_CSB_ID],
1470 { "CSB ID", "mikey.csb_id",
1471 FT_UINT32, BASE_HEX, NULL, 0x0,
1473 { &hf_mikey[POS_HDR_CS_COUNT],
1474 { "#CS", "mikey.cs_count",
1475 FT_UINT8, BASE_DEC, NULL, 0x0,
1477 { &hf_mikey[POS_HDR_CS_ID_MAP_TYPE],
1478 { "CS ID map type", "mikey.cs_id_map_type",
1479 FT_UINT8, BASE_DEC, VALS(cs_id_map_vals), 0x0,
1483 { &hf_mikey[POS_ID_SRTP],
1484 { "SRTP ID", "mikey.srtp_id",
1485 FT_NONE, BASE_NONE, NULL, 0x0,
1487 { &hf_mikey[POS_ID_SRTP_NO],
1488 { "Policy No", "mikey.srtp_id.policy_no",
1489 FT_UINT8, BASE_DEC, NULL, 0x0,
1491 { &hf_mikey[POS_ID_SRTP_SSRC],
1492 { "SSRC", "mikey.srtp_id.ssrc",
1493 FT_UINT32, BASE_HEX, NULL, 0x0,
1495 { &hf_mikey[POS_ID_SRTP_ROC],
1496 { "ROC", "mikey.srtp_id.roc",
1497 FT_UINT32, BASE_HEX, NULL, 0x0,
1500 /* Key Data Transport payload (KEMAC) */
1501 { &hf_mikey[POS_KEMAC_ENCR_ALG],
1502 { "Encr alg", "mikey.kemac.encr_alg",
1503 FT_UINT8, BASE_DEC, VALS(encr_alg_vals), 0x0,
1505 { &hf_mikey[POS_KEMAC_ENCR_DATA_LEN],
1506 { "Key data len", "mikey.kemac.key_data_len",
1507 FT_UINT16, BASE_DEC, NULL, 0x0,
1509 { &hf_mikey[POS_KEMAC_ENCR_DATA],
1510 { "Key data", "mikey.kemac.key_data",
1511 FT_BYTES, BASE_NONE, NULL, 0x0,
1513 { &hf_mikey[POS_KEMAC_MAC_ALG],
1514 { "Mac alg", "mikey.kemac.mac_alg",
1515 FT_UINT8, BASE_DEC, VALS(mac_alg_vals), 0x0,
1517 { &hf_mikey[POS_KEMAC_MAC],
1518 { "MAC", "mikey.kemac.mac",
1519 FT_BYTES, BASE_NONE, NULL, 0x0,
1522 /* Envelope Data payload (PKE) */
1523 { &hf_mikey[POS_PKE_C],
1524 { "C", "mikey.pke.c",
1525 FT_UINT16, BASE_DEC, VALS(pke_c_vals), 0xc000,
1527 { &hf_mikey[POS_PKE_DATA_LEN],
1528 { "Data len", "mikey.pke.len",
1529 FT_UINT16, BASE_DEC, NULL, 0x3fff,
1531 { &hf_mikey[POS_PKE_DATA],
1532 { "Data", "mikey.pke.data",
1533 FT_BYTES, BASE_NONE, NULL, 0x0,
1536 /* DH data payload (DH) */
1537 { &hf_mikey[POS_DH_GROUP],
1538 { "DH-Group", "mikey.dh.group",
1539 FT_UINT8, BASE_DEC, VALS(oakley_vals), 0x0,
1541 { &hf_mikey[POS_DH_VALUE],
1542 { "DH-Value", "mikey.dh.value",
1543 FT_BYTES, BASE_NONE, NULL, 0x0,
1545 { &hf_mikey[POS_DH_RESERV],
1546 { "Reserv", "mikey.dh.reserv",
1547 FT_UINT8, BASE_HEX, NULL, 0xf0,
1549 { &hf_mikey[POS_DH_KV],
1550 { "KV", "mikey.dh.kv",
1551 FT_UINT8, BASE_DEC, VALS(kv_vals), 0x0f,
1554 /* Signature payload (SIGN) */
1555 { &hf_mikey[POS_SIGN_S_TYPE],
1556 { "Signature type", "mikey.sign.type",
1557 FT_UINT16, BASE_DEC, VALS(sign_s_vals), 0xf000,
1559 { &hf_mikey[POS_SIGNATURE_LEN],
1560 { "Signature len", "mikey.sign.len",
1561 FT_UINT16, BASE_DEC, NULL, 0x0fff,
1563 { &hf_mikey[POS_SIGNATURE],
1564 { "Signature", "mikey.sign.data",
1565 FT_BYTES, BASE_NONE, NULL, 0x0,
1568 /* Timestamp payload (T) */
1569 { &hf_mikey[POS_TS_TYPE],
1570 { "TS type", "mikey.t.ts_type",
1571 FT_UINT8, BASE_DEC, VALS(ts_type_vals), 0x0,
1573 { &hf_mikey[POS_TS_NTP],
1574 { "NTP timestamp", "mikey.t.ntp",
1575 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
1578 { &hf_mikey[POS_PAYLOAD_STR],
1579 { "Payload", "mikey.payload",
1580 FT_STRING, BASE_NONE, NULL, 0x0,
1583 /* ID payload (ID) */
1584 { &hf_mikey[POS_ID_TYPE],
1585 { "ID type", "mikey.id.type",
1586 FT_UINT8, BASE_DEC, VALS(id_type_vals), 0x0,
1588 { &hf_mikey[POS_ID_LEN],
1589 { "ID len", "mikey.id.len",
1590 FT_UINT16, BASE_DEC, NULL, 0x0,
1592 { &hf_mikey[POS_ID],
1593 { "ID", "mikey.id.data",
1594 FT_STRING, BASE_NONE, NULL, 0x0,
1597 /* Certificate payload (CERT) */
1598 { &hf_mikey[POS_CERT_LEN],
1599 { "Certificate len", "mikey.cert.len",
1600 FT_UINT16, BASE_DEC, NULL, 0x0,
1602 { &hf_mikey[POS_CERT_TYPE],
1603 { "Certificate type", "mikey.cert.type",
1604 FT_UINT8, BASE_DEC, VALS(cert_type_vals), 0x0,
1606 { &hf_mikey[POS_CERTIFICATE],
1607 { "Certificate", "mikey.cert.data",
1608 FT_BYTES, BASE_NONE, NULL, 0x0,
1611 /* Ver msg payload (V) */
1612 { &hf_mikey[POS_V_AUTH_ALG],
1613 { "Auth alg", "mikey.v.auth_alg",
1614 FT_UINT8, BASE_DEC, VALS(mac_alg_vals), 0x0,
1616 { &hf_mikey[POS_V_DATA],
1617 { "Ver data", "mikey.v.ver_data",
1618 FT_BYTES, BASE_NONE, NULL, 0x0,
1621 /* Security Policy payload (SP) */
1622 { &hf_mikey[POS_SP_NO],
1623 { "Policy No", "mikey.sp.no",
1624 FT_UINT8, BASE_DEC, NULL, 0x0,
1626 { &hf_mikey[POS_SP_TYPE],
1627 { "Protocol type", "mikey.sp.proto_type",
1628 FT_UINT8, BASE_DEC, VALS(sp_prot_type_vals), 0x0,
1630 { &hf_mikey[POS_SP_PARAM_LEN],
1631 { "Policy param length", "mikey.sp.param_len",
1632 FT_UINT16, BASE_DEC, NULL, 0x0,
1635 /* Security Policy param */
1636 { &hf_mikey[POS_SP_PARAM_F],
1637 { "Policy param", "mikey.sp.param",
1638 FT_BYTES, BASE_NONE, NULL, 0x0,
1640 { &hf_mikey[POS_SP_PARAM_F_TYPE],
1641 { "Type", "mikey.sp.param.type",
1642 FT_UINT8, BASE_DEC, NULL, 0x0,
1644 { &hf_mikey[POS_SP_PARAM_F_LEN],
1645 { "Length", "mikey.sp.param.len",
1646 FT_UINT8, BASE_DEC, NULL, 0x0,
1648 { &hf_mikey[POS_SP_PARAM_F_VALUE],
1649 { "Value", "mikey.sp.patam.value",
1650 FT_BYTES, BASE_NONE, NULL, 0x0,
1653 /* SRTP policy param */
1654 { &hf_mikey_sp_param[SP_ENCR_ALG],
1655 { SP_TEXT_ENCR_ALG, "mikey.sp.encr_alg",
1656 FT_UINT8, BASE_DEC, VALS(sp_encr_alg_vals), 0x0,
1658 { &hf_mikey_sp_param[SP_ENCR_LEN],
1659 { SP_TEXT_ENCR_LEN, "mikey.sp.encr_len",
1660 FT_UINT8, BASE_DEC, NULL, 0x0,
1662 { &hf_mikey_sp_param[SP_AUTH_ALG],
1663 { SP_TEXT_AUTH_ALG, "mikey.sp.auth_alg",
1664 FT_UINT8, BASE_DEC, VALS(sp_auth_alg_vals), 0x0,
1666 { &hf_mikey_sp_param[SP_AUTH_KEY_LEN],
1667 { SP_TEXT_AUTH_KEY_LEN, "mikey.sp.auth_key_len",
1668 FT_UINT8, BASE_DEC, NULL, 0x0,
1670 { &hf_mikey_sp_param[SP_SALT_LEN],
1671 { SP_TEXT_SALT_LEN, "mikey.sp.salt_len",
1672 FT_UINT8, BASE_DEC, NULL, 0x0,
1674 { &hf_mikey_sp_param[SP_PRF],
1675 { SP_TEXT_PRF, "mikey.sp.prf",
1676 FT_UINT8, BASE_DEC, VALS(sp_prf_vals), 0x0,
1678 { &hf_mikey_sp_param[SP_KD_RATE],
1679 { SP_TEXT_KD_RATE, "mikey.sp.kd_rate",
1680 FT_UINT8, BASE_DEC, NULL, 0x0,
1682 { &hf_mikey_sp_param[SP_SRTP_ENCR],
1683 { SP_TEXT_SRTP_ENCR, "mikey.sp.srtp_encr",
1684 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1686 { &hf_mikey_sp_param[SP_SRTCP_ENCR],
1687 { SP_TEXT_SRTCP_ENCR, "mikey.sp.srtcp_encr",
1688 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1690 { &hf_mikey_sp_param[SP_FEC],
1691 { SP_TEXT_FEC, "mikey.sp.fec",
1692 FT_UINT8, BASE_DEC, VALS(sp_fec_vals), 0x0,
1694 { &hf_mikey_sp_param[SP_SRTP_AUTH],
1695 { SP_TEXT_SRTP_AUTH, "mikey.sp.srtp_auth",
1696 FT_UINT8, BASE_DEC, VALS(on_off_vals), 0x0,
1698 { &hf_mikey_sp_param[SP_AUTH_TAG_LEN],
1699 { SP_TEXT_AUTH_TAG_LEN, "mikey.sp.auth_tag_len",
1700 FT_UINT8, BASE_DEC, NULL, 0x0,
1702 { &hf_mikey_sp_param[SP_SRTP_PREFIX],
1703 { SP_TEXT_SRTP_PREFIX, "mikey.sp.srtp_prefix",
1704 FT_UINT8, BASE_DEC, NULL, 0x0,
1707 /* RAND payload (RAND) */
1708 { &hf_mikey[POS_RAND_LEN],
1709 { "RAND len", "mikey.rand.len",
1710 FT_UINT8, BASE_DEC, NULL, 0x0,
1712 { &hf_mikey[POS_RAND],
1713 { "RAND", "mikey.rand.data",
1714 FT_BYTES, BASE_NONE, NULL, 0x0,
1717 /* Error payload (ERR) */
1718 { &hf_mikey[POS_ERR_NO],
1719 { "Error no.", "mikey.err.no",
1720 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &err_vals_ext, 0x0,
1722 { &hf_mikey[POS_ERR_RESERVED],
1723 { "Reserved", "mikey.err.reserved",
1724 FT_BYTES, BASE_NONE, NULL, 0x0,
1728 { &hf_mikey[POS_ID_ROLE],
1729 { "ID role", "mikey.id.role",
1730 FT_UINT8, BASE_DEC, VALS(id_role_vals), 0x0,
1733 /* Key data sub-payload */
1734 { &hf_mikey[POS_KEY_DATA_TYPE],
1735 { "Type", "mikey.key.type",
1736 FT_UINT8, BASE_DEC, VALS(kd_vals), 0xf0,
1738 { &hf_mikey[POS_KEY_DATA_KV],
1739 { "KV", "mikey.key.kv",
1740 FT_UINT8, BASE_DEC, VALS(kv_vals), 0x0f,
1742 { &hf_mikey[POS_KEY_DATA_LEN],
1743 { "Key len", "mikey.key.data.len",
1744 FT_UINT16, BASE_DEC, NULL, 0x0,
1746 { &hf_mikey[POS_KEY_DATA],
1747 { "Key", "mikey.key.data",
1748 FT_BYTES, BASE_NONE, NULL, 0x0,
1750 { &hf_mikey[POS_KEY_SALT_LEN],
1751 { "Salt key len", "mikey.key.salt.len",
1752 FT_UINT16, BASE_DEC, NULL, 0x0,
1754 { &hf_mikey[POS_KEY_SALT],
1755 { "Salt key", "mikey.key.salt",
1756 FT_BYTES, BASE_NONE, NULL, 0x0,
1758 { &hf_mikey[POS_KEY_KV_FROM_LEN],
1759 { "Valid from len", "mikey.key.kv.from.len",
1760 FT_UINT8, BASE_DEC, NULL, 0x0,
1762 { &hf_mikey[POS_KEY_KV_FROM],
1763 { "Valid from", "mikey.key.kv.from",
1764 FT_BYTES, BASE_NONE, NULL, 0x0,
1766 { &hf_mikey[POS_KEY_KV_TO_LEN],
1767 { "Valid to len", "mikey.key.kv.to.len",
1768 FT_UINT8, BASE_DEC, NULL, 0x0,
1770 { &hf_mikey[POS_KEY_KV_TO],
1771 { "Valid to", "mikey.key.kv.to",
1772 FT_BYTES, BASE_NONE, NULL, 0x0,
1774 { &hf_mikey[POS_KEY_KV_SPI_LEN],
1775 { "Valid SPI len", "mikey.key.kv.spi.len",
1776 FT_UINT8, BASE_DEC, NULL, 0x0,
1778 { &hf_mikey[POS_KEY_KV_SPI],
1779 { "Valid SPI", "mikey.key.kv.spi",
1780 FT_BYTES, BASE_NONE, NULL, 0x0,
1783 /* General Extension payload (GENERAL_EXT) */
1784 { &hf_mikey[POS_GENERAL_EXT_TYPE],
1785 { "Extension type", "mikey.ext.type",
1786 FT_UINT8, BASE_DEC, VALS(genext_type_vals), 0x0,
1788 { &hf_mikey[POS_GENERAL_EXT_LEN],
1789 { "Length", "mikey.ext.len",
1790 FT_UINT16, BASE_DEC, NULL, 0x0,
1792 { &hf_mikey[POS_GENERAL_EXT_DATA],
1793 { "Data", "mikey.ext.data",
1794 FT_BYTES, BASE_NONE, NULL, 0x0,
1796 { &hf_mikey[POS_GENERAL_EXT_VALUE],
1797 { "Value", "mikey.ext.value",
1798 FT_STRING, BASE_NONE, NULL, 0x0,
1802 { &hf_mikey[POS_SAKKE_PARAMS],
1803 { "SAKKE params", "mikey.sakke.params",
1804 FT_UINT8, BASE_DEC, NULL, 0x0,
1806 { &hf_mikey[POS_SAKKE_ID_SCHEME],
1807 { "ID scheme", "mikey.sakke.idscheme",
1808 FT_UINT8, BASE_DEC, NULL, 0x0,
1810 { &hf_mikey[POS_SAKKE_LEN],
1811 { "SAKKE data length", "mikey.sakke.len",
1812 FT_UINT16, BASE_DEC, NULL, 0x0,
1814 { &hf_mikey[POS_SAKKE_DATA],
1815 { "SAKKE data", "mikey.sakke.data",
1816 FT_BYTES, BASE_NONE, NULL, 0x0,
1820 { &hf_mikey[POS_SP_PARAM],
1821 { "Policy param", "mikey.policy_param",
1822 FT_BYTES, BASE_NONE, NULL, 0x0,
1825 { &hf_mikey[POS_PAYLOAD],
1826 { "Payload", "mikey.payload",
1827 FT_BYTES, BASE_HEX, NULL, 0x0,
1832 /* Setup protocol subtree array */
1833 static gint *ett[] = {
1836 &ett_mikey_sp_param,
1841 module_t *mikey_module;
1843 /* Register the protocol name and description */
1844 proto_mikey = proto_register_protocol("Multimedia Internet KEYing",
1847 mikey_handle = new_register_dissector("mikey", dissect_mikey, proto_mikey);
1849 /* Required function calls to register the header fields and subtrees used */
1850 proto_register_field_array(proto_mikey, hf, array_length(hf));
1851 proto_register_subtree_array(ett, array_length(ett));
1853 /* Register our configuration options */
1854 mikey_module = prefs_register_protocol(proto_mikey, proto_reg_handoff_mikey);
1856 prefs_register_uint_preference(mikey_module, "udp.port", "MIKEY UDP Port",
1857 "Set the port for MIKEY messages (if other than the default of 2269)",
1858 10, &global_mikey_udp_port);
1860 prefs_register_uint_preference(mikey_module, "tcp.port", "MIKEY TCP Port",
1861 "Set the port for MIKEY messages (if other than the default of 2269)",
1862 10, &global_mikey_tcp_port);
1868 proto_reg_handoff_mikey(void)
1870 static guint mikey_tcp_port;
1871 static guint mikey_udp_port;
1872 static gboolean inited = FALSE;
1875 dissector_add_string("key_mgmt", "mikey", mikey_handle);
1878 dissector_delete_uint("udp.port", mikey_udp_port, mikey_handle);
1879 dissector_delete_uint("tcp.port", mikey_tcp_port, mikey_handle);
1882 dissector_add_uint("udp.port", global_mikey_udp_port, mikey_handle);
1883 dissector_add_uint("tcp.port", global_mikey_tcp_port, mikey_handle);
1885 mikey_udp_port = global_mikey_udp_port;
1886 mikey_tcp_port = global_mikey_tcp_port;
1889 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1894 * indent-tabs-mode: t
1897 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1898 * :indentSize=8:tabSize=8:noTabs=false: