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 * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9 * decryption of kerberos blobs if keytab is provided
11 * See RFC 1510, and various I-Ds and other documents showing additions,
12 * e.g. ones listed under
14 * http://www.isi.edu/people/bcn/krb-revisions/
18 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-07.txt
22 * http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-referrals-05.txt
24 * Some structures from RFC2630
26 * Wireshark - Network traffic analyzer
27 * By Gerald Combs <gerald@wireshark.org>
28 * Copyright 1998 Gerald Combs
30 * SPDX-License-Identifier: GPL-2.0-or-later
34 * Some of the development of the Kerberos protocol decoder was sponsored by
35 * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
36 * CableLabs' specifications. Your license and use of this protocol decoder
37 * does not mean that you are licensed to use the CableLabs'
38 * specifications. If you have questions about this protocol, contact
39 * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
46 #define HAVE_KRB5_CRYPTO_FX_CF2 1
47 #define HAVE_KRB5_C_FX_CF2_SIMPLE 1
51 #include <epan/packet.h>
52 #include <epan/exceptions.h>
53 #include <epan/strutil.h>
54 #include <epan/conversation.h>
55 #include <epan/asn1.h>
56 #include <epan/expert.h>
57 #include <epan/prefs.h>
58 #include <epan/proto_data.h>
59 #include <wsutil/wsgcrypt.h>
60 #include <wsutil/file_util.h>
61 #include <wsutil/str_util.h>
62 #include <wsutil/pint.h>
63 #include "packet-kerberos.h"
64 #include "packet-netbios.h"
65 #include "packet-tcp.h"
66 #include "packet-ber.h"
67 #include "packet-pkinit.h"
68 #include "packet-cms.h"
69 #include "packet-windows-common.h"
71 #include "read_keytab_file.h"
73 #include "packet-dcerpc-netlogon.h"
74 #include "packet-dcerpc.h"
76 #include "packet-gssapi.h"
77 #include "packet-smb-common.h"
78 #include "packet-x509af.h"
80 #define KEY_USAGE_FAST_REQ_CHKSUM 50
81 #define KEY_USAGE_FAST_ENC 51
82 #define KEY_USAGE_FAST_REP 52
83 #define KEY_USAGE_FAST_FINISHED 53
84 #define KEY_USAGE_ENC_CHALLENGE_CLIENT 54
85 #define KEY_USAGE_ENC_CHALLENGE_KDC 55
87 void proto_register_kerberos(void);
88 void proto_reg_handoff_kerberos(void);
90 #define UDP_PORT_KERBEROS 88
91 #define TCP_PORT_KERBEROS 88
93 #define ADDRESS_STR_BUFSIZ 256
95 typedef struct kerberos_key {
98 const guint8 *keyvalue;
103 gboolean kdc_response_initialized;
104 gboolean kdc_response;
106 gboolean try_nt_status;
109 guint32 is_enc_padata;
114 guint32 checksum_type;
115 const enc_key_t *last_decryption_key;
116 gboolean is_win2k_pkinit;
118 gboolean fast_armor_request;
119 gboolean fast_armor_within_enc_ticket_part;
120 const enc_key_t *fast_armor_ticket_sessionkey;
121 gboolean fast_armor_within_authenticator;
122 const enc_key_t *fast_armor_remote_subkey;
123 const enc_key_t *fast_armor_key;
124 gboolean fast_strengthen_key_needed;
125 const enc_key_t *fast_strengthen_key;
126 } kerberos_private_data_t;
128 static dissector_handle_t kerberos_handle_udp;
130 /* Forward declarations */
131 static int dissect_kerberos_Applications(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
132 static int dissect_kerberos_AuthorizationData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
133 static int dissect_kerberos_PA_ENC_TIMESTAMP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
134 static int dissect_kerberos_PA_ENC_TS_ENC(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
135 static int dissect_kerberos_PA_PAC_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
136 static int dissect_kerberos_PA_S4U2Self(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
137 static int dissect_kerberos_PA_S4U_X509_USER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
138 static int dissect_kerberos_ETYPE_INFO(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
139 static int dissect_kerberos_ETYPE_INFO2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
140 static int dissect_kerberos_AD_IF_RELEVANT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
141 static int dissect_kerberos_PA_AUTHENTICATION_SET_ELEM(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
142 static int dissect_kerberos_PA_FX_FAST_REQUEST(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
143 static int dissect_kerberos_PA_FX_FAST_REPLY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
144 static int dissect_kerberos_KrbFastReq(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
145 static int dissect_kerberos_KrbFastResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
146 static int dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
147 static int dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
148 static int dissect_kerberos_PA_PAC_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
149 static int dissect_kerberos_KERB_AD_RESTRICTION_ENTRY(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
150 static int dissect_kerberos_SEQUENCE_OF_ENCTYPE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
151 static int dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
152 static int dissect_kerberos_AD_TARGET_PRINCIPAL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
153 static int dissect_kerberos_Checksum(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
155 /* Desegment Kerberos over TCP messages */
156 static gboolean krb_desegment = TRUE;
158 static gint proto_kerberos = -1;
160 static gint hf_krb_rm_reserved = -1;
161 static gint hf_krb_rm_reclen = -1;
162 static gint hf_krb_provsrv_location = -1;
163 static gint hf_krb_smb_nt_status = -1;
164 static gint hf_krb_smb_unknown = -1;
165 static gint hf_krb_address_ip = -1;
166 static gint hf_krb_address_netbios = -1;
167 static gint hf_krb_address_ipv6 = -1;
168 static gint hf_krb_gssapi_len = -1;
169 static gint hf_krb_gssapi_bnd = -1;
170 static gint hf_krb_gssapi_dlgopt = -1;
171 static gint hf_krb_gssapi_dlglen = -1;
172 static gint hf_krb_gssapi_c_flag_deleg = -1;
173 static gint hf_krb_gssapi_c_flag_mutual = -1;
174 static gint hf_krb_gssapi_c_flag_replay = -1;
175 static gint hf_krb_gssapi_c_flag_sequence = -1;
176 static gint hf_krb_gssapi_c_flag_conf = -1;
177 static gint hf_krb_gssapi_c_flag_integ = -1;
178 static gint hf_krb_gssapi_c_flag_dce_style = -1;
179 static gint hf_krb_midl_version = -1;
180 static gint hf_krb_midl_hdr_len = -1;
181 static gint hf_krb_midl_fill_bytes = -1;
182 static gint hf_krb_midl_blob_len = -1;
183 static gint hf_krb_pac_signature_type = -1;
184 static gint hf_krb_pac_signature_signature = -1;
185 static gint hf_krb_w2k_pac_entries = -1;
186 static gint hf_krb_w2k_pac_version = -1;
187 static gint hf_krb_w2k_pac_type = -1;
188 static gint hf_krb_w2k_pac_size = -1;
189 static gint hf_krb_w2k_pac_offset = -1;
190 static gint hf_krb_pac_clientid = -1;
191 static gint hf_krb_pac_namelen = -1;
192 static gint hf_krb_pac_clientname = -1;
193 static gint hf_krb_pac_logon_info = -1;
194 static gint hf_krb_pac_credential_data = -1;
195 static gint hf_krb_pac_credential_info = -1;
196 static gint hf_krb_pac_credential_info_version = -1;
197 static gint hf_krb_pac_credential_info_etype = -1;
198 static gint hf_krb_pac_s4u_delegation_info = -1;
199 static gint hf_krb_pac_upn_dns_info = -1;
200 static gint hf_krb_pac_upn_flags = -1;
201 static gint hf_krb_pac_upn_dns_offset = -1;
202 static gint hf_krb_pac_upn_dns_len = -1;
203 static gint hf_krb_pac_upn_upn_offset = -1;
204 static gint hf_krb_pac_upn_upn_len = -1;
205 static gint hf_krb_pac_upn_upn_name = -1;
206 static gint hf_krb_pac_upn_dns_name = -1;
207 static gint hf_krb_pac_server_checksum = -1;
208 static gint hf_krb_pac_privsvr_checksum = -1;
209 static gint hf_krb_pac_client_info_type = -1;
210 static gint hf_krb_pac_client_claims_info = -1;
211 static gint hf_krb_pac_device_info = -1;
212 static gint hf_krb_pac_device_claims_info = -1;
213 static gint hf_krb_pa_supported_enctypes = -1;
214 static gint hf_krb_pa_supported_enctypes_des_cbc_crc = -1;
215 static gint hf_krb_pa_supported_enctypes_des_cbc_md5 = -1;
216 static gint hf_krb_pa_supported_enctypes_rc4_hmac = -1;
217 static gint hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96 = -1;
218 static gint hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96 = -1;
219 static gint hf_krb_pa_supported_enctypes_fast_supported = -1;
220 static gint hf_krb_pa_supported_enctypes_compound_identity_supported = -1;
221 static gint hf_krb_pa_supported_enctypes_claims_supported = -1;
222 static gint hf_krb_pa_supported_enctypes_resource_sid_compression_disabled = -1;
223 static gint hf_krb_ad_ap_options = -1;
224 static gint hf_krb_ad_ap_options_cbt = -1;
225 static gint hf_krb_ad_target_principal = -1;
226 #include "packet-kerberos-hf.c"
228 /* Initialize the subtree pointers */
229 static gint ett_kerberos = -1;
230 static gint ett_krb_recordmark = -1;
231 static gint ett_krb_pac = -1;
232 static gint ett_krb_pac_drep = -1;
233 static gint ett_krb_pac_midl_blob = -1;
234 static gint ett_krb_pac_logon_info = -1;
235 static gint ett_krb_pac_credential_info = -1;
236 static gint ett_krb_pac_s4u_delegation_info = -1;
237 static gint ett_krb_pac_upn_dns_info = -1;
238 static gint ett_krb_pac_server_checksum = -1;
239 static gint ett_krb_pac_privsvr_checksum = -1;
240 static gint ett_krb_pac_client_info_type = -1;
241 static gint ett_krb_pa_supported_enctypes = -1;
242 static gint ett_krb_ad_ap_options = -1;
243 #include "packet-kerberos-ett.c"
245 static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
246 static expert_field ei_kerberos_address = EI_INIT;
247 static expert_field ei_krb_gssapi_dlglen = EI_INIT;
249 static dissector_handle_t krb4_handle=NULL;
251 /* Global variables */
252 static guint32 gbl_keytype;
253 static gboolean gbl_do_col_info;
255 #include "packet-kerberos-val.h"
258 call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
266 cb->callback(pinfo, tvb, tree);
274 static kerberos_private_data_t*
275 kerberos_get_private_data_p(packet_info *pinfo)
277 void *p = p_get_proto_data(pinfo->pool, pinfo, proto_kerberos, 0);
279 p = wmem_new0(pinfo->pool, kerberos_private_data_t);
280 p_add_proto_data(pinfo->pool, pinfo, proto_kerberos, 0, p);
282 return (kerberos_private_data_t *)(p);
285 static kerberos_private_data_t*
286 kerberos_get_private_data(asn1_ctx_t *actx)
288 if (actx->private_data == NULL) {
289 actx->private_data = kerberos_get_private_data_p(actx->pinfo);
291 return (kerberos_private_data_t *)(actx->private_data);
295 kerberos_is_win2k_pkinit(asn1_ctx_t *actx)
297 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
299 return private_data->is_win2k_pkinit;
304 /* Decrypt Kerberos blobs */
305 gboolean krb_decrypt = FALSE;
307 /* keytab filename */
308 static const char *keytab_filename = "";
311 read_keytab_file_from_preferences(void)
313 static char *last_keytab = NULL;
319 if (keytab_filename == NULL) {
323 if (last_keytab && !strcmp(last_keytab, keytab_filename)) {
328 last_keytab = g_strdup(keytab_filename);
330 read_keytab_file(last_keytab);
332 #endif /* HAVE_KERBEROS */
334 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
336 /* prevent redefinition warnings in kfw-2.5\inc\win_mac.h */
337 #undef HAVE_GETADDRINFO
338 #undef HAVE_SYS_TYPES_H
341 enc_key_t *enc_key_list=NULL;
344 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
348 if(pinfo->fd->visited){
352 new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
353 g_snprintf(new_key->key_origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u",origin,pinfo->num);
354 new_key->fd_num = pinfo->num;
355 new_key->next=enc_key_list;
356 enc_key_list=new_key;
357 new_key->keytype=keytype;
358 new_key->keylength=keylength;
359 /*XXX this needs to be freed later */
360 new_key->keyvalue=(char *)g_memdup(keyvalue, keylength);
363 static void used_encryption_key(proto_tree *tree, packet_info *pinfo,
364 enc_key_t *ek, int usage, tvbuff_t *cryptotvb)
366 kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
368 proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
370 "Decrypted keytype %d usage %d in frame %u "
371 "using %s (%02x%02x%02x%02x...)",
372 ek->keytype, usage, pinfo->fd->num, ek->key_origin,
373 ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
374 ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
376 private_data->last_decryption_key = ek;
379 static void used_signing_key(proto_tree *tree, packet_info *pinfo,
380 enc_key_t *ek, tvbuff_t *tvb,
381 krb5_cksumtype checksum,
384 proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
386 "%s checksum %d keytype %d in frame %u "
387 "using %s (%02x%02x%02x%02x...)",
388 reason, checksum, ek->keytype, pinfo->fd->num, ek->key_origin,
389 ek->keyvalue[0] & 0xFF, ek->keyvalue[1] & 0xFF,
390 ek->keyvalue[2] & 0xFF, ek->keyvalue[3] & 0xFF);
394 krb5_fast_key(packet_info *pinfo,
395 const enc_key_t *ek1, const char *p1,
396 const enc_key_t *ek2, const char *p2,
400 krb5_fast_armor_key(packet_info *pinfo,
401 const enc_key_t *remote_subkey,
402 const enc_key_t *ticket_sessionkey)
404 kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
413 private_data->fast_armor_key = enc_key_list;
416 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
418 #if defined(HAVE_MIT_KERBEROS)
420 static krb5_context krb5_ctx;
423 krb5_fast_key(packet_info *pinfo,
424 const enc_key_t *ek1, const char *p1,
425 const enc_key_t *ek2, const char *p2,
428 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
432 krb5_keyblock *k = NULL;
446 k1.magic = KV5M_KEYBLOCK;
447 k1.enctype = ek1->keytype;
448 k1.length = ek1->keylength;
449 k1.contents = (guint8 *)ek1->keyvalue;
451 k2.magic = KV5M_KEYBLOCK;
452 k2.enctype = ek2->keytype;
453 k2.length = ek2->keylength;
454 k2.contents = (guint8 *)ek2->keyvalue;
456 ret = krb5_c_fx_cf2_simple(krb5_ctx, &k1, p1, &k2, p2, &k);
461 add_encryption_key(pinfo, k->enctype, k->length,
462 (const char *)k->contents, origin);
464 krb5_free_keyblock(krb5_ctx, k);
468 USES_APPLE_DEPRECATED_API
470 read_keytab_file(const char *filename)
474 krb5_keytab_entry key;
475 krb5_kt_cursor cursor;
476 static gboolean first_time=TRUE;
478 if (filename == NULL || filename[0] == 0) {
484 ret = krb5_init_context(&krb5_ctx);
485 if(ret && ret != KRB5_CONFIG_CANTOPEN){
490 /* should use a file in the wireshark users dir */
491 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
493 fprintf(stderr, "KERBEROS ERROR: Badly formatted keytab filename :%s\n",filename);
498 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
500 fprintf(stderr, "KERBEROS ERROR: Could not open or could not read from keytab file :%s\n",filename);
505 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
511 new_key = g_new(enc_key_t, 1);
512 new_key->fd_num = -1;
513 new_key->next = enc_key_list;
515 /* generate origin string, describing where this key came from */
516 pos=new_key->key_origin;
517 pos+=MIN(KRB_MAX_ORIG_LEN,
518 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
519 for(i=0;i<key.principal->length;i++){
520 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
521 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "%s%s",(i?"/":""),(key.principal->data[i]).data));
523 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
524 g_snprintf(pos, (gulong)(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin)), "@%s",key.principal->realm.data));
526 new_key->keytype=key.key.enctype;
527 new_key->keylength=key.key.length;
528 new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
529 enc_key_list=new_key;
530 ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
532 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
533 ret = 0; /* try to continue with the next entry */
538 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
540 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
542 ret = krb5_kt_close(krb5_ctx, keytab);
544 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
550 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
556 kerberos_private_data_t *private_data = kerberos_get_private_data_p(pinfo);
557 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
558 const enc_key_t *ak = private_data->fast_armor_key;
559 const enc_key_t *sk = private_data->fast_strengthen_key;
563 krb5_data data = {0,0,NULL};
564 krb5_keytab_entry key;
565 int length = tvb_captured_length(cryptotvb);
566 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
568 /* don't do anything if we are not attempting to decrypt data */
569 if(!krb_decrypt || length < 1){
573 /* make sure we have all the data we need */
574 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
578 read_keytab_file_from_preferences();
579 data.data = (char *)wmem_alloc(pinfo->pool, length);
580 data.length = length;
582 for(ek=enc_key_list;ek;ek=ek->next){
585 /* shortcircuit and bail out if enctypes are not matching */
586 if((keytype != -1) && (ek->keytype != keytype)) {
590 input.enctype = ek->keytype;
591 input.ciphertext.length = length;
592 input.ciphertext.data = (guint8 *)cryptotext;
594 #ifdef HAVE_KRB5_C_FX_CF2_SIMPLE
599 if (ak != NULL && ak != ek && ak->keytype == ek->keytype) {
602 krb5_keyblock *k = NULL;
603 const char *p1 = NULL;
605 k1.magic = KV5M_KEYBLOCK;
606 k1.enctype = ak->keytype;
607 k1.length = ak->keylength;
608 k1.contents = (guint8 *)ak->keyvalue;
610 k2.magic = KV5M_KEYBLOCK;
611 k2.enctype = ek->keytype;
612 k2.length = ek->keylength;
613 k2.contents = (guint8 *)ek->keyvalue;
615 if (private_data->kdc_response) {
616 p1 = "kdcchallengearmor";
618 p1 = "clientchallengearmor";
621 ret = krb5_c_fx_cf2_simple(krb5_ctx,
623 &k2, "challengelongterm",
629 ret = krb5_c_decrypt(krb5_ctx, k, usage, 0, &input, &data);
633 add_encryption_key(pinfo, k->enctype, k->length,
634 (const char *)k->contents,
636 krb5_free_keyblock(krb5_ctx, k);
638 used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
640 /* return a private g_malloced blob to the caller */
643 *datalen = data.length;
648 krb5_free_keyblock(krb5_ctx, k);
651 if (sk != NULL && sk != ek && sk->keytype == ek->keytype) {
654 krb5_keyblock *k = NULL;
656 k1.magic = KV5M_KEYBLOCK;
657 k1.enctype = sk->keytype;
658 k1.length = sk->keylength;
659 k1.contents = (guint8 *)sk->keyvalue;
661 k2.magic = KV5M_KEYBLOCK;
662 k2.enctype = ek->keytype;
663 k2.length = ek->keylength;
664 k2.contents = (guint8 *)ek->keyvalue;
666 ret = krb5_c_fx_cf2_simple(krb5_ctx,
667 &k1, "strengthenkey",
674 ret = krb5_c_decrypt(krb5_ctx, k, usage, 0, &input, &data);
678 add_encryption_key(pinfo, k->enctype, k->length,
679 (const char *)k->contents,
681 krb5_free_keyblock(krb5_ctx, k);
683 used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
685 /* return a private g_malloced blob to the caller */
688 *datalen = data.length;
693 krb5_free_keyblock(krb5_ctx, k);
697 key.key.enctype=ek->keytype;
698 key.key.length=ek->keylength;
699 key.key.contents=ek->keyvalue;
700 ret = krb5_c_decrypt(krb5_ctx, &(key.key), usage, 0, &input, &data);
704 used_encryption_key(tree, pinfo, ek, usage, cryptotvb);
708 *datalen = data.length;
718 extern krb5_error_code
719 krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
722 verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
725 enc_key_t *ek = NULL;;
726 krb5_data checksum_data = {0,0,NULL};
727 krb5_cksumtype server_checksum = 0;
728 krb5_cksumtype kdc_checksum = 0;
729 int length = tvb_captured_length(pactvb);
730 const guint8 *pacbuffer = NULL;
733 /* don't do anything if we are not attempting to decrypt data */
734 if(!krb_decrypt || length < 1){
738 /* make sure we have all the data we need */
739 if (tvb_captured_length(pactvb) < tvb_reported_length(pactvb)) {
743 pacbuffer = tvb_get_ptr(pactvb, 0, length);
745 ret = krb5_pac_parse(krb5_ctx, pacbuffer, length, &pac);
747 proto_tree_add_expert_format(tree, actx->pinfo, &ei_kerberos_decrypted_keytype,
749 "Failed to parse PAC buffer %d in frame %u",
750 ret, actx->pinfo->fd->num);
754 ret = krb5_pac_get_buffer(krb5_ctx, pac, KRB5_PAC_SERVER_CHECKSUM,
757 server_checksum = pletoh32(checksum_data.data);
758 krb5_free_data_contents(krb5_ctx, &checksum_data);
760 ret = krb5_pac_get_buffer(krb5_ctx, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
763 kdc_checksum = pletoh32(checksum_data.data);
764 krb5_free_data_contents(krb5_ctx, &checksum_data);
767 read_keytab_file_from_preferences();
769 for(ek=enc_key_list;ek;ek=ek->next){
770 krb5_keyblock keyblock;
771 krb5_cksumtype checksumtype = 0;
773 if (server_checksum == 0 && kdc_checksum == 0) {
777 ret = krb5int_c_mandatory_cksumtype(krb5_ctx, ek->keytype,
783 keyblock.magic = KV5M_KEYBLOCK;
784 keyblock.enctype = ek->keytype;
785 keyblock.length = ek->keylength;
786 keyblock.contents = (guint8 *)ek->keyvalue;
788 if (checksumtype == server_checksum) {
789 ret = krb5_pac_verify(krb5_ctx, pac, 0, NULL,
792 used_signing_key(tree, actx->pinfo, ek, pactvb,
793 server_checksum, "Verified Server");
798 if (checksumtype == kdc_checksum) {
799 ret = krb5_pac_verify(krb5_ctx, pac, 0, NULL,
802 used_signing_key(tree, actx->pinfo, ek, pactvb,
803 kdc_checksum, "Verified KDC");
810 krb5_pac_free(krb5_ctx, pac);
813 #elif defined(HAVE_HEIMDAL_KERBEROS)
814 static krb5_context krb5_ctx;
816 USES_APPLE_DEPRECATED_API
819 krb5_fast_key(packet_info *pinfo,
820 const enc_key_t *ek1, const char *p1,
821 const enc_key_t *ek2, const char *p2,
824 #ifdef HAVE_KRB5_CRYPTO_FX_CF2
829 read_keytab_file(const char *filename)
833 krb5_keytab_entry key;
834 krb5_kt_cursor cursor;
836 static gboolean first_time=TRUE;
838 if (filename == NULL || filename[0] == 0) {
844 ret = krb5_init_context(&krb5_ctx);
850 /* should use a file in the wireshark users dir */
851 ret = krb5_kt_resolve(krb5_ctx, filename, &keytab);
853 fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
858 ret = krb5_kt_start_seq_get(krb5_ctx, keytab, &cursor);
860 fprintf(stderr, "KERBEROS ERROR: Could not read from keytab file :%s\n",filename);
865 ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
870 new_key = g_new0(enc_key_t, 1);
871 new_key->fd_num = -1;
872 new_key->next = enc_key_list;
874 /* generate origin string, describing where this key came from */
875 pos=new_key->key_origin;
876 pos+=MIN(KRB_MAX_ORIG_LEN,
877 g_snprintf(pos, KRB_MAX_ORIG_LEN, "keytab principal "));
878 for(i=0;i<key.principal->name.name_string.len;i++){
879 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
880 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "%s%s",(i?"/":""),key.principal->name.name_string.val[i]));
882 pos+=MIN(KRB_MAX_ORIG_LEN-(pos-new_key->key_origin),
883 g_snprintf(pos, KRB_MAX_ORIG_LEN-(pos-new_key->key_origin), "@%s",key.principal->realm));
885 new_key->keytype=key.keyblock.keytype;
886 new_key->keylength=(int)key.keyblock.keyvalue.length;
887 new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
888 enc_key_list=new_key;
889 ret = krb5_kt_free_entry(krb5_ctx, &key);
891 fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
892 ret = 0; /* try to continue with the next entry */
897 ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
899 fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
901 ret = krb5_kt_close(krb5_ctx, keytab);
903 fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
911 decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
920 int length = tvb_captured_length(cryptotvb);
921 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
923 /* don't do anything if we are not attempting to decrypt data */
928 /* make sure we have all the data we need */
929 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
933 read_keytab_file_from_preferences();
935 for(ek=enc_key_list;ek;ek=ek->next){
936 krb5_keytab_entry key;
938 guint8 *cryptocopy; /* workaround for pre-0.6.1 heimdal bug */
940 /* shortcircuit and bail out if enctypes are not matching */
941 if((keytype != -1) && (ek->keytype != keytype)) {
945 key.keyblock.keytype=ek->keytype;
946 key.keyblock.keyvalue.length=ek->keylength;
947 key.keyblock.keyvalue.data=ek->keyvalue;
948 ret = krb5_crypto_init(krb5_ctx, &(key.keyblock), (krb5_enctype)ENCTYPE_NULL, &crypto);
953 /* pre-0.6.1 versions of Heimdal would sometimes change
954 the cryptotext data even when the decryption failed.
955 This would obviously not work since we iterate over the
956 keys. So just give it a copy of the crypto data instead.
957 This has been seen for RC4-HMAC blobs.
959 cryptocopy = (guint8 *)wmem_memdup(wmem_packet_scope(), cryptotext, length);
960 ret = krb5_decrypt_ivec(krb5_ctx, crypto, usage,
964 if((ret == 0) && (length>0)){
967 proto_tree_add_expert_format(tree, pinfo, &ei_kerberos_decrypted_keytype,
969 "Decrypted keytype %d in frame %u using %s",
970 ek->keytype, pinfo->num, ek->key_origin);
972 krb5_crypto_destroy(krb5_ctx, crypto);
973 /* return a private wmem_alloced blob to the caller */
974 user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
976 *datalen = (int)data.length;
980 krb5_crypto_destroy(krb5_ctx, crypto);
985 #elif defined (HAVE_LIBNETTLE)
987 #define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
988 #define KEYTYPE_DES3_CBC_MD5 5 /* Currently the only one supported */
990 typedef struct _service_key_t {
995 char origin[KRB_MAX_ORIG_LEN+1];
997 GSList *service_key_list = NULL;
1001 add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, const char *origin)
1003 service_key_t *new_key;
1005 if(pinfo->fd->visited){
1009 new_key = g_malloc(sizeof(service_key_t));
1011 new_key->keytype = keytype;
1012 new_key->length = keylength;
1013 new_key->contents = g_memdup(keyvalue, keylength);
1014 g_snprintf(new_key->origin, KRB_MAX_ORIG_LEN, "%s learnt from frame %u", origin, pinfo->num);
1015 service_key_list = g_slist_append(service_key_list, (gpointer) new_key);
1019 clear_keytab(void) {
1023 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
1024 sk = (service_key_t *) ske->data;
1026 g_free(sk->contents);
1030 g_slist_free(service_key_list);
1031 service_key_list = NULL;
1035 read_keytab_file(const char *service_key_file)
1040 unsigned char buf[SERVICE_KEY_SIZE];
1041 int newline_skip = 0, count = 0;
1043 if (service_key_file != NULL && ws_stat64 (service_key_file, &st) == 0) {
1045 /* The service key file contains raw 192-bit (24 byte) 3DES keys.
1046 * There can be zero, one (\n), or two (\r\n) characters between
1047 * keys. Trailing characters are ignored.
1050 /* XXX We should support the standard keytab format instead */
1051 if (st.st_size > SERVICE_KEY_SIZE) {
1052 if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
1053 (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
1055 } else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
1056 (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
1061 skf = ws_fopen(service_key_file, "rb");
1064 while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
1065 sk = g_malloc(sizeof(service_key_t));
1066 sk->kvno = buf[0] << 8 | buf[1];
1067 sk->keytype = KEYTYPE_DES3_CBC_MD5;
1068 sk->length = DES3_KEY_SIZE;
1069 sk->contents = g_memdup(buf + 2, DES3_KEY_SIZE);
1070 g_snprintf(sk->origin, KRB_MAX_ORIG_LEN, "3DES service key file, key #%d, offset %ld", count, ftell(skf));
1071 service_key_list = g_slist_append(service_key_list, (gpointer) sk);
1072 if (fseek(skf, newline_skip, SEEK_CUR) < 0) {
1073 fprintf(stderr, "unable to seek...\n");
1082 #define CONFOUNDER_PLUS_CHECKSUM 24
1085 decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
1087 tvbuff_t *cryptotvb,
1092 guint8 *decrypted_data = NULL, *plaintext = NULL;
1095 guint32 tag, item_len, data_len;
1096 int id_offset, offset;
1097 guint8 key[DES3_KEY_SIZE];
1098 guint8 initial_vector[DES_BLOCK_SIZE];
1099 gcry_md_hd_t md5_handle;
1101 guint8 zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1102 guint8 confounder[8];
1106 struct des3_ctx ctx;
1107 int length = tvb_captured_length(cryptotvb);
1108 const guint8 *cryptotext = tvb_get_ptr(cryptotvb, 0, length);
1111 /* don't do anything if we are not attempting to decrypt data */
1116 /* make sure we have all the data we need */
1117 if (tvb_captured_length(cryptotvb) < tvb_reported_length(cryptotvb)) {
1121 if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
1125 decrypted_data = wmem_alloc(wmem_packet_scope(), length);
1126 for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
1127 gboolean do_continue = FALSE;
1129 sk = (service_key_t *) ske->data;
1131 des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
1133 memset(initial_vector, 0, DES_BLOCK_SIZE);
1134 des3_set_key(&ctx, key);
1135 cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
1136 length, decrypted_data, cryptotext);
1137 encr_tvb = tvb_new_real_data(decrypted_data, length, length);
1139 tvb_memcpy(encr_tvb, confounder, 0, 8);
1141 /* We have to pull the decrypted data length from the decrypted
1142 * content. If the key doesn't match or we otherwise get garbage,
1143 * an exception may get thrown while decoding the ASN.1 header.
1144 * Catch it, just in case.
1147 id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
1148 offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
1150 CATCH_BOUNDS_ERRORS {
1156 if (do_continue) continue;
1158 data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
1159 if ((int) item_len + offset > length) {
1164 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
1167 gcry_md_write(md5_handle, confounder, 8);
1168 gcry_md_write(md5_handle, zero_fill, 16);
1169 gcry_md_write(md5_handle, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
1170 digest = gcry_md_read(md5_handle, 0);
1172 digest_ok = (tvb_memeql (encr_tvb, 8, digest, HASH_MD5_LENGTH) == 0);
1173 gcry_md_close(md5_handle);
1175 plaintext = (guint8* )tvb_memdup(pinfo->pool, encr_tvb, CONFOUNDER_PLUS_CHECKSUM, data_len);
1179 *datalen = data_len;
1189 #endif /* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
1191 #define INET6_ADDRLEN 16
1193 /* TCP Record Mark */
1194 #define KRB_RM_RESERVED 0x80000000U
1195 #define KRB_RM_RECLEN 0x7fffffffU
1197 #define KRB5_MSG_TICKET 1 /* Ticket */
1198 #define KRB5_MSG_AUTHENTICATOR 2 /* Authenticator */
1199 #define KRB5_MSG_ENC_TICKET_PART 3 /* EncTicketPart */
1200 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
1201 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
1202 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
1203 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
1204 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
1205 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
1207 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
1208 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
1209 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
1210 #define KRB5_MSG_ENC_AS_REP_PART 25 /* EncASRepPart */
1211 #define KRB5_MSG_ENC_TGS_REP_PART 26 /* EncTGSRepPart */
1212 #define KRB5_MSG_ENC_AP_REP_PART 27 /* EncAPRepPart */
1213 #define KRB5_MSG_ENC_KRB_PRIV_PART 28 /* EncKrbPrivPart */
1214 #define KRB5_MSG_ENC_KRB_CRED_PART 29 /* EncKrbCredPart */
1215 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
1217 #define KRB5_CHKSUM_GSSAPI 0x8003
1219 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
1221 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
1223 * unless it's expired.
1226 /* Principal name-type */
1227 #define KRB5_NT_UNKNOWN 0
1228 #define KRB5_NT_PRINCIPAL 1
1229 #define KRB5_NT_SRV_INST 2
1230 #define KRB5_NT_SRV_HST 3
1231 #define KRB5_NT_SRV_XHST 4
1232 #define KRB5_NT_UID 5
1233 #define KRB5_NT_X500_PRINCIPAL 6
1234 #define KRB5_NT_SMTP_NAME 7
1235 #define KRB5_NT_ENTERPRISE 10
1238 * MS specific name types, from
1240 * http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
1242 #define KRB5_NT_MS_PRINCIPAL -128
1243 #define KRB5_NT_MS_PRINCIPAL_AND_SID -129
1244 #define KRB5_NT_ENT_PRINCIPAL_AND_SID -130
1245 #define KRB5_NT_PRINCIPAL_AND_SID -131
1246 #define KRB5_NT_SRV_INST_AND_SID -132
1248 /* error table constants */
1249 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
1250 #define KRB5_ET_KRB5KDC_ERR_NONE 0
1251 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
1252 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
1253 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
1254 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
1255 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
1256 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
1257 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
1258 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
1259 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
1260 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
1261 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
1262 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
1263 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
1264 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
1265 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
1266 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
1267 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
1268 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
1269 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
1270 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
1271 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
1272 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
1273 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
1274 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
1275 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
1276 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
1277 #define KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER 27
1278 #define KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED 28
1279 #define KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE 29
1280 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
1281 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
1282 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
1283 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
1284 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
1285 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
1286 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
1287 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
1288 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
1289 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
1290 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
1291 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
1292 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
1293 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
1294 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
1295 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
1296 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
1297 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
1298 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
1299 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
1300 #define KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED 51
1301 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG 52
1302 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
1303 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
1304 #define KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED 62
1305 #define KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED 63
1306 #define KRB5_ET_KDC_ERROR_INVALID_SIG 64
1307 #define KRB5_ET_KDC_ERR_KEY_TOO_WEAK 65
1308 #define KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH 66
1309 #define KRB5_ET_KRB_AP_ERR_NO_TGT 67
1310 #define KRB5_ET_KDC_ERR_WRONG_REALM 68
1311 #define KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED 69
1312 #define KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE 70
1313 #define KRB5_ET_KDC_ERR_INVALID_CERTIFICATE 71
1314 #define KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE 72
1315 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN 73
1316 #define KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE 74
1317 #define KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH 75
1318 #define KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH 76
1319 #define KRB5_ET_KDC_ERR_PREAUTH_EXPIRED 90
1320 #define KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91
1321 #define KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET 92
1322 #define KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS 93
1324 static const value_string krb5_error_codes[] = {
1325 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
1326 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
1327 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
1328 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
1329 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
1330 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
1331 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
1332 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
1333 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
1334 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
1335 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
1336 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
1337 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
1338 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
1339 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
1340 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
1341 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
1342 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
1343 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
1344 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
1345 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
1346 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
1347 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
1348 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
1349 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
1350 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
1351 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
1352 { KRB5_ET_KRB5KDC_ERR_MUST_USE_USER2USER, "KRB5KDC_ERR_MUST_USE_USER2USER" },
1353 { KRB5_ET_KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KRB5KDC_ERR_PATH_NOT_ACCEPTED" },
1354 { KRB5_ET_KRB5KDC_ERR_SVC_UNAVAILABLE, "KRB5KDC_ERR_SVC_UNAVAILABLE" },
1355 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
1356 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
1357 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
1358 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
1359 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
1360 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
1361 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
1362 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
1363 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
1364 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
1365 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
1366 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
1367 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
1368 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
1369 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
1370 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
1371 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
1372 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
1373 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
1374 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
1375 { KRB5_ET_KRB5KDC_AP_PATH_NOT_ACCEPTED, "KRB5KDC_AP_PATH_NOT_ACCEPTED" },
1376 { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
1377 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
1378 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
1379 { KRB5_ET_KDC_ERROR_CLIENT_NOT_TRUSTED, "KDC_ERROR_CLIENT_NOT_TRUSTED" },
1380 { KRB5_ET_KDC_ERROR_KDC_NOT_TRUSTED, "KDC_ERROR_KDC_NOT_TRUSTED" },
1381 { KRB5_ET_KDC_ERROR_INVALID_SIG, "KDC_ERROR_INVALID_SIG" },
1382 { KRB5_ET_KDC_ERR_KEY_TOO_WEAK, "KDC_ERR_KEY_TOO_WEAK" },
1383 { KRB5_ET_KDC_ERR_CERTIFICATE_MISMATCH, "KDC_ERR_CERTIFICATE_MISMATCH" },
1384 { KRB5_ET_KRB_AP_ERR_NO_TGT, "KRB_AP_ERR_NO_TGT" },
1385 { KRB5_ET_KDC_ERR_WRONG_REALM, "KDC_ERR_WRONG_REALM" },
1386 { KRB5_ET_KRB_AP_ERR_USER_TO_USER_REQUIRED, "KRB_AP_ERR_USER_TO_USER_REQUIRED" },
1387 { KRB5_ET_KDC_ERR_CANT_VERIFY_CERTIFICATE, "KDC_ERR_CANT_VERIFY_CERTIFICATE" },
1388 { KRB5_ET_KDC_ERR_INVALID_CERTIFICATE, "KDC_ERR_INVALID_CERTIFICATE" },
1389 { KRB5_ET_KDC_ERR_REVOKED_CERTIFICATE, "KDC_ERR_REVOKED_CERTIFICATE" },
1390 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "KDC_ERR_REVOCATION_STATUS_UNKNOWN" },
1391 { KRB5_ET_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "KDC_ERR_REVOCATION_STATUS_UNAVAILABLE" },
1392 { KRB5_ET_KDC_ERR_CLIENT_NAME_MISMATCH, "KDC_ERR_CLIENT_NAME_MISMATCH" },
1393 { KRB5_ET_KDC_ERR_KDC_NAME_MISMATCH, "KDC_ERR_KDC_NAME_MISMATCH" },
1394 { KRB5_ET_KDC_ERR_PREAUTH_EXPIRED, "KDC_ERR_PREAUTH_EXPIRED" },
1395 { KRB5_ET_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "KDC_ERR_MORE_PREAUTH_DATA_REQUIRED" },
1396 { KRB5_ET_KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET, "KDC_ERR_PREAUTH_BAD_AUTHENTICATION_SET" },
1397 { KRB5_ET_KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, "KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS" },
1402 #define PAC_LOGON_INFO 1
1403 #define PAC_CREDENTIAL_TYPE 2
1404 #define PAC_SERVER_CHECKSUM 6
1405 #define PAC_PRIVSVR_CHECKSUM 7
1406 #define PAC_CLIENT_INFO_TYPE 10
1407 #define PAC_S4U_DELEGATION_INFO 11
1408 #define PAC_UPN_DNS_INFO 12
1409 #define PAC_CLIENT_CLAIMS_INFO 13
1410 #define PAC_DEVICE_INFO 14
1411 #define PAC_DEVICE_CLAIMS_INFO 15
1412 static const value_string w2k_pac_types[] = {
1413 { PAC_LOGON_INFO , "Logon Info" },
1414 { PAC_CREDENTIAL_TYPE , "Credential Type" },
1415 { PAC_SERVER_CHECKSUM , "Server Checksum" },
1416 { PAC_PRIVSVR_CHECKSUM , "Privsvr Checksum" },
1417 { PAC_CLIENT_INFO_TYPE , "Client Info Type" },
1418 { PAC_S4U_DELEGATION_INFO , "S4U Delegation Info" },
1419 { PAC_UPN_DNS_INFO , "UPN DNS Info" },
1420 { PAC_CLIENT_CLAIMS_INFO , "Client Claims Info" },
1421 { PAC_DEVICE_INFO , "Device Info" },
1422 { PAC_DEVICE_CLAIMS_INFO , "Device Claims Info" },
1426 static const value_string krb5_msg_types[] = {
1427 { KRB5_MSG_TICKET, "Ticket" },
1428 { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
1429 { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
1430 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
1431 { KRB5_MSG_TGS_REP, "TGS-REP" },
1432 { KRB5_MSG_AS_REQ, "AS-REQ" },
1433 { KRB5_MSG_AS_REP, "AS-REP" },
1434 { KRB5_MSG_AP_REQ, "AP-REQ" },
1435 { KRB5_MSG_AP_REP, "AP-REP" },
1436 { KRB5_MSG_SAFE, "KRB-SAFE" },
1437 { KRB5_MSG_PRIV, "KRB-PRIV" },
1438 { KRB5_MSG_CRED, "KRB-CRED" },
1439 { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
1440 { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
1441 { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
1442 { KRB5_MSG_ENC_KRB_PRIV_PART, "EncKrbPrivPart" },
1443 { KRB5_MSG_ENC_KRB_CRED_PART, "EncKrbCredPart" },
1444 { KRB5_MSG_ERROR, "KRB-ERROR" },
1448 #define KRB5_GSS_C_DELEG_FLAG 0x01
1449 #define KRB5_GSS_C_MUTUAL_FLAG 0x02
1450 #define KRB5_GSS_C_REPLAY_FLAG 0x04
1451 #define KRB5_GSS_C_SEQUENCE_FLAG 0x08
1452 #define KRB5_GSS_C_CONF_FLAG 0x10
1453 #define KRB5_GSS_C_INTEG_FLAG 0x20
1454 #define KRB5_GSS_C_DCE_STYLE 0x1000
1456 static const true_false_string tfs_gss_flags_deleg = {
1457 "Delegate credentials to remote peer",
1460 static const true_false_string tfs_gss_flags_mutual = {
1461 "Request that remote peer authenticates itself",
1462 "Mutual authentication NOT required"
1464 static const true_false_string tfs_gss_flags_replay = {
1465 "Enable replay protection for signed or sealed messages",
1466 "Do NOT enable replay protection"
1468 static const true_false_string tfs_gss_flags_sequence = {
1469 "Enable Out-of-sequence detection for sign or sealed messages",
1470 "Do NOT enable out-of-sequence detection"
1472 static const true_false_string tfs_gss_flags_conf = {
1473 "Confidentiality (sealing) may be invoked",
1474 "Do NOT use Confidentiality (sealing)"
1476 static const true_false_string tfs_gss_flags_integ = {
1477 "Integrity protection (signing) may be invoked",
1478 "Do NOT use integrity protection"
1481 static const true_false_string tfs_gss_flags_dce_style = {
1483 "Not using DCE-STYLE"
1486 #ifdef HAVE_KERBEROS
1488 dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1489 proto_tree *tree, int hf_index _U_)
1493 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1496 next_tvb=tvb_new_subset_remaining(tvb, offset);
1497 length=tvb_captured_length_remaining(tvb, offset);
1499 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1501 * All Ticket encrypted parts use usage == 2
1503 plaintext=decrypt_krb5_data(tree, actx->pinfo, 2, next_tvb, private_data->etype, NULL);
1506 tvbuff_t *child_tvb;
1507 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1509 /* Add the decrypted data to the data source list. */
1510 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1512 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1518 dissect_krb5_decrypt_authenticator_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1519 proto_tree *tree, int hf_index _U_)
1523 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1526 next_tvb=tvb_new_subset_remaining(tvb, offset);
1527 length=tvb_captured_length_remaining(tvb, offset);
1529 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1531 * Authenticators are encrypted with usage
1535 plaintext=decrypt_krb5_data(tree, actx->pinfo, 7, next_tvb, private_data->etype, NULL);
1538 plaintext=decrypt_krb5_data(tree, actx->pinfo, 11, next_tvb, private_data->etype, NULL);
1542 tvbuff_t *child_tvb;
1543 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1545 /* Add the decrypted data to the data source list. */
1546 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1548 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1554 dissect_krb5_decrypt_authorization_data(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1555 proto_tree *tree, int hf_index _U_)
1559 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1562 next_tvb=tvb_new_subset_remaining(tvb, offset);
1563 length=tvb_captured_length_remaining(tvb, offset);
1565 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1567 * Authenticators are encrypted with usage
1571 plaintext=decrypt_krb5_data(tree, actx->pinfo, 5, next_tvb, private_data->etype, NULL);
1574 plaintext=decrypt_krb5_data(tree, actx->pinfo, 4, next_tvb, private_data->etype, NULL);
1578 tvbuff_t *child_tvb;
1579 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1581 /* Add the decrypted data to the data source list. */
1582 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1584 offset=dissect_kerberos_AuthorizationData(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1590 dissect_krb5_decrypt_KDC_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1591 proto_tree *tree, int hf_index _U_)
1595 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1598 next_tvb=tvb_new_subset_remaining(tvb, offset);
1599 length=tvb_captured_length_remaining(tvb, offset);
1601 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1603 * ASREP/TGSREP encryptedparts are encrypted with usage
1608 plaintext=decrypt_krb5_data(tree, actx->pinfo, 3, next_tvb, private_data->etype, NULL);
1611 plaintext=decrypt_krb5_data(tree, actx->pinfo, 8, next_tvb, private_data->etype, NULL);
1615 plaintext=decrypt_krb5_data(tree, actx->pinfo, 9, next_tvb, private_data->etype, NULL);
1619 tvbuff_t *child_tvb;
1620 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1622 /* Add the decrypted data to the data source list. */
1623 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1625 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1631 dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1632 proto_tree *tree, int hf_index _U_)
1636 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1639 next_tvb=tvb_new_subset_remaining(tvb, offset);
1640 length=tvb_captured_length_remaining(tvb, offset);
1642 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1644 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
1647 plaintext=decrypt_krb5_data(tree, actx->pinfo, 1, next_tvb, private_data->etype, NULL);
1650 tvbuff_t *child_tvb;
1651 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1653 /* Add the decrypted data to the data source list. */
1654 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1656 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1662 dissect_krb5_decrypt_AP_REP_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1663 proto_tree *tree, int hf_index _U_)
1667 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1670 next_tvb=tvb_new_subset_remaining(tvb, offset);
1671 length=tvb_captured_length_remaining(tvb, offset);
1673 /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
1675 * AP-REP are encrypted with usage == 12
1677 plaintext=decrypt_krb5_data(tree, actx->pinfo, 12, next_tvb, private_data->etype, NULL);
1680 tvbuff_t *child_tvb;
1681 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1683 /* Add the decrypted data to the data source list. */
1684 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1686 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1692 dissect_krb5_decrypt_PRIV_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1693 proto_tree *tree, int hf_index _U_)
1697 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1700 next_tvb=tvb_new_subset_remaining(tvb, offset);
1701 length=tvb_captured_length_remaining(tvb, offset);
1704 * EncKrbPrivPart encrypted with usage
1707 plaintext=decrypt_krb5_data(tree, actx->pinfo, 13, next_tvb, private_data->etype, NULL);
1710 tvbuff_t *child_tvb;
1711 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1713 /* Add the decrypted data to the data source list. */
1714 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1716 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1722 dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1723 proto_tree *tree, int hf_index _U_)
1727 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1730 next_tvb=tvb_new_subset_remaining(tvb, offset);
1731 length=tvb_captured_length_remaining(tvb, offset);
1734 * EncKrbCredPart encrypted with usage
1737 plaintext=decrypt_krb5_data(tree, actx->pinfo, 14, next_tvb, private_data->etype, NULL);
1740 tvbuff_t *child_tvb;
1741 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1743 /* Add the decrypted data to the data source list. */
1744 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1746 offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1752 dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1753 proto_tree *tree, int hf_index _U_)
1757 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1760 next_tvb=tvb_new_subset_remaining(tvb, offset);
1761 length=tvb_captured_length_remaining(tvb, offset);
1764 * KrbFastResponse encrypted with usage
1765 * KEY_USAGE_FAST_ENC 51
1767 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
1768 next_tvb, private_data->etype, NULL);
1771 tvbuff_t *child_tvb;
1772 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1774 /* Add the decrypted data to the data source list. */
1775 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1777 offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1783 dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1784 proto_tree *tree, int hf_index _U_)
1788 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1791 next_tvb=tvb_new_subset_remaining(tvb, offset);
1792 length=tvb_captured_length_remaining(tvb, offset);
1796 * KrbFastResponse encrypted with usage
1797 * KEY_USAGE_FAST_REP 52
1799 plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
1800 next_tvb, private_data->etype, NULL);
1803 tvbuff_t *child_tvb;
1804 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1806 /* Add the decrypted data to the data source list. */
1807 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1809 private_data->fast_armor_key = private_data->last_decryption_key;
1810 offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1816 dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
1817 proto_tree *tree, int hf_index _U_)
1821 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1825 next_tvb=tvb_new_subset_remaining(tvb, offset);
1826 length=tvb_captured_length_remaining(tvb, offset);
1829 * KEY_USAGE_ENC_CHALLENGE_CLIENT 54
1830 * KEY_USAGE_ENC_CHALLENGE_KDC 55
1832 if (private_data->kdc_response) {
1833 usage = KEY_USAGE_ENC_CHALLENGE_KDC;
1835 usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
1837 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
1840 tvbuff_t *child_tvb;
1841 child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
1843 /* Add the decrypted data to the data source list. */
1844 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
1846 offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
1852 static const int *hf_krb_pa_supported_enctypes_fields[] = {
1853 &hf_krb_pa_supported_enctypes_des_cbc_crc,
1854 &hf_krb_pa_supported_enctypes_des_cbc_md5,
1855 &hf_krb_pa_supported_enctypes_rc4_hmac,
1856 &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
1857 &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
1858 &hf_krb_pa_supported_enctypes_fast_supported,
1859 &hf_krb_pa_supported_enctypes_compound_identity_supported,
1860 &hf_krb_pa_supported_enctypes_claims_supported,
1861 &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
1865 static const true_false_string supported_tfs = {
1866 "Supported", "Not supported"
1870 dissect_kerberos_PA_SUPPORTED_ENCTYPES(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1871 int offset _U_, asn1_ctx_t *actx _U_,
1872 proto_tree *tree _U_, int hf_index _U_)
1874 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1875 hf_krb_pa_supported_enctypes,
1876 ett_krb_pa_supported_enctypes,
1877 hf_krb_pa_supported_enctypes_fields,
1884 static const int *hf_krb_ad_ap_options_fields[] = {
1885 &hf_krb_ad_ap_options_cbt,
1889 static const true_false_string set_tfs = {
1894 dissect_kerberos_AD_AP_OPTIONS(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1895 int offset _U_, asn1_ctx_t *actx _U_,
1896 proto_tree *tree _U_, int hf_index _U_)
1898 actx->created_item = proto_tree_add_bitmask(tree, tvb, offset,
1899 hf_krb_ad_ap_options,
1900 ett_krb_ad_ap_options,
1901 hf_krb_ad_ap_options_fields,
1909 dissect_kerberos_AD_TARGET_PRINCIPAL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
1910 int offset _U_, asn1_ctx_t *actx _U_,
1911 proto_tree *tree _U_, int hf_index _U_)
1913 int tp_offset, tp_len;
1917 bc = tvb_reported_length_remaining(tvb, offset);
1920 tp = get_unicode_or_ascii_string(tvb, &offset, TRUE, &tp_len, TRUE, TRUE, &bc);
1921 proto_tree_add_string(tree, hf_krb_ad_target_principal, tvb, tp_offset, tp_len, tp);
1926 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
1929 dissect_krb5_rfc1964_checksum(asn1_ctx_t *actx _U_, proto_tree *tree, tvbuff_t *tvb)
1935 /* Length of Bnd field */
1936 len=tvb_get_letohl(tvb, offset);
1937 proto_tree_add_item(tree, hf_krb_gssapi_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1941 proto_tree_add_item(tree, hf_krb_gssapi_bnd, tvb, offset, len, ENC_NA);
1946 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_dce_style, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1947 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_integ, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1948 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_conf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1949 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_sequence, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1950 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_replay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1951 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_mutual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1952 proto_tree_add_item(tree, hf_krb_gssapi_c_flag_deleg, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1955 /* the next fields are optional so we have to check that we have
1956 * more data in our buffers */
1957 if(tvb_reported_length_remaining(tvb, offset)<2){
1960 /* dlgopt identifier */
1961 proto_tree_add_item(tree, hf_krb_gssapi_dlgopt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1964 if(tvb_reported_length_remaining(tvb, offset)<2){
1967 /* dlglen identifier */
1968 dlglen=tvb_get_letohs(tvb, offset);
1969 proto_tree_add_item(tree, hf_krb_gssapi_dlglen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1972 if(dlglen!=tvb_reported_length_remaining(tvb, offset)){
1973 proto_tree_add_expert_format(tree, actx->pinfo, &ei_krb_gssapi_dlglen, tvb, 0, 0,
1974 "Error: DlgLen:%d is not the same as number of bytes remaining:%d", dlglen, tvb_captured_length_remaining(tvb, offset));
1978 /* this should now be a KRB_CRED message */
1979 offset=dissect_kerberos_Applications(FALSE, tvb, offset, actx, tree, /* hf_index */ -1);
1985 dissect_krb5_PA_PROV_SRV_LOCATION(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1987 offset=dissect_ber_GeneralString(actx, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
1993 dissect_krb5_PW_SALT(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_)
1995 kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
1996 gint remaining = tvb_reported_length_remaining(tvb, offset);
1997 guint32 nt_status = 0;
2001 if (private_data->errorcode == 0) {
2005 if (!private_data->try_nt_status) {
2009 if (remaining != 12) {
2013 nt_status=tvb_get_letohl(tvb, offset);
2014 val_0=tvb_get_letohl(tvb, offset + 4);
2015 val_1=tvb_get_letohl(tvb, offset + 8);
2017 if (val_0 != 0 || val_1 != 1) {
2021 /* Microsoft stores a special 12 byte blob here
2023 * guint32 unknown (== 0)
2024 * guint32 unknown (== 1)
2026 proto_tree_add_item(tree, hf_krb_smb_nt_status, tvb, offset, 4,
2028 nt_status=tvb_get_letohl(tvb, offset);
2030 col_append_fstr(actx->pinfo->cinfo, COL_INFO,
2032 val_to_str(nt_status, NT_errors,
2033 "Unknown error code %#x"));
2037 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2041 proto_tree_add_item(tree, hf_krb_smb_unknown, tvb, offset, 4,
2048 return offset + remaining;
2052 dissect_krb5_PAC_DREP(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep)
2057 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_drep, NULL, "DREP");
2059 val = tvb_get_guint8(tvb, offset);
2060 proto_tree_add_uint(tree, hf_dcerpc_drep_byteorder, tvb, offset, 1, val>>4);
2071 /* This might be some sort of header that MIDL generates when creating
2072 * marshalling/unmarshalling code for blobs that are not to be transported
2073 * ontop of DCERPC and where the DREP fields specifying things such as
2074 * endianess and similar are not available.
2077 dissect_krb5_PAC_NDRHEADERBLOB(proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 *drep, asn1_ctx_t *actx _U_)
2081 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16, ett_krb_pac_midl_blob, NULL, "MES header");
2083 /* modified DREP field that is used for stuff that is transporetd ontop
2086 proto_tree_add_item(tree, hf_krb_midl_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2089 offset = dissect_krb5_PAC_DREP(tree, tvb, offset, drep);
2092 proto_tree_add_item(tree, hf_krb_midl_hdr_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2095 proto_tree_add_item(tree, hf_krb_midl_fill_bytes, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2098 /* length of blob that follows */
2099 proto_tree_add_item(tree, hf_krb_midl_blob_len, tvb, offset, 8, ENC_LITTLE_ENDIAN);
2106 dissect_krb5_PAC_LOGON_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2110 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2111 static dcerpc_info di; /* fake dcerpc_info struct */
2112 static dcerpc_call_value call_data;
2114 item = proto_tree_add_item(parent_tree, hf_krb_pac_logon_info, tvb, offset, -1, ENC_NA);
2115 tree = proto_item_add_subtree(item, ett_krb_pac_logon_info);
2117 /* skip the first 16 bytes, they are some magic created by the idl
2118 * compiler the first 4 bytes might be flags?
2120 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2122 /* the PAC_LOGON_INFO blob */
2123 /* fake whatever state the dcerpc runtime support needs */
2124 di.conformant_run=0;
2125 /* we need di->call_data->flags.NDR64 == 0 */
2126 di.call_data=&call_data;
2127 init_ndr_pointer_list(&di);
2128 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2129 netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_UNIQUE,
2130 "PAC_LOGON_INFO:", -1);
2137 dissect_krb5_PAC_CREDENTIAL_DATA(proto_tree *parent_tree, tvbuff_t *tvb, int offset, packet_info *pinfo _U_)
2139 proto_tree_add_item(parent_tree, hf_krb_pac_credential_data, tvb, offset, -1, ENC_NA);
2145 dissect_krb5_PAC_CREDENTIAL_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2150 guint8 *plaintext = NULL;
2154 #define KRB5_KU_OTHER_ENCRYPTED 16
2155 int usage = KRB5_KU_OTHER_ENCRYPTED;
2157 item = proto_tree_add_item(parent_tree, hf_krb_pac_credential_info, tvb, offset, -1, ENC_NA);
2158 tree = proto_item_add_subtree(item, ett_krb_pac_credential_info);
2161 proto_tree_add_item(tree, hf_krb_pac_credential_info_version, tvb,
2162 offset, 4, ENC_LITTLE_ENDIAN);
2166 etype = tvb_get_letohl(tvb, offset);
2167 proto_tree_add_item(tree, hf_krb_pac_credential_info_etype, tvb,
2168 offset, 4, ENC_LITTLE_ENDIAN);
2172 next_tvb=tvb_new_subset_remaining(tvb, offset);
2173 length=tvb_captured_length_remaining(tvb, offset);
2175 plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, (int)etype, &plainlen);
2177 if (plaintext != NULL) {
2178 tvbuff_t *child_tvb;
2179 child_tvb = tvb_new_child_real_data(tvb, plaintext, plainlen, plainlen);
2181 /* Add the decrypted data to the data source list. */
2182 add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
2184 dissect_krb5_PAC_CREDENTIAL_DATA(tree, child_tvb, 0, actx->pinfo);
2187 return offset + length;
2191 dissect_krb5_PAC_S4U_DELEGATION_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2195 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
2196 static dcerpc_info di; /* fake dcerpc_info struct */
2197 static dcerpc_call_value call_data;
2199 item = proto_tree_add_item(parent_tree, hf_krb_pac_s4u_delegation_info, tvb, offset, -1, ENC_NA);
2200 tree = proto_item_add_subtree(item, ett_krb_pac_s4u_delegation_info);
2202 /* skip the first 16 bytes, they are some magic created by the idl
2203 * compiler the first 4 bytes might be flags?
2205 offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
2208 /* the S4U_DELEGATION_INFO blob. See [MS-PAC] */
2209 /* fake whatever state the dcerpc runtime support needs */
2210 di.conformant_run=0;
2211 /* we need di->call_data->flags.NDR64 == 0 */
2212 di.call_data=&call_data;
2213 init_ndr_pointer_list(&di);
2214 offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
2215 netlogon_dissect_PAC_S4U_DELEGATION_INFO, NDR_POINTER_UNIQUE,
2216 "PAC_S4U_DELEGATION_INFO:", -1);
2222 dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2226 guint16 dns_offset, dns_len;
2227 guint16 upn_offset, upn_len;
2232 item = proto_tree_add_item(parent_tree, hf_krb_pac_upn_dns_info, tvb, offset, -1, ENC_NA);
2233 tree = proto_item_add_subtree(item, ett_krb_pac_upn_dns_info);
2236 upn_len = tvb_get_letohs(tvb, offset);
2237 proto_tree_add_item(tree, hf_krb_pac_upn_upn_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2239 upn_offset = tvb_get_letohs(tvb, offset);
2240 proto_tree_add_item(tree, hf_krb_pac_upn_upn_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2244 dns_len = tvb_get_letohs(tvb, offset);
2245 proto_tree_add_item(tree, hf_krb_pac_upn_dns_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2247 dns_offset = tvb_get_letohs(tvb, offset);
2248 proto_tree_add_item(tree, hf_krb_pac_upn_dns_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2252 proto_tree_add_item(tree, hf_krb_pac_upn_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2255 offset = upn_offset;
2257 bc = tvb_reported_length_remaining(tvb, offset);
2258 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
2259 proto_tree_add_string(tree, hf_krb_pac_upn_upn_name, tvb, upn_offset, upn_len, dn);
2262 offset = dns_offset;
2264 bc = tvb_reported_length_remaining(tvb, offset);
2265 dn = get_unicode_or_ascii_string(tvb, &offset, TRUE, &dn_len, TRUE, TRUE, &bc);
2266 proto_tree_add_string(tree, hf_krb_pac_upn_dns_name, tvb, dns_offset, dns_len, dn);
2272 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2274 proto_tree_add_item(parent_tree, hf_krb_pac_client_claims_info, tvb, offset, -1, ENC_NA);
2280 dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2282 proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
2288 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2290 proto_tree_add_item(parent_tree, hf_krb_pac_device_claims_info, tvb, offset, -1, ENC_NA);
2296 dissect_krb5_PAC_SERVER_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2301 item = proto_tree_add_item(parent_tree, hf_krb_pac_server_checksum, tvb, offset, -1, ENC_NA);
2302 tree = proto_item_add_subtree(item, ett_krb_pac_server_checksum);
2304 /* signature type */
2305 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2308 /* signature data */
2309 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
2315 dissect_krb5_PAC_PRIVSVR_CHECKSUM(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2320 item = proto_tree_add_item(parent_tree, hf_krb_pac_privsvr_checksum, tvb, offset, -1, ENC_NA);
2321 tree = proto_item_add_subtree(item, ett_krb_pac_privsvr_checksum);
2323 /* signature type */
2324 proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2327 /* signature data */
2328 proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, -1, ENC_NA);
2334 dissect_krb5_PAC_CLIENT_INFO_TYPE(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2340 item = proto_tree_add_item(parent_tree, hf_krb_pac_client_info_type, tvb, offset, -1, ENC_NA);
2341 tree = proto_item_add_subtree(item, ett_krb_pac_client_info_type);
2344 offset = dissect_nt_64bit_time(tvb, tree, offset, hf_krb_pac_clientid);
2347 namelen=tvb_get_letohs(tvb, offset);
2348 proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
2352 proto_tree_add_item(tree, hf_krb_pac_clientname, tvb, offset, namelen, ENC_UTF_16|ENC_LITTLE_ENDIAN);
2359 dissect_krb5_AD_WIN2K_PAC_struct(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx)
2364 proto_item *it=NULL;
2365 proto_tree *tr=NULL;
2368 /* type of pac data */
2369 pac_type=tvb_get_letohl(tvb, offset);
2370 it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
2371 tr=proto_item_add_subtree(it, ett_krb_pac);
2375 /* size of pac data */
2376 pac_size=tvb_get_letohl(tvb, offset);
2377 proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
2380 /* offset to pac data */
2381 pac_offset=tvb_get_letohl(tvb, offset);
2382 proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
2385 next_tvb=tvb_new_subset_length_caplen(tvb, pac_offset, pac_size, pac_size);
2387 case PAC_LOGON_INFO:
2388 dissect_krb5_PAC_LOGON_INFO(tr, next_tvb, 0, actx);
2390 case PAC_CREDENTIAL_TYPE:
2391 dissect_krb5_PAC_CREDENTIAL_INFO(tr, next_tvb, 0, actx);
2393 case PAC_SERVER_CHECKSUM:
2394 dissect_krb5_PAC_SERVER_CHECKSUM(tr, next_tvb, 0, actx);
2396 case PAC_PRIVSVR_CHECKSUM:
2397 dissect_krb5_PAC_PRIVSVR_CHECKSUM(tr, next_tvb, 0, actx);
2399 case PAC_CLIENT_INFO_TYPE:
2400 dissect_krb5_PAC_CLIENT_INFO_TYPE(tr, next_tvb, 0, actx);
2402 case PAC_S4U_DELEGATION_INFO:
2403 dissect_krb5_PAC_S4U_DELEGATION_INFO(tr, next_tvb, 0, actx);
2405 case PAC_UPN_DNS_INFO:
2406 dissect_krb5_PAC_UPN_DNS_INFO(tr, next_tvb, 0, actx);
2408 case PAC_CLIENT_CLAIMS_INFO:
2409 dissect_krb5_PAC_CLIENT_CLAIMS_INFO(tr, next_tvb, 0, actx);
2411 case PAC_DEVICE_INFO:
2412 dissect_krb5_PAC_DEVICE_INFO(tr, next_tvb, 0, actx);
2414 case PAC_DEVICE_CLAIMS_INFO:
2415 dissect_krb5_PAC_DEVICE_CLAIMS_INFO(tr, next_tvb, 0, actx);
2425 dissect_krb5_AD_WIN2K_PAC(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
2431 #ifdef HAVE_KERBEROS
2432 verify_krb5_pac(tree, actx, tvb);
2435 /* first in the PAC structure comes the number of entries */
2436 entries=tvb_get_letohl(tvb, offset);
2437 proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
2440 /* second comes the version */
2441 version=tvb_get_letohl(tvb, offset);
2442 proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
2445 for(i=0;i<entries;i++){
2446 offset=dissect_krb5_AD_WIN2K_PAC_struct(tree, tvb, offset, actx);
2452 #include "packet-kerberos-fn.c"
2454 /* Make wrappers around exported functions for now */
2456 dissect_krb5_Checksum(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2458 return dissect_kerberos_Checksum(FALSE, tvb, offset, actx, tree, hf_kerberos_cksum);
2463 dissect_krb5_ctime(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2465 return dissect_kerberos_KerberosTime(FALSE, tvb, offset, actx, tree, hf_kerberos_ctime);
2470 dissect_krb5_cname(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2472 return dissect_kerberos_PrincipalName(FALSE, tvb, offset, actx, tree, hf_kerberos_cname);
2475 dissect_krb5_realm(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
2477 return dissect_kerberos_Realm(FALSE, tvb, offset, actx, tree, hf_kerberos_realm);
2482 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2483 gboolean dci, gboolean do_col_protocol, gboolean have_rm,
2484 kerberos_callbacks *cb)
2486 volatile int offset = 0;
2487 proto_tree *volatile kerberos_tree = NULL;
2488 proto_item *volatile item = NULL;
2489 asn1_ctx_t asn1_ctx;
2491 /* TCP record mark and length */
2493 gint krb_reclen = 0;
2495 gbl_do_col_info=dci;
2498 krb_rm = tvb_get_ntohl(tvb, offset);
2499 krb_reclen = kerberos_rm_to_reclen(krb_rm);
2501 * What is a reasonable size limit?
2503 if (krb_reclen > 10 * 1024 * 1024) {
2507 if (do_col_protocol) {
2508 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2512 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2513 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2516 show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
2519 /* Do some sanity checking here,
2520 * All krb5 packets start with a TAG class that is BER_CLASS_APP
2521 * and a tag value that is either of the values below:
2522 * If it doesn't look like kerberos, return 0 and let someone else have
2529 get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
2530 if(tmp_class!=BER_CLASS_APP){
2534 case KRB5_MSG_TICKET:
2535 case KRB5_MSG_AUTHENTICATOR:
2536 case KRB5_MSG_ENC_TICKET_PART:
2537 case KRB5_MSG_AS_REQ:
2538 case KRB5_MSG_AS_REP:
2539 case KRB5_MSG_TGS_REQ:
2540 case KRB5_MSG_TGS_REP:
2541 case KRB5_MSG_AP_REQ:
2542 case KRB5_MSG_AP_REP:
2543 case KRB5_MSG_ENC_AS_REP_PART:
2544 case KRB5_MSG_ENC_TGS_REP_PART:
2545 case KRB5_MSG_ENC_AP_REP_PART:
2546 case KRB5_MSG_ENC_KRB_PRIV_PART:
2547 case KRB5_MSG_ENC_KRB_CRED_PART:
2550 case KRB5_MSG_ERROR:
2555 if (do_col_protocol) {
2556 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2558 if (gbl_do_col_info) {
2559 col_clear(pinfo->cinfo, COL_INFO);
2562 item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, ENC_NA);
2563 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
2566 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2567 asn1_ctx.private_data = cb;
2570 offset=dissect_kerberos_Applications(FALSE, tvb, offset, &asn1_ctx , kerberos_tree, /* hf_index */ -1);
2571 } CATCH_BOUNDS_ERRORS {
2575 proto_item_set_len(item, offset);
2580 * Display the TCP record mark.
2583 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
2586 proto_tree *rm_tree;
2591 rec_len = kerberos_rm_to_reclen(krb_rm);
2592 rm_tree = proto_tree_add_subtree_format(tree, tvb, start, 4, ett_krb_recordmark, NULL,
2593 "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
2594 proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
2595 proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
2599 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info, kerberos_callbacks *cb)
2601 return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE, FALSE, cb));
2605 kerberos_output_keytype(void)
2611 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2613 /* Some weird kerberos implementation apparently do krb4 on the krb5 port.
2614 Since all (except weirdo transarc krb4 stuff) use
2615 an opcode <=16 in the first byte, use this to see if it might
2617 All krb5 commands start with an APPL tag and thus is >=0x60
2618 so if first byte is <=16 just blindly assume it is krb4 then
2620 if(tvb_captured_length(tvb) >= 1 && tvb_get_guint8(tvb, 0)<=0x10){
2624 res=call_dissector_only(krb4_handle, tvb, pinfo, tree, NULL);
2632 return dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, FALSE, NULL);
2636 kerberos_rm_to_reclen(guint krb_rm)
2638 return (krb_rm & KRB_RM_RECLEN);
2642 get_krb_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2647 krb_rm = tvb_get_ntohl(tvb, offset);
2648 pdulen = kerberos_rm_to_reclen(krb_rm);
2649 return (pdulen + 4);
2652 kerberos_prefs_apply_cb(void) {
2653 #ifdef HAVE_LIBNETTLE
2655 read_keytab_file(keytab_filename);
2660 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2662 pinfo->fragmented = TRUE;
2663 if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE, TRUE, NULL) < 0) {
2665 * The dissector failed to recognize this as a valid
2666 * Kerberos message. Mark it as a continuation packet.
2668 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
2671 return tvb_captured_length(tvb);
2675 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2677 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
2678 col_clear(pinfo->cinfo, COL_INFO);
2680 tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
2681 dissect_kerberos_tcp_pdu, data);
2682 return tvb_captured_length(tvb);
2685 /*--- proto_register_kerberos -------------------------------------------*/
2686 void proto_register_kerberos(void) {
2688 /* List of fields */
2690 static hf_register_info hf[] = {
2691 { &hf_krb_rm_reserved, {
2692 "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
2693 TFS(&tfs_set_notset), KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
2694 { &hf_krb_rm_reclen, {
2695 "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
2696 NULL, KRB_RM_RECLEN, NULL, HFILL }},
2697 { &hf_krb_provsrv_location, {
2698 "PROVSRV Location", "kerberos.provsrv_location", FT_STRING, BASE_NONE,
2699 NULL, 0, "PacketCable PROV SRV Location", HFILL }},
2700 { &hf_krb_smb_nt_status,
2701 { "NT Status", "kerberos.smb.nt_status", FT_UINT32, BASE_HEX,
2702 VALS(NT_errors), 0, "NT Status code", HFILL }},
2703 { &hf_krb_smb_unknown,
2704 { "Unknown", "kerberos.smb.unknown", FT_UINT32, BASE_HEX,
2705 NULL, 0, NULL, HFILL }},
2706 { &hf_krb_address_ip, {
2707 "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
2708 NULL, 0, NULL, HFILL }},
2709 { &hf_krb_address_ipv6, {
2710 "IPv6 Address", "kerberos.addr_ipv6", FT_IPv6, BASE_NONE,
2711 NULL, 0, NULL, HFILL }},
2712 { &hf_krb_address_netbios, {
2713 "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
2714 NULL, 0, "NetBIOS Address and type", HFILL }},
2715 { &hf_krb_gssapi_len, {
2716 "Length", "kerberos.gssapi.len", FT_UINT32, BASE_DEC,
2717 NULL, 0, "Length of GSSAPI Bnd field", HFILL }},
2718 { &hf_krb_gssapi_bnd, {
2719 "Bnd", "kerberos.gssapi.bdn", FT_BYTES, BASE_NONE,
2720 NULL, 0, "GSSAPI Bnd field", HFILL }},
2721 { &hf_krb_gssapi_c_flag_deleg, {
2722 "Deleg", "kerberos.gssapi.checksum.flags.deleg", FT_BOOLEAN, 32,
2723 TFS(&tfs_gss_flags_deleg), KRB5_GSS_C_DELEG_FLAG, NULL, HFILL }},
2724 { &hf_krb_gssapi_c_flag_mutual, {
2725 "Mutual", "kerberos.gssapi.checksum.flags.mutual", FT_BOOLEAN, 32,
2726 TFS(&tfs_gss_flags_mutual), KRB5_GSS_C_MUTUAL_FLAG, NULL, HFILL }},
2727 { &hf_krb_gssapi_c_flag_replay, {
2728 "Replay", "kerberos.gssapi.checksum.flags.replay", FT_BOOLEAN, 32,
2729 TFS(&tfs_gss_flags_replay), KRB5_GSS_C_REPLAY_FLAG, NULL, HFILL }},
2730 { &hf_krb_gssapi_c_flag_sequence, {
2731 "Sequence", "kerberos.gssapi.checksum.flags.sequence", FT_BOOLEAN, 32,
2732 TFS(&tfs_gss_flags_sequence), KRB5_GSS_C_SEQUENCE_FLAG, NULL, HFILL }},
2733 { &hf_krb_gssapi_c_flag_conf, {
2734 "Conf", "kerberos.gssapi.checksum.flags.conf", FT_BOOLEAN, 32,
2735 TFS(&tfs_gss_flags_conf), KRB5_GSS_C_CONF_FLAG, NULL, HFILL }},
2736 { &hf_krb_gssapi_c_flag_integ, {
2737 "Integ", "kerberos.gssapi.checksum.flags.integ", FT_BOOLEAN, 32,
2738 TFS(&tfs_gss_flags_integ), KRB5_GSS_C_INTEG_FLAG, NULL, HFILL }},
2739 { &hf_krb_gssapi_c_flag_dce_style, {
2740 "DCE-style", "kerberos.gssapi.checksum.flags.dce-style", FT_BOOLEAN, 32,
2741 TFS(&tfs_gss_flags_dce_style), KRB5_GSS_C_DCE_STYLE, NULL, HFILL }},
2742 { &hf_krb_gssapi_dlgopt, {
2743 "DlgOpt", "kerberos.gssapi.dlgopt", FT_UINT16, BASE_DEC,
2744 NULL, 0, "GSSAPI DlgOpt", HFILL }},
2745 { &hf_krb_gssapi_dlglen, {
2746 "DlgLen", "kerberos.gssapi.dlglen", FT_UINT16, BASE_DEC,
2747 NULL, 0, "GSSAPI DlgLen", HFILL }},
2748 { &hf_krb_midl_blob_len, {
2749 "Blob Length", "kerberos.midl_blob_len", FT_UINT64, BASE_DEC,
2750 NULL, 0, "Length of NDR encoded data that follows", HFILL }},
2751 { &hf_krb_midl_fill_bytes, {
2752 "Fill bytes", "kerberos.midl.fill_bytes", FT_UINT32, BASE_HEX,
2753 NULL, 0, "Just some fill bytes", HFILL }},
2754 { &hf_krb_midl_version, {
2755 "Version", "kerberos.midl.version", FT_UINT8, BASE_DEC,
2756 NULL, 0, "Version of pickling", HFILL }},
2757 { &hf_krb_midl_hdr_len, {
2758 "HDR Length", "kerberos.midl.hdr_len", FT_UINT16, BASE_DEC,
2759 NULL, 0, "Length of header", HFILL }},
2760 { &hf_krb_pac_signature_type, {
2761 "Type", "kerberos.pac.signature.type", FT_INT32, BASE_DEC,
2762 NULL, 0, "PAC Signature Type", HFILL }},
2763 { &hf_krb_pac_signature_signature, {
2764 "Signature", "kerberos.pac.signature.signature", FT_BYTES, BASE_NONE,
2765 NULL, 0, "A PAC signature blob", HFILL }},
2766 { &hf_krb_w2k_pac_entries, {
2767 "Num Entries", "kerberos.pac.entries", FT_UINT32, BASE_DEC,
2768 NULL, 0, "Number of W2k PAC entries", HFILL }},
2769 { &hf_krb_w2k_pac_version, {
2770 "Version", "kerberos.pac.version", FT_UINT32, BASE_DEC,
2771 NULL, 0, "Version of PAC structures", HFILL }},
2772 { &hf_krb_w2k_pac_type, {
2773 "Type", "kerberos.pac.type", FT_UINT32, BASE_DEC,
2774 VALS(w2k_pac_types), 0, "Type of W2k PAC entry", HFILL }},
2775 { &hf_krb_w2k_pac_size, {
2776 "Size", "kerberos.pac.size", FT_UINT32, BASE_DEC,
2777 NULL, 0, "Size of W2k PAC entry", HFILL }},
2778 { &hf_krb_w2k_pac_offset, {
2779 "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
2780 NULL, 0, "Offset to W2k PAC entry", HFILL }},
2781 { &hf_krb_pac_clientid, {
2782 "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2783 NULL, 0, "ClientID Timestamp", HFILL }},
2784 { &hf_krb_pac_namelen, {
2785 "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
2786 NULL, 0, "Length of client name", HFILL }},
2787 { &hf_krb_pac_clientname, {
2788 "Name", "kerberos.pac.name", FT_STRING, BASE_NONE,
2789 NULL, 0, "Name of the Client in the PAC structure", HFILL }},
2790 { &hf_krb_pac_logon_info, {
2791 "PAC_LOGON_INFO", "kerberos.pac_logon_info", FT_BYTES, BASE_NONE,
2792 NULL, 0, "PAC_LOGON_INFO structure", HFILL }},
2793 { &hf_krb_pac_credential_data, {
2794 "PAC_CREDENTIAL_DATA", "kerberos.pac_credential_data", FT_BYTES, BASE_NONE,
2795 NULL, 0, "PAC_CREDENTIAL_DATA structure", HFILL }},
2796 { &hf_krb_pac_credential_info, {
2797 "PAC_CREDENTIAL_INFO", "kerberos.pac_credential_info", FT_BYTES, BASE_NONE,
2798 NULL, 0, "PAC_CREDENTIAL_INFO structure", HFILL }},
2799 { &hf_krb_pac_credential_info_version, {
2800 "Version", "kerberos.pac_credential_info.version", FT_UINT32, BASE_DEC,
2801 NULL, 0, NULL, HFILL }},
2802 { &hf_krb_pac_credential_info_etype, {
2803 "Etype", "kerberos.pac_credential_info.etype", FT_UINT32, BASE_DEC,
2804 NULL, 0, NULL, HFILL }},
2805 { &hf_krb_pac_server_checksum, {
2806 "PAC_SERVER_CHECKSUM", "kerberos.pac_server_checksum", FT_BYTES, BASE_NONE,
2807 NULL, 0, "PAC_SERVER_CHECKSUM structure", HFILL }},
2808 { &hf_krb_pac_privsvr_checksum, {
2809 "PAC_PRIVSVR_CHECKSUM", "kerberos.pac_privsvr_checksum", FT_BYTES, BASE_NONE,
2810 NULL, 0, "PAC_PRIVSVR_CHECKSUM structure", HFILL }},
2811 { &hf_krb_pac_client_info_type, {
2812 "PAC_CLIENT_INFO_TYPE", "kerberos.pac_client_info_type", FT_BYTES, BASE_NONE,
2813 NULL, 0, "PAC_CLIENT_INFO_TYPE structure", HFILL }},
2814 { &hf_krb_pac_s4u_delegation_info, {
2815 "PAC_S4U_DELEGATION_INFO", "kerberos.pac_s4u_delegation_info", FT_BYTES, BASE_NONE,
2816 NULL, 0, "PAC_S4U_DELEGATION_INFO structure", HFILL }},
2817 { &hf_krb_pac_upn_dns_info, {
2818 "UPN_DNS_INFO", "kerberos.pac_upn_dns_info", FT_BYTES, BASE_NONE,
2819 NULL, 0, "UPN_DNS_INFO structure", HFILL }},
2820 { &hf_krb_pac_upn_flags, {
2821 "Flags", "kerberos.pac.upn.flags", FT_UINT32, BASE_HEX,
2822 NULL, 0, "UPN flags", HFILL }},
2823 { &hf_krb_pac_upn_dns_offset, {
2824 "DNS Offset", "kerberos.pac.upn.dns_offset", FT_UINT16, BASE_DEC,
2825 NULL, 0, NULL, HFILL }},
2826 { &hf_krb_pac_upn_dns_len, {
2827 "DNS Len", "kerberos.pac.upn.dns_len", FT_UINT16, BASE_DEC,
2828 NULL, 0, NULL, HFILL }},
2829 { &hf_krb_pac_upn_upn_offset, {
2830 "UPN Offset", "kerberos.pac.upn.upn_offset", FT_UINT16, BASE_DEC,
2831 NULL, 0, NULL, HFILL }},
2832 { &hf_krb_pac_upn_upn_len, {
2833 "UPN Len", "kerberos.pac.upn.upn_len", FT_UINT16, BASE_DEC,
2834 NULL, 0, NULL, HFILL }},
2835 { &hf_krb_pac_upn_upn_name, {
2836 "UPN Name", "kerberos.pac.upn.upn_name", FT_STRING, BASE_NONE,
2837 NULL, 0, NULL, HFILL }},
2838 { &hf_krb_pac_upn_dns_name, {
2839 "DNS Name", "kerberos.pac.upn.dns_name", FT_STRING, BASE_NONE,
2840 NULL, 0, NULL, HFILL }},
2841 { &hf_krb_pac_client_claims_info, {
2842 "PAC_CLIENT_CLAIMS_INFO", "kerberos.pac_client_claims_info", FT_BYTES, BASE_NONE,
2843 NULL, 0, "PAC_CLIENT_CLAIMS_INFO structure", HFILL }},
2844 { &hf_krb_pac_device_info, {
2845 "PAC_DEVICE_INFO", "kerberos.pac_device_info", FT_BYTES, BASE_NONE,
2846 NULL, 0, "PAC_DEVICE_INFO structure", HFILL }},
2847 { &hf_krb_pac_device_claims_info, {
2848 "PAC_DEVICE_CLAIMS_INFO", "kerberos.pac_device_claims_info", FT_BYTES, BASE_NONE,
2849 NULL, 0, "PAC_DEVICE_CLAIMS_INFO structure", HFILL }},
2850 { &hf_krb_pa_supported_enctypes,
2851 { "SupportedEnctypes", "kerberos.supported_entypes",
2852 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2853 { &hf_krb_pa_supported_enctypes_des_cbc_crc,
2854 { "des-cbc-crc", "kerberos.supported_entypes.des-cbc-crc",
2855 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000001, NULL, HFILL }},
2856 { &hf_krb_pa_supported_enctypes_des_cbc_md5,
2857 { "des-cbc-md5", "kerberos.supported_entypes.des-cbc-md5",
2858 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000002, NULL, HFILL }},
2859 { &hf_krb_pa_supported_enctypes_rc4_hmac,
2860 { "rc4-hmac", "kerberos.supported_entypes.rc4-hmac",
2861 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000004, NULL, HFILL }},
2862 { &hf_krb_pa_supported_enctypes_aes128_cts_hmac_sha1_96,
2863 { "aes128-cts-hmac-sha1-96", "kerberos.supported_entypes.aes128-cts-hmac-sha1-96",
2864 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000008, NULL, HFILL }},
2865 { &hf_krb_pa_supported_enctypes_aes256_cts_hmac_sha1_96,
2866 { "aes256-cts-hmac-sha1-96", "kerberos.supported_entypes.aes256-cts-hmac-sha1-96",
2867 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00000010, NULL, HFILL }},
2868 { &hf_krb_pa_supported_enctypes_fast_supported,
2869 { "fast-supported", "kerberos.supported_entypes.fast-supported",
2870 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00010000, NULL, HFILL }},
2871 { &hf_krb_pa_supported_enctypes_compound_identity_supported,
2872 { "compound-identity-supported", "kerberos.supported_entypes.compound-identity-supported",
2873 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00020000, NULL, HFILL }},
2874 { &hf_krb_pa_supported_enctypes_claims_supported,
2875 { "claims-supported", "kerberos.supported_entypes.claims-supported",
2876 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00040000, NULL, HFILL }},
2877 { &hf_krb_pa_supported_enctypes_resource_sid_compression_disabled,
2878 { "resource-sid-compression-disabled", "kerberos.supported_entypes.resource-sid-compression-disabled",
2879 FT_BOOLEAN, 32, TFS(&supported_tfs), 0x00080000, NULL, HFILL }},
2880 { &hf_krb_ad_ap_options,
2881 { "AD-AP-Options", "kerberos.ad_ap_options",
2882 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
2883 { &hf_krb_ad_ap_options_cbt,
2884 { "ChannelBindings", "kerberos.ad_ap_options.cbt",
2885 FT_BOOLEAN, 32, TFS(&set_tfs), 0x00004000, NULL, HFILL }},
2886 { &hf_krb_ad_target_principal, {
2887 "Target Principal", "kerberos.ad_target_principal", FT_STRING, BASE_NONE,
2888 NULL, 0, NULL, HFILL }},
2890 #include "packet-kerberos-hfarr.c"
2893 /* List of subtrees */
2894 static gint *ett[] = {
2896 &ett_krb_recordmark,
2899 &ett_krb_pac_midl_blob,
2900 &ett_krb_pac_logon_info,
2901 &ett_krb_pac_credential_info,
2902 &ett_krb_pac_s4u_delegation_info,
2903 &ett_krb_pac_upn_dns_info,
2904 &ett_krb_pac_server_checksum,
2905 &ett_krb_pac_privsvr_checksum,
2906 &ett_krb_pac_client_info_type,
2907 &ett_krb_pa_supported_enctypes,
2908 &ett_krb_ad_ap_options,
2909 #include "packet-kerberos-ettarr.c"
2912 static ei_register_info ei[] = {
2913 { &ei_kerberos_decrypted_keytype, { "kerberos.decrypted_keytype", PI_SECURITY, PI_CHAT, "Decryted keytype", EXPFILL }},
2914 { &ei_kerberos_address, { "kerberos.address.unknown", PI_UNDECODED, PI_WARN, "KRB Address: I don't know how to parse this type of address yet", EXPFILL }},
2915 { &ei_krb_gssapi_dlglen, { "kerberos.gssapi.dlglen.error", PI_MALFORMED, PI_ERROR, "DlgLen is not the same as number of bytes remaining", EXPFILL }},
2918 expert_module_t* expert_krb;
2919 module_t *krb_module;
2921 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
2922 proto_register_field_array(proto_kerberos, hf, array_length(hf));
2923 proto_register_subtree_array(ett, array_length(ett));
2924 expert_krb = expert_register_protocol(proto_kerberos);
2925 expert_register_field_array(expert_krb, ei, array_length(ei));
2927 /* Register preferences */
2928 krb_module = prefs_register_protocol(proto_kerberos, kerberos_prefs_apply_cb);
2929 prefs_register_bool_preference(krb_module, "desegment",
2930 "Reassemble Kerberos over TCP messages spanning multiple TCP segments",
2931 "Whether the Kerberos dissector should reassemble messages spanning multiple TCP segments."
2932 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2934 #ifdef HAVE_KERBEROS
2935 prefs_register_bool_preference(krb_module, "decrypt",
2936 "Try to decrypt Kerberos blobs",
2937 "Whether the dissector should try to decrypt "
2938 "encrypted Kerberos blobs. This requires that the proper "
2939 "keytab file is installed as well.", &krb_decrypt);
2941 prefs_register_filename_preference(krb_module, "file",
2942 "Kerberos keytab file",
2943 "The keytab file containing all the secrets",
2944 &keytab_filename, FALSE);
2948 static int wrap_dissect_gss_kerb(tvbuff_t *tvb, int offset, packet_info *pinfo,
2949 proto_tree *tree, dcerpc_info *di _U_,guint8 *drep _U_)
2953 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2955 dissect_kerberos_main(auth_tvb, pinfo, tree, FALSE, NULL);
2957 return tvb_captured_length_remaining(tvb, offset);
2961 static dcerpc_auth_subdissector_fns gss_kerb_auth_connect_fns = {
2962 wrap_dissect_gss_kerb, /* Bind */
2963 wrap_dissect_gss_kerb, /* Bind ACK */
2964 wrap_dissect_gss_kerb, /* AUTH3 */
2965 NULL, /* Request verifier */
2966 NULL, /* Response verifier */
2967 NULL, /* Request data */
2968 NULL /* Response data */
2971 static dcerpc_auth_subdissector_fns gss_kerb_auth_sign_fns = {
2972 wrap_dissect_gss_kerb, /* Bind */
2973 wrap_dissect_gss_kerb, /* Bind ACK */
2974 wrap_dissect_gss_kerb, /* AUTH3 */
2975 wrap_dissect_gssapi_verf, /* Request verifier */
2976 wrap_dissect_gssapi_verf, /* Response verifier */
2977 NULL, /* Request data */
2978 NULL /* Response data */
2981 static dcerpc_auth_subdissector_fns gss_kerb_auth_seal_fns = {
2982 wrap_dissect_gss_kerb, /* Bind */
2983 wrap_dissect_gss_kerb, /* Bind ACK */
2984 wrap_dissect_gss_kerb, /* AUTH3 */
2985 wrap_dissect_gssapi_verf, /* Request verifier */
2986 wrap_dissect_gssapi_verf, /* Response verifier */
2987 wrap_dissect_gssapi_payload, /* Request data */
2988 wrap_dissect_gssapi_payload /* Response data */
2994 proto_reg_handoff_kerberos(void)
2996 dissector_handle_t kerberos_handle_tcp;
2998 krb4_handle = find_dissector_add_dependency("krb4", proto_kerberos);
3000 kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
3003 kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
3006 dissector_add_uint_with_preference("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
3007 dissector_add_uint_with_preference("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
3009 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
3010 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3011 &gss_kerb_auth_connect_fns);
3013 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
3014 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3015 &gss_kerb_auth_sign_fns);
3017 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
3018 DCE_C_RPC_AUTHN_PROTOCOL_GSS_KERBEROS,
3019 &gss_kerb_auth_seal_fns);
3023 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3028 * indent-tabs-mode: t
3031 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3032 * :indentSize=8:tabSize=8:noTabs=false: