This fix now allows SASL/GSS-API with integrity only to be properly dissected
[metze/wireshark/wip.git] / asn1 / spnego / packet-spnego-template.c
index c1a6120ce6e029bb87d6fc58623a3eb4ab1d17d5..801ba66de7191ae9dd5d8a0393627151da531ad0 100644 (file)
@@ -7,8 +7,6 @@
  * Copyright 2005, Ronnie Sahlberg (krb decryption)
  * Copyright 2005, Anders Broman (converted to asn2wrs generated dissector)
  *
- * $Id$
- *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /* The heimdal code for decryption of GSSAPI wrappers using heimdal comes from
    Heimdal 1.6 and has been modified for wireshark's requirements.
 */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <glib.h>
+
+#include <wsutil/rc4.h>
+
 #include <epan/packet.h>
 #include <epan/asn1.h>
 #include "packet-dcerpc.h"
 #include "packet-gssapi.h"
 #include "packet-kerberos.h"
-#include <epan/crypt/crypt-rc4.h>
 #include <epan/conversation.h>
-#include <epan/emem.h>
+#include <epan/wmem/wmem.h>
 #include <epan/asn1.h>
 
-#include <stdio.h>
 #include <string.h>
 
 #include "packet-ber.h"
@@ -56,6 +53,9 @@
 #define PSNAME "SPNEGO"
 #define PFNAME "spnego"
 
+void proto_register_spnego(void);
+void proto_reg_handoff_spnego(void);
+
 /* Initialize the protocol and registered fields */
 static int proto_spnego = -1;
 static int proto_spnego_krb5 = -1;
@@ -96,13 +96,16 @@ static gint ett_spnego_krb5_cfx_flags = -1;
 #include "packet-spnego-ett.c"
 
 /*
- * Unfortunately, we have to have a forward declaration of this,
+ * Unfortunately, we have to have forward declarations of thess,
  * as the code generated by asn2wrs includes a call before the
  * definition.
  */
-static int dissect_spnego_PrincipalSeq(gboolean implicit_tag, tvbuff_t *tvb,
+static int dissect_spnego_NegTokenInit(gboolean implicit_tag, tvbuff_t *tvb,
                                        int offset, asn1_ctx_t *actx _U_,
                                        proto_tree *tree, int hf_index);
+static int dissect_spnego_NegTokenInit2(gboolean implicit_tag, tvbuff_t *tvb,
+                                        int offset, asn1_ctx_t *actx _U_,
+                                        proto_tree *tree, int hf_index);
 
 #include "packet-spnego-fn.c"
 /*
@@ -180,9 +183,8 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        int offset = 0;
        guint16 token_id;
        const char *oid;
-       gssapi_oid_value *value;
        tvbuff_t *krb5_tvb;
-       gint8 class;
+       gint8 ber_class;
        gboolean pc, ind = 0;
        gint32 tag;
        guint32 len;
@@ -190,7 +192,7 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
 
        item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset,
-                                  -1, FALSE);
+                                  -1, ENC_NA);
 
        subtree = proto_item_add_subtree(item, ett_spnego_krb5);
 
@@ -224,12 +226,12 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /*
         * Get the first header ...
         */
-       get_ber_identifier(tvb, offset, &class, &pc, &tag);
-       if (class == BER_CLASS_APP && pc) {
+       get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
+       if (ber_class == BER_CLASS_APP && pc) {
            /*
             * [APPLICATION <tag>]
             */
-           offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &class, &pc, &tag);
+           offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &ber_class, &pc, &tag);
            offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind);
 
            switch (tag) {
@@ -242,8 +244,6 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                /* Next, the OID */
                offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid);
 
-               value = gssapi_lookup_oid_str(oid);
-
                token_id = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
                                    token_id);
@@ -258,13 +258,13 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 * No token ID - just dissect as a Kerberos message and
                 * return.
                 */
-               offset = dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL);
+               dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL);
                return;
 
            default:
                proto_tree_add_text(subtree, tvb, offset, 0,
                        "Unknown header (class=%d, pc=%d, tag=%d)",
-                       class, pc, tag);
+                       ber_class, pc, tag);
                goto done;
            }
        } else {
@@ -317,7 +317,7 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 }
 
 #ifdef HAVE_KERBEROS
-#include <epan/crypt/crypt-md5.h>
+#include <wsutil/md5.h>
 
 #ifndef KEYTYPE_ARCFOUR_56
 # define KEYTYPE_ARCFOUR_56 24
@@ -328,9 +328,9 @@ dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 #endif
 
 static int
