packet-kerberos: implement PAC Ticket checksum verification

We use some private functions from MIT kerberos:
- krb5_free_enc_tkt_part()
- decode_krb5_enc_tkt_part()
- encode_krb5_enc_tkt_part()
but we already do that for krb5int_c_mandatory_cksumtype(),
which is newer than the above functions.

We use all of them only under HAVE_KRB5_PAC_VERIFY,
so we don't seem to need additional configure tests.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Stefan Metzmacher 2021-07-05 10:57:12 +02:00 committed by Wireshark GitLab Utility
parent 8cd877fc4d
commit 94ac641efa
4 changed files with 518 additions and 6 deletions

View File

@ -92,6 +92,8 @@ if(KERBEROS_FOUND)
check_symbol_exists("krb5_pac_verify" "krb5.h" HAVE_KRB5_PAC_VERIFY)
# see also HAVE_KRB5_C_FX_CF2_SIMPLE in cmakeconfig.h.in
check_symbol_exists("krb5_c_fx_cf2_simple" "krb5.h" HAVE_KRB5_C_FX_CF2_SIMPLE)
check_function_exists(decode_krb5_enc_tkt_part HAVE_DECODE_KRB5_ENC_TKT_PART)
check_function_exists(encode_krb5_enc_tkt_part HAVE_ENCODE_KRB5_ENC_TKT_PART)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
if(NOT HAVE_HEIMDAL_KERBEROS)

View File

@ -91,6 +91,12 @@
/* Define to 1 if you have the `krb5_c_fx_cf2_simple' function. */
#cmakedefine HAVE_KRB5_C_FX_CF2_SIMPLE 1
/* Define to 1 if you have the `decode_krb5_enc_tkt_part' function. */
#cmakedefine HAVE_DECODE_KRB5_ENC_TKT_PART 1
/* Define to 1 if you have the `encode_krb5_enc_tkt_part' function. */
#cmakedefine HAVE_ENCODE_KRB5_ENC_TKT_PART 1
/* Define to 1 if you have the `inflatePrime' function. */
#cmakedefine HAVE_INFLATEPRIME 1

View File

