Ethereal-dev: Re: [Ethereal-dev] kerberos help with automake magic

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Gerald Combs <gerald@xxxxxxxxxxxx>
Date: Thu, 14 Oct 2004 22:11:42 -0500
I suppose it would help if I actually attached the patch in question. I'll check if in tomorrow.

ronnie sahlberg wrote:
I assume you refer to doing the decryption of kerberos stuff using
Nettle instead
of MIT/Heimdal?

That sounds excellent.  It would stop making us depend on either Heimdal or MIT.

Go ahead  check it in,   beware though that someone might soon checkin
(i hope) automake magic to handle configure detecting MIT
automagically)



On Thu, 14 Oct 2004 16:54:36 -0500, Gerald Combs  wrote:

ronnie sahlberg wrote:

list  ,  automake wizards


packet-kerberos.c   now supports using the mit api to do very cool
stuff other loser
products fail to do.

Cool!  I don't mean to complicate matters further, but attached is a
patch that adds support for decoding DES3/CBC/MD5 ciphers directly using
the Nettle library.  Would it conflict with anything you're working on
if I checked it in?


Index: Makefile.nmake
===================================================================
--- Makefile.nmake	(revision 12296)
+++ Makefile.nmake	(working copy)
@@ -206,6 +206,7 @@
 	sed -e s/@VERSION@/$(VERSION)/ \
 	    -e "s/@HAVE_GNU_ADNS@/$(ADNS_CONFIG)/" \
 	    -e "s/@HAVE_PCRE@/$(PCRE_CONFIG)/" \
+	    -e "s/@HAVE_NETTLE@/$(NETTLE_CONFIG)/" \
 	    -e "s/@HAVE_LIBZ@/$(ZLIB_CONFIG)/" \
 	    -e "s/@HAVE_LIBPCAP@/$(WINPCAP_CONFIG)/" \
 	    -e "s/@HAVE_PCAP_FINDALLDEVS@/$(PCAP_FINDALLDEVS_CONFIG)/" \
Index: epan/Makefile.nmake
===================================================================
--- epan/Makefile.nmake	(revision 12296)
+++ epan/Makefile.nmake	(working copy)
@@ -21,6 +21,7 @@
 	$(GLIB_LIBS)	\
 	$(ADNS_LIBS) \
 	$(PCRE_LIBS) \
+	$(NETTLE_LIBS) \
 	$(ZLIB_LIBS) \
 	$(NET_SNMP_DIR)\win32\lib\netsnmp.lib \
 	ftypes\ftypes.lib \
Index: epan/dissectors/Makefile.nmake
===================================================================
--- epan/dissectors/Makefile.nmake	(revision 12296)
+++ epan/dissectors/Makefile.nmake	(working copy)
@@ -11,7 +11,8 @@
 
 CFLAGS=-DHAVE_CONFIG_H /I. /I.. /I../.. $(GLIB_CFLAGS) \
 	/I$(NET_SNMP_DIR)\include /I$(NET_SNMP_DIR)\win32 \
-	$(PCRE_CFLAGS) /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+	$(PCRE_CFLAGS) $(NETTLE_CFLAGS) \
+	/I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
 
 CVARSDLL=-DWIN32 -DNULL=0 -D_MT -D_DLL 
 
Index: epan/dissectors/packet-kerberos.c
===================================================================
--- epan/dissectors/packet-kerberos.c	(revision 12296)
+++ epan/dissectors/packet-kerberos.c	(working copy)
@@ -44,6 +44,16 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+/*
+ * Some of the development of the RADIUS protocol decoder was sponsored by
+ * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
+ * CableLabs' specifications. Your license and use of this protocol decoder
+ * does not mean that you are licensed to use the CableLabs'
+ * specifications.  If you have questions about this protocol, contact
+ * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
+ * information.
+ */
+
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
@@ -52,6 +62,13 @@
 #include <string.h>
 #include <ctype.h>
 
+#ifdef HAVE_LIBNETTLE
+#include <des.h>
+#include <cbc.h>
+#include "crypt-md5.h"
+#include <sys/stat.h>	/* For keyfile manipulation */
+#endif
+
 #include <glib.h>
 
 #include <epan/packet.h>
@@ -341,7 +358,7 @@
 	ret = krb5_kt_resolve(*context, filename, &keytab);
 	if(ret){
 		fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
-		
+
 		return;
 	}
 
@@ -397,7 +414,7 @@
 	if(!krb_decrypt){
 		return NULL;
 	}
-    
+
 	/* XXX we should only do this for first time, then store somewhere */
 
 	/* should this have a destroy context ?  heidal people would know */
@@ -410,7 +427,7 @@
 		read_keytab_file(keytab_filename, &context);
 	}
 