-arcfour_mic_key(void *key_data, size_t key_size, int key_type,
-               void *cksum_data, size_t cksum_size,
-               void *key6_data)
+arcfour_mic_key(const guint8 *key_data, size_t key_size, int key_type,
+               const guint8 *cksum_data, size_t cksum_size,
+               guint8 *key6_data)
 {
     guint8 k5_data[16];
     guint8 T[4];
@@ -345,14 +345,14 @@ arcfour_mic_key(void *key_data, size_t key_size, int key_type,
                 L40, 14,
                 key_data,
                 key_size,
-               k5_data);
+               k5_data);
        memset(&k5_data[7], 0xAB, 9);
     } else {
        md5_hmac(
                 T, 4,
                 key_data,
                 key_size,
-               k5_data);
+               k5_data);
     }
 
     md5_hmac(
@@ -384,17 +384,17 @@ usage2arcfour(int usage)
 
 static int
 arcfour_mic_cksum(guint8 *key_data, int key_length,
-                 unsigned usage,
+                 unsigned int usage,
                  guint8 sgn_cksum[8],
-                 const void *v1, size_t l1,
-                 const void *v2, size_t l2,
-                 const void *v3, size_t l3)
+                 const guint8 *v1, size_t l1,
+                 const guint8 *v2, size_t l2,
+                 const guint8 *v3, size_t l3)
 {
-    const guint8 signature[] = "signaturekey";
+    static const guint8 signature[] = "signaturekey";
     guint8 ksign_c[16];
-    unsigned char t[4];
+    guint8 t[4];
     md5_state_t ms;
-    unsigned char digest[16];
+    guint8 digest[16];
     int rc4_usage;
     guint8 cksum[16];
 
@@ -423,12 +423,12 @@ arcfour_mic_cksum(guint8 *key_data, int key_length,
  * Verify padding of a gss wrapped message and return its length.
  */
 static int
-gssapi_verify_pad(unsigned char *wrapped_data, int wrapped_length,
-                  size_t datalen,
-                  size_t *padlen)
+gssapi_verify_pad(guint8 *wrapped_data, int wrapped_length,
+                  int datalen,
+                  int *padlen)
 {
-    unsigned char *pad;
-    size_t padlength;
+    guint8 *pad;
+    int padlength;
     int i;
 
     pad = wrapped_data + wrapped_length - 1;
@@ -455,15 +455,14 @@ decrypt_arcfour(packet_info *pinfo,
 {
     guint8 Klocaldata[16];
     int ret;
-    gint32 seq_number;
-    size_t datalen;
+    int datalen;
     guint8 k6_data[16];
     guint32 SND_SEQ[2];
     guint8 Confounder[8];
     guint8 cksum_data[8];
     int cmp;
     int conf_flag;
-    size_t padlen = 0;
+    int padlen = 0;
 
     datalen = tvb_length(pinfo->gssapi_encrypted_tvb);
 
@@ -480,7 +479,7 @@ decrypt_arcfour(packet_info *pinfo,
     }
 
     ret = arcfour_mic_key(key_value, key_size, key_type,
-                         (void *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
+                         tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
                          8, /* SGN_CKSUM */
                          k6_data);
     if (ret) {
@@ -491,13 +490,12 @@ decrypt_arcfour(packet_info *pinfo,
        rc4_state_struct rc4_state;
 
        crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
-       memcpy(SND_SEQ, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 8, 8), 8);
-       crypt_rc4(&rc4_state, (unsigned char *)SND_SEQ, 8);
+       tvb_memcpy(pinfo->gssapi_wrap_tvb, SND_SEQ, 8, 8);
+       crypt_rc4(&rc4_state, (guint8 *)SND_SEQ, 8);
 
        memset(k6_data, 0, sizeof(k6_data));
     }
 
-    seq_number=g_ntohl(SND_SEQ[0]);
 
     if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) {
        return -6;
@@ -510,7 +508,7 @@ decrypt_arcfour(packet_info *pinfo,
            Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0;
     }
     ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type,
-                         (unsigned char *)SND_SEQ, 4,
+                         (const guint8 *)SND_SEQ, 4,
                          k6_data);
     memset(Klocaldata, 0, sizeof(Klocaldata));
     if (ret) {
@@ -521,14 +519,12 @@ decrypt_arcfour(packet_info *pinfo,
        rc4_state_struct rc4_state;
 
        crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
-       memcpy(Confounder, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8), 8);
+       tvb_memcpy(pinfo->gssapi_wrap_tvb, Confounder, 24, 8);
        crypt_rc4(&rc4_state, Confounder, 8);
        memcpy(output_message_buffer, input_message_buffer, datalen);
        crypt_rc4(&rc4_state, output_message_buffer, datalen);
     } else {
-       memcpy(Confounder,
-               tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8),
-               8); /* Confounder */
+       tvb_memcpy(pinfo->gssapi_wrap_tvb, Confounder, 24, 8);
        memcpy(output_message_buffer,
                input_message_buffer,
                datalen);
@@ -557,9 +553,7 @@ decrypt_arcfour(packet_info *pinfo,
            return -10;
        }
 
-       cmp = memcmp(cksum_data,
-           tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
-           8); /* SGN_CKSUM */
+       cmp = tvb_memeql(pinfo->gssapi_wrap_tvb, 16, cksum_data, 8); /* SGN_CKSUM */
        if (cmp) {
            return -11;
        }
@@ -580,18 +574,9 @@ decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *
        int length;
        const guint8 *original_data;
 
-       static int omb_index=0;
-       static guint8 *omb_arr[4]={NULL,NULL,NULL,NULL};
-       static guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */
+       guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */
        guint8 *output_message_buffer;
 
-       omb_index++;
-       if(omb_index>=4){
-               omb_index=0;
-       }
-       output_message_buffer=omb_arr[omb_index];
-
-
        length=tvb_length(pinfo->gssapi_encrypted_tvb);
        original_data=tvb_get_ptr(pinfo->gssapi_encrypted_tvb, 0, length);
 
@@ -604,12 +589,8 @@ decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *
        /* XXX we should only do this for first time, then store somewhere */
        /* XXX We also need to re-read the keytab when the preference changes */
 
-       cryptocopy=ep_alloc(length);
-       if(output_message_buffer){
-               g_free(output_message_buffer);
-               output_message_buffer=NULL;
-       }
-       output_message_buffer=g_malloc(length);
+       cryptocopy=(guint8 *)wmem_alloc(wmem_packet_scope(), length);
+       output_message_buffer=(guint8 *)wmem_alloc(pinfo->pool, length);
 
        for(ek=enc_key_list;ek;ek=ek->next){
                /* shortcircuit and bail out if enctypes are not matching */
@@ -633,10 +614,9 @@ decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *
                                            );
                if (ret >= 0) {
                        proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
-                       pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, 
+                       pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb,
                                output_message_buffer,
                                ret, ret);
-                       tvb_set_free_cb(pinfo->gssapi_decrypted_tvb, g_free);
                        add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
                        return;
                }
@@ -646,9 +626,9 @@ decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *
 
 /* borrowed from heimdal */
 static int
-rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
+rrc_rotate(guint8 *data, int len, guint16 rrc, int unrotate)
 {
-       unsigned char *tmp, buf[256];
+       guint8 *tmp, buf[256];
        size_t left;
 
        if (len == 0)
@@ -664,18 +644,18 @@ rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
        if (rrc <= sizeof(buf)) {
                tmp = buf;
        } else {
-               tmp = g_malloc(rrc);
+               tmp = (guint8 *)g_malloc(rrc);
                if (tmp == NULL)
                        return -1;
        }
 
        if (unrotate) {
                memcpy(tmp, data, rrc);
-               memmove(data, (unsigned char *)data + rrc, left);
-               memcpy((unsigned char *)data + left, tmp, rrc);
+               memmove(data, data + rrc, left);
+               memcpy(data + left, tmp, rrc);
        } else {
-               memcpy(tmp, (unsigned char *)data + left, rrc);
-               memmove((unsigned char *)data + rrc, data, left);
+               memcpy(tmp, data + left, rrc);
+               memmove(data + rrc, data, left);
                memcpy(data, tmp, rrc);
        }
 
@@ -692,11 +672,18 @@ rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
 #define KRB5_KU_USAGE_INITIATOR_SIGN   25
 
 static void
-decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_, packet_info *pinfo _U_, tvbuff_t *tvb _U_, guint16 ec _U_, guint16 rrc _U_, int keytype, unsigned int usage)
+decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_,
+                           packet_info *pinfo,
+                           tvbuff_t *checksum_tvb,
+                           tvbuff_t *encrypted_tvb,
+                           guint16 ec,
+                           guint16 rrc,
+                           gboolean is_dce,
+                           int keytype,
+                           unsigned int usage)
 {
-       int res;
-       char *rotated;
-       char *output;
+       guint8 *rotated;
+       guint8 *output;
        int datalen;
        tvbuff_t *next_tvb;
 
@@ -705,26 +692,38 @@ decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_, packet_info *pinfo _U_, tvbuff
                return;
        }
 
-       rotated = tvb_memdup(tvb, 0, tvb_length(tvb));
-       res = rrc_rotate(rotated, tvb_length(tvb), rrc, TRUE);
+       datalen = tvb_length(checksum_tvb) + tvb_length(encrypted_tvb);
 
-       next_tvb=tvb_new_child_real_data(tvb, rotated, tvb_length(tvb), tvb_reported_length(tvb));
-       tvb_set_free_cb(next_tvb, g_free);
+       rotated = (guint8 *)wmem_alloc(pinfo->pool, datalen);
+
+       tvb_memcpy(checksum_tvb, rotated,
+                  0, tvb_length(checksum_tvb));
+       tvb_memcpy(encrypted_tvb, rotated + tvb_length(checksum_tvb),
+                  0, tvb_length(encrypted_tvb));
+
+       if (is_dce) {
+               rrc += ec;
+       }
+
+       rrc_rotate(rotated, datalen, rrc, TRUE);
+
+       next_tvb=tvb_new_child_real_data(encrypted_tvb, rotated,
+                                        datalen, datalen);
        add_new_data_source(pinfo, next_tvb, "GSSAPI CFX");
 
        output = decrypt_krb5_data(tree, pinfo, usage, next_tvb,
                  keytype, &datalen);
 
        if (output) {
-               char *outdata;
+               guint8 *outdata;
 
-               outdata = g_memdup(output, tvb_length(tvb));
+               outdata = (guint8 *)g_memdup(output, tvb_length(encrypted_tvb));
                g_free(output);
 
-               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb,
+               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(encrypted_tvb,
                        outdata,
-                       datalen-16,
-                       datalen-16);
+                       tvb_length(encrypted_tvb),
+                       tvb_length(encrypted_tvb));
                add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
                tvb_set_free_cb(pinfo->gssapi_decrypted_tvb, g_free);
                return;
@@ -783,14 +782,14 @@ dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
        /* Encrypted sequence number */
 
        proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
-                           TRUE);
+                           ENC_NA);
 
        offset += 8;
 
        /* Checksum of plaintext padded data */
 
        proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
-                           TRUE);
+                           ENC_NA);
 
        offset += 8;
 
