STEP01x ? OK RFC6113.asn ....
[metze/wireshark/wip.git] / epan / dissectors / asn1 / kerberos / packet-kerberos-template.c
index 6ce598896f1d9fe627da75af9a3fda9f36476182..bf4b7eec77698ab15babf78e5cb8773ae8dd6e47 100644 (file)
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
 
 #include "packet-gssapi.h"
 #include "packet-smb-common.h"
+#include "packet-x509af.h"
 
+#define KEY_USAGE_FAST_REQ_CHKSUM       50
+#define KEY_USAGE_FAST_ENC              51
+#define KEY_USAGE_FAST_REP              52
+#define KEY_USAGE_FAST_FINISHED         53
+#define KEY_USAGE_ENC_CHALLENGE_CLIENT  54
+#define KEY_USAGE_ENC_CHALLENGE_KDC     55
 
 void proto_register_kerberos(void);
 void proto_reg_handoff_kerberos(void);
@@ -98,8 +93,12 @@ typedef struct kerberos_key {
 } kerberos_key_t;
 
 typedef struct {
+       guint32 msg_type;
+       gboolean kdc_response_initialized;
+       gboolean kdc_response;
        guint32 etype;
        guint32 padata_type;
+       guint32 is_enc_padata;
        guint32 enctype;
        kerberos_key_t key;
        guint32 ad_type;
@@ -112,12 +111,19 @@ static dissector_handle_t kerberos_handle_udp;
 /* Forward declarations */
 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_);
 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_);
+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_);
 static int dissect_kerberos_KERB_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_);
 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_);
+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_);
 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_);
 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_);
 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_);
-
+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_);
+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_);
+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_);
+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_);
+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_);
+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_);
 
 /* Desegment Kerberos over TCP messages */
 static gboolean krb_desegment = TRUE;
@@ -251,10 +257,7 @@ read_keytab_file_from_preferences(void)
                return;
        }
 
-       if (last_keytab != NULL) {
-               g_free(last_keytab);
-               last_keytab = NULL;
-       }
+       g_free(last_keytab);
        last_keytab = g_strdup(keytab_filename);
 
        read_keytab_file(last_keytab);
