Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-gpef.c
Line
Count
Source
1
/* packet-gpef.c
2
 * Routines for dissection of Group Policy : Encrypted File System Extension
3
 * Described in Microsoft document MS-GPEF.pdf
4
 * Copyright 2008, Ronnie Sahlberg
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include "packet-windows-common.h"
17
#include <epan/asn1.h>
18
#include "packet-x509af.h"
19
20
void proto_register_gpef(void);
21
22
static int proto_gpef;
23
static int hf_gpef_keycount;
24
static int hf_gpef_efskey;
25
static int hf_gpef_efskey_length1;
26
static int hf_gpef_efskey_length2;
27
static int hf_gpef_efskey_sid_offset;
28
static int hf_gpef_efskey_cert_offset;
29
static int hf_gpef_efskey_cert_length;
30
static int hf_gpef_efskey_certificate;
31
32
static int ett_gpef;
33
static int ett_gpef_efskey;
34
35
36
/* MS-GPEF section 2.2.1.2.2 EfsKey*/
37
static int
38
dissect_gpef_efskey(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
39
0
{
40
0
  proto_item *item = NULL;
41
0
  proto_tree *tree = NULL;
42
0
  int old_offset = offset;
43
0
  uint32_t length1, sid_offset;
44
0
  uint32_t cert_length, cert_offset;
45
0
  tvbuff_t *next_tvb;
46
0
  asn1_ctx_t asn1_ctx;
47
0
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
48
49
0
  if (parent_tree) {
50
0
    item = proto_tree_add_item(parent_tree, hf_gpef_efskey, tvb, 0, -1, ENC_NA);
51
0
    tree = proto_item_add_subtree(item, ett_gpef_efskey);
52
0
  }
53
54
  /* length 1 */
55
0
  proto_tree_add_item_ret_uint(tree, hf_gpef_efskey_length1, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length1);
56
0
  offset += 4;
57
58
  /* length 2 */
59
0
  proto_tree_add_item(tree, hf_gpef_efskey_length2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
60
0
  offset += 4;
61
62
  /* sid offset */
63
0
  proto_tree_add_item_ret_uint(tree, hf_gpef_efskey_sid_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &sid_offset);
64
0
  offset += 4;
65
66
  /* reserved */
67
0
  offset += 4;
68
69
  /* cert length */
70
0
  proto_tree_add_item_ret_uint(tree, hf_gpef_efskey_cert_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &cert_length);
71
0
  offset += 4;
72
73
  /* cert offset */
74
0
  proto_tree_add_item_ret_uint(tree, hf_gpef_efskey_cert_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &cert_offset);
75
  /*offset += 4;*/
76
77
  /* reserved, must be 0x20 0x00 0x00 0x00 */
78
  /*offset += 4;*/
79
80
  /* sid */
81
0
  dissect_nt_sid(tvb, pinfo, old_offset+4+sid_offset, tree, "sid", NULL, -1);
82
83
  /* certificate */
84
0
  next_tvb = tvb_new_subset_length(tvb, old_offset+4+cert_offset, cert_length);
85
0
  (void)dissect_x509af_Certificate(false, next_tvb, 0, &asn1_ctx, tree, hf_gpef_efskey_certificate);
86
87
88
0
  offset = old_offset + length1;
89
0
  proto_item_set_len(item, offset-old_offset);
90
0
  return offset;
91
0
}
92
93
/* MS-GPEF section 2.2.1.2.1 */
94
static int
95
dissect_gpef_efsblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
96
0
{
97
0
  unsigned offset = 0;
98
0
  proto_tree *tree;
99
0
  proto_item *item;
100
0
  uint32_t count;
101
102
0
  item = proto_tree_add_item(parent_tree, proto_gpef, tvb, 0, -1, ENC_NA);
103
0
  tree = proto_item_add_subtree(item, ett_gpef);
104
105
  /* reserved, must be 0x01 0x00 0x01 0x00 */
106
0
  offset += 4;
107
108
  /* key count */
109
0
  proto_tree_add_item_ret_uint(tree, hf_gpef_keycount, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count);
110
0
  offset += 4;
111
112
0
  while (count--) {
113
0
        offset = dissect_gpef_efskey(tvb, offset, pinfo, tree);
114
0
  }
115
116
0
  return offset;
117
0
}
118
119
void
120
proto_register_gpef(void)
121
16
{
122
16
  static hf_register_info hf[] = {
123
16
    { &hf_gpef_keycount,
124
16
      { "Key Count",   "gpef.key_count", FT_UINT32, BASE_DEC, NULL,
125
16
        0x0, NULL, HFILL }},
126
127
16
    { &hf_gpef_efskey_length1,
128
16
      { "Length1",   "gpef.efskey.length1", FT_UINT32, BASE_DEC, NULL,
129
16
        0x0, NULL, HFILL }},
130
131
16
    { &hf_gpef_efskey_length2,
132
16
      { "Length2",   "gpef.efskey.length2", FT_UINT32, BASE_DEC, NULL,
133
16
        0x0, NULL, HFILL }},
134
135
16
    { &hf_gpef_efskey_sid_offset,
136
16
      { "SID Offset",   "gpef.efskey.sid_offset", FT_UINT32, BASE_DEC, NULL,
137
16
        0x0, NULL, HFILL }},
138
139
16
    { &hf_gpef_efskey_cert_offset,
140
16
      { "Cert Offset",   "gpef.efskey.cert_offset", FT_UINT32, BASE_DEC, NULL,
141
16
        0x0, NULL, HFILL }},
142
143
16
    { &hf_gpef_efskey_cert_length,
144
16
      { "Cert Length",   "gpef.efskey.cert_length", FT_UINT32, BASE_DEC, NULL,
145
16
        0x0, NULL, HFILL }},
146
147
16
    { &hf_gpef_efskey,
148
16
      { "EfsKey",   "gpef.efskey", FT_NONE, BASE_NONE, NULL,
149
16
        0x0, NULL, HFILL }},
150
151
16
    { &hf_gpef_efskey_certificate,
152
16
      { "Certificate", "gpef.efskey.certificate", FT_NONE, BASE_NONE, NULL,
153
16
        0x0, NULL, HFILL }},
154
155
16
  };
156
157
16
  static int *ett[] = {
158
16
    &ett_gpef,
159
16
    &ett_gpef_efskey,
160
16
  };
161
162
16
  proto_gpef = proto_register_protocol("GPEF", "GPEF", "gpef");
163
16
  proto_register_field_array(proto_gpef, hf, array_length(hf));
164
16
  proto_register_subtree_array(ett, array_length(ett));
165
166
16
  register_dissector("efsblob", dissect_gpef_efsblob, proto_gpef);
167
16
}
168
169
/*
170
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
171
 *
172
 * Local variables:
173
 * c-basic-offset: 8
174
 * tab-width: 8
175
 * indent-tabs-mode: t
176
 * End:
177
 *
178
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
179
 * :indentSize=8:tabSize=8:noTabs=false:
180
 */