@@ -807,7 +806,7 @@ dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
               we may need to make this an option. gal 17/2/06 */
            (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) {
          proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
-                             TRUE);
+                             ENC_NA);
          offset += 8;
        }
 
@@ -896,14 +895,14 @@ dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U
        /* Encrypted sequence number */
 
        proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
-                           TRUE);
+                           ENC_NA);
 
        offset += 8;
 
        /* Checksum of plaintext padded data */
 
        proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
-                           TRUE);
+                           ENC_NA);
 
        offset += 8;
 
@@ -921,7 +920,7 @@ dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U
        if (tvb_length_remaining(tvb, offset)) {
          if (sgn_alg == KRB_SGN_ALG_HMAC) {
            proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
-                             TRUE);
+                             ENC_NA);
 
            offset += 8;
          }
@@ -978,7 +977,9 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
 {
        guint8 flags;
        guint16 ec;
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
        guint16 rrc;
+#endif
        int checksum_size;
        int start_offset=offset;
 
@@ -998,38 +999,67 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
        /* Skip the filler */
 
        proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1,
-                           FALSE);
+                           ENC_NA);
        offset += 1;
 
        /* EC */
        ec = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2,
-                           FALSE);
+                           ENC_BIG_ENDIAN);
        offset += 2;
 
        /* RRC */
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
        rrc = tvb_get_ntohs(tvb, offset);
