2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
6 * $Id: packet-kerberos.c,v 1.25 2002/08/28 21:00:19 jmayer Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #include <epan/packet.h>
39 #include <epan/strutil.h>
42 #include "packet-netbios.h"
44 #define UDP_PORT_KERBEROS 88
45 #define TCP_PORT_KERBEROS 88
47 static gint proto_kerberos = -1;
49 static gint ett_kerberos = -1;
50 static gint ett_preauth = -1;
51 static gint ett_addresses = -1;
52 static gint ett_request = -1;
53 static gint ett_princ = -1;
54 static gint ett_ticket = -1;
55 static gint ett_encrypted = -1;
56 static gint ett_etype = -1;
57 static gint ett_additional_tickets = -1;
59 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
60 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
61 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
62 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
63 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
64 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
66 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
67 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
68 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
69 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
71 /* Type tags within KDC-REQ */
72 #define KRB5_KDC_REQ_PVNO 1
73 #define KRB5_KDC_REQ_MSG_TYPE 2
74 #define KRB5_KDC_REQ_PADATA 3
75 #define KRB5_KDC_REQ_REQBODY 4
77 /* Type tags within KDC-REP */
78 #define KRB5_KDC_REP_PVNO 0
79 #define KRB5_KDC_REP_MSG_TYPE 1
80 #define KRB5_KDC_REP_PADATA 2
81 #define KRB5_KDC_REP_CREALM 3
82 #define KRB5_KDC_REP_CNAME 4
83 #define KRB5_KDC_REP_TICKET 5
84 #define KRB5_KDC_REP_ENC_PART 6
86 /* Type tags within KDC-REQ-BODY */
87 #define KRB5_BODY_KDC_OPTIONS 0
88 #define KRB5_BODY_CNAME 1
89 #define KRB5_BODY_REALM 2
90 #define KRB5_BODY_SNAME 3
91 #define KRB5_BODY_FROM 4
92 #define KRB5_BODY_TILL 5
93 #define KRB5_BODY_RTIME 6
94 #define KRB5_BODY_NONCE 7
95 #define KRB5_BODY_ENCTYPE 8
96 #define KRB5_BODY_ADDRESSES 9
97 #define KRB5_BODY_ENC_AUTHORIZATION_DATA 10
98 #define KRB5_BODY_ADDITIONAL_TICKETS 11
100 /* Type tags within KRB-ERROR */
101 #define KRB5_ERROR_PVNO 0
102 #define KRB5_ERROR_MSG_TYPE 1
103 #define KRB5_ERROR_CTIME 2
104 #define KRB5_ERROR_CUSEC 3
105 #define KRB5_ERROR_STIME 4
106 #define KRB5_ERROR_SUSEC 5
107 #define KRB5_ERROR_ERROR_CODE 6
108 #define KRB5_ERROR_CREALM 7
109 #define KRB5_ERROR_CNAME 8
110 #define KRB5_ERROR_REALM 9
111 #define KRB5_ERROR_SNAME 10
112 #define KRB5_ERROR_ETEXT 11
113 #define KRB5_ERROR_EDATA 12
115 /* address type constants */
116 #define KRB5_ADDR_IPv4 0x02
117 #define KRB5_ADDR_CHAOS 0x05
118 #define KRB5_ADDR_XEROX 0x06
119 #define KRB5_ADDR_ISO 0x07
120 #define KRB5_ADDR_DECNET 0x0c
121 #define KRB5_ADDR_APPLETALK 0x10
122 #define KRB5_ADDR_NETBIOS 0x14
124 /* encryption type constants */
125 #define KRB5_ENCTYPE_NULL 0
126 #define KRB5_ENCTYPE_DES_CBC_CRC 1
127 #define KRB5_ENCTYPE_DES_CBC_MD4 2
128 #define KRB5_ENCTYPE_DES_CBC_MD5 3
129 #define KRB5_ENCTYPE_DES_CBC_RAW 4
130 #define KRB5_ENCTYPE_DES3_CBC_SHA 5
131 #define KRB5_ENCTYPE_DES3_CBC_RAW 6
132 #define KRB5_ENCTYPE_DES_HMAC_SHA1 8
133 #define KRB5_ENCTYPE_DES3_CBC_SHA1 0x10
134 #define KRB5_ENCTYPE_UNKNOWN 0x1ff
135 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
137 /* pre-authentication type constants */
138 #define KRB5_PA_TGS_REQ 1
139 #define KRB5_PA_ENC_TIMESTAMP 2
140 #define KRB5_PA_PW_SALT 3
141 #define KRB5_PA_ENC_ENCKEY 4
142 #define KRB5_PA_ENC_UNIX_TIME 5
143 #define KRB5_PA_ENC_SANDIA_SECURID 6
144 #define KRB5_PA_SESAME 7
145 #define KRB5_PA_OSF_DCE 8
146 #define KRB5_PA_CYBERSAFE_SECUREID 9
147 #define KRB5_PA_AFS3_SALT 10
148 #define KRB5_PA_ENCTYPE_INFO 11
149 #define KRB5_PA_SAM_CHALLENGE 12
150 #define KRB5_PA_SAM_RESPONSE 13
151 #define KRB5_PA_DASS 16
153 /* Type tags within Ticket */
154 #define KRB5_TKT_TKT_VNO 0
155 #define KRB5_TKT_REALM 1
156 #define KRB5_TKT_SNAME 2
157 #define KRB5_TKT_ENC_PART 3
159 /* Principal name-type */
160 #define KRB5_NT_UNKNOWN 0
161 #define KRB5_NT_PRINCIPAL 1
162 #define KRB5_NT_SRV_INST 2
163 #define KRB5_NT_SRV_HST 3
164 #define KRB5_NT_SRV_XHST 4
165 #define KRB5_NT_UID 5
167 /* error table constants */
168 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
169 #define KRB5_ET_KRB5KDC_ERR_NONE 0
170 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
171 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
172 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
173 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
174 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
175 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
176 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
177 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
178 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
179 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
180 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
181 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
182 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
183 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
184 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
185 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
186 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
187 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
188 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
189 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
190 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
191 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
192 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
193 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
194 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
195 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
196 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
197 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
198 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
199 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
200 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
201 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
202 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
203 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
204 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
205 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
206 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
207 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
208 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
209 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
210 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
211 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
212 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
213 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
214 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
215 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
216 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
217 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
219 static const value_string krb5_error_codes[] = {
220 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
221 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
222 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
223 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
224 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
225 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
226 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
227 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
228 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
229 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
230 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
231 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
232 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
233 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
234 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
235 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
236 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
237 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
238 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
239 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
240 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
241 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
242 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
243 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
244 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
245 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
246 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
247 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
248 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
249 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
250 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
251 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
252 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
253 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
254 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
255 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
256 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
257 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
258 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
259 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
260 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
261 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
262 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
263 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
264 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
265 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
266 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
267 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
268 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
273 static const value_string krb5_princ_types[] = {
274 { KRB5_NT_UNKNOWN , "Unknown" },
275 { KRB5_NT_PRINCIPAL , "Principal" },
276 { KRB5_NT_SRV_INST , "Service and Instance" },
277 { KRB5_NT_SRV_HST , "Service and Host" },
278 { KRB5_NT_SRV_XHST , "Service and Host Components" },
279 { KRB5_NT_UID , "Unique ID" },
283 static const value_string krb5_preauthentication_types[] = {
284 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
285 { KRB5_PA_ENC_TIMESTAMP , "PA-ENC-TIMESTAMP" },
286 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
287 { KRB5_PA_ENC_ENCKEY , "PA-ENC-ENCKEY" },
288 { KRB5_PA_ENC_UNIX_TIME , "PA-ENC-UNIX-TIME" },
289 { KRB5_PA_ENC_SANDIA_SECURID , "PA-PW-SALT" },
290 { KRB5_PA_SESAME , "PA-SESAME" },
291 { KRB5_PA_OSF_DCE , "PA-OSF-DCE" },
292 { KRB5_PA_CYBERSAFE_SECUREID , "PA-CYBERSAFE-SECURID" },
293 { KRB5_PA_AFS3_SALT , "PA-AFS3-SALT" },
294 { KRB5_PA_ENCTYPE_INFO , "PA-ENCTYPE-INFO" },
295 { KRB5_PA_SAM_CHALLENGE , "PA-SAM-CHALLENGE" },
296 { KRB5_PA_SAM_RESPONSE , "PA-SAM-RESPONSE" },
297 { KRB5_PA_DASS , "PA-DASS" },
301 static const value_string krb5_encryption_types[] = {
302 { KRB5_ENCTYPE_NULL , "NULL" },
303 { KRB5_ENCTYPE_DES_CBC_CRC , "des-cbc-crc" },
304 { KRB5_ENCTYPE_DES_CBC_MD4 , "des-cbc-md4" },
305 { KRB5_ENCTYPE_DES_CBC_MD5 , "des-cbc-md5" },
306 { KRB5_ENCTYPE_DES_CBC_RAW , "des-cbc-raw" },
307 { KRB5_ENCTYPE_DES3_CBC_SHA , "des3-cbc-sha" },
308 { KRB5_ENCTYPE_DES3_CBC_RAW , "des3-cbc-raw" },
309 { KRB5_ENCTYPE_DES_HMAC_SHA1 , "des-hmac-sha1" },
310 { KRB5_ENCTYPE_DES3_CBC_SHA1 , "des3-cbc-sha1" },
311 { KRB5_ENCTYPE_UNKNOWN , "unknown" },
312 { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 , "local-des3-hmac-sha1" },
316 static const value_string krb5_address_types[] = {
317 { KRB5_ADDR_IPv4, "IPv4"},
318 { KRB5_ADDR_CHAOS, "CHAOS"},
319 { KRB5_ADDR_XEROX, "XEROX"},
320 { KRB5_ADDR_ISO, "ISO"},
321 { KRB5_ADDR_DECNET, "DECNET"},
322 { KRB5_ADDR_APPLETALK, "APPLETALK"},
323 { KRB5_ADDR_NETBIOS, "NETBIOS"},
327 static const value_string krb5_msg_types[] = {
328 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
329 { KRB5_MSG_TGS_REP, "TGS-REP" },
330 { KRB5_MSG_AS_REQ, "AS-REQ" },
331 { KRB5_MSG_AS_REP, "AS-REP" },
332 { KRB5_MSG_AP_REQ, "AP-REQ" },
333 { KRB5_MSG_AP_REP, "AP-REP" },
334 { KRB5_MSG_SAFE, "KRB-SAFE" },
335 { KRB5_MSG_PRIV, "KRB-PRIV" },
336 { KRB5_MSG_CRED, "KRB-CRED" },
337 { KRB5_MSG_ERROR, "KRB-ERROR" },
341 static int dissect_PrincipalName(char *title, ASN1_SCK *asn1p,
342 packet_info *pinfo, proto_tree *tree,
344 static int dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
345 proto_tree *tree, int start_offset);
346 static int dissect_EncryptedData(char *title, ASN1_SCK *asn1p,
347 packet_info *pinfo, proto_tree *tree,
349 static int dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
350 proto_tree *tree, int start_offset);
353 to_error_str(int ret) {
356 case ASN1_ERR_EOC_MISMATCH:
357 return("EOC mismatch");
359 case ASN1_ERR_WRONG_TYPE:
360 return("Wrong type for that item");
362 case ASN1_ERR_LENGTH_NOT_DEFINITE:
363 return("Length was indefinite");
365 case ASN1_ERR_LENGTH_MISMATCH:
366 return("Length mismatch");
368 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
369 return("Wrong length for that item's type");
372 return("Unknown error");
376 krb_proto_tree_add_time(proto_tree *tree, tvbuff_t *tvb, int offset,
377 int str_len, char *name, guchar *str)
380 proto_tree_add_text(tree, tvb, offset, str_len,
381 "%s: %.4s-%.2s-%.2s %.2s:%.2s:%.2s (%.1s)",
382 name, str, str+4, str+6,
383 str+8, str+10, str+12,
389 * You must be kidding. I'm going to actually use a macro to do something?
393 #define KRB_HEAD_DECODE_OR_DIE(token) \
394 start = asn1p->offset; \
395 ret = asn1_header_decode (asn1p, &cls, &con, &tag, &def, &item_len); \
396 if (ret != ASN1_ERR_NOERROR) {\
397 if (check_col(pinfo->cinfo, COL_INFO)) \
398 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
399 token, to_error_str(ret)); \
403 if (check_col(pinfo->cinfo, COL_INFO)) \
404 col_add_fstr(pinfo->cinfo, COL_INFO, "not definite: %s", token); \
405 fprintf(stderr,"not definite: %s\n", token); \
408 offset += (asn1p->offset - start);
410 #define CHECK_APPLICATION_TYPE(expected_tag) \
411 (cls == ASN1_APL && con == ASN1_CON && tag == expected_tag)
413 #define DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag) \
414 if (!CHECK_APPLICATION_TYPE(expected_tag)) \
415 DIE_WITH_BAD_TYPE(token, expected_tag);
417 #define CHECK_CONTEXT_TYPE(expected_tag) \
418 (cls == ASN1_CTX && con == ASN1_CON && tag == expected_tag)
420 #define DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag) \
421 if (!CHECK_CONTEXT_TYPE(expected_tag)) \
422 DIE_WITH_BAD_TYPE(token, expected_tag);
424 #define DIE_WITH_BAD_TYPE(token, expected_tag) \
426 if (check_col(pinfo->cinfo, COL_INFO)) \
427 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s (tag=%d exp=%d)", \
428 token, to_error_str(ASN1_ERR_WRONG_TYPE), tag, expected_tag); \
432 #define KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE(token, expected_tag) \
433 KRB_HEAD_DECODE_OR_DIE(token); \
434 DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag);
436 #define KRB_DECODE_CONTEXT_HEAD_OR_DIE(token, expected_tag) \
437 KRB_HEAD_DECODE_OR_DIE(token); \
438 DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag);
440 #define KRB_SEQ_HEAD_DECODE_OR_DIE(token) \
441 ret = asn1_sequence_decode (asn1p, &item_len, &header_len); \
442 if (ret != ASN1_ERR_NOERROR) {\
443 if (check_col(pinfo->cinfo, COL_INFO)) \
444 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
445 token, to_error_str(ret)); \
448 offset += header_len;
450 #define KRB_DECODE_OR_DIE(token, fn, val) \
451 ret = fn (asn1p, &val, &length); \
452 if (ret != ASN1_ERR_NOERROR) { \
453 if (check_col(pinfo->cinfo, COL_INFO)) \
454 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
455 token, to_error_str(ret)); \
459 #define KRB_DECODE_UINT32_OR_DIE(token, val) \
460 KRB_DECODE_OR_DIE(token, asn1_uint32_decode, val);
462 #define KRB_DECODE_STRING_OR_DIE(token, expected_tag, val, val_len, item_len) \
463 ret = asn1_string_decode (asn1p, &val, &val_len, &item_len, expected_tag); \
464 if (ret != ASN1_ERR_NOERROR) { \
465 if (check_col(pinfo->cinfo, COL_INFO)) \
466 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
467 token, to_error_str(ret)); \
471 #define KRB_DECODE_OCTET_STRING_OR_DIE(token, val, val_len, item_len) \
472 KRB_DECODE_STRING_OR_DIE(token, ASN1_OTS, val, val_len, item_len)
474 #define KRB_DECODE_GENERAL_STRING_OR_DIE(token, val, val_len, item_len) \
475 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENSTR, val, val_len, item_len)
477 #define KRB_DECODE_GENERAL_TIME_OR_DIE(token, val, val_len, item_len) \
478 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENTIM, val, val_len, item_len)
480 /* dissect_type_value_pair decodes (roughly) this:
487 which is all over the place in krb5 */
490 dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
491 guint32 *type, int *type_len, int *type_off,
492 guchar **val, int *val_len, int *val_off) {
501 start = asn1p->offset;
502 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
503 offset += (asn1p->offset - start);
507 start = asn1p->offset;
508 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
509 offset += (asn1p->offset - start);
515 ret = asn1_uint32_decode(asn1p, type, type_len);
516 if (ret != ASN1_ERR_NOERROR) {
517 fprintf(stderr,"die: type_value_pair: type, %s\n", to_error_str(ret));
522 /* OCTET STRING (or generic data) */
524 start = asn1p->offset;
525 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
526 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
527 offset += asn1p->offset - start;
533 asn1_string_value_decode (asn1p, *val_len, val);
535 *inoff = offset + *val_len;
539 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
542 proto_tree *kerberos_tree = NULL;
543 proto_tree *etype_tree = NULL;
544 proto_tree *preauth_tree = NULL;
545 proto_tree *request_tree = NULL;
546 proto_tree *additional_tickets_tree = NULL;
547 ASN1_SCK asn1, *asn1p = &asn1;
548 proto_item *item = NULL;
555 int start, end, message_end, sequence_end;
559 guint protocol_message_type;
563 guint32 preauth_type;
569 int tmp_pos1, tmp_pos2;
571 asn1_open(&asn1, tvb, 0);
574 KRB_HEAD_DECODE_OR_DIE("top");
575 protocol_message_type = tag;
577 item = proto_tree_add_item(tree, proto_kerberos, tvb, offset,
579 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
581 message_end = asn1p->offset + item_len;
584 KRB_HEAD_DECODE_OR_DIE("top2");
587 KRB_HEAD_DECODE_OR_DIE("version-wrap");
588 KRB_DECODE_UINT32_OR_DIE("version", version);
591 proto_tree_add_text(kerberos_tree, tvb, offset, length,
598 KRB_HEAD_DECODE_OR_DIE("message-type-wrap");
599 KRB_DECODE_UINT32_OR_DIE("message-type", msg_type);
602 proto_tree_add_text(kerberos_tree, tvb, offset, length,
604 val_to_str(msg_type, krb5_msg_types,
605 "Unknown msg type %#x"));
609 if (check_col(pinfo->cinfo, COL_INFO))
610 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(msg_type, krb5_msg_types,
611 "Unknown msg type %#x"));
613 /* is preauthentication present? */
614 KRB_HEAD_DECODE_OR_DIE("padata-or-body");
615 if (((protocol_message_type == KRB5_MSG_AS_REQ ||
616 protocol_message_type == KRB5_MSG_TGS_REQ) &&
617 tag == KRB5_KDC_REQ_PADATA) ||
618 ((protocol_message_type == KRB5_MSG_AS_REP ||
619 protocol_message_type == KRB5_MSG_TGS_REP) &&
620 tag == KRB5_KDC_REP_PADATA)) {
621 /* pre-authentication supplied */
624 item = proto_tree_add_text(kerberos_tree, tvb, offset,
625 item_len, "Pre-Authentication");
626 preauth_tree = proto_item_add_subtree(item, ett_preauth);
629 KRB_HEAD_DECODE_OR_DIE("sequence of pa-data");
630 end = asn1p->offset + item_len;
632 while(asn1p->offset < end) {
633 dissect_type_value_pair(asn1p, &offset,
634 &preauth_type, &item_len, &tmp_pos1,
635 &str, &str_len, &tmp_pos2);
638 proto_tree_add_text(preauth_tree, tvb, tmp_pos1,
639 item_len, "Type: %s",
640 val_to_str(preauth_type,
641 krb5_preauthentication_types,
642 "Unknown preauth type %#x"));
643 proto_tree_add_text(preauth_tree, tvb, tmp_pos2,
644 str_len, "Value: %s",
645 bytes_to_str(str, str_len));
648 KRB_HEAD_DECODE_OR_DIE("message-body");
651 switch (protocol_message_type) {
653 case KRB5_MSG_AS_REQ:
654 case KRB5_MSG_TGS_REQ:
656 AS-REQ ::= [APPLICATION 10] KDC-REQ
657 TGS-REQ ::= [APPLICATION 12] KDC-REQ
659 KDC-REQ ::= SEQUENCE {
662 padata[3] SEQUENCE OF PA-DATA OPTIONAL,
663 req-body[4] KDC-REQ-BODY
666 KDC-REQ-BODY ::= SEQUENCE {
667 kdc-options[0] KDCOptions,
668 cname[1] PrincipalName OPTIONAL,
669 -- Used only in AS-REQ
670 realm[2] Realm, -- Server's realm
671 -- Also client's in AS-REQ
672 sname[3] PrincipalName OPTIONAL,
673 from[4] KerberosTime OPTIONAL,
674 till[5] KerberosTime,
675 rtime[6] KerberosTime OPTIONAL,
677 etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
678 -- in preference order
679 addresses[9] HostAddresses OPTIONAL,
680 enc-authorization-data[10] EncryptedData OPTIONAL,
681 -- Encrypted AuthorizationData encoding
682 additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
687 KRB_HEAD_DECODE_OR_DIE("body-sequence");
689 item = proto_tree_add_text(kerberos_tree, tvb, offset,
690 item_len, "Request");
691 request_tree = proto_item_add_subtree(item, ett_request);
693 sequence_end = asn1p->offset + item_len;
696 KRB_HEAD_DECODE_OR_DIE("kdc options");
698 KRB_HEAD_DECODE_OR_DIE("kdc options:bits");
701 proto_tree_add_text(request_tree, tvb, offset, item_len,
703 tvb_bytes_to_str(asn1p->tvb, asn1p->offset,
707 asn1p->offset += item_len;
709 KRB_HEAD_DECODE_OR_DIE("Client Name or Realm");
711 if (CHECK_CONTEXT_TYPE(KRB5_BODY_CNAME)) {
712 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
713 request_tree, offset);
717 KRB_HEAD_DECODE_OR_DIE("Realm");
720 DIE_IF_NOT_CONTEXT_TYPE("Realm", KRB5_BODY_REALM);
721 KRB_DECODE_GENERAL_STRING_OR_DIE("Realm", str, str_len, item_len);
723 proto_tree_add_text(request_tree, tvb, offset, item_len,
724 "Realm: %.*s", str_len, str);
728 KRB_HEAD_DECODE_OR_DIE("Server Name");
729 if (CHECK_CONTEXT_TYPE(KRB5_BODY_SNAME)) {
730 item_len = dissect_PrincipalName("Server Name", asn1p, pinfo,
731 request_tree, offset);
735 KRB_HEAD_DECODE_OR_DIE("From or Till");
738 if (CHECK_CONTEXT_TYPE(KRB5_BODY_FROM)) {
739 KRB_DECODE_GENERAL_TIME_OR_DIE("From", str, str_len, item_len);
740 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
743 KRB_HEAD_DECODE_OR_DIE("Till");
746 DIE_IF_NOT_CONTEXT_TYPE("Till", KRB5_BODY_TILL);
747 KRB_DECODE_GENERAL_TIME_OR_DIE("Till", str, str_len, item_len);
748 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
752 KRB_HEAD_DECODE_OR_DIE("Renewable Until or Nonce");
753 if (CHECK_CONTEXT_TYPE(KRB5_BODY_RTIME)) {
754 KRB_DECODE_GENERAL_TIME_OR_DIE("Renewable Until", str, str_len, item_len);
755 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
756 "Renewable Until", str);
758 KRB_HEAD_DECODE_OR_DIE("Nonce");
761 DIE_IF_NOT_CONTEXT_TYPE("Nonce", KRB5_BODY_NONCE);
762 KRB_DECODE_UINT32_OR_DIE("Nonce", tmp_int);
764 proto_tree_add_text(request_tree, tvb, offset, length,
770 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type spot",
772 KRB_HEAD_DECODE_OR_DIE("encryption type list");
774 item = proto_tree_add_text(request_tree, tvb, offset,
775 item_len, "Encryption Types");
776 etype_tree = proto_item_add_subtree(item, ett_etype);
778 total_len = item_len;
779 while(total_len > 0) {
780 KRB_DECODE_UINT32_OR_DIE("encryption type", tmp_int);
782 proto_tree_add_text(etype_tree, tvb, offset, length,
785 krb5_encryption_types,
786 "Unknown encryption type %#x"));
792 if (asn1p->offset >= sequence_end)
794 KRB_HEAD_DECODE_OR_DIE("addresses or enc-authorization-data");
795 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ADDRESSES)) {
796 /* addresses supplied */
798 length = dissect_Addresses(asn1p, pinfo, kerberos_tree,
803 if (asn1p->offset >= sequence_end)
805 KRB_HEAD_DECODE_OR_DIE("enc-authorization-data or additional-tickets");
808 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ENC_AUTHORIZATION_DATA)) {
809 /* enc-authorization-data supplied */
810 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
811 kerberos_tree, offset);
815 if (asn1p->offset >= sequence_end)
817 KRB_HEAD_DECODE_OR_DIE("additional-tickets");
820 /* additional-tickets supplied */
822 item = proto_tree_add_text(kerberos_tree, tvb, offset,
823 item_len, "Additional Tickets");
824 additional_tickets_tree = proto_item_add_subtree(item, ett_additional_tickets);
826 end = asn1p->offset + item_len;
827 while(asn1p->offset < end) {
828 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
829 length = dissect_Ticket(asn1p, pinfo, additional_tickets_tree,
838 case KRB5_MSG_AS_REP:
839 case KRB5_MSG_TGS_REP:
841 AS-REP ::= [APPLICATION 11] KDC-REP
842 TGS-REP ::= [APPLICATION 13] KDC-REP
844 KDC-REP ::= SEQUENCE {
847 padata[2] SEQUENCE OF PA-DATA OPTIONAL,
849 cname[4] PrincipalName,
851 enc-part[6] EncryptedData
855 DIE_IF_NOT_CONTEXT_TYPE("crealm", KRB5_KDC_REP_CREALM);
856 KRB_DECODE_GENERAL_STRING_OR_DIE("realm name", str, str_len, item_len);
858 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
859 "Realm: %.*s", str_len, str);
863 KRB_DECODE_CONTEXT_HEAD_OR_DIE("cname", KRB5_KDC_REP_CNAME);
864 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
865 kerberos_tree, offset);
870 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
871 length = dissect_Ticket(asn1p, pinfo, kerberos_tree, offset);
876 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-msg-part",
877 KRB5_KDC_REP_ENC_PART);
878 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
879 kerberos_tree, offset);
887 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
890 ctime[2] KerberosTime OPTIONAL,
891 cusec[3] INTEGER OPTIONAL,
892 stime[4] KerberosTime,
894 error-code[6] INTEGER,
895 crealm[7] Realm OPTIONAL,
896 cname[8] PrincipalName OPTIONAL,
897 realm[9] Realm, -- Correct realm
898 sname[10] PrincipalName, -- Correct name
899 e-text[11] GeneralString OPTIONAL,
900 e-data[12] OCTET STRING OPTIONAL
907 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CTIME)) {
908 KRB_DECODE_GENERAL_TIME_OR_DIE("ctime", str, str_len, item_len);
909 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
912 KRB_HEAD_DECODE_OR_DIE("cusec");
916 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CUSEC)) {
917 KRB_DECODE_UINT32_OR_DIE("cusec", tmp_int);
919 proto_tree_add_text(kerberos_tree, tvb, offset, length,
925 KRB_HEAD_DECODE_OR_DIE("sutime");
928 DIE_IF_NOT_CONTEXT_TYPE("sutime", KRB5_ERROR_STIME);
929 KRB_DECODE_GENERAL_TIME_OR_DIE("stime", str, str_len, item_len);
930 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
934 KRB_HEAD_DECODE_OR_DIE("susec");
935 DIE_IF_NOT_CONTEXT_TYPE("susec", KRB5_ERROR_SUSEC);
936 KRB_DECODE_UINT32_OR_DIE("susec", tmp_int);
938 proto_tree_add_text(kerberos_tree, tvb, offset, length,
944 KRB_HEAD_DECODE_OR_DIE("errcode");
945 DIE_IF_NOT_CONTEXT_TYPE("errcode", KRB5_ERROR_ERROR_CODE);
946 KRB_DECODE_UINT32_OR_DIE("errcode", tmp_int);
948 proto_tree_add_text(kerberos_tree, tvb, offset, length,
950 val_to_str(tmp_int, krb5_error_codes,
951 "Unknown error code %#x"));
954 KRB_HEAD_DECODE_OR_DIE("crealm");
956 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CREALM)) {
957 KRB_DECODE_GENERAL_STRING_OR_DIE("crealm", str, str_len, item_len);
959 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
960 "crealm: %.*s", str_len, str);
963 KRB_HEAD_DECODE_OR_DIE("cname");
966 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CNAME)) {
967 item_len = dissect_PrincipalName("cname", asn1p, pinfo,
968 kerberos_tree, offset);
972 KRB_HEAD_DECODE_OR_DIE("realm");
975 DIE_IF_NOT_CONTEXT_TYPE("realm", KRB5_ERROR_REALM);
976 KRB_DECODE_GENERAL_STRING_OR_DIE("realm", str, str_len, item_len);
978 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
979 "realm: %.*s", str_len, str);
982 KRB_HEAD_DECODE_OR_DIE("sname");
984 DIE_IF_NOT_CONTEXT_TYPE("sname", KRB5_ERROR_SNAME);
985 item_len = dissect_PrincipalName("sname", asn1p, pinfo,
986 kerberos_tree, offset);
991 if (asn1p->offset >= message_end)
993 KRB_HEAD_DECODE_OR_DIE("e-text");
994 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_ETEXT) ) {
995 KRB_DECODE_GENERAL_STRING_OR_DIE("etext", str, str_len, item_len);
997 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
998 "etext: %.*s", str_len, str);
1001 if (asn1p->offset >= message_end)
1003 KRB_HEAD_DECODE_OR_DIE("e-data");
1006 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_EDATA) ) {
1010 KRB_DECODE_OCTET_STRING_OR_DIE("e-data", data, data_len, item_len);
1012 if (kerberos_tree) {
1013 proto_tree_add_text(kerberos_tree, tvb, offset, data_len,
1014 "Error Data: %s", bytes_to_str(data, item_len));
1025 dissect_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1027 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1028 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1030 dissect_kerberos_main(tvb, pinfo, tree);
1034 dissect_PrincipalName(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1035 proto_tree *tree, int start_offset)
1038 PrincipalName ::= SEQUENCE {
1039 name-type[0] INTEGER,
1040 name-string[1] SEQUENCE OF GeneralString
1043 proto_tree *princ_tree = NULL;
1044 int offset = start_offset;
1049 guint cls, con, tag;
1050 guint header_len, item_len, total_len, type_len;
1053 proto_item *item = NULL;
1062 /* principal name */
1063 KRB_SEQ_HEAD_DECODE_OR_DIE("principal section");
1066 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1067 (offset - start_offset) + item_len, "%s",
1069 princ_tree = proto_item_add_subtree(item, ett_princ);
1075 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal type", 0);
1076 KRB_DECODE_UINT32_OR_DIE("princ-type", princ_type);
1077 type_offset = offset;
1078 type_len = item_len;
1082 proto_tree_add_text(princ_tree, asn1p->tvb, type_offset, type_len,
1084 val_to_str(princ_type, krb5_princ_types,
1085 "Unknown name type %#x"));
1088 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal name-string", 1);
1089 KRB_SEQ_HEAD_DECODE_OR_DIE("principal name-string sequence-of");
1090 total_len = item_len;
1091 if (total_len == 0) {
1092 /* There are no name strings in this PrincipalName, so we can't
1093 put any in the top-level item. */
1094 return offset - start_offset;
1097 /* Put the first name string in the top-level item. */
1098 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1100 proto_item_set_text(item, "%s: %.*s", title, (int) name_len, name);
1101 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1102 "Name: %.*s", (int) name_len, name);
1104 total_len -= item_len;
1107 /* Now process the rest of the strings.
1108 XXX - put them in the item as well? */
1109 while (total_len > 0) {
1110 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1112 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1113 "Name: %.*s", (int) name_len, name);
1115 total_len -= item_len;
1118 return offset - start_offset;
1122 dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
1123 proto_tree *tree, int start_offset) {
1124 proto_tree *address_tree = NULL;
1125 int offset = start_offset;
1128 guint cls, con, tag;
1132 proto_item *item = NULL;
1135 int tmp_pos1, tmp_pos2;
1136 guint32 address_type;
1141 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1142 int netbios_name_type;
1144 KRB_HEAD_DECODE_OR_DIE("sequence of addresses");
1146 item = proto_tree_add_text(tree, asn1p->tvb, offset,
1147 item_len, "Addresses");
1148 address_tree = proto_item_add_subtree(item, ett_addresses);
1152 end = asn1p->offset + item_len;
1154 while(asn1p->offset < end) {
1155 dissect_type_value_pair(asn1p, &offset,
1156 &address_type, &item_len, &tmp_pos1,
1157 &str, &str_len, &tmp_pos2);
1160 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos1,
1161 item_len, "Type: %s",
1162 val_to_str(address_type, krb5_address_types,
1163 "Unknown address type %#x"));
1164 switch(address_type) {
1165 case KRB5_ADDR_IPv4:
1166 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1167 str_len, "Value: %d.%d.%d.%d",
1168 str[0], str[1], str[2], str[3]);
1171 case KRB5_ADDR_NETBIOS:
1172 if (str_len == NETBIOS_NAME_LEN) {
1173 netbios_name_type = process_netbios_name(str,
1175 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1177 "Value: %s<%02x> (%s)",
1178 netbios_name, netbios_name_type,
1179 netbios_name_type_descr(netbios_name_type));
1181 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1183 "Value (Invalid length %d, should be 16): \"%s\"",
1184 str_len, format_text(str, str_len));
1189 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1190 str_len, "Value: %s",
1191 bytes_to_str(str, str_len));
1196 return offset - start_offset;
1200 dissect_EncryptedData(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1201 proto_tree *tree, int start_offset)
1204 EncryptedData ::= SEQUENCE {
1205 etype[0] INTEGER, -- EncryptionType
1206 kvno[1] INTEGER OPTIONAL,
1207 cipher[2] OCTET STRING -- ciphertext
1210 proto_tree *encr_tree = NULL;
1211 int offset = start_offset;
1214 guint cls, con, tag;
1215 guint header_len, item_len, data_len;
1218 proto_item *item = NULL;
1225 KRB_SEQ_HEAD_DECODE_OR_DIE("encrypted data section");
1228 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1229 (offset - start_offset) + item_len,
1230 "Encrypted Data: %s", title);
1231 encr_tree = proto_item_add_subtree(item, ett_princ);
1235 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type", 0);
1236 KRB_DECODE_UINT32_OR_DIE("encr-type", val);
1238 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1240 val_to_str(val, krb5_encryption_types,
1241 "Unknown encryption type %#x"));
1246 KRB_HEAD_DECODE_OR_DIE("kvno-wrap or cipher-wrap");
1247 if (CHECK_CONTEXT_TYPE(1)) {
1248 KRB_DECODE_UINT32_OR_DIE("kvno", val);
1250 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1254 KRB_HEAD_DECODE_OR_DIE("cipher-wrap");
1257 DIE_IF_NOT_CONTEXT_TYPE("cipher-wrap", 2);
1258 KRB_DECODE_OCTET_STRING_OR_DIE("cipher", data, data_len, item_len);
1261 proto_tree_add_text(encr_tree, asn1p->tvb, offset, data_len,
1262 "CipherText: %s", bytes_to_str(data, item_len));
1266 return offset - start_offset;
1270 dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
1271 proto_tree *tree, int start_offset)
1274 Ticket ::= [APPLICATION 1] SEQUENCE {
1277 sname[2] PrincipalName,
1278 enc-part[3] EncryptedData
1281 proto_tree *ticket_tree = NULL;
1282 int offset = start_offset;
1285 guint cls, con, tag;
1286 guint header_len, total_len;
1290 proto_item *item = NULL;
1298 KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE("Ticket section", 1);
1299 KRB_SEQ_HEAD_DECODE_OR_DIE("Ticket sequence");
1300 total_len = item_len;
1303 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1304 (offset - start_offset) + item_len,
1306 ticket_tree = proto_item_add_subtree(item, ett_ticket);
1310 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket tkt-vno", KRB5_TKT_TKT_VNO);
1311 KRB_DECODE_UINT32_OR_DIE("Ticket tkt-vno", val);
1313 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, length,
1314 "Version: %u", val);
1317 total_len -= length;
1320 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket realm", KRB5_TKT_REALM);
1321 KRB_DECODE_GENERAL_STRING_OR_DIE("Ticket realm string", str, str_len, item_len);
1323 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, item_len,
1324 "Realm: %.*s", str_len, str);
1327 total_len -= item_len;
1329 /* server name (sname) */
1330 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket sname", KRB5_TKT_SNAME);
1331 item_len = dissect_PrincipalName("Service Name", asn1p, pinfo, ticket_tree,
1337 /* encrypted part */
1338 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-part", KRB5_TKT_ENC_PART);
1339 length = dissect_EncryptedData("Ticket data", asn1p, pinfo, ticket_tree,
1345 return offset - start_offset;
1350 proto_register_kerberos(void) {
1352 static hf_register_info hf[] = {
1355 static gint *ett[] = {
1364 &ett_additional_tickets,
1366 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
1368 proto_register_field_array(proto_kerberos, hf, array_length(hf));
1370 proto_register_subtree_array(ett, array_length(ett));
1374 proto_reg_handoff_kerberos(void)
1376 dissector_handle_t kerberos_handle;
1378 kerberos_handle = create_dissector_handle(dissect_kerberos, proto_kerberos);
1379 dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle);
1380 dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle);
1385 MISC definitions from RFC1510:
1387 Realm ::= GeneralString
1389 KerberosTime ::= GeneralizedTime
1391 HostAddress ::= SEQUENCE {
1392 addr-type[0] INTEGER,
1393 address[1] OCTET STRING
1396 HostAddresses ::= SEQUENCE OF SEQUENCE {
1397 addr-type[0] INTEGER,
1398 address[1] OCTET STRING
1401 AuthorizationData ::= SEQUENCE OF SEQUENCE {
1403 ad-data[1] OCTET STRING
1405 APOptions ::= BIT STRING {
1412 TicketFlags ::= BIT STRING {
1427 KDCOptions ::= BIT STRING {
1441 enc-tkt-in-skey(28),
1447 LastReq ::= SEQUENCE OF SEQUENCE {
1449 lr-value[1] KerberosTime
1452 Ticket ::= [APPLICATION 1] SEQUENCE {
1455 sname[2] PrincipalName,
1456 enc-part[3] EncryptedData
1459 -- Encrypted part of ticket
1460 EncTicketPart ::= [APPLICATION 3] SEQUENCE {
1461 flags[0] TicketFlags,
1462 key[1] EncryptionKey,
1464 cname[3] PrincipalName,
1465 transited[4] TransitedEncoding,
1466 authtime[5] KerberosTime,
1467 starttime[6] KerberosTime OPTIONAL,
1468 endtime[7] KerberosTime,
1469 renew-till[8] KerberosTime OPTIONAL,
1470 caddr[9] HostAddresses OPTIONAL,
1471 authorization-data[10] AuthorizationData OPTIONAL
1474 -- encoded Transited field
1475 TransitedEncoding ::= SEQUENCE {
1476 tr-type[0] INTEGER, -- must be registered
1477 contents[1] OCTET STRING
1480 -- Unencrypted authenticator
1481 Authenticator ::= [APPLICATION 2] SEQUENCE {
1482 authenticator-vno[0] INTEGER,
1484 cname[2] PrincipalName,
1485 cksum[3] Checksum OPTIONAL,
1487 ctime[5] KerberosTime,
1488 subkey[6] EncryptionKey OPTIONAL,
1489 seq-number[7] INTEGER OPTIONAL,
1490 authorization-data[8] AuthorizationData OPTIONAL
1493 PA-DATA ::= SEQUENCE {
1494 padata-type[1] INTEGER,
1495 padata-value[2] OCTET STRING,
1496 -- might be encoded AP-REQ
1499 padata-type ::= PA-ENC-TIMESTAMP
1500 padata-value ::= EncryptedData -- PA-ENC-TS-ENC
1502 PA-ENC-TS-ENC ::= SEQUENCE {
1503 patimestamp[0] KerberosTime, -- client's time
1504 pausec[1] INTEGER OPTIONAL
1507 EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart
1508 EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
1510 EncKDCRepPart ::= SEQUENCE {
1511 key[0] EncryptionKey,
1512 last-req[1] LastReq,
1514 key-expiration[3] KerberosTime OPTIONAL,
1515 flags[4] TicketFlags,
1516 authtime[5] KerberosTime,
1517 starttime[6] KerberosTime OPTIONAL,
1518 endtime[7] KerberosTime,
1519 renew-till[8] KerberosTime OPTIONAL,
1521 sname[10] PrincipalName,
1522 caddr[11] HostAddresses OPTIONAL
1525 AP-REQ ::= [APPLICATION 14] SEQUENCE {
1527 msg-type[1] INTEGER,
1528 ap-options[2] APOptions,
1530 authenticator[4] EncryptedData
1533 APOptions ::= BIT STRING {
1539 AP-REP ::= [APPLICATION 15] SEQUENCE {
1541 msg-type[1] INTEGER,
1542 enc-part[2] EncryptedData
1545 EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
1546 ctime[0] KerberosTime,
1548 subkey[2] EncryptionKey OPTIONAL,
1549 seq-number[3] INTEGER OPTIONAL
1552 KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
1554 msg-type[1] INTEGER,
1555 safe-body[2] KRB-SAFE-BODY,
1559 KRB-SAFE-BODY ::= SEQUENCE {
1560 user-data[0] OCTET STRING,
1561 timestamp[1] KerberosTime OPTIONAL,
1562 usec[2] INTEGER OPTIONAL,
1563 seq-number[3] INTEGER OPTIONAL,
1564 s-address[4] HostAddress,
1565 r-address[5] HostAddress OPTIONAL
1568 KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
1570 msg-type[1] INTEGER,
1571 enc-part[3] EncryptedData
1574 EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
1575 user-data[0] OCTET STRING,
1576 timestamp[1] KerberosTime OPTIONAL,
1577 usec[2] INTEGER OPTIONAL,
1578 seq-number[3] INTEGER OPTIONAL,
1579 s-address[4] HostAddress, -- sender's addr
1580 r-address[5] HostAddress OPTIONAL
1584 KRB-CRED ::= [APPLICATION 22] SEQUENCE {
1586 msg-type[1] INTEGER, -- KRB_CRED
1587 tickets[2] SEQUENCE OF Ticket,
1588 enc-part[3] EncryptedData
1591 EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
1592 ticket-info[0] SEQUENCE OF KrbCredInfo,
1593 nonce[1] INTEGER OPTIONAL,
1594 timestamp[2] KerberosTime OPTIONAL,
1595 usec[3] INTEGER OPTIONAL,
1596 s-address[4] HostAddress OPTIONAL,
1597 r-address[5] HostAddress OPTIONAL
1600 KrbCredInfo ::= SEQUENCE {
1601 key[0] EncryptionKey,
1602 prealm[1] Realm OPTIONAL,
1603 pname[2] PrincipalName OPTIONAL,
1604 flags[3] TicketFlags OPTIONAL,
1605 authtime[4] KerberosTime OPTIONAL,
1606 starttime[5] KerberosTime OPTIONAL,
1607 endtime[6] KerberosTime OPTIONAL
1608 renew-till[7] KerberosTime OPTIONAL,
1609 srealm[8] Realm OPTIONAL,
1610 sname[9] PrincipalName OPTIONAL,
1611 caddr[10] HostAddresses OPTIONAL
1614 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
1616 msg-type[1] INTEGER,
1617 ctime[2] KerberosTime OPTIONAL,
1618 cusec[3] INTEGER OPTIONAL,
1619 stime[4] KerberosTime,
1621 error-code[6] INTEGER,
1622 crealm[7] Realm OPTIONAL,
1623 cname[8] PrincipalName OPTIONAL,
1624 realm[9] Realm, -- Correct realm
1625 sname[10] PrincipalName, -- Correct name
1626 e-text[11] GeneralString OPTIONAL,
1627 e-data[12] OCTET STRING OPTIONAL
1630 e-data This field contains additional data about the error for use
1631 by the application to help it recover from or handle the
1632 error. If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
1633 the e-data field will contain an encoding of a sequence of
1634 padata fields, each corresponding to an acceptable pre-
1635 authentication method and optionally containing data for
1638 METHOD-DATA ::= SEQUENCE of PA-DATA
1640 If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
1641 contain an encoding of the following sequence:
1643 METHOD-DATA ::= SEQUENCE {
1644 method-type[0] INTEGER,
1645 method-data[1] OCTET STRING OPTIONAL
1648 EncryptionKey ::= SEQUENCE {
1650 keyvalue[1] OCTET STRING
1653 Checksum ::= SEQUENCE {
1654 cksumtype[0] INTEGER,
1655 checksum[1] OCTET STRING