-	for(ek=enc_key_list;ek;ek=ek->next){	
+	for(ek=enc_key_list;ek;ek=ek->next){
 		krb5_enc_data input;
 
 		input.enctype = ek->key.key.enctype;
@@ -422,7 +439,7 @@
 			g_free(data.data);
 		}
 		data.data = g_malloc(length);
-		
+
 		/* shortcircuit and bail out if enctypes are not matching */
 		if(ek->key.key.enctype!=keytype){
 			continue;
@@ -438,11 +455,9 @@
 
 	return NULL;
 }
-#endif
 
+#elif defined(HAVE_HEIMDAL_KERBEROS)
 
-
-#ifdef HAVE_HEIMDAL_KERBEROS
 #include <krb5.h>
 
 #define MAX_ORIG_LEN	256
@@ -489,7 +504,7 @@
 	ret = krb5_kt_resolve(*context, filename, &keytab);
 	if(ret){
 		fprintf(stderr, "KERBEROS ERROR: Could not open keytab file :%s\n",filename);
-		
+
 		return;
 	}
 
@@ -545,7 +560,7 @@
 	if(!krb_decrypt){
 		return NULL;
 	}
-    
+
 	/* XXX we should only do this for first time, then store somewhere */
 
 	/* should this have a destroy context ?  heidal people would know */
@@ -558,10 +573,10 @@
 		read_keytab_file(keytab_filename, &context);
 	}
 