+#endif
        proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2,
-                           FALSE);
+                           ENC_BIG_ENDIAN);
        offset += 2;
 
        /* sequence number */
 
        proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
-                           FALSE);
+                           ENC_BIG_ENDIAN);
        offset += 8;
 
        /* Checksum of plaintext padded data */
 
        if (pinfo->gssapi_data_encrypted) {
                checksum_size = 44 + ec;
+
+               proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
+                                   checksum_size, ENC_NA);
+               offset += checksum_size;
+
        } else {
-               checksum_size = 12;
-       }
+               int inner_token_len = 0;
 
-       proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
-                           checksum_size, FALSE);
-       offset += checksum_size;
+               /*
+                * We know we have a wrap token, but we have to let the proto
+                * above us decode that, so hand it back in gssapi_wrap_tvb
+                * and put the checksum in the tree.
+                */
+
+               checksum_size = ec;
+
+               inner_token_len = tvb_reported_length_remaining(tvb, offset) -
+                                       ec;
+
+               pinfo->gssapi_wrap_tvb = tvb_new_subset(tvb, offset,
+                                               inner_token_len, inner_token_len);
+
+               offset += inner_token_len;
+
+               proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
+                                   checksum_size, ENC_NA);
+
+               /*
+                * Return an offset that puts our caller before the inner
+                * token. This is better than before, but we still see the
+                * checksum included in the LDAP query at times.
+                */
+               return offset - inner_token_len;
+       }
 
        if(pinfo->decrypt_gssapi_tvb){
                /* if the caller did not provide a tvb, then we just use
@@ -1062,21 +1092,25 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
        }
 
 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
-       pinfo->gssapi_encrypted_tvb = tvb_new_subset_remaining(tvb, 16);
+{
+       tvbuff_t *checksum_tvb = tvb_new_subset(tvb, 16, checksum_size, checksum_size);
 
-       if (flags & 0x0002) {
+       if (pinfo->gssapi_data_encrypted) {
                if(pinfo->gssapi_encrypted_tvb){
                        decrypt_gssapi_krb_cfx_wrap(tree,
                                pinfo,
+                               checksum_tvb,
                                pinfo->gssapi_encrypted_tvb,
                                ec,
                                rrc,
+                               (pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE)?TRUE:FALSE,
                                -1,
                                (flags & 0x0001)?
                                KRB5_KU_USAGE_ACCEPTOR_SEAL:
                                KRB5_KU_USAGE_INITIATOR_SEAL);
                }
        }
+}
 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
 
        /*
@@ -1112,13 +1146,13 @@ dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinf
        /* Skip the filler */
 
        proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5,
-                           FALSE);
+                           ENC_NA);
        offset += 5;
 
        /* sequence number */
 
        proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
