Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-wifi-dpp.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-wifi-dpp.c
2
 *
3
 * Wi-Fi Device Provisioning Protocol (DPP)
4
 *
5
 * Copyright 2017-2020 Richard Sharpe <realrichardsharpe@gmail.com>
6
 * Copyright 2017-2020 The WiFi Alliance
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
/*
12
 * Code and constants based on Device_Provisioning_Protocol_Specification_v1.2.9
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include "packet-tcp.h"
19
#include <epan/to_str.h>
20
#include <epan/expert.h>
21
22
#include "packet-wifi-dpp.h"
23
#include "packet-ieee80211.h"
24
25
extern const value_string wfa_subtype_vals[];
26
27
void proto_register_wifi_dpp(void);
28
void proto_reg_handoff_wifi_dpp(void);
29
30
static dissector_handle_t wifi_dpp_handle;
31
static dissector_handle_t wifi_dpp_tcp_handle;
32
static dissector_handle_t wifi_dpp_ie_handle;
33
static dissector_handle_t wifi_dpp_pubact_handle;
34
35
#define WIFI_DPP_TCP_PORT (7871)
36
static unsigned wifi_dpp_tcp_port = WIFI_DPP_TCP_PORT;
37
38
enum {
39
  DPP_STATUS_OK =                0,
40
  DPP_STATUS_NOT_COMPATIBLE =    1,
41
  DPP_STATUS_AUTH_FAILURE =      2,
42
  DPP_STATUS_UNWRAP_FAILURE =    3,
43
  DPP_STATUS_BAD_GROUP =         4,
44
  DPP_STATUS_CONFIGURE_FAILURE = 5,
45
  DPP_STATUS_RESPONSE_PENDING =  6,
46
  DPP_STATUS_INVALID_CONNECTOR = 7,
47
  DPP_STATUS_NO_MATCH =          8,
48
  DPP_STATUS_CONFIG_REJECTED   = 9,
49
  DPP_STATUS_NO_AP =             10,
50
  DPP_STATUS_CONFIGURE_PENDING = 11,
51
  DPP_STATUS_CSR_NEEDED =        12,
52
  DPP_STATUS_CSR_BAD =           13
53
};
54
55
static const value_string dpp_status_codes[] = {
56
  { DPP_STATUS_OK,                 "OK" },
57
  { DPP_STATUS_NOT_COMPATIBLE,     "Not Compatible" },
58
  { DPP_STATUS_AUTH_FAILURE,       "Auth Failure" },
59
  { DPP_STATUS_UNWRAP_FAILURE,     "Unwrap Failure" },
60
  { DPP_STATUS_BAD_GROUP,          "Bad Group" },
61
  { DPP_STATUS_CONFIGURE_FAILURE,  "Configure Failure" },
62
  { DPP_STATUS_RESPONSE_PENDING,   "Response Pending" },
63
  { DPP_STATUS_INVALID_CONNECTOR,  "Invalid Connector" },
64
  { DPP_STATUS_NO_MATCH,           "No Match" },
65
  { DPP_STATUS_CONFIG_REJECTED,    "Enrollee rejected the config" },
66
  { DPP_STATUS_NO_AP,              "Enrollee failed to discover an AP" },
67
  { DPP_STATUS_CONFIGURE_PENDING,  "Configuration response is not ready yet. The enrollee needs to request again." },
68
  { DPP_STATUS_CSR_NEEDED,         "Configuration requires a Certificate Signing Request. Enrollee needs to request again." },
69
  { DPP_STATUS_CSR_BAD,            "The Certificate Signing Request was invalid." },
70
  { 0, NULL }
71
};
72
73
enum {
74
  DPP_STATUS                           = 0x1000,
75
  DPP_INITIATOR_BOOTSTRAPPING_KEY_HASH = 0x1001,
76
  DPP_RESPONDER_BOOTSTRAPPING_KEY_HASH = 0x1002,
77
  DPP_INITIATOR_PROTOCOL_KEY           = 0x1003,
78
  DPP_WRAPPED_DATA                     = 0x1004,
79
  DPP_INITIATOR_NONCE                  = 0x1005,
80
  DPP_INITIATOR_CAPABILITIES           = 0x1006,
81
  DPP_RESPONDER_NONCE                  = 0x1007,
82
  DPP_RESPONDER_CAPABILITIES           = 0x1008,
83
  DPP_RESPONDER_PROTOCOL_KEY           = 0x1009,
84
  DPP_INITIATOR_AUTHENTICATING_TAG     = 0x100A,
85
  DPP_RESPONDER_AUTHENTICATING_TAG     = 0x100B,
86
  DPP_CONFIGURATION_OBJECT             = 0x100C,
87
  DPP_CONNECTOR                        = 0x100D,
88
  DPP_CONFIGURATION_ATTRIBUTES_OBJECT  = 0x100E,
89
  DPP_BOOTSTRAPPING_KEY                = 0x100F,
90
  DPP_FINITE_CYCLIC_GROUP              = 0x1012,
91
  DPP_ENCRYPTED_KEY                    = 0x1013,
92
  DPP_ENROLLEE_NONCE                   = 0x1014,
93
  DPP_CODE_IDENTIFIER                  = 0x1015,
94
  DPP_TRANSACTION_ID                   = 0x1016,
95
  DPP_BOOTSTRAPPING_INFO               = 0x1017,
96
  DPP_CHANNEL                          = 0x1018,
97
  DPP_PROTOCOL_VERSION                 = 0x1019,
98
  DPP_ENVELOPEDATA                     = 0x101A,
99
  DPP_SENDCONNSTATUS                   = 0x101B,
100
  DPP_CONNSTATUS                       = 0x101C,
101
  DPP_RECONFIG_FLAGS                   = 0x101D,
102
  DPP_C_SIGN_KEY_HASH                  = 0x101E,
103
  DPP_CSR_ATTRIBUTES_REQUEST           = 0x101F,
104
  DPP_A_NONCE                          = 0x1020,
105
  DPP_E_PRIME_ID                       = 0x1021
106
};
107
108
static const value_string dpp_ie_attr_ids[] = {
109
  { DPP_STATUS,                           "DPP Status" },
110
  { DPP_INITIATOR_BOOTSTRAPPING_KEY_HASH, "DPP Initiator Bootstrapping Key Hash" },
111
  { DPP_RESPONDER_BOOTSTRAPPING_KEY_HASH, "DPP Responder Bootstrapping Key Hash" },
112
  { DPP_INITIATOR_PROTOCOL_KEY,           "DPP Initiator Protocol Key" },
113
  { DPP_WRAPPED_DATA,                     "DPP Primary Wrapped Data" },
114
  { DPP_INITIATOR_NONCE,                  "DPP Initiator Nonce" },
115
  { DPP_INITIATOR_CAPABILITIES,           "DPP Initiator Capabilities" },
116
  { DPP_RESPONDER_NONCE,                  "DPP Responder Nonce" },
117
  { DPP_RESPONDER_CAPABILITIES,           "DPP Responder Capabilities" },
118
  { DPP_RESPONDER_PROTOCOL_KEY,           "DPP Responder Protocol Key" },
119
  { DPP_INITIATOR_AUTHENTICATING_TAG,     "DPP Initiator Authenticating Tag" },
120
  { DPP_RESPONDER_AUTHENTICATING_TAG,     "DPP Responder Authenticating Tag" },
121
  { DPP_CONFIGURATION_OBJECT,             "DPP Configuration Object" },
122
  { DPP_CONNECTOR,                        "DPP Connector" },
123
  { DPP_CONFIGURATION_ATTRIBUTES_OBJECT,  "DPP Configuration Attributes Object" },
124
  { DPP_BOOTSTRAPPING_KEY,                "DPP Bootstrapping Key" },
125
  { DPP_FINITE_CYCLIC_GROUP,              "DPP Finite Cyclic Group" },
126
  { DPP_ENCRYPTED_KEY,                    "DPP Encrypted Key" },
127
  { DPP_CODE_IDENTIFIER,                  "DPP Code Identifier" },
128
  { DPP_TRANSACTION_ID,                   "DPP Transaction ID" },
129
  { DPP_BOOTSTRAPPING_INFO,               "DPP Bootstrapping Info" },
130
  { DPP_CHANNEL,                          "DPP Channel" },
131
  { DPP_PROTOCOL_VERSION,                 "DPP Protocol Version" },
132
  { DPP_ENVELOPEDATA,                     "DPP Enveloped Data" },
133
  { DPP_SENDCONNSTATUS,                   "DPP Send Conn Status" },
134
  { DPP_CONNSTATUS,                       "DPP Conn Status" },
135
  { DPP_RECONFIG_FLAGS,                   "DPP Reconfig Flags" },
136
  { DPP_C_SIGN_KEY_HASH,                  "DPP C-sign key Hash" },
137
  { DPP_CSR_ATTRIBUTES_REQUEST,           "DPP CSR Attributes Request" },
138
  { DPP_A_NONCE,                          "DPP A-NONCE" },
139
  { DPP_E_PRIME_ID,                       "DPP E'-id" },
140
  { 0, NULL }
141
};
142
143
enum {
144
  DPP_AUTHENTICATION_REQUEST          = 0,
145
  DPP_AUTHENTICATION_RESPONSE         = 1,
146
  DPP_AUTHENTICATION_CONFIRM          = 2,
147
  DPP_PEER_DISCOVERY_REQUEST          = 5,
148
  DPP_PEER_DISCOVERY_RESPONSE         = 6,
149
  DPP_PKEX_EXCHANGE_REQUEST           = 7,
150
  DPP_PKEX_EXCHANGE_RESPONSE          = 8,
151
  DPP_PKEX_COMMIT_REVEAL_REQUEST      = 9,
152
  DPP_PKEX_COMMIT_REVEAL_RESPONSE     = 10,
153
  DPP_CONFIGURATION_RESULT            = 11,
154
  DPP_CONNECTION_STATUS_RESULT        = 12,
155
  DPP_PRESENCE_ANNOUNCEMENT           = 13,
156
  DPP_RECONFIG_ANNOUNCEMENT           = 14,
157
  DPP_RECONFIG_AUTH_REQUEST           = 15,
158
  DPP_RECONFIG_AUTH_RESPONSE          = 16,
159
  DPP_RECONFIG_AUTH_CONFIRM           = 17
160
};
161
162
static const value_string dpp_public_action_subtypes[] = {
163
  { DPP_AUTHENTICATION_REQUEST,           "Authentication Request" },
164
  { DPP_AUTHENTICATION_RESPONSE,          "Authentication Response" },
165
  { DPP_AUTHENTICATION_CONFIRM,           "Authentication Confirm" },
166
  { DPP_PEER_DISCOVERY_REQUEST,           "Peer Discovery Request" },
167
  { DPP_PEER_DISCOVERY_RESPONSE,          "Peer Discovery Response" },
168
  { DPP_PKEX_EXCHANGE_REQUEST,            "PKEX Exchange Request" },
169
  { DPP_PKEX_EXCHANGE_RESPONSE,           "PKEX Exchange Response" },
170
  { DPP_PKEX_COMMIT_REVEAL_REQUEST,       "PKEX Commit-Reveal Request" },
171
  { DPP_PKEX_COMMIT_REVEAL_RESPONSE,      "PKEX Commit-Reveal Response" },
172
  { DPP_CONFIGURATION_RESULT,             "Configuration Result" },
173
  { DPP_CONNECTION_STATUS_RESULT,         "Connection Status Result" },
174
  { DPP_PRESENCE_ANNOUNCEMENT,            "Presence Announcement" },
175
  { DPP_RECONFIG_ANNOUNCEMENT,            "Reconfig Announcement" },
176
  { DPP_RECONFIG_AUTH_REQUEST,            "Reconfig Authentication Request" },
177
  { DPP_RECONFIG_AUTH_RESPONSE,           "Reconfig Authentication Response" },
178
  { DPP_RECONFIG_AUTH_CONFIRM,            "Reconfig Authentication Confirm" },
179
  { 0, NULL }
180
};
181
182
/*
183
 * This table and the one above share values ... but this one is truncated.
184
 */
