2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
5 * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and
6 * added AP-REQ and AP-REP dissection
8 * See RFC 1510, and various I-Ds and other documents showing additions,
9 * e.g. ones listed under
11 * http://www.isi.edu/people/bcn/krb-revisions/
15 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-03.txt
17 * $Id: packet-kerberos.c,v 1.42 2003/12/04 08:15:20 sahlberg Exp $
19 * Ethereal - Network traffic analyzer
20 * By Gerald Combs <gerald@ethereal.com>
21 * Copyright 1998 Gerald Combs
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
48 #include <epan/packet.h>
50 #include <epan/strutil.h>
53 #include "packet-netbios.h"
54 #include "packet-gssapi.h"
55 #include "packet-tcp.h"
58 #define UDP_PORT_KERBEROS 88
59 #define TCP_PORT_KERBEROS 88
61 /* Desegment Kerberos over TCP messages */
62 static gboolean krb_desegment = TRUE;
64 static gint proto_kerberos = -1;
65 static gint hf_krb_rm_reserved = -1;
66 static gint hf_krb_rm_reclen = -1;
68 static gint ett_kerberos = -1;
69 static gint ett_preauth = -1;
70 static gint ett_addresses = -1;
71 static gint ett_request = -1;
72 static gint ett_princ = -1;
73 static gint ett_ticket = -1;
74 static gint ett_encrypted = -1;
75 static gint ett_etype = -1;
76 static gint ett_additional_tickets = -1;
77 static gint ett_recordmark = -1;
80 #define KRB_RM_RESERVED 0x80000000L
81 #define KRB_RM_RECLEN 0x7fffffffL
83 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
84 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
85 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
86 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
87 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
88 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
90 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
91 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
92 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
93 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
95 /* Type tags within KDC-REQ */
96 #define KRB5_KDC_REQ_PVNO 1
97 #define KRB5_KDC_REQ_MSG_TYPE 2
98 #define KRB5_KDC_REQ_PADATA 3
99 #define KRB5_KDC_REQ_REQBODY 4
101 /* Type tags within KDC-REP */
102 #define KRB5_KDC_REP_PVNO 0
103 #define KRB5_KDC_REP_MSG_TYPE 1
104 #define KRB5_KDC_REP_PADATA 2
105 #define KRB5_KDC_REP_CREALM 3
106 #define KRB5_KDC_REP_CNAME 4
107 #define KRB5_KDC_REP_TICKET 5
108 #define KRB5_KDC_REP_ENC_PART 6
110 /* Type tags within KDC-REQ-BODY */
111 #define KRB5_BODY_KDC_OPTIONS 0
112 #define KRB5_BODY_CNAME 1
113 #define KRB5_BODY_REALM 2
114 #define KRB5_BODY_SNAME 3
115 #define KRB5_BODY_FROM 4
116 #define KRB5_BODY_TILL 5
117 #define KRB5_BODY_RTIME 6
118 #define KRB5_BODY_NONCE 7
119 #define KRB5_BODY_ENCTYPE 8
120 #define KRB5_BODY_ADDRESSES 9
121 #define KRB5_BODY_ENC_AUTHORIZATION_DATA 10
122 #define KRB5_BODY_ADDITIONAL_TICKETS 11
124 /* TAGs within AP-REQ */
125 #define KRB5_AP_REQ_APOPTIONS 2
126 #define KRB5_AP_REQ_TICKET 3
127 #define KRB5_AP_REQ_ENC_DATA 4
129 /* TAGs within AP-REP */
130 #define KRB5_AP_REP_ENC_DATA 2
132 /* Type tags within KRB-ERROR */
133 #define KRB5_ERROR_PVNO 0
134 #define KRB5_ERROR_MSG_TYPE 1
135 #define KRB5_ERROR_CTIME 2
136 #define KRB5_ERROR_CUSEC 3
137 #define KRB5_ERROR_STIME 4
138 #define KRB5_ERROR_SUSEC 5
139 #define KRB5_ERROR_ERROR_CODE 6
140 #define KRB5_ERROR_CREALM 7
141 #define KRB5_ERROR_CNAME 8
142 #define KRB5_ERROR_REALM 9
143 #define KRB5_ERROR_SNAME 10
144 #define KRB5_ERROR_ETEXT 11
145 #define KRB5_ERROR_EDATA 12
147 /* address type constants */
148 #define KRB5_ADDR_IPv4 0x02
149 #define KRB5_ADDR_CHAOS 0x05
150 #define KRB5_ADDR_XEROX 0x06
151 #define KRB5_ADDR_ISO 0x07
152 #define KRB5_ADDR_DECNET 0x0c
153 #define KRB5_ADDR_APPLETALK 0x10
154 #define KRB5_ADDR_NETBIOS 0x14
155 #define KRB5_ADDR_IPv6 0x18
157 /* encryption type constants */
158 #define KRB5_ENCTYPE_NULL 0
159 #define KRB5_ENCTYPE_DES_CBC_CRC 1
160 #define KRB5_ENCTYPE_DES_CBC_MD4 2
161 #define KRB5_ENCTYPE_DES_CBC_MD5 3
162 #define KRB5_ENCTYPE_DES_CBC_RAW 4
163 #define KRB5_ENCTYPE_DES3_CBC_SHA 5
164 #define KRB5_ENCTYPE_DES3_CBC_RAW 6
165 #define KRB5_ENCTYPE_DES_HMAC_SHA1 8
166 #define KRB5_ENCTYPE_DES3_CBC_SHA1 16
167 #define KERB_ENCTYPE_RC4_HMAC 23
168 #define KERB_ENCTYPE_RC4_HMAC_EXP 24
169 #define KRB5_ENCTYPE_UNKNOWN 0x1ff
170 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
173 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
175 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
177 * unless it's expired.
180 /* pre-authentication type constants */
181 #define KRB5_PA_TGS_REQ 1
182 #define KRB5_PA_ENC_TIMESTAMP 2
183 #define KRB5_PA_PW_SALT 3
184 #define KRB5_PA_ENC_ENCKEY 4
185 #define KRB5_PA_ENC_UNIX_TIME 5
186 #define KRB5_PA_ENC_SANDIA_SECURID 6
187 #define KRB5_PA_SESAME 7
188 #define KRB5_PA_OSF_DCE 8
189 #define KRB5_PA_CYBERSAFE_SECUREID 9
190 #define KRB5_PA_AFS3_SALT 10
191 #define KRB5_PA_ENCTYPE_INFO 11
192 #define KRB5_PA_SAM_CHALLENGE 12
193 #define KRB5_PA_SAM_RESPONSE 13
194 #define KRB5_PA_DASS 16
195 #define KRB5_PA_USE_SPECIFIED_KVNO 20
196 #define KRB5_PA_SAM_REDIRECT 21
197 #define KRB5_PA_GET_FROM_TYPED_DATA 22
198 #define KRB5_PA_SAM_ETYPE_INFO 23
199 #define KRB5_PA_ALT_PRINC 24
200 #define KRB5_PA_SAM_CHALLENGE2 30
201 #define KRB5_PA_SAM_RESPONSE2 31
202 #define KRB5_PA_PAC_REQUEST 128
204 /* Type tags within Ticket */
205 #define KRB5_TKT_TKT_VNO 0
206 #define KRB5_TKT_REALM 1
207 #define KRB5_TKT_SNAME 2
208 #define KRB5_TKT_ENC_PART 3
210 /* Principal name-type */
211 #define KRB5_NT_UNKNOWN 0
212 #define KRB5_NT_PRINCIPAL 1
213 #define KRB5_NT_SRV_INST 2
214 #define KRB5_NT_SRV_HST 3
215 #define KRB5_NT_SRV_XHST 4
216 #define KRB5_NT_UID 5
218 /* error table constants */
219 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
220 #define KRB5_ET_KRB5KDC_ERR_NONE 0
221 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
222 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
223 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
224 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
225 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
226 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
227 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
228 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
229 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
230 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
231 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
232 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
233 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
234 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
235 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
236 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
237 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
238 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
239 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
240 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
241 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
242 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
243 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
244 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
245 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
246 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
247 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
248 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
249 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
250 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
251 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
252 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
253 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
254 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
255 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
256 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
257 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
258 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
259 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
260 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
261 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
262 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
263 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
264 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
265 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
266 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
267 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
268 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
269 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
271 static const value_string krb5_error_codes[] = {
272 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
273 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
274 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
275 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
276 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
277 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
278 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
279 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
280 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
281 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
282 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
283 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
284 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
285 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
286 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
287 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
288 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
289 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
290 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
291 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
292 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
293 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
294 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
295 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
296 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
297 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
298 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
299 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
300 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
301 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
302 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
303 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
304 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
305 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
306 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
307 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
308 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
309 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
310 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
311 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
312 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
313 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
314 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
315 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
316 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
317 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
318 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
319 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
320 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
321 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
326 static const value_string krb5_princ_types[] = {
327 { KRB5_NT_UNKNOWN , "Unknown" },
328 { KRB5_NT_PRINCIPAL , "Principal" },
329 { KRB5_NT_SRV_INST , "Service and Instance" },
330 { KRB5_NT_SRV_HST , "Service and Host" },
331 { KRB5_NT_SRV_XHST , "Service and Host Components" },
332 { KRB5_NT_UID , "Unique ID" },
336 static const value_string krb5_preauthentication_types[] = {
337 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
338 { KRB5_PA_ENC_TIMESTAMP , "PA-ENC-TIMESTAMP" },
339 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
340 { KRB5_PA_ENC_ENCKEY , "PA-ENC-ENCKEY" },
341 { KRB5_PA_ENC_UNIX_TIME , "PA-ENC-UNIX-TIME" },
342 { KRB5_PA_ENC_SANDIA_SECURID , "PA-PW-SALT" },
343 { KRB5_PA_SESAME , "PA-SESAME" },
344 { KRB5_PA_OSF_DCE , "PA-OSF-DCE" },
345 { KRB5_PA_CYBERSAFE_SECUREID , "PA-CYBERSAFE-SECURID" },
346 { KRB5_PA_AFS3_SALT , "PA-AFS3-SALT" },
347 { KRB5_PA_ENCTYPE_INFO , "PA-ENCTYPE-INFO" },
348 { KRB5_PA_SAM_CHALLENGE , "PA-SAM-CHALLENGE" },
349 { KRB5_PA_SAM_RESPONSE , "PA-SAM-RESPONSE" },
350 { KRB5_PA_DASS , "PA-DASS" },
351 { KRB5_PA_USE_SPECIFIED_KVNO , "PA-USE-SPECIFIED-KVNO" },
352 { KRB5_PA_SAM_REDIRECT , "PA-SAM-REDIRECT" },
353 { KRB5_PA_GET_FROM_TYPED_DATA , "PA-GET-FROM-TYPED-DATA" },
354 { KRB5_PA_SAM_ETYPE_INFO , "PA-SAM-ETYPE-INFO" },
355 { KRB5_PA_ALT_PRINC , "PA-ALT-PRINC" },
356 { KRB5_PA_SAM_CHALLENGE2 , "PA-SAM-CHALLENGE2" },
357 { KRB5_PA_SAM_RESPONSE2 , "PA-SAM-RESPONSE2" },
358 { KRB5_PA_PAC_REQUEST , "PA-PAC-REQUEST" },
362 static const value_string krb5_encryption_types[] = {
363 { KRB5_ENCTYPE_NULL , "NULL" },
364 { KRB5_ENCTYPE_DES_CBC_CRC , "des-cbc-crc" },
365 { KRB5_ENCTYPE_DES_CBC_MD4 , "des-cbc-md4" },
366 { KRB5_ENCTYPE_DES_CBC_MD5 , "des-cbc-md5" },
367 { KRB5_ENCTYPE_DES_CBC_RAW , "des-cbc-raw" },
368 { KRB5_ENCTYPE_DES3_CBC_SHA , "des3-cbc-sha" },
369 { KRB5_ENCTYPE_DES3_CBC_RAW , "des3-cbc-raw" },
370 { KRB5_ENCTYPE_DES_HMAC_SHA1 , "des-hmac-sha1" },
371 { KRB5_ENCTYPE_DES3_CBC_SHA1 , "des3-cbc-sha1" },
372 { KERB_ENCTYPE_RC4_HMAC , "rc4-hmac" },
373 { KERB_ENCTYPE_RC4_HMAC_EXP , "rc4-hmac-exp" },
374 { KRB5_ENCTYPE_UNKNOWN , "unknown" },
375 { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 , "local-des3-hmac-sha1" },
379 static const value_string krb5_address_types[] = {
380 { KRB5_ADDR_IPv4, "IPv4"},
381 { KRB5_ADDR_CHAOS, "CHAOS"},
382 { KRB5_ADDR_XEROX, "XEROX"},
383 { KRB5_ADDR_ISO, "ISO"},
384 { KRB5_ADDR_DECNET, "DECNET"},
385 { KRB5_ADDR_APPLETALK, "APPLETALK"},
386 { KRB5_ADDR_NETBIOS, "NETBIOS"},
387 { KRB5_ADDR_IPv6, "IPv6"},
391 static const value_string krb5_msg_types[] = {
392 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
393 { KRB5_MSG_TGS_REP, "TGS-REP" },
394 { KRB5_MSG_AS_REQ, "AS-REQ" },
395 { KRB5_MSG_AS_REP, "AS-REP" },
396 { KRB5_MSG_AP_REQ, "AP-REQ" },
397 { KRB5_MSG_AP_REP, "AP-REP" },
398 { KRB5_MSG_SAFE, "KRB-SAFE" },
399 { KRB5_MSG_PRIV, "KRB-PRIV" },
400 { KRB5_MSG_CRED, "KRB-CRED" },
401 { KRB5_MSG_ERROR, "KRB-ERROR" },
405 static struct { char *set; char *unset; } bitval = { "Set", "Not set" };
407 static int dissect_PrincipalName(char *title, ASN1_SCK *asn1p,
408 packet_info *pinfo, proto_tree *tree,
410 static int dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
411 proto_tree *tree, int start_offset);
412 static int dissect_EncryptedData(char *title, ASN1_SCK *asn1p,
413 packet_info *pinfo, proto_tree *tree,
415 static int dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
416 proto_tree *tree, int start_offset);
417 static void dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo,
419 static void dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo,
421 static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
422 proto_tree *tree, int do_col_info,
424 static void show_krb_recordmark(proto_tree *kerberos_tree, tvbuff_t *tvb,
425 gint start, guint32 krb_rm);
426 static gint kerberos_rm_to_reclen(guint krb_rm);
427 static void dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
429 static guint get_krb_pdu_len(tvbuff_t *tvb, int offset);
432 to_error_str(int ret) {
435 case ASN1_ERR_EOC_MISMATCH:
436 return("EOC mismatch");
438 case ASN1_ERR_WRONG_TYPE:
439 return("Wrong type for that item");
441 case ASN1_ERR_LENGTH_NOT_DEFINITE:
442 return("Length was indefinite");
444 case ASN1_ERR_LENGTH_MISMATCH:
445 return("Length mismatch");
447 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
448 return("Wrong length for that item's type");
451 return("Unknown error");
455 krb_proto_tree_add_time(proto_tree *tree, tvbuff_t *tvb, int offset,
456 int str_len, char *name, guchar *str)
459 proto_tree_add_text(tree, tvb, offset, str_len,
460 "%s: %.4s-%.2s-%.2s %.2s:%.2s:%.2s (%.1s)",
461 name, str, str+4, str+6,
462 str+8, str+10, str+12,
468 * You must be kidding. I'm going to actually use a macro to do something?
472 #define KRB_HEAD_DECODE_OR_DIE(token) \
473 start = asn1p->offset; \
474 ret = asn1_header_decode (asn1p, &cls, &con, &tag, &def, &item_len); \
475 if (ret != ASN1_ERR_NOERROR) {\
476 if (check_col(pinfo->cinfo, COL_INFO)) \
477 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s, offset: %d", \
478 token, to_error_str(ret), start); \
482 if (check_col(pinfo->cinfo, COL_INFO)) \
483 col_add_fstr(pinfo->cinfo, COL_INFO, "not definite: %s", token); \
484 fprintf(stderr,"not definite: %s\n", token); \
487 offset += (asn1p->offset - start);
489 #define CHECK_APPLICATION_TYPE(expected_tag) \
490 (cls == ASN1_APL && con == ASN1_CON && tag == expected_tag)
492 #define DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag) \
493 if (!CHECK_APPLICATION_TYPE(expected_tag)) \
494 DIE_WITH_BAD_TYPE(token, expected_tag);
496 #define CHECK_CONTEXT_TYPE(expected_tag) \
497 (cls == ASN1_CTX && con == ASN1_CON && tag == expected_tag)
499 #define DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag) \
500 if (!CHECK_CONTEXT_TYPE(expected_tag)) \
501 DIE_WITH_BAD_TYPE(token, expected_tag);
503 #define DIE_WITH_BAD_TYPE(token, expected_tag) \
505 if (check_col(pinfo->cinfo, COL_INFO)) \
506 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s (tag=%d exp=%d, con=%d, cls=%d, offset=%0x)", \
507 token, to_error_str(ASN1_ERR_WRONG_TYPE), tag, expected_tag, con, cls, start); \
511 #define KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE(token, expected_tag) \
512 KRB_HEAD_DECODE_OR_DIE(token); \
513 DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag);
515 #define KRB_DECODE_CONTEXT_HEAD_OR_DIE(token, expected_tag) \
516 KRB_HEAD_DECODE_OR_DIE(token); \
517 DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag);
519 #define KRB_SEQ_HEAD_DECODE_OR_DIE(token) \
520 ret = asn1_sequence_decode (asn1p, &item_len, &header_len); \
521 if (ret != ASN1_ERR_NOERROR) {\
522 if (check_col(pinfo->cinfo, COL_INFO)) \
523 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
524 token, to_error_str(ret)); \
527 offset += header_len;
529 #define KRB_DECODE_OR_DIE(token, fn, val) \
530 ret = fn (asn1p, &val, &length); \
531 if (ret != ASN1_ERR_NOERROR) { \
532 if (check_col(pinfo->cinfo, COL_INFO)) \
533 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
534 token, to_error_str(ret)); \
538 #define KRB_DECODE_UINT32_OR_DIE(token, val) \
539 KRB_DECODE_OR_DIE(token, asn1_uint32_decode, val);
541 #define KRB_DECODE_STRING_OR_DIE(token, expected_tag, val, val_len, item_len) \
542 ret = asn1_string_decode (asn1p, &val, &val_len, &item_len, expected_tag); \
543 if (ret != ASN1_ERR_NOERROR) { \
544 if (check_col(pinfo->cinfo, COL_INFO)) \
545 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
546 token, to_error_str(ret)); \
550 #define KRB_DECODE_OCTET_STRING_OR_DIE(token, val, val_len, item_len) \
551 KRB_DECODE_STRING_OR_DIE(token, ASN1_OTS, val, val_len, item_len)
553 #define KRB_DECODE_GENERAL_STRING_OR_DIE(token, val, val_len, item_len) \
554 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENSTR, val, val_len, item_len)
556 #define KRB_DECODE_GENERAL_TIME_OR_DIE(token, val, val_len, item_len) \
557 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENTIM, val, val_len, item_len)
559 /* dissect_type_value_pair decodes (roughly) this:
566 which is all over the place in krb5 */
571 * Dissect Kerberos 5 flags, which seems to be encoded as an ASN.1
572 * bit field ... but, there is a one byte padding field (why the f***
573 * they did that I don't know ...
575 * We will use this routine to dissect several different types of flags
576 * so we will pass in the ETT value to build the flags etc
579 dissect_ap_options(tvbuff_t *tvb, int offset)
587 dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
588 guint32 *type, int *type_len, int *type_off,
589 guchar **val, int *val_len, int *val_off) {
598 start = asn1p->offset;
599 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
600 offset += (asn1p->offset - start);
604 start = asn1p->offset;
605 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
606 offset += (asn1p->offset - start);
612 ret = asn1_uint32_decode(asn1p, type, type_len);
613 if (ret != ASN1_ERR_NOERROR) {
614 fprintf(stderr,"die: type_value_pair: type, %s\n", to_error_str(ret));
619 /* OCTET STRING (or generic data) */
621 start = asn1p->offset;
622 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
623 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
624 offset += asn1p->offset - start;
630 asn1_string_value_decode (asn1p, *val_len, val);
632 *inoff = offset + *val_len;
636 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info)
638 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE));
642 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
644 if (check_col(pinfo->cinfo, COL_PROTOCOL))
645 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
647 (void)dissect_kerberos_common(tvb, pinfo, tree, TRUE, FALSE);
651 kerberos_rm_to_reclen(guint krb_rm)
653 return (krb_rm & KRB_RM_RECLEN);
657 get_krb_pdu_len(tvbuff_t *tvb, int offset)
662 krb_rm = tvb_get_ntohl(tvb, offset);
663 pdulen = kerberos_rm_to_reclen(krb_rm);
668 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
670 pinfo->fragmented = TRUE;
671 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE) < 0) {
673 * The dissector failed to recognize this as a valid
674 * Kerberos message. Mark it as a continuation packet.
676 if (check_col(pinfo->cinfo, COL_INFO)) {
677 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
683 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
685 if (check_col(pinfo->cinfo, COL_PROTOCOL))
686 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
688 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
689 dissect_kerberos_tcp_pdu);
693 * Display the TCP record mark.
696 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
705 rec_len = kerberos_rm_to_reclen(krb_rm);
706 rm_item = proto_tree_add_text(tree, tvb, start, 4,
707 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
708 rm_tree = proto_item_add_subtree(rm_item, ett_recordmark);
709 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
710 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
714 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
715 int do_col_info, gboolean have_rm)
718 proto_tree *kerberos_tree = NULL;
719 proto_tree *etype_tree = NULL;
720 proto_tree *preauth_tree = NULL;
721 proto_tree *request_tree = NULL;
722 proto_tree *additional_tickets_tree = NULL;
723 ASN1_SCK asn1, *asn1p = &asn1;
724 proto_item *item = NULL;
731 int start, end, message_end, sequence_end;
735 guint protocol_message_type;
739 guint32 preauth_type;
745 int tmp_pos1, tmp_pos2;
747 /* TCP record mark and length */
752 krb_rm = tvb_get_ntohl(tvb, offset);
753 krb_reclen = kerberos_rm_to_reclen(krb_rm);
756 * What is a reasonable size limit?
758 if (krb_reclen > 10 * 1024 * 1024) {
764 asn1_open(&asn1, tvb, offset);
767 KRB_HEAD_DECODE_OR_DIE("top");
768 protocol_message_type = tag;
770 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
771 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
774 * If item_len and krb_reclen disagree, which should we trust? Stick
775 * with item_len for now.
777 message_end = asn1p->offset + item_len;
780 KRB_HEAD_DECODE_OR_DIE("top2");
783 KRB_HEAD_DECODE_OR_DIE("version-wrap");
784 KRB_DECODE_UINT32_OR_DIE("version", version);
788 show_krb_recordmark(kerberos_tree, tvb, 0, krb_rm);
790 proto_tree_add_text(kerberos_tree, tvb, offset, length,
797 KRB_HEAD_DECODE_OR_DIE("message-type-wrap");
798 KRB_DECODE_UINT32_OR_DIE("message-type", msg_type);
801 proto_tree_add_text(kerberos_tree, tvb, offset, length,
803 val_to_str(msg_type, krb5_msg_types,
804 "Unknown msg type %#x"));
808 if (do_col_info & check_col(pinfo->cinfo, COL_INFO))
809 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(msg_type, krb5_msg_types,
810 "Unknown msg type %#x"));
812 /* is preauthentication present? */
813 KRB_HEAD_DECODE_OR_DIE("padata-or-body");
814 if (((protocol_message_type == KRB5_MSG_AS_REQ ||
815 protocol_message_type == KRB5_MSG_TGS_REQ) &&
816 tag == KRB5_KDC_REQ_PADATA) ||
817 ((protocol_message_type == KRB5_MSG_AS_REP ||
818 protocol_message_type == KRB5_MSG_TGS_REP) &&
819 tag == KRB5_KDC_REP_PADATA)) {
820 /* pre-authentication supplied */
823 item = proto_tree_add_text(kerberos_tree, tvb, offset,
824 item_len, "Pre-Authentication");
825 preauth_tree = proto_item_add_subtree(item, ett_preauth);
828 KRB_HEAD_DECODE_OR_DIE("sequence of pa-data");
829 end = asn1p->offset + item_len;
831 while(asn1p->offset < end) {
832 dissect_type_value_pair(asn1p, &offset,
833 &preauth_type, &item_len, &tmp_pos1,
834 &str, &str_len, &tmp_pos2);
837 proto_tree_add_text(preauth_tree, tvb, tmp_pos1,
838 item_len, "Type: %s",
839 val_to_str(preauth_type,
840 krb5_preauthentication_types,
841 "Unknown preauth type %#x"));
842 proto_tree_add_text(preauth_tree, tvb, tmp_pos2,
843 str_len, "Value: %s",
844 bytes_to_str(str, str_len));
847 KRB_HEAD_DECODE_OR_DIE("message-body");
850 switch (protocol_message_type) {
852 case KRB5_MSG_AS_REQ:
853 case KRB5_MSG_TGS_REQ:
855 AS-REQ ::= [APPLICATION 10] KDC-REQ
856 TGS-REQ ::= [APPLICATION 12] KDC-REQ
858 KDC-REQ ::= SEQUENCE {
861 padata[3] SEQUENCE OF PA-DATA OPTIONAL,
862 req-body[4] KDC-REQ-BODY
865 KDC-REQ-BODY ::= SEQUENCE {
866 kdc-options[0] KDCOptions,
867 cname[1] PrincipalName OPTIONAL,
868 -- Used only in AS-REQ
869 realm[2] Realm, -- Server's realm
870 -- Also client's in AS-REQ
871 sname[3] PrincipalName OPTIONAL,
872 from[4] KerberosTime OPTIONAL,
873 till[5] KerberosTime,
874 rtime[6] KerberosTime OPTIONAL,
876 etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
877 -- in preference order
878 addresses[9] HostAddresses OPTIONAL,
879 enc-authorization-data[10] EncryptedData OPTIONAL,
880 -- Encrypted AuthorizationData encoding
881 additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
886 KRB_HEAD_DECODE_OR_DIE("body-sequence");
888 item = proto_tree_add_text(kerberos_tree, tvb, offset,
889 item_len, "Request");
890 request_tree = proto_item_add_subtree(item, ett_request);
892 sequence_end = asn1p->offset + item_len;
895 KRB_HEAD_DECODE_OR_DIE("kdc options");
897 KRB_HEAD_DECODE_OR_DIE("kdc options:bits");
900 proto_tree_add_text(request_tree, tvb, offset, item_len,
902 tvb_bytes_to_str(asn1p->tvb, asn1p->offset,
906 asn1p->offset += item_len;
908 KRB_HEAD_DECODE_OR_DIE("Client Name or Realm");
910 if (CHECK_CONTEXT_TYPE(KRB5_BODY_CNAME)) {
911 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
912 request_tree, offset);
916 KRB_HEAD_DECODE_OR_DIE("Realm");
919 DIE_IF_NOT_CONTEXT_TYPE("Realm", KRB5_BODY_REALM);
920 KRB_DECODE_GENERAL_STRING_OR_DIE("Realm", str, str_len, item_len);
922 proto_tree_add_text(request_tree, tvb, offset, item_len,
923 "Realm: %.*s", str_len, str);
927 KRB_HEAD_DECODE_OR_DIE("Server Name");
928 if (CHECK_CONTEXT_TYPE(KRB5_BODY_SNAME)) {
929 item_len = dissect_PrincipalName("Server Name", asn1p, pinfo,
930 request_tree, offset);
934 KRB_HEAD_DECODE_OR_DIE("From or Till");
937 if (CHECK_CONTEXT_TYPE(KRB5_BODY_FROM)) {
938 KRB_DECODE_GENERAL_TIME_OR_DIE("From", str, str_len, item_len);
939 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
942 KRB_HEAD_DECODE_OR_DIE("Till");
945 DIE_IF_NOT_CONTEXT_TYPE("Till", KRB5_BODY_TILL);
946 KRB_DECODE_GENERAL_TIME_OR_DIE("Till", str, str_len, item_len);
947 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
951 KRB_HEAD_DECODE_OR_DIE("Renewable Until or Nonce");
952 if (CHECK_CONTEXT_TYPE(KRB5_BODY_RTIME)) {
953 KRB_DECODE_GENERAL_TIME_OR_DIE("Renewable Until", str, str_len, item_len);
954 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
955 "Renewable Until", str);
957 KRB_HEAD_DECODE_OR_DIE("Nonce");
960 DIE_IF_NOT_CONTEXT_TYPE("Nonce", KRB5_BODY_NONCE);
961 KRB_DECODE_UINT32_OR_DIE("Nonce", tmp_int);
963 proto_tree_add_text(request_tree, tvb, offset, length,
969 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type spot",
971 KRB_HEAD_DECODE_OR_DIE("encryption type list");
973 item = proto_tree_add_text(request_tree, tvb, offset,
974 item_len, "Encryption Types");
975 etype_tree = proto_item_add_subtree(item, ett_etype);
977 total_len = item_len;
978 while(total_len > 0) {
979 KRB_DECODE_UINT32_OR_DIE("encryption type", tmp_int);
981 proto_tree_add_text(etype_tree, tvb, offset, length,
984 krb5_encryption_types,
985 "Unknown encryption type %#x"));
991 if (asn1p->offset >= sequence_end)
993 KRB_HEAD_DECODE_OR_DIE("addresses or enc-authorization-data");
994 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ADDRESSES)) {
995 /* addresses supplied */
997 length = dissect_Addresses(asn1p, pinfo, kerberos_tree,
1002 if (asn1p->offset >= sequence_end)
1004 KRB_HEAD_DECODE_OR_DIE("enc-authorization-data or additional-tickets");
1007 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ENC_AUTHORIZATION_DATA)) {
1008 /* enc-authorization-data supplied */
1009 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
1010 kerberos_tree, offset);
1014 if (asn1p->offset >= sequence_end)
1016 KRB_HEAD_DECODE_OR_DIE("additional-tickets");
1019 /* additional-tickets supplied */
1020 if (kerberos_tree) {
1021 item = proto_tree_add_text(kerberos_tree, tvb, offset,
1022 item_len, "Additional Tickets");
1023 additional_tickets_tree = proto_item_add_subtree(item, ett_additional_tickets);
1025 end = asn1p->offset + item_len;
1026 while(asn1p->offset < end) {
1027 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
1028 length = dissect_Ticket(asn1p, pinfo, additional_tickets_tree,
1037 case KRB5_MSG_AS_REP:
1038 case KRB5_MSG_TGS_REP:
1040 AS-REP ::= [APPLICATION 11] KDC-REP
1041 TGS-REP ::= [APPLICATION 13] KDC-REP
1043 KDC-REP ::= SEQUENCE {
1045 msg-type[1] INTEGER,
1046 padata[2] SEQUENCE OF PA-DATA OPTIONAL,
1048 cname[4] PrincipalName,
1050 enc-part[6] EncryptedData
1054 DIE_IF_NOT_CONTEXT_TYPE("crealm", KRB5_KDC_REP_CREALM);
1055 KRB_DECODE_GENERAL_STRING_OR_DIE("realm name", str, str_len, item_len);
1056 if (kerberos_tree) {
1057 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1058 "Realm: %.*s", str_len, str);
1062 KRB_DECODE_CONTEXT_HEAD_OR_DIE("cname", KRB5_KDC_REP_CNAME);
1063 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
1064 kerberos_tree, offset);
1069 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
1070 length = dissect_Ticket(asn1p, pinfo, kerberos_tree, offset);
1075 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-msg-part",
1076 KRB5_KDC_REP_ENC_PART);
1077 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
1078 kerberos_tree, offset);
1084 case KRB5_MSG_AP_REQ:
1087 /* We pulled the header above */
1089 KRB_HEAD_DECODE_OR_DIE("ap options:bits");
1091 if (kerberos_tree) {
1092 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1094 tvb_bytes_to_str(asn1p->tvb, asn1p->offset,
1098 asn1p->offset += item_len;
1100 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_AP_REQ_TICKET);
1101 length = dissect_Ticket(asn1p, pinfo, kerberos_tree, offset);
1106 KRB_DECODE_CONTEXT_HEAD_OR_DIE("authenticator",
1107 KRB5_AP_REQ_ENC_DATA);
1108 length = dissect_EncryptedData("Authenticator", asn1p, pinfo,
1109 kerberos_tree, offset);
1115 case KRB5_MSG_AP_REP:
1116 length = dissect_EncryptedData("EncPart", asn1p, pinfo,
1117 kerberos_tree, offset);
1123 case KRB5_MSG_ERROR:
1125 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
1127 msg-type[1] INTEGER,
1128 ctime[2] KerberosTime OPTIONAL,
1129 cusec[3] INTEGER OPTIONAL,
1130 stime[4] KerberosTime,
1132 error-code[6] INTEGER,
1133 crealm[7] Realm OPTIONAL,
1134 cname[8] PrincipalName OPTIONAL,
1135 realm[9] Realm, -- Correct realm
1136 sname[10] PrincipalName, -- Correct name
1137 e-text[11] GeneralString OPTIONAL,
1138 e-data[12] OCTET STRING OPTIONAL
1145 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CTIME)) {
1146 KRB_DECODE_GENERAL_TIME_OR_DIE("ctime", str, str_len, item_len);
1147 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
1150 KRB_HEAD_DECODE_OR_DIE("cusec");
1154 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CUSEC)) {
1155 KRB_DECODE_UINT32_OR_DIE("cusec", tmp_int);
1156 if (kerberos_tree) {
1157 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1163 KRB_HEAD_DECODE_OR_DIE("sutime");
1166 DIE_IF_NOT_CONTEXT_TYPE("sutime", KRB5_ERROR_STIME);
1167 KRB_DECODE_GENERAL_TIME_OR_DIE("stime", str, str_len, item_len);
1168 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
1172 KRB_HEAD_DECODE_OR_DIE("susec");
1173 DIE_IF_NOT_CONTEXT_TYPE("susec", KRB5_ERROR_SUSEC);
1174 KRB_DECODE_UINT32_OR_DIE("susec", tmp_int);
1175 if (kerberos_tree) {
1176 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1182 KRB_HEAD_DECODE_OR_DIE("errcode");
1183 DIE_IF_NOT_CONTEXT_TYPE("errcode", KRB5_ERROR_ERROR_CODE);
1184 KRB_DECODE_UINT32_OR_DIE("errcode", tmp_int);
1185 if (kerberos_tree) {
1186 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1188 val_to_str(tmp_int, krb5_error_codes,
1189 "Unknown error code %#x"));
1191 if (check_col(pinfo->cinfo, COL_INFO)) {
1192 col_append_fstr(pinfo->cinfo, COL_INFO, ", KRB Error:%s",
1193 val_to_str(tmp_int, krb5_error_codes,
1194 "Unknown error code %#x"));
1199 KRB_HEAD_DECODE_OR_DIE("crealm");
1201 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CREALM)) {
1202 KRB_DECODE_GENERAL_STRING_OR_DIE("crealm", str, str_len, item_len);
1203 if (kerberos_tree) {
1204 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1205 "crealm: %.*s", str_len, str);
1208 KRB_HEAD_DECODE_OR_DIE("cname");
1211 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CNAME)) {
1212 item_len = dissect_PrincipalName("cname", asn1p, pinfo,
1213 kerberos_tree, offset);
1217 KRB_HEAD_DECODE_OR_DIE("realm");
1220 DIE_IF_NOT_CONTEXT_TYPE("realm", KRB5_ERROR_REALM);
1221 KRB_DECODE_GENERAL_STRING_OR_DIE("realm", str, str_len, item_len);
1222 if (kerberos_tree) {
1223 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1224 "realm: %.*s", str_len, str);
1227 KRB_HEAD_DECODE_OR_DIE("sname");
1229 DIE_IF_NOT_CONTEXT_TYPE("sname", KRB5_ERROR_SNAME);
1230 item_len = dissect_PrincipalName("sname", asn1p, pinfo,
1231 kerberos_tree, offset);
1236 if (asn1p->offset >= message_end)
1238 KRB_HEAD_DECODE_OR_DIE("e-text");
1239 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_ETEXT) ) {
1240 KRB_DECODE_GENERAL_STRING_OR_DIE("etext", str, str_len, item_len);
1241 if (kerberos_tree) {
1242 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1243 "etext: %.*s", str_len, str);
1246 if (asn1p->offset >= message_end)
1248 KRB_HEAD_DECODE_OR_DIE("e-data");
1251 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_EDATA) ) {
1255 KRB_DECODE_OCTET_STRING_OR_DIE("e-data", data, data_len, item_len);
1257 if (kerberos_tree) {
1258 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1259 "Error Data: %s", bytes_to_str(data, data_len));
1270 dissect_PrincipalName(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1271 proto_tree *tree, int start_offset)
1274 PrincipalName ::= SEQUENCE {
1275 name-type[0] INTEGER,
1276 name-string[1] SEQUENCE OF GeneralString
1279 proto_tree *princ_tree = NULL;
1280 int offset = start_offset;
1285 guint cls, con, tag;
1286 guint header_len, item_len, total_len, type_len;
1289 proto_item *item = NULL;
1298 /* principal name */
1299 KRB_SEQ_HEAD_DECODE_OR_DIE("principal section");
1302 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1303 (offset - start_offset) + item_len, "%s",
1305 princ_tree = proto_item_add_subtree(item, ett_princ);
1311 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal type", 0);
1312 KRB_DECODE_UINT32_OR_DIE("princ-type", princ_type);
1313 type_offset = offset;
1314 type_len = item_len;
1318 proto_tree_add_text(princ_tree, asn1p->tvb, type_offset, type_len,
1320 val_to_str(princ_type, krb5_princ_types,
1321 "Unknown name type %#x"));
1324 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal name-string", 1);
1325 KRB_SEQ_HEAD_DECODE_OR_DIE("principal name-string sequence-of");
1326 total_len = item_len;
1327 if (total_len == 0) {
1328 /* There are no name strings in this PrincipalName, so we can't
1329 put any in the top-level item. */
1330 return offset - start_offset;
1333 /* Put the first name string in the top-level item. */
1334 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1336 proto_item_set_text(item, "%s: %.*s", title, (int) name_len, name);
1337 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1338 "Name: %.*s", (int) name_len, name);
1340 total_len -= item_len;
1343 /* Now process the rest of the strings.
1344 XXX - put them in the item as well? */
1345 while (total_len > 0) {
1346 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1348 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1349 "Name: %.*s", (int) name_len, name);
1351 total_len -= item_len;
1354 return offset - start_offset;
1358 dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
1359 proto_tree *tree, int start_offset) {
1360 proto_tree *address_tree = NULL;
1361 int offset = start_offset;
1364 guint cls, con, tag;
1368 proto_item *item = NULL;
1371 int tmp_pos1, tmp_pos2;
1372 guint32 address_type;
1377 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1378 int netbios_name_type;
1380 KRB_HEAD_DECODE_OR_DIE("sequence of addresses");
1382 item = proto_tree_add_text(tree, asn1p->tvb, offset,
1383 item_len, "Addresses");
1384 address_tree = proto_item_add_subtree(item, ett_addresses);
1388 end = asn1p->offset + item_len;
1390 while(asn1p->offset < end) {
1391 dissect_type_value_pair(asn1p, &offset,
1392 &address_type, &item_len, &tmp_pos1,
1393 &str, &str_len, &tmp_pos2);
1396 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos1,
1397 item_len, "Type: %s",
1398 val_to_str(address_type, krb5_address_types,
1399 "Unknown address type %#x"));
1400 switch(address_type) {
1401 case KRB5_ADDR_IPv4:
1402 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1403 str_len, "Value: %d.%d.%d.%d",
1404 str[0], str[1], str[2], str[3]);
1407 case KRB5_ADDR_NETBIOS:
1408 if (str_len == NETBIOS_NAME_LEN) {
1409 netbios_name_type = process_netbios_name(str,
1411 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1413 "Value: %s<%02x> (%s)",
1414 netbios_name, netbios_name_type,
1415 netbios_name_type_descr(netbios_name_type));
1417 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1419 "Value (Invalid length %d, should be 16): \"%s\"",
1420 str_len, format_text(str, str_len));
1424 /* XXX - do KRB5_ADDR_IPv6 */
1427 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1428 str_len, "Value: %s",
1429 bytes_to_str(str, str_len));
1434 return offset - start_offset;
1438 dissect_EncryptedData(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1439 proto_tree *tree, int start_offset)
1442 EncryptedData ::= SEQUENCE {
1443 etype[0] INTEGER, -- EncryptionType
1444 kvno[1] INTEGER OPTIONAL,
1445 cipher[2] OCTET STRING -- ciphertext
1448 proto_tree *encr_tree = NULL;
1449 int offset = start_offset;
1452 guint cls, con, tag;
1453 guint header_len, item_len, data_len;
1456 proto_item *item = NULL;
1463 KRB_SEQ_HEAD_DECODE_OR_DIE("encrypted data section");
1466 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1467 (offset - start_offset) + item_len,
1468 "Encrypted Data: %s", title);
1469 encr_tree = proto_item_add_subtree(item, ett_princ);
1473 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type", 0);
1474 KRB_DECODE_UINT32_OR_DIE("encr-type", val);
1476 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1478 val_to_str(val, krb5_encryption_types,
1479 "Unknown encryption type %#x"));
1484 KRB_HEAD_DECODE_OR_DIE("kvno-wrap or cipher-wrap");
1485 if (CHECK_CONTEXT_TYPE(1)) {
1486 KRB_DECODE_UINT32_OR_DIE("kvno", val);
1488 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1492 KRB_HEAD_DECODE_OR_DIE("cipher-wrap");
1495 DIE_IF_NOT_CONTEXT_TYPE("cipher-wrap", 2);
1496 KRB_DECODE_OCTET_STRING_OR_DIE("cipher", data, data_len, item_len);
1499 proto_tree_add_text(encr_tree, asn1p->tvb, offset, item_len,
1500 "CipherText: %s", bytes_to_str(data, data_len));
1504 return offset - start_offset;
1508 dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
1509 proto_tree *tree, int start_offset)
1512 Ticket ::= [APPLICATION 1] SEQUENCE {
1515 sname[2] PrincipalName,
1516 enc-part[3] EncryptedData
1519 proto_tree *ticket_tree = NULL;
1520 int offset = start_offset;
1523 guint cls, con, tag;
1524 guint header_len, total_len;
1528 proto_item *item = NULL;
1536 KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE("Ticket section", 1);
1537 KRB_SEQ_HEAD_DECODE_OR_DIE("Ticket sequence");
1538 total_len = item_len;
1541 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1542 (offset - start_offset) + item_len,
1544 ticket_tree = proto_item_add_subtree(item, ett_ticket);
1548 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket tkt-vno", KRB5_TKT_TKT_VNO);
1549 KRB_DECODE_UINT32_OR_DIE("Ticket tkt-vno", val);
1551 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, length,
1552 "Version: %u", val);
1555 total_len -= length;
1558 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket realm", KRB5_TKT_REALM);
1559 KRB_DECODE_GENERAL_STRING_OR_DIE("Ticket realm string", str, str_len, item_len);
1561 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, item_len,
1562 "Realm: %.*s", str_len, str);
1565 total_len -= item_len;
1567 /* server name (sname) */
1568 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket sname", KRB5_TKT_SNAME);
1569 item_len = dissect_PrincipalName("Service Name", asn1p, pinfo, ticket_tree,
1575 /* encrypted part */
1576 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-part", KRB5_TKT_ENC_PART);
1577 length = dissect_EncryptedData("Ticket data", asn1p, pinfo, ticket_tree,
1583 return offset - start_offset;
1588 proto_register_kerberos(void)
1590 static hf_register_info hf[] = {
1591 { &hf_krb_rm_reserved, {
1592 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
1593 &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
1594 { &hf_krb_rm_reclen, {
1595 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
1596 NULL, KRB_RM_RECLEN, "Record length", HFILL }},
1599 static gint *ett[] = {
1608 &ett_additional_tickets,
1611 module_t *krb_module;
1613 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
1614 proto_register_field_array(proto_kerberos, hf, array_length(hf));
1615 proto_register_subtree_array(ett, array_length(ett));
1617 /* Register preferences */
1618 krb_module = prefs_register_protocol(proto_kerberos, NULL);
1619 prefs_register_bool_preference(krb_module, "desegment",
1620 "Desegment Kerberos over TCP messages",
1621 "Whether the dissector should desegment "
1622 "multi-segment Kerberos messages", &krb_desegment);
1626 proto_reg_handoff_kerberos(void)
1628 dissector_handle_t kerberos_handle_udp;
1629 dissector_handle_t kerberos_handle_tcp;
1631 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
1633 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
1635 dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
1636 dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
1642 MISC definitions from RFC1510:
1644 Realm ::= GeneralString
1646 KerberosTime ::= GeneralizedTime
1648 HostAddress ::= SEQUENCE {
1649 addr-type[0] INTEGER,
1650 address[1] OCTET STRING
1653 HostAddresses ::= SEQUENCE OF SEQUENCE {
1654 addr-type[0] INTEGER,
1655 address[1] OCTET STRING
1658 AuthorizationData ::= SEQUENCE OF SEQUENCE {
1660 ad-data[1] OCTET STRING
1662 APOptions ::= BIT STRING {
1669 TicketFlags ::= BIT STRING {
1684 KDCOptions ::= BIT STRING {
1698 enc-tkt-in-skey(28),
1704 LastReq ::= SEQUENCE OF SEQUENCE {
1706 lr-value[1] KerberosTime
1709 Ticket ::= [APPLICATION 1] SEQUENCE {
1712 sname[2] PrincipalName,
1713 enc-part[3] EncryptedData
1716 -- Encrypted part of ticket
1717 EncTicketPart ::= [APPLICATION 3] SEQUENCE {
1718 flags[0] TicketFlags,
1719 key[1] EncryptionKey,
1721 cname[3] PrincipalName,
1722 transited[4] TransitedEncoding,
1723 authtime[5] KerberosTime,
1724 starttime[6] KerberosTime OPTIONAL,
1725 endtime[7] KerberosTime,
1726 renew-till[8] KerberosTime OPTIONAL,
1727 caddr[9] HostAddresses OPTIONAL,
1728 authorization-data[10] AuthorizationData OPTIONAL
1731 -- encoded Transited field
1732 TransitedEncoding ::= SEQUENCE {
1733 tr-type[0] INTEGER, -- must be registered
1734 contents[1] OCTET STRING
1737 -- Unencrypted authenticator
1738 Authenticator ::= [APPLICATION 2] SEQUENCE {
1739 authenticator-vno[0] INTEGER,
1741 cname[2] PrincipalName,
1742 cksum[3] Checksum OPTIONAL,
1744 ctime[5] KerberosTime,
1745 subkey[6] EncryptionKey OPTIONAL,
1746 seq-number[7] INTEGER OPTIONAL,
1747 authorization-data[8] AuthorizationData OPTIONAL
1750 PA-DATA ::= SEQUENCE {
1751 padata-type[1] INTEGER,
1752 padata-value[2] OCTET STRING,
1753 -- might be encoded AP-REQ
1756 padata-type ::= PA-ENC-TIMESTAMP
1757 padata-value ::= EncryptedData -- PA-ENC-TS-ENC
1759 PA-ENC-TS-ENC ::= SEQUENCE {
1760 patimestamp[0] KerberosTime, -- client's time
1761 pausec[1] INTEGER OPTIONAL
1764 EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart
1765 EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
1767 EncKDCRepPart ::= SEQUENCE {
1768 key[0] EncryptionKey,
1769 last-req[1] LastReq,
1771 key-expiration[3] KerberosTime OPTIONAL,
1772 flags[4] TicketFlags,
1773 authtime[5] KerberosTime,
1774 starttime[6] KerberosTime OPTIONAL,
1775 endtime[7] KerberosTime,
1776 renew-till[8] KerberosTime OPTIONAL,
1778 sname[10] PrincipalName,
1779 caddr[11] HostAddresses OPTIONAL
1782 AP-REQ ::= [APPLICATION 14] SEQUENCE {
1784 msg-type[1] INTEGER,
1785 ap-options[2] APOptions,
1787 authenticator[4] EncryptedData
1790 APOptions ::= BIT STRING {
1796 AP-REP ::= [APPLICATION 15] SEQUENCE {
1798 msg-type[1] INTEGER,
1799 enc-part[2] EncryptedData
1802 EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
1803 ctime[0] KerberosTime,
1805 subkey[2] EncryptionKey OPTIONAL,
1806 seq-number[3] INTEGER OPTIONAL
1809 KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
1811 msg-type[1] INTEGER,
1812 safe-body[2] KRB-SAFE-BODY,
1816 KRB-SAFE-BODY ::= SEQUENCE {
1817 user-data[0] OCTET STRING,
1818 timestamp[1] KerberosTime OPTIONAL,
1819 usec[2] INTEGER OPTIONAL,
1820 seq-number[3] INTEGER OPTIONAL,
1821 s-address[4] HostAddress,
1822 r-address[5] HostAddress OPTIONAL
1825 KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
1827 msg-type[1] INTEGER,
1828 enc-part[3] EncryptedData
1831 EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
1832 user-data[0] OCTET STRING,
1833 timestamp[1] KerberosTime OPTIONAL,
1834 usec[2] INTEGER OPTIONAL,
1835 seq-number[3] INTEGER OPTIONAL,
1836 s-address[4] HostAddress, -- sender's addr
1837 r-address[5] HostAddress OPTIONAL
1841 KRB-CRED ::= [APPLICATION 22] SEQUENCE {
1843 msg-type[1] INTEGER, -- KRB_CRED
1844 tickets[2] SEQUENCE OF Ticket,
1845 enc-part[3] EncryptedData
1848 EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
1849 ticket-info[0] SEQUENCE OF KrbCredInfo,
1850 nonce[1] INTEGER OPTIONAL,
1851 timestamp[2] KerberosTime OPTIONAL,
1852 usec[3] INTEGER OPTIONAL,
1853 s-address[4] HostAddress OPTIONAL,
1854 r-address[5] HostAddress OPTIONAL
1857 KrbCredInfo ::= SEQUENCE {
1858 key[0] EncryptionKey,
1859 prealm[1] Realm OPTIONAL,
1860 pname[2] PrincipalName OPTIONAL,
1861 flags[3] TicketFlags OPTIONAL,
1862 authtime[4] KerberosTime OPTIONAL,
1863 starttime[5] KerberosTime OPTIONAL,
1864 endtime[6] KerberosTime OPTIONAL
1865 renew-till[7] KerberosTime OPTIONAL,
1866 srealm[8] Realm OPTIONAL,
1867 sname[9] PrincipalName OPTIONAL,
1868 caddr[10] HostAddresses OPTIONAL
1871 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
1873 msg-type[1] INTEGER,
1874 ctime[2] KerberosTime OPTIONAL,
1875 cusec[3] INTEGER OPTIONAL,
1876 stime[4] KerberosTime,
1878 error-code[6] INTEGER,
1879 crealm[7] Realm OPTIONAL,
1880 cname[8] PrincipalName OPTIONAL,
1881 realm[9] Realm, -- Correct realm
1882 sname[10] PrincipalName, -- Correct name
1883 e-text[11] GeneralString OPTIONAL,
1884 e-data[12] OCTET STRING OPTIONAL
1887 e-data This field contains additional data about the error for use
1888 by the application to help it recover from or handle the
1889 error. If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
1890 the e-data field will contain an encoding of a sequence of
1891 padata fields, each corresponding to an acceptable pre-
1892 authentication method and optionally containing data for
1895 METHOD-DATA ::= SEQUENCE of PA-DATA
1897 If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
1898 contain an encoding of the following sequence:
1900 METHOD-DATA ::= SEQUENCE {
1901 method-type[0] INTEGER,
1902 method-data[1] OCTET STRING OPTIONAL
1905 EncryptionKey ::= SEQUENCE {
1907 keyvalue[1] OCTET STRING
1910 Checksum ::= SEQUENCE {
1911 cksumtype[0] INTEGER,
1912 checksum[1] OCTET STRING