-	for(ek=enc_key_list;ek;ek=ek->next){	
+	for(ek=enc_key_list;ek;ek=ek->next){
 		krb5_crypto crypto;
 		guint8 *cryptocopy; /* workaround for pre-6.1 heimdal bug */
-		
+
 		/* shortcircuit and bail out if enctypes are not matching */
 		if(ek->key.keyblock.keytype!=keytype){
 			continue;
@@ -576,13 +591,13 @@
 		  the cryptotext data even when the decryption failed.
 		  This would obviously not work since we iterate over the
 		  keys. So just give it a copy of the crypto data instead.
-		  This has been seen for RC4-HMAC blobs. 
+		  This has been seen for RC4-HMAC blobs.
 		*/
 		cryptocopy=g_malloc(length);
 		memcpy(cryptocopy, cryptotext, length);
-		ret = krb5_decrypt_ivec(context, crypto, usage, 
-				cryptocopy, length, 
-				&data, 
+		ret = krb5_decrypt_ivec(context, crypto, usage,
+				cryptocopy, length,
+				&data,
 				NULL);
 		g_free(cryptocopy);
 		if (ret == 0) {
@@ -595,10 +610,195 @@
 	}
 	return NULL;
 }
-#endif
 
+#elif defined (HAVE_LIBNETTLE)
 
+#define MAX_ORIG_LEN	256
+#define SERVICE_KEY_SIZE (DES3_KEY_SIZE + 2)
+#define KEYTYPE_DES3_CBC_MD5 5	/* Currently the only one supported */
 
+typedef struct _service_key_t {
+    guint16 kvno;
+    int     keytype;
+    int     length;
+    guint8 *contents;
+    char    origin[MAX_ORIG_LEN+1];
+} service_key_t;
+GSList *service_key_list = NULL;
+
+
+static void
+add_encryption_key(packet_info *pinfo, int keytype, int keylength, const char *keyvalue, char *origin)
+{
+	service_key_t *new_key;
+
+	if(pinfo->fd->flags.visited){
+		return;
+	}
+printf("added key in %d\n",pinfo->fd->num);
+
+	new_key = g_malloc(sizeof(service_key_t));
+	new_key->kvno = 0;
+	new_key->keytype = keytype;
+	new_key->length = keylength;
+	new_key->contents = g_malloc(keylength);
+	memcpy(new_key->contents, keyvalue, keylength);
+	sprintf(new_key->origin, "%s learnt from frame %d", origin, pinfo->fd->num);
+}
+
+static void
+read_keytab_file(char *service_key_file)
+{
+	FILE *skf;
+	struct stat st;
+	service_key_t *sk;
+	unsigned char buf[SERVICE_KEY_SIZE];
+	int newline_skip = 0, count = 0;
+
+	if (service_key_file != NULL && stat (service_key_file, &st) == 0) {
+
+		/* The service key file contains raw 192-bit (24 byte) 3DES keys.
+		 * There can be zero, one (\n), or two (\r\n) characters between
+		 * keys.  Trailing characters are ignored.
+		 */
+		if (st.st_size > SERVICE_KEY_SIZE) {
+			if ( (st.st_size % (SERVICE_KEY_SIZE + 1) == 0) ||
+			     (st.st_size % (SERVICE_KEY_SIZE + 1) == SERVICE_KEY_SIZE) ) {
+			    newline_skip = 1;
+			} else if ( (st.st_size % (SERVICE_KEY_SIZE + 2) == 0) ||
+			     (st.st_size % (SERVICE_KEY_SIZE + 2) == SERVICE_KEY_SIZE) ) {
+			    newline_skip = 2;
+			}
+		}
+
+		skf = fopen(service_key_file, "rb");
+		if (! skf) return;
+
+		while (fread(buf, SERVICE_KEY_SIZE, 1, skf) == 1) {
+			sk = g_malloc(sizeof(service_key_t));
+			sk->kvno = buf[0] << 8 | buf[1];
+			sk->keytype = KEYTYPE_DES3_CBC_MD5;
+			sk->length = DES3_KEY_SIZE;
+			sk->contents = g_malloc(DES3_KEY_SIZE);
+			memcpy(sk->contents, buf + 2, DES3_KEY_SIZE);
+			sprintf(sk->origin, "3DES service key file, key #%d, offset %d", count, ftell(skf));
+			service_key_list = g_slist_append(service_key_list, (gpointer) sk);
+			fseek(skf, newline_skip, SEEK_CUR);
+			count++;
+g_warning("added key: %s", sk->origin);
+		}
+		fclose(skf);
+	}
+}
+
+#define CONFOUNDER_PLUS_CHECKSUM 24
+
+static guint8 *
+decrypt_krb5_data(proto_tree *tree, packet_info *pinfo,
+			int usage,
+			int length,
+			const char *cryptotext,
+			int keytype)
+{
+	static gboolean first_time = TRUE;
+
+	tvbuff_t *encr_tvb;
+	guint8 *decrypted_data = NULL, *plaintext = NULL;
+	int res;
+	guint8 cls;
+	gboolean pc;
+	guint32 tag, item_len, data_len;
+	int id_offset, offset;
+	guint8 key[DES3_KEY_SIZE];
+	guint8 initial_vector[DES_BLOCK_SIZE];
+	md5_state_t md5s;
+	md5_byte_t digest[16];
+	md5_byte_t zero_fill[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	md5_byte_t confounder[8];
+	gboolean ind;
+	GSList *ske;
+	service_key_t *sk;
+	struct des3_ctx ctx;
+
+
+	/* dont do anything if we are not attempting to decrypt data */
+	if(!krb_decrypt){
+		return NULL;
+	}
+
+	/* XXX we should only do this for first time, then store somewhere */
+
+	/* should this have a destroy context ?  heidal people would know */
+	if(first_time){
+		first_time = FALSE;
+		read_keytab_file(keytab_filename);
+	}
+
+	if (keytype != KEYTYPE_DES3_CBC_MD5 || service_key_list == NULL) {
+		return NULL;
+	}
+
+	decrypted_data = g_malloc(length);
+	for(ske = service_key_list; ske != NULL; ske = g_slist_next(ske)){
+		sk = (service_key_t *) ske->data;
+
+		des_fix_parity(DES3_KEY_SIZE, key, sk->contents);
+
+		md5_init(&md5s);
+		memset(initial_vector, 0, DES_BLOCK_SIZE);
+		res = des3_set_key(&ctx, key);
+		cbc_decrypt(&ctx, des3_decrypt, DES_BLOCK_SIZE, initial_vector,
+		    length, decrypted_data, cryptotext);
+		encr_tvb = tvb_new_real_data(decrypted_data, length, length);
+
+		tvb_memcpy(encr_tvb, confounder, 0, 8);
+
+		/* We have to pull the decrypted data length from the decrypted
+		 * content.  If the key doesn't match or we otherwise get garbage,
+		 * an exception may get thrown while decoding the ASN.1 header.
+		 * Catch it, just in case.
+		 */
+		TRY {
+			id_offset = get_ber_identifier(encr_tvb, CONFOUNDER_PLUS_CHECKSUM, &cls, &pc, &tag);
+			offset = get_ber_length(encr_tvb, id_offset, &item_len, &ind);
+		}
+		CATCH (BoundsError) {
+			tvb_free(encr_tvb);
+			continue;
+		}
+		ENDTRY;
+
+		data_len = item_len + offset - CONFOUNDER_PLUS_CHECKSUM;
+		if ((int) item_len + offset > length) {
+			tvb_free(encr_tvb);
+			continue;
+		}
+
+		md5_append(&md5s, confounder, 8);
+		md5_append(&md5s, zero_fill, 16);
+		md5_append(&md5s, decrypted_data + CONFOUNDER_PLUS_CHECKSUM, data_len);
+		md5_finish(&md5s, digest);
+
+		if (tvb_memeql (encr_tvb, 8, digest, 16) == 0) {
+g_warning("woohoo decrypted keytype:%d in frame:%d\n", keytype, pinfo->fd->num);
+			plaintext = g_malloc(data_len);
+			tvb_memcpy(encr_tvb, plaintext, CONFOUNDER_PLUS_CHECKSUM, data_len);
+			tvb_free(encr_tvb);
+
+			g_free(decrypted_data);
+			return(plaintext);
+		}
+	}
+
+	g_free(decrypted_data);
+	return NULL;
+}
+
+
+#endif	/* HAVE_MIT_KERBEROS / HAVE_HEIMDAL_KERBEROS / HAVE_LIBNETTLE */
+
+
+
 /* TCP Record Mark */
 #define	KRB_RM_RESERVED	0x80000000L
 #define	KRB_RM_RECLEN	0x7fffffffL
@@ -648,7 +848,7 @@
 #define KRB5_ENCTYPE_DES_EDE3_CBC_ENV    15
 #define KRB5_ENCTYPE_DES3_CBC_SHA1       16
 #define KRB5_ENCTYPE_DES_CBC_MD5_NT      20
-#define KERB_ENCTYPE_RC4_HMAC            23 
+#define KERB_ENCTYPE_RC4_HMAC            23
 #define KERB_ENCTYPE_RC4_HMAC_EXP        24
 #define KRB5_ENCTYPE_UNKNOWN                0x1ff
 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1   0x7007
@@ -738,7 +938,7 @@
 /* Principal name-type */
 #define KRB5_NT_UNKNOWN        0
 #define KRB5_NT_PRINCIPAL      1
-#define KRB5_NT_SRV_INST       2	
+#define KRB5_NT_SRV_INST       2
 #define KRB5_NT_SRV_HST        3
 #define KRB5_NT_SRV_XHST       4
 #define KRB5_NT_UID            5
@@ -751,7 +951,7 @@
  *
  *	http://msdn.microsoft.com/library/en-us/security/security/kerb_external_name.asp
  */
-#define KRB5_NT_MS_PRINCIPAL		-128	
+#define KRB5_NT_MS_PRINCIPAL		-128
 #define KRB5_NT_MS_PRINCIPAL_AND_SID	-129
 #define KRB5_NT_ENT_PRINCIPAL_AND_SID	-130
 #define KRB5_NT_PRINCIPAL_AND_SID 	-131
@@ -1133,7 +1333,7 @@
 };
 
 
-static int 
+static int
 dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_choice(pinfo, tree, tvb, offset, kerberos_applications_choice, -1, -1);
@@ -1219,19 +1419,19 @@
 
 static int* KDCOptions_bits[] = {
   &hf_krb_KDCOptions_forwardable,
-  &hf_krb_KDCOptions_forwarded,  
-  &hf_krb_KDCOptions_proxyable,  
-  &hf_krb_KDCOptions_proxy,      
+  &hf_krb_KDCOptions_forwarded,
+  &hf_krb_KDCOptions_proxyable,
+  &hf_krb_KDCOptions_proxy,
   &hf_krb_KDCOptions_allow_postdate,
-  &hf_krb_KDCOptions_postdated,   
+  &hf_krb_KDCOptions_postdated,
   &hf_krb_KDCOptions_renewable,
   &hf_krb_KDCOptions_opt_hardware_auth,
   &hf_krb_KDCOptions_canonicalize,
-  &hf_krb_KDCOptions_disable_transited_check,   
+  &hf_krb_KDCOptions_disable_transited_check,
   &hf_krb_KDCOptions_renewable_ok,
   &hf_krb_KDCOptions_enc_tkt_in_skey,
-  &hf_krb_KDCOptions_renew,       
-  &hf_krb_KDCOptions_validate,    
+  &hf_krb_KDCOptions_renew,
+  &hf_krb_KDCOptions_validate,
   NULL
 };
 
@@ -1242,14 +1442,14 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_rtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_rtime);
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_ctime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_ctime);
@@ -1262,7 +1462,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_stime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_stime);
@@ -1281,7 +1481,7 @@
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_error_code, &krb5_errorcode);
 	if(krb5_errorcode && check_col(pinfo->cinfo, COL_INFO)) {
-		col_add_fstr(pinfo->cinfo, COL_INFO, 
+		col_add_fstr(pinfo->cinfo, COL_INFO,
 			"KRB Error: %s",
 			val_to_str(krb5_errorcode, krb5_error_codes,
 			"Unknown error code %#x"));
@@ -1291,13 +1491,13 @@
 }
 
 
-static int 
+static int
 dissect_krb5_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_till);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_from(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_from);