185
static const value_string dpp_action_subtypes[] = {
186
  { DPP_AUTHENTICATION_REQUEST, "Authentication Request" },
187
  { DPP_AUTHENTICATION_RESPONSE, "Authentication Response" },
188
  { DPP_AUTHENTICATION_CONFIRM, "Authentication Confirm" },
189
  { DPP_PEER_DISCOVERY_REQUEST, "Peer Discovery Request" },
190
  { DPP_PEER_DISCOVERY_RESPONSE, "Peer Discovery Response" },
191
  { 0, NULL }
192
};
193
194
static const range_string dpp_protocol_version_rvals[] = {
195
  { 0, 0,   "Reserved" },
196
  { 1, 1,   "1.0" },
197
  { 2, 255, "Reserved" },
198
  { 0, 0, NULL }
199
};
200
201
static int proto_wifi_dpp;
202
203
static int ett_wifi_dpp_ie_generic;
204
static int ett_wifi_dpp_attributes;
205
static int ett_wifi_dpp_pa;
206
static int ett_wifi_dpp_attribute;
207
static int ett_wifi_dpp_attr_header;
208
static int ett_wifi_dpp_attr_value;
209
210
static int hf_wifi_dpp_ie_attr_id;
211
static int hf_wifi_dpp_ie_attr_len;
212
static int hf_wifi_dpp_ie_generic;  /* Remove eventually */
213
static int hf_wifi_dpp_action_dialog_token;
214
static int hf_wifi_dpp_action_subtype;
215
static int hf_wifi_dpp_crypto_suite;
216
static int hf_wifi_dpp_public_action_subtype;
217
static int hf_wifi_dpp_init_hash;
218
static int hf_wifi_dpp_resp_hash;
219
static int hf_wifi_dpp_status;
220
static int hf_wifi_dpp_key_x;
221
static int hf_wifi_dpp_key_y;
222
static int hf_wifi_dpp_trans_id;
223
static int hf_wifi_dpp_finite_cyclic_group;
224
static int hf_wifi_dpp_capabilities;
225
static int hf_wifi_dpp_code_identifier;
226
static int hf_wifi_dpp_enc_key_attribute;
227
static int hf_wifi_dpp_primary_wrapped_data;
228
static int hf_wifi_dpp_connector_attr;
229
static int hf_wifi_dpp_initiator_nonce;
230
static int hf_wifi_dpp_operating_class;
231
static int hf_wifi_dpp_channel;
232
static int hf_wifi_dpp_protocol_version;
233
static int hf_wifi_dpp_a_nonce;
234
static int hf_wifi_dpp_e_prime_id;
235
static int hf_wifi_dpp_unknown_anqp_item;
236
237
static int hf_wifi_dpp_tcp_pdu_length;
238
static int hf_wifi_dpp_tcp_pdu_action_field;
239
static int hf_wifi_dpp_tcp_oui;
240
static int hf_wifi_dpp_tcp_oui_type;
241
static int hf_wifi_dpp_tcp_dialog_token;
242
static int hf_wifi_dpp_tcp_adv_proto_elt;
243
static int hf_wifi_dpp_tcp_vendor_specific;
244
static int hf_wifi_dpp_tcp_vendor_spec_len;
245
static int hf_wifi_dpp_tcp_config;
246
static int hf_wifi_dpp_tcp_query_req_len;
247
static int hf_wifi_dpp_tcp_status_code;
248
static int hf_wifi_dpp_gas_query_resp_frag_id;
249
static int hf_wifi_dpp_tcp_comeback_delay;
250
static int hf_wifi_dpp_tcp_query_resp_len;
251
252
static int
253
dissect_wifi_dpp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
254
0
{
255
0
  int offset = 0;
256
257
0
  proto_tree_add_item(tree, hf_wifi_dpp_unknown_anqp_item, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
258
0
  return tvb_captured_length(tvb);
259
0
}
260
261
static int
262
dissect_wifi_dpp_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
263
0
{
264
0
  proto_item *ie;
265
0
  unsigned remaining_len = tvb_reported_length(tvb);
266
267
0
  ie = proto_tree_add_subtree(tree, tvb, 0, remaining_len, ett_wifi_dpp_ie_generic, NULL, "Generic DPP IE");
268
0
  proto_tree_add_item(ie, hf_wifi_dpp_ie_generic, tvb, 0, remaining_len,
269
0
                      ENC_NA);
270
0
  return tvb_captured_length(tvb);
271
0
}
272
273
static int
274
dissect_wifi_dpp_attributes(packet_info *pinfo _U_, proto_tree *tree,
275
                            tvbuff_t *tvb, int offset _U_)
276
3
{
277
3
  proto_item *si = NULL;
278
3
  uint8_t status;
279
3
  proto_tree *attr, *specific_attr, *attr_hdr;
280
3
  uint16_t attribute_id;
281
3
  uint16_t attribute_len;
282
3
  unsigned attributes_len = 0;
283
3
  unsigned remaining_len = tvb_reported_length_remaining(tvb, offset);
284
285
4
  while (remaining_len) {
286
4
    attribute_id = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN);
287
4
    attribute_len = tvb_get_uint16(tvb, offset + 2, ENC_LITTLE_ENDIAN);
288
4
    attr = proto_tree_add_subtree_format(tree, tvb, offset,
289
4
                                attribute_len + 4, ett_wifi_dpp_attribute,
290
4
                                &si, "%s Attribute",
291
4
                                val_to_str(attribute_id,
292
4
                                        dpp_ie_attr_ids,
293
4
                                        "Unknown (%u)"));
294
4
    attr_hdr = proto_tree_add_subtree(attr, tvb, offset, 4,
295
4
                                        ett_wifi_dpp_attr_header, NULL,
296
4
                                        "Attribute Header");
297
298
4
    proto_tree_add_item(attr_hdr, hf_wifi_dpp_ie_attr_id, tvb, offset, 2,
299
4
                        ENC_LITTLE_ENDIAN);
300
4
    offset += 2;
301
4
    proto_tree_add_item(attr_hdr, hf_wifi_dpp_ie_attr_len, tvb, offset, 2,
302
4
                        ENC_LITTLE_ENDIAN);
303
4
    offset += 2;
304
305
4
    specific_attr = proto_tree_add_subtree(attr, tvb, offset, attribute_len,
306
4
                                        ett_wifi_dpp_attr_value,
307
4
                                        NULL, "Attribute Value");
308
309
4
    switch (attribute_id) {
310
0
    case DPP_STATUS:
311
0
      status = tvb_get_uint8(tvb, offset);
312
0
      proto_item_append_text(si, ": %s", val_to_str(status,
313
0
                                         dpp_status_codes,
314
0
                                         "Unknown (%u)"));
315
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_status, tvb, offset, attribute_len, ENC_LITTLE_ENDIAN);
316
0
      break;
317
318
0
    case DPP_INITIATOR_BOOTSTRAPPING_KEY_HASH:
319
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_init_hash, tvb, offset, attribute_len, ENC_NA);
320
0
      break;
321
322
0
    case DPP_RESPONDER_BOOTSTRAPPING_KEY_HASH:
323
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_resp_hash, tvb, offset, attribute_len, ENC_NA);
324
0
      break;