-                           FALSE);
+                           ENC_BIG_ENDIAN);
        offset += 8;
 
        /* Checksum of plaintext padded data */
@@ -1126,7 +1160,7 @@ dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinf
        checksum_size = tvb_length_remaining(tvb, offset);
 
        proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
-                           checksum_size, FALSE);
+                           checksum_size, ENC_NA);
        offset += checksum_size;
 
        /*
@@ -1147,14 +1181,14 @@ dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinf
  * getting it accepted.
  */
 static int
-dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
 {
        proto_item *item;
        proto_tree *subtree;
        int offset = 0;
        guint16 token_id;
 
-       item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, FALSE);
+       item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, ENC_NA);
 
        subtree = proto_item_add_subtree(item, ett_spnego_krb5);
 
@@ -1207,7 +1241,7 @@ dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 /* Spnego stuff from here */
 
 static int
-dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
 {
        proto_item *item;
        proto_tree *subtree;
@@ -1215,7 +1249,7 @@ dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        asn1_ctx_t asn1_ctx;
        asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
 
-
+       MechType_oid = NULL;
 
        /*
         * We need this later, so lets get it now ...
@@ -1225,7 +1259,7 @@ dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
 
        item = proto_tree_add_item(tree, proto_spnego, tvb, offset,
-                                  -1, FALSE);
+                                  -1, ENC_NA);
 
        subtree = proto_item_add_subtree(item, ett_spnego);
        /*
@@ -1257,7 +1291,7 @@ dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
         * It has to be per-frame as there can be more than one GSS-API
         * negotiation in a conversation.
         */
-       next_level_value = p_get_proto_data(pinfo->fd, proto_spnego);
+       next_level_value = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0);
        if (!next_level_value && !pinfo->fd->flags.visited) {
            /*
             * No handle attached to this frame, but it's the first
@@ -1270,15 +1304,15 @@ dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                             pinfo->destport, 0);
 
            if (conversation) {
-               next_level_value = conversation_get_proto_data(conversation,
+               next_level_value = (gssapi_oid_value *)conversation_get_proto_data(conversation,
                                                               proto_spnego);
                if (next_level_value)
-                   p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
+                   p_add_proto_data(wmem_file_scope(), pinfo, proto_spnego, 0, next_level_value);
            }
        }
 
        item = proto_tree_add_item(parent_tree, proto_spnego, tvb, offset,
-                                  -1, FALSE);
+                                  -1, ENC_NA);
 
        subtree = proto_item_add_subtree(item, ett_spnego);
 
@@ -1309,7 +1343,7 @@ dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
         * as well. Naughty, naughty.
         *
         */
-       offset = dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1);
+       dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1);
 
 }