@ -126,6 +126,7 @@ typedef struct {
#ifdef HAVE_KERBEROS
enc_key_t *last_decryption_key;
enc_key_t *last_added_key;
tvbuff_t *last_ticket_enc_part_tvb;
#endif
gint save_encryption_key_parent_hf_index;
kerberos_key_save_fn save_encryption_key_fn;
@ -1792,6 +1793,12 @@ decrypt_krb5_krb_cfx_dce(proto_tree *tree,
extern krb5_error_code
krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
extern void krb5_free_enc_tkt_part(krb5_context, krb5_enc_tkt_part *);
extern krb5_error_code
decode_krb5_enc_tkt_part(const krb5_data *output, krb5_enc_tkt_part **rep);
extern krb5_error_code
encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code);
static int
keytype_for_cksumtype(krb5_cksumtype checksum)
{
@ -1829,6 +1836,8 @@ struct verify_krb5_pac_state {
krb5_cksumtype kdc_checksum;
guint kdc_count;
enc_key_t *kdc_ek;
krb5_cksumtype ticket_checksum_type;
const krb5_data *ticket_checksum_data;
};
static void
@ -1929,12 +1938,236 @@ verify_krb5_pac_try_kdc_key(gpointer __key _U_, gpointer value, gpointer userdat
}
}
#define __KRB5_PAC_TICKET_CHECKSUM 16
static void
verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
asn1_ctx_t *actx _U_,
tvbuff_t *pactvb _U_,
struct verify_krb5_pac_state *state _U_)
{
#ifdef HAVE_DECODE_KRB5_ENC_TKT_PART
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *teptvb = private_data->last_ticket_enc_part_tvb;
guint teplength = 0;
const guint8 *tepbuffer = NULL;
krb5_data tepdata = { .length = 0, };
krb5_enc_tkt_part *tep = NULL;
krb5_data *tmpdata = NULL;
krb5_error_code ret;
krb5_authdata **recoded_container = NULL;
gint ad_orig_idx = -1;
krb5_authdata *ad_orig_ptr = NULL;
gint l0idx = 0;
krb5_keyblock kdc_key = { .magic = KV5M_KEYBLOCK, };
size_t checksum_length = 0;
krb5_checksum checksum = { .checksum_type = 0, };
krb5_boolean valid = FALSE;
if (state->kdc_ek == NULL) {
int keytype = keytype_for_cksumtype(state->ticket_checksum_type);
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
keytype,
"Missing KDC (for ticket)",
"kdc_checksum_key",
0,
0);
return;
}
if (teptvb == NULL) {
return;
}
teplength = tvb_captured_length(teptvb);
/* make sure we have all the data we need */
if (teplength < tvb_reported_length(teptvb)) {
return;
}
tepbuffer = tvb_get_ptr(teptvb, 0, teplength);
if (tepbuffer == NULL) {
return;
}
kdc_key.magic = KV5M_KEYBLOCK;
kdc_key.enctype = state->kdc_ek->keytype;
kdc_key.length = state->kdc_ek->keylength;
kdc_key.contents = (guint8 *)state->kdc_ek->keyvalue;
checksum.checksum_type = state->ticket_checksum_type;
checksum.length = state->ticket_checksum_data->length;
checksum.contents = (guint8 *)state->ticket_checksum_data->data;
if (checksum.length >= 4) {
checksum.length -= 4;
checksum.contents += 4;
}
ret = krb5_c_checksum_length(krb5_ctx,
checksum.checksum_type,
&checksum_length);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_c_checksum_length failed for Ticket Signature",
"kdc_checksum_key",
1,
0);
return;
}
checksum.length = MIN(checksum.length, (unsigned int)checksum_length);
tepdata.data = (void *)(uintptr_t)tepbuffer;
tepdata.length = teplength;
ret = decode_krb5_enc_tkt_part(&tepdata, &tep);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"decode_krb5_enc_tkt_part failed",
"kdc_checksum_key",
1,
0);
return;
}
for (l0idx = 0; tep->authorization_data[l0idx]; l0idx++) {
krb5_authdata *adl0 = tep->authorization_data[l0idx];
krb5_authdata **decoded_container = NULL;
krb5_authdata *ad_pac = NULL;
gint l1idx = 0;
if (adl0->ad_type != KRB5_AUTHDATA_IF_RELEVANT) {
continue;
}
ret = krb5_decode_authdata_container(krb5_ctx,
KRB5_AUTHDATA_IF_RELEVANT,
adl0,
&decoded_container);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_decode_authdata_container failed",
"kdc_checksum_key",
1,
0);
krb5_free_enc_tkt_part(krb5_ctx, tep);
return;
}
for (l1idx = 0; decoded_container[l1idx]; l1idx++) {
krb5_authdata *adl1 = decoded_container[l1idx];
if (adl1->ad_type != KRB5_AUTHDATA_WIN2K_PAC) {
continue;
}
ad_pac = adl1;
break;
}
if (ad_pac == NULL) {
krb5_free_authdata(krb5_ctx, decoded_container);
continue;
}
ad_pac->length = 1;
ad_pac->contents[0] = '\0';
ret = krb5_encode_authdata_container(krb5_ctx,
KRB5_AUTHDATA_IF_RELEVANT,
decoded_container,
&recoded_container);
krb5_free_authdata(krb5_ctx, decoded_container);
decoded_container = NULL;
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_encode_authdata_container failed",
"kdc_checksum_key",
1,
0);
krb5_free_enc_tkt_part(krb5_ctx, tep);
return;
}
ad_orig_idx = l0idx;
ad_orig_ptr = adl0;
tep->authorization_data[l0idx] = recoded_container[0];
break;
}
ret = encode_krb5_enc_tkt_part(tep, &tmpdata);
if (ad_orig_ptr != NULL) {
tep->authorization_data[ad_orig_idx] = ad_orig_ptr;
}
krb5_free_enc_tkt_part(krb5_ctx, tep);
tep = NULL;
if (recoded_container != NULL) {
krb5_free_authdata(krb5_ctx, recoded_container);
recoded_container = NULL;
}
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"encode_krb5_enc_tkt_part failed",
"kdc_checksum_key",
1,
0);
return;
}
ret = krb5_c_verify_checksum(krb5_ctx, &kdc_key,
KRB5_KEYUSAGE_APP_DATA_CKSUM,
tmpdata, &checksum, &valid);
krb5_free_data(krb5_ctx, tmpdata);
tmpdata = NULL;
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_c_verify_checksum failed for Ticket Signature",
"kdc_checksum_key",
1,
1);
return;
}
if (valid == FALSE) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"Invalid Ticket",
"kdc_checksum_key",
1,
1);
return;
}
used_signing_key(tree, actx->pinfo, private_data,
state->kdc_ek, pactvb,
state->ticket_checksum_type,
"Verified Ticket",
"kdc_checksum_key",
1,
1);
#endif /* HAVE_DECODE_KRB5_ENC_TKT_PART */
}
static void
verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
krb5_error_code ret;
krb5_data checksum_data = {0,0,NULL};
krb5_data ticket_checksum_data = {0,0,NULL};
int length = tvb_captured_length(pactvb);
const guint8 *pacbuffer = NULL;
struct verify_krb5_pac_state state = {
@ -1974,6 +2207,13 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
state.kdc_checksum = pletoh32(checksum_data.data);
krb5_free_data_contents(krb5_ctx, &checksum_data);
};
ret = krb5_pac_get_buffer(krb5_ctx, state.pac,
__KRB5_PAC_TICKET_CHECKSUM,
&ticket_checksum_data);
if (ret == 0) {
state.ticket_checksum_data = &ticket_checksum_data;
state.ticket_checksum_type = pletoh32(ticket_checksum_data.data);
};
read_keytab_file_from_preferences();
@ -2016,6 +2256,14 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
state.kdc_count);
}
if (state.ticket_checksum_type != 0) {
verify_krb5_pac_ticket_checksum(tree, actx, pactvb, &state);
}
if (state.ticket_checksum_data != NULL) {
krb5_free_data_contents(krb5_ctx, &ticket_checksum_data);
}
krb5_pac_free(krb5_ctx, state.pac);
}
#endif /* HAVE_KRB5_PAC_VERIFY */
@ -2829,13 +3077,17 @@ dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offse
plaintext=decrypt_krb5_data_asn1(tree, actx, 2, next_tvb, &length);
if(plaintext){
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *last_ticket_enc_part_tvb = private_data->last_ticket_enc_part_tvb;
tvbuff_t *child_tvb;
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 Ticket");
private_data->last_ticket_enc_part_tvb = child_tvb;
offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
private_data->last_ticket_enc_part_tvb = last_ticket_enc_part_tvb;
}
return offset;
}