325
326
0
    case DPP_RESPONDER_PROTOCOL_KEY:
327
0
    case DPP_INITIATOR_PROTOCOL_KEY:
328
      // This is two protocol keys of equal length, X then Y.
329
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_key_x, tvb, offset, attribute_len/2, ENC_NA);
330
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_key_y, tvb, offset + attribute_len/2, attribute_len/2, ENC_NA);
331
0
      break;
332
333
0
    case DPP_TRANSACTION_ID:
334
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_trans_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
335
0
      break;
336
337
0
    case DPP_FINITE_CYCLIC_GROUP:
338
0
    case DPP_RESPONDER_CAPABILITIES:
339
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_finite_cyclic_group, tvb, offset, 2, ENC_LITTLE_ENDIAN);
340
0
      break;
341
342
0
    case DPP_INITIATOR_CAPABILITIES:
343
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_capabilities, tvb, offset, 1, ENC_LITTLE_ENDIAN);
344
0
      break;
345
346
0
    case DPP_CODE_IDENTIFIER:
347
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_code_identifier, tvb, offset, attribute_len, ENC_UTF_8);
348
0
      break;
349
350
0
    case DPP_ENCRYPTED_KEY:
351
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_enc_key_attribute, tvb, offset, attribute_len, ENC_NA);
352
0
      break;
