packet-spnego: fix decryption of DCERPC packets in decrypt_gssapi_krb_cfx_wrap()
[metze/wireshark/wip.git] / asn1 / spnego / packet-spnego-template.c
1 /* packet-spnego.c
2  * Routines for the simple and protected GSS-API negotiation mechanism
3  * as described in RFC 2478.
4  * Copyright 2002, Tim Potter <tpot@samba.org>
5  * Copyright 2002, Richard Sharpe <rsharpe@ns.aus.com>
6  * Copyright 2003, Richard Sharpe <rsharpe@richardsharpe.com>
7  * Copyright 2005, Ronnie Sahlberg (krb decryption)
8  * Copyright 2005, Anders Broman (converted to asn2wrs generated dissector)
9  *
10  * $Id$
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29  */
30 /* The heimdal code for decryption of GSSAPI wrappers using heimdal comes from
31    Heimdal 1.6 and has been modified for wireshark's requirements.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39 #include <epan/packet.h>
40 #include <epan/asn1.h>
41 #include "packet-dcerpc.h"
42 #include "packet-gssapi.h"
43 #include "packet-kerberos.h"
44 #include <epan/crypt/crypt-rc4.h>
45 #include <epan/conversation.h>
46 #include <epan/emem.h>
47 #include <epan/asn1.h>
48
49 #include <stdio.h>
50 #include <string.h>
51
52 #include "packet-ber.h"
53
54
55 #define PNAME  "Simple Protected Negotiation"
56 #define PSNAME "SPNEGO"
57 #define PFNAME "spnego"
58
59 /* Initialize the protocol and registered fields */
60 static int proto_spnego = -1;
61 static int proto_spnego_krb5 = -1;
62
63
64 static int hf_spnego = -1;
65 static int hf_spnego_wraptoken = -1;
66 static int hf_spnego_krb5_oid;
67 static int hf_spnego_krb5 = -1;
68 static int hf_spnego_krb5_tok_id = -1;
69 static int hf_spnego_krb5_sgn_alg = -1;
70 static int hf_spnego_krb5_seal_alg = -1;
71 static int hf_spnego_krb5_snd_seq = -1;
72 static int hf_spnego_krb5_sgn_cksum = -1;
73 static int hf_spnego_krb5_confounder = -1;
74 static int hf_spnego_krb5_filler = -1;
75 static int hf_spnego_krb5_cfx_flags = -1;
76 static int hf_spnego_krb5_cfx_flags_01 = -1;
77 static int hf_spnego_krb5_cfx_flags_02 = -1;
78 static int hf_spnego_krb5_cfx_flags_04 = -1;
79 static int hf_spnego_krb5_cfx_ec = -1;
80 static int hf_spnego_krb5_cfx_rrc = -1;
81 static int hf_spnego_krb5_cfx_seq = -1;
82
83 #include "packet-spnego-hf.c"
84
85 /* Global variables */
86 static const char *MechType_oid;
87 gssapi_oid_value *next_level_value;
88 gboolean saw_mechanism = FALSE;
89
90
91 /* Initialize the subtree pointers */
92 static gint ett_spnego;
93 static gint ett_spnego_wraptoken;
94 static gint ett_spnego_krb5 = -1;
95 static gint ett_spnego_krb5_cfx_flags = -1;
96
97 #include "packet-spnego-ett.c"
98
99 /*
100  * Unfortunately, we have to have a forward declaration of this,
101  * as the code generated by asn2wrs includes a call before the
102  * definition.
103  */
104 static int dissect_spnego_PrincipalSeq(gboolean implicit_tag, tvbuff_t *tvb,
105                                        int offset, asn1_ctx_t *actx _U_,
106                                        proto_tree *tree, int hf_index);
107
108 #include "packet-spnego-fn.c"
109 /*
110  * This is the SPNEGO KRB5 dissector. It is not true KRB5, but some ASN.1
111  * wrapped blob with an OID, USHORT token ID, and a Ticket, that is also
112  * ASN.1 wrapped by the looks of it. It conforms to RFC1964.
113  */
114
115 #define KRB_TOKEN_AP_REQ                0x0001
116 #define KRB_TOKEN_AP_REP                0x0002
117 #define KRB_TOKEN_AP_ERR                0x0003
118 #define KRB_TOKEN_GETMIC                0x0101
119 #define KRB_TOKEN_WRAP                  0x0102
120 #define KRB_TOKEN_DELETE_SEC_CONTEXT    0x0201
121 #define KRB_TOKEN_CFX_GETMIC            0x0404
122 #define KRB_TOKEN_CFX_WRAP              0x0405
123
124 static const value_string spnego_krb5_tok_id_vals[] = {
125   { KRB_TOKEN_AP_REQ,             "KRB5_AP_REQ"},
126   { KRB_TOKEN_AP_REP,             "KRB5_AP_REP"},
127   { KRB_TOKEN_AP_ERR,             "KRB5_ERROR"},
128   { KRB_TOKEN_GETMIC,             "KRB5_GSS_GetMIC" },
129   { KRB_TOKEN_WRAP,               "KRB5_GSS_Wrap" },
130   { KRB_TOKEN_DELETE_SEC_CONTEXT, "KRB5_GSS_Delete_sec_context" },
131   { KRB_TOKEN_CFX_GETMIC,         "KRB_TOKEN_CFX_GetMic" },
132   { KRB_TOKEN_CFX_WRAP,           "KRB_TOKEN_CFX_WRAP" },
133   { 0, NULL}
134 };
135
136 #define KRB_SGN_ALG_DES_MAC_MD5 0x0000
137 #define KRB_SGN_ALG_MD2_5       0x0001
138 #define KRB_SGN_ALG_DES_MAC     0x0002
139 #define KRB_SGN_ALG_HMAC        0x0011
140
141 static const value_string spnego_krb5_sgn_alg_vals[] = {
142   { KRB_SGN_ALG_DES_MAC_MD5, "DES MAC MD5"},
143   { KRB_SGN_ALG_MD2_5,       "MD2.5"},
144   { KRB_SGN_ALG_DES_MAC,     "DES MAC"},
145   { KRB_SGN_ALG_HMAC,        "HMAC"},
146   { 0, NULL}
147 };
148
149 #define KRB_SEAL_ALG_DES_CBC    0x0000
150 #define KRB_SEAL_ALG_RC4        0x0010
151 #define KRB_SEAL_ALG_NONE       0xffff
152
153 static const value_string spnego_krb5_seal_alg_vals[] = {
154   { KRB_SEAL_ALG_DES_CBC, "DES CBC"},
155   { KRB_SEAL_ALG_RC4,     "RC4"},
156   { KRB_SEAL_ALG_NONE,    "None"},
157   { 0, NULL}
158 };
159
160 /*
161  * XXX - is this for SPNEGO or just GSS-API?
162  * RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
163  * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
164  * than designating SPNEGO as the mechanism, offering Kerberos V5, and
165  * getting it accepted.
166  */
167 static int
168 dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
169 static int
170 dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 token_id);
171 static int
172 dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
173 static int
174 dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 token_id);
175
176 static void
177 dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
178 {
179         proto_item *item;
180         proto_tree *subtree;
181         int offset = 0;
182         guint16 token_id;
183         const char *oid;
184         gssapi_oid_value *value;
185         tvbuff_t *krb5_tvb;
186         gint8 class;
187         gboolean pc, ind = 0;
188         gint32 tag;
189         guint32 len;
190         asn1_ctx_t asn1_ctx;
191         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
192
193         item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset,
194                                    -1, FALSE);
195
196         subtree = proto_item_add_subtree(item, ett_spnego_krb5);
197
198         /*
199          * The KRB5 blob conforms to RFC1964:
200          * [APPLICATION 0] {
201          *   OID,
202          *   USHORT (0x0001 == AP-REQ, 0x0002 == AP-REP, 0x0003 == ERROR),
203          *   OCTET STRING }
204          *
205          * However, for some protocols, the KRB5 blob starts at the SHORT
206          * and has no DER encoded header etc.
207          *
208          * It appears that for some other protocols the KRB5 blob is just
209          * a Kerberos message, with no [APPLICATION 0] header, no OID,
210          * and no USHORT.
211          *
212          * So:
213          *
214          *      If we see an [APPLICATION 0] HEADER, we show the OID and
215          *      the USHORT, and then dissect the rest as a Kerberos message.
216          *
217          *      If we see an [APPLICATION 14] or [APPLICATION 15] header,
218          *      we assume it's an AP-REQ or AP-REP message, and dissect
219          *      it all as a Kerberos message.
220          *
221          *      Otherwise, we show the USHORT, and then dissect the rest
222          *      as a Kerberos message.
223          */
224
225         /*
226          * Get the first header ...
227          */
228         get_ber_identifier(tvb, offset, &class, &pc, &tag);
229         if (class == BER_CLASS_APP && pc) {
230             /*
231              * [APPLICATION <tag>]
232              */
233             offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &class, &pc, &tag);
234             offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind);
235
236             switch (tag) {
237
238             case 0:
239                 /*
240                  * [APPLICATION 0]
241                  */
242
243                 /* Next, the OID */
244                 offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, tvb, offset, hf_spnego_krb5_oid, &oid);
245
246                 value = gssapi_lookup_oid_str(oid);
247
248                 token_id = tvb_get_letohs(tvb, offset);
249                 proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
250                                     token_id);
251
252                 offset += 2;
253
254                 break;
255
256             case 14:    /* [APPLICATION 14] */
257             case 15:    /* [APPLICATION 15] */
258                 /*
259                  * No token ID - just dissect as a Kerberos message and
260                  * return.
261                  */
262                 offset = dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL);
263                 return;
264
265             default:
266                 proto_tree_add_text(subtree, tvb, offset, 0,
267                         "Unknown header (class=%d, pc=%d, tag=%d)",
268                         class, pc, tag);
269                 goto done;
270             }
271         } else {
272             /* Next, the token ID ... */
273
274             token_id = tvb_get_letohs(tvb, offset);
275             proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
276                                 token_id);
277
278             offset += 2;
279         }
280
281         switch (token_id) {
282
283         case KRB_TOKEN_AP_REQ:
284         case KRB_TOKEN_AP_REP:
285         case KRB_TOKEN_AP_ERR:
286           krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
287           offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
288           break;
289
290         case KRB_TOKEN_GETMIC:
291           offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree);
292           break;
293
294         case KRB_TOKEN_WRAP:
295           offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
296           break;
297
298         case KRB_TOKEN_DELETE_SEC_CONTEXT:
299
300           break;
301
302         case KRB_TOKEN_CFX_GETMIC:
303           offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree);
304           break;
305
306         case KRB_TOKEN_CFX_WRAP:
307           offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id);
308           break;
309
310         default:
311
312           break;
313         }
314
315  done:
316         proto_item_set_len(item, offset);
317         return;
318 }
319
320 #ifdef HAVE_KERBEROS
321 #include <epan/crypt/crypt-md5.h>
322
323 #ifndef KEYTYPE_ARCFOUR_56
324 # define KEYTYPE_ARCFOUR_56 24
325 #endif
326 /* XXX - We should probably do a configure-time check for this instead */
327 #ifndef KRB5_KU_USAGE_SEAL
328 # define KRB5_KU_USAGE_SEAL 22
329 #endif
330
331 static int
332 arcfour_mic_key(void *key_data, size_t key_size, int key_type,
333                 void *cksum_data, size_t cksum_size,
334                 void *key6_data)
335 {
336     guint8 k5_data[16];
337     guint8 T[4];
338
339     memset(T, 0, 4);
340
341     if (key_type == KEYTYPE_ARCFOUR_56) {
342         guint8 L40[14] = "fortybits";
343
344         memcpy(L40 + 10, T, sizeof(T));
345         md5_hmac(
346                 L40, 14,
347                 key_data,
348                 key_size,
349                 k5_data);
350         memset(&k5_data[7], 0xAB, 9);
351     } else {
352         md5_hmac(
353                 T, 4,
354                 key_data,
355                 key_size,
356                 k5_data);
357     }
358
359     md5_hmac(
360         cksum_data, cksum_size,
361         k5_data,
362         16,
363         key6_data);
364
365     return 0;
366 }
367
368 static int
369 usage2arcfour(int usage)
370 {
371     switch (usage) {
372     case 3: /*KRB5_KU_AS_REP_ENC_PART 3 */
373     case 9: /*KRB5_KU_TGS_REP_ENC_PART_SUB_KEY 9 */
374         return 8;
375     case 22: /*KRB5_KU_USAGE_SEAL 22 */
376         return 13;
377     case 23: /*KRB5_KU_USAGE_SIGN 23 */
378         return 15;
379     case 24: /*KRB5_KU_USAGE_SEQ 24 */
380         return 0;
381     default :
382         return 0;
383     }
384 }
385
386 static int
387 arcfour_mic_cksum(guint8 *key_data, int key_length,
388                   unsigned usage,
389                   guint8 sgn_cksum[8],
390                   const void *v1, size_t l1,
391                   const void *v2, size_t l2,
392                   const void *v3, size_t l3)
393 {
394     const guint8 signature[] = "signaturekey";
395     guint8 ksign_c[16];
396     unsigned char t[4];
397     md5_state_t ms;
398     unsigned char digest[16];
399     int rc4_usage;
400     guint8 cksum[16];
401
402     rc4_usage=usage2arcfour(usage);
403     md5_hmac(signature, sizeof(signature),
404                 key_data, key_length,
405                 ksign_c);
406     md5_init(&ms);
407     t[0] = (rc4_usage >>  0) & 0xFF;
408     t[1] = (rc4_usage >>  8) & 0xFF;
409     t[2] = (rc4_usage >> 16) & 0xFF;
410     t[3] = (rc4_usage >> 24) & 0xFF;
411     md5_append(&ms, t, 4);
412     md5_append(&ms, v1, l1);
413     md5_append(&ms, v2, l2);
414     md5_append(&ms, v3, l3);
415     md5_finish(&ms, digest);
416     md5_hmac(digest, 16, ksign_c, 16, cksum);
417
418     memcpy(sgn_cksum, cksum, 8);
419
420     return 0;
421 }
422
423 /*
424  * Verify padding of a gss wrapped message and return its length.
425  */
426 static int
427 gssapi_verify_pad(unsigned char *wrapped_data, int wrapped_length,
428                    size_t datalen,
429                    size_t *padlen)
430 {
431     unsigned char *pad;
432     size_t padlength;
433     int i;
434
435     pad = wrapped_data + wrapped_length - 1;
436     padlength = *pad;
437
438     if (padlength > datalen)
439         return 1;
440
441     for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
442         ;
443     if (i != 0)
444         return 2;
445
446     *padlen = padlength;
447
448     return 0;
449 }
450
451 static int
452 decrypt_arcfour(packet_info *pinfo,
453          guint8 *input_message_buffer,
454          guint8 *output_message_buffer,
455          guint8 *key_value, int key_size, int key_type)
456 {
457     guint8 Klocaldata[16];
458     int ret;
459     gint32 seq_number;
460     size_t datalen;
461     guint8 k6_data[16];
462     guint32 SND_SEQ[2];
463     guint8 Confounder[8];
464     guint8 cksum_data[8];
465     int cmp;
466     int conf_flag;
467     size_t padlen = 0;
468
469     datalen = tvb_length(pinfo->gssapi_encrypted_tvb);
470
471     if(tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 4)==0x1000){
472         conf_flag=1;
473     } else if (tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 4)==0xffff){
474         conf_flag=0;
475     } else {
476         return -3;
477     }
478
479     if(tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 6)!=0xffff){
480         return -4;
481     }
482
483     ret = arcfour_mic_key(key_value, key_size, key_type,
484                           (void *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
485                           8, /* SGN_CKSUM */
486                           k6_data);
487     if (ret) {
488         return -5;
489     }
490
491     {
492         rc4_state_struct rc4_state;
493
494         crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
495         memcpy(SND_SEQ, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 8, 8), 8);
496         crypt_rc4(&rc4_state, (unsigned char *)SND_SEQ, 8);
497
498         memset(k6_data, 0, sizeof(k6_data));
499     }
500
501     seq_number=g_ntohl(SND_SEQ[0]);
502
503     if (SND_SEQ[1] != 0xFFFFFFFF && SND_SEQ[1] != 0x00000000) {
504         return -6;
505     }
506
507     {
508         int i;
509
510         for (i = 0; i < 16; i++)
511             Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0;
512     }
513     ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type,
514                           (unsigned char *)SND_SEQ, 4,
515                           k6_data);
516     memset(Klocaldata, 0, sizeof(Klocaldata));
517     if (ret) {
518         return -7;
519     }
520
521     if(conf_flag) {
522         rc4_state_struct rc4_state;
523
524         crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
525         memcpy(Confounder, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8), 8);
526         crypt_rc4(&rc4_state, Confounder, 8);
527         memcpy(output_message_buffer, input_message_buffer, datalen);
528         crypt_rc4(&rc4_state, output_message_buffer, datalen);
529     } else {
530         memcpy(Confounder,
531                 tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8),
532                 8); /* Confounder */
533         memcpy(output_message_buffer,
534                 input_message_buffer,
535                 datalen);
536     }
537     memset(k6_data, 0, sizeof(k6_data));
538
539     /* only normal (i.e. non DCE style  wrapping use padding ? */
540     if(pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){
541         ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen);
542         if (ret) {
543             return -9;
544         }
545         datalen -= padlen;
546     }
547
548     /* dont know what the checksum looks like for dce style gssapi */
549     if(pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){
550         ret = arcfour_mic_cksum(key_value, key_size,
551                             KRB5_KU_USAGE_SEAL,
552                             cksum_data,
553                             tvb_get_ptr(pinfo->gssapi_wrap_tvb, 0, 8), 8,
554                             Confounder, sizeof(Confounder),
555                             output_message_buffer,
556                             datalen + padlen);
557         if (ret) {
558             return -10;
559         }
560
561         cmp = memcmp(cksum_data,
562             tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
563             8); /* SGN_CKSUM */
564         if (cmp) {
565             return -11;
566         }
567     }
568
569     return datalen;
570 }
571
572
573
574 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
575
576 static void
577 decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int keytype)
578 {
579         int ret;
580         enc_key_t *ek;
581         int length;
582         const guint8 *original_data;
583
584         static int omb_index=0;
585         static guint8 *omb_arr[4]={NULL,NULL,NULL,NULL};
586         static guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */
587         guint8 *output_message_buffer;
588
589         omb_index++;
590         if(omb_index>=4){
591                 omb_index=0;
592         }
593         output_message_buffer=omb_arr[omb_index];
594
595
596         length=tvb_length(pinfo->gssapi_encrypted_tvb);
597         original_data=tvb_get_ptr(pinfo->gssapi_encrypted_tvb, 0, length);
598
599         /* dont do anything if we are not attempting to decrypt data */
600 /*
601         if(!krb_decrypt){
602                 return;
603         }
604 */
605         /* XXX we should only do this for first time, then store somewhere */
606         /* XXX We also need to re-read the keytab when the preference changes */
607
608         cryptocopy=ep_alloc(length);
609         if(output_message_buffer){
610                 g_free(output_message_buffer);
611                 output_message_buffer=NULL;
612         }
613         output_message_buffer=g_malloc(length);
614
615         for(ek=enc_key_list;ek;ek=ek->next){
616                 /* shortcircuit and bail out if enctypes are not matching */
617                 if(ek->keytype!=keytype){
618                         continue;
619                 }
620
621                 /* pre-0.6.1 versions of Heimdal would sometimes change
622                   the cryptotext data even when the decryption failed.
623                   This would obviously not work since we iterate over the
624                   keys. So just give it a copy of the crypto data instead.
625                   This has been seen for RC4-HMAC blobs.
626                 */
627                 memcpy(cryptocopy, original_data, length);
628                 ret=decrypt_arcfour(pinfo,
629                                 cryptocopy,
630                                 output_message_buffer,
631                                 ek->keyvalue,
632                                 ek->keylength,
633                                 ek->keytype
634                                             );
635                 if (ret >= 0) {
636                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
637                         pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb, 
638                                 output_message_buffer,
639                                 ret, ret);
640                         add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
641                         return;
642                 }
643         }
644         return;
645 }
646
647 /* borrowed from heimdal */
648 static int
649 rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
650 {
651         unsigned char *tmp, buf[256];
652         size_t left;
653
654         if (len == 0)
655                 return 0;
656
657         rrc %= len;
658
659         if (rrc == 0)
660                 return 0;
661
662         left = len - rrc;
663
664         if (rrc <= sizeof(buf)) {
665                 tmp = buf;
666         } else {
667                 tmp = g_malloc(rrc);
668                 if (tmp == NULL)
669                         return -1;
670         }
671
672         if (unrotate) {
673                 memcpy(tmp, data, rrc);
674                 memmove(data, (unsigned char *)data + rrc, left);
675                 memcpy((unsigned char *)data + left, tmp, rrc);
676         } else {
677                 memcpy(tmp, (unsigned char *)data + left, rrc);
678                 memmove((unsigned char *)data + rrc, data, left);
679                 memcpy(data, tmp, rrc);
680         }
681
682         if (rrc > sizeof(buf))
683                 g_free(tmp);
684
685         return 0;
686 }
687
688
689 #define KRB5_KU_USAGE_ACCEPTOR_SEAL     22
690 #define KRB5_KU_USAGE_ACCEPTOR_SIGN     23
691 #define KRB5_KU_USAGE_INITIATOR_SEAL    24
692 #define KRB5_KU_USAGE_INITIATOR_SIGN    25
693
694 static void
695 decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_,
696                             packet_info *pinfo,
697                             tvbuff_t *checksum_tvb,
698                             tvbuff_t *encrypted_tvb,
699                             guint16 ec,
700                             guint16 rrc,
701                             gboolean is_dce,
702                             int keytype,
703                             unsigned int usage)
704 {
705         int res;
706         char *rotated;
707         char *output;
708         int datalen;
709
710         /* dont do anything if we are not attempting to decrypt data */
711         if(!krb_decrypt){
712                 return;
713         }
714
715         datalen = tvb_length(checksum_tvb) + tvb_length(encrypted_tvb);
716         rotated = ep_alloc(datalen);
717
718         tvb_memcpy(checksum_tvb, rotated,
719                    0, tvb_length(checksum_tvb));
720         tvb_memcpy(encrypted_tvb, rotated + tvb_length(checksum_tvb),
721                    0, tvb_length(encrypted_tvb));
722
723         if (is_dce) {
724                 rrc += ec;
725         }
726
727         res = rrc_rotate(rotated, datalen, rrc, TRUE);
728
729         output = decrypt_krb5_data(tree, pinfo, usage, datalen,
730                   rotated, keytype, &datalen);
731
732         if (output) {
733                 char *outdata;
734
735                 outdata = ep_alloc(tvb_length(encrypted_tvb));
736                 memcpy(outdata, output, tvb_length(encrypted_tvb));
737                 g_free(output);
738
739                 pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(encrypted_tvb,
740                         outdata,
741                         tvb_length(encrypted_tvb),
742                         tvb_length(encrypted_tvb));
743                 add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
744                 return;
745         }
746         return;
747 }
748
749 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
750
751
752 #endif
753
754 /*
755  * This is for GSSAPI Wrap tokens ...
756  */
757 static int
758 dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
759 #ifndef HAVE_KERBEROS
760         _U_
761 #endif
762     , proto_tree *tree, guint16 token_id
763 #ifndef HAVE_KERBEROS
764         _U_
765 #endif
766     )
767 {
768         guint16 sgn_alg, seal_alg;
769 #ifdef HAVE_KERBEROS
770         int start_offset=offset;
771 #endif
772
773         /*
774          * The KRB5 blob conforms to RFC1964:
775          *   USHORT (0x0102 == GSS_Wrap)
776          *   and so on }
777          */
778
779         /* Now, the sign and seal algorithms ... */
780
781         sgn_alg = tvb_get_letohs(tvb, offset);
782         proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
783                             sgn_alg);
784
785         offset += 2;
786
787         seal_alg = tvb_get_letohs(tvb, offset);
788         proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2,
789                             seal_alg);
790
791         offset += 2;
792
793         /* Skip the filler */
794
795         offset += 2;
796
797         /* Encrypted sequence number */
798
799         proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
800                             TRUE);
801
802         offset += 8;
803
804         /* Checksum of plaintext padded data */
805
806         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
807                             TRUE);
808
809         offset += 8;
810
811         /*
812          * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
813          * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
814          * extra 8 bytes of "Random confounder" after the checksum.
815          * It certainly confounds code expecting all Kerberos 5
816          * GSS_Wrap() tokens to look the same....
817          */
818         if ((sgn_alg == KRB_SGN_ALG_HMAC) ||
819             /* there also seems to be a confounder for DES MAC MD5 - certainly seen when using with
820                SASL with LDAP between a Java client and Active Directory. If this breaks other things
821                we may need to make this an option. gal 17/2/06 */
822             (sgn_alg == KRB_SGN_ALG_DES_MAC_MD5)) {
823           proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
824                               TRUE);
825           offset += 8;
826         }
827
828         /* Is the data encrypted? */
829         pinfo->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE);
830
831 #ifdef HAVE_KERBEROS
832 #define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
833         if(pinfo->decrypt_gssapi_tvb){
834                 /* if the caller did not provide a tvb, then we just use
835                    whatever is left of our current tvb.
836                 */
837                 if(!pinfo->gssapi_encrypted_tvb){
838                         int len;
839                         len=tvb_reported_length_remaining(tvb,offset);
840                         if(len>tvb_length_remaining(tvb, offset)){
841                                 /* no point in trying to decrypt,
842                                    we dont have the full pdu.
843                                 */
844                                 return offset;
845                         }
846                         pinfo->gssapi_encrypted_tvb = tvb_new_subset(
847                                         tvb, offset, len, len);
848                 }
849
850                 /* if this is KRB5 wrapped rc4-hmac */
851                 if((token_id==KRB_TOKEN_WRAP)
852                  &&(sgn_alg==KRB_SGN_ALG_HMAC)
853                  &&(seal_alg==KRB_SEAL_ALG_RC4)){
854                         /* do we need to create a tvb for the wrapper
855                            as well ?
856                         */
857                         if(!pinfo->gssapi_wrap_tvb){
858                                 pinfo->gssapi_wrap_tvb = tvb_new_subset(
859                                         tvb, start_offset-2,
860                                         GSS_ARCFOUR_WRAP_TOKEN_SIZE,
861                                         GSS_ARCFOUR_WRAP_TOKEN_SIZE);
862                         }
863 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
864                         decrypt_gssapi_krb_arcfour_wrap(tree,
865                                 pinfo,
866                                 tvb,
867                                 23 /* rc4-hmac */);
868 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
869                 }
870         }
871 #endif
872         /*
873          * Return the offset past the checksum, so that we know where
874          * the data we're wrapped around starts.  Also, set the length
875          * of our top-level item to that offset, so it doesn't cover
876          * the data we're wrapped around.
877          *
878          * Note that for DCERPC the GSSAPI blobs comes after the data it wraps,
879          * not before.
880          */
881         return offset;
882 }
883
884 /*
885  * XXX - This is for GSSAPI GetMIC tokens ...
886  */
887 static int
888 dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
889 {
890         guint16 sgn_alg;
891
892         /*
893          * The KRB5 blob conforms to RFC1964:
894          *   USHORT (0x0101 == GSS_GetMIC)
895          *   and so on }
896          */
897
898         /* Now, the sign algorithm ... */
899
900         sgn_alg = tvb_get_letohs(tvb, offset);
901         proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
902                             sgn_alg);
903
904         offset += 2;
905
906         /* Skip the filler */
907
908         offset += 4;
909
910         /* Encrypted sequence number */
911
912         proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
913                             TRUE);
914
915         offset += 8;
916
917         /* Checksum of plaintext padded data */
918
919         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
920                             TRUE);
921
922         offset += 8;
923
924         /*
925          * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
926          * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
927          * extra 8 bytes of "Random confounder" after the checksum.
928          * It certainly confounds code expecting all Kerberos 5
929          * GSS_Wrap() tokens to look the same....
930          *
931          * The exception is DNS/TSIG where there is no such confounder
932          * so we need to test here if there are more bytes in our tvb or not.
933          *  -- ronnie
934          */
935         if (tvb_length_remaining(tvb, offset)) {
936           if (sgn_alg == KRB_SGN_ALG_HMAC) {
937             proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
938                               TRUE);
939
940             offset += 8;
941           }
942         }
943
944         /*
945          * Return the offset past the checksum, so that we know where
946          * the data we're wrapped around starts.  Also, set the length
947          * of our top-level item to that offset, so it doesn't cover
948          * the data we're wrapped around.
949          */
950
951         return offset;
952 }
953
954 static int
955 dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset,
956                               proto_tree *spnego_krb5_tree,
957                               guint8 cfx_flags)
958 {
959         proto_tree *cfx_flags_tree = NULL;
960         proto_item *tf = NULL;
961
962         if (spnego_krb5_tree) {
963                 tf = proto_tree_add_uint(spnego_krb5_tree,
964                                          hf_spnego_krb5_cfx_flags,
965                                          tvb, offset, 1, cfx_flags);
966                 cfx_flags_tree = proto_item_add_subtree(tf, ett_spnego_krb5_cfx_flags);
967         }
968
969         proto_tree_add_boolean(cfx_flags_tree,
970                                hf_spnego_krb5_cfx_flags_04,
971                                tvb, offset, 1, cfx_flags);
972         proto_tree_add_boolean(cfx_flags_tree,
973                                hf_spnego_krb5_cfx_flags_02,
974                                tvb, offset, 1, cfx_flags);
975         proto_tree_add_boolean(cfx_flags_tree,
976                                hf_spnego_krb5_cfx_flags_01,
977                                tvb, offset, 1, cfx_flags);
978
979         return (offset + 1);
980 }
981
982 /*
983  * This is for GSSAPI CFX Wrap tokens ...
984  */
985 static int
986 dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
987 #ifndef HAVE_KERBEROS
988         _U_
989 #endif
990     , proto_tree *tree, guint16 token_id _U_
991     )
992 {
993         guint8 flags;
994         guint16 ec;
995         guint16 rrc;
996         int checksum_size;
997         int start_offset=offset;
998
999         /*
1000          * The KRB5 blob conforms to RFC4121:
1001          *   USHORT (0x0504)
1002          *   and so on }
1003          */
1004
1005         /* Now, the sign and seal algorithms ... */
1006
1007         flags = tvb_get_guint8(tvb, offset);
1008         offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags);
1009
1010         pinfo->gssapi_data_encrypted=(flags & 2);
1011
1012         /* Skip the filler */
1013
1014         proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 1,
1015                             FALSE);
1016         offset += 1;
1017
1018         /* EC */
1019         ec = tvb_get_ntohs(tvb, offset);
1020         proto_tree_add_item(tree, hf_spnego_krb5_cfx_ec, tvb, offset, 2,
1021                             FALSE);
1022         offset += 2;
1023
1024         /* RRC */
1025         rrc = tvb_get_ntohs(tvb, offset);
1026         proto_tree_add_item(tree, hf_spnego_krb5_cfx_rrc, tvb, offset, 2,
1027                             FALSE);
1028         offset += 2;
1029
1030         /* sequence number */
1031
1032         proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
1033                             FALSE);
1034         offset += 8;
1035
1036         /* Checksum of plaintext padded data */
1037
1038         if (pinfo->gssapi_data_encrypted) {
1039                 checksum_size = 44 + ec;
1040         } else {
1041                 checksum_size = 12;
1042         }
1043
1044         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
1045                             checksum_size, FALSE);
1046         offset += checksum_size;
1047
1048         if(pinfo->decrypt_gssapi_tvb){
1049                 /* if the caller did not provide a tvb, then we just use
1050                    whatever is left of our current tvb.
1051                 */
1052                 if(!pinfo->gssapi_encrypted_tvb){
1053                         int len;
1054                         len=tvb_reported_length_remaining(tvb,offset);
1055                         if(len>tvb_length_remaining(tvb, offset)){
1056                                 /* no point in trying to decrypt,
1057                                    we dont have the full pdu.
1058                                 */
1059                                 return offset;
1060                         }
1061                         pinfo->gssapi_encrypted_tvb = tvb_new_subset(
1062                                         tvb, offset, len, len);
1063                 }
1064
1065                 if (pinfo->gssapi_data_encrypted) {
1066                         /* do we need to create a tvb for the wrapper
1067                            as well ?
1068                         */
1069                         if(!pinfo->gssapi_wrap_tvb){
1070                                 pinfo->gssapi_wrap_tvb = tvb_new_subset(
1071                                         tvb, start_offset-2,
1072                                         offset - (start_offset-2),
1073                                         offset - (start_offset-2));
1074                         }
1075                 }
1076         }
1077
1078 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
1079 {
1080         tvbuff_t *checksum_tvb = tvb_new_subset(tvb, 16, checksum_size, checksum_size);
1081
1082         if (pinfo->gssapi_data_encrypted) {
1083                 if(pinfo->gssapi_encrypted_tvb){
1084                         decrypt_gssapi_krb_cfx_wrap(tree,
1085                                 pinfo,
1086                                 checksum_tvb,
1087                                 pinfo->gssapi_encrypted_tvb,
1088                                 ec,
1089                                 rrc,
1090                                 (pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE)?TRUE:FALSE,
1091                                 -1,
1092                                 (flags & 0x0001)?
1093                                 KRB5_KU_USAGE_ACCEPTOR_SEAL:
1094                                 KRB5_KU_USAGE_INITIATOR_SEAL);
1095                 }
1096         }
1097 }
1098 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
1099
1100         /*
1101          * Return the offset past the checksum, so that we know where
1102          * the data we're wrapped around starts.  Also, set the length
1103          * of our top-level item to that offset, so it doesn't cover
1104          * the data we're wrapped around.
1105          *
1106          * Note that for DCERPC the GSSAPI blobs comes after the data it wraps,
1107          * not before.
1108          */
1109         return offset;
1110 }
1111
1112 /*
1113  * XXX - This is for GSSAPI CFX GetMIC tokens ...
1114  */
1115 static int
1116 dissect_spnego_krb5_cfx_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
1117 {
1118         guint8 flags;
1119         int checksum_size;
1120
1121         /*
1122          * The KRB5 blob conforms to RFC4121:
1123          *   USHORT (0x0404 == GSS_GetMIC)
1124          *   and so on }
1125          */
1126
1127         flags = tvb_get_guint8(tvb, offset);
1128         offset = dissect_spnego_krb5_cfx_flags(tvb, offset, tree, flags);
1129
1130         /* Skip the filler */
1131
1132         proto_tree_add_item(tree, hf_spnego_krb5_filler, tvb, offset, 5,
1133                             FALSE);
1134         offset += 5;
1135
1136         /* sequence number */
1137
1138         proto_tree_add_item(tree, hf_spnego_krb5_cfx_seq, tvb, offset, 8,
1139                             FALSE);
1140         offset += 8;
1141
1142         /* Checksum of plaintext padded data */
1143
1144         checksum_size = tvb_length_remaining(tvb, offset);
1145
1146         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset,
1147                             checksum_size, FALSE);
1148         offset += checksum_size;
1149
1150         /*
1151          * Return the offset past the checksum, so that we know where
1152          * the data we're wrapped around starts.  Also, set the length
1153          * of our top-level item to that offset, so it doesn't cover
1154          * the data we're wrapped around.
1155          */
1156
1157         return offset;
1158 }
1159
1160 /*
1161  * XXX - is this for SPNEGO or just GSS-API?
1162  * RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
1163  * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
1164  * than designating SPNEGO as the mechanism, offering Kerberos V5, and
1165  * getting it accepted.
1166  */
1167 static int
1168 dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1169 {
1170         proto_item *item;
1171         proto_tree *subtree;
1172         int offset = 0;
1173         guint16 token_id;
1174
1175         item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, FALSE);
1176
1177         subtree = proto_item_add_subtree(item, ett_spnego_krb5);
1178
1179         /*
1180          * The KRB5 blob conforms to RFC1964:
1181          *   USHORT (0x0102 == GSS_Wrap)
1182          *   and so on }
1183          */
1184
1185         /* First, the token ID ... */
1186
1187         token_id = tvb_get_letohs(tvb, offset);
1188         proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
1189                             token_id);
1190
1191         offset += 2;
1192
1193         switch (token_id) {
1194         case KRB_TOKEN_GETMIC:
1195           offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree);
1196           break;
1197
1198         case KRB_TOKEN_WRAP:
1199           offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
1200           break;
1201
1202         case KRB_TOKEN_CFX_GETMIC:
1203           offset = dissect_spnego_krb5_cfx_getmic_base(tvb, offset, pinfo, subtree);
1204           break;
1205
1206         case KRB_TOKEN_CFX_WRAP:
1207           offset = dissect_spnego_krb5_cfx_wrap_base(tvb, offset, pinfo, subtree, token_id);
1208           break;
1209
1210         default:
1211
1212           break;
1213         }
1214
1215         /*
1216          * Return the offset past the checksum, so that we know where
1217          * the data we're wrapped around starts.  Also, set the length
1218          * of our top-level item to that offset, so it doesn't cover
1219          * the data we're wrapped around.
1220          */
1221         proto_item_set_len(item, offset);
1222         return offset;
1223 }
1224
1225 /* Spnego stuff from here */
1226
1227 static int
1228 dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1229 {
1230         proto_item *item;
1231         proto_tree *subtree;
1232         int offset = 0;
1233         asn1_ctx_t asn1_ctx;
1234         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1235
1236
1237
1238         /*
1239          * We need this later, so lets get it now ...
1240          * It has to be per-frame as there can be more than one GSS-API
1241          * negotiation in a conversation.
1242          */
1243
1244
1245         item = proto_tree_add_item(tree, hf_spnego, tvb, offset,
1246                                    -1, FALSE);
1247
1248         subtree = proto_item_add_subtree(item, ett_spnego);
1249         /*
1250          * The TVB contains a [0] header and a sequence that consists of an
1251          * object ID and a blob containing the data ...
1252          * XXX - is this RFC 2743's "Mechanism-Independent Token Format",
1253          * with the "optional" "use in non-initial tokens" being chosen.
1254          * ASN1 code addet to spnego.asn to handle this.
1255          */
1256
1257         offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, &asn1_ctx , subtree, -1);
1258
1259         return offset;
1260 }
1261
1262
1263 static void
1264 dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1265 {
1266         proto_item *item;
1267         proto_tree *subtree;
1268         int offset = 0;
1269         conversation_t *conversation;
1270         asn1_ctx_t asn1_ctx;
1271         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
1272
1273         /*
1274          * We need this later, so lets get it now ...
1275          * It has to be per-frame as there can be more than one GSS-API
1276          * negotiation in a conversation.
1277          */
1278         next_level_value = p_get_proto_data(pinfo->fd, proto_spnego);
1279         if (!next_level_value && !pinfo->fd->flags.visited) {
1280             /*
1281              * No handle attached to this frame, but it's the first
1282              * pass, so it'd be attached to the conversation.
1283              * If we have a conversation, try to get the handle,
1284              * and if we get one, attach it to the frame.
1285              */
1286             conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1287                                              pinfo->ptype, pinfo->srcport,
1288                                              pinfo->destport, 0);
1289
1290             if (conversation) {
1291                 next_level_value = conversation_get_proto_data(conversation,
1292                                                                proto_spnego);
1293                 if (next_level_value)
1294                     p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
1295             }
1296         }
1297
1298         item = proto_tree_add_item(parent_tree, hf_spnego, tvb, offset,
1299                                    -1, FALSE);
1300
1301         subtree = proto_item_add_subtree(item, ett_spnego);
1302
1303         /*
1304          * The TVB contains a [0] header and a sequence that consists of an
1305          * object ID and a blob containing the data ...
1306          * Actually, it contains, according to RFC2478:
1307          * NegotiationToken ::= CHOICE {
1308          *          negTokenInit [0] NegTokenInit,
1309          *          negTokenTarg [1] NegTokenTarg }
1310          * NegTokenInit ::= SEQUENCE {
1311          *          mechTypes [0] MechTypeList OPTIONAL,
1312          *          reqFlags [1] ContextFlags OPTIONAL,
1313          *          mechToken [2] OCTET STRING OPTIONAL,
1314          *          mechListMIC [3] OCTET STRING OPTIONAL }
1315          * NegTokenTarg ::= SEQUENCE {
1316          *          negResult [0] ENUMERATED {
1317          *              accept_completed (0),
1318          *              accept_incomplete (1),
1319          *              reject (2) } OPTIONAL,
1320          *          supportedMech [1] MechType OPTIONAL,
1321          *          responseToken [2] OCTET STRING OPTIONAL,
1322          *          mechListMIC [3] OCTET STRING OPTIONAL }
1323          *
1324          * Windows typically includes mechTypes and mechListMic ('NONE'
1325          * in the case of NTLMSSP only).
1326          * It seems to duplicate the responseToken into the mechListMic field
1327          * as well. Naughty, naughty.
1328          *
1329          */
1330         offset = dissect_spnego_NegotiationToken(FALSE, tvb, offset, &asn1_ctx, subtree, -1);
1331
1332 }
1333
1334 /*--- proto_register_spnego -------------------------------------------*/
1335 void proto_register_spnego(void) {
1336
1337         /* List of fields */
1338         static hf_register_info hf[] = {
1339                 { &hf_spnego,
1340                   { "SPNEGO", "spnego", FT_NONE, BASE_NONE, NULL, 0x0,
1341                     NULL, HFILL }},
1342                 { &hf_spnego_wraptoken,
1343                   { "wrapToken", "spnego.wraptoken",
1344                     FT_NONE, BASE_NONE, NULL, 0x0, "SPNEGO wrapToken",
1345                     HFILL}},
1346                 { &hf_spnego_krb5,
1347                   { "krb5_blob", "spnego.krb5.blob", FT_BYTES,
1348                     BASE_NONE, NULL, 0, NULL, HFILL }},
1349                 { &hf_spnego_krb5_oid,
1350                   { "KRB5 OID", "spnego.krb5_oid", FT_STRING,
1351                     BASE_NONE, NULL, 0, NULL, HFILL }},
1352                 { &hf_spnego_krb5_tok_id,
1353                   { "krb5_tok_id", "spnego.krb5.tok_id", FT_UINT16, BASE_HEX,
1354                     VALS(spnego_krb5_tok_id_vals), 0, "KRB5 Token Id", HFILL}},
1355                 { &hf_spnego_krb5_sgn_alg,
1356                   { "krb5_sgn_alg", "spnego.krb5.sgn_alg", FT_UINT16, BASE_HEX,
1357                     VALS(spnego_krb5_sgn_alg_vals), 0, "KRB5 Signing Algorithm", HFILL}},
1358                 { &hf_spnego_krb5_seal_alg,
1359                   { "krb5_seal_alg", "spnego.krb5.seal_alg", FT_UINT16, BASE_HEX,
1360                     VALS(spnego_krb5_seal_alg_vals), 0, "KRB5 Sealing Algorithm", HFILL}},
1361                 { &hf_spnego_krb5_snd_seq,
1362                   { "krb5_snd_seq", "spnego.krb5.snd_seq", FT_BYTES, BASE_NONE,
1363                     NULL, 0, "KRB5 Encrypted Sequence Number", HFILL}},
1364                 { &hf_spnego_krb5_sgn_cksum,
1365                   { "krb5_sgn_cksum", "spnego.krb5.sgn_cksum", FT_BYTES, BASE_NONE,
1366                     NULL, 0, "KRB5 Data Checksum", HFILL}},
1367                 { &hf_spnego_krb5_confounder,
1368                   { "krb5_confounder", "spnego.krb5.confounder", FT_BYTES, BASE_NONE,
1369                     NULL, 0, "KRB5 Confounder", HFILL}},
1370                 { &hf_spnego_krb5_filler,
1371                   { "krb5_filler", "spnego.krb5.filler", FT_BYTES, BASE_NONE,
1372                     NULL, 0, "KRB5 Filler", HFILL}},
1373                 { &hf_spnego_krb5_cfx_flags,
1374                   { "krb5_cfx_flags", "spnego.krb5.cfx_flags", FT_UINT8, BASE_HEX,
1375                     NULL, 0, "KRB5 CFX Flags", HFILL}},
1376                 { &hf_spnego_krb5_cfx_flags_01,
1377                   { "SendByAcceptor", "spnego.krb5.send_by_acceptor", FT_BOOLEAN, 8,
1378                     TFS (&tfs_set_notset), 0x01, NULL, HFILL}},
1379                 { &hf_spnego_krb5_cfx_flags_02,
1380                   { "Sealed", "spnego.krb5.sealed", FT_BOOLEAN, 8,
1381                     TFS (&tfs_set_notset), 0x02, NULL, HFILL}},
1382                 { &hf_spnego_krb5_cfx_flags_04,
1383                   { "AcceptorSubkey", "spnego.krb5.acceptor_subkey", FT_BOOLEAN, 8,
1384                     TFS (&tfs_set_notset), 0x04, NULL, HFILL}},
1385                 { &hf_spnego_krb5_cfx_ec,
1386                   { "krb5_cfx_ec", "spnego.krb5.cfx_ec", FT_UINT16, BASE_DEC,
1387                     NULL, 0, "KRB5 CFX Extra Count", HFILL}},
1388                 { &hf_spnego_krb5_cfx_rrc,
1389                   { "krb5_cfx_rrc", "spnego.krb5.cfx_rrc", FT_UINT16, BASE_DEC,
1390                     NULL, 0, "KRB5 CFX Right Rotation Count", HFILL}},
1391                 { &hf_spnego_krb5_cfx_seq,
1392                   { "krb5_cfx_seq", "spnego.krb5.cfx_seq", FT_UINT64, BASE_DEC,
1393                     NULL, 0, "KRB5 Sequence Number", HFILL}},
1394
1395 #include "packet-spnego-hfarr.c"
1396         };
1397
1398         /* List of subtrees */
1399         static gint *ett[] = {
1400                 &ett_spnego,
1401                 &ett_spnego_wraptoken,
1402                 &ett_spnego_krb5,
1403                 &ett_spnego_krb5_cfx_flags,
1404
1405 #include "packet-spnego-ettarr.c"
1406         };
1407
1408         /* Register protocol */
1409         proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME);
1410
1411         register_dissector("spnego", dissect_spnego, proto_spnego);
1412
1413         proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5",
1414                                                     "SPNEGO-KRB5",
1415                                                     "spnego-krb5");
1416
1417         register_dissector("spnego-krb5", dissect_spnego_krb5, proto_spnego_krb5);
1418         new_register_dissector("spnego-krb5-wrap", dissect_spnego_krb5_wrap, proto_spnego_krb5);
1419
1420         /* Register fields and subtrees */
1421         proto_register_field_array(proto_spnego, hf, array_length(hf));
1422         proto_register_subtree_array(ett, array_length(ett));
1423 }
1424
1425
1426 /*--- proto_reg_handoff_spnego ---------------------------------------*/
1427 void proto_reg_handoff_spnego(void) {
1428
1429         dissector_handle_t spnego_handle, spnego_wrap_handle;
1430         dissector_handle_t spnego_krb5_handle, spnego_krb5_wrap_handle;
1431
1432         /* Register protocol with GSS-API module */
1433
1434         spnego_handle = find_dissector("spnego");
1435         spnego_wrap_handle = new_create_dissector_handle(dissect_spnego_wrap,  proto_spnego);
1436         gssapi_init_oid("1.3.6.1.5.5.2", proto_spnego, ett_spnego,
1437             spnego_handle, spnego_wrap_handle,
1438             "SPNEGO - Simple Protected Negotiation");
1439
1440         /* Register both the one MS created and the real one */
1441         /*
1442          * Thanks to Jean-Baptiste Marchand and Richard B Ward, the
1443          * mystery of the MS KRB5 OID is cleared up. It was due to a library
1444          * that did not handle OID components greater than 16 bits, and was
1445          * fixed in Win2K SP2 as well as WinXP.
1446          * See the archive of <ietf-krb-wg@anl.gov> for the thread topic
1447          * SPNEGO implementation issues. 3-Dec-2002.
1448          */
1449         spnego_krb5_handle = find_dissector("spnego-krb5");
1450         spnego_krb5_wrap_handle = find_dissector("spnego-krb5-wrap");
1451         gssapi_init_oid("1.2.840.48018.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
1452                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1453                         "MS KRB5 - Microsoft Kerberos 5");
1454         gssapi_init_oid("1.2.840.113554.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
1455                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1456                         "KRB5 - Kerberos 5");
1457         gssapi_init_oid("1.2.840.113554.1.2.2.3", proto_spnego_krb5, ett_spnego_krb5,
1458                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1459                         "KRB5 - Kerberos 5 - User to User");
1460
1461 }