@@ -1306,7 +1506,7 @@
 
 
 
-static int 
+static int
 dissect_krb5_nonce(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_nonce, NULL);
@@ -1317,14 +1517,14 @@
 /*
  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
  */
-static int 
+static int
 dissect_krb5_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	guint32 etype;
 
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(etype, krb5_encryption_types,
 			"%d"));
 	}
@@ -1341,48 +1541,48 @@
 	return offset;
 }
 static guint32 authenticator_etype;
-static int 
+static int
 dissect_krb5_authenticator_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(authenticator_etype, krb5_encryption_types,
 			"%#x"));
 	}
 	return offset;
 }
 static guint32 Ticket_etype;
-static int 
+static int
 dissect_krb5_Ticket_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(Ticket_etype, krb5_encryption_types,
 			"%#x"));
 	}
 	return offset;
 }
 static guint32 AP_REP_etype;
-static int 
+static int
 dissect_krb5_AP_REP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(AP_REP_etype, krb5_encryption_types,
 			"%#x"));
 	}
 	return offset;
 }
 static guint32 PA_ENC_TIMESTAMP_etype;
-static int 
+static int
 dissect_krb5_PA_ENC_TIMESTAMP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
 			"%#x"));
 	}
@@ -1429,7 +1629,7 @@
 		int netbios_name_type;
 
 		netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name);
-		snprintf(address_str, 255, "%s<%02x>", netbios_name, netbios_name_type); 
+		snprintf(address_str, 255, "%s<%02x>", netbios_name, netbios_name_type);
 		it=proto_tree_add_string_format(tree, hf_krb_address_netbios, tvb, offset, 16, netbios_name, "NetBIOS Name: %s (%s)", address_str, netbios_name_type_descr(netbios_name_type));
 		}
 		break;
