2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
6 * $Id: packet-kerberos.c,v 1.6 2000/11/19 08:53:58 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Didier Jorand
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
47 #include "packet-kerberos.h"
49 #define UDP_PORT_KERBEROS 88
50 #define TCP_PORT_KERBEROS 88
52 static gint ett_kerberos = -1;
53 static gint ett_preauth = -1;
54 static gint ett_addresses = -1;
55 static gint ett_request = -1;
56 static gint ett_princ = -1;
57 static gint ett_ticket = -1;
58 static gint ett_encrypted = -1;
59 static gint ett_etype = -1;
60 static gint proto_kerberos = -1;
62 #define KRB5_MSG_AS_REQ 0x0a
63 #define KRB5_MSG_AS_RESP 0x0b
64 #define KRB5_MSG_TGS_REQ 0x0c
65 #define KRB5_MSG_TGS_RESP 0x0d
67 #define KRB5_KDC_REQ_PVNO 0x01
68 #define KRB5_KDC_REQ_MSG_TYPE 0x02
69 #define KRB5_KDC_REQ_PADATA 0x03
70 #define KRB5_KDC_REQ_REQBODY 0x04
72 #define KRB5_KDC_RESP_PVNO 0x00
73 #define KRB5_KDC_RESP_MSG_TYPE 0x01
74 #define KRB5_KDC_RESP_PADATA 0x02
75 #define KRB5_KDC_RESP_CREALM 0x03
76 #define KRB5_KDC_RESP_CNAME 0x04
77 #define KRB5_KDC_RESP_TICKET 0x05
78 #define KRB5_KDC_RESP_ENC_PART 0x06
80 #define KRB5_BODY_KDC_OPTIONS 0x00
81 #define KRB5_BODY_CNAME 0x01
82 #define KRB5_BODY_REALM 0x02
83 #define KRB5_BODY_SNAME 0x03
84 #define KRB5_BODY_FROM 0x04
85 #define KRB5_BODY_TILL 0x05
86 #define KRB5_BODY_RTIME 0x06
87 #define KRB5_BODY_NONCE 0x07
88 #define KRB5_BODY_ETYPE 0x08
89 #define KRB5_BODY_ADDRESSES 0x09
90 #define KRB5_BODY_ENC_AUTHORIZATION_DATA 0x0a
91 #define KRB5_BODY_ADDITIONAL_TICKETS 0x0b
93 #define KRB5_ADDR_IPv4 0x02
94 #define KRB5_ADDR_CHAOS 0x05
95 #define KRB5_ADDR_XEROX 0x06
96 #define KRB5_ADDR_ISO 0x07
97 #define KRB5_ADDR_DECNET 0x0c
98 #define KRB5_ADDR_APPLETALK 0x10
100 #define KRB5_ETYPE_NULL 0
101 #define KRB5_ETYPE_DES_CBC_CRC 1
102 #define KRB5_ETYPE_DES_CBC_MD4 2
103 #define KRB5_ETYPE_DES_CBC_MD5 3
105 #define KRB5_PA_TGS_REQ 0x01
106 #define KRB5_PA_ENC_TIMESTAMP 0x02
107 #define KRB5_PA_PW_SALT 0x03
109 static const value_string krb5_preauthentication_types[] = {
110 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
111 { KRB5_PA_ENC_TIMESTAMP, "PA-ENC-TIMESTAMP" },
112 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
115 static const value_string krb5_encryption_types[] = {
116 { KRB5_ETYPE_NULL , "NULL" },
117 { KRB5_ETYPE_DES_CBC_CRC , "des-cbc-crc" },
118 { KRB5_ETYPE_DES_CBC_MD4 , "des-cbc-md4" },
119 { KRB5_ETYPE_DES_CBC_MD5 , "des-cbc-md5" },
122 static const value_string krb5_address_types[] = {
123 { KRB5_ADDR_IPv4, "IPv4"},
124 { KRB5_ADDR_CHAOS, "CHAOS"},
125 { KRB5_ADDR_XEROX, "XEROX"},
126 { KRB5_ADDR_ISO, "ISO"},
127 { KRB5_ADDR_DECNET, "DECNET"},
128 { KRB5_ADDR_APPLETALK, "APPLETALK"}
131 static const value_string krb5_msg_types[] = {
132 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
133 { KRB5_MSG_TGS_RESP, "TGS-RESP" },
134 { KRB5_MSG_AS_REQ, "AS-REQ" },
135 { KRB5_MSG_AS_RESP, "AS-RESP" }
139 to_error_str(int ret) {
143 return("Ran out of data");
145 case ASN1_ERR_EOC_MISMATCH:
146 return("EOC mismatch");
148 case ASN1_ERR_WRONG_TYPE:
149 return("Wrong type for that item");
151 case ASN1_ERR_LENGTH_NOT_DEFINITE:
152 return("Length was indefinite");
154 case ASN1_ERR_LENGTH_MISMATCH:
155 return("Length mismatch");
157 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
158 return("Wrong length for that item's type");
161 return("Unknown error");
165 krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
166 char *name, guchar *str) {
168 proto_tree_add_text(tree, NullTVB, offset, str_len,
169 "%s: %.4s-%.2s-%.2s %.2s:%.2s:%.2s (%.1s)",
170 name, str, str+4, str+6,
171 str+8, str+10, str+12,
177 * You must be kidding. I'm going to actually use a macro to do something?
181 #define KRB_HEAD_DECODE_OR_DIE(token) \
182 start = asn1p->pointer; \
183 ret = asn1_header_decode (asn1p, &cls, &con, &tag, &def, &item_len); \
184 if (ret != ASN1_ERR_NOERROR && ret != ASN1_ERR_EMPTY) {\
185 if (check_col(fd, COL_INFO)) \
186 col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
187 token, to_error_str(ret)); \
191 if (check_col(fd, COL_INFO)) \
192 col_add_fstr(fd, COL_INFO, "not definite: %s", token); \
193 fprintf(stderr,"not definite: %s\n", token); \
196 offset += (asn1p->pointer - start);
199 #define KRB_DECODE_OR_DIE(token, fn, val) \
200 ret = fn (asn1p, &val, &length); \
201 if (ret != ASN1_ERR_NOERROR) { \
202 if (check_col(fd, COL_INFO)) \
203 col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
204 token, to_error_str(ret)); \
208 /* dissect_type_value_pair decodes (roughly) this:
215 which is all over the place in krb5 */
218 dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
219 int *type, int *type_len, int *type_off,
220 guchar **val, int *val_len, int *val_off) {
229 start = asn1p->pointer;
230 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
231 offset += (asn1p->pointer - start);
235 start = asn1p->pointer;
236 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
237 offset += (asn1p->pointer - start);
243 ret = asn1_int32_decode(asn1p, type, type_len);
244 if (ret != ASN1_ERR_NOERROR) {
245 fprintf(stderr,"die: type_value_pair: type, %s\n", to_error_str(ret));
250 /* OCTET STRING (or generic data) */
252 start = asn1p->pointer;
253 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
254 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
255 offset += asn1p->pointer - start;
261 asn1_octet_string_value_decode (asn1p, *val_len, val);
263 *inoff = offset + *val_len;
268 dissect_kerberos(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
270 proto_tree *kerberos_tree = NULL;
271 proto_tree *etype_tree = NULL;
272 proto_tree *preauth_tree = NULL;
273 proto_tree *request_tree = NULL;
274 ASN1_SCK asn1, *asn1p = &asn1;
275 proto_item *item = NULL;
280 guint item_len, total_len;
285 guint protocol_message_type;
295 int tmp_pos1, tmp_pos2;
297 OLD_CHECK_DISPLAY_AS_DATA(proto_kerberos, pd, offset, fd, tree);
299 if (check_col(fd, COL_PROTOCOL))
300 col_set_str(fd, COL_PROTOCOL, "KRB5");
303 item = proto_tree_add_item(tree, proto_kerberos, NullTVB, offset,
304 END_OF_FRAME, FALSE);
305 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
308 asn1_open(&asn1, &pd[offset], END_OF_FRAME);
311 KRB_HEAD_DECODE_OR_DIE("top");
312 protocol_message_type = tag;
315 KRB_HEAD_DECODE_OR_DIE("top2");
318 KRB_HEAD_DECODE_OR_DIE("version-wrap");
319 KRB_DECODE_OR_DIE("version", asn1_int32_decode, version);
322 proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
329 KRB_HEAD_DECODE_OR_DIE("message-type-wrap");
330 KRB_DECODE_OR_DIE("message-type", asn1_int32_decode, msg_type);
333 proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
335 val_to_str(msg_type, krb5_msg_types,
336 "Unknown msg type %#x"));
340 if (check_col(fd, COL_INFO))
341 col_add_str(fd, COL_INFO, val_to_str(msg_type, krb5_msg_types,
342 "Unknown msg type %#x"));
344 /* is preauthentication present? */
345 KRB_HEAD_DECODE_OR_DIE("padata-or-body");
346 if (((protocol_message_type == KRB5_MSG_AS_REQ ||
347 protocol_message_type == KRB5_MSG_TGS_REQ) &&
348 tag == KRB5_KDC_REQ_PADATA) ||
349 ((protocol_message_type == KRB5_MSG_AS_RESP ||
350 protocol_message_type == KRB5_MSG_TGS_RESP) &&
351 tag == KRB5_KDC_RESP_PADATA)) {
352 /* pre-authentication supplied */
355 item = proto_tree_add_text(kerberos_tree, NullTVB, offset,
356 item_len, "Pre-Authentication");
357 preauth_tree = proto_item_add_subtree(item, ett_preauth);
360 KRB_HEAD_DECODE_OR_DIE("sequence of pa-data");
361 start = asn1p->pointer + item_len;
363 while(start > asn1p->pointer) {
364 dissect_type_value_pair(asn1p, &offset,
365 &preauth_type, &item_len, &tmp_pos1,
366 &str, &str_len, &tmp_pos2);
369 proto_tree_add_text(preauth_tree, NullTVB, tmp_pos1,
370 item_len, "Type: %s",
371 val_to_str(preauth_type,
372 krb5_preauthentication_types,
373 "Unknown preauth type %#x"));
374 proto_tree_add_text(preauth_tree, NullTVB, tmp_pos2,
375 str_len, "Value: %s",
376 bytes_to_str(str, str_len));
379 KRB_HEAD_DECODE_OR_DIE("message-body");
382 if (protocol_message_type == KRB5_MSG_AS_REQ ||
383 protocol_message_type == KRB5_MSG_TGS_REQ) {
386 KRB_HEAD_DECODE_OR_DIE("body-sequence");
388 item = proto_tree_add_text(kerberos_tree, NullTVB, offset,
389 item_len, "Request");
390 request_tree = proto_item_add_subtree(item, ett_request);
394 KRB_HEAD_DECODE_OR_DIE("kdc options");
396 KRB_HEAD_DECODE_OR_DIE("kdc options:bits");
399 proto_tree_add_text(request_tree, NullTVB, offset, item_len,
401 bytes_to_str(asn1.pointer, item_len));
404 asn1.pointer += item_len;
406 KRB_HEAD_DECODE_OR_DIE("Principal Name");
408 if (tag == KRB5_BODY_CNAME) {
409 dissect_PrincipalName("Client Name", asn1p, fd, request_tree,
411 KRB_HEAD_DECODE_OR_DIE("realm name");
414 if (tag == KRB5_BODY_REALM) {
415 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
416 offset += item_len - str_len;
418 proto_tree_add_text(request_tree, NullTVB, offset, str_len,
419 "Realm: %.*s", str_len, str);
422 KRB_HEAD_DECODE_OR_DIE("realm name");
427 if (tag == KRB5_BODY_SNAME) {
428 dissect_PrincipalName("Server Name", asn1p, fd, request_tree, &offset);
429 KRB_HEAD_DECODE_OR_DIE("realm name");
432 if (tag == KRB5_BODY_FROM) {
433 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
434 offset += item_len - str_len;
435 krb_proto_tree_add_time(request_tree, offset, str_len,
438 KRB_HEAD_DECODE_OR_DIE("realm name");
441 if (tag == KRB5_BODY_TILL) {
442 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
443 offset += item_len - str_len;
444 krb_proto_tree_add_time(request_tree, offset, str_len,
447 KRB_HEAD_DECODE_OR_DIE("realm name");
452 if (tag == KRB5_BODY_RTIME) {
453 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
454 offset += item_len - str_len;
455 krb_proto_tree_add_time(request_tree, offset, str_len,
456 "Renewable Until", str);
458 KRB_HEAD_DECODE_OR_DIE("realm name");
461 if (tag == KRB5_BODY_NONCE) {
462 ret = asn1_int32_decode(asn1p, &tmp_int, &length);
463 if (ret != ASN1_ERR_NOERROR) {
464 fprintf(stderr,"die: nonce, %s\n", to_error_str(ret));
468 proto_tree_add_text(request_tree, NullTVB, offset, length,
477 KRB_HEAD_DECODE_OR_DIE("encryption type spot");
478 if (tag == KRB5_BODY_ETYPE) {
479 KRB_HEAD_DECODE_OR_DIE("encryption type list");
481 item = proto_tree_add_text(request_tree, NullTVB, offset,
482 item_len, "Encryption Types");
483 etype_tree = proto_item_add_subtree(item, ett_etype);
485 total_len = item_len;
486 while(total_len > 0) {
487 ret = asn1_int32_decode(asn1p, &tmp_int, &length);
488 if (ret != ASN1_ERR_NOERROR) {
489 fprintf(stderr,"die: etype, %s\n", to_error_str(ret));
493 proto_tree_add_text(etype_tree, NullTVB, offset, length,
496 krb5_encryption_types,
497 "Unknown encryption type %#x"));
506 KRB_HEAD_DECODE_OR_DIE("addresses");
507 if (tag == KRB5_BODY_ADDRESSES) {
508 /* pre-authentication supplied */
510 dissect_Addresses("Addresses", asn1p, fd, kerberos_tree, &offset);
511 KRB_HEAD_DECODE_OR_DIE("auth-data");
513 } else if (protocol_message_type == KRB5_MSG_AS_RESP ||
514 protocol_message_type == KRB5_MSG_TGS_RESP) {
515 if (tag == KRB5_KDC_RESP_CREALM) {
516 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
517 offset += item_len - str_len;
519 proto_tree_add_text(kerberos_tree, NullTVB, offset, str_len,
520 "Realm: %.*s", str_len, str);
527 KRB_HEAD_DECODE_OR_DIE("cname");
528 if (tag == KRB5_KDC_RESP_CNAME) {
529 dissect_PrincipalName("Client Name", asn1p, fd, kerberos_tree,
535 KRB_HEAD_DECODE_OR_DIE("ticket");
536 if (tag == KRB5_KDC_RESP_TICKET) {
537 dissect_ticket("ticket", asn1p, fd, kerberos_tree, &offset);
542 KRB_HEAD_DECODE_OR_DIE("enc-msg-part");
543 if (tag == KRB5_KDC_RESP_TICKET) {
544 dissect_EncryptedData("Encrypted Payload", asn1p, fd, kerberos_tree,
553 dissect_GeneralString(ASN1_SCK *asn1p, guchar **where,
554 guint *item_len, guint *pkt_len)
558 const guchar *start = asn1p->pointer;
560 asn1_header_decode (asn1p, &cls, &con, &tag, &def, item_len);
561 asn1_octet_string_value_decode (asn1p, *item_len, where);
562 *pkt_len = asn1p->pointer - start;
566 dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
567 proto_tree *tree, int *inoff) {
568 proto_tree *princ_tree = NULL;
575 guint item_len, total_len, type_len;
578 proto_item *item = NULL;
591 KRB_HEAD_DECODE_OR_DIE("principal section");
593 KRB_HEAD_DECODE_OR_DIE("principal type");
594 KRB_DECODE_OR_DIE("princ-type", asn1_int32_decode, princ_type);
595 type_offset = offset;
599 KRB_HEAD_DECODE_OR_DIE("cname header");
600 total_len = item_len;
602 dissect_GeneralString(asn1p, &name, &name_len, &item_len);
603 offset += item_len - name_len;
606 item = proto_tree_add_text(tree, NullTVB, *inoff, total_len,
607 "%s: %.*s", title, (int) name_len, name);
608 princ_tree = proto_item_add_subtree(item, ett_princ);
610 proto_tree_add_text(princ_tree, NullTVB, type_offset, type_len,
611 "Type: %d", princ_type);
612 proto_tree_add_text(princ_tree, NullTVB, offset, name_len,
613 "Name: %.*s", (int) name_len, name);
616 total_len -= item_len;
619 while(total_len > 0) {
620 dissect_GeneralString(asn1p, &name, &name_len, &item_len);
621 offset += item_len - name_len;
623 proto_tree_add_text(princ_tree, NullTVB, offset, name_len,
624 "Name: %.*s", (int) name_len, name);
626 total_len -= item_len;
634 dissect_Addresses(char *title, ASN1_SCK *asn1p, frame_data *fd,
635 proto_tree *tree, int *inoff) {
636 proto_tree *address_tree = NULL;
644 proto_item *item = NULL;
647 int tmp_pos1, tmp_pos2;
656 KRB_HEAD_DECODE_OR_DIE("sequence of addresses");
658 item = proto_tree_add_text(tree, NullTVB, offset,
659 item_len, "Addresses");
660 address_tree = proto_item_add_subtree(item, ett_addresses);
663 start = asn1p->pointer + item_len;
665 while(start > asn1p->pointer) {
666 dissect_type_value_pair(asn1p, &offset,
667 &address_type, &item_len, &tmp_pos1,
668 &str, &str_len, &tmp_pos2);
671 proto_tree_add_text(address_tree, NullTVB, tmp_pos1,
672 item_len, "Type: %s",
673 val_to_str(address_type, krb5_address_types,
674 "Unknown address type %#x"));
675 switch(address_type) {
677 proto_tree_add_text(address_tree, NullTVB, tmp_pos2,
678 str_len, "Value: %d.%d.%d.%d",
679 str[0], str[1], str[2], str[3]);
683 proto_tree_add_text(address_tree, NullTVB, tmp_pos2,
684 str_len, "Value: %s",
685 bytes_to_str(str, str_len));
695 dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
696 proto_tree *tree, int *inoff) {
697 proto_tree *encr_tree = NULL;
705 proto_item *item = NULL;
715 KRB_HEAD_DECODE_OR_DIE("encrypted data section");
718 item = proto_tree_add_text(tree, NullTVB, *inoff, item_len,
719 "Encrypted Data: %s", title);
720 encr_tree = proto_item_add_subtree(item, ett_princ);
724 KRB_HEAD_DECODE_OR_DIE("encryption type");
725 KRB_DECODE_OR_DIE("encr-type", asn1_int32_decode, val);
728 proto_tree_add_text(encr_tree, NullTVB, offset, length,
730 val_to_str(val, krb5_encryption_types,
731 "Unknown encryption type %#x"));
736 KRB_HEAD_DECODE_OR_DIE("kvno-wrap");
737 KRB_DECODE_OR_DIE("kvno", asn1_int32_decode, val);
740 proto_tree_add_text(encr_tree, NullTVB, offset, length,
745 KRB_HEAD_DECODE_OR_DIE("cipher-wrap");
746 KRB_HEAD_DECODE_OR_DIE("cipher");
747 asn1_octet_string_value_decode (asn1p, item_len, &data);
750 proto_tree_add_text(encr_tree, NullTVB, offset, length,
751 "Cipher: %s", bytes_to_str(data, item_len));
760 dissect_ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
763 Ticket ::= [APPLICATION 1] SEQUENCE {
766 sname[2] PrincipalName,
767 enc-part[3] EncryptedData
770 proto_tree *ticket_tree = NULL;
778 proto_item *item = NULL;
789 KRB_HEAD_DECODE_OR_DIE("ticket section");
790 KRB_HEAD_DECODE_OR_DIE("ticket sequence");
793 item = proto_tree_add_text(tree, NullTVB, *inoff, item_len,
795 ticket_tree = proto_item_add_subtree(item, ett_ticket);
799 KRB_HEAD_DECODE_OR_DIE("ticket type");
800 KRB_DECODE_OR_DIE("ticket-type", asn1_int32_decode, val);
803 proto_tree_add_text(ticket_tree, NullTVB, offset, length,
809 KRB_HEAD_DECODE_OR_DIE("realm");
810 dissect_GeneralString(asn1p, &str, &str_len, &item_len);
811 offset += item_len - str_len;
813 proto_tree_add_text(ticket_tree, NullTVB, offset, str_len,
814 "Realm: %.*s", str_len, str);
818 /* server name (sname) */
819 KRB_HEAD_DECODE_OR_DIE("sname");
820 dissect_PrincipalName("Service Name", asn1p, fd, ticket_tree, &offset);
823 KRB_HEAD_DECODE_OR_DIE("enc-part");
824 dissect_EncryptedData("ticket data", asn1p, fd, ticket_tree, &offset);
832 proto_register_kerberos(void) {
834 static hf_register_info hf[] = {
837 static gint *ett[] = {
847 proto_kerberos = proto_register_protocol("Kerberos", "kerberos");
849 proto_register_field_array(proto_kerberos, hf, array_length(hf));
851 proto_register_subtree_array(ett, array_length(ett));
855 proto_reg_handoff_kerberos(void)
857 old_dissector_add("udp.port", UDP_PORT_KERBEROS, dissect_kerberos);
858 old_dissector_add("tcp.port", TCP_PORT_KERBEROS, dissect_kerberos);
863 MISC definitions from RFC1510:
865 KerberosTime ::= GeneralizedTime
866 Realm ::= GeneralString
867 PrincipalName ::= SEQUENCE {
868 name-type[0] INTEGER,
869 name-string[1] SEQUENCE OF GeneralString
871 HostAddress ::= SEQUENCE {
872 addr-type[0] INTEGER,
873 address[1] OCTET STRING
876 HostAddresses ::= SEQUENCE OF SEQUENCE {
877 addr-type[0] INTEGER,
878 address[1] OCTET STRING
881 AS-REQ ::= [APPLICATION 10] KDC-REQ
882 TGS-REQ ::= [APPLICATION 12] KDC-REQ
884 KDC-REQ ::= SEQUENCE {
887 padata[3] SEQUENCE OF PA-DATA OPTIONAL,
888 req-body[4] KDC-REQ-BODY
891 PA-DATA ::= SEQUENCE {
892 padata-type[1] INTEGER,
893 padata-value[2] OCTET STRING,
894 -- might be encoded AP-REQ
897 KDC-REQ-BODY ::= SEQUENCE {
898 kdc-options[0] KDCOptions,
899 cname[1] PrincipalName OPTIONAL,
900 -- Used only in AS-REQ
901 realm[2] Realm, -- Server's realm
902 -- Also client's in AS-REQ
903 sname[3] PrincipalName OPTIONAL,
904 from[4] KerberosTime OPTIONAL,
905 till[5] KerberosTime,
906 rtime[6] KerberosTime OPTIONAL,
908 etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
909 -- in preference order
910 addresses[9] HostAddresses OPTIONAL,
911 enc-authorization-data[10] EncryptedData OPTIONAL,
912 -- Encrypted AuthorizationData encoding
913 additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
916 AS-REP ::= [APPLICATION 11] KDC-REP
917 TGS-REP ::= [APPLICATION 13] KDC-REP
919 KDC-REP ::= SEQUENCE {
922 padata[2] SEQUENCE OF PA-DATA OPTIONAL,
924 cname[4] PrincipalName,
926 enc-part[6] EncryptedData
929 EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart
930 EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
932 EncKDCRepPart ::= SEQUENCE {
933 key[0] EncryptionKey,
936 key-expiration[3] KerberosTime OPTIONAL,
937 flags[4] TicketFlags,
938 authtime[5] KerberosTime,
939 starttime[6] KerberosTime OPTIONAL,
940 endtime[7] KerberosTime,
941 renew-till[8] KerberosTime OPTIONAL,
943 sname[10] PrincipalName,
944 caddr[11] HostAddresses OPTIONAL
947 Ticket ::= [APPLICATION 1] SEQUENCE {
950 sname[2] PrincipalName,
951 enc-part[3] EncryptedData