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