353
354
0
    case DPP_WRAPPED_DATA:
355
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_primary_wrapped_data, tvb, offset, attribute_len, ENC_NA);
356
0
      break;
357
358
0
    case DPP_CONNECTOR:
359
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_connector_attr, tvb,
360
0
                          offset, attribute_len, ENC_NA);
361
0
      break;
362
363
0
    case DPP_INITIATOR_NONCE:
364
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_initiator_nonce, tvb,
365
0
                          offset, attribute_len, ENC_NA);
366
0
      break;
367
368
0
    case DPP_CHANNEL:
369
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_operating_class, tvb,
370
0
                          offset, 1, ENC_NA);
371
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_channel, tvb, offset + 1,
372
0
                          1, ENC_NA);
373
0
      break;
374
375
0
    case DPP_PROTOCOL_VERSION:
376
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_protocol_version, tvb,
377
0
                          offset, 1, ENC_NA);
378
0
      break;
379
380
0
    case DPP_A_NONCE:
381
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_a_nonce, tvb, offset,
382
0
                          attribute_len, ENC_NA);
383
0
      break;
384
385
0
    case DPP_E_PRIME_ID:
386
0
      proto_tree_add_item(specific_attr, hf_wifi_dpp_e_prime_id, tvb, offset,
387
0
                          attribute_len, ENC_NA);
