Coverage Report

Created: 2026-06-30 07:22

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