@@ -1497,7 +1697,7 @@
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_msg_type, &msgtype);
 
 	if (do_col_info & check_col(pinfo->cinfo, COL_INFO)) {
-		col_add_str(pinfo->cinfo, COL_INFO, 
+		col_add_str(pinfo->cinfo, COL_INFO,
 			val_to_str(msgtype, krb5_msg_types,
 			"Unknown msg type %#x"));
 	}
@@ -1527,20 +1727,20 @@
  * }
  */
 guint32 name_type;
-static int 
+static int
 dissect_krb5_name_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_name_type, &name_type);
 	if(tree){
-		proto_item_append_text(tree, " (%s):", 
+		proto_item_append_text(tree, " (%s):",
 			val_to_str(name_type, krb5_princ_types,
 			"Unknown:%d"));
 	}
 	return offset;
 }
 static char name_string_separator;
-static int 
+static int
 dissect_krb5_name_string(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	char name_string[256];
@@ -1556,7 +1756,7 @@
 static ber_sequence name_stringe_sequence_of[1] = {
   { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
 };
-static int 
+static int
 dissect_krb5_name_strings(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	name_string_separator=' ';
@@ -1587,14 +1787,14 @@
 }
 
 
-static int 
+static int
 dissect_krb5_realm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_realm, NULL, 0);
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_crealm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_crealm, NULL, 0);
@@ -1658,13 +1858,13 @@
 
 
 #ifdef HAVE_KERBEROS
-static int 
+static int
 dissect_krb5_pausec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_pausec, NULL);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_patimestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_patimestamp);
@@ -1685,7 +1885,7 @@
 
 	/* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
 	 * 7.5.1
-	 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage 
+	 * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
 	 * == 1
 	 */
 	if(!plaintext){
@@ -1698,11 +1898,11 @@
                                           length,
                                           length);
 		tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-            
+
 		/* Add the decrypted data to the data source list. */
 		add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
-            
 
+
 		offset=dissect_ber_sequence(FALSE, pinfo, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
 
 	}
@@ -1722,7 +1922,7 @@
 	return offset;
 }
 static ber_sequence PA_ENC_TIMESTAMP_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_PA_ENC_TIMESTAMP_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -1748,7 +1948,7 @@
 }
 
 static ber_sequence PA_ENCTYPE_INFO_ENTRY_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_etype_info_salt },
@@ -1788,7 +1988,7 @@
 	krb_PA_DATA_type&=0xff; /*this is really just one single byte */
 
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
 			"Unknown:%d"));
 	}
@@ -1922,17 +2122,17 @@
 
 static int* TicketFlags_bits[] = {
   &hf_krb_TicketFlags_forwardable,
-  &hf_krb_TicketFlags_forwarded,  
-  &hf_krb_TicketFlags_proxyable,  
-  &hf_krb_TicketFlags_proxy,      
+  &hf_krb_TicketFlags_forwarded,
+  &hf_krb_TicketFlags_proxyable,
+  &hf_krb_TicketFlags_proxy,
   &hf_krb_TicketFlags_allow_postdate,
-  &hf_krb_TicketFlags_postdated,   
-  &hf_krb_TicketFlags_invalid,   
+  &hf_krb_TicketFlags_postdated,
+  &hf_krb_TicketFlags_invalid,
   &hf_krb_TicketFlags_renewable,
   &hf_krb_TicketFlags_initial,
   &hf_krb_TicketFlags_pre_auth,
   &hf_krb_TicketFlags_hw_auth,
-  &hf_krb_TicketFlags_transited_policy_checked,   
+  &hf_krb_TicketFlags_transited_policy_checked,
   &hf_krb_TicketFlags_ok_as_delegate,
   NULL
 };
@@ -1946,12 +2146,12 @@
 
 
 static guint32 keytype;
-static int 
+static int
 dissect_krb5_keytype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_keytype, &keytype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(keytype, krb5_encryption_types,
 			"%#x"));
 	}
@@ -1966,7 +2166,7 @@
 	keyvalue=tvb_get_ptr(tvb, offset, keylength);
 	return 0;
 }
-static int 
+static int
 dissect_krb5_keyvalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
@@ -2008,7 +2208,7 @@
 
 
 