388
0
       break;
389
390
0
    case DPP_INITIATOR_AUTHENTICATING_TAG:
391
392
0
    case DPP_RESPONDER_AUTHENTICATING_TAG:
393
394
0
    case DPP_CONFIGURATION_OBJECT:
395
396
0
    case DPP_CONFIGURATION_ATTRIBUTES_OBJECT:
397
398
0
    case DPP_BOOTSTRAPPING_KEY:
399
400
0
    case DPP_ENROLLEE_NONCE:
401
402
4
    default:
403
4
      proto_tree_add_item(specific_attr, hf_wifi_dpp_ie_generic, tvb, offset, attribute_len, ENC_NA);
404
4
      break;
405
4
    }
406
407
1
    offset += attribute_len;
408
1
    attributes_len += attribute_len + 4;
409
1
    remaining_len -= (attribute_len + 4);
410
411
1
  }
412
413
0
  return attributes_len; // We return the attribute length plus hdr!
414
3
}
415
416
int
417
dissect_wifi_dpp_config_proto(packet_info *pinfo _U_, proto_tree *tree,
418
                             tvbuff_t *tvb, int offset _U_)
419
0
{
420
0
  proto_item *dpp_item;
421
0
  proto_tree *dpp_tree, *attr_tree;
422
0
  unsigned remaining_len = tvb_reported_length_remaining(tvb, offset);
423
424
0
  dpp_item = proto_tree_add_item(tree, proto_wifi_dpp, tvb, offset, -1, ENC_NA);
425
0
  dpp_tree = proto_item_add_subtree(dpp_item, ett_wifi_dpp_pa);
426
0
  proto_item_append_text(dpp_item, " Configuration");
427
428
0
  attr_tree = proto_tree_add_subtree_format(dpp_tree, tvb, offset,
429
0
                                            remaining_len,
430
0
                                            ett_wifi_dpp_attributes, NULL,
431
0
                                            "DPP Attributes");
432
433
0
  offset = dissect_wifi_dpp_attributes(pinfo, attr_tree, tvb, offset);
434
435
0
  return offset;
436
0
}
437
438
int
439
dissect_wifi_dpp_public_action(tvbuff_t *tvb, packet_info *pinfo,
440
                               proto_tree *tree, void *data _U_)
441
3
{
442
3
  uint8_t subtype;
443
3
  unsigned remaining_len;
444
3
  proto_item *dpp_item;
445
3
  proto_tree *dpp_tree, *attr_tree;
446
3
  uint16_t attributes_len;
447
3
  int offset = 0;
448
449
3
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "wifi_dpp");
450
451
  /* The Crypto suite comes before the DPP frame type */
452
3
  subtype = tvb_get_uint8(tvb, offset + 1);
453
3
  col_append_fstr(pinfo->cinfo, COL_INFO, ", DPP - %s",
454
3
                  val_to_str(subtype, dpp_public_action_subtypes,
455
3
                             "Unknown (%u)"));
456
457
3
  remaining_len = tvb_reported_length_remaining(tvb, offset);
458
459
3
  dpp_item = proto_tree_add_item(tree, proto_wifi_dpp, tvb, offset, -1, ENC_NA);
460
3
  dpp_tree = proto_item_add_subtree(dpp_item, ett_wifi_dpp_pa);
461
3
  proto_item_append_text(dpp_item, ": %s", val_to_str(subtype,
462
3
                                                 dpp_public_action_subtypes,
463
3
                                                 "Unknown (%u)"));
464
3
  proto_tree_add_item(dpp_tree, hf_wifi_dpp_crypto_suite, tvb, offset, 1,
465
3
                      ENC_LITTLE_ENDIAN);
466
3
  offset++;
467
3
  remaining_len--;
468
469
3
  proto_tree_add_item(dpp_tree, hf_wifi_dpp_public_action_subtype, tvb, offset,
470
3
                      1, ENC_LITTLE_ENDIAN);
471
3
  offset++;  /* Skip the OUI Subtype/DPP Request type */
472
3
  remaining_len--;
473
3
  if (remaining_len) {
474
3
    attr_tree = proto_tree_add_subtree_format(dpp_tree, tvb, offset,
475
3
                       remaining_len,
476
3
                       ett_wifi_dpp_attributes, NULL, "DPP Attributes");
477
478
3
    attributes_len = dissect_wifi_dpp_attributes(pinfo, attr_tree, tvb, offset);
479
3
    offset += attributes_len;
480
3
  }
481
482
3
  return offset;
483
3
}
484
485
static int
486
dissect_wifi_dpp_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo _U_,
487
  proto_tree *tree, void *data _U_)
488
5
{
489
5
  int offset = 0;
490
5
  uint8_t action;
491
5
  tvbuff_t *newtvb;
492
493
5
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "dpp");
494
495
  /*
496
   * We get a length, followed by Action field, OUI, OUI type and then a
497
   * DPP public action
498
   */
499
5
  proto_tree_add_item(tree, hf_wifi_dpp_tcp_pdu_length, tvb, offset, 4,
500
5
                      ENC_BIG_ENDIAN);
