Move epan/crypt-md5.[ch] to epan/crypt. Remove
[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 "packet-dcerpc.h"
41 #include "packet-gssapi.h"
42 #include "packet-kerberos.h"
43 #include <epan/crypt-rc4.h>
44 #include <epan/conversation.h>
45 #include <epan/emem.h>
46
47 #include <stdio.h>
48 #include <string.h>
49
50 #include "packet-ber.h"
51
52
53 #define PNAME  "Simple Protected Negotiation"
54 #define PSNAME "SPNEGO"
55 #define PFNAME "spnego"
56
57 /* Initialize the protocol and registered fields */
58 static int proto_spnego = -1;
59 static int proto_spnego_krb5 = -1;
60
61
62 static int hf_spnego = -1;
63 static int hf_spnego_wraptoken = -1;
64 static int hf_spnego_krb5_oid;
65 static int hf_spnego_krb5 = -1;
66 static int hf_spnego_krb5_tok_id = -1;
67 static int hf_spnego_krb5_sgn_alg = -1;
68 static int hf_spnego_krb5_seal_alg = -1;
69 static int hf_spnego_krb5_snd_seq = -1;
70 static int hf_spnego_krb5_sgn_cksum = -1;
71 static int hf_spnego_krb5_confounder = -1;
72
73 #include "packet-spnego-hf.c"
74
75 /* Global variables */
76 static const char *MechType_oid;
77 gssapi_oid_value *next_level_value;
78 gboolean saw_mechanism = FALSE;
79
80
81 /* Initialize the subtree pointers */
82 static gint ett_spnego;
83 static gint ett_spnego_wraptoken;
84 static gint ett_spnego_krb5 = -1;
85
86 #include "packet-spnego-ett.c"
87
88 static dissector_handle_t data_handle;
89
90 /*
91  * Unfortunately, we have to have a forward declaration of this,
92  * as the code generated by asn2wrs includes a call before the
93  * definition.
94  */
95 static int dissect_spnego_PrincipalSeq(gboolean implicit_tag, tvbuff_t *tvb,
96                                        int offset, packet_info *pinfo,
97                                        proto_tree *tree, int hf_index);
98
99 #include "packet-spnego-fn.c"
100 /*
101  * This is the SPNEGO KRB5 dissector. It is not true KRB5, but some ASN.1
102  * wrapped blob with an OID, USHORT token ID, and a Ticket, that is also
103  * ASN.1 wrapped by the looks of it. It conforms to RFC1964.
104  */
105
106 #define KRB_TOKEN_AP_REQ                0x0001
107 #define KRB_TOKEN_AP_REP                0x0002
108 #define KRB_TOKEN_AP_ERR                0x0003
109 #define KRB_TOKEN_GETMIC                0x0101
110 #define KRB_TOKEN_WRAP                  0x0102
111 #define KRB_TOKEN_DELETE_SEC_CONTEXT    0x0201
112
113 static const value_string spnego_krb5_tok_id_vals[] = {
114   { KRB_TOKEN_AP_REQ,             "KRB5_AP_REQ"},
115   { KRB_TOKEN_AP_REP,             "KRB5_AP_REP"},
116   { KRB_TOKEN_AP_ERR,             "KRB5_ERROR"},
117   { KRB_TOKEN_GETMIC,             "KRB5_GSS_GetMIC" },
118   { KRB_TOKEN_WRAP,               "KRB5_GSS_Wrap" },
119   { KRB_TOKEN_DELETE_SEC_CONTEXT, "KRB5_GSS_Delete_sec_context" },
120   { 0, NULL}
121 };
122
123 #define KRB_SGN_ALG_DES_MAC_MD5 0x0000
124 #define KRB_SGN_ALG_MD2_5       0x0001
125 #define KRB_SGN_ALG_DES_MAC     0x0002
126 #define KRB_SGN_ALG_HMAC        0x0011
127
128 static const value_string spnego_krb5_sgn_alg_vals[] = {
129   { KRB_SGN_ALG_DES_MAC_MD5, "DES MAC MD5"},
130   { KRB_SGN_ALG_MD2_5,       "MD2.5"},
131   { KRB_SGN_ALG_DES_MAC,     "DES MAC"},
132   { KRB_SGN_ALG_HMAC,        "HMAC"},
133   { 0, NULL}
134 };
135
136 #define KRB_SEAL_ALG_DES_CBC    0x0000
137 #define KRB_SEAL_ALG_RC4        0x0010
138 #define KRB_SEAL_ALG_NONE       0xffff
139
140 static const value_string spnego_krb5_seal_alg_vals[] = {
141   { KRB_SEAL_ALG_DES_CBC, "DES CBC"},
142   { KRB_SEAL_ALG_RC4,     "RC4"},
143   { KRB_SEAL_ALG_NONE,    "None"},
144   { 0, NULL}
145 };
146
147 /*
148  * XXX - is this for SPNEGO or just GSS-API?
149  * RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
150  * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
151  * than designating SPNEGO as the mechanism, offering Kerberos V5, and
152  * getting it accepted.
153  */
154 static int
155 dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
156 static int
157 dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 token_id);
158
159 static void
160 dissect_spnego_krb5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
161 {
162         proto_item *item;
163         proto_tree *subtree;
164         int offset = 0;
165         guint16 token_id;
166         const char *oid;
167         gssapi_oid_value *value;
168         tvbuff_t *krb5_tvb;
169         gint8 class;
170         gboolean pc, ind = 0;
171         gint32 tag;
172         guint32 len;
173
174         item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, offset,
175                                    -1, FALSE);
176
177         subtree = proto_item_add_subtree(item, ett_spnego_krb5);
178
179         /*
180          * The KRB5 blob conforms to RFC1964:
181          * [APPLICATION 0] {
182          *   OID,
183          *   USHORT (0x0001 == AP-REQ, 0x0002 == AP-REP, 0x0003 == ERROR),
184          *   OCTET STRING }
185          *
186          * However, for some protocols, the KRB5 blob starts at the SHORT
187          * and has no DER encoded header etc.
188          *
189          * It appears that for some other protocols the KRB5 blob is just
190          * a Kerberos message, with no [APPLICATION 0] header, no OID,
191          * and no USHORT.
192          *
193          * So:
194          *
195          *      If we see an [APPLICATION 0] HEADER, we show the OID and
196          *      the USHORT, and then dissect the rest as a Kerberos message.
197          *
198          *      If we see an [APPLICATION 14] or [APPLICATION 15] header,
199          *      we assume it's an AP-REQ or AP-REP message, and dissect
200          *      it all as a Kerberos message.
201          *
202          *      Otherwise, we show the USHORT, and then dissect the rest
203          *      as a Kerberos message.
204          */
205
206         /*
207          * Get the first header ...
208          */
209         get_ber_identifier(tvb, offset, &class, &pc, &tag);
210         if (class == BER_CLASS_APP && pc) {
211             /*
212              * [APPLICATION <tag>]
213              */
214             offset = dissect_ber_identifier(pinfo, subtree, tvb, offset, &class, &pc, &tag);
215             offset = dissect_ber_length(pinfo, subtree, tvb, offset, &len, &ind);
216
217             switch (tag) {
218
219             case 0:
220                 /*
221                  * [APPLICATION 0]
222                  */
223
224                 /* Next, the OID */
225                 offset=dissect_ber_object_identifier_str(FALSE, pinfo, subtree, tvb, offset, hf_spnego_krb5_oid, &oid);
226
227                 value = gssapi_lookup_oid_str(oid);
228
229                 token_id = tvb_get_letohs(tvb, offset);
230                 proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
231                                     token_id);
232
233                 offset += 2;
234
235                 break;
236
237             case 14:    /* [APPLICATION 14] */
238             case 15:    /* [APPLICATION 15] */
239                 /*
240                  * No token ID - just dissect as a Kerberos message and
241                  * return.
242                  */
243                 offset = dissect_kerberos_main(tvb, pinfo, subtree, FALSE, NULL);
244                 return;
245
246             default:
247                 proto_tree_add_text(subtree, tvb, offset, 0,
248                         "Unknown header (class=%d, pc=%d, tag=%d)",
249                         class, pc, tag);
250                 goto done;
251             }
252         } else {
253             /* Next, the token ID ... */
254
255             token_id = tvb_get_letohs(tvb, offset);
256             proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
257                                 token_id);
258
259             offset += 2;
260         }
261
262         switch (token_id) {
263
264         case KRB_TOKEN_AP_REQ:
265         case KRB_TOKEN_AP_REP:
266         case KRB_TOKEN_AP_ERR:
267           krb5_tvb = tvb_new_subset(tvb, offset, -1, -1);
268           offset = dissect_kerberos_main(krb5_tvb, pinfo, subtree, FALSE, NULL);
269           break;
270
271         case KRB_TOKEN_GETMIC:
272           offset = dissect_spnego_krb5_getmic_base(tvb, offset, pinfo, subtree);
273           break;
274
275         case KRB_TOKEN_WRAP:
276           offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
277           break;
278
279         case KRB_TOKEN_DELETE_SEC_CONTEXT:
280
281           break;
282
283         default:
284
285           break;
286         }
287
288  done:
289         return;
290 }
291
292 #ifdef HAVE_KERBEROS
293 #include <epan/crypt/crypt-md5.h>
294
295 #ifndef KEYTYPE_ARCFOUR_56
296 # define KEYTYPE_ARCFOUR_56 24
297 #endif
298 /* XXX - We should probably do a configure-time check for this instead */
299 #ifndef KRB5_KU_USAGE_SEAL
300 # define KRB5_KU_USAGE_SEAL 22
301 #endif
302
303 static int
304 arcfour_mic_key(void *key_data, size_t key_size, int key_type,
305                 void *cksum_data, size_t cksum_size,
306                 void *key6_data)
307 {
308     guint8 k5_data[16];
309     guint8 T[4];
310
311     memset(T, 0, 4);
312
313     if (key_type == KEYTYPE_ARCFOUR_56) {
314         guint8 L40[14] = "fortybits";
315
316         memcpy(L40 + 10, T, sizeof(T));
317         md5_hmac(
318                 L40, 14,
319                 key_data,
320                 key_size,
321                 k5_data);
322         memset(&k5_data[7], 0xAB, 9);
323     } else {
324         md5_hmac(
325                 T, 4,
326                 key_data,
327                 key_size,
328                 k5_data);
329     }
330
331     md5_hmac(
332         cksum_data, cksum_size,
333         k5_data,
334         16,
335         key6_data);
336
337     return 0;
338 }
339
340 static int
341 usage2arcfour(int usage)
342 {
343     switch (usage) {
344     case 3: /*KRB5_KU_AS_REP_ENC_PART 3 */
345     case 9: /*KRB5_KU_TGS_REP_ENC_PART_SUB_KEY 9 */
346         return 8;
347     case 22: /*KRB5_KU_USAGE_SEAL 22 */
348         return 13;
349     case 23: /*KRB5_KU_USAGE_SIGN 23 */
350         return 15;
351     case 24: /*KRB5_KU_USAGE_SEQ 24 */
352         return 0;
353     default :
354         return 0;
355     }
356 }
357
358 static int
359 arcfour_mic_cksum(guint8 *key_data, int key_length,
360                   unsigned usage,
361                   guint8 sgn_cksum[8],
362                   const void *v1, size_t l1,
363                   const void *v2, size_t l2,
364                   const void *v3, size_t l3)
365 {
366     const guint8 signature[] = "signaturekey";
367     guint8 ksign_c[16];
368     unsigned char t[4];
369     md5_state_t ms;
370     unsigned char digest[16];
371     int rc4_usage;
372     guint8 cksum[16];
373
374     rc4_usage=usage2arcfour(usage);
375     md5_hmac(signature, sizeof(signature),
376                 key_data, key_length,
377                 ksign_c);
378     md5_init(&ms);
379     t[0] = (rc4_usage >>  0) & 0xFF;
380     t[1] = (rc4_usage >>  8) & 0xFF;
381     t[2] = (rc4_usage >> 16) & 0xFF;
382     t[3] = (rc4_usage >> 24) & 0xFF;
383     md5_append(&ms, t, 4);
384     md5_append(&ms, v1, l1);
385     md5_append(&ms, v2, l2);
386     md5_append(&ms, v3, l3);
387     md5_finish(&ms, digest);
388     md5_hmac(digest, 16, ksign_c, 16, cksum);
389
390     memcpy(sgn_cksum, cksum, 8);
391
392     return 0;
393 }
394
395 /*
396  * Verify padding of a gss wrapped message and return its length.
397  */
398 static int
399 gssapi_verify_pad(unsigned char *wrapped_data, int wrapped_length,
400                    size_t datalen,
401                    size_t *padlen)
402 {
403     unsigned char *pad;
404     size_t padlength;
405     int i;
406
407     pad = wrapped_data + wrapped_length - 1;
408     padlength = *pad;
409
410     if (padlength > datalen)
411         return 1;
412
413     for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
414         ;
415     if (i != 0)
416         return 2;
417
418     *padlen = padlength;
419
420     return 0;
421 }
422
423 static int
424 decrypt_arcfour(packet_info *pinfo,
425          guint8 *input_message_buffer,
426          guint8 *output_message_buffer,
427          guint8 *key_value, int key_size, int key_type)
428 {
429     guint8 Klocaldata[16];
430     int ret;
431     gint32 seq_number;
432     size_t datalen;
433     guint8 k6_data[16], SND_SEQ[8], Confounder[8];
434     guint8 cksum_data[8];
435     int cmp;
436     int conf_flag;
437     size_t padlen = 0;
438
439     datalen = tvb_length(pinfo->gssapi_encrypted_tvb);
440
441     if(tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 4)==0x1000){
442         conf_flag=1;
443     } else if (tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 4)==0xffff){
444         conf_flag=0;
445     } else {
446         return -3;
447     }
448
449     if(tvb_get_ntohs(pinfo->gssapi_wrap_tvb, 6)!=0xffff){
450         return -4;
451     }
452
453     ret = arcfour_mic_key(key_value, key_size, key_type,
454                           (void *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
455                           8, /* SGN_CKSUM */
456                           k6_data);
457     if (ret) {
458         return -5;
459     }
460
461     {
462         rc4_state_struct rc4_state;
463
464         crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
465         memcpy(SND_SEQ, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 8, 8), 8);
466         crypt_rc4(&rc4_state, SND_SEQ, 8);
467
468         memset(k6_data, 0, sizeof(k6_data));
469     }
470
471     seq_number=g_ntohl(*((guint32 *)SND_SEQ));
472
473     cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
474     if(cmp){
475         cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
476     }
477
478     if (cmp != 0) {
479         return -6;
480     }
481
482     {
483         int i;
484
485         for (i = 0; i < 16; i++)
486             Klocaldata[i] = ((guint8 *)key_value)[i] ^ 0xF0;
487     }
488     ret = arcfour_mic_key(Klocaldata,sizeof(Klocaldata),key_type,
489                           SND_SEQ, 4,
490                           k6_data);
491     memset(Klocaldata, 0, sizeof(Klocaldata));
492     if (ret) {
493         return -7;
494     }
495
496     if(conf_flag) {
497         rc4_state_struct rc4_state;
498
499         crypt_rc4_init(&rc4_state, k6_data, sizeof(k6_data));
500         memcpy(Confounder, (unsigned char *)tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8), 8);
501         crypt_rc4(&rc4_state, Confounder, 8);
502         memcpy(output_message_buffer, input_message_buffer, datalen);
503         crypt_rc4(&rc4_state, output_message_buffer, datalen);
504     } else {
505         memcpy(Confounder,
506                 tvb_get_ptr(pinfo->gssapi_wrap_tvb, 24, 8),
507                 8); /* Confounder */
508         memcpy(output_message_buffer,
509                 input_message_buffer,
510                 datalen);
511     }
512     memset(k6_data, 0, sizeof(k6_data));
513
514     /* only normal (i.e. non DCE style  wrapping use padding ? */
515     if(pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){
516         ret = gssapi_verify_pad(output_message_buffer,datalen,datalen, &padlen);
517         if (ret) {
518             return -9;
519         }
520         datalen -= padlen;
521     }
522
523     /* dont know what the checksum looks like for dce style gssapi */
524     if(pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_NORMAL){
525         ret = arcfour_mic_cksum(key_value, key_size,
526                             KRB5_KU_USAGE_SEAL,
527                             cksum_data,
528                             tvb_get_ptr(pinfo->gssapi_wrap_tvb, 0, 8), 8,
529                             Confounder, sizeof(Confounder),
530                             output_message_buffer,
531                             datalen + padlen);
532         if (ret) {
533             return -10;
534         }
535
536         cmp = memcmp(cksum_data,
537             tvb_get_ptr(pinfo->gssapi_wrap_tvb, 16, 8),
538             8); /* SGN_CKSUM */
539         if (cmp) {
540             return -11;
541         }
542     }
543
544     return datalen;
545 }
546
547
548
549 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
550
551 static void
552 decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int keytype)
553 {
554         int ret;
555         enc_key_t *ek;
556         int length;
557         const guint8 *original_data;
558
559         static int omb_index=0;
560         static guint8 *omb_arr[4]={NULL,NULL,NULL,NULL};
561         static guint8 *cryptocopy=NULL; /* workaround for pre-0.6.1 heimdal bug */
562         guint8 *output_message_buffer;
563
564         omb_index++;
565         if(omb_index>=4){
566                 omb_index=0;
567         }
568         output_message_buffer=omb_arr[omb_index];
569
570
571         length=tvb_length(pinfo->gssapi_encrypted_tvb);
572         original_data=tvb_get_ptr(pinfo->gssapi_encrypted_tvb, 0, length);
573
574         /* dont do anything if we are not attempting to decrypt data */
575 /*
576         if(!krb_decrypt){
577                 return;
578         }
579 */
580         /* XXX we should only do this for first time, then store somewhere */
581         /* XXX We also need to re-read the keytab when the preference changes */
582
583         cryptocopy=ep_alloc(length);
584         if(output_message_buffer){
585                 g_free(output_message_buffer);
586                 output_message_buffer=NULL;
587         }
588         output_message_buffer=g_malloc(length);
589
590         for(ek=enc_key_list;ek;ek=ek->next){
591                 /* shortcircuit and bail out if enctypes are not matching */
592                 if(ek->keytype!=keytype){
593                         continue;
594                 }
595
596                 /* pre-0.6.1 versions of Heimdal would sometimes change
597                   the cryptotext data even when the decryption failed.
598                   This would obviously not work since we iterate over the
599                   keys. So just give it a copy of the crypto data instead.
600                   This has been seen for RC4-HMAC blobs.
601                 */
602                 memcpy(cryptocopy, original_data, length);
603                 ret=decrypt_arcfour(pinfo,
604                                 cryptocopy,
605                                 output_message_buffer,
606                                 ek->keyvalue,
607                                 ek->keylength,
608                                 ek->keytype
609                                             );
610                 if (ret >= 0) {
611                         proto_tree_add_text(tree, NULL, 0, 0, "[Decrypted using: %s]", ek->key_origin);
612                         pinfo->gssapi_decrypted_tvb=tvb_new_real_data(
613                                 output_message_buffer,
614                                 ret, ret);
615                         tvb_set_child_real_data_tvbuff(tvb, pinfo->gssapi_decrypted_tvb);
616                         add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
617                         return;
618                 }
619         }
620         return;
621 }
622 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
623
624
625 #endif
626
627 /*
628  * XXX - This is for GSSAPI Wrap tokens ...
629  */
630 static int
631 dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
632 #ifndef HAVE_KERBEROS
633         _U_
634 #endif
635     , proto_tree *tree, guint16 token_id
636 #ifndef HAVE_KERBEROS
637         _U_
638 #endif
639     )
640 {
641         guint16 sgn_alg, seal_alg;
642 #ifdef HAVE_KERBEROS
643         int start_offset=offset;
644 #endif
645
646         /*
647          * The KRB5 blob conforms to RFC1964:
648          *   USHORT (0x0102 == GSS_Wrap)
649          *   and so on }
650          */
651
652         /* Now, the sign and seal algorithms ... */
653
654         sgn_alg = tvb_get_letohs(tvb, offset);
655         proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
656                             sgn_alg);
657
658         offset += 2;
659
660         seal_alg = tvb_get_letohs(tvb, offset);
661         proto_tree_add_uint(tree, hf_spnego_krb5_seal_alg, tvb, offset, 2,
662                             seal_alg);
663
664         offset += 2;
665
666         /* Skip the filler */
667
668         offset += 2;
669
670         /* Encrypted sequence number */
671
672         proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
673                             TRUE);
674
675         offset += 8;
676
677         /* Checksum of plaintext padded data */
678
679         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
680                             TRUE);
681
682         offset += 8;
683
684         /*
685          * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
686          * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
687          * extra 8 bytes of "Random confounder" after the checksum.
688          * It certainly confounds code expecting all Kerberos 5
689          * GSS_Wrap() tokens to look the same....
690          */
691         if (sgn_alg == KRB_SGN_ALG_HMAC) {
692           proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
693                               TRUE);
694           offset += 8;
695         }
696
697         /* Is the data encrypted? */
698         pinfo->gssapi_data_encrypted=(seal_alg!=KRB_SEAL_ALG_NONE);
699
700 #ifdef HAVE_KERBEROS
701 #define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
702         if(pinfo->decrypt_gssapi_tvb){
703                 /* if the caller did not provide a tvb, then we just use
704                    whatever is left of our current tvb.
705                 */
706                 if(!pinfo->gssapi_encrypted_tvb){
707                         int len;
708                         len=tvb_reported_length_remaining(tvb,offset);
709                         if(len>tvb_length_remaining(tvb, offset)){
710                                 /* no point in trying to decrypt,
711                                    we dont have the full pdu.
712                                 */
713                                 return offset;
714                         }
715                         pinfo->gssapi_encrypted_tvb = tvb_new_subset(
716                                         tvb, offset, len, len);
717                 }
718
719                 /* if this is KRB5 wrapped rc4-hmac */
720                 if((token_id==KRB_TOKEN_WRAP)
721                  &&(sgn_alg==KRB_SGN_ALG_HMAC)
722                  &&(seal_alg==KRB_SEAL_ALG_RC4)){
723                         /* do we need to create a tvb for the wrapper
724                            as well ?
725                         */
726                         if(!pinfo->gssapi_wrap_tvb){
727                                 pinfo->gssapi_wrap_tvb = tvb_new_subset(
728                                         tvb, start_offset-2,
729                                         GSS_ARCFOUR_WRAP_TOKEN_SIZE,
730                                         GSS_ARCFOUR_WRAP_TOKEN_SIZE);
731                         }
732 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
733                         decrypt_gssapi_krb_arcfour_wrap(tree,
734                                 pinfo,
735                                 tvb,
736                                 23 /* rc4-hmac */);
737 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
738                 }
739         }
740 #endif
741         /*
742          * Return the offset past the checksum, so that we know where
743          * the data we're wrapped around starts.  Also, set the length
744          * of our top-level item to that offset, so it doesn't cover
745          * the data we're wrapped around.
746          *
747          * Note that for DCERPC the GSSAPI blobs comes after the data it wraps,
748          * not before.
749          */
750         return offset;
751 }
752
753 /*
754  * XXX - This is for GSSAPI GetMIC tokens ...
755  */
756 static int
757 dissect_spnego_krb5_getmic_base(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
758 {
759         guint16 sgn_alg;
760
761         /*
762          * The KRB5 blob conforms to RFC1964:
763          *   USHORT (0x0101 == GSS_GetMIC)
764          *   and so on }
765          */
766
767         /* Now, the sign algorithm ... */
768
769         sgn_alg = tvb_get_letohs(tvb, offset);
770         proto_tree_add_uint(tree, hf_spnego_krb5_sgn_alg, tvb, offset, 2,
771                             sgn_alg);
772
773         offset += 2;
774
775         /* Skip the filler */
776
777         offset += 4;
778
779         /* Encrypted sequence number */
780
781         proto_tree_add_item(tree, hf_spnego_krb5_snd_seq, tvb, offset, 8,
782                             TRUE);
783
784         offset += 8;
785
786         /* Checksum of plaintext padded data */
787
788         proto_tree_add_item(tree, hf_spnego_krb5_sgn_cksum, tvb, offset, 8,
789                             TRUE);
790
791         offset += 8;
792
793         /*
794          * At least according to draft-brezak-win2k-krb-rc4-hmac-04,
795          * if the signing algorithm is KRB_SGN_ALG_HMAC, there's an
796          * extra 8 bytes of "Random confounder" after the checksum.
797          * It certainly confounds code expecting all Kerberos 5
798          * GSS_Wrap() tokens to look the same....
799          *
800          * The exception is DNS/TSIG where there is no such confounder
801          * so we need to test here if there are more bytes in our tvb or not.
802          *  -- ronnie
803          */
804         if (tvb_length_remaining(tvb, offset)) {
805           if (sgn_alg == KRB_SGN_ALG_HMAC) {
806             proto_tree_add_item(tree, hf_spnego_krb5_confounder, tvb, offset, 8,
807                               TRUE);
808
809             offset += 8;
810           }
811         }
812
813         /*
814          * Return the offset past the checksum, so that we know where
815          * the data we're wrapped around starts.  Also, set the length
816          * of our top-level item to that offset, so it doesn't cover
817          * the data we're wrapped around.
818          */
819
820         return offset;
821 }
822
823 /*
824  * XXX - is this for SPNEGO or just GSS-API?
825  * RFC 1964 is "The Kerberos Version 5 GSS-API Mechanism"; presumably one
826  * can directly designate Kerberos V5 as a mechanism in GSS-API, rather
827  * than designating SPNEGO as the mechanism, offering Kerberos V5, and
828  * getting it accepted.
829  */
830 static int
831 dissect_spnego_krb5_wrap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
832 {
833         proto_item *item;
834         proto_tree *subtree;
835         int offset = 0;
836         guint16 token_id;
837
838         item = proto_tree_add_item(tree, hf_spnego_krb5, tvb, 0, -1, FALSE);
839
840         subtree = proto_item_add_subtree(item, ett_spnego_krb5);
841
842         /*
843          * The KRB5 blob conforms to RFC1964:
844          *   USHORT (0x0102 == GSS_Wrap)
845          *   and so on }
846          */
847
848         /* First, the token ID ... */
849
850         token_id = tvb_get_letohs(tvb, offset);
851         proto_tree_add_uint(subtree, hf_spnego_krb5_tok_id, tvb, offset, 2,
852                             token_id);
853
854         offset += 2;
855
856         offset = dissect_spnego_krb5_wrap_base(tvb, offset, pinfo, subtree, token_id);
857
858         /*
859          * Return the offset past the checksum, so that we know where
860          * the data we're wrapped around starts.  Also, set the length
861          * of our top-level item to that offset, so it doesn't cover
862          * the data we're wrapped around.
863          */
864         proto_item_set_len(item, offset);
865         return offset;
866 }
867
868 /* Spnego stuff from here */
869
870 static int
871 dissect_spnego_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
872 {
873         proto_item *item;
874         proto_tree *subtree;
875
876         int offset = 0;
877
878
879         /*
880          * We need this later, so lets get it now ...
881          * It has to be per-frame as there can be more than one GSS-API
882          * negotiation in a conversation.
883          */
884
885
886         item = proto_tree_add_item(tree, hf_spnego, tvb, offset,
887                                    -1, FALSE);
888
889         subtree = proto_item_add_subtree(item, ett_spnego);
890         /*
891          * The TVB contains a [0] header and a sequence that consists of an
892          * object ID and a blob containing the data ...
893          * XXX - is this RFC 2743's "Mechanism-Independent Token Format",
894          * with the "optional" "use in non-initial tokens" being chosen.
895          * ASN1 code addet to spnego.asn to handle this.
896          */
897
898         offset = dissect_spnego_InitialContextToken(FALSE, tvb, offset, pinfo , subtree, -1);
899
900         return offset;
901 }
902
903
904 static void
905 dissect_spnego(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
906 {
907         proto_item *item;
908         proto_tree *subtree;
909         int offset = 0;
910         conversation_t *conversation;
911
912         /*
913          * We need this later, so lets get it now ...
914          * It has to be per-frame as there can be more than one GSS-API
915          * negotiation in a conversation.
916          */
917         next_level_value = p_get_proto_data(pinfo->fd, proto_spnego);
918         if (!next_level_value && !pinfo->fd->flags.visited) {
919             /*
920              * No handle attached to this frame, but it's the first
921              * pass, so it'd be attached to the conversation.
922              * If we have a conversation, try to get the handle,
923              * and if we get one, attach it to the frame.
924              */
925             conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
926                                              pinfo->ptype, pinfo->srcport,
927                                              pinfo->destport, 0);
928
929             if (conversation) {
930                 next_level_value = conversation_get_proto_data(conversation,
931                                                                proto_spnego);
932                 if (next_level_value)
933                     p_add_proto_data(pinfo->fd, proto_spnego, next_level_value);
934             }
935         }
936
937         item = proto_tree_add_item(parent_tree, hf_spnego, tvb, offset,
938                                    -1, FALSE);
939
940         subtree = proto_item_add_subtree(item, ett_spnego);
941
942         /*
943          * The TVB contains a [0] header and a sequence that consists of an
944          * object ID and a blob containing the data ...
945          * Actually, it contains, according to RFC2478:
946          * NegotiationToken ::= CHOICE {
947          *          negTokenInit [0] NegTokenInit,
948          *          negTokenTarg [1] NegTokenTarg }
949          * NegTokenInit ::= SEQUENCE {
950          *          mechTypes [0] MechTypeList OPTIONAL,
951          *          reqFlags [1] ContextFlags OPTIONAL,
952          *          mechToken [2] OCTET STRING OPTIONAL,
953          *          mechListMIC [3] OCTET STRING OPTIONAL }
954          * NegTokenTarg ::= SEQUENCE {
955          *          negResult [0] ENUMERATED {
956          *              accept_completed (0),
957          *              accept_incomplete (1),
958          *              reject (2) } OPTIONAL,
959          *          supportedMech [1] MechType OPTIONAL,
960          *          responseToken [2] OCTET STRING OPTIONAL,
961          *          mechListMIC [3] OCTET STRING OPTIONAL }
962          *
963          * Windows typically includes mechTypes and mechListMic ('NONE'
964          * in the case of NTLMSSP only).
965          * It seems to duplicate the responseToken into the mechListMic field
966          * as well. Naughty, naughty.
967          *
968          */
969         offset = dissect_spnego_NegotiationToken(FALSE, tvb, offset, pinfo, subtree, -1);
970
971 }
972
973 /*--- proto_register_spnego -------------------------------------------*/
974 void proto_register_spnego(void) {
975
976         /* List of fields */
977         static hf_register_info hf[] = {
978                 { &hf_spnego,
979                   { "SPNEGO", "spnego", FT_NONE, BASE_NONE, NULL, 0x0,
980                     "SPNEGO", HFILL }},
981                 { &hf_spnego_wraptoken,
982                   { "wrapToken", "spnego.wraptoken",
983                     FT_NONE, BASE_NONE, NULL, 0x0, "SPNEGO wrapToken",
984                     HFILL}},
985                 { &hf_spnego_krb5,
986                   { "krb5_blob", "spnego.krb5.blob", FT_BYTES,
987                     BASE_NONE, NULL, 0, "krb5_blob", HFILL }},
988                 { &hf_spnego_krb5_oid,
989                   { "KRB5 OID", "spnego.krb5_oid", FT_STRING,
990                     BASE_NONE, NULL, 0, "KRB5 OID", HFILL }},
991                 { &hf_spnego_krb5_tok_id,
992                   { "krb5_tok_id", "spnego.krb5.tok_id", FT_UINT16, BASE_HEX,
993                     VALS(spnego_krb5_tok_id_vals), 0, "KRB5 Token Id", HFILL}},
994                 { &hf_spnego_krb5_sgn_alg,
995                   { "krb5_sgn_alg", "spnego.krb5.sgn_alg", FT_UINT16, BASE_HEX,
996                     VALS(spnego_krb5_sgn_alg_vals), 0, "KRB5 Signing Algorithm", HFILL}},
997                 { &hf_spnego_krb5_seal_alg,
998                   { "krb5_seal_alg", "spnego.krb5.seal_alg", FT_UINT16, BASE_HEX,
999                     VALS(spnego_krb5_seal_alg_vals), 0, "KRB5 Sealing Algorithm", HFILL}},
1000                 { &hf_spnego_krb5_snd_seq,
1001                   { "krb5_snd_seq", "spnego.krb5.snd_seq", FT_BYTES, BASE_NONE,
1002                     NULL, 0, "KRB5 Encrypted Sequence Number", HFILL}},
1003                 { &hf_spnego_krb5_sgn_cksum,
1004                   { "krb5_sgn_cksum", "spnego.krb5.sgn_cksum", FT_BYTES, BASE_NONE,
1005                     NULL, 0, "KRB5 Data Checksum", HFILL}},
1006                 { &hf_spnego_krb5_confounder,
1007                   { "krb5_confounder", "spnego.krb5.confounder", FT_BYTES, BASE_NONE,
1008                     NULL, 0, "KRB5 Confounder", HFILL}},
1009
1010 #include "packet-spnego-hfarr.c"
1011         };
1012
1013         /* List of subtrees */
1014         static gint *ett[] = {
1015                 &ett_spnego,
1016                 &ett_spnego_wraptoken,
1017                 &ett_spnego_krb5,
1018
1019 #include "packet-spnego-ettarr.c"
1020         };
1021
1022         /* Register protocol */
1023         proto_spnego = proto_register_protocol(PNAME, PSNAME, PFNAME);
1024
1025         proto_spnego_krb5 = proto_register_protocol("SPNEGO-KRB5",
1026                                                     "SPNEGO-KRB5",
1027                                                     "spnego-krb5");
1028         /* Register fields and subtrees */
1029         proto_register_field_array(proto_spnego, hf, array_length(hf));
1030         proto_register_subtree_array(ett, array_length(ett));
1031 }
1032
1033
1034 /*--- proto_reg_handoff_spnego ---------------------------------------*/
1035 void proto_reg_handoff_spnego(void) {
1036
1037         dissector_handle_t spnego_handle, spnego_wrap_handle;
1038         dissector_handle_t spnego_krb5_handle, spnego_krb5_wrap_handle;
1039
1040         /* Register protocol with GSS-API module */
1041
1042         spnego_handle = create_dissector_handle(dissect_spnego, proto_spnego);
1043         spnego_wrap_handle = new_create_dissector_handle(dissect_spnego_wrap,
1044                                                          proto_spnego);
1045         gssapi_init_oid("1.3.6.1.5.5.2", proto_spnego, ett_spnego,
1046             spnego_handle, spnego_wrap_handle,
1047             "SPNEGO - Simple Protected Negotiation");
1048
1049         /* Register both the one MS created and the real one */
1050         /*
1051          * Thanks to Jean-Baptiste Marchand and Richard B Ward, the
1052          * mystery of the MS KRB5 OID is cleared up. It was due to a library
1053          * that did not handle OID components greater than 16 bits, and was
1054          * fixed in Win2K SP2 as well as WinXP.
1055          * See the archive of <ietf-krb-wg@anl.gov> for the thread topic
1056          * SPNEGO implementation issues. 3-Dec-2002.
1057          */
1058         spnego_krb5_handle = create_dissector_handle(dissect_spnego_krb5,
1059                                                      proto_spnego_krb5);
1060         spnego_krb5_wrap_handle = new_create_dissector_handle(dissect_spnego_krb5_wrap,
1061                                                               proto_spnego_krb5);
1062         gssapi_init_oid("1.2.840.48018.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
1063                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1064                         "MS KRB5 - Microsoft Kerberos 5");
1065         gssapi_init_oid("1.2.840.113554.1.2.2", proto_spnego_krb5, ett_spnego_krb5,
1066                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1067                         "KRB5 - Kerberos 5");
1068         gssapi_init_oid("1.2.840.113554.1.2.2.3", proto_spnego_krb5, ett_spnego_krb5,
1069                         spnego_krb5_handle, spnego_krb5_wrap_handle,
1070                         "KRB5 - Kerberos 5 - User to User");
1071
1072         /*
1073          * Find the data handle for some calls
1074          */
1075         data_handle = find_dissector("data");
1076 }