-static int 
+static int
 dissect_krb5_PAC_LOGON_INFO(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
 {
 	proto_item *item=NULL;
@@ -2043,7 +2243,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_PAC_CREDENTIAL_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
 {
 	proto_item *item=NULL;
@@ -2058,7 +2258,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_PAC_SERVER_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
 {
 	proto_item *item=NULL;
@@ -2079,7 +2279,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_PAC_PRIVSVR_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
 {
 	proto_item *item=NULL;
@@ -2100,7 +2300,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_PAC_CLIENT_INFO_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
 {
 	proto_item *item=NULL;
@@ -2130,7 +2330,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_AD_WIN2K_PAC_struct(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	guint32 pac_type;
@@ -2148,18 +2348,18 @@
 	}
 
 	offset += 4;
-	
+
 	/* size of pac data */
 	pac_size=tvb_get_letohl(tvb, offset);
 	proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
 	offset += 4;
-	
+
 	/* offset to pac data */
 	pac_offset=tvb_get_letohl(tvb, offset);
 	proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
 	offset += 8;
-	
 
+
 	next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
 	switch(pac_type){
 	case PAC_LOGON_INFO:
@@ -2183,7 +2383,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_AD_WIN2K_PAC(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	guint32 entries;
@@ -2208,18 +2408,18 @@
 }
 
 static guint32 IF_RELEVANT_type;
-static int 
+static int
 dissect_krb5_IF_RELEVANT_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_IF_RELEVANT_type, &IF_RELEVANT_type);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(IF_RELEVANT_type, krb5_ad_types,
 			"%#x"));
 	}
 	return offset;
 }
-static int 
+static int
 dissect_krb5_IF_RELEVANT_value(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	switch(IF_RELEVANT_type){
@@ -2238,7 +2438,7 @@
 		dissect_krb5_IF_RELEVANT_value },
 	{ 0, 0, 0, NULL }
 };
-static int 
+static int
 dissect_krb5_IF_RELEVANT_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_item_sequence, hf_krb_IF_RELEVANT, ett_krb_IF_RELEVANT);
@@ -2250,7 +2450,7 @@
   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_IF_RELEVANT_item },
 };
 
-static int 
+static int
 dissect_krb5_IF_RELEVANT(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_sequence_of, -1, -1);
@@ -2259,18 +2459,18 @@
 }
 
 static guint32 adtype;
-static int 
+static int
 dissect_krb5_adtype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_adtype, &adtype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(adtype, krb5_ad_types,
 			"%#x"));
 	}
 	return offset;
 }
-static int 
+static int
 dissect_krb5_advalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	switch(adtype){
@@ -2314,21 +2514,21 @@
 }
 
 
-static int 
+static int
 dissect_krb5_transited_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	guint32 trtype;
 
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_transitedtype, &trtype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(trtype, krb5_transited_types,
 			"%#x"));
 	}
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_transited_contents(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_transitedcontents, NULL);
@@ -2356,25 +2556,25 @@
 }
 
 
-static int 
+static int
 dissect_krb5_authtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_authtime);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_starttime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_starttime);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_endtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_endtime);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_renew_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_renew_till);
@@ -2401,7 +2601,7 @@
 		dissect_krb5_TicketFlags },
 	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_key },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_crealm },
 	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_cname },
@@ -2515,7 +2715,7 @@
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_key_expiration(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_key_expire);
@@ -2541,7 +2741,7 @@
 		dissect_krb5_endtime },
 	{ BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
 		dissect_krb5_renew_till },
-	{ BER_CLASS_CON, 9, 0, 
+	{ BER_CLASS_CON, 9, 0,
 		dissect_krb5_realm },
 	{ BER_CLASS_CON, 10, 0,
 		dissect_krb5_sname },
@@ -2616,7 +2816,7 @@
 static ber_sequence Authenticator_sequence[] = {
 	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_authenticator_vno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_crealm },
 	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_cname },
@@ -2658,7 +2858,7 @@
 	return offset;
 }
 static ber_sequence ENC_PRIV_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -2673,9 +2873,9 @@
 	return offset;
 }
 static ber_sequence PRIV_BODY_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
 	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_ENC_PRIV },
@@ -2699,7 +2899,7 @@
 	call_kerberos_callbacks(pinfo, tree, new_tvb, KRB_CBTAG_SAFE_USER_DATA);
 	return offset;
 }
-static int 
+static int
 dissect_krb5_SAFE_BODY_timestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_timestamp);
@@ -2714,11 +2914,11 @@
 }
 
 static ber_sequence SAFE_BODY_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_SAFE_BODY_user_data },
-	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, 
+	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_SAFE_BODY_timestamp },
-	{ BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, 
+	{ BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
 		dissect_krb5_SAFE_BODY_usec },
 	{ BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
 		dissect_krb5_seq_number },
@@ -2741,13 +2941,13 @@
 
 
 static ber_sequence SAFE_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_SAFE_BODY },
-	{ BER_CLASS_CON, 3, 0, 
+	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_Checksum },
 	{ 0, 0, 0, NULL }
 };
@@ -2793,7 +2993,7 @@
 		dissect_krb5_sname },
 	{ BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
 		dissect_krb5_from },
-		/* this field is not optional in the kerberos spec, 
+		/* this field is not optional in the kerberos spec,
 		 * however, in the packetcable spec it is optional.
 		 * make it optional here since normal kerberos will
 		 * still decode the pdu correctly.
@@ -2831,9 +3031,9 @@
  * }
  */
 static ber_sequence KDC_REQ_sequence[] = {
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_msg_type },
 	{ BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
 		dissect_krb5_padata },
@@ -2861,7 +3061,7 @@
 
 	/* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
 	 * 7.5.1
-	 * Authenticators are encrypted with usage 
+	 * Authenticators are encrypted with usage
 	 * == 7 or
 	 * == 11
 	 */