501
5
  offset += 4;
502
503
5
  action = tvb_get_uint8(tvb, offset);
504
5
  proto_tree_add_item(tree, hf_wifi_dpp_tcp_pdu_action_field, tvb, offset, 1,
505
5
                      ENC_NA);
506
5
  offset += 1;
507
508
5
  if (action == 0x09) {
509
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui, tvb, offset, 3, ENC_NA);
510
0
    offset += 3;
511
512
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui_type, tvb, offset, 1, ENC_NA);
513
0
    offset += 1;
514
515
0
    newtvb = tvb_new_subset_remaining(tvb, offset);
516
517
0
    offset += dissect_wifi_dpp_public_action(newtvb, pinfo, tree, NULL);
518
5
  } else if (action == 0x0a) {
519
0
    col_append_str(pinfo->cinfo, COL_INFO, ", DPP - Configuration Request");
520
521
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_dialog_token, tvb, offset, 1,
522
0
                        ENC_NA);
523
0
    offset += 1;
524
525
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_adv_proto_elt, tvb, offset, 3,
526
0
                        ENC_NA);
527
0
    offset += 3;
528
529
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_vendor_specific, tvb, offset, 1,
530
0
                        ENC_NA);
531
0
    offset += 1;
532
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_vendor_spec_len, tvb, offset, 1,
533
0
                        ENC_NA);
534
0
    offset += 1;
535
536
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui, tvb, offset, 3, ENC_NA);
537
0
    offset += 3;
538
539
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui_type, tvb, offset, 1, ENC_NA);
540
0
    offset += 1;
541
542
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_config, tvb, offset, 1, ENC_NA);
543
0
    offset += 1;
544
545
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_query_req_len, tvb, offset, 2,
546
0
                        ENC_LITTLE_ENDIAN);
547
0
    offset += 2;
548
549
0
    offset += dissect_wifi_dpp_config_proto(pinfo, tree, tvb, offset);
550
5
  } else if (action == 0x0b || action == 0x0d) {
551
0
    uint16_t qr_len;
552
553
0
    col_append_str(pinfo->cinfo, COL_INFO, ", DPP - Configuration Response");
554
555
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_dialog_token, tvb, offset, 1,
556
0
                        ENC_NA);
557
0
    offset += 1;
558
559
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_status_code, tvb, offset, 2,
560
0
                        ENC_LITTLE_ENDIAN);
561
0
    offset += 2;
562
563
0
    if (action == 0x0d) {
564
0
      proto_tree_add_item(tree, hf_wifi_dpp_gas_query_resp_frag_id, tvb, offset,
565
0
                          1, ENC_NA);
566
0
      offset += 1;
567
0
    }
568
569
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_comeback_delay, tvb, offset, 2,
570
0
                        ENC_LITTLE_ENDIAN);
571
0
    offset += 2;
572
573
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_adv_proto_elt, tvb, offset, 3,
574
0
                        ENC_NA);
575
0
    offset += 3;
576
577
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_vendor_specific, tvb, offset, 1,
578
0
                        ENC_NA);
579
0
    offset += 1;
580
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_vendor_spec_len, tvb, offset, 1,
581
0
                        ENC_NA);
582
0
    offset += 1;
583
584
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui, tvb, offset, 3, ENC_NA);
585
0
    offset += 3;
586
587
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_oui_type, tvb, offset, 1, ENC_NA);
588
0
    offset += 1;
589
590
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_config, tvb, offset, 1, ENC_NA);
591
0
    offset += 1;
592
593
0
    qr_len = tvb_get_letohs(tvb, offset);
594
0
    proto_tree_add_item(tree, hf_wifi_dpp_tcp_query_resp_len, tvb, offset, 2,
595
0
                        ENC_LITTLE_ENDIAN);
596
0
    offset += 2;
597
598
0
    if (qr_len) {
599
0
      offset += dissect_wifi_dpp_config_proto(pinfo, tree, tvb, offset);
600
0
    }
601
0
  }
602
603
5
  return offset;
604
5
}
605
606
static unsigned
607
get_wifi_dpp_tcp_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
608
  void *data _U_)
609
5
{
610
5
  unsigned pkt_len;
611
612
5
  pkt_len = tvb_get_ntohl(tvb, offset);
613
614
5
  return pkt_len + 4;
615
5
}
616
617
/*
618
 * We need 4 bytes for the length ...
619
 */
620
4
#define DPP_TCP_HEADER_LEN 4
621
static int
622
dissect_wifi_dpp_tcp_pdus(tvbuff_t *tvb, packet_info *pinfo _U_,
623
  proto_tree *tree, void *data _U_)
