2 * Routines for dissection of Group Policy : Encrypted File System Extension
3 * Described in Microsoft document MS-GPEF.pdf
4 * Copyright 2008, Ronnie Sahlberg
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include "packet-windows-common.h"
32 #include <epan/asn1.h>
33 #include "packet-x509af.h"
34 #include "packet-x509if.h"
36 static int proto_gpef
= -1;
37 static int hf_gpef_keycount
= -1;
38 static int hf_gpef_efskey
= -1;
39 static int hf_gpef_efskey_length1
= -1;
40 static int hf_gpef_efskey_length2
= -1;
41 static int hf_gpef_efskey_sid_offset
= -1;
42 static int hf_gpef_efskey_cert_offset
= -1;
43 static int hf_gpef_efskey_cert_length
= -1;
44 static int hf_gpef_efskey_certificate
= -1;
46 static gint ett_gpef
= -1;
47 static gint ett_gpef_efskey
= -1;
50 /* MS-GPEF section 2.2.1.2.2 EfsKey*/
52 dissect_gpef_efskey(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*parent_tree
)
54 proto_item
*item
= NULL
;
55 proto_tree
*tree
= NULL
;
56 int old_offset
= offset
;
57 guint32 length1
, sid_offset
;
58 guint32 cert_length
, cert_offset
;
61 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, TRUE
, pinfo
);
64 item
= proto_tree_add_item(parent_tree
, hf_gpef_efskey
, tvb
, -1, -1, ENC_NA
);
65 tree
= proto_item_add_subtree(item
, ett_gpef_efskey
);
69 length1
= tvb_get_letohl(tvb
, offset
);
70 proto_tree_add_item(tree
, hf_gpef_efskey_length1
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
74 proto_tree_add_item(tree
, hf_gpef_efskey_length2
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
78 sid_offset
= tvb_get_letohl(tvb
, offset
);
79 proto_tree_add_item(tree
, hf_gpef_efskey_sid_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
86 cert_length
= tvb_get_letohl(tvb
, offset
);
87 proto_tree_add_item(tree
, hf_gpef_efskey_cert_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
91 cert_offset
= tvb_get_letohl(tvb
, offset
);
92 proto_tree_add_item(tree
, hf_gpef_efskey_cert_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
95 /* reserved, must be 0x20 0x00 0x00 0x00 */
99 dissect_nt_sid(tvb
, old_offset
+4+sid_offset
, tree
, "sid", NULL
, -1);
102 next_tvb
= tvb_new_subset(tvb
, old_offset
+4+cert_offset
, cert_length
, cert_length
);
103 (void)dissect_x509af_Certificate(FALSE
, next_tvb
, 0, &asn1_ctx
, tree
, hf_gpef_efskey_certificate
);
106 offset
= old_offset
+ length1
;
107 proto_item_set_len(item
, offset
-old_offset
);
111 /* MS-GPEF section 2.2.1.2.1 */
113 dissect_gpef_efsblob(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*parent_tree
, void *data _U_
)
116 proto_tree
*tree
= NULL
;
117 proto_item
*item
= NULL
;
121 item
= proto_tree_add_item(parent_tree
, proto_gpef
, tvb
, 0, -1, ENC_NA
);
122 tree
= proto_item_add_subtree(item
, ett_gpef
);
125 /* reserved, must be 0x01 0x00 0x01 0x00 */
129 count
= tvb_get_letohl(tvb
, offset
);
130 proto_tree_add_item(tree
, hf_gpef_keycount
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
134 offset
= dissect_gpef_efskey(tvb
, offset
, pinfo
, tree
);
141 proto_register_gpef(void)
143 static hf_register_info hf
[] = {
145 { "Key Count", "gpef.key_count", FT_UINT32
, BASE_DEC
, NULL
,
148 { &hf_gpef_efskey_length1
,
149 { "Length1", "gpef.efskey.length1", FT_UINT32
, BASE_DEC
, NULL
,
152 { &hf_gpef_efskey_length2
,
153 { "Length2", "gpef.efskey.length2", FT_UINT32
, BASE_DEC
, NULL
,
156 { &hf_gpef_efskey_sid_offset
,
157 { "SID Offset", "gpef.efskey.sid_offset", FT_UINT32
, BASE_DEC
, NULL
,
160 { &hf_gpef_efskey_cert_offset
,
161 { "Cert Offset", "gpef.efskey.cert_offset", FT_UINT32
, BASE_DEC
, NULL
,
164 { &hf_gpef_efskey_cert_length
,
165 { "Cert Length", "gpef.efskey.cert_length", FT_UINT32
, BASE_DEC
, NULL
,
169 { "EfsKey", "gpef.efskey", FT_NONE
, BASE_NONE
, NULL
,
172 { &hf_gpef_efskey_certificate
,
173 { "Certificate", "gpef.efskey.certificate", FT_NONE
, BASE_NONE
, NULL
,
178 static gint
*ett
[] = {
183 proto_gpef
= proto_register_protocol("GPEF", "GPEF", "gpef");
184 proto_register_field_array(proto_gpef
, hf
, array_length(hf
));
185 proto_register_subtree_array(ett
, array_length(ett
));
187 new_register_dissector("efsblob", dissect_gpef_efsblob
, proto_gpef
);
191 proto_reg_handoff_gpef(void)