@@ -2878,11 +3078,11 @@
                                           length,
                                           length);
 		tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-            
+
 		/* Add the decrypted data to the data source list. */
 		add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
-            
 
+
 		offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1);
 
 	}
@@ -2909,7 +3109,7 @@
 	return offset;
 }
 static ber_sequence encrypted_authenticator_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_authenticator_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -2928,7 +3128,7 @@
 
 
 
-static int 
+static int
 dissect_krb5_tkt_vno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_tkt_vno, NULL);
@@ -2947,7 +3147,7 @@
 
 	/* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
 	 * 7.5.1
-	 * All Ticket encrypted parts use usage == 2 
+	 * All Ticket encrypted parts use usage == 2
 	 */
 	if( (plaintext=decrypt_krb5_data(tree, pinfo, 2, length, tvb_get_ptr(tvb, offset, length), Ticket_etype)) ){
 		tvbuff_t *next_tvb;
@@ -2955,11 +3155,11 @@
                                           length,
                                           length);
 		tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-            
+
 		/* Add the decrypted data to the data source list. */
 		add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
-            
 
+
 		offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1);
 
 	}
@@ -2978,7 +3178,7 @@
 	return offset;
 }
 static ber_sequence encrypted_Ticket_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_Ticket_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -2995,13 +3195,13 @@
 }
 
 static ber_sequence Application_1_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_tkt_vno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_realm },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_sname },
-	{ BER_CLASS_CON, 3, 0, 
+	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_Ticket_encrypted },
 	{ 0, 0, 0, NULL }
 };
@@ -3016,7 +3216,7 @@
 
 
 static const ber_choice Ticket_choice[] = {
-	{ 1, BER_CLASS_APP, 1,  0,	
+	{ 1, BER_CLASS_APP, 1,  0,
 		dissect_krb5_Application_1 },
 	{ 0, 0, 0, 0, NULL }
 };
@@ -3041,15 +3241,15 @@
  *  }
  */
 static ber_sequence AP_REQ_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_APOptions },
-	{ BER_CLASS_CON, 3, 0, 
+	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_Ticket },
-	{ BER_CLASS_CON, 4, 0, 
+	{ BER_CLASS_CON, 4, 0,
 		dissect_krb5_encrypted_authenticator },
 	{ 0, 0, 0, NULL }
 };
@@ -3075,7 +3275,7 @@
 
 	/* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
 	 * 7.5.1
-	 * Authenticators are encrypted with usage 
+	 * Authenticators are encrypted with usage
 	 * == 7 or
 	 * == 11
 	 */
@@ -3089,11 +3289,11 @@
                                           length,
                                           length);
 		tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-            
+
 		/* Add the decrypted data to the data source list. */
 		add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
-            
 
+
 		offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1);
 
 	}
@@ -3113,7 +3313,7 @@
 	return offset;
 }
 static ber_sequence encrypted_AP_REP_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_AP_REP_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -3137,11 +3337,11 @@
  *  }
  */
 static ber_sequence AP_REP_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
-	{ BER_CLASS_CON, 2, 0, 
+	{ BER_CLASS_CON, 2, 0,
 		dissect_krb5_encrypted_AP_REP },
 	{ 0, 0, 0, NULL }
 };
@@ -3158,12 +3358,12 @@
 
 
 static guint32 KDC_REP_etype;
-static int 
+static int
 dissect_krb5_KDC_REP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &KDC_REP_etype);
 	if(tree){
-		proto_item_append_text(tree, " %s", 
+		proto_item_append_text(tree, " %s",
 			val_to_str(KDC_REP_etype, krb5_encryption_types,
 			"%#x"));
 	}
@@ -3181,7 +3381,7 @@
 
 	/* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
 	 * 7.5.1
-	 * ASREP/TGSREP encryptedparts are encrypted with usage 
+	 * ASREP/TGSREP encryptedparts are encrypted with usage
 	 * == 3 or
 	 * == 8 or
          * == 9
@@ -3202,11 +3402,11 @@
                                           length,
                                           length);
 		tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-            
+
 		/* Add the decrypted data to the data source list. */
 		add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
-            
 
+
 		offset=dissect_ber_choice(pinfo, tree, next_tvb, 0, kerberos_applications_choice, -1, -1);
 
 	}
@@ -3226,7 +3426,7 @@
 	return offset;
 }
 static ber_sequence encrypted_KDC_REP_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_KDC_REP_etype },
 	{ BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
 		dissect_krb5_kvno },
@@ -3254,19 +3454,19 @@
  *  }
  */
 static ber_sequence KDC_REP_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