624
2
{
625
2
  if (!tvb_bytes_exist(tvb, 0, DPP_TCP_HEADER_LEN))
626
0
    return 0;
627
628
2
  tcp_dissect_pdus(tvb, pinfo, tree, true, DPP_TCP_HEADER_LEN,
629
2
                   get_wifi_dpp_tcp_len, dissect_wifi_dpp_tcp_pdu, data);
630
2
  return tvb_reported_length(tvb);
631
2
}
632
633
void
634
proto_register_wifi_dpp(void)
635
14
{
636
14
  static module_t *wifi_dpp_module;
637
14
  static hf_register_info hf[] = {
638
14
    { &hf_wifi_dpp_status,
639
14
      { "Wi-Fi DPP Status", "dpp.status",
640
14
        FT_UINT8, BASE_HEX, VALS(dpp_status_codes), 0x0, NULL, HFILL }},
641
14
    { &hf_wifi_dpp_init_hash,
642
14
      { "Wi-Fi DPP Initiator Hash", "dpp.init.hash",
643
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
644
14
    { &hf_wifi_dpp_resp_hash,
645
14
      { "Wi-Fi DPP Responder Hash", "dpp.resp.hash",
646
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
647
14
    { &hf_wifi_dpp_key_x,
648
14
      { "Wi-Fi DPP Key X value", "dpp.key.x",
649
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
650
14
    { &hf_wifi_dpp_key_y,
651
14
      { "Wi-Fi DPP Key Y value", "dpp.key.y",
652
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
653
14
    { &hf_wifi_dpp_trans_id,
654
14
      { "Wi-Fi DPP Transaction ID", "dpp.trans_id",
655
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
656
14
    { &hf_wifi_dpp_finite_cyclic_group,
657
14
      { "Wi-Fi DPP Finite Cyclic Group", "dpp.finite_cyclic_group",
658
14
        FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
659
14
    { &hf_wifi_dpp_capabilities,
660
14
      { "Wi-Fi DPP Capabilities", "dpp.capabilities",
661
14
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
662
14
    { &hf_wifi_dpp_code_identifier,
663
14
      { "Wi-Fi DPP Code Identifier", "dpp.code_identifier",
664
14
        FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
665
14
    { &hf_wifi_dpp_enc_key_attribute,
666
14
      { "Wi-Fi DPP Encrypted Key Attribute", "dpp.pkex.enckey",
667
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
668
14
    { &hf_wifi_dpp_primary_wrapped_data,
669
14
      { "Wi-Fi DPP Primary Wrapped Data", "dpp.primary.wrapped_data",
670
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
671
14
    { &hf_wifi_dpp_connector_attr,
672
14
      { "Wi-Fi DPP Connector Attribute", "dpp.connector_data",
673
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
674
14
    { &hf_wifi_dpp_initiator_nonce,
675
14
      { "Wi-Fi DPP Initiator Nonce", "dpp.initiator_nonce",
676
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
677
14
    { &hf_wifi_dpp_operating_class,
678
14
      { "Operating Class", "dpp.operating_class",
679
14
       FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
680
14
    { &hf_wifi_dpp_channel,
681
14
      { "Channel", "dpp.channel",
682
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
683
14
    { &hf_wifi_dpp_protocol_version,
684
14
      { "Protocol Version", "dpp.protocol_version",
685
14
        FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(dpp_protocol_version_rvals),
686
14
        0x0, NULL, HFILL }},
687
14
    { &hf_wifi_dpp_a_nonce,
688
14
      { "A-NONCE", "dpp.a_nonce",
689
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
690
14
    { &hf_wifi_dpp_e_prime_id,
691
14
      { "E'-id", "dpp.e_prime_id",
692
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
693
14
    { &hf_wifi_dpp_ie_attr_id,
694
14
      { "Wi-Fi DPP IE Attribute ID", "dpp.ie.attr_id",
695
14
        FT_UINT16, BASE_HEX, VALS(dpp_ie_attr_ids), 0x0, NULL, HFILL }},
696
14
    { &hf_wifi_dpp_ie_attr_len,
697
14
      { "Wi-Fi DPP IE Attribute Len", "dpp.ie.attr_len",
698
14
       FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
699
14
    { &hf_wifi_dpp_ie_generic,
700
14
      { "Wi-Fi DPP IE generic", "dpp.ie.generic",
701
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
702
14
    { &hf_wifi_dpp_action_subtype,
703
14
      { "Wi-Fi DPP Action Subtype", "dpp.action.subtype",
704
14
        FT_UINT8, BASE_DEC, VALS(dpp_action_subtypes), 0x0, NULL, HFILL }},
705
14
    { &hf_wifi_dpp_action_dialog_token,
706
14
      { "Wi-Fi DPP Action Dialog Token", "dpp.action.dialog_token",
707
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
708
14
    { &hf_wifi_dpp_crypto_suite,
709
14
      { "Wi-Fi DPP Cryptographic Suite", "dpp.public_action.crypto_suite",
710
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
711
14
    { &hf_wifi_dpp_public_action_subtype,
712
14
      { "Wi-Fi DPP Public Action Subtype", "dpp.public_action.subtype",
713
14
        FT_UINT8, BASE_DEC, VALS(dpp_public_action_subtypes), 0x0, NULL, HFILL }},
714
14
    { &hf_wifi_dpp_unknown_anqp_item,
715
14
      { "Wi-fi DPP Unknown ANQP Item", "dpp.unknown_anqp_item",
716
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
717
718
14
    { &hf_wifi_dpp_tcp_pdu_length,
719
14
      { "DPP TCP PDU length", "dpp.tcp.length",
720
14
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
721
722
14
    { &hf_wifi_dpp_tcp_pdu_action_field,
723
14
      { "DPP TCP PDU Action type", "dpp.tcp.action_type",
724
14
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
725
726
14
    { &hf_wifi_dpp_tcp_oui,
727
14
      { "DPP TCP PDU OUI", "dpp.tcp.oui",
728
14
        FT_UINT24, BASE_OUI, NULL, 0x0, NULL, HFILL }},
729
730
14
    { &hf_wifi_dpp_tcp_oui_type,
731
14
      { "DPP TCP PDU OUI type", "dpp.tcp.oui_type",
732
14
        FT_UINT8, BASE_DEC, VALS(wfa_subtype_vals), 0, NULL, HFILL }},
733
734
14
    { &hf_wifi_dpp_tcp_dialog_token,
735
14
      { "DPP TCP PDU Dialog Token", "dpp.tcp.dialog_token",
736
14
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
737
738
14
    { &hf_wifi_dpp_tcp_adv_proto_elt,
739
14
      { "DPP TCP PDU Advertisement Protocol Element",
740
14
        "dpp.tcp.adv_proto_elt",
741
14
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
742
743
14
    { &hf_wifi_dpp_tcp_vendor_specific,
744
14
      { "DPP TCP PDU Vendor Specific tag", "dpp.tcp.vendor_spec_tag",
745
14
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
746
747
14
    { &hf_wifi_dpp_tcp_vendor_spec_len,
748
14
      { "DPP TCP PDU Vendor Specific len", "dpp.tcp.vendor_spec_len",
749
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
750
751
14
    { &hf_wifi_dpp_tcp_config,
752
14
      { "DPP TCP PDU Configuration", "dpp.tcp.config",
753
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
754
755
14
    { &hf_wifi_dpp_tcp_query_req_len,
756
14
      { "DPP TCP PDU Query Req len", "dpp.tcp.query_req_len",
757
14
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
758
759
14
    { &hf_wifi_dpp_gas_query_resp_frag_id,
760
14
      { "DPP TCP PDU GAS Query Response Fragment ID",
761
14
        "dpp.tp.query_resp_frag_id",
762
14
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
763
764
14
    { &hf_wifi_dpp_tcp_status_code,
765
14
      { "DPP TCP PDU Status Code", "dpp.tcp.status_code",
766
14
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
767
768
14
    { &hf_wifi_dpp_tcp_comeback_delay,
769
14
      { "DPP TCP PDU Comeback Delay", "dpp.tcp.comeback_delay",
770
14
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
771
772
14
    { &hf_wifi_dpp_tcp_query_resp_len,
773
14
      { "DPP TCP PDU Query Resp Len", "dpp.tcp.query_resp_len",
774
14
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
775
14
  };
776
14
  static int *ett[] = {
777
14
    &ett_wifi_dpp_ie_generic,
778
14
    &ett_wifi_dpp_attributes,
779
14
    &ett_wifi_dpp_pa,
780
14
    &ett_wifi_dpp_attribute,
781
14
    &ett_wifi_dpp_attr_header,
782
14
    &ett_wifi_dpp_attr_value,
783
14
  };
784
785
14
  proto_wifi_dpp = proto_register_protocol("Wi-Fi Device Provisioning Protocol", "Wi-Fi DPP", "dpp");
786
14
  proto_register_field_array(proto_wifi_dpp, hf, array_length(hf));
787
14
  proto_register_subtree_array(ett, array_length(ett));
788
789
  /* Register the dissector handles */
790
14
  wifi_dpp_handle = register_dissector("dpp", dissect_wifi_dpp, proto_wifi_dpp);
791
14
  wifi_dpp_tcp_handle = register_dissector("dpp.tcp", dissect_wifi_dpp_tcp_pdus, proto_wifi_dpp);
792
14
  wifi_dpp_ie_handle = register_dissector("dpp.ie", dissect_wifi_dpp_ie, proto_wifi_dpp);
793
14
  wifi_dpp_pubact_handle = register_dissector("dpp.public_action", dissect_wifi_dpp_public_action, proto_wifi_dpp);
794
795
  /* Register the preferred TCP port? Is there one? */
796
14
  wifi_dpp_module = prefs_register_protocol(proto_wifi_dpp, NULL);
797
14
  prefs_register_uint_preference(wifi_dpp_module, "tcp.port", "DPP TCP Port",
798
14
                                 "The TCP port DPP over TCP uses",
799
14
                                 10, &wifi_dpp_tcp_port);
800
14
}
801
802
void
803
proto_reg_handoff_wifi_dpp(void)
804
14
{
805
14
  static bool initialized = false;
806
14
  static int current_port;
807
808
14
  dissector_add_uint("wlan.anqp.wifi_alliance.subtype", WFA_SUBTYPE_DPP, wifi_dpp_handle);
809
14
  dissector_add_uint("wlan.ie.wifi_alliance.subtype", WFA_SUBTYPE_DPP, wifi_dpp_ie_handle);
810
14
  dissector_add_uint("wlan.pa.wifi_alliance.subtype", WFA_SUBTYPE_DPP, wifi_dpp_pubact_handle);
811
812
  /*
813
   * Register the TCP port
814
   */
815
14
  if (!initialized) {
816
14
    initialized = true;
817
14
  } else {
818
0
    dissector_delete_uint("tcp.port", current_port, wifi_dpp_tcp_handle);
819
0
  }
820
821
14
  current_port = wifi_dpp_tcp_port;
822
14
  dissector_add_uint("tcp.port", current_port, wifi_dpp_tcp_handle);
823
14
}
824
825
/*
826
 * Editor modelines
827
 *
828
 * Local Variables:
829
 * c-basic-offset: 2
830
 * tab-width: 8
831
 * indent-tabs-mode: nil
832
 * End:
833
 *
834
 * ex: set shiftwidth=2 tabstop=8 expandtab:
835
 * :indentSize=2:tabSize=8:noTabs=true:
836
 */