Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-wai.c
Line
Count
Source
1
/* packet-wai.c
2
 * Routines for WAI packet dissection
3
 * Based on: WAPI ISO submission - ISO/IEC JTC 1 N 9880 [ref: 1]
4
 *           chapter "8.1.4 WAI protocol"
5
 *
6
 * Written by Lukasz Kotasa <lukasz.kotasa@tieto.com>
7
 *            Lukasz Suchy  <lukasz.suchy@tieto.com>
8
 * Copyright 2010, Tieto.
9
 *
10
 * Wireshark - Network traffic analyzer
11
 * By Gerald Combs <gerald@wireshark.org>
12
 * Copyright 1998 Gerald Combs
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 */
16
/* Protocol reference:
17
 * http://isotc.iso.org/livelink/livelink?func=ll&objId=8500308&objAction=Open&ei=nt-RTKe1IJKTjAeepLS8BQ&usg=AFQjCNEn8hlU_SfoAGkM-X48JL_BL8bptA&sig2=JOHNPrqgCMO4q0cWhAfkow
18
 * (chapter: 8.1.4. WAI protocol)
19
 */
20
21
22
#include "config.h"
23
24
#include <epan/packet.h>
25
#include <epan/etypes.h>
26
#include <epan/reassemble.h>
27
#include <epan/tfs.h>
28
#include <wsutil/array.h>
29
30
0
#define WAI_SUB_PRE_AUTHENTICATION      0x01    /* pre-authentication start */
31
0
#define WAI_SUB_STAKEY_REQ              0x02    /* STAKey request */
32
0
#define WAI_SUB_AUTH_ACTIVATION         0x03    /* authentication activation */
33
0
#define WAI_SUB_ACCESS_AUTH_REQ         0x04    /* access authentication request */
34
0
#define WAI_SUB_ACCESS_AUTH_RESP        0x05    /* access authentication response */
35
0
#define WAI_SUB_CERT_AUTH_REQ           0x06    /* certificate authentication request */
36
0
#define WAI_SUB_CERT_AUTH_RESP          0x07    /* certificate authentication response */
37
0
#define WAI_SUB_UNICAST_KEY_REQ         0x08    /* unicast key negotiation request */
38
0
#define WAI_SUB_UNICAST_KEY_RESP        0x09    /* unicast key negotiation response */
39
0
#define WAI_SUB_UNICAST_KEY_CONFIRM     0x0A    /* unicast key negotiation confirmation */
40
0
#define WAI_SUB_MULTICAST_ANNOUNCE      0x0B    /* multicast key/STAKey announcement */
41
0
#define WAI_SUB_MULTICAST_ANNOUNCE_RESP 0x0C    /* multicast key/STAKey announcement response */
42
43
16
#define FLAG_BIT0       0x01
44
16
#define FLAG_BIT1       0x02
45
16
#define FLAG_BIT2       0x04
46
16
#define FLAG_BIT3       0x08
47
16
#define FLAG_BIT4       0x10
48
16
#define FLAG_BIT5       0x20
49
16
#define FLAG_BIT6       0x40
50
16
#define FLAG_BIT7       0x80
51
52
void proto_register_wai(void);
53
void proto_reg_handoff_wai(void);
54
55
static reassembly_table wai_reassembly_table;
56
57
static dissector_handle_t wai_handle;
58
59
static int proto_wai;
60
61
static int hf_wai_version;
62
static int hf_wai_type;
63
static int hf_wai_subtype;
64
static int hf_wai_reserved;
65
static int hf_wai_length;
66
static int hf_wai_seq;
67
static int hf_wai_fragm_seq;
68
static int hf_wai_flag;
69
static int hf_wai_data;
70
static int hf_wai_bk_rekeying_flag;
71
static int hf_wai_preauthentication_flag;
72
static int hf_wai_certificate_flag;
73
static int hf_wai_optional_flag;
74
static int hf_wai_usk_rekeying_flag;
75
static int hf_wai_negotiation_flag;
76
static int hf_wai_revoking_flag;
77
static int hf_wai_reserved_flag;
78
static int hf_wai_attr_type;
79
static int hf_wai_cert;
80
static int hf_wai_cert_id;
81
static int hf_wai_cert_data;
82
static int hf_wai_cert_len;
83
static int hf_wai_addid;
84
static int hf_wai_ae_mac;
85
static int hf_wai_asue_mac;
86
static int hf_wai_bkid;
87
static int hf_wai_uskid;
88
static int hf_wai_wie;
89
static int hf_wai_message_auth_code;
90
static int hf_wai_mskid;
91
static int hf_wai_data_pack_num;
92
static int hf_wai_key_data;
93
static int hf_wai_key_data_len;
94
static int hf_wai_key_data_content;
95
static int hf_wai_key_ann_id;
96
static int hf_wai_auth_id;
97
static int hf_wai_identity;
98
static int hf_wai_identity_id;
99
static int hf_wai_identity_len;
100
static int hf_wai_identity_data;
101
static int hf_wai_ecdh;
102
static int hf_wai_ecdh_id;
103
static int hf_wai_ecdh_len;
104
static int hf_wai_ecdh_content;
105
static int hf_wai_counter;
106
static int hf_wai_sta_key_id;
107
static int hf_wai_challenge;
108
static int hf_wai_cert_ver;
109
static int hf_wai_nonce;
110
static int hf_wai_ver_res;
111
static int hf_wai_sign_alg;
112
static int hf_wai_hash_alg_id;
113
static int hf_wai_sign_alg_id;
114
static int hf_wai_param;
115
static int hf_wai_param_id;
116
static int hf_wai_param_content;
117
static int hf_wai_sign_val;
118
static int hf_wai_sign_content;
119
static int hf_wai_sign;
120
static int hf_wai_identity_list;
121
static int hf_wai_reserved_byte;
122
static int hf_wai_no_of_ids;
123
static int hf_wai_access_res;
124
static int hf_wai_fragments;
125
static int hf_wai_fragment;
126
static int hf_wai_fragment_overlap;
127
static int hf_wai_fragment_overlap_conflicts;
128
static int hf_wai_fragment_multiple_tails;
129
static int hf_wai_fragment_too_long_fragment;
130
static int hf_wai_fragment_error;
131
static int hf_wai_fragment_count;
132
static int hf_wai_reassembled_in;
133
static int hf_wai_reassembled_length;
134
135
static int ett_wai;
136
static int ett_wai_data;
137
static int ett_wai_flags;
138
static int ett_wai_certificate;
139
static int ett_wai_mac;
140
static int ett_wai_identity;
141
static int ett_wai_key_data;
142
static int ett_wai_ecdh_param;
143
static int ett_wai_certificate_verification;
144
static int ett_wai_identity_list;
145
static int ett_wai_sign;
146
static int ett_wai_sign_alg;
147
static int ett_wai_sign_val;
148
static int ett_wai_parameter;
149
static int ett_wai_fragment;
150
static int ett_wai_fragments;
151
152
static const value_string wai_type_names [] = {
153
    { 1, "WAI protocol package"},
154
    { 0, NULL }
155
};
156
157
static const value_string wai_attr_type_names [] = {
158
    { 1, "Signature"},
159
    { 2, "Certificate Authentication Result"},
160
    { 3, "Identity List"},
161
    { 0, NULL }
162
};
163
164
static const value_string wai_ver_res_names [] = {
165
    { 0, "Certificate is valid" },
166
    { 1, "Certificate issuer is unknown"},
167
    { 2, "Root certificate is untrusted"},
168
    { 3, "Certificate time is invalid"},
169
    { 4, "Certificate signature is invalid"},
170
    { 5, "Certificate is revoked"},
171
    { 6, "Certificate is not valid in its proposed usage"},
172
    { 7, "Certificate revocation state is unknown"},
173
    { 8, "Certificate has an unknown error"},
174
    { 0, NULL }
175
};
176
177
static const value_string wai_access_res_names [] = {
178
    { 0, "Success" },
179
    { 1, "Unidentified certificate"},
180
    { 2, "Certificate Error"},
181
    { 3, "Prohibited by AE"},
182
    { 0, NULL }
183
};
184
185
static const fragment_items wai_frag_items = {
186
    /* Fragment subtrees */
187
    &ett_wai_fragment,
188
    &ett_wai_fragments,
189
    /* Fragment fields */
190
    &hf_wai_fragments,
191
    &hf_wai_fragment,
192
    &hf_wai_fragment_overlap,
193
    &hf_wai_fragment_overlap_conflicts,
194
    &hf_wai_fragment_multiple_tails,
195
    &hf_wai_fragment_too_long_fragment,
196
    &hf_wai_fragment_error,
197
    &hf_wai_fragment_count,
198
    /* Reassembled in field */
199
    &hf_wai_reassembled_in,
200
    /* Reassembled length field */
201
    &hf_wai_reassembled_length,
202
    /* Reassembled data field */
203
    NULL,
204
    /* Tag */
205
    "Message fragments"
206
};
207
208
static const value_string wai_subtype_names[] = {
209
    {  WAI_SUB_PRE_AUTHENTICATION,      "Pre-Authentication start" },
210
    {  WAI_SUB_STAKEY_REQ,              "STAKey request" },
211
    {  WAI_SUB_AUTH_ACTIVATION,         "Authentication activation" },
212
    {  WAI_SUB_ACCESS_AUTH_REQ,         "Access authentication request" },
213
    {  WAI_SUB_ACCESS_AUTH_RESP,        "Access authentication response" },
214
    {  WAI_SUB_CERT_AUTH_REQ,           "Certificate authentication request" },
215
    {  WAI_SUB_CERT_AUTH_RESP,          "Certificate authentication response" },
216
    {  WAI_SUB_UNICAST_KEY_REQ,         "Unicast key negotiation request" },
217
    {  WAI_SUB_UNICAST_KEY_RESP,        "Unicast key negotiation response" },
218
    {  WAI_SUB_UNICAST_KEY_CONFIRM,     "Unicast key negotiation confirmation" },
219
    {  WAI_SUB_MULTICAST_ANNOUNCE,      "Multicast key/STAKey announcement" },
220
    {  WAI_SUB_MULTICAST_ANNOUNCE_RESP, "Multicast key/STAKey announcement response" },
221
    { 0, NULL }
222
};
223
static value_string_ext wai_subtype_names_ext = VALUE_STRING_EXT_INIT(wai_subtype_names);
224
225
static const true_false_string wai_bk_rekeying_flag = {
226
    "Packet is a BK rekeying packet",
227
    "Packet is not a BK rekeying packet"
228
};
229
230
static const true_false_string wai_preauthentication_flag = {
231
    "Packet is a pre-authentication packet",
232
    "Packet is not a pre-authentication packet"
233
};
234
235
static const true_false_string  wai_certificate_flag = {
236
    "STA requires to verify the peers certificate",
237
    "STA doesn't require to verify the peers certificate"
238
};
239
240
static const true_false_string  wai_optional_flag = {
241
    "There are some optional fields in packet",
242
    "No optional fields in packet"
243
};
244
245
static const true_false_string  wai_usk_rekeying_flag = {
246
    "Packet is a USK rekeying packet",
247
    "Packet is not a USK rekeying packet"
248
};
249
250
static const true_false_string  wai_negotiation_flag = {
251
    "Packet is a STAKey negotiation packet",
252
    "Packet is not a STAKey negotiation packet"
253
};
254
255
static const true_false_string  wai_revoking_flag = {
256
    "STA delete a STAKey",
257
    "STA doesn't delete a STAKey"
258
};
259
260
static const true_false_string  wai_reserved_flag = {
261
    "reserved 1",
262
    "reserved 0"
263
};
264
265
static void
266
dissect_flag(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
267
0
{
268
0
    proto_item *flag_item;
269
0
    proto_tree *flag_tree;
270
271
0
    flag_item = proto_tree_add_item(tree, hf_wai_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
272
0
    flag_tree = proto_item_add_subtree (flag_item, ett_wai_flags);
273
274
0
    proto_tree_add_item (flag_tree, hf_wai_bk_rekeying_flag,       tvb, offset, 1, ENC_BIG_ENDIAN);
275
0
    proto_tree_add_item (flag_tree, hf_wai_preauthentication_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
276
0
    proto_tree_add_item (flag_tree, hf_wai_certificate_flag,       tvb, offset, 1, ENC_BIG_ENDIAN);
277
0
    proto_tree_add_item (flag_tree, hf_wai_optional_flag,          tvb, offset, 1, ENC_BIG_ENDIAN);
278
0
    proto_tree_add_item (flag_tree, hf_wai_usk_rekeying_flag,      tvb, offset, 1, ENC_BIG_ENDIAN);
279
0
    proto_tree_add_item (flag_tree, hf_wai_negotiation_flag,       tvb, offset, 1, ENC_BIG_ENDIAN);
280
0
    proto_tree_add_item (flag_tree, hf_wai_revoking_flag,          tvb, offset, 1, ENC_BIG_ENDIAN);
281
0
    proto_tree_add_item (flag_tree, hf_wai_reserved_flag,          tvb, offset, 1, ENC_BIG_ENDIAN);
282
0
}
283
284
inline static void
285
dissect_bkid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
286
0
{
287
0
    proto_tree_add_item(tree, hf_wai_bkid, tvb, offset, 16, ENC_NA);
288
0
}
289
290
inline static void
291
dissect_uskid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
292
0
{
293
0
    proto_tree_add_item(tree, hf_wai_uskid, tvb, offset, 1, ENC_NA);
294
0
}
295
296
inline static void dissect_wie(tvbuff_t *tvb, unsigned offset, unsigned length, proto_tree *tree)
297
0
{
298
0
    proto_tree_add_item(tree, hf_wai_wie, tvb, offset, length, ENC_NA);
299
0
}
300
301
inline static void
302
dissect_message_auth_code(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
303
0
{
304
0
    proto_tree_add_item(tree, hf_wai_message_auth_code, tvb, offset, 20, ENC_NA);
305
0
}
306
307
inline static void
308
dissect_mskid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
309
0
{
310
0
    proto_tree_add_item(tree, hf_wai_mskid, tvb, offset, 1, ENC_NA);
311
0
}
312
313
inline static void
314
dissect_key_announcement_identifier(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
315
0
{
316
0
    proto_tree_add_item(tree, hf_wai_key_ann_id, tvb, offset, 16, ENC_NA);
317
0
}
318
319
inline static void
320
dissect_counter(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
321
0
{
322
0
    proto_tree_add_item(tree, hf_wai_counter, tvb, offset, 16, ENC_NA);
323
0
}
324
325
inline static void
326
dissect_authentication_id(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
327
0
{
328
0
    proto_tree_add_item(tree, hf_wai_auth_id, tvb, offset, 32, ENC_NA);
329
0
}
330
331
static void
332
dissect_addid(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
333
0
{
334
0
    proto_item *mac_item;
335
0
    proto_tree *mac_tree;
336
337
0
    mac_item = proto_tree_add_string(tree, hf_wai_addid, tvb, offset, 12, "AE MAC and ASUE MAC addresses");
338
339
0
    mac_tree = proto_item_add_subtree(mac_item, ett_wai_mac);
340
0
    proto_tree_add_item(mac_tree, hf_wai_ae_mac,   tvb, offset,   6, ENC_NA);
341
0
    proto_tree_add_item(mac_tree, hf_wai_asue_mac, tvb, offset+6, 6, ENC_NA);
342
0
}
343
344
static uint16_t
345
dissect_identity(tvbuff_t * tvb, const uint16_t offset, proto_tree * tree,
346
   const char * const label)
347
0
{
348
0
    proto_tree *id_tree;
349
0
    proto_item *id_item;
350
0
    uint16_t    length;
351
352
0
    length = tvb_get_ntohs(tvb, offset+2);
353
354
0
    id_item = proto_tree_add_item(tree, hf_wai_identity, tvb, offset, length+4, ENC_NA);
355
0
    id_tree = proto_item_add_subtree(id_item, ett_wai_identity);
356
0
    proto_item_set_text(id_item, "%sIdentity", ((label==NULL)?"":label));
357
0
    proto_tree_add_item(id_tree, hf_wai_identity_id,   tvb, offset,   2, ENC_BIG_ENDIAN);
358
0
    proto_tree_add_item(id_tree, hf_wai_identity_len,  tvb, offset+2, 2, ENC_BIG_ENDIAN);
359
0
    proto_tree_add_item(id_tree, hf_wai_identity_data, tvb, offset+4, length, ENC_NA);
360
361
0
    return length + 4;
362
0
}
363
364
static int16_t
365
dissect_certificate(tvbuff_t * tvb, const int offset, proto_tree * tree,
366
                    const char * const label)
367
0
{
368
0
    proto_item  *certificate_item;
369
0
    proto_tree  *certificate_tree;
370
0
    proto_item  *id_item;
371
0
    uint16_t     length;
372
0
    uint16_t     id;
373
0
    const char *id_name = "unknown";
374
375
0
    id = tvb_get_ntohs(tvb, offset);
376
377
0
    if (id == 1) {
378
0
        id_name = "X.509 v3";
379
0
    } else if (id == 2){
380
0
        id_name = "GBW";
381
0
    }
382
383
0
    length = tvb_get_ntohs(tvb, offset+2);
384
385
0
    certificate_item = proto_tree_add_item(tree, hf_wai_cert, tvb, offset, length+4, ENC_NA);
386
0
    proto_item_set_text(certificate_item, "%sCertificate",  ((label==NULL)?"":label));
387
0
    certificate_tree = proto_item_add_subtree(certificate_item, ett_wai_certificate);
388
389
0
    id_item = proto_tree_add_item(certificate_tree, hf_wai_cert_id, tvb, offset, 2, ENC_BIG_ENDIAN);
390
0
    proto_item_set_text(id_item, "Certificate Identifier: %s (%#x)", id_name, id);
391
0
    proto_tree_add_item(certificate_tree, hf_wai_cert_len,  tvb, offset+2, 2, ENC_BIG_ENDIAN);
392
0
    proto_tree_add_item(certificate_tree, hf_wai_cert_data, tvb, offset+4, length, ENC_NA);
393
394
0
    return length + 4;
395
0
}
396
397
static uint16_t
398
dissect_ecdh_parameter(tvbuff_t * tvb, const int offset, proto_tree * tree)
399
0
{
400
0
    proto_item  *ecdh_item;
401
0
    proto_tree  *ecdh_tree;
402
0
    proto_item  *ecdh_id_item;
403
0
    uint8_t      ecdh_id;
404
0
    uint16_t     ecdh_len;
405
0
    const char *id_name = "unknown";
406
407
0
    ecdh_id = tvb_get_uint8(tvb, offset);
408
409
0
    if (ecdh_id == 1) {
410
0
        id_name = "OID";
411
0
    } else if (ecdh_id == 2) {
412
0
        id_name = "Detailed parameter";
413
0
    }
414
415
0
    ecdh_len = tvb_get_ntohs(tvb, offset+1);
416
417
0
    ecdh_item = proto_tree_add_item(tree, hf_wai_ecdh,  tvb, offset, ecdh_len+3, ENC_NA);
418
0
    ecdh_tree = proto_item_add_subtree(ecdh_item, ett_wai_ecdh_param);
419
0
    ecdh_id_item = proto_tree_add_item(ecdh_tree, hf_wai_ecdh_id, tvb, offset, 1, ENC_BIG_ENDIAN);
420
0
    proto_item_set_text(ecdh_id_item, "ID: %s (%#x)", id_name, ecdh_id);
421
0
    proto_tree_add_item(ecdh_tree, hf_wai_ecdh_len,     tvb, offset+1, 2, ENC_BIG_ENDIAN);
422
0
    proto_tree_add_item(ecdh_tree, hf_wai_ecdh_content, tvb, offset+3, ecdh_len, ENC_NA);
423
424
0
    return ecdh_len + 3;
425
0
}
426
427
static uint16_t
428
dissect_challenge(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char * const label)
429
0
{
430
0
    proto_item    *challenge_item;
431
0
    const uint16_t challenge_length = 32;
432
433
0
    challenge_item = proto_tree_add_item(tree, hf_wai_challenge, tvb, offset, 32, ENC_NA);
434
0
    proto_item_append_text(challenge_item, "(%schallenge)",  ((label==NULL)?"":label));
435
436
0
    return challenge_length;
437
0
}
438
439
static uint16_t
440
dissect_key_data(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *const label)
441
0
{
442
0
    proto_item  *key_data_item;
443
0
    proto_tree  *key_data_tree;
444
0
    uint8_t     length;
445
446
0
    length = tvb_get_uint8(tvb, offset);
447
448
0
    key_data_item = proto_tree_add_item(tree, hf_wai_key_data, tvb, offset, length+1, ENC_NA);
449
0
    proto_item_set_text(key_data_item, "%sKey Data", ((label==NULL)?"":label));
450
0
    key_data_tree = proto_item_add_subtree(key_data_item, ett_wai_key_data);
451
0
    proto_tree_add_item(key_data_tree, hf_wai_key_data_len, tvb, offset, 1, ENC_BIG_ENDIAN);
452
453
0
    if (length > 0) {
454
0
        proto_tree_add_item(key_data_tree, hf_wai_key_data_content, tvb, offset+1, length, ENC_NA);
455
0
    }
456
457
0
    return length + 1;
458
0
}
459
460
static unsigned
461
dissect_multiple_certificate(tvbuff_t * tvb, unsigned offset, proto_tree *tree)
462
0
{
463
0
    proto_item *multicert_item;
464
0
    proto_tree *multicert_tree;
465
0
    proto_item *nonce_1_item;
466
0
    proto_item *nonce_2_item;
467
0
    unsigned    length;
468
469
0
    length = tvb_get_ntohs(tvb, offset+1);
470
0
    multicert_item = proto_tree_add_item(tree, hf_wai_cert_ver, tvb, offset, length+3, ENC_NA);
471
0
    multicert_tree = proto_item_add_subtree(multicert_item, ett_wai_certificate_verification);
472
0
    proto_tree_add_item(multicert_tree, hf_wai_attr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
473
0
    offset += 1;
474
0
    proto_tree_add_item(multicert_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
475
0
    offset += 2;
476
0
    nonce_1_item = proto_tree_add_item(multicert_tree, hf_wai_nonce, tvb, offset, 32, ENC_NA);
477
0
    offset += 32;
478
0
    proto_item_append_text(nonce_1_item, " 1");
479
0
    nonce_2_item = proto_tree_add_item(multicert_tree, hf_wai_nonce, tvb, offset, 32, ENC_NA);
480
0
    offset += 32;
481
0
    proto_item_append_text(nonce_2_item, " 2");
482
0
    proto_tree_add_item(multicert_tree, hf_wai_ver_res, tvb, offset, 1, ENC_BIG_ENDIAN);
483
0
    offset += 1;
484
0
    offset += dissect_certificate(tvb, offset, multicert_tree, "1 ");
485
0
    proto_tree_add_item(multicert_tree, hf_wai_ver_res, tvb, offset, 1, ENC_BIG_ENDIAN);
486
0
    offset += 1;
487
0
    dissect_certificate(tvb, offset, multicert_tree, "2 ");
488
489
0
    return length + 3;
490
0
}
491
492
static unsigned
493
dissect_identity_list(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
494
0
{
495
0
    proto_item *id_list_item;
496
0
    proto_tree *id_list_tree;
497
0
    uint16_t    length;
498
0
    uint16_t    no_of_ids;
499
0
    uint16_t    i;
500
501
0
    length = tvb_get_ntohs(tvb, offset+1);
502
0
    id_list_item = proto_tree_add_item(tree, hf_wai_identity_list, tvb, offset, length+3, ENC_NA);
503
0
    id_list_tree = proto_item_add_subtree(id_list_item, ett_wai_identity_list);
504
0
    proto_tree_add_item(id_list_tree, hf_wai_attr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
505
0
    offset += 1;
506
0
    proto_tree_add_item(id_list_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
507
0
    offset += 2;
508
0
    proto_tree_add_item(id_list_tree, hf_wai_reserved_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
509
0
    offset += 1;
510
0
    proto_tree_add_item_ret_uint16(id_list_tree, hf_wai_no_of_ids, tvb, offset, 2, ENC_BIG_ENDIAN, &no_of_ids);
511
0
    offset += 2;
512
513
0
    for(i=0; i < no_of_ids; i++) {
514
0
        char number[6] = {0};
515
516
0
        snprintf(number, 6, "%d", i);
517
0
        offset += dissect_identity(tvb, offset, id_list_tree, number);
518
0
    }
519
520
0
    return length + 3;
521
0
}
522
523
static uint16_t
524
dissect_signature_algorithm(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
525
0
{
526
0
    proto_item *sa_item;
527
0
    proto_tree *sa_tree;
528
0
    proto_item *param_item;
529
0
    proto_tree *param_tree;
530
0
    proto_item *alg_name_item;
531
0
    proto_item *sig_name_item;
532
0
    uint16_t    length;
533
0
    uint8_t     alg_id;
534
0
    uint8_t     sig_id;
535
0
    uint16_t    param_len;
536
537
0
    length  = tvb_get_ntohs(tvb, offset);
538
539
0
    sa_item = proto_tree_add_item(tree, hf_wai_sign_alg, tvb, offset,  length+2, ENC_NA);
540
0
    sa_tree = proto_item_add_subtree(sa_item, ett_wai_sign_alg);
541
542
0
    proto_tree_add_item(sa_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
543
0
    offset += 2;
544
545
0
    alg_name_item = proto_tree_add_item_ret_uint8(sa_tree, hf_wai_hash_alg_id, tvb, offset, 1, ENC_BIG_ENDIAN, &alg_id);
546
547
0
    if (1 == alg_id) {
548
0
        proto_item_set_text(alg_name_item, "Algorithm Identifier: SHA-256  (0x01)");
549
0
    }
550
551
0
    offset += 1;
552
0
    sig_name_item = proto_tree_add_item_ret_uint8(sa_tree, hf_wai_sign_alg_id, tvb, offset, 1, ENC_BIG_ENDIAN, &sig_id);
553
554
0
    if (1 == sig_id) {
555
0
        proto_item_set_text(sig_name_item, "Signature Algorithm Identifier: ECDSA-192  (0x01)");
556
0
    }
557
558
0
    offset += 1;
559
0
    param_len  = tvb_get_ntohs(tvb, offset+1);
560
0
    param_item = proto_tree_add_item(sa_tree, hf_wai_param, tvb, offset,  param_len+3, ENC_NA);
561
0
    param_tree = proto_item_add_subtree(param_item, ett_wai_parameter);
562
0
    proto_tree_add_item(param_tree, hf_wai_param_id, tvb, offset, 1, ENC_NA);
563
0
    offset += 1;
564
0
    proto_tree_add_item(param_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
565
0
    offset += 2;
566
0
    proto_tree_add_item(param_tree, hf_wai_param_content, tvb, offset, param_len, ENC_NA);
567
568
0
    return length + 2;
569
0
}
570
571
static uint16_t
572
dissect_signature_value(tvbuff_t *tvb, unsigned offset, proto_tree *tree)
573
0
{
574
0
    proto_item *sv_item;
575
0
    proto_tree *sv_tree;
576
0
    uint16_t    length = 0;
577
578
0
    length  = tvb_get_ntohs(tvb, offset);
579
580
0
    sv_item = proto_tree_add_item(tree, hf_wai_sign_val, tvb, offset,  length+2, ENC_NA);
581
0
    sv_tree = proto_item_add_subtree(sv_item, ett_wai_sign_val);
582
583
0
    proto_tree_add_item(sv_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
584
0
    offset += 2;
585
586
0
    proto_tree_add_item(sv_tree, hf_wai_sign_content, tvb, offset, length, ENC_NA);
587
588
0
    return length + 2;
589
0
}
590
591
static uint16_t
592
dissect_signature(tvbuff_t *tvb, unsigned offset, proto_tree *tree, const char *const label)
593
0
{
594
0
    proto_item *ss_item;
595
0
    proto_tree *ss_tree;
596
0
    unsigned    length = 0;
597
598
0
    length  = tvb_get_ntohs(tvb, offset+1);
599
600
0
    ss_item = proto_tree_add_item(tree, hf_wai_sign, tvb, offset, length+3, ENC_NA);
601
0
    proto_item_set_text(ss_item, "%s", (label==NULL)?"Signature":label);
602
0
    ss_tree = proto_item_add_subtree(ss_item, ett_wai_sign);
603
604
0
    proto_tree_add_item(ss_tree, hf_wai_attr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
605
0
    offset += 1;
606
607
0
    proto_tree_add_item(ss_tree, hf_wai_length, tvb, offset, 2, ENC_BIG_ENDIAN);
608
0
    offset += 2;
609
610
0
    offset += dissect_identity(tvb, offset, ss_tree, NULL);
611
0
    offset += dissect_signature_algorithm(tvb, offset, ss_tree);
612
0
    dissect_signature_value(tvb, offset, ss_tree);
613
614
0
    return length + 3;
615
0
}
616
617
618
static void
619
dissect_wai_data(tvbuff_t *tvb, proto_tree *tree, uint8_t subtype, uint16_t lenx)
620
0
{
621
0
    proto_item  *data_item;
622
0
    proto_tree  *data_tree;
623
0
    const char *type_name;
624
625
0
    data_item = proto_tree_add_item(tree, hf_wai_data, tvb, 0, lenx, ENC_NA);
626
0
    data_tree = proto_item_add_subtree (data_item, ett_wai_data);
627
628
0
    type_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type");
629
630
0
    proto_item_set_text(data_item, "%s data (%d bytes)", type_name, lenx);
631
632
0
    switch (subtype) {
633
0
        case WAI_SUB_PRE_AUTHENTICATION:
634
0
        {
635
            /* Chapter 8.1.4.6 Preauthentication [ref: 1] */
636
0
            dissect_flag(tvb, 0, data_tree);
637
0
            dissect_uskid(tvb, 1, data_tree);
638
0
            dissect_addid(tvb, 2, data_tree);
639
0
            dissect_counter(tvb, 14, data_tree);
640
0
            dissect_message_auth_code(tvb, 30, data_tree);
641
0
            break;
642
0
        }
643
0
        case WAI_SUB_STAKEY_REQ:
644
0
        {
645
            /* Chapter 8.1.4.5 STAKey Establishment procedure [ref: 1] */
646
0
            dissect_flag(tvb, 0, data_tree);
647
0
            proto_tree_add_item(data_tree, hf_wai_sta_key_id, tvb, 1, 1, ENC_BIG_ENDIAN);
648
0
            dissect_uskid(tvb, 2, data_tree);
649
0
            dissect_addid(tvb, 3, data_tree);
650
0
            dissect_counter(tvb, 15, data_tree);
651
0
            dissect_message_auth_code(tvb, 31, data_tree);
652
0
            break;
653
0
        }
654
0
        case WAI_SUB_AUTH_ACTIVATION:
655
0
        {
656
            /* Chapter 8.1.4.2.1 WAI Authentication Activation  [ref: 1] */
657
0
            uint16_t offset = 0;
658
659
0
            dissect_flag(tvb, offset, data_tree);
660
0
            offset += 1;
661
0
            dissect_authentication_id(tvb, offset, data_tree);
662
0
            offset += 32;
663
0
            offset += dissect_identity(tvb, offset, data_tree, "Local ASU ");
664
0
            offset += dissect_certificate(tvb, offset, data_tree, "STE AE ");
665
0
            dissect_ecdh_parameter(tvb, offset, data_tree);
666
0
            break;
667
0
        }
668
0
        case WAI_SUB_ACCESS_AUTH_REQ:
669
0
        {
670
            /* Chapter 8.1.4.2.2 Access WAI Authentication Request  [ref: 1] */
671
0
            uint16_t offset = 0;
672
0
            uint8_t optional_field;
673
674
0
            optional_field = tvb_get_uint8(tvb, 0) & FLAG_BIT3;
675
676
0
            dissect_flag(tvb, offset, data_tree);
677
0
            offset += 1;
678
0
            dissect_authentication_id(tvb, offset, data_tree);
679
0
            offset += 32;
680
0
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
681
0
            offset += dissect_key_data(tvb, offset, data_tree, "ASUE ");
682
0
            offset += dissect_identity(tvb, offset, data_tree, "STA AE ");
683
0
            offset += dissect_certificate(tvb, offset, data_tree, "STA ASUE ");
684
0
            offset += dissect_ecdh_parameter(tvb, offset, data_tree);
685
686
0
            if (optional_field) {
687
0
                offset += dissect_identity_list(tvb, offset, data_tree);
688
0
            }
689
690
0
            dissect_signature(tvb, offset, data_tree, "ASUE Signature");
691
0
            break;
692
0
        }
693
0
        case WAI_SUB_ACCESS_AUTH_RESP:
694
0
        {
695
            /* Chapter 8.1.4.2.5 Access WAI Authentication Response  [ref: 1] */
696
0
            uint16_t offset = 0;
697
0
            uint8_t optional_field;
698
699
0
            optional_field = tvb_get_uint8(tvb, 0) & FLAG_BIT3;
700
701
0
            dissect_flag(tvb, offset, data_tree);
702
0
            offset += 1;
703
0
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
704
0
            offset += dissect_challenge(tvb, offset, data_tree, "AE ");
705
0
            proto_tree_add_item(data_tree, hf_wai_access_res, tvb, offset, 1, ENC_BIG_ENDIAN);
706
0
            offset += 1;
707
0
            offset += dissect_key_data(tvb, offset, data_tree, "ASUE ");
708
0
            offset += dissect_key_data(tvb, offset, data_tree, "AE ");
709
0
            offset += dissect_identity(tvb, offset, data_tree, "STA AE ");
710
0
            offset += dissect_identity(tvb, offset, data_tree, "STA ASUE ");
711
712
0
            if (optional_field) {
713
0
                unsigned  length = 0;
714
0
                offset += dissect_multiple_certificate(tvb, offset, data_tree);
715
0
                offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE");
716
0
                length  = tvb_get_ntohs(tvb, offset+1);
717
0
                if (length + 3 + offset + 1 < lenx)
718
0
                    offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE");
719
0
            }
720
721
0
            dissect_signature(tvb, offset, data_tree, "AE Signature");
722
0
            break;
723
0
        }
724
0
        case WAI_SUB_CERT_AUTH_REQ:
725
0
        {
726
            /* Chapter 8.1.4.2.3 Certificate Authentication Request  [ref: 1] */
727
0
            uint16_t offset = 0;
728
0
            uint8_t optional_field;
729
730
0
            optional_field = tvb_get_uint8(tvb, 0) & FLAG_BIT3;
731
732
0
            dissect_addid(tvb, offset, data_tree);
733
0
            offset += 12;
734
0
            offset += dissect_challenge(tvb, offset, data_tree, "AE ");
735
0
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
736
0
            offset += dissect_certificate(tvb, offset, data_tree, "STE ASUE ");
737
0
            offset += dissect_certificate(tvb, offset, data_tree, "STE AE ");
738
0
            if (optional_field) {
739
0
                dissect_identity_list(tvb, offset, data_tree);
740
0
            }
741
0
            break;
742
0
        }
743
0
        case WAI_SUB_CERT_AUTH_RESP:
744
0
        {
745
            /* Chapter 8.1.4.2.4 Certificate Authentication Response  [ref: 1] */
746
0
            uint16_t offset = 0;
747
748
0
            dissect_addid(tvb, offset, data_tree);
749
0
            offset += 12;
750
0
            offset += dissect_multiple_certificate(tvb, offset, data_tree);
751
0
            offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE");
752
0
            if (offset < lenx)
753
0
                dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE");
754
0
            break;
755
0
        }
756
0
        case WAI_SUB_UNICAST_KEY_REQ:
757
0
        {
758
            /* Chapter 8.1.4.3.1 Unicast Key Negotiation Request [ref: 1] */
759
0
            dissect_flag(tvb, 0, data_tree);
760
0
            dissect_bkid(tvb, 1, data_tree);
761
0
            dissect_uskid(tvb, 17, data_tree);
762
0
            dissect_addid(tvb, 18, data_tree);
763
0
            dissect_challenge(tvb, 30, data_tree , "AE ");
764
0
            break;
765
0
        }
766
0
        case WAI_SUB_UNICAST_KEY_RESP:
767
0
        {
768
            /* Chapter 8.1.4.3.2 Unicast Key Negotiation Response [ref: 1] */
769
0
            tvbuff_t *next_tvb;
770
0
            unsigned  length = 0;
771
772
0
            dissect_flag(tvb, 0, data_tree);
773
0
            dissect_bkid(tvb, 1, data_tree);
774
0
            dissect_uskid(tvb, 17, data_tree);
775
0
            dissect_addid(tvb, 18, data_tree);
776
0
            dissect_challenge(tvb, 30, data_tree, "ASUE ");
777
0
            dissect_challenge(tvb, 62, data_tree, "AE ");
778
779
0
            next_tvb = tvb_new_subset_remaining(tvb, 96);
780
0
            length = tvb_reported_length(next_tvb);
781
782
0
            dissect_wie(next_tvb, 0, length-20, data_tree);
783
0
            dissect_message_auth_code(next_tvb, length-20, data_tree);
784
0
            break;
785
0
        }
786
0
        case WAI_SUB_UNICAST_KEY_CONFIRM:
787
0
        {
788
            /* Chapter 8.1.4.3.3 Unicast Key Negotiation Confirmation [ref: 1] */
789
0
            tvbuff_t *next_tvb;
790
0
            unsigned  length = 0;
791
792
0
            dissect_flag(tvb, 0, data_tree);
793
0
            dissect_bkid(tvb, 1, data_tree);
794
0
            dissect_uskid(tvb, 17, data_tree);
795
0
            dissect_addid(tvb, 18, data_tree);
796
0
            dissect_challenge(tvb, 30, data_tree, "ASUE ");
797
798
0
            next_tvb = tvb_new_subset_remaining(tvb, 62);
799
0
            length = tvb_reported_length(next_tvb);
800
801
0
            dissect_wie(next_tvb, 0, length-20, data_tree);
802
0
            dissect_message_auth_code(next_tvb, length-20, data_tree);
803
0
            break;
804
0
        }
805
0
        case WAI_SUB_MULTICAST_ANNOUNCE:
806
0
        {
807
            /* Chapter 8.1.4.4.1 Multicast Key/STAKey Announcement [ref: 1] */
808
0
            uint16_t offset = 0;
809
810
0
            dissect_flag(tvb, offset, data_tree);
811
0
            offset += 1;
812
0
            dissect_mskid(tvb, offset, data_tree);
813
0
            offset += 1;
814
0
            dissect_uskid(tvb, offset, data_tree);
815
0
            offset += 1;
816
0
            dissect_addid(tvb, offset, data_tree);
817
0
            offset += 12;
818
0
            proto_tree_add_item(data_tree, hf_wai_data_pack_num, tvb, offset, 16, ENC_NA);
819
0
            offset += 16;
820
0
            dissect_key_announcement_identifier(tvb, offset, data_tree);
821
0
            offset += 16;
822
0
            offset += dissect_key_data(tvb, offset, data_tree, NULL);
823
0
            dissect_message_auth_code(tvb, offset, data_tree);
824
0
            break;
825
0
        }
826
0
        case WAI_SUB_MULTICAST_ANNOUNCE_RESP:
827
0
        {
828
            /* Chapter 8.1.4.4.2 Multicast Key/STAKey Announcement Response [ref: 1] */
829
0
            dissect_flag(tvb,  0, data_tree);
830
0
            dissect_mskid(tvb, 1, data_tree);
831
0
            dissect_uskid(tvb, 2, data_tree);
832
0
            dissect_addid(tvb, 3, data_tree);
833
0
            dissect_key_announcement_identifier(tvb, 15, data_tree);
834
0
            dissect_message_auth_code(tvb, 31, data_tree);
835
0
            break;
836
0
        }
837
0
        default:
838
0
            break;
839
0
    }
840
0
}
841
842
static int
843
dissect_wai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
844
7
{
845
/* Format of WAPI protocol packet in WAI authentication system
846
847
0      2      3         4         6         8        10        11      12
848
-------------------------------------------------------------------------------
849
| Ver. | Type | Subtype | Reserved | Length | packet  |  fragm. | flag | data |
850
|                                           | seq. no | seq. no |             |
851
|-----------------------------------------------------------------------------|
852
Figure 18 from [ref:1]
853
*/
854
14
#define WAI_MESSAGE_LENGTH 12   /*Length of all fields without 'Data' field*/
855
7
#define WAI_DATA_OFFSET    WAI_MESSAGE_LENGTH
856
7
    uint16_t       version;
857
7
    uint8_t        subtype;
858
7
    uint16_t       length;
859
7
    uint16_t       packet_num;
860
7
    uint8_t        fragment_num;
861
7
    uint8_t        flags;
862
7
    fragment_head *frag_msg;
863
7
    proto_tree    *wai_tree     = NULL;
864
7
    tvbuff_t      *next_tvb;
865
7
    tvbuff_t      *new_tvb;
866
7
    const char    *subtype_name = "Unknown type";
867
868
7
    length = tvb_get_ntohs(tvb, 6)-WAI_MESSAGE_LENGTH;
869
7
    subtype = tvb_get_uint8(tvb, 3);
870
871
    /* quick sanity check */
872
7
    if ((length != tvb_reported_length (tvb)-WAI_MESSAGE_LENGTH) ||
873
7
        (subtype > WAI_SUB_MULTICAST_ANNOUNCE_RESP)) {
874
7
        return 0;
875
7
    }
876
877
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WAI");
878
0
    col_clear(pinfo->cinfo, COL_INFO);
879
0
    version = tvb_get_ntohs(tvb, 0);
880
881
0
    if (version == 1) {
882
0
        subtype_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type");
883
0
    }
884
0
    col_append_str(pinfo->cinfo, COL_INFO, subtype_name);
885
886
    /* Field lengths and offsets in WAI protocol described above */
887
0
    packet_num   = tvb_get_ntohs(tvb, 8);
888
0
    fragment_num = tvb_get_uint8(tvb, 10);
889
0
    flags        = tvb_get_uint8(tvb, 11);
890
891
0
    if (tree) {
892
0
        proto_item *wai_item;
893
894
0
        wai_item = proto_tree_add_item(tree, proto_wai, tvb, 0, -1, ENC_NA);
895
896
0
        proto_item_set_text (wai_item, "WAI Protocol (%s)",
897
0
                                val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"));
898
0
        wai_tree = proto_item_add_subtree(wai_item, ett_wai);
899
900
        /* Field lengths and offsets in WAI protocol described above */
901
0
        proto_tree_add_item(wai_tree, hf_wai_version,   tvb, 0,  2, ENC_BIG_ENDIAN);
902
0
        proto_tree_add_item(wai_tree, hf_wai_type,      tvb, 2,  1, ENC_BIG_ENDIAN);
903
0
        proto_tree_add_item(wai_tree, hf_wai_subtype,   tvb, 3,  1, ENC_BIG_ENDIAN);
904
0
        proto_tree_add_item(wai_tree, hf_wai_reserved,  tvb, 4,  2, ENC_BIG_ENDIAN);
905
0
        proto_tree_add_item(wai_tree, hf_wai_length,    tvb, 6,  2, ENC_BIG_ENDIAN);
906
0
        proto_tree_add_item(wai_tree, hf_wai_seq,       tvb, 8,  2, ENC_BIG_ENDIAN);
907
0
        proto_tree_add_item(wai_tree, hf_wai_fragm_seq, tvb, 10, 1, ENC_BIG_ENDIAN);
908
0
        proto_tree_add_item(wai_tree, hf_wai_flag,      tvb, 11, 1, ENC_BIG_ENDIAN);
909
0
    }
910
911
0
    frag_msg =  fragment_add_seq_check (&wai_reassembly_table,
912
0
                                        tvb, WAI_DATA_OFFSET,
913
0
                                        pinfo,
914
0
                                        packet_num,
915
0
                                        NULL,
916
0
                                        fragment_num,
917
0
                                        length,
918
0
                                        flags);
919
920
0
    next_tvb = tvb_new_subset_remaining(tvb, WAI_DATA_OFFSET);
921
922
    /* Replace INFO column if message is fragmented and call data dissector */
923
0
    if (flags) {
924
0
        col_add_fstr(pinfo->cinfo, COL_INFO,
925
0
                     "Fragment (%d) of message, data not dissected", fragment_num);
926
927
0
        process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
928
0
                                 "Reassembled WAI", frag_msg, &wai_frag_items,
929
0
                                 NULL, wai_tree);
930
931
0
        call_data_dissector(next_tvb, pinfo, tree);
932
0
    } else {
933
        /* If this is the last fragment of fragmented message, then reassamble and dissect
934
           otherwise only dissect */
935
0
        if (fragment_num > 0) {
936
0
            new_tvb = process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
937
0
                                               "Reassembled WAI", frag_msg, &wai_frag_items,
938
0
                                               NULL, wai_tree);
939
940
0
            if (new_tvb) {
941
0
                col_set_str(pinfo->cinfo, COL_INFO, "Last fragment of message, data dissected");
942
0
                col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", subtype_name);
943
0
                next_tvb=new_tvb;
944
0
                length = tvb_reported_length (next_tvb);
945
0
            }
946
0
        }
947
        /* dissect Data field of WAI packet */
948
0
        if (tree) {
949
0
            dissect_wai_data(next_tvb, wai_tree, subtype, length);
950
0
        }
951
0
    }
952
953
0
    return tvb_captured_length(tvb);
954
7
}
955
956
void
957
proto_register_wai(void)
958
16
{
959
16
    static hf_register_info hf[] = {
960
16
        { &hf_wai_version,
961
16
          { "Version", "wai.version",
962
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
963
16
            "Version of authentication infrastructure", HFILL }},
964
965
16
        { &hf_wai_type,
966
16
          { "Type", "wai.type",
967
16
            FT_UINT8, BASE_HEX, VALS(wai_type_names), 0x0,
968
16
            "Protocol type", HFILL }},
969
970
16
        { &hf_wai_subtype,
971
16
          { "Subtype", "wai.subtype",
972
16
            FT_UINT8, BASE_DEC|BASE_EXT_STRING, &wai_subtype_names_ext, 0x0,
973
16
            NULL, HFILL }},
974
975
16
        { &hf_wai_reserved,
976
16
          { "Reserved", "wai.reserved",
977
16
            FT_UINT16, BASE_HEX, NULL, 0x0,
978
16
            NULL, HFILL }},
979
980
16
        { &hf_wai_length,
981
16
          { "Length", "wai.length",
982
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
983
16
            NULL, HFILL }},
984
985
16
        { &hf_wai_seq,
986
16
          { "Sequence number", "wai.seq",
987
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
988
16
            "Packet sequence number", HFILL }},
989
990
16
        { &hf_wai_fragm_seq,
991
16
          { "Fragment sequence number", "wai.fragm.seq",
992
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
993
16
            NULL, HFILL }},
994
995
16
        { &hf_wai_flag,
996
16
          { "Flag", "wai.flag",
997
16
            FT_UINT8, BASE_HEX, NULL, 0x0,
998
16
            NULL, HFILL }},
999
1000
16
        { &hf_wai_data,
1001
16
          { "Data", "wai.data",
1002
16
            FT_BYTES, BASE_NONE, NULL, 0x0,
1003
16
            NULL, HFILL }},
1004
1005
16
        { &hf_wai_bk_rekeying_flag,
1006
16
          {"BK rekeying", "wai.bk.rekeying.flag",
1007
16
           FT_BOOLEAN, 8, TFS (&wai_bk_rekeying_flag), FLAG_BIT0,
1008
16
           "BK rekeying flag", HFILL }},
1009
1010
16
        { &hf_wai_preauthentication_flag,
1011
16
          {"Pre-Authentication", "wai.preauthentication.flag",
1012
16
           FT_BOOLEAN, 8, TFS (&wai_preauthentication_flag), FLAG_BIT1,
1013
16
           "Pre-Authentication flag", HFILL }},
1014
1015
16
        { &hf_wai_certificate_flag,
1016
16
          {"Certificate", "wai.certificate.flag",
1017
16
           FT_BOOLEAN, 8, TFS (&wai_certificate_flag), FLAG_BIT2,
1018
16
           "Certificate flag", HFILL }},
1019
1020
16
        { &hf_wai_optional_flag,
1021
16
          {"Optional", "wai.optional.flag",
1022
16
           FT_BOOLEAN, 8, TFS (&wai_optional_flag), FLAG_BIT3,
1023
16
           "Optional flag", HFILL }},
1024
1025
16
        { &hf_wai_usk_rekeying_flag,
1026
16
            {"USK rekeying", "wai.usk.rekeying.flag",
1027
16
                    FT_BOOLEAN, 8, TFS (&wai_usk_rekeying_flag), FLAG_BIT4,
1028
16
                    "USK rekeying flag", HFILL }},
1029
1030
16
        { &hf_wai_negotiation_flag,
1031
16
            {"STA negotiation", "wai.negotiation.flag",
1032
16
                    FT_BOOLEAN, 8, TFS (&wai_negotiation_flag), FLAG_BIT5,
1033
16
                    "STA negotiation flag", HFILL }},
1034
1035
16
        { &hf_wai_revoking_flag,
1036
16
            {"STA revoking", "wai.revoking.flag",
1037
16
                    FT_BOOLEAN, 8, TFS (&wai_revoking_flag), FLAG_BIT6,
1038
16
                    "STA revoking flag", HFILL }},
1039
1040
16
        { &hf_wai_reserved_flag,
1041
16
            {"Reserved", "wai.reserved.flag",
1042
16
                    FT_BOOLEAN, 8, TFS (&wai_reserved_flag), FLAG_BIT7,
1043
16
                    "Reserved flag", HFILL }},
1044
1045
16
        { &hf_wai_attr_type,
1046
16
          { "Type", "wai.attrtype",
1047
16
            FT_UINT8, BASE_HEX, VALS(wai_attr_type_names), 0x0,
1048
16
            "Attribute type", HFILL }},
1049
1050
16
        { &hf_wai_cert,
1051
16
            {"Certificate", "wai.cert",
1052
16
                    FT_BYTES, BASE_NONE, NULL, 0x0,
1053
16
             NULL, HFILL }},
1054
1055
16
        { &hf_wai_cert_id,
1056
16
          {"Id", "wai.cert.id",
1057
16
           FT_UINT16, BASE_HEX, NULL, 0x0,
1058
16
           "Certificate Id", HFILL }},
1059
1060
16
        { &hf_wai_cert_data,
1061
16
          {"Data", "wai.cert.data",
1062
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1063
16
           "Certificate data", HFILL }},
1064
1065
16
        { &hf_wai_cert_len,
1066
16
          {"Length", "wai.cert.len",
1067
16
           FT_UINT16, BASE_DEC, NULL, 0x0,
1068
16
           "Certificate length", HFILL }},
1069
1070
16
        { &hf_wai_addid,
1071
16
          {"ADDID", "wai.addid",
1072
16
           FT_STRING, BASE_NONE, NULL, 0x0,
1073
16
           NULL, HFILL }},
1074
1075
16
        { &hf_wai_ae_mac,
1076
16
          {"AE MAC", "wai.ae.mac",
1077
16
           FT_ETHER, BASE_NONE, NULL, 0x0,
1078
16
           "AE MAC address", HFILL }},
1079
1080
16
        { &hf_wai_asue_mac,
1081
16
          {"ASUE MAC", "wai.asue.mac",
1082
16
           FT_ETHER, BASE_NONE, NULL, 0x0,
1083
16
           "ASUE MAC address", HFILL }},
1084
1085
16
        { &hf_wai_bkid,
1086
16
          {"BKID", "wai.bkid",
1087
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1088
16
           NULL, HFILL }},
1089
1090
16
        { &hf_wai_uskid,
1091
16
          {"USKID", "wai.uskid",
1092
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1093
16
           NULL, HFILL }},
1094
1095
16
        { &hf_wai_wie,
1096
16
          {"WIE from ASUE", "wai.wie",
1097
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1098
16
           NULL, HFILL }},
1099
1100
16
        { &hf_wai_message_auth_code,
1101
16
          {"Message Authentication Code", "wai.message.auth.code",
1102
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1103
16
           NULL, HFILL }},
1104
1105
16
        { &hf_wai_mskid,
1106
16
          {"MSKID/STAKeyID", "wai.mskid",
1107
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1108
16
           NULL, HFILL }},
1109
1110
16
        { &hf_wai_data_pack_num,
1111
16
          {"Data packet number", "wai.data.packet.num",
1112
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1113
16
           NULL, HFILL }},
1114
1115
16
        { &hf_wai_key_data,
1116
16
          {"Key Data", "wai.key.data",
1117
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1118
16
           NULL, HFILL }},
1119
1120
16
        { &hf_wai_key_data_len,
1121
16
          {"Length", "wai.key.data.len",
1122
16
           FT_UINT8, BASE_DEC, NULL, 0x0,
1123
16
           "Key data length", HFILL }},
1124
1125
16
        { &hf_wai_key_data_content,
1126
16
          {"Content", "wai.key.data.content",
1127
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1128
16
           "Key data content", HFILL }},
1129
1130
16
        { &hf_wai_key_ann_id,
1131
16
          {"Key Announcement Identifier", "wai.key.ann.id",
1132
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1133
16
           NULL, HFILL }},
1134
1135
16
        { &hf_wai_auth_id,
1136
16
          {"Authentication Identifier", "wai.auth.id",
1137
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1138
16
           NULL, HFILL }},
1139
1140
16
        { &hf_wai_identity,
1141
16
          {"Identifier", "wai.identity",
1142
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1143
16
           NULL, HFILL }},
1144
1145
16
        { &hf_wai_identity_id,
1146
16
          {"Id", "wai.identity.id",
1147
16
           FT_UINT16, BASE_HEX, NULL, 0x0,
1148
16
           NULL, HFILL }},
1149
1150
16
        { &hf_wai_identity_len,
1151
16
          {"Length", "wai.identity.len",
1152
16
           FT_UINT16, BASE_DEC, NULL, 0x0,
1153
16
           "Identity length", HFILL }},
1154
1155
16
        { &hf_wai_identity_data,
1156
16
          {"Data", "wai.identity.data",
1157
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1158
16
           "Identity data", HFILL }},
1159
1160
16
        { &hf_wai_ecdh,
1161
16
          {"ECDH Parameter", "wai.ecdhp",
1162
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1163
16
           NULL, HFILL }},
1164
1165
16
        { &hf_wai_ecdh_id,
1166
16
          {"ID", "wai.edch.id",
1167
16
           FT_UINT8, BASE_HEX, NULL, 0x0,
1168
16
           "ECDH Parameter Identifier", HFILL }},
1169
1170
16
        { &hf_wai_ecdh_len,
1171
16
          {"Length", "wai.ecdh.len",
1172
16
           FT_UINT16, BASE_DEC, NULL, 0x0,
1173
16
           "ECDH Parameter Length", HFILL }},
1174
1175
16
        { &hf_wai_ecdh_content,
1176
16
          {"Content", "wai.ecdh.content",
1177
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1178
16
           "ECDH Parameter Content", HFILL }},
1179
1180
16
        { &hf_wai_counter,
1181
16
          {"Replay counter", "wai.counter",
1182
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1183
16
           NULL, HFILL }},
1184
1185
16
        { &hf_wai_sta_key_id,
1186
16
          {"STAKeyID", "wai.sta.key.id",
1187
16
           FT_UINT8, BASE_HEX, NULL, 0x0,
1188
16
           NULL, HFILL }},
1189
1190
16
        { &hf_wai_challenge,
1191
16
          {"Challenge", "wai.challenge",
1192
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1193
16
           NULL, HFILL }},
1194
1195
16
        { &hf_wai_cert_ver,
1196
16
          {"Multiple Certificate Verification Result", "wai.cert.ver",
1197
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1198
16
           NULL, HFILL }},
1199
1200
16
        { &hf_wai_nonce,
1201
16
          {"Nonce", "wai.nonce",
1202
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1203
16
           NULL, HFILL }},
1204
1205
16
        { &hf_wai_ver_res,
1206
16
          {"Verification result", "wai.ver.res",
1207
16
           FT_UINT8, BASE_HEX, VALS(wai_ver_res_names), 0x0,
1208
16
           NULL, HFILL }},
1209
1210
16
        { &hf_wai_sign_alg,
1211
16
          {"Signature Algorithm", "wai.sign.alg",
1212
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1213
16
           NULL, HFILL }},
1214
1215
16
        { &hf_wai_hash_alg_id,
1216
16
          {"Hash Algorithm Identifier", "wai.hash.alg.id",
1217
16
           FT_UINT8, BASE_HEX, NULL, 0x0,
1218
16
           NULL, HFILL }},
1219
1220
16
        { &hf_wai_sign_alg_id,
1221
16
          {"Signature Algorithm Identifier", "wai.sign.alg.id",
1222
16
           FT_UINT8, BASE_HEX, NULL, 0x0,
1223
16
           NULL, HFILL }},
1224
1225
16
        { &hf_wai_param,
1226
16
          {"Parameter", "wai.param",
1227
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1228
16
           NULL, HFILL }},
1229
1230
16
        { &hf_wai_param_id,
1231
16
          {"Parameter Identifier", "wai.param.id",
1232
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1233
16
           NULL, HFILL }},
1234
1235
16
        { &hf_wai_param_content,
1236
16
          {"Parameter Content", "wai.param.content",
1237
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1238
16
           NULL, HFILL }},
1239
1240
16
        { &hf_wai_sign_val,
1241
16
          {"Signature Value", "wai.sign.val",
1242
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1243
16
           NULL, HFILL }},
1244
1245
16
        { &hf_wai_sign_content,
1246
16
          {"Signature Content", "wai.sign.content",
1247
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1248
16
           NULL, HFILL }},
1249
1250
16
        { &hf_wai_sign,
1251
16
          {"Signature", "wai.sign",
1252
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1253
16
           NULL, HFILL }},
1254
1255
16
        { &hf_wai_identity_list,
1256
16
          {"ASU List trusted by ASUE", "wai.identity_list",
1257
16
           FT_BYTES, BASE_NONE, NULL, 0x0,
1258
16
           "Identity list", HFILL }},
1259
1260
16
        { &hf_wai_reserved_byte,
1261
16
          {"Reserved", "wai.reserved.byte",
1262
16
           FT_UINT8, BASE_HEX, NULL, 0x0,
1263
16
           NULL, HFILL }},
1264
1265
16
        { &hf_wai_no_of_ids,
1266
16
          {"Number of Identities", "wai.no.of.ids",
1267
16
           FT_UINT16, BASE_DEC, NULL, 0x0,
1268
16
           NULL, HFILL }},
1269
1270
16
        { &hf_wai_access_res,
1271
16
        {"Access result", "wai.access_result",
1272
16
         FT_UINT8, BASE_HEX, VALS(wai_access_res_names), 0x0,
1273
16
         NULL, HFILL }},
1274
1275
16
        { &hf_wai_fragments,
1276
16
          {"Message fragments", "wai.fragments",
1277
16
           FT_NONE, BASE_NONE, NULL, 0x00,
1278
16
           NULL, HFILL }},
1279
1280
16
        { &hf_wai_fragment,
1281
16
          {"Message fragment", "wai.fragment",
1282
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00,
1283
16
           NULL, HFILL }},
1284
1285
16
        { &hf_wai_fragment_overlap,
1286
16
          {"Message fragment overlap", "wai.fragment.overlap",
1287
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1288
16
           NULL, HFILL }},
1289
1290
16
        { &hf_wai_fragment_overlap_conflicts,
1291
16
          {"Message fragment overlapping with conflicting data", "wai.fragment.overlap.conflicts",
1292
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1293
16
           NULL, HFILL }},
1294
1295
16
        { &hf_wai_fragment_multiple_tails,
1296
16
          {"Message has multiple tail fragments", "wai.fragment.multiple_tails",
1297
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1298
16
           NULL, HFILL }},
1299
1300
16
        { &hf_wai_fragment_too_long_fragment,
1301
16
          {"Message fragment too long", "wai.fragment.too_long_fragment",
1302
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1303
16
           NULL, HFILL }},
1304
1305
16
        { &hf_wai_fragment_error,
1306
16
          {"Message defragmentation error", "wai.fragment.error",
1307
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00,
1308
16
           NULL, HFILL }},
1309
1310
16
        { &hf_wai_fragment_count,
1311
16
          {"Message fragment count", "wai.fragment.count",
1312
16
           FT_UINT32, BASE_DEC, NULL, 0x00,
1313
16
           NULL, HFILL }},
1314
1315
16
        { &hf_wai_reassembled_in,
1316
16
          {"Reassembled in", "wai.reassembled.in",
1317
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00,
1318
16
           NULL, HFILL }},
1319
1320
16
        { &hf_wai_reassembled_length,
1321
16
          {"Reassembled length", "wai.reassembled.length",
1322
16
           FT_UINT32, BASE_DEC, NULL, 0x00,
1323
16
           NULL, HFILL }}
1324
16
    };
1325
1326
16
    static int *ett[] = {
1327
16
        &ett_wai,
1328
16
        &ett_wai_data,
1329
16
        &ett_wai_flags,
1330
16
        &ett_wai_certificate,
1331
16
        &ett_wai_mac,
1332
16
        &ett_wai_identity,
1333
16
        &ett_wai_key_data,
1334
16
        &ett_wai_ecdh_param,
1335
16
        &ett_wai_certificate_verification,
1336
16
        &ett_wai_identity_list,
1337
16
        &ett_wai_sign,
1338
16
        &ett_wai_sign_alg,
1339
16
        &ett_wai_sign_val,
1340
16
        &ett_wai_parameter,
1341
16
        &ett_wai_fragment,
1342
16
        &ett_wai_fragments
1343
16
    };
1344
1345
16
    proto_wai = proto_register_protocol("WAI Protocol", "WAI", "wai");
1346
16
    proto_register_field_array(proto_wai, hf, array_length(hf));
1347
16
    proto_register_subtree_array(ett, array_length(ett));
1348
16
    reassembly_table_register(&wai_reassembly_table,
1349
16
                          &addresses_reassembly_table_functions);
1350
1351
16
    wai_handle = register_dissector("wai", dissect_wai, proto_wai);
1352
16
}
1353
1354
void
1355
proto_reg_handoff_wai(void)
1356
16
{
1357
16
    dissector_add_uint("ethertype", ETHERTYPE_WAI, wai_handle);
1358
16
}
1359
1360
/*
1361
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1362
 *
1363
 * Local variables:
1364
 * c-basic-offset: 4
1365
 * tab-width: 8
1366
 * indent-tabs-mode: nil
1367
 * End:
1368
 *
1369
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1370
 * :indentSize=4:tabSize=8:noTabs=true:
1371
 */