-	{ BER_CLASS_CON, 1, 0, 
+	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
 	{ BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
 		dissect_krb5_padata },
-	{ BER_CLASS_CON, 3, 0, 
+	{ BER_CLASS_CON, 3, 0,
 		dissect_krb5_crealm },
 	{ BER_CLASS_CON, 4, 0,
 		dissect_krb5_cname },
-	{ BER_CLASS_CON, 5, 0, 
+	{ BER_CLASS_CON, 5, 0,
 		dissect_krb5_Ticket },
-	{ BER_CLASS_CON, 6, 0, 
+	{ BER_CLASS_CON, 6, 0,
 		dissect_krb5_encrypted_KDC_REP },
 	{ 0, 0, 0, NULL }
 };
@@ -3281,14 +3481,14 @@
 
 
 
-static int 
+static int
 dissect_krb5_e_text(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_e_text, NULL, 0);
 	return offset;
 }
 
-static int 
+static int
 dissect_krb5_e_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	switch(krb5_errorcode){
@@ -3303,10 +3503,10 @@
 }
 
 
-/* This optional field in KRB_ERR is used by the early drafts which 
+/* This optional field in KRB_ERR is used by the early drafts which
  * PacketCable still use.
  */
-static int 
+static int
 dissect_krb5_e_checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
 {
 	offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Checksum_sequence, hf_krb_e_checksum, ett_krb_e_checksum);
@@ -3341,7 +3541,7 @@
  *            the method:
  */
 static ber_sequence ERROR_sequence[] = {
-	{ BER_CLASS_CON, 0, 0, 
+	{ BER_CLASS_CON, 0, 0,
 		dissect_krb5_pvno },
 	{ BER_CLASS_CON, 1, 0,
 		dissect_krb5_msg_type },
@@ -3361,7 +3561,7 @@
 		dissect_krb5_cname },
 	{ BER_CLASS_CON, 9, 0,
 		dissect_krb5_realm },
-	{ BER_CLASS_CON, 10, 0, 
+	{ BER_CLASS_CON, 10, 0,
 		dissect_krb5_sname },
 	{ BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
 		dissect_krb5_e_text },
@@ -3534,7 +3734,7 @@
 	{ &hf_krb_transitedtype, {
 	    "Type", "kerberos.transited.type", FT_UINT32, BASE_DEC,
 	    VALS(krb5_transited_types), 0, "Transited Type", HFILL }},
-	{ &hf_krb_transitedcontents, {	
+	{ &hf_krb_transitedcontents, {
 	    "Contents", "kerberos.transited.contents", FT_BYTES, BASE_HEX,
 	    NULL, 0, "Transitent Contents string", HFILL }},
 	{ &hf_krb_keytype, {
@@ -3921,10 +4121,10 @@
 	{ &hf_krb_w2k_pac_offset, {
 	    "Offset", "kerberos.pac.offset", FT_UINT32, BASE_DEC,
 	    NULL, 0, "Offset to W2k PAC entry", HFILL }},
-	{ &hf_krb_pac_clientid, { 
+	{ &hf_krb_pac_clientid, {
 	    "ClientID", "kerberos.pac.clientid", FT_ABSOLUTE_TIME, BASE_NONE,
 	    NULL, 0, "ClientID Timestamp", HFILL }},
-	{ &hf_krb_pac_namelen, { 
+	{ &hf_krb_pac_namelen, {
 	    "Name Length", "kerberos.pac.namelen", FT_UINT16, BASE_DEC,
 	    NULL, 0, "Length of client name", HFILL }},
 	{ &hf_krb_e_checksum, {
Index: config.nmake
===================================================================
--- config.nmake	(revision 12296)
+++ config.nmake	(working copy)
@@ -123,6 +123,15 @@
 PCRE_DIR=$(ETHEREAL_LIBS)\pcre-4.4
 
 #
+# If you have the Nettle encryption library, set this to the pathname
+# of the directory in which the nettle package has been extracted.
+#
+# If you don't have Nettle, comment this line out, so that NETTLE_DIR
+# isn't defined.
+#
+NETTLE_DIR=$(ETHEREAL_LIBS)\nettle-1.10
+
+#
 # Set ICONV_DIR to the pathname of the directory in which the
 # ICONV include files and library resides.
 #
@@ -319,6 +328,17 @@
 PCRE_CONFIG=
 !ENDIF
 
+!IFDEF NETTLE_DIR
+NETTLE_CFLAGS=/I$(NETTLE_DIR)
+NETTLE_LIBS=$(NETTLE_DIR)\libnettle.lib
+# Nmake uses carets to escape special characters
+NETTLE_CONFIG=^#define HAVE_LIBNETTLE 1
+!else
+NETTLE_CFLAGS=
+NETTLE_LIBS=
+NETTLE_CONFIG=
+!ENDIF
+
 !IFDEF ENABLE_LIBETHEREAL
 LIBETHEREAL_CONFIG=^#define HAVE_LIBETHEREALDLL 1
 !ELSE
Index: config.h.win32
===================================================================
--- config.h.win32	(revision 12296)
+++ config.h.win32	(working copy)
@@ -179,6 +179,12 @@
 /* Define to use the PCRE library */
 @HAVE_PCRE@
 
+/* Define to use the Nettle library */
+@HAVE_NETTLE@
+#ifdef HAVE_LIBNETTLE
+#define HAVE_KERBEROS 1
+#endif
+
 #ifndef WIN32
 #define WIN32			1
 #endif