View File

@ -134,6 +134,7 @@ typedef struct {
#ifdef HAVE_KERBEROS
enc_key_t *last_decryption_key;
enc_key_t *last_added_key;
tvbuff_t *last_ticket_enc_part_tvb;
#endif
gint save_encryption_key_parent_hf_index;
kerberos_key_save_fn save_encryption_key_fn;
@ -533,7 +534,7 @@ static int hf_kerberos_PAC_OPTIONS_FLAGS_forward_to_full_dc = -1;
static int hf_kerberos_PAC_OPTIONS_FLAGS_resource_based_constrained_delegation = -1;
/*--- End of included file: packet-kerberos-hf.c ---*/
#line 295 "./asn1/kerberos/packet-kerberos-template.c"
#line 296 "./asn1/kerberos/packet-kerberos-template.c"
/* Initialize the subtree pointers */
static gint ett_kerberos = -1;
@ -650,7 +651,7 @@ static gint ett_kerberos_SPAKEResponse = -1;
static gint ett_kerberos_PA_SPAKE = -1;
/*--- End of included file: packet-kerberos-ett.c ---*/
#line 322 "./asn1/kerberos/packet-kerberos-template.c"
#line 323 "./asn1/kerberos/packet-kerberos-template.c"
static expert_field ei_kerberos_missing_keytype = EI_INIT;
static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
@ -781,7 +782,7 @@ typedef enum _KERBEROS_KRBFASTARMORTYPES_enum {
} KERBEROS_KRBFASTARMORTYPES_enum;
/*--- End of included file: packet-kerberos-val.h ---*/
#line 336 "./asn1/kerberos/packet-kerberos-template.c"
#line 337 "./asn1/kerberos/packet-kerberos-template.c"
static void
call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
@ -2241,6 +2242,12 @@ decrypt_krb5_krb_cfx_dce(proto_tree *tree,
extern krb5_error_code
krb5int_c_mandatory_cksumtype(krb5_context, krb5_enctype, krb5_cksumtype *);
extern void krb5_free_enc_tkt_part(krb5_context, krb5_enc_tkt_part *);
extern krb5_error_code
decode_krb5_enc_tkt_part(const krb5_data *output, krb5_enc_tkt_part **rep);
extern krb5_error_code
encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code);
static int
keytype_for_cksumtype(krb5_cksumtype checksum)
{
@ -2278,6 +2285,8 @@ struct verify_krb5_pac_state {
krb5_cksumtype kdc_checksum;
guint kdc_count;
enc_key_t *kdc_ek;
krb5_cksumtype ticket_checksum_type;
const krb5_data *ticket_checksum_data;
};
static void
@ -2378,12 +2387,236 @@ verify_krb5_pac_try_kdc_key(gpointer __key _U_, gpointer value, gpointer userdat
}
}
#define __KRB5_PAC_TICKET_CHECKSUM 16
static void
verify_krb5_pac_ticket_checksum(proto_tree *tree _U_,
asn1_ctx_t *actx _U_,
tvbuff_t *pactvb _U_,
struct verify_krb5_pac_state *state _U_)
{
#ifdef HAVE_DECODE_KRB5_ENC_TKT_PART
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *teptvb = private_data->last_ticket_enc_part_tvb;
guint teplength = 0;
const guint8 *tepbuffer = NULL;
krb5_data tepdata = { .length = 0, };
krb5_enc_tkt_part *tep = NULL;
krb5_data *tmpdata = NULL;
krb5_error_code ret;
krb5_authdata **recoded_container = NULL;
gint ad_orig_idx = -1;
krb5_authdata *ad_orig_ptr = NULL;
gint l0idx = 0;
krb5_keyblock kdc_key = { .magic = KV5M_KEYBLOCK, };
size_t checksum_length = 0;
krb5_checksum checksum = { .checksum_type = 0, };
krb5_boolean valid = FALSE;
if (state->kdc_ek == NULL) {
int keytype = keytype_for_cksumtype(state->ticket_checksum_type);
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
keytype,
"Missing KDC (for ticket)",
"kdc_checksum_key",
0,
0);
return;
}
if (teptvb == NULL) {
return;
}
teplength = tvb_captured_length(teptvb);
/* make sure we have all the data we need */
if (teplength < tvb_reported_length(teptvb)) {
return;
}
tepbuffer = tvb_get_ptr(teptvb, 0, teplength);
if (tepbuffer == NULL) {
return;
}
kdc_key.magic = KV5M_KEYBLOCK;
kdc_key.enctype = state->kdc_ek->keytype;
kdc_key.length = state->kdc_ek->keylength;
kdc_key.contents = (guint8 *)state->kdc_ek->keyvalue;
checksum.checksum_type = state->ticket_checksum_type;
checksum.length = state->ticket_checksum_data->length;
checksum.contents = (guint8 *)state->ticket_checksum_data->data;
if (checksum.length >= 4) {
checksum.length -= 4;
checksum.contents += 4;
}
ret = krb5_c_checksum_length(krb5_ctx,
checksum.checksum_type,
&checksum_length);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_c_checksum_length failed for Ticket Signature",
"kdc_checksum_key",
1,
0);
return;
}
checksum.length = MIN(checksum.length, (unsigned int)checksum_length);
tepdata.data = (void *)(uintptr_t)tepbuffer;
tepdata.length = teplength;
ret = decode_krb5_enc_tkt_part(&tepdata, &tep);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"decode_krb5_enc_tkt_part failed",
"kdc_checksum_key",
1,
0);
return;
}
for (l0idx = 0; tep->authorization_data[l0idx]; l0idx++) {
krb5_authdata *adl0 = tep->authorization_data[l0idx];
krb5_authdata **decoded_container = NULL;
krb5_authdata *ad_pac = NULL;
gint l1idx = 0;
if (adl0->ad_type != KRB5_AUTHDATA_IF_RELEVANT) {
continue;
}
ret = krb5_decode_authdata_container(krb5_ctx,
KRB5_AUTHDATA_IF_RELEVANT,
adl0,
&decoded_container);
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_decode_authdata_container failed",
"kdc_checksum_key",
1,
0);
krb5_free_enc_tkt_part(krb5_ctx, tep);
return;
}
for (l1idx = 0; decoded_container[l1idx]; l1idx++) {
krb5_authdata *adl1 = decoded_container[l1idx];
if (adl1->ad_type != KRB5_AUTHDATA_WIN2K_PAC) {
continue;
}
ad_pac = adl1;
break;
}
if (ad_pac == NULL) {
krb5_free_authdata(krb5_ctx, decoded_container);
continue;
}
ad_pac->length = 1;
ad_pac->contents[0] = '\0';
ret = krb5_encode_authdata_container(krb5_ctx,
KRB5_AUTHDATA_IF_RELEVANT,
decoded_container,
&recoded_container);
krb5_free_authdata(krb5_ctx, decoded_container);
decoded_container = NULL;
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_encode_authdata_container failed",
"kdc_checksum_key",
1,
0);
krb5_free_enc_tkt_part(krb5_ctx, tep);
return;
}
ad_orig_idx = l0idx;
ad_orig_ptr = adl0;
tep->authorization_data[l0idx] = recoded_container[0];
break;
}
ret = encode_krb5_enc_tkt_part(tep, &tmpdata);
if (ad_orig_ptr != NULL) {
tep->authorization_data[ad_orig_idx] = ad_orig_ptr;
}
krb5_free_enc_tkt_part(krb5_ctx, tep);
tep = NULL;
if (recoded_container != NULL) {
krb5_free_authdata(krb5_ctx, recoded_container);
recoded_container = NULL;
}
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"encode_krb5_enc_tkt_part failed",
"kdc_checksum_key",
1,
0);
return;
}
ret = krb5_c_verify_checksum(krb5_ctx, &kdc_key,
KRB5_KEYUSAGE_APP_DATA_CKSUM,
tmpdata, &checksum, &valid);
krb5_free_data(krb5_ctx, tmpdata);
tmpdata = NULL;
if (ret != 0) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"krb5_c_verify_checksum failed for Ticket Signature",
"kdc_checksum_key",
1,
1);
return;
}
if (valid == FALSE) {
missing_signing_key(tree, actx->pinfo, private_data,
pactvb, state->ticket_checksum_type,
state->kdc_ek->keytype,
"Invalid Ticket",
"kdc_checksum_key",
1,
1);
return;
}
used_signing_key(tree, actx->pinfo, private_data,
state->kdc_ek, pactvb,
state->ticket_checksum_type,
"Verified Ticket",
"kdc_checksum_key",
1,
1);
#endif /* HAVE_DECODE_KRB5_ENC_TKT_PART */
}
static void
verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
{
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
krb5_error_code ret;
krb5_data checksum_data = {0,0,NULL};
krb5_data ticket_checksum_data = {0,0,NULL};
int length = tvb_captured_length(pactvb);
const guint8 *pacbuffer = NULL;
struct verify_krb5_pac_state state = {
@ -2423,6 +2656,13 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
state.kdc_checksum = pletoh32(checksum_data.data);
krb5_free_data_contents(krb5_ctx, &checksum_data);
};
ret = krb5_pac_get_buffer(krb5_ctx, state.pac,
__KRB5_PAC_TICKET_CHECKSUM,
&ticket_checksum_data);
if (ret == 0) {
state.ticket_checksum_data = &ticket_checksum_data;
state.ticket_checksum_type = pletoh32(ticket_checksum_data.data);
};
read_keytab_file_from_preferences();
@ -2465,6 +2705,14 @@ verify_krb5_pac(proto_tree *tree _U_, asn1_ctx_t *actx, tvbuff_t *pactvb)
state.kdc_count);
}
if (state.ticket_checksum_type != 0) {
verify_krb5_pac_ticket_checksum(tree, actx, pactvb, &state);
}
if (state.ticket_checksum_data != NULL) {
krb5_free_data_contents(krb5_ctx, &ticket_checksum_data);
}
krb5_pac_free(krb5_ctx, state.pac);
}
#endif /* HAVE_KRB5_PAC_VERIFY */
@ -3278,13 +3526,17 @@ dissect_krb5_decrypt_ticket_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offse
plaintext=decrypt_krb5_data_asn1(tree, actx, 2, next_tvb, &length);
if(plaintext){
kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
tvbuff_t *last_ticket_enc_part_tvb = private_data->last_ticket_enc_part_tvb;
tvbuff_t *child_tvb;
child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
/* Add the decrypted data to the data source list. */
add_new_data_source(actx->pinfo, child_tvb, "Krb5 Ticket");
private_data->last_ticket_enc_part_tvb = child_tvb;
offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
private_data->last_ticket_enc_part_tvb = last_ticket_enc_part_tvb;
}
return offset;
}
@ -7429,7 +7681,7 @@ dissect_kerberos_PA_SPAKE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offs
/*--- End of included file: packet-kerberos-fn.c ---*/
#line 3902 "./asn1/kerberos/packet-kerberos-template.c"
#line 4154 "./asn1/kerberos/packet-kerberos-template.c"
#ifdef HAVE_KERBEROS
static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = {
@ -9239,7 +9491,7 @@ void proto_register_kerberos(void) {
NULL, HFILL }},
/*--- End of included file: packet-kerberos-hfarr.c ---*/
#line 4795 "./asn1/kerberos/packet-kerberos-template.c"
#line 5047 "./asn1/kerberos/packet-kerberos-template.c"
};
/* List of subtrees */
@ -9358,7 +9610,7 @@ void proto_register_kerberos(void) {
&ett_kerberos_PA_SPAKE,
/*--- End of included file: packet-kerberos-ettarr.c ---*/
#line 4824 "./asn1/kerberos/packet-kerberos-template.c"
#line 5076 "./asn1/kerberos/packet-kerberos-template.c"
};
static ei_register_info ei[] = {