@@ -275,7 +278,7 @@ add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *k
 {
        enc_key_t *new_key;
 
-       if(pinfo->fd->flags.visited){
+       if(pinfo->fd->visited){
                return;
        }
 
@@ -303,7 +306,6 @@ read_keytab_file(const char *filename)
        krb5_error_code ret;
        krb5_keytab_entry key;
        krb5_kt_cursor cursor;
-       enc_key_t *new_key;
        static gboolean first_time=TRUE;
 
        if (filename == NULL || filename[0] == 0) {
@@ -333,14 +335,16 @@ read_keytab_file(const char *filename)
        }
 
        do{
-               new_key=(enc_key_t *)g_malloc(sizeof(enc_key_t));
-               new_key->fd_num = -1;
-               new_key->next=enc_key_list;
                ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
                if(ret==0){
+                       enc_key_t *new_key;
                        int i;
                        char *pos;
 
+                       new_key = g_new(enc_key_t, 1);
+                       new_key->fd_num = -1;
+                       new_key->next = enc_key_list;
+
                        /* generate origin string, describing where this key came from */
                        pos=new_key->key_origin;
                        pos+=MIN(KRB_MAX_ORIG_LEN,
@@ -356,12 +360,21 @@ read_keytab_file(const char *filename)
                        new_key->keylength=key.key.length;
                        new_key->keyvalue=(char *)g_memdup(key.key.contents, key.key.length);
                        enc_key_list=new_key;
+                       ret = krb5_free_keytab_entry_contents(krb5_ctx, &key);
+                       if (ret) {
+                               fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
+                               ret = 0; /* try to continue with the next entry */
+                       }
                }
        }while(ret==0);
 
        ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
        if(ret){
-               krb5_kt_close(krb5_ctx, keytab);
+               fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
+       }
+       ret = krb5_kt_close(krb5_ctx, keytab);
+       if(ret){
+               fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
        }
 }
 
@@ -417,6 +430,8 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
                                                                   "Decrypted keytype %d in frame %u using %s",
                                                                   ek->keytype, pinfo->num, ek->key_origin);
 
+                       proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
+
                        user_data=data.data;
                        if (datalen) {
                                *datalen = data.length;
@@ -470,14 +485,15 @@ read_keytab_file(const char *filename)
        }
 
        do{
-               new_key = (enc_key_t *)g_malloc(sizeof(enc_key_t));
-               new_key->fd_num = -1;
-               new_key->next=enc_key_list;
                ret = krb5_kt_next_entry(krb5_ctx, keytab, &key, &cursor);
                if(ret==0){
                        unsigned int i;
                        char *pos;
 
+                       new_key = g_new0(enc_key_t, 1);
+                       new_key->fd_num = -1;
+                       new_key->next = enc_key_list;
+
                        /* generate origin string, describing where this key came from */
                        pos=new_key->key_origin;
                        pos+=MIN(KRB_MAX_ORIG_LEN,
@@ -493,12 +509,21 @@ read_keytab_file(const char *filename)
                        new_key->keylength=(int)key.keyblock.keyvalue.length;
                        new_key->keyvalue = (guint8 *)g_memdup(key.keyblock.keyvalue.data, (guint)key.keyblock.keyvalue.length);
                        enc_key_list=new_key;
+                       ret = krb5_kt_free_entry(krb5_ctx, &key);
+                       if (ret) {
+                               fprintf(stderr, "KERBEROS ERROR: Could not release the entry: %d", ret);
+                               ret = 0; /* try to continue with the next entry */
+                       }
                }
        }while(ret==0);
 
        ret = krb5_kt_end_seq_get(krb5_ctx, keytab, &cursor);
        if(ret){
-               krb5_kt_close(krb5_ctx, keytab);
+               fprintf(stderr, "KERBEROS ERROR: Could not release the keytab cursor: %d", ret);
+       }
+       ret = krb5_kt_close(krb5_ctx, keytab);
+       if(ret){
+               fprintf(stderr, "KERBEROS ERROR: Could not close the key table handle: %d", ret);
        }
 
 }
@@ -566,6 +591,8 @@ decrypt_krb5_data(proto_tree *tree _U_, packet_info *pinfo,
                                                                   "Decrypted keytype %d in frame %u using %s",
                                                                   ek->keytype, pinfo->num, ek->key_origin);
 
+                       proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
+
                        krb5_crypto_destroy(krb5_ctx, crypto);
                        /* return a private wmem_alloced blob to the caller */
                        user_data = (char *)wmem_memdup(pinfo->pool, data.data, (guint)data.length);
@@ -599,7 +626,7 @@ add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *k
 {
        service_key_t *new_key;
 
-       if(pinfo->fd->flags.visited){
+       if(pinfo->fd->visited){
                return;
        }
 
@@ -620,9 +647,9 @@ clear_keytab(void) {
        for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
                sk = (service_key_t *) ske->data;
                if (sk) {
-                                       g_free(sk->contents);
-                                       g_free(sk);
-                               }
+                       g_free(sk->contents);
+                       g_free(sk);
+               }
        }
        g_slist_free(service_key_list);
        service_key_list = NULL;
@@ -820,48 +847,6 @@ decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
  * unless it's expired.
  */
 
-/* pre-authentication type constants */
-#define KRB5_PA_TGS_REQ                        1
-#define KRB5_PA_ENC_TIMESTAMP          2
-#define KRB5_PA_PW_SALT                        3
-#define KRB5_PA_ENC_ENCKEY             4
-#define KRB5_PA_ENC_UNIX_TIME          5
-#define KRB5_PA_ENC_SANDIA_SECURID     6
-#define KRB5_PA_SESAME                 7
-#define KRB5_PA_OSF_DCE                        8
-#define KRB5_PA_CYBERSAFE_SECUREID     9
-#define KRB5_PA_AFS3_SALT              10
-#define KRB5_PA_ENCTYPE_INFO           11
-#define KRB5_PA_SAM_CHALLENGE          12
-#define KRB5_PA_SAM_RESPONSE           13
-#define KRB5_PA_PK_AS_REQ              14
-#define KRB5_PA_PK_AS_REP              15
-#define KRB5_PA_DASS                   16
-#define KRB5_PA_ENCTYPE_INFO2          19
-#define KRB5_PA_USE_SPECIFIED_KVNO     20
-#define KRB5_PA_SAM_REDIRECT           21
-#define KRB5_PA_GET_FROM_TYPED_DATA    22
-#define KRB5_PA_SAM_ETYPE_INFO         23
-#define KRB5_PA_ALT_PRINC              24
-#define KRB5_PA_SAM_CHALLENGE2         30
-#define KRB5_PA_SAM_RESPONSE2          31
-#define KRB5_TD_PKINIT_CMS_CERTIFICATES        101
-#define KRB5_TD_KRB_PRINCIPAL          102
-#define KRB5_TD_KRB_REALM              103
-#define KRB5_TD_TRUSTED_CERTIFIERS     104
-#define KRB5_TD_CERTIFICATE_INDEX      105
-#define KRB5_TD_APP_DEFINED_ERROR      106
-#define KRB5_TD_REQ_NONCE              107
-#define KRB5_TD_REQ_SEQ                        108
-/* preauthentication types >127 (i.e. negative ones) are app specific.
-   however since Microsoft is the dominant(only?) user of types in this range
-   we also treat the type as unsigned.
-*/
-#define KRB5_PA_PAC_REQUEST            128    /* (Microsoft extension) */
-#define KRB5_PA_FOR_USER               129    /* Impersonation (Microsoft extension) See [MS-SFU]. XXX - replaced by KRB5_PA_S4U2SELF */
-#define KRB5_PA_S4U2SELF               129
-
-#define KRB5_PA_PROV_SRV_LOCATION 0xffffffff    /* (gint32)0xFF) packetcable stuff */
 /* Principal name-type */
 #define KRB5_NT_UNKNOWN                0
 #define KRB5_NT_PRINCIPAL      1
@@ -1048,102 +1033,6 @@ static const value_string w2k_pac_types[] = {
        { 0, NULL },
 };
 
-#if 0
-static const value_string krb5_princ_types[] = {
-       { KRB5_NT_UNKNOWN              , "Unknown" },
-       { KRB5_NT_PRINCIPAL            , "Principal" },
-       { KRB5_NT_SRV_INST             , "Service and Instance" },
-       { KRB5_NT_SRV_HST              , "Service and Host" },
-       { KRB5_NT_SRV_XHST             , "Service and Host Components" },
-       { KRB5_NT_UID                  , "Unique ID" },
-       { KRB5_NT_X500_PRINCIPAL       , "Encoded X.509 Distinguished Name" },
-       { KRB5_NT_SMTP_NAME            , "SMTP Name" },
-       { KRB5_NT_ENTERPRISE           , "Enterprise Name" },
-       { KRB5_NT_MS_PRINCIPAL         , "NT 4.0 style name (MS specific)" },
-       { KRB5_NT_MS_PRINCIPAL_AND_SID , "NT 4.0 style name with SID (MS specific)"},
-       { KRB5_NT_ENT_PRINCIPAL_AND_SID, "UPN and SID (MS specific)"},
-       { KRB5_NT_PRINCIPAL_AND_SID    , "Principal name and SID (MS specific)"},
-       { KRB5_NT_SRV_INST_AND_SID     , "SPN and SID (MS specific)"},
-       { 0                            , NULL },
-};
-#endif
-
-static const value_string krb5_preauthentication_types[] = {
-       { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
-       { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
-       { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
-       { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
-       { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
-       { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
-       { KRB5_PA_SESAME               , "PA-SESAME" },
-       { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
-       { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
-       { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
-       { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
-       { KRB5_PA_ENCTYPE_INFO2         , "PA-ENCTYPE-INFO2" },
-       { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
-       { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
-       { KRB5_PA_PK_AS_REQ            , "PA-PK-AS-REQ" },
-       { KRB5_PA_PK_AS_REP            , "PA-PK-AS-REP" },
-       { KRB5_PA_DASS                 , "PA-DASS" },
-       { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
-       { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
-       { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
-       { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
-       { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
-       { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
-       { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
-       { KRB5_TD_PKINIT_CMS_CERTIFICATES, "TD-PKINIT-CMS-CERTIFICATES" },
-       { KRB5_TD_KRB_PRINCIPAL        , "TD-KRB-PRINCIPAL" },
-       { KRB5_TD_KRB_REALM , "TD-KRB-REALM" },
-       { KRB5_TD_TRUSTED_CERTIFIERS   , "TD-TRUSTED-CERTIFIERS" },
-       { KRB5_TD_CERTIFICATE_INDEX    , "TD-CERTIFICATE-INDEX" },
-       { KRB5_TD_APP_DEFINED_ERROR    , "TD-APP-DEFINED-ERROR" },
-       { KRB5_TD_REQ_NONCE            , "TD-REQ-NONCE" },
-       { KRB5_TD_REQ_SEQ              , "TD-REQ-SEQ" },
-       { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
-       { KRB5_PA_FOR_USER             , "PA-FOR-USER" },
-       { KRB5_PA_PROV_SRV_LOCATION    , "PA-PROV-SRV-LOCATION" },
-       { 0                            , NULL },
-};
-
-#define KRB5_AD_IF_RELEVANT                    1
-#define KRB5_AD_INTENDED_FOR_SERVER            2
-#define KRB5_AD_INTENDED_FOR_APPLICATION_CLASS 3
-#define KRB5_AD_KDC_ISSUED                     4
-#define KRB5_AD_OR                             5
-#define KRB5_AD_MANDATORY_TICKET_EXTENSIONS    6
-#define KRB5_AD_IN_TICKET_EXTENSIONS           7
-#define KRB5_AD_MANDATORY_FOR_KDC              8
-#define KRB5_AD_OSF_DCE                                64
-#define KRB5_AD_SESAME                         65
-#define KRB5_AD_OSF_DCE_PKI_CERTID             66
-#define KRB5_AD_WIN2K_PAC                              128
-#define KRB5_AD_SIGNTICKET                     0xffffffef
-
-static const value_string krb5_ad_types[] = {
-       { KRB5_AD_IF_RELEVANT                   , "AD-IF-RELEVANT" },
-       { KRB5_AD_INTENDED_FOR_SERVER           , "AD-Intended-For-Server" },
-       { KRB5_AD_INTENDED_FOR_APPLICATION_CLASS        , "AD-Intended-For-Application-Class" },
-       { KRB5_AD_KDC_ISSUED                    , "AD-KDCIssued" },
-       { KRB5_AD_OR                            , "AD-AND-OR" },
-       { KRB5_AD_MANDATORY_TICKET_EXTENSIONS   , "AD-Mandatory-Ticket-Extensions" },
-       { KRB5_AD_IN_TICKET_EXTENSIONS          , "AD-IN-Ticket-Extensions" },
-       { KRB5_AD_MANDATORY_FOR_KDC                     , "AD-MANDATORY-FOR-KDC" },
-       { KRB5_AD_OSF_DCE                               , "AD-OSF-DCE" },
-       { KRB5_AD_SESAME                                , "AD-SESAME" },
-       { KRB5_AD_OSF_DCE_PKI_CERTID            , "AD-OSF-DCE-PKI-CertID" },
-       { KRB5_AD_WIN2K_PAC                             , "AD-Win2k-PAC" },
-       { KRB5_AD_SIGNTICKET                    , "AD-SignTicket" },
-       { 0     , NULL },
-};
-#if 0
-static const value_string krb5_transited_types[] = {
-       { 1                           , "DOMAIN-X500-COMPRESS" },
-       { 0                           , NULL }
-};
-#endif
-
 static const value_string krb5_msg_types[] = {
        { KRB5_MSG_TICKET,              "Ticket" },
        { KRB5_MSG_AUTHENTICATOR,       "Authenticator" },
@@ -1338,7 +1227,7 @@ dissect_krb5_decrypt_PA_ENC_TIMESTAMP (gboolean imp_tag _U_, tvbuff_t *tvb, int
                /* Add the decrypted data to the data source list. */
                add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
 
-               offset=dissect_kerberos_Applications(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+               offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
        }
        return offset;
 }
@@ -1432,6 +1321,108 @@ dissect_krb5_decrypt_CRED_data (gboolean imp_tag _U_, tvbuff_t *tvb, int offset,
        }
        return offset;
 }
+
+static int
+dissect_krb5_decrypt_KrbFastReq(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
+                               proto_tree *tree, int hf_index _U_)
+{
+       guint8 *plaintext;
+       int length;
+       kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+       tvbuff_t *next_tvb;
+
+       next_tvb=tvb_new_subset_remaining(tvb, offset);
+       length=tvb_captured_length_remaining(tvb, offset);
+
+       /* RFC6113 :
+        * KrbFastResponse encrypted with usage
+        * KEY_USAGE_FAST_ENC 51
+        */
+       plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_ENC,
+                                   next_tvb, private_data->etype, NULL);
+
+       if(plaintext){
+               tvbuff_t *child_tvb;
+               child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
+               tvb_set_free_cb(child_tvb, g_free);
+
+               /* Add the decrypted data to the data source list. */
+               add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
+
+               offset=dissect_kerberos_KrbFastReq(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+       }
+       return offset;
+}
+
+static int
+dissect_krb5_decrypt_KrbFastResponse(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
+                                    proto_tree *tree, int hf_index _U_)
+{
+       guint8 *plaintext;
+       int length;
+       kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+       tvbuff_t *next_tvb;
+
+       next_tvb=tvb_new_subset_remaining(tvb, offset);
+       length=tvb_captured_length_remaining(tvb, offset);
+
+       /*
+        * RFC6113 :
+        * KrbFastResponse encrypted with usage
+        * KEY_USAGE_FAST_REP 52
+        */
+       plaintext=decrypt_krb5_data(tree, actx->pinfo, KEY_USAGE_FAST_REP,
+                                   next_tvb, private_data->etype, NULL);
+
+       if(plaintext){
+               tvbuff_t *child_tvb;
+               child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
+               tvb_set_free_cb(child_tvb, g_free);
+
+               /* Add the decrypted data to the data source list. */
+               add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
+
+               offset=dissect_kerberos_KrbFastResponse(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+       }
+       return offset;
+}
+
+static int
+dissect_krb5_decrypt_EncryptedChallenge(gboolean imp_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx,
+                                       proto_tree *tree, int hf_index _U_)
+{
+       guint8 *plaintext;
+       int length;
+       kerberos_private_data_t *private_data = kerberos_get_private_data(actx);
+       tvbuff_t *next_tvb;
+       int usage = 0;
+
+       next_tvb=tvb_new_subset_remaining(tvb, offset);
+       length=tvb_captured_length_remaining(tvb, offset);
+
+       /* RFC6113 :
+        * KEY_USAGE_ENC_CHALLENGE_CLIENT  54
+        * KEY_USAGE_ENC_CHALLENGE_KDC     55
+        */
+       if (private_data->kdc_response) {
+               usage = KEY_USAGE_ENC_CHALLENGE_KDC;
+       } else {
+               usage = KEY_USAGE_ENC_CHALLENGE_CLIENT;
+       }
+       plaintext=decrypt_krb5_data(tree, actx->pinfo, usage, next_tvb, private_data->etype, NULL);
+
+       if(plaintext){
+               tvbuff_t *child_tvb;
+               child_tvb = tvb_new_child_real_data(tvb, plaintext, length, length);
+               tvb_set_free_cb(child_tvb, g_free);
+
+               /* Add the decrypted data to the data source list. */
+               add_new_data_source(actx->pinfo, child_tvb, "Decrypted Krb5");
+
+               offset=dissect_kerberos_PA_ENC_TS_ENC(FALSE, child_tvb, 0, actx , tree, /* hf_index*/ -1);
+       }
+       return offset;
+}
 #endif
 
 /* Dissect a GSSAPI checksum as per RFC1964. This is NOT ASN.1 encoded.
@@ -1955,10 +1946,10 @@ dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                        default:
                                return 0;
                }
-       if (do_col_protocol) {
+               if (do_col_protocol) {
                        col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
-       }
-       if (gbl_do_col_info) {
+               }
+               if (gbl_do_col_info) {
                        col_clear(pinfo->cinfo, COL_INFO);
                }
                if (tree) {