rxkad-krb5-20021027
authorLove Hörnquist-Åstrand <lha@it.su.se>
Mon, 28 Oct 2002 01:18:38 +0000 (01:18 +0000)
committerJeffrey Hutzleman <jhutz@grand.central.org>
Mon, 28 Oct 2002 01:18:38 +0000 (01:18 +0000)
Added support to rxkad for servers accepting Kerberos V5 tickets and
truncated "proposal 2b" tickets.  When used with an appropriate aklog
or krb524d (such as shipped with Heimdal and MIT Kerberos), this allows
the use of Kerberos V5 tickets (with DES session keys) to authenticate
connections to OpenAFS servers.

21 files changed:
src/libafsrpc/Makefile.in
src/rxkad/Makefile.in
src/rxkad/README.v5 [new file with mode: 0644]
src/rxkad/asn1-common.h [new file with mode: 0644]
src/rxkad/asn1_err.h [new file with mode: 0644]
src/rxkad/crc.c [new file with mode: 0644]
src/rxkad/der.h [new file with mode: 0644]
src/rxkad/rxkad.p.h
src/rxkad/rxkad_prototypes.h
src/rxkad/rxkad_server.c
src/rxkad/test/Makefile.in
src/rxkad/test/stress.c
src/rxkad/test/stress_c.c
src/rxkad/test/stress_internal.h
src/rxkad/test/stress_s.c
src/rxkad/ticket5.c [new file with mode: 0644]
src/rxkad/v5der.c [new file with mode: 0644]
src/rxkad/v5gen-rewrite.h [new file with mode: 0644]
src/rxkad/v5gen.c [new file with mode: 0644]
src/rxkad/v5gen.h [new file with mode: 0644]
src/shlibafsrpc/Makefile.in

index 0c3a455..7b905a2 100644 (file)
@@ -83,6 +83,8 @@ RXKADOBJS =\
        rxkad_server.o \
        rxkad_common.o \
        ticket.o \
+       ticket5.o \
+       crc.o \
        fcrypt.o \
        crypt_conn.o
 
@@ -182,6 +184,12 @@ rxkad_common.o: ${RXKAD}/rxkad_common.c
 ticket.o: ${RXKAD}/ticket.c
        ${CCRULE}
 
+ticket5.o: ${RXKAD}/ticket5.c
+       ${CCRULE}
+
+crc.o: ${RXKAD}/crc.c
+       ${CCRULE}
+
 fcrypt.o: ${RXKAD}/fcrypt.c
        ${CCRULE}
 
index cab3d1d..21bb102 100644 (file)
@@ -11,10 +11,10 @@ include @TOP_OBJDIR@/src/config/Makefile.config
 CFLAGS=-I. -I${srcdir} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
 INCLS=${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \
        ${TOP_INCDIR}/rx/fcrypt.h \
-       rxkad.h rxkad_prototypes.h fcrypt.h
+       rxkad.h rxkad_prototypes.h fcrypt.h v5gen.h
 
-OBJS=rxkad_client.o rxkad_server.o rxkad_common.o ticket.o rxkad_errs.o \
-       fcrypt.o crypt_conn.o
+OBJS=rxkad_client.o rxkad_server.o rxkad_common.o rxkad_errs.o \
+       fcrypt.o crypt_conn.o ticket.o ticket5.o crc.o
 
 fc_test_OBJS=fc_test.o
 
@@ -77,6 +77,10 @@ rxkad_errs.c rxkad.h: rxkad_errs.et rxkad.p.h
 
 ticket.o: ticket.c lifetimes.h ${INCLS}
 
+ticket5.o: ticket5.c v5gen.c v5der.c v5gen-rewrite.h ${INCLS}
+
+crc.o: crc.c ${INCLS}
+
 fcrypt.o: fcrypt.c fcrypt.h sboxes.h rxkad.h rxkad_prototypes.h
        ${CC} ${CFLAGS} -c fcrypt.c
 
diff --git a/src/rxkad/README.v5 b/src/rxkad/README.v5
new file mode 100644 (file)
index 0000000..379372f
--- /dev/null
@@ -0,0 +1,90 @@
+#
+#  This code depends on heimdal's asn1_compile generated krb5 decoding
+#  stuff. The code is orignally from rxkad that Björn Grönvall
+#  <bg@sics.se> for kth-krb and was included in Arla.
+# 
+#  The first file, v5der.c are part for of support functions
+#  that all generated files depends on.
+# 
+#  The second file (v5gen.h) is the headerfile that is generated for
+#  the decoding functions.
+# 
+#  The third file (v5gen.c) is the subset of the genrated functions we
+#  need to decode the authenticator.
+# 
+#  The forth file (v5gen-rewrite.h) is used to make sure we don't
+#  polute the namespace.
+# 
+#  All files are modified to build within OpenAFS enviroment without
+#  any external dependencies. Below is the shellscript that is used to
+#  import the code into the four files.
+# 
+#  All internal symbols are rewritten to _rxkad_v5_.
+#
+
+# Make sure we don't export too much
+# 
+# : lha@nutcracker ; nm ticket5.o | grep T | grep -v _rxkad_v5 
+# 00005748 T tkt_DecodeTicket5
+#
+
+
+htree=/home/lha/src/cvs/heimdal
+hotree=/sources/obj/heimdal
+otree=/sources/afs/openafs-rxkad5
+
+export htree otree
+
+(cd $htree/lib/asn1 ; \
+ echo '#include "asn1_err.h"'; 
+ echo '#include <errno.h>'; 
+ cat der_get.c \
+ der_put.c \
+ der_free.c \
+ der_length.c \
+ der_copy.c \
+ timegm.c \
+    )  \
+| grep -v 'include "der_locl.h"' \
+| grep -v 'include <version.h>' \
+| sed 's!\(RCSID.*\)!/* \1 */!' \
+| sed 's!$Id: !Heimdal: !' \
+| cat > $otree/src/rxkad/v5der.c
+
+grep -v 'struct units'  $hotree/lib/asn1/krb5_asn1.h \
+   > $otree/src/rxkad/v5gen.h
+
+(cd $hotree/lib/asn1 ; \
+ cat asn1_Ticket.c \
+    asn1_EncryptedData.c \
+    asn1_PrincipalName.c \
+    asn1_HostAddresses.c \
+    asn1_HostAddress.c \
+    asn1_AuthorizationData.c \
+    asn1_EncTicketPart.c \
+    asn1_KerberosTime.c \
+    asn1_TransitedEncoding.c \
+    asn1_EncryptionKey.c \
+    asn1_TicketFlags.c \
+    asn1_Realm.c \
+    asn1_ENCTYPE.c \
+    asn1_NAME_TYPE.c \
+    ) \
+ | grep -v 'include <krb5_asn1.h>' \
+ | grep -v 'include <der.h>' \
+ | grep -v 'include <parse_units.h>' \
+ | perl \
+   -e '$f=0; while(<>){$f=1 if(/struct units/);print if($f eq 0);$f=0 if(/^};/);}' \
+ | cat > $otree/src/rxkad/v5gen.c
+
+( \
+ perl -p -e 's/^(encode_|decode_|free_|copy_|length_)([^(]*)\([^)]*\)\n$/#define $1$2 _rxkad_v5_$1$2\n/' $otree/src/rxkad/v5gen.c ; \
+  perl -p -e 's/^(der_|copy_|encode_|decode_|len_|length_|free_|fix_dce|time2generalizedtime)([^(]*).*/#define $1$2 _rxkad_v5_$1$2/' /sources/afs/openafs-krb5/src/rxkad/v5der.c ; \
+  echo '#define TicketFlags2int _rxkad_v5_TicketFlags2int' ; \
+  echo '#define int2TicketFlags _rxkad_v5_int2TicketFlags' ; \
+  : ) | \
+ (grep _rxkad_v5 ; \
+  echo '#ifndef HAVE_TIMEGM' ; \
+  echo '#define timegm _rxkad_timegm' ; \
+  echo '#endif' ; \
+  :) > $otree/src/rxkad/v5gen-rewrite.h
diff --git a/src/rxkad/asn1-common.h b/src/rxkad/asn1-common.h
new file mode 100644 (file)
index 0000000..6f470d7
--- /dev/null
@@ -0,0 +1,21 @@
+/* $Id$ */
+
+#include <stddef.h>
+#include <time.h>
+
+#ifndef __asn1_common_definitions__
+#define __asn1_common_definitions__
+
+typedef struct octet_string {
+    size_t length;
+    void *data;
+} octet_string;
+
+typedef char *general_string;
+
+typedef struct oid {
+    size_t length;
+    unsigned *components;
+} oid;
+
+#endif
diff --git a/src/rxkad/asn1_err.h b/src/rxkad/asn1_err.h
new file mode 100644 (file)
index 0000000..fe81da9
--- /dev/null
@@ -0,0 +1,23 @@
+/* Generated from ../../../lib/asn1/asn1_err.et */
+/* $Id$ */
+
+#ifndef __asn1_err_h__
+#define __asn1_err_h__
+
+typedef enum asn1_error_number{
+       ERROR_TABLE_BASE_asn1 = 1859794432,
+       asn1_err_base = 1859794432,
+       ASN1_BAD_TIMEFORMAT = 1859794432,
+       ASN1_MISSING_FIELD = 1859794433,
+       ASN1_MISPLACED_FIELD = 1859794434,
+       ASN1_TYPE_MISMATCH = 1859794435,
+       ASN1_OVERFLOW = 1859794436,
+       ASN1_OVERRUN = 1859794437,
+       ASN1_BAD_ID = 1859794438,
+       ASN1_BAD_LENGTH = 1859794439,
+       ASN1_BAD_FORMAT = 1859794440,
+       ASN1_PARSE_ERROR = 1859794441,
+       asn1_num_errors = 10
+} asn1_error_number;
+
+#endif /* __asn1_err_h__ */
diff --git a/src/rxkad/crc.c b/src/rxkad/crc.c
new file mode 100644 (file)
index 0000000..a89f44d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* RCSID("$Heimdal: crc.c,v 1.9 2000/08/03 01:45:14 assar Exp $"); */
+
+#include <afsconfig.h>
+#if defined(UKERNEL)
+#include "../afs/param.h"
+#else
+#include <afs/param.h>
+#endif
+
+RCSID("$Header$");
+
+#if defined(UKERNEL)
+#include "../afs/sysincludes.h"
+#include "../afs/afsincludes.h"
+#include "../afs/stds.h"
+#include "../rx/xdr.h"
+#include "../rx/rx.h"
+#include "../des/des.h"
+#include "../afs/lifetimes.h"
+#include "../afs/rxkad.h"
+#else /* defined(UKERNEL) */
+#include <afs/stds.h>
+#include <sys/types.h>
+#ifdef AFS_NT40_ENV
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#include <rx/xdr.h>
+#include <rx/rx.h>
+#include <des.h>
+#include "lifetimes.h"
+#include "rxkad.h"
+#endif /* defined(UKERNEL) */
+
+static u_long table[256];
+
+#define CRC_GEN 0xEDB88320L
+
+void
+_rxkad_crc_init_table(void)
+{
+    static int flag = 0;
+    unsigned long crc, poly;
+    int     i, j;
+    
+    if(flag) return;
+    poly = CRC_GEN;
+    for (i = 0; i < 256; i++) {
+       crc = i;
+       for (j = 8; j > 0; j--) {
+           if (crc & 1) {
+               crc = (crc >> 1) ^ poly;
+           } else {
+               crc >>= 1;
+           }
+       }
+       table[i] = crc;
+    }
+    flag = 1;
+}
+
+afs_uint32
+_rxkad_crc_update (const char *p, size_t len, afs_uint32 res)
+{
+    while (len--)
+       res = table[(res ^ *p++) & 0xFF] ^ (res >> 8);
+    return res & 0xFFFFFFFF;
+}
diff --git a/src/rxkad/der.h b/src/rxkad/der.h
new file mode 100644 (file)
index 0000000..cd2a40a
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id$ */
+
+#ifndef __DER_H__
+#define __DER_H__
+
+#include <time.h>
+
+typedef enum {UNIV = 0, APPL = 1, CONTEXT = 2 , PRIVATE = 3} Der_class;
+
+typedef enum {PRIM = 0, CONS = 1} Der_type;
+
+/* Universal tags */
+
+enum {
+     UT_Boolean                = 1,
+     UT_Integer                = 2,
+     UT_BitString      = 3,
+     UT_OctetString    = 4,
+     UT_Null           = 5,
+     UT_OID            = 6,
+     UT_Enumerated     = 10,
+     UT_Sequence       = 16,
+     UT_Set            = 17,
+     UT_PrintableString        = 19,
+     UT_IA5String      = 22,
+     UT_UTCTime                = 23,
+     UT_GeneralizedTime        = 24,
+     UT_VisibleString  = 26,
+     UT_GeneralString  = 27
+};
+
+#define ASN1_INDEFINITE 0xdce0deed
+
+#ifndef HAVE_TIMEGM
+time_t timegm (struct tm *);
+#endif
+
+int time2generalizedtime (time_t t, octet_string *s);
+
+int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size);
+int der_get_length (const unsigned char *p, size_t len,
+                   size_t *val, size_t *size);
+int der_get_general_string (const unsigned char *p, size_t len, 
+                           general_string *str, size_t *size);
+int der_get_octet_string (const unsigned char *p, size_t len, 
+                         octet_string *data, size_t *size);
+int der_get_oid (const unsigned char *p, size_t len,
+                oid *data, size_t *size);
+int der_get_tag (const unsigned char *p, size_t len, 
+                Der_class *class, Der_type *type,
+                int *tag, size_t *size);
+
+int der_match_tag (const unsigned char *p, size_t len, 
+                  Der_class class, Der_type type,
+                  int tag, size_t *size);
+int der_match_tag_and_length (const unsigned char *p, size_t len,
+                             Der_class class, Der_type type, int tag,
+                             size_t *length_ret, size_t *size);
+
+int decode_integer (const unsigned char*, size_t, int*, size_t*);
+int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*);
+int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*);
+int decode_general_string (const unsigned char*, size_t,
+                          general_string*, size_t*);
+int decode_oid (const unsigned char *p, size_t len, 
+               oid *k, size_t *size);
+int decode_octet_string (const unsigned char*, size_t, octet_string*, size_t*);
+int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*);
+
+int der_put_int (unsigned char *p, size_t len, int val, size_t*);
+int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
+int der_put_general_string (unsigned char *p, size_t len,
+                           const general_string *str, size_t*);
+int der_put_octet_string (unsigned char *p, size_t len,
+                         const octet_string *data, size_t*);
+int der_put_oid (unsigned char *p, size_t len,
+                const oid *data, size_t *size);
+int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+                int tag, size_t*);
+int der_put_length_and_tag (unsigned char*, size_t, size_t, 
+                           Der_class, Der_type, int, size_t*);
+
+int encode_integer (unsigned char *p, size_t len,
+                   const int *data, size_t*);
+int encode_unsigned (unsigned char *p, size_t len,
+                    const unsigned *data, size_t*);
+int encode_enumerated (unsigned char *p, size_t len,
+                      const unsigned *data, size_t*);
+int encode_general_string (unsigned char *p, size_t len, 
+                          const general_string *data, size_t*);
+int encode_octet_string (unsigned char *p, size_t len,
+                        const octet_string *k, size_t*);
+int encode_oid (unsigned char *p, size_t len,
+               const oid *k, size_t*);
+int encode_generalized_time (unsigned char *p, size_t len,
+                            const time_t *t, size_t*);
+
+void free_integer (int *num);
+void free_general_string (general_string *str);
+void free_octet_string (octet_string *k);
+void free_oid (oid *k);
+void free_generalized_time (time_t *t);
+
+size_t length_len (size_t len);
+size_t length_integer (const int *data);
+size_t length_unsigned (const unsigned *data);
+size_t length_enumerated (const unsigned *data);
+size_t length_general_string (const general_string *data);
+size_t length_octet_string (const octet_string *k);
+size_t length_oid (const oid *k);
+size_t length_generalized_time (const time_t *t);
+
+int copy_general_string (const general_string *from, general_string *to);
+int copy_octet_string (const octet_string *from, octet_string *to);
+int copy_oid (const oid *from, oid *to);
+
+int fix_dce(size_t reallen, size_t *len);
+
+#endif /* __DER_H__ */
index c64fb27..4825d4d 100644 (file)
@@ -36,6 +36,9 @@
  * passed to/from ktc_[SG]etToken.
  */
 #define RXKAD_TKT_TYPE_KERBEROS_V5             256
+#define RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY        213
+
+#define MAXKRB5TICKETLEN                       1024
 
 /*
  * The AFS/DFS translator may also make use of additional ticket types in
index 3767513..408ed50 100644 (file)
@@ -97,5 +97,17 @@ extern afs_int32 ktohl (char flags, afs_int32 l);
 extern afs_uint32 life_to_time (afs_uint32 start, unsigned char life);
 extern unsigned char time_to_life (afs_uint32 start, afs_uint32 end);
 
+/* ticket5.c */
+extern int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, 
+                     int (*get_key)(char *, int, struct ktc_encryptionKey *),
+                     char *get_key_rock,
+                     int serv_kvno,
+                     char *name, 
+                     char *inst, 
+                     char *cell, 
+                     char *session_key, 
+                     afs_int32 *host, 
+                     afs_int32 *start, 
+                     afs_int32 *end);
 
 #endif
index 11d6948..94e9df3 100644 (file)
@@ -303,6 +303,23 @@ int rxkad_CheckResponse (struct rx_securityClass *aobj,
      * If the alternate decoder is not present, or returns -1, then
      * assume the ticket is of the default style.
      */
+    if (code == -1 && 
+       (kvno == RXKAD_TKT_TYPE_KERBEROS_V5) ||
+       (kvno == RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY)) 
+    {
+       code = tkt_DecodeTicket5 (tix, tlen, 
+                                 tsp->get_key,
+                                 tsp->get_key_rock,
+                                 kvno,
+                                 client.name, client.instance, client.cell,
+                                 &sessionkey, &host, &start, &end);
+       if (code) return RXKADBADTICKET;
+    }
+
+    /*
+     * If the alternate decoder/kerberos 5 decoder is not present, or
+     * returns -1, then assume the ticket is of the default style.
+     */
     if (code == -1) {
        /* get ticket's key */
        code = (*tsp->get_key)(tsp->get_key_rock, kvno, &serverKey);
index faca0a8..34e8290 100644 (file)
@@ -13,8 +13,10 @@ CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
 
 HEADERS = ../rxkad.h stress.h stress_internal.h stress_errs.h
 
-LIBS=${TOP_LIBDIR}/librx.a \
+LIBS=${TOP_LIBDIR}/libauth.a \
+       ${TOP_LIBDIR}/librx.a \
        ${TOP_LIBDIR}/liblwp.a \
+       ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/librxkad.a \
        ${TOP_LIBDIR}/libdes.a \
index c11fa3e..a457006 100644 (file)
@@ -89,6 +89,9 @@ static int StringToAuth (authname)
 #define aRECLAIM     21
 #define a2DCHOICE     22
 #define aMAXSKEW       23
+#define aUSETOKENS 24
+#define aCELL 25
+#define aKEYFILE 26
 
 static int CommandProc (as, arock)
   char *arock;
@@ -122,6 +125,7 @@ static int CommandProc (as, arock)
     cParms->callTest = (as->parms[aCALLTEST].items != 0);
     cParms->hijackTest = (as->parms[aHIJACKTEST].items != 0);
     cParms->stopServer = (as->parms[aSTOPSERVER].items != 0);
+    cParms->useTokens = (as->parms[aUSETOKENS].items != 0);
 
     if (as->parms[aMELT1b].items) 
        meltdown_1pkt = 0; 
@@ -151,6 +155,8 @@ static int CommandProc (as, arock)
        if (as->parms[aMINSERVERAUTH].items)
            sParms->authentication =
                StringToAuth (as->parms[aMINSERVERAUTH].items->data);
+        if (as->parms[aKEYFILE].items)
+            sParms->keyfile = as->parms[aKEYFILE].items->data;
 
 #ifdef AFS_PTHREAD_ENV
        {
@@ -231,6 +237,9 @@ static int CommandProc (as, arock)
        if (as->parms[aAUTHENTICATION].items)
            cParms->authentication =
                StringToAuth (as->parms[aAUTHENTICATION].items->data);
+        cParms->cell = RXKST_CLIENT_CELL;
+        if (as->parms[aCELL].items)
+            cParms->cell = as->parms[aCELL].items->data;
 
        code = rxkst_StartClient (cParms);
        if (code) {
@@ -268,6 +277,7 @@ void main (argc, argv)
     initialize_RXK_error_table();
     initialize_RKS_error_table();
     initialize_CMD_error_table();
+    initialize_KTC_error_table();
 
     code = rx_Init (0);
     rx_SetRxDeadTime(120);
@@ -308,6 +318,9 @@ void main (argc, argv)
     cmd_AddParm (ts, "-noreclaim", CMD_FLAG, CMD_OPTIONAL, "dont aggressively reclaim packets");
     cmd_AddParm (ts, "-no2dchoice", CMD_FLAG, CMD_OPTIONAL, "disable rx_getcall 2d choice code");
     cmd_AddParm (ts, "-maxskew", CMD_SINGLE, CMD_OPTIONAL, "max client server skew in seconds");
+    cmd_AddParm (ts, "-usetokens", CMD_FLAG, CMD_OPTIONAL, "use ktc tokens");
+    cmd_AddParm (ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "name of test cell");
+    cmd_AddParm (ts, "-keyfile", CMD_SINGLE, CMD_OPTIONAL, "read server key from file");
 
     code = cmd_Dispatch (argc, argv);
     exit (code!=0);
index aac2536..bd75c68 100644 (file)
@@ -26,6 +26,7 @@ RCSID("$Header$");
 #include <afs/com_err.h>
 #include <afs/afsutil.h>
 #include <rx/rxkad.h>
+#include <afs/auth.h>
 #include "stress.h"
 #include "stress_internal.h"
 #ifdef AFS_PTHREAD_ENV
@@ -52,7 +53,30 @@ static long GetServer(aname)
     return addr;
 }
 
-static long GetTicket (versionP, session, ticketLenP, ticket)
+static long GetToken (versionP, session, ticketLenP, ticket, cell)
+  OUT long *versionP;
+  OUT struct ktc_encryptionKey *session;
+  OUT int *ticketLenP;
+  OUT char *ticket;
+{
+  struct ktc_principal sname;
+  struct ktc_token ttoken;
+    long code;
+
+  strcpy(sname.cell, cell);
+  sname.instance[0] = 0;
+  strcpy(sname.name, "afs");
+  code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
+  if (code) return code;
+
+  *versionP = ttoken.kvno;
+  *ticketLenP = ttoken.ticketLen;
+  memcpy(ticket, ttoken.ticket, ttoken.ticketLen);
+  memcpy(session, &ttoken.sessionKey, sizeof(struct ktc_encryptionKey));
+  return 0;
+}
+
+static long GetTicket (versionP, session, ticketLenP, ticket, cell)
   OUT long *versionP;
   OUT struct ktc_encryptionKey *session;
   OUT int *ticketLenP;
@@ -68,7 +92,7 @@ static long GetTicket (versionP, session, ticketLenP, ticket)
     /* now create the actual ticket */
     *ticketLenP = 0;
     code = tkt_MakeTicket(ticket, ticketLenP, &serviceKey,
-                         RXKST_CLIENT_NAME, RXKST_CLIENT_INST, "",
+                         RXKST_CLIENT_NAME, RXKST_CLIENT_INST, cell,
                          /*start,end*/0, 0xffffffff, session, /*host*/0,
                          RXKST_SERVER_NAME, RXKST_SERVER_NAME);
     /* parms were buffer, ticketlen, key to seal ticket with, principal name,
@@ -1142,7 +1166,10 @@ long rxkst_StartClient (parms)
        int ticketLen;
        struct ktc_encryptionKey Ksession;
 
-       code = GetTicket (&kvno, &Ksession, &ticketLen, ticket);
+       if (parms->useTokens)
+           code = GetToken (&kvno, &Ksession, &ticketLen, ticket, parms->cell);
+       else
+           code = GetTicket (&kvno, &Ksession, &ticketLen, ticket, parms->cell);
        if (code) return code;
 
        /* next, we have ticket, kvno and session key, authenticate the conn */
index efc5394..61d3905 100644 (file)
@@ -19,6 +19,7 @@ extern long serviceKeyVersion;
 #define RXKST_SERVER_INST ""
 #define RXKST_CLIENT_NAME "rxkad_stress_test_client"
 #define RXKST_CLIENT_INST ""
+#define RXKST_CLIENT_CELL "rxtest.openafs.org"
 
 extern int errno;
 
@@ -26,6 +27,7 @@ struct serverParms {
     char *whoami;
     u_int threads;
     int authentication;                        /* minimum level  of auth to permit */
+    char *keyfile;
 };
 
 struct clientParms {
@@ -44,6 +46,8 @@ struct clientParms {
     int hijackTest;                    /* check hijack prevention measures */
     int stopServer;                    /* send stop server RPC */
     int authentication;                        /* type of authentication to use */
+    int useTokens;                     /* use user's existing tokens */
+    char *cell;                         /* test cell name */
     u_long repeatInterval;             /* secs between load test activity */
     u_long repeatCount;                        /* times load test activity repeated */
 };
@@ -51,11 +55,6 @@ struct clientParms {
 long rxkst_StartClient(INOUT struct clientParms *parms);
 long rxkst_StartServer(INOUT struct serverParms *parms);
 
-long RXKST_Fast();
-long RXKST_Slow();
-long RXKST_Copious();
-long RXKST_Kill();
-
 /* For backward compatibility with AFS3.0 release. */
 
 #ifndef assert
index ceb7789..0df3725 100644 (file)
@@ -16,6 +16,7 @@ RCSID("$Header$");
 
 #include <afs/stds.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #ifdef AFS_NT40_ENV
 #include <winsock2.h>
@@ -26,6 +27,9 @@ RCSID("$Header$");
 
 #include <rx/rxkad.h>
 
+#include <afs/keys.h>
+#include <afs/cellconfig.h>
+
 #include "stress.h"
 #include "stress_internal.h"
 
@@ -41,8 +45,38 @@ static long GetKey (rock, kvno, key)
   IN long  kvno;
   OUT struct ktc_encryptionKey *key;
 {
-    memcpy(key, &serviceKey, sizeof(*key));
-    return 0;
+    struct serverParms *parms = (struct serverParms *)rock;
+    struct afsconf_keys tstr;
+    afs_int32 code;
+    int fd;
+
+    fprintf(stderr, "GetKey called for kvno %d\n", kvno);
+    if (!parms->keyfile) {
+        memcpy(key, &serviceKey, sizeof(*key));
+        return 0;
+    }
+
+    /* the rest of this function borrows heavily from auth/cellconfig.c */
+    fd = open(parms->keyfile, O_RDONLY);
+    if (fd < 0) {
+        return AFSCONF_FAILURE;
+    }
+    code = read(fd, &tstr, sizeof(struct afsconf_keys));
+    close(fd);
+    if (code < sizeof(afs_int32)) {
+        return AFSCONF_FAILURE;
+    }
+
+    /* convert key structure to host order */
+    tstr.nkeys = ntohl(tstr.nkeys);
+    for(fd = 0; fd < tstr.nkeys; fd++) {
+        if (kvno == ntohl(tstr.key[fd].kvno)) {
+            memcpy(key, tstr.key[fd].key, sizeof(*key));
+            return 0;
+        }
+    }
+
+    return AFSCONF_NOTFOUND;
 }
 
 static int minAuth;
@@ -61,7 +95,7 @@ long rxkst_StartServer (parms)
 
     sc[0] = rxnull_NewServerSecurityObject();
     sc[1] = 0;                         /* no rxvab anymore */
-    sc[2] = rxkad_NewServerSecurityObject (minLevel, 0, GetKey, 0);
+    sc[2] = rxkad_NewServerSecurityObject (minLevel, (void *)parms, GetKey, 0);
     tservice = rx_NewService(htons(RXKST_SERVICEPORT), RXKST_SERVICEID,
                             "stress test", sc, 3, RXKST_ExecuteRequest);
     if (tservice == (struct rx_service *)0) {
@@ -77,6 +111,10 @@ long rxkst_StartServer (parms)
     return 0;
 }
 
+static char test_client_name[MAXKTCNAMELEN];
+static char test_client_inst[MAXKTCNAMELEN];
+static char test_client_cell[MAXKTCREALMLEN];
+static int got_client_id = 0;
 static long CheckAuth (call)
   IN struct rx_call *call;
 {
@@ -105,16 +143,23 @@ static long CheckAuth (call)
                                name, inst, cell, &kvno);
     if (code) return code;
     if (minAuth > level) return -1;
-    if (kvno != serviceKeyVersion) return RXKST_BADKVNO;
-    if (strcmp (name, RXKST_CLIENT_NAME) ||
-       strcmp (inst, RXKST_CLIENT_INST) ||
-       cell[0]) return RXKST_BADCLIENT;
+    fprintf(stderr, "Test client is %s.%s@%s\n", name, inst, cell);
+    if (got_client_id) {
+        if (strcmp(name, test_client_name)) return RXKST_BADCLIENT;
+        if (strcmp(inst, test_client_inst)) return RXKST_BADCLIENT;
+        if (strcmp(cell, test_client_cell)) return RXKST_BADCLIENT;
+    } else {
+        strcpy(test_client_name, name);
+        strcpy(test_client_inst, inst);
+        strcpy(test_client_cell, cell);
+        got_client_id = 1;
+    }
     return 0;
 }
 
 /* Stop the server.  There isn't a graceful way to do this so just exit. */
 
-long SRXKST_Kill (call)
+afs_int32 SRXKST_Kill (call)
   IN struct rx_call *call;
 {
     long code;
@@ -131,7 +176,7 @@ long SRXKST_Kill (call)
     return 0;    
 }
 
-long SRXKST_Fast (call, n, inc_nP)
+afs_int32 SRXKST_Fast (call, n, inc_nP)
   IN struct rx_call *call;
   IN u_long n;
   OUT u_long *inc_nP;
@@ -140,7 +185,7 @@ long SRXKST_Fast (call, n, inc_nP)
     return 0;
 }
 
-long SRXKST_Slow (call, tag, nowP)
+afs_int32 SRXKST_Slow (call, tag, nowP)
   IN struct rx_call *call;
   IN u_long tag;
   OUT u_long *nowP;
@@ -184,7 +229,7 @@ static void PutBuffer(b)
     buflist = bl;
 }
 
-long SRXKST_Copious (call, inlen, insum, outlen, outsum)
+afs_int32 SRXKST_Copious (call, inlen, insum, outlen, outsum)
   IN struct rx_call *call;
   IN u_long inlen;
   IN u_long insum;
diff --git a/src/rxkad/ticket5.c b/src/rxkad/ticket5.c
new file mode 100644 (file)
index 0000000..f9b5229
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <afsconfig.h>
+#if defined(UKERNEL)
+#include "../afs/param.h"
+#else
+#include <afs/param.h>
+#endif
+
+RCSID("$Header$");
+
+#if defined(UKERNEL)
+#include "../afs/sysincludes.h"
+#include "../afs/afsincludes.h"
+#include "../afs/stds.h"
+#include "../rx/xdr.h"
+#include "../rx/rx.h"
+#include "../des/des.h"
+#include "../afs/lifetimes.h"
+#include "../afs/rxkad.h"
+#else /* defined(UKERNEL) */
+#include <afs/stds.h>
+#include <sys/types.h>
+#ifdef AFS_NT40_ENV
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#include <rx/xdr.h>
+#include <rx/rx.h>
+#include <des.h>
+#include "lifetimes.h"
+#include "rxkad.h"
+#endif /* defined(UKERNEL) */
+
+#include "v5gen-rewrite.h"
+#include "asn1-common.h"
+#include "der.h"
+#include "v5gen.h"
+#include "v5der.c"
+#include "v5gen.c"
+
+static int
+krb5_des_decrypt(struct ktc_encryptionKey *, 
+                int, void *, size_t, void *, size_t *);
+
+
+
+
+int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, 
+                     int (*get_key)(char *, int, struct ktc_encryptionKey *),
+                     char *get_key_rock,
+                     int serv_kvno,
+                     char *name, 
+                     char *inst, 
+                     char *cell, 
+                     char *session_key, 
+                     afs_int32 *host, 
+                     afs_int32 *start, 
+                     afs_int32 *end)
+{
+    char plain[MAXKRB5TICKETLEN];
+    struct ktc_encryptionKey serv_key;
+    Ticket t5; /* Must free */
+    EncTicketPart decr_part;   /* Must free */
+    int code;
+    size_t siz, plainsiz;
+    int v5_serv_kvno;
+
+    memset(&t5, 0, sizeof(t5));
+    memset(&decr_part, 0, sizeof(decr_part));
+
+    *host = 0;
+
+    if (ticket_len == 0)
+       return RXKADBADTICKET; /* no ticket */
+
+    if (serv_kvno == RXKAD_TKT_TYPE_KERBEROS_V5) {
+       code = decode_Ticket(ticket, ticket_len, &t5, &siz);
+       if (code != 0)
+           goto cleanup;
+
+       if (t5.tkt_vno != 5)
+           goto bad_ticket;
+    } else {
+       code = decode_EncryptedData(ticket, ticket_len, &t5.enc_part, &siz);
+       if (code != 0)
+           goto cleanup;
+    }
+
+    /* Find the real service key version number */
+    if (t5.enc_part.kvno == NULL)
+       goto bad_ticket;
+    v5_serv_kvno = *t5.enc_part.kvno;
+    
+
+    code = (*get_key)(get_key_rock, v5_serv_kvno, &serv_key);
+    if (code)
+       goto unknown_key;
+
+    /* Check that the key type really fit into 8 bytes */
+    switch (t5.enc_part.etype) {
+    case ETYPE_DES_CBC_CRC:
+    case ETYPE_DES_CBC_MD4:
+    case ETYPE_DES_CBC_MD5:
+       break;
+    default:
+       goto unknown_key;
+    }
+
+    /* check ticket */
+    if (t5.enc_part.cipher.length > sizeof(plain) ||
+       t5.enc_part.cipher.length % 8 != 0)
+       goto bad_ticket;
+
+    /* Decrypt data here, save in plain, assume it will shrink */
+    code = krb5_des_decrypt(&serv_key,
+                           t5.enc_part.etype,
+                           t5.enc_part.cipher.data,
+                           t5.enc_part.cipher.length,
+                           plain,
+                           &plainsiz);
+    if (code != 0)
+       goto bad_ticket;
+
+    /* Decode ticket */
+    code = decode_EncTicketPart(plain, plainsiz, &decr_part, &siz);
+    if (code != 0)
+       goto bad_ticket;
+    
+    /* Extract realm and principal */  
+    strncpy(cell, decr_part.crealm, MAXKTCNAMELEN);
+    cell[MAXKTCNAMELEN - 1] = '\0';
+    inst[0] = '\0';
+    switch (decr_part.cname.name_string.len) {
+    case 2:
+       strncpy(inst, decr_part.cname.name_string.val[1], MAXKTCNAMELEN);
+       inst[MAXKTCNAMELEN - 1] = '\0';
+    case 1:
+       strncpy(name, decr_part.cname.name_string.val[0], MAXKTCNAMELEN);
+       name[MAXKTCNAMELEN - 1] = '\0';
+       break;
+    default:
+       goto bad_ticket;
+    }
+    
+    /* Verify that decr_part.key is of right type */
+    switch (decr_part.key.keytype) {
+    case ETYPE_DES_CBC_CRC:
+    case ETYPE_DES_CBC_MD4:
+    case ETYPE_DES_CBC_MD5:
+       break;
+    default:
+       goto bad_ticket;
+    }
+
+    if (decr_part.key.keyvalue.length != 8)
+       goto bad_ticket;
+
+    /* Extract session key */
+    memcpy(session_key, decr_part.key.keyvalue.data, 8);
+    
+    /* Check lifetimes and host addresses, flags etc */
+    {
+       time_t now = time(0);   /* Use fast time package instead??? */
+       *start = decr_part.authtime;
+       if (decr_part.starttime)
+           *start = *decr_part.starttime;
+#if 0
+       if (*start - now > CLOCK_SKEW || decr_part.flags.invalid)
+           goto no_auth;
+#else
+       if (decr_part.flags.invalid)
+           goto no_auth;
+#endif
+       if (now > decr_part.endtime)
+           goto tkt_expired;
+       *end = decr_part.endtime;
+    }
+
+ cleanup:
+    if (serv_kvno == RXKAD_TKT_TYPE_KERBEROS_V5)
+       free_Ticket(&t5);
+    else
+       free_EncryptedData(&t5.enc_part);
+    free_EncTicketPart(&decr_part);
+    memset(&serv_key, 0, sizeof(serv_key));
+    return code;
+
+ unknown_key:
+    code = RXKADUNKNOWNKEY;
+    goto cleanup;
+ no_auth:
+    code = RXKADNOAUTH;
+    goto cleanup;
+ tkt_expired:
+    code = RXKADEXPIRED;
+    goto cleanup;
+ bad_ticket:
+    code = RXKADBADTICKET;
+    goto cleanup;
+
+}
+
+static int
+verify_checksum_crc(void *data, size_t len,
+                   void *cksum, size_t cksumsz, 
+                   struct ktc_encryptionKey *key)
+{
+    afs_uint32 crc;
+    char r[4];
+
+    _rxkad_crc_init_table ();
+    crc = _rxkad_crc_update (data, len, 0);
+    r[0] = crc & 0xff;
+    r[1] = (crc >> 8)  & 0xff;
+    r[2] = (crc >> 16) & 0xff;
+    r[3] = (crc >> 24) & 0xff;
+    
+    if (memcmp(cksum, r, 4) != 0)
+       return 1;
+    return 0;
+}
+
+
+static int
+krb5_des_decrypt(struct ktc_encryptionKey *key,
+                int etype,
+                void *in, size_t insz,
+                void *out, size_t *outsz)
+{
+    int (*cksum_func)(void *,size_t,void *,size_t,struct ktc_encryptionKey *);
+    des_cblock ivec;
+    des_key_schedule s;
+    char cksum[24];
+    size_t cksumsz;
+    int ret;
+
+    cksum_func = NULL;
+
+    des_key_sched(key, &s);
+
+#define CONFOUNDERSZ 8
+
+    switch (etype) {
+    case ETYPE_DES_CBC_CRC:
+       memcpy(&ivec, key, sizeof(ivec));
+       cksumsz = 4;
+       cksum_func = verify_checksum_crc;
+       break;
+    case ETYPE_DES_CBC_MD4:
+       memset(&ivec, 0, sizeof(ivec));
+       cksumsz = 16;
+       /* FIXME: cksum_func = verify_checksum_md4 */;
+       break;
+    case ETYPE_DES_CBC_MD5:
+       memset(&ivec, 0, sizeof(ivec));
+       cksumsz = 16;
+       /* FIXME: cksum_func = verify_checksum_md5 */;
+       break;
+    default:
+       abort();
+    }
+
+    des_cbc_encrypt(in, out, insz, s, &ivec, 0);
+
+    memcpy(cksum, (char *)out + CONFOUNDERSZ, cksumsz);
+    memset((char *)out + CONFOUNDERSZ, 0, cksumsz);
+
+    if (cksum_func)
+       ret = (*cksum_func)(out, insz, cksum, cksumsz, key);
+
+    *outsz = insz - CONFOUNDERSZ - cksumsz;
+    memmove(out, (char *)out + CONFOUNDERSZ + cksumsz, *outsz);
+
+    return ret;
+}
diff --git a/src/rxkad/v5der.c b/src/rxkad/v5der.c
new file mode 100644 (file)
index 0000000..f149d30
--- /dev/null
@@ -0,0 +1,1243 @@
+#include "asn1_err.h"
+#include <errno.h>
+/*
+ * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $"); */
+
+
+/* 
+ * All decoding functions take a pointer `p' to first position in
+ * which to read, from the left, `len' which means the maximum number
+ * of characters we are able to read, `ret' were the value will be
+ * returned and `size' where the number of used bytes is stored.
+ * Either 0 or an error code is returned.
+ */
+
+static int
+der_get_unsigned (const unsigned char *p, size_t len,
+                 unsigned *ret, size_t *size)
+{
+    unsigned val = 0;
+    size_t oldlen = len;
+
+    while (len--)
+       val = val * 256 + *p++;
+    *ret = val;
+    if(size) *size = oldlen;
+    return 0;
+}
+
+int
+der_get_int (const unsigned char *p, size_t len,
+            int *ret, size_t *size)
+{
+    int val = 0;
+    size_t oldlen = len;
+
+    if (len > 0) {
+       val = (signed char)*p++;
+       while (--len)
+           val = val * 256 + *p++;
+    }
+    *ret = val;
+    if(size) *size = oldlen;
+    return 0;
+}
+
+int
+der_get_length (const unsigned char *p, size_t len,
+               size_t *val, size_t *size)
+{
+    size_t v;
+
+    if (len <= 0)
+       return ASN1_OVERRUN;
+    --len;
+    v = *p++;
+    if (v < 128) {
+       *val = v;
+       if(size) *size = 1;
+    } else {
+       int e;
+       size_t l;
+       unsigned tmp;
+
+       if(v == 0x80){
+           *val = ASN1_INDEFINITE;
+           if(size) *size = 1;
+           return 0;
+       }
+       v &= 0x7F;
+       if (len < v)
+           return ASN1_OVERRUN;
+       e = der_get_unsigned (p, v, &tmp, &l);
+       if(e) return e;
+       *val = tmp;
+       if(size) *size = l + 1;
+    }
+    return 0;
+}
+
+int
+der_get_general_string (const unsigned char *p, size_t len, 
+                       general_string *str, size_t *size)
+{
+    char *s;
+
+    s = malloc (len + 1);
+    if (s == NULL)
+       return ENOMEM;
+    memcpy (s, p, len);
+    s[len] = '\0';
+    *str = s;
+    if(size) *size = len;
+    return 0;
+}
+
+int
+der_get_octet_string (const unsigned char *p, size_t len, 
+                     octet_string *data, size_t *size)
+{
+    data->length = len;
+    data->data = malloc(len);
+    if (data->data == NULL && data->length != 0)
+       return ENOMEM;
+    memcpy (data->data, p, len);
+    if(size) *size = len;
+    return 0;
+}
+
+int
+der_get_oid (const unsigned char *p, size_t len,
+            oid *data, size_t *size)
+{
+    int n;
+    size_t oldlen = len;
+
+    if (len < 1)
+       return ASN1_OVERRUN;
+
+    data->components = malloc(len * sizeof(*data->components));
+    if (data->components == NULL && len != 0)
+       return ENOMEM;
+    data->components[0] = (*p) / 40;
+    data->components[1] = (*p) % 40;
+    --len;
+    ++p;
+    for (n = 2; len > 0; ++n) {
+       unsigned u = 0;
+
+       do {
+           --len;
+           u = u * 128 + (*p++ % 128);
+       } while (len > 0 && p[-1] & 0x80);
+       data->components[n] = u;
+    }
+    if (p[-1] & 0x80) {
+       free_oid (data);
+       return ASN1_OVERRUN;
+    }
+    data->length = n;
+    if (size)
+       *size = oldlen;
+    return 0;
+}
+
+int
+der_get_tag (const unsigned char *p, size_t len,
+            Der_class *class, Der_type *type,
+            int *tag, size_t *size)
+{
+    if (len < 1)
+       return ASN1_OVERRUN;
+    *class = (Der_class)(((*p) >> 6) & 0x03);
+    *type = (Der_type)(((*p) >> 5) & 0x01);
+    *tag = (*p) & 0x1F;
+    if(size) *size = 1;
+    return 0;
+}
+
+int
+der_match_tag (const unsigned char *p, size_t len,
+              Der_class class, Der_type type,
+              int tag, size_t *size)
+{
+    size_t l;
+    Der_class thisclass;
+    Der_type thistype;
+    int thistag;
+    int e;
+
+    e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
+    if (e) return e;
+    if (class != thisclass || type != thistype)
+       return ASN1_BAD_ID;
+    if(tag > thistag)
+       return ASN1_MISPLACED_FIELD;
+    if(tag < thistag)
+       return ASN1_MISSING_FIELD;
+    if(size) *size = l;
+    return 0;
+}
+
+int
+der_match_tag_and_length (const unsigned char *p, size_t len,
+                         Der_class class, Der_type type, int tag,
+                         size_t *length_ret, size_t *size)
+{
+    size_t l, ret = 0;
+    int e;
+
+    e = der_match_tag (p, len, class, type, tag, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    e = der_get_length (p, len, length_ret, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_integer (const unsigned char *p, size_t len,
+               int *num, size_t *size)
+{
+    size_t ret = 0;
+    size_t l, reallen;
+    int e;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    e = der_get_length (p, len, &reallen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (reallen > len)
+       return ASN1_OVERRUN;
+    e = der_get_int (p, reallen, num, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_unsigned (const unsigned char *p, size_t len,
+                unsigned *num, size_t *size)
+{
+    size_t ret = 0;
+    size_t l, reallen;
+    int e;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    e = der_get_length (p, len, &reallen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (reallen > len)
+       return ASN1_OVERRUN;
+    e = der_get_unsigned (p, reallen, num, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_enumerated (const unsigned char *p, size_t len,
+                  unsigned *num, size_t *size)
+{
+    size_t ret = 0;
+    size_t l, reallen;
+    int e;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_Enumerated, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    e = der_get_length (p, len, &reallen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    e = der_get_int (p, reallen, num, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_general_string (const unsigned char *p, size_t len, 
+                      general_string *str, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+    size_t slen;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+
+    e = der_get_length (p, len, &slen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (len < slen)
+       return ASN1_OVERRUN;
+
+    e = der_get_general_string (p, slen, str, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_octet_string (const unsigned char *p, size_t len, 
+                    octet_string *k, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+    size_t slen;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+
+    e = der_get_length (p, len, &slen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (len < slen)
+       return ASN1_OVERRUN;
+
+    e = der_get_octet_string (p, slen, k, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+int
+decode_oid (const unsigned char *p, size_t len, 
+           oid *k, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+    size_t slen;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_OID, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+
+    e = der_get_length (p, len, &slen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (len < slen)
+       return ASN1_OVERRUN;
+
+    e = der_get_oid (p, slen, k, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if(size) *size = ret;
+    return 0;
+}
+
+static void
+generalizedtime2time (const char *s, time_t *t)
+{
+    struct tm tm;
+
+    memset(&tm, 0, sizeof(tm));
+    sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
+           &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+           &tm.tm_min, &tm.tm_sec);
+    tm.tm_year -= 1900;
+    tm.tm_mon -= 1;
+    *t = timegm (&tm);
+}
+
+int
+decode_generalized_time (const unsigned char *p, size_t len,
+                        time_t *t, size_t *size)
+{
+    octet_string k;
+    char *times;
+    size_t ret = 0;
+    size_t l;
+    int e;
+    size_t slen;
+
+    e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+
+    e = der_get_length (p, len, &slen, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    if (len < slen)
+       return ASN1_OVERRUN;
+    e = der_get_octet_string (p, slen, &k, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    times = realloc(k.data, k.length + 1);
+    if (times == NULL){
+       free(k.data);
+       return ENOMEM;
+    }
+    times[k.length] = 0;
+    generalizedtime2time (times, t);
+    free (times);
+    if(size) *size = ret;
+    return 0;
+}
+
+
+int
+fix_dce(size_t reallen, size_t *len)
+{
+    if(reallen == ASN1_INDEFINITE)
+       return 1;
+    if(*len < reallen)
+       return -1;
+    *len = reallen;
+    return 0;
+}
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: der_put.c,v 1.27 2001/09/25 23:37:25 assar Exp $"); */
+
+/*
+ * All encoding functions take a pointer `p' to first position in
+ * which to write, from the right, `len' which means the maximum
+ * number of characters we are able to write.  The function returns
+ * the number of characters written in `size' (if non-NULL).
+ * The return value is 0 or an error.
+ */
+
+static int
+der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
+{
+    unsigned char *base = p;
+
+    if (val) {
+       while (len > 0 && val) {
+           *p-- = val % 256;
+           val /= 256;
+           --len;
+       }
+       if (val != 0)
+           return ASN1_OVERFLOW;
+       else {
+           *size = base - p;
+           return 0;
+       }
+    } else if (len < 1)
+       return ASN1_OVERFLOW;
+    else {
+       *p    = 0;
+       *size = 1;
+       return 0;
+    }
+}
+
+int
+der_put_int (unsigned char *p, size_t len, int val, size_t *size)
+{
+    unsigned char *base = p;
+
+    if(val >= 0) {
+       do {
+           if(len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = val % 256;
+           len--;
+           val /= 256;
+       } while(val);
+       if(p[1] >= 128) {
+           if(len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 0;
+           len--;
+       }
+    } else {
+       val = ~val;
+       do {
+           if(len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = ~(val % 256);
+           len--;
+           val /= 256;
+       } while(val);
+       if(p[1] < 128) {
+           if(len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 0xff;
+           len--;
+       }
+    }
+    *size = base - p;
+    return 0;
+}
+
+
+int
+der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
+{
+    if (len < 1)
+       return ASN1_OVERFLOW;
+    if (val < 128) {
+       *p = val;
+       *size = 1;
+       return 0;
+    } else {
+       size_t l;
+       int e;
+
+       e = der_put_unsigned (p, len - 1, val, &l);
+       if (e)
+           return e;
+       p -= l;
+       *p = 0x80 | l;
+       *size = l + 1;
+       return 0;
+    }
+}
+
+int
+der_put_general_string (unsigned char *p, size_t len, 
+                       const general_string *str, size_t *size)
+{
+    size_t slen = strlen(*str);
+
+    if (len < slen)
+       return ASN1_OVERFLOW;
+    p -= slen;
+    len -= slen;
+    memcpy (p+1, *str, slen);
+    *size = slen;
+    return 0;
+}
+
+int
+der_put_octet_string (unsigned char *p, size_t len, 
+                     const octet_string *data, size_t *size)
+{
+    if (len < data->length)
+       return ASN1_OVERFLOW;
+    p -= data->length;
+    len -= data->length;
+    memcpy (p+1, data->data, data->length);
+    *size = data->length;
+    return 0;
+}
+
+int
+der_put_oid (unsigned char *p, size_t len,
+            const oid *data, size_t *size)
+{
+    unsigned char *base = p;
+    int n;
+
+    for (n = data->length - 1; n >= 2; --n) {
+       unsigned u = data->components[n];
+
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = u % 128;
+       u /= 128;
+       --len;
+       while (u > 0) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 128 + u % 128;
+           u /= 128;
+           --len;
+       }
+    }
+    if (len < 1)
+       return ASN1_OVERFLOW;
+    *p-- = 40 * data->components[0] + data->components[1];
+    *size = base - p;
+    return 0;
+}
+
+int
+der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+            int tag, size_t *size)
+{
+    if (len < 1)
+       return ASN1_OVERFLOW;
+    *p = (class << 6) | (type << 5) | tag; /* XXX */
+    *size = 1;
+    return 0;
+}
+
+int
+der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
+                       Der_class class, Der_type type, int tag, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    e = der_put_length (p, len, len_val, &l);
+    if(e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_tag (p, len, class, type, tag, &l);
+    if(e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
+{
+    int num = *data;
+    size_t ret = 0;
+    size_t l;
+    int e;
+    
+    e = der_put_int (p, len, num, &l);
+    if(e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_unsigned (unsigned char *p, size_t len, const unsigned *data,
+                size_t *size)
+{
+    unsigned num = *data;
+    size_t ret = 0;
+    size_t l;
+    int e;
+    
+    e = der_put_unsigned (p, len, num, &l);
+    if(e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_enumerated (unsigned char *p, size_t len, const unsigned *data,
+                  size_t *size)
+{
+    unsigned num = *data;
+    size_t ret = 0;
+    size_t l;
+    int e;
+    
+    e = der_put_int (p, len, num, &l);
+    if(e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Enumerated, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_general_string (unsigned char *p, size_t len, 
+                      const general_string *data, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    e = der_put_general_string (p, len, data, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_GeneralString, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_octet_string (unsigned char *p, size_t len, 
+                    const octet_string *k, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    e = der_put_octet_string (p, len, k, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OctetString, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+encode_oid(unsigned char *p, size_t len,
+          const oid *k, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    e = der_put_oid (p, len, k, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OID, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+
+int
+time2generalizedtime (time_t t, octet_string *s)
+{
+     struct tm *tm;
+
+     s->data = malloc(16);
+     if (s->data == NULL)
+        return ENOMEM;
+     s->length = 15;
+     tm = gmtime (&t);
+     sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
+             tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
+             tm->tm_sec);
+     return 0;
+}
+
+int
+encode_generalized_time (unsigned char *p, size_t len,
+                        const time_t *t, size_t *size)
+{
+    size_t ret = 0;
+    size_t l;
+    octet_string k;
+    int e;
+
+    e = time2generalizedtime (*t, &k);
+    if (e)
+       return e;
+    e = der_put_octet_string (p, len, &k, &l);
+    free (k.data);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    e = der_put_length_and_tag (p, len, k.length, UNIV, PRIM, 
+                               UT_GeneralizedTime, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+    *size = ret;
+    return 0;
+}
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: der_free.c,v 1.8 2001/09/25 13:39:26 assar Exp $"); */
+
+void
+free_general_string (general_string *str)
+{
+    free(*str);
+}
+
+void
+free_octet_string (octet_string *k)
+{
+    free(k->data);
+}
+
+void
+free_oid (oid *k)
+{
+    free(k->components);
+}
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: der_length.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); */
+
+static size_t
+len_unsigned (unsigned val)
+{
+  size_t ret = 0;
+
+  do {
+    ++ret;
+    val /= 256;
+  } while (val);
+  return ret;
+}
+
+static size_t
+len_int (int val)
+{
+  size_t ret = 0;
+
+  if (val == 0)
+    return 1;
+  while (val > 255 || val < -255) {
+    ++ret;
+    val /= 256;
+  }
+  if (val != 0) {
+    ++ret;
+    if ((signed char)val != val)
+      ++ret;
+    val /= 256;
+  }
+  return ret;
+}
+
+static size_t
+len_oid (const oid *oid)
+{
+    size_t ret = 1;
+    int n;
+
+    for (n = 2; n < oid->length; ++n) {
+       unsigned u = oid->components[n];
+
+       ++ret;
+       u /= 128;
+       while (u > 0) {
+           ++ret;
+           u /= 128;
+       }
+    }
+    return ret;
+}
+
+size_t
+length_len (size_t len)
+{
+  if (len < 128)
+    return 1;
+  else
+    return len_unsigned (len) + 1;
+}
+
+size_t
+length_integer (const int *data)
+{
+  size_t len = len_int (*data);
+
+  return 1 + length_len(len) + len;
+}
+
+size_t
+length_unsigned (const unsigned *data)
+{
+  size_t len = len_unsigned (*data);
+
+  return 1 + length_len(len) + len;
+}
+
+size_t
+length_enumerated (const unsigned *data)
+{
+  size_t len = len_int (*data);
+
+  return 1 + length_len(len) + len;
+}
+
+size_t
+length_general_string (const general_string *data)
+{
+  char *str = *data;
+  size_t len = strlen(str);
+  return 1 + length_len(len) + len;
+}
+
+size_t
+length_octet_string (const octet_string *k)
+{
+  return 1 + length_len(k->length) + k->length;
+}
+
+size_t
+length_oid (const oid *k)
+{
+  size_t len = len_oid (k);
+
+  return 1 + length_len(len) + len;
+}
+
+size_t
+length_generalized_time (const time_t *t)
+{
+  octet_string k;
+  size_t ret;
+
+  time2generalizedtime (*t, &k);
+  ret = 1 + length_len(k.length) + k.length;
+  free (k.data);
+  return ret;
+}
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: der_copy.c,v 1.9 2001/09/25 13:39:25 assar Exp $"); */
+
+int
+copy_general_string (const general_string *from, general_string *to)
+{
+    *to = malloc(strlen(*from) + 1);
+    if(*to == NULL)
+       return ENOMEM;
+    strcpy(*to, *from);
+    return 0;
+}
+
+int
+copy_octet_string (const octet_string *from, octet_string *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length);
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length);
+    return 0;
+}
+
+int
+copy_oid (const oid *from, oid *to)
+{
+    to->length     = from->length;
+    to->components = malloc(to->length * sizeof(*to->components));
+    if (to->length != 0 && to->components == NULL)
+       return ENOMEM;
+    memcpy(to->components, from->components, to->length);
+    return 0;
+}
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+/* RCSID("Heimdal: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); */
+
+#ifndef HAVE_TIMEGM
+
+static int
+is_leap(unsigned y)
+{
+    y += 1900;
+    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+time_t
+timegm (struct tm *tm)
+{
+  static const unsigned ndays[2][12] ={
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+  time_t res = 0;
+  unsigned i;
+
+  for (i = 70; i < tm->tm_year; ++i)
+    res += is_leap(i) ? 366 : 365;
+
+  for (i = 0; i < tm->tm_mon; ++i)
+    res += ndays[is_leap(tm->tm_year)][i];
+  res += tm->tm_mday - 1;
+  res *= 24;
+  res += tm->tm_hour;
+  res *= 60;
+  res += tm->tm_min;
+  res *= 60;
+  res += tm->tm_sec;
+  return res;
+}
+
+#endif /* HAVE_TIMEGM */
diff --git a/src/rxkad/v5gen-rewrite.h b/src/rxkad/v5gen-rewrite.h
new file mode 100644 (file)
index 0000000..6761af5
--- /dev/null
@@ -0,0 +1,125 @@
+#define encode_Ticket _rxkad_v5_encode_Ticket
+#define decode_Ticket _rxkad_v5_decode_Ticket
+#define free_Ticket _rxkad_v5_free_Ticket
+#define length_Ticket _rxkad_v5_length_Ticket
+#define copy_Ticket _rxkad_v5_copy_Ticket
+#define encode_EncryptedData _rxkad_v5_encode_EncryptedData
+#define decode_EncryptedData _rxkad_v5_decode_EncryptedData
+#define free_EncryptedData _rxkad_v5_free_EncryptedData
+#define length_EncryptedData _rxkad_v5_length_EncryptedData
+#define copy_EncryptedData _rxkad_v5_copy_EncryptedData
+#define encode_PrincipalName _rxkad_v5_encode_PrincipalName
+#define decode_PrincipalName _rxkad_v5_decode_PrincipalName
+#define free_PrincipalName _rxkad_v5_free_PrincipalName
+#define length_PrincipalName _rxkad_v5_length_PrincipalName
+#define copy_PrincipalName _rxkad_v5_copy_PrincipalName
+#define encode_HostAddresses _rxkad_v5_encode_HostAddresses
+#define decode_HostAddresses _rxkad_v5_decode_HostAddresses
+#define free_HostAddresses _rxkad_v5_free_HostAddresses
+#define length_HostAddresses _rxkad_v5_length_HostAddresses
+#define copy_HostAddresses _rxkad_v5_copy_HostAddresses
+#define encode_HostAddress _rxkad_v5_encode_HostAddress
+#define decode_HostAddress _rxkad_v5_decode_HostAddress
+#define free_HostAddress _rxkad_v5_free_HostAddress
+#define length_HostAddress _rxkad_v5_length_HostAddress
+#define copy_HostAddress _rxkad_v5_copy_HostAddress
+#define encode_AuthorizationData _rxkad_v5_encode_AuthorizationData
+#define decode_AuthorizationData _rxkad_v5_decode_AuthorizationData
+#define free_AuthorizationData _rxkad_v5_free_AuthorizationData
+#define length_AuthorizationData _rxkad_v5_length_AuthorizationData
+#define copy_AuthorizationData _rxkad_v5_copy_AuthorizationData
+#define encode_EncTicketPart _rxkad_v5_encode_EncTicketPart
+#define decode_EncTicketPart _rxkad_v5_decode_EncTicketPart
+#define free_EncTicketPart _rxkad_v5_free_EncTicketPart
+#define length_EncTicketPart _rxkad_v5_length_EncTicketPart
+#define copy_EncTicketPart _rxkad_v5_copy_EncTicketPart
+#define encode_KerberosTime _rxkad_v5_encode_KerberosTime
+#define decode_KerberosTime _rxkad_v5_decode_KerberosTime
+#define free_KerberosTime _rxkad_v5_free_KerberosTime
+#define length_KerberosTime _rxkad_v5_length_KerberosTime
+#define copy_KerberosTime _rxkad_v5_copy_KerberosTime
+#define encode_TransitedEncoding _rxkad_v5_encode_TransitedEncoding
+#define decode_TransitedEncoding _rxkad_v5_decode_TransitedEncoding
+#define free_TransitedEncoding _rxkad_v5_free_TransitedEncoding
+#define length_TransitedEncoding _rxkad_v5_length_TransitedEncoding
+#define copy_TransitedEncoding _rxkad_v5_copy_TransitedEncoding
+#define encode_EncryptionKey _rxkad_v5_encode_EncryptionKey
+#define decode_EncryptionKey _rxkad_v5_decode_EncryptionKey
+#define free_EncryptionKey _rxkad_v5_free_EncryptionKey
+#define length_EncryptionKey _rxkad_v5_length_EncryptionKey
+#define copy_EncryptionKey _rxkad_v5_copy_EncryptionKey
+#define encode_TicketFlags _rxkad_v5_encode_TicketFlags
+#define decode_TicketFlags _rxkad_v5_decode_TicketFlags
+#define free_TicketFlags _rxkad_v5_free_TicketFlags
+#define length_TicketFlags _rxkad_v5_length_TicketFlags
+#define copy_TicketFlags _rxkad_v5_copy_TicketFlags
+#define encode_Realm _rxkad_v5_encode_Realm
+#define decode_Realm _rxkad_v5_decode_Realm
+#define free_Realm _rxkad_v5_free_Realm
+#define length_Realm _rxkad_v5_length_Realm
+#define copy_Realm _rxkad_v5_copy_Realm
+#define encode_ENCTYPE _rxkad_v5_encode_ENCTYPE
+#define decode_ENCTYPE _rxkad_v5_decode_ENCTYPE
+#define free_ENCTYPE _rxkad_v5_free_ENCTYPE
+#define length_ENCTYPE _rxkad_v5_length_ENCTYPE
+#define copy_ENCTYPE _rxkad_v5_copy_ENCTYPE
+#define encode_NAME_TYPE _rxkad_v5_encode_NAME_TYPE
+#define decode_NAME_TYPE _rxkad_v5_decode_NAME_TYPE
+#define free_NAME_TYPE _rxkad_v5_free_NAME_TYPE
+#define length_NAME_TYPE _rxkad_v5_length_NAME_TYPE
+#define copy_NAME_TYPE _rxkad_v5_copy_NAME_TYPE
+#define der_get_unsigned  _rxkad_v5_der_get_unsigned 
+#define der_get_int  _rxkad_v5_der_get_int 
+#define der_get_length  _rxkad_v5_der_get_length 
+#define der_get_general_string  _rxkad_v5_der_get_general_string 
+#define der_get_octet_string  _rxkad_v5_der_get_octet_string 
+#define der_get_oid  _rxkad_v5_der_get_oid 
+#define der_get_tag  _rxkad_v5_der_get_tag 
+#define der_match_tag  _rxkad_v5_der_match_tag 
+#define der_match_tag_and_length  _rxkad_v5_der_match_tag_and_length 
+#define decode_integer  _rxkad_v5_decode_integer 
+#define decode_unsigned  _rxkad_v5_decode_unsigned 
+#define decode_enumerated  _rxkad_v5_decode_enumerated 
+#define decode_general_string  _rxkad_v5_decode_general_string 
+#define decode_octet_string  _rxkad_v5_decode_octet_string 
+#define decode_oid  _rxkad_v5_decode_oid 
+#define decode_generalized_time  _rxkad_v5_decode_generalized_time 
+#define fix_dce _rxkad_v5_fix_dce
+#define der_put_unsigned  _rxkad_v5_der_put_unsigned 
+#define der_put_int  _rxkad_v5_der_put_int 
+#define der_put_length  _rxkad_v5_der_put_length 
+#define der_put_general_string  _rxkad_v5_der_put_general_string 
+#define der_put_octet_string  _rxkad_v5_der_put_octet_string 
+#define der_put_oid  _rxkad_v5_der_put_oid 
+#define der_put_tag  _rxkad_v5_der_put_tag 
+#define der_put_length_and_tag  _rxkad_v5_der_put_length_and_tag 
+#define encode_integer  _rxkad_v5_encode_integer 
+#define encode_unsigned  _rxkad_v5_encode_unsigned 
+#define encode_enumerated  _rxkad_v5_encode_enumerated 
+#define encode_general_string  _rxkad_v5_encode_general_string 
+#define encode_octet_string  _rxkad_v5_encode_octet_string 
+#define encode_oid _rxkad_v5_encode_oid
+#define time2generalizedtime  _rxkad_v5_time2generalizedtime 
+#define encode_generalized_time  _rxkad_v5_encode_generalized_time 
+#define free_general_string  _rxkad_v5_free_general_string 
+#define free_octet_string  _rxkad_v5_free_octet_string 
+#define free_oid  _rxkad_v5_free_oid 
+#define len_unsigned  _rxkad_v5_len_unsigned 
+#define len_int  _rxkad_v5_len_int 
+#define len_oid  _rxkad_v5_len_oid 
+#define length_len  _rxkad_v5_length_len 
+#define length_integer  _rxkad_v5_length_integer 
+#define length_unsigned  _rxkad_v5_length_unsigned 
+#define length_enumerated  _rxkad_v5_length_enumerated 
+#define length_general_string  _rxkad_v5_length_general_string 
+#define length_octet_string  _rxkad_v5_length_octet_string 
+#define length_oid  _rxkad_v5_length_oid 
+#define length_generalized_time  _rxkad_v5_length_generalized_time 
+#define copy_general_string  _rxkad_v5_copy_general_string 
+#define copy_octet_string  _rxkad_v5_copy_octet_string 
+#define copy_oid  _rxkad_v5_copy_oid 
+#define TicketFlags2int _rxkad_v5_TicketFlags2int
+#define int2TicketFlags _rxkad_v5_int2TicketFlags
+#ifndef HAVE_TIMEGM
+#define timegm _rxkad_timegm
+#endif
diff --git a/src/rxkad/v5gen.c b/src/rxkad/v5gen.c
new file mode 100644 (file)
index 0000000..7efa509
--- /dev/null
@@ -0,0 +1,2490 @@
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_Ticket(unsigned char *p, size_t len, const Ticket *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_EncryptedData(p, len, &(data)->enc_part, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 3, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_PrincipalName(p, len, &(data)->sname, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 2, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_Realm(p, len, &(data)->realm, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, &(data)->tkt_vno, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, APPL, CONS, 1, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_Ticket(const unsigned char *p, size_t len, Ticket *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, APPL, CONS, 1, &reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_integer(p, len, &(data)->tkt_vno, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_Realm(p, len, &(data)->realm, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 2, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_PrincipalName(p, len, &(data)->sname, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 3, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_EncryptedData(p, len, &(data)->enc_part, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_Ticket(data);
+return e;
+}
+
+void
+free_Ticket(Ticket *data)
+{
+free_Realm(&(data)->realm);
+free_PrincipalName(&(data)->sname);
+free_EncryptedData(&(data)->enc_part);
+}
+
+size_t
+length_Ticket(const Ticket *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_integer(&(data)->tkt_vno);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_Realm(&(data)->realm);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_PrincipalName(&(data)->sname);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_EncryptedData(&(data)->enc_part);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+ret += 1 + length_len (ret);
+return ret;
+}
+
+int
+copy_Ticket(const Ticket *from, Ticket *to)
+{
+*(&(to)->tkt_vno) = *(&(from)->tkt_vno);
+if(copy_Realm(&(from)->realm, &(to)->realm)) return ENOMEM;
+if(copy_PrincipalName(&(from)->sname, &(to)->sname)) return ENOMEM;
+if(copy_EncryptedData(&(from)->enc_part, &(to)->enc_part)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_EncryptedData(unsigned char *p, size_t len, const EncryptedData *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_octet_string(p, len, &(data)->cipher, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 2, &l);
+BACK;
+ret += oldret;
+}
+if((data)->kvno)
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, (data)->kvno, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_ENCTYPE(p, len, &(data)->etype, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_EncryptedData(const unsigned char *p, size_t len, EncryptedData *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_ENCTYPE(p, len, &(data)->etype, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+(data)->kvno = NULL;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+(data)->kvno = malloc(sizeof(*(data)->kvno));
+if((data)->kvno == NULL) return ENOMEM;
+e = decode_integer(p, len, (data)->kvno, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 2, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_octet_string(p, len, &(data)->cipher, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_EncryptedData(data);
+return e;
+}
+
+void
+free_EncryptedData(EncryptedData *data)
+{
+free_ENCTYPE(&(data)->etype);
+if((data)->kvno) {
+free((data)->kvno);
+}
+free_octet_string(&(data)->cipher);
+}
+
+size_t
+length_EncryptedData(const EncryptedData *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_ENCTYPE(&(data)->etype);
+ret += 1 + length_len(ret) + oldret;
+}
+if((data)->kvno){
+int oldret = ret;
+ret = 0;
+ret += length_integer((data)->kvno);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_octet_string(&(data)->cipher);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+return ret;
+}
+
+int
+copy_EncryptedData(const EncryptedData *from, EncryptedData *to)
+{
+if(copy_ENCTYPE(&(from)->etype, &(to)->etype)) return ENOMEM;
+if((from)->kvno) {
+(to)->kvno = malloc(sizeof(*(to)->kvno));
+if((to)->kvno == NULL) return ENOMEM;
+*((to)->kvno) = *((from)->kvno);
+}else
+(to)->kvno = NULL;
+if(copy_octet_string(&(from)->cipher, &(to)->cipher)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_PrincipalName(unsigned char *p, size_t len, const PrincipalName *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+for(i = (&(data)->name_string)->len - 1; i >= 0; --i) {
+int oldret = ret;
+ret = 0;
+e = encode_general_string(p, len, &(&(data)->name_string)->val[i], &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_NAME_TYPE(p, len, &(data)->name_type, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_PrincipalName(const unsigned char *p, size_t len, PrincipalName *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_NAME_TYPE(p, len, &(data)->name_type, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+if(len < reallen)
+return ASN1_OVERRUN;
+len = reallen;
+{
+size_t origlen = len;
+int oldret = ret;
+ret = 0;
+(&(data)->name_string)->len = 0;
+(&(data)->name_string)->val = NULL;
+while(ret < origlen) {
+(&(data)->name_string)->len++;
+(&(data)->name_string)->val = realloc((&(data)->name_string)->val, sizeof(*((&(data)->name_string)->val)) * (&(data)->name_string)->len);
+e = decode_general_string(p, len, &(&(data)->name_string)->val[(&(data)->name_string)->len-1], &l);
+FORW;
+len = origlen - ret;
+}
+ret += oldret;
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_PrincipalName(data);
+return e;
+}
+
+void
+free_PrincipalName(PrincipalName *data)
+{
+free_NAME_TYPE(&(data)->name_type);
+while((&(data)->name_string)->len){
+free_general_string(&(&(data)->name_string)->val[(&(data)->name_string)->len-1]);
+(&(data)->name_string)->len--;
+}
+free((&(data)->name_string)->val);
+}
+
+size_t
+length_PrincipalName(const PrincipalName *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_NAME_TYPE(&(data)->name_type);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+{
+int oldret = ret;
+int i;
+ret = 0;
+for(i = (&(data)->name_string)->len - 1; i >= 0; --i){
+ret += length_general_string(&(&(data)->name_string)->val[i]);
+}
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+return ret;
+}
+
+int
+copy_PrincipalName(const PrincipalName *from, PrincipalName *to)
+{
+if(copy_NAME_TYPE(&(from)->name_type, &(to)->name_type)) return ENOMEM;
+if(((&(to)->name_string)->val = malloc((&(from)->name_string)->len * sizeof(*(&(to)->name_string)->val))) == NULL && (&(from)->name_string)->len != 0)
+return ENOMEM;
+for((&(to)->name_string)->len = 0; (&(to)->name_string)->len < (&(from)->name_string)->len; (&(to)->name_string)->len++){
+if(copy_general_string(&(&(from)->name_string)->val[(&(to)->name_string)->len], &(&(to)->name_string)->val[(&(to)->name_string)->len])) return ENOMEM;
+}
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_HostAddresses(unsigned char *p, size_t len, const HostAddresses *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+for(i = (data)->len - 1; i >= 0; --i) {
+int oldret = ret;
+ret = 0;
+e = encode_HostAddress(p, len, &(data)->val[i], &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_HostAddresses(const unsigned char *p, size_t len, HostAddresses *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+if(len < reallen)
+return ASN1_OVERRUN;
+len = reallen;
+{
+size_t origlen = len;
+int oldret = ret;
+ret = 0;
+(data)->len = 0;
+(data)->val = NULL;
+while(ret < origlen) {
+(data)->len++;
+(data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
+e = decode_HostAddress(p, len, &(data)->val[(data)->len-1], &l);
+FORW;
+len = origlen - ret;
+}
+ret += oldret;
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_HostAddresses(data);
+return e;
+}
+
+void
+free_HostAddresses(HostAddresses *data)
+{
+while((data)->len){
+free_HostAddress(&(data)->val[(data)->len-1]);
+(data)->len--;
+}
+free((data)->val);
+}
+
+size_t
+length_HostAddresses(const HostAddresses *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+int i;
+ret = 0;
+for(i = (data)->len - 1; i >= 0; --i){
+ret += length_HostAddress(&(data)->val[i]);
+}
+ret += 1 + length_len(ret) + oldret;
+}
+return ret;
+}
+
+int
+copy_HostAddresses(const HostAddresses *from, HostAddresses *to)
+{
+if(((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL && (from)->len != 0)
+return ENOMEM;
+for((to)->len = 0; (to)->len < (from)->len; (to)->len++){
+if(copy_HostAddress(&(from)->val[(to)->len], &(to)->val[(to)->len])) return ENOMEM;
+}
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_HostAddress(unsigned char *p, size_t len, const HostAddress *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_octet_string(p, len, &(data)->address, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, &(data)->addr_type, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_HostAddress(const unsigned char *p, size_t len, HostAddress *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_integer(p, len, &(data)->addr_type, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_octet_string(p, len, &(data)->address, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_HostAddress(data);
+return e;
+}
+
+void
+free_HostAddress(HostAddress *data)
+{
+free_octet_string(&(data)->address);
+}
+
+size_t
+length_HostAddress(const HostAddress *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_integer(&(data)->addr_type);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_octet_string(&(data)->address);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+return ret;
+}
+
+int
+copy_HostAddress(const HostAddress *from, HostAddress *to)
+{
+*(&(to)->addr_type) = *(&(from)->addr_type);
+if(copy_octet_string(&(from)->address, &(to)->address)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_AuthorizationData(unsigned char *p, size_t len, const AuthorizationData *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+for(i = (data)->len - 1; i >= 0; --i) {
+int oldret = ret;
+ret = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_octet_string(p, len, &(&(data)->val[i])->ad_data, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, &(&(data)->val[i])->ad_type, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_AuthorizationData(const unsigned char *p, size_t len, AuthorizationData *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+if(len < reallen)
+return ASN1_OVERRUN;
+len = reallen;
+{
+size_t origlen = len;
+int oldret = ret;
+ret = 0;
+(data)->len = 0;
+(data)->val = NULL;
+while(ret < origlen) {
+(data)->len++;
+(data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_integer(p, len, &(&(data)->val[(data)->len-1])->ad_type, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_octet_string(p, len, &(&(data)->val[(data)->len-1])->ad_data, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+len = origlen - ret;
+}
+ret += oldret;
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_AuthorizationData(data);
+return e;
+}
+
+void
+free_AuthorizationData(AuthorizationData *data)
+{
+while((data)->len){
+free_octet_string(&(&(data)->val[(data)->len-1])->ad_data);
+(data)->len--;
+}
+free((data)->val);
+}
+
+size_t
+length_AuthorizationData(const AuthorizationData *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+int i;
+ret = 0;
+for(i = (data)->len - 1; i >= 0; --i){
+{
+int oldret = ret;
+ret = 0;
+ret += length_integer(&(&(data)->val[i])->ad_type);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_octet_string(&(&(data)->val[i])->ad_data);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+}
+ret += 1 + length_len(ret) + oldret;
+}
+return ret;
+}
+
+int
+copy_AuthorizationData(const AuthorizationData *from, AuthorizationData *to)
+{
+if(((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL && (from)->len != 0)
+return ENOMEM;
+for((to)->len = 0; (to)->len < (from)->len; (to)->len++){
+*(&(&(to)->val[(to)->len])->ad_type) = *(&(&(from)->val[(to)->len])->ad_type);
+if(copy_octet_string(&(&(from)->val[(to)->len])->ad_data, &(&(to)->val[(to)->len])->ad_data)) return ENOMEM;
+}
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_EncTicketPart(unsigned char *p, size_t len, const EncTicketPart *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+if((data)->authorization_data)
+{
+int oldret = ret;
+ret = 0;
+e = encode_AuthorizationData(p, len, (data)->authorization_data, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 10, &l);
+BACK;
+ret += oldret;
+}
+if((data)->caddr)
+{
+int oldret = ret;
+ret = 0;
+e = encode_HostAddresses(p, len, (data)->caddr, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 9, &l);
+BACK;
+ret += oldret;
+}
+if((data)->renew_till)
+{
+int oldret = ret;
+ret = 0;
+e = encode_KerberosTime(p, len, (data)->renew_till, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 8, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_KerberosTime(p, len, &(data)->endtime, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 7, &l);
+BACK;
+ret += oldret;
+}
+if((data)->starttime)
+{
+int oldret = ret;
+ret = 0;
+e = encode_KerberosTime(p, len, (data)->starttime, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 6, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_KerberosTime(p, len, &(data)->authtime, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 5, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_TransitedEncoding(p, len, &(data)->transited, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 4, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_PrincipalName(p, len, &(data)->cname, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 3, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_Realm(p, len, &(data)->crealm, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 2, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_EncryptionKey(p, len, &(data)->key, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_TicketFlags(p, len, &(data)->flags, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, APPL, CONS, 3, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_EncTicketPart(const unsigned char *p, size_t len, EncTicketPart *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, APPL, CONS, 3, &reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_TicketFlags(p, len, &(data)->flags, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_EncryptionKey(p, len, &(data)->key, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 2, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_Realm(p, len, &(data)->crealm, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 3, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_PrincipalName(p, len, &(data)->cname, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 4, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_TransitedEncoding(p, len, &(data)->transited, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 5, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_KerberosTime(p, len, &(data)->authtime, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 6, &l);
+if (e)
+(data)->starttime = NULL;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+(data)->starttime = malloc(sizeof(*(data)->starttime));
+if((data)->starttime == NULL) return ENOMEM;
+e = decode_KerberosTime(p, len, (data)->starttime, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 7, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_KerberosTime(p, len, &(data)->endtime, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 8, &l);
+if (e)
+(data)->renew_till = NULL;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+(data)->renew_till = malloc(sizeof(*(data)->renew_till));
+if((data)->renew_till == NULL) return ENOMEM;
+e = decode_KerberosTime(p, len, (data)->renew_till, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 9, &l);
+if (e)
+(data)->caddr = NULL;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+(data)->caddr = malloc(sizeof(*(data)->caddr));
+if((data)->caddr == NULL) return ENOMEM;
+e = decode_HostAddresses(p, len, (data)->caddr, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 10, &l);
+if (e)
+(data)->authorization_data = NULL;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+(data)->authorization_data = malloc(sizeof(*(data)->authorization_data));
+if((data)->authorization_data == NULL) return ENOMEM;
+e = decode_AuthorizationData(p, len, (data)->authorization_data, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_EncTicketPart(data);
+return e;
+}
+
+void
+free_EncTicketPart(EncTicketPart *data)
+{
+free_TicketFlags(&(data)->flags);
+free_EncryptionKey(&(data)->key);
+free_Realm(&(data)->crealm);
+free_PrincipalName(&(data)->cname);
+free_TransitedEncoding(&(data)->transited);
+free_KerberosTime(&(data)->authtime);
+if((data)->starttime) {
+free_KerberosTime((data)->starttime);
+free((data)->starttime);
+}
+free_KerberosTime(&(data)->endtime);
+if((data)->renew_till) {
+free_KerberosTime((data)->renew_till);
+free((data)->renew_till);
+}
+if((data)->caddr) {
+free_HostAddresses((data)->caddr);
+free((data)->caddr);
+}
+if((data)->authorization_data) {
+free_AuthorizationData((data)->authorization_data);
+free((data)->authorization_data);
+}
+}
+
+size_t
+length_EncTicketPart(const EncTicketPart *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_TicketFlags(&(data)->flags);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_EncryptionKey(&(data)->key);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_Realm(&(data)->crealm);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_PrincipalName(&(data)->cname);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_TransitedEncoding(&(data)->transited);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_KerberosTime(&(data)->authtime);
+ret += 1 + length_len(ret) + oldret;
+}
+if((data)->starttime){
+int oldret = ret;
+ret = 0;
+ret += length_KerberosTime((data)->starttime);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_KerberosTime(&(data)->endtime);
+ret += 1 + length_len(ret) + oldret;
+}
+if((data)->renew_till){
+int oldret = ret;
+ret = 0;
+ret += length_KerberosTime((data)->renew_till);
+ret += 1 + length_len(ret) + oldret;
+}
+if((data)->caddr){
+int oldret = ret;
+ret = 0;
+ret += length_HostAddresses((data)->caddr);
+ret += 1 + length_len(ret) + oldret;
+}
+if((data)->authorization_data){
+int oldret = ret;
+ret = 0;
+ret += length_AuthorizationData((data)->authorization_data);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+ret += 1 + length_len (ret);
+return ret;
+}
+
+int
+copy_EncTicketPart(const EncTicketPart *from, EncTicketPart *to)
+{
+if(copy_TicketFlags(&(from)->flags, &(to)->flags)) return ENOMEM;
+if(copy_EncryptionKey(&(from)->key, &(to)->key)) return ENOMEM;
+if(copy_Realm(&(from)->crealm, &(to)->crealm)) return ENOMEM;
+if(copy_PrincipalName(&(from)->cname, &(to)->cname)) return ENOMEM;
+if(copy_TransitedEncoding(&(from)->transited, &(to)->transited)) return ENOMEM;
+if(copy_KerberosTime(&(from)->authtime, &(to)->authtime)) return ENOMEM;
+if((from)->starttime) {
+(to)->starttime = malloc(sizeof(*(to)->starttime));
+if((to)->starttime == NULL) return ENOMEM;
+if(copy_KerberosTime((from)->starttime, (to)->starttime)) return ENOMEM;
+}else
+(to)->starttime = NULL;
+if(copy_KerberosTime(&(from)->endtime, &(to)->endtime)) return ENOMEM;
+if((from)->renew_till) {
+(to)->renew_till = malloc(sizeof(*(to)->renew_till));
+if((to)->renew_till == NULL) return ENOMEM;
+if(copy_KerberosTime((from)->renew_till, (to)->renew_till)) return ENOMEM;
+}else
+(to)->renew_till = NULL;
+if((from)->caddr) {
+(to)->caddr = malloc(sizeof(*(to)->caddr));
+if((to)->caddr == NULL) return ENOMEM;
+if(copy_HostAddresses((from)->caddr, (to)->caddr)) return ENOMEM;
+}else
+(to)->caddr = NULL;
+if((from)->authorization_data) {
+(to)->authorization_data = malloc(sizeof(*(to)->authorization_data));
+if((to)->authorization_data == NULL) return ENOMEM;
+if(copy_AuthorizationData((from)->authorization_data, (to)->authorization_data)) return ENOMEM;
+}else
+(to)->authorization_data = NULL;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_KerberosTime(unsigned char *p, size_t len, const KerberosTime *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+e = encode_generalized_time(p, len, data, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_KerberosTime(const unsigned char *p, size_t len, KerberosTime *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = decode_generalized_time(p, len, data, &l);
+FORW;
+if(size) *size = ret;
+return 0;
+fail:
+free_KerberosTime(data);
+return e;
+}
+
+void
+free_KerberosTime(KerberosTime *data)
+{
+}
+
+size_t
+length_KerberosTime(const KerberosTime *data)
+{
+size_t ret = 0;
+ret += length_generalized_time(data);
+return ret;
+}
+
+int
+copy_KerberosTime(const KerberosTime *from, KerberosTime *to)
+{
+*(to) = *(from);
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_TransitedEncoding(unsigned char *p, size_t len, const TransitedEncoding *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_octet_string(p, len, &(data)->contents, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, &(data)->tr_type, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_TransitedEncoding(const unsigned char *p, size_t len, TransitedEncoding *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_integer(p, len, &(data)->tr_type, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_octet_string(p, len, &(data)->contents, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_TransitedEncoding(data);
+return e;
+}
+
+void
+free_TransitedEncoding(TransitedEncoding *data)
+{
+free_octet_string(&(data)->contents);
+}
+
+size_t
+length_TransitedEncoding(const TransitedEncoding *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_integer(&(data)->tr_type);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_octet_string(&(data)->contents);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+return ret;
+}
+
+int
+copy_TransitedEncoding(const TransitedEncoding *from, TransitedEncoding *to)
+{
+*(&(to)->tr_type) = *(&(from)->tr_type);
+if(copy_octet_string(&(from)->contents, &(to)->contents)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_EncryptionKey(unsigned char *p, size_t len, const EncryptionKey *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+int oldret = ret;
+ret = 0;
+e = encode_octet_string(p, len, &(data)->keyvalue, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 1, &l);
+BACK;
+ret += oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+e = encode_integer(p, len, &(data)->keytype, &l);
+BACK;
+e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, 0, &l);
+BACK;
+ret += oldret;
+}
+e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_EncryptionKey(const unsigned char *p, size_t len, EncryptionKey *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,&reallen, &l);
+FORW;
+{
+int dce_fix;
+if((dce_fix = fix_dce(reallen, &len)) < 0)
+return ASN1_BAD_FORMAT;
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 0, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_integer(p, len, &(data)->keytype, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+{
+size_t newlen, oldlen;
+
+e = der_match_tag (p, len, CONTEXT, CONS, 1, &l);
+if (e)
+return e;
+else {
+p += l;
+len -= l;
+ret += l;
+e = der_get_length (p, len, &newlen, &l);
+FORW;
+{
+int dce_fix;
+oldlen = len;
+if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT;
+e = decode_octet_string(p, len, &(data)->keyvalue, &l);
+FORW;
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}else 
+len = oldlen - newlen;
+}
+}
+}
+if(dce_fix){
+e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l);
+FORW;
+}
+}
+if(size) *size = ret;
+return 0;
+fail:
+free_EncryptionKey(data);
+return e;
+}
+
+void
+free_EncryptionKey(EncryptionKey *data)
+{
+free_octet_string(&(data)->keyvalue);
+}
+
+size_t
+length_EncryptionKey(const EncryptionKey *data)
+{
+size_t ret = 0;
+{
+int oldret = ret;
+ret = 0;
+ret += length_integer(&(data)->keytype);
+ret += 1 + length_len(ret) + oldret;
+}
+{
+int oldret = ret;
+ret = 0;
+ret += length_octet_string(&(data)->keyvalue);
+ret += 1 + length_len(ret) + oldret;
+}
+ret += 1 + length_len(ret);
+return ret;
+}
+
+int
+copy_EncryptionKey(const EncryptionKey *from, EncryptionKey *to)
+{
+*(&(to)->keytype) = *(&(from)->keytype);
+if(copy_octet_string(&(from)->keyvalue, &(to)->keyvalue)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_TicketFlags(unsigned char *p, size_t len, const TicketFlags *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+{
+unsigned char c = 0;
+*p-- = c; len--; ret++;
+c = 0;
+*p-- = c; len--; ret++;
+c = 0;
+if(data->anonymous) c |= 1<<1;
+if(data->ok_as_delegate) c |= 1<<2;
+if(data->transited_policy_checked) c |= 1<<3;
+if(data->hw_authent) c |= 1<<4;
+if(data->pre_authent) c |= 1<<5;
+if(data->initial) c |= 1<<6;
+if(data->renewable) c |= 1<<7;
+*p-- = c; len--; ret++;
+c = 0;
+if(data->invalid) c |= 1<<0;
+if(data->postdated) c |= 1<<1;
+if(data->may_postdate) c |= 1<<2;
+if(data->proxy) c |= 1<<3;
+if(data->proxiable) c |= 1<<4;
+if(data->forwarded) c |= 1<<5;
+if(data->forwardable) c |= 1<<6;
+if(data->reserved) c |= 1<<7;
+*p-- = c;
+*p-- = 0;
+len -= 2;
+ret += 2;
+}
+
+e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,UT_BitString, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_TicketFlags(const unsigned char *p, size_t len, TicketFlags *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,&reallen, &l);
+FORW;
+if(len < reallen)
+return ASN1_OVERRUN;
+p++;
+len--;
+reallen--;
+ret++;
+data->reserved = (*p >> 7) & 1;
+data->forwardable = (*p >> 6) & 1;
+data->forwarded = (*p >> 5) & 1;
+data->proxiable = (*p >> 4) & 1;
+data->proxy = (*p >> 3) & 1;
+data->may_postdate = (*p >> 2) & 1;
+data->postdated = (*p >> 1) & 1;
+data->invalid = (*p >> 0) & 1;
+p++; len--; reallen--; ret++;
+data->renewable = (*p >> 7) & 1;
+data->initial = (*p >> 6) & 1;
+data->pre_authent = (*p >> 5) & 1;
+data->hw_authent = (*p >> 4) & 1;
+data->transited_policy_checked = (*p >> 3) & 1;
+data->ok_as_delegate = (*p >> 2) & 1;
+data->anonymous = (*p >> 1) & 1;
+p += reallen; len -= reallen; ret += reallen;
+if(size) *size = ret;
+return 0;
+fail:
+free_TicketFlags(data);
+return e;
+}
+
+void
+free_TicketFlags(TicketFlags *data)
+{
+}
+
+size_t
+length_TicketFlags(const TicketFlags *data)
+{
+size_t ret = 0;
+ret += 7;
+return ret;
+}
+
+int
+copy_TicketFlags(const TicketFlags *from, TicketFlags *to)
+{
+*(to) = *(from);
+return 0;
+}
+
+unsigned TicketFlags2int(TicketFlags f)
+{
+unsigned r = 0;
+if(f.reserved) r |= (1U << 0);
+if(f.forwardable) r |= (1U << 1);
+if(f.forwarded) r |= (1U << 2);
+if(f.proxiable) r |= (1U << 3);
+if(f.proxy) r |= (1U << 4);
+if(f.may_postdate) r |= (1U << 5);
+if(f.postdated) r |= (1U << 6);
+if(f.invalid) r |= (1U << 7);
+if(f.renewable) r |= (1U << 8);
+if(f.initial) r |= (1U << 9);
+if(f.pre_authent) r |= (1U << 10);
+if(f.hw_authent) r |= (1U << 11);
+if(f.transited_policy_checked) r |= (1U << 12);
+if(f.ok_as_delegate) r |= (1U << 13);
+if(f.anonymous) r |= (1U << 14);
+return r;
+}
+
+TicketFlags int2TicketFlags(unsigned n)
+{
+       TicketFlags flags;
+
+       flags.reserved = (n >> 0) & 1;
+       flags.forwardable = (n >> 1) & 1;
+       flags.forwarded = (n >> 2) & 1;
+       flags.proxiable = (n >> 3) & 1;
+       flags.proxy = (n >> 4) & 1;
+       flags.may_postdate = (n >> 5) & 1;
+       flags.postdated = (n >> 6) & 1;
+       flags.invalid = (n >> 7) & 1;
+       flags.renewable = (n >> 8) & 1;
+       flags.initial = (n >> 9) & 1;
+       flags.pre_authent = (n >> 10) & 1;
+       flags.hw_authent = (n >> 11) & 1;
+       flags.transited_policy_checked = (n >> 12) & 1;
+       flags.ok_as_delegate = (n >> 13) & 1;
+       flags.anonymous = (n >> 14) & 1;
+       return flags;
+}
+
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_Realm(unsigned char *p, size_t len, const Realm *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+e = encode_general_string(p, len, data, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_Realm(const unsigned char *p, size_t len, Realm *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = decode_general_string(p, len, data, &l);
+FORW;
+if(size) *size = ret;
+return 0;
+fail:
+free_Realm(data);
+return e;
+}
+
+void
+free_Realm(Realm *data)
+{
+free_general_string(data);
+}
+
+size_t
+length_Realm(const Realm *data)
+{
+size_t ret = 0;
+ret += length_general_string(data);
+return ret;
+}
+
+int
+copy_Realm(const Realm *from, Realm *to)
+{
+if(copy_general_string(from, to)) return ENOMEM;
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_ENCTYPE(unsigned char *p, size_t len, const ENCTYPE *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+e = encode_integer(p, len, (const int*)data, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_ENCTYPE(const unsigned char *p, size_t len, ENCTYPE *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = decode_integer(p, len, (int*)data, &l);
+FORW;
+if(size) *size = ret;
+return 0;
+fail:
+free_ENCTYPE(data);
+return e;
+}
+
+void
+free_ENCTYPE(ENCTYPE *data)
+{
+}
+
+size_t
+length_ENCTYPE(const ENCTYPE *data)
+{
+size_t ret = 0;
+ret += length_integer((const int*)data);
+return ret;
+}
+
+int
+copy_ENCTYPE(const ENCTYPE *from, ENCTYPE *to)
+{
+*(to) = *(from);
+return 0;
+}
+
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <asn1_err.h>
+
+#define BACK if (e) return e; p -= l; len -= l; ret += l
+
+int
+encode_NAME_TYPE(unsigned char *p, size_t len, const NAME_TYPE *data, size_t *size)
+{
+size_t ret = 0;
+size_t l;
+int i, e;
+
+i = 0;
+e = encode_integer(p, len, (const int*)data, &l);
+BACK;
+*size = ret;
+return 0;
+}
+
+#define FORW if(e) goto fail; p += l; len -= l; ret += l
+
+int
+decode_NAME_TYPE(const unsigned char *p, size_t len, NAME_TYPE *data, size_t *size)
+{
+size_t ret = 0, reallen;
+size_t l;
+int e;
+
+memset(data, 0, sizeof(*data));
+reallen = 0;
+e = decode_integer(p, len, (int*)data, &l);
+FORW;
+if(size) *size = ret;
+return 0;
+fail:
+free_NAME_TYPE(data);
+return e;
+}
+
+void
+free_NAME_TYPE(NAME_TYPE *data)
+{
+}
+
+size_t
+length_NAME_TYPE(const NAME_TYPE *data)
+{
+size_t ret = 0;
+ret += length_integer((const int*)data);
+return ret;
+}
+
+int
+copy_NAME_TYPE(const NAME_TYPE *from, NAME_TYPE *to)
+{
+*(to) = *(from);
+return 0;
+}
+
diff --git a/src/rxkad/v5gen.h b/src/rxkad/v5gen.h
new file mode 100644 (file)
index 0000000..163cdd8
--- /dev/null
@@ -0,0 +1,1272 @@
+/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Do not edit */
+
+#ifndef __krb5_asn1_h__
+#define __krb5_asn1_h__
+
+#include <stddef.h>
+#include <time.h>
+
+#ifndef __asn1_common_definitions__
+#define __asn1_common_definitions__
+
+typedef struct octet_string {
+  size_t length;
+  void *data;
+} octet_string;
+
+typedef char *general_string;
+
+typedef struct oid {
+  size_t length;
+  unsigned *components;
+} oid;
+
+#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \
+  do {                                                         \
+    (BL) = length_##T((S));                                    \
+    (B) = malloc((BL));                                        \
+    if((B) == NULL) {                                          \
+      (R) = ENOMEM;                                            \
+    } else {                                                   \
+      (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
+                       (S), (L));                              \
+      if((R) != 0) {                                           \
+        free((B));                                             \
+        (B) = NULL;                                            \
+      }                                                        \
+    }                                                          \
+  } while (0)
+
+#endif
+
+/*
+NAME-TYPE ::= INTEGER
+*/
+
+typedef enum NAME_TYPE {
+  KRB5_NT_UNKNOWN = 0,
+  KRB5_NT_PRINCIPAL = 1,
+  KRB5_NT_SRV_INST = 2,
+  KRB5_NT_SRV_HST = 3,
+  KRB5_NT_SRV_XHST = 4,
+  KRB5_NT_UID = 5,
+  KRB5_NT_X500_PRINCIPAL = 6
+} NAME_TYPE;
+
+int    encode_NAME_TYPE(unsigned char *, size_t, const NAME_TYPE *, size_t *);
+int    decode_NAME_TYPE(const unsigned char *, size_t, NAME_TYPE *, size_t *);
+void   free_NAME_TYPE  (NAME_TYPE *);
+size_t length_NAME_TYPE(const NAME_TYPE *);
+int    copy_NAME_TYPE  (const NAME_TYPE *, NAME_TYPE *);
+
+
+/*
+MESSAGE-TYPE ::= INTEGER
+*/
+
+typedef enum MESSAGE_TYPE {
+  krb_as_req = 10,
+  krb_as_rep = 11,
+  krb_tgs_req = 12,
+  krb_tgs_rep = 13,
+  krb_ap_req = 14,
+  krb_ap_rep = 15,
+  krb_safe = 20,
+  krb_priv = 21,
+  krb_cred = 22,
+  krb_error = 30
+} MESSAGE_TYPE;
+
+int    encode_MESSAGE_TYPE(unsigned char *, size_t, const MESSAGE_TYPE *, size_t *);
+int    decode_MESSAGE_TYPE(const unsigned char *, size_t, MESSAGE_TYPE *, size_t *);
+void   free_MESSAGE_TYPE  (MESSAGE_TYPE *);
+size_t length_MESSAGE_TYPE(const MESSAGE_TYPE *);
+int    copy_MESSAGE_TYPE  (const MESSAGE_TYPE *, MESSAGE_TYPE *);
+
+
+/*
+PADATA-TYPE ::= INTEGER
+*/
+
+typedef enum PADATA_TYPE {
+  KRB5_PADATA_NONE = 0,
+  KRB5_PADATA_TGS_REQ = 1,
+  KRB5_PADATA_AP_REQ = 1,
+  KRB5_PADATA_ENC_TIMESTAMP = 2,
+  KRB5_PADATA_PW_SALT = 3,
+  KRB5_PADATA_ENC_UNIX_TIME = 5,
+  KRB5_PADATA_SANDIA_SECUREID = 6,
+  KRB5_PADATA_SESAME = 7,
+  KRB5_PADATA_OSF_DCE = 8,
+  KRB5_PADATA_CYBERSAFE_SECUREID = 9,
+  KRB5_PADATA_AFS3_SALT = 10,
+  KRB5_PADATA_ETYPE_INFO = 11,
+  KRB5_PADATA_SAM_CHALLENGE = 12,
+  KRB5_PADATA_SAM_RESPONSE = 13,
+  KRB5_PADATA_PK_AS_REQ = 14,
+  KRB5_PADATA_PK_AS_REP = 15,
+  KRB5_PADATA_PK_AS_SIGN = 16,
+  KRB5_PADATA_PK_KEY_REQ = 17,
+  KRB5_PADATA_PK_KEY_REP = 18,
+  KRB5_PADATA_USE_SPECIFIED_KVNO = 20,
+  KRB5_PADATA_SAM_REDIRECT = 21,
+  KRB5_PADATA_GET_FROM_TYPED_DATA = 22,
+  KRB5_PADATA_SAM_ETYPE_INFO = 23
+} PADATA_TYPE;
+
+int    encode_PADATA_TYPE(unsigned char *, size_t, const PADATA_TYPE *, size_t *);
+int    decode_PADATA_TYPE(const unsigned char *, size_t, PADATA_TYPE *, size_t *);
+void   free_PADATA_TYPE  (PADATA_TYPE *);
+size_t length_PADATA_TYPE(const PADATA_TYPE *);
+int    copy_PADATA_TYPE  (const PADATA_TYPE *, PADATA_TYPE *);
+
+
+/*
+CKSUMTYPE ::= INTEGER
+*/
+
+typedef enum CKSUMTYPE {
+  CKSUMTYPE_NONE = 0,
+  CKSUMTYPE_CRC32 = 1,
+  CKSUMTYPE_RSA_MD4 = 2,
+  CKSUMTYPE_RSA_MD4_DES = 3,
+  CKSUMTYPE_DES_MAC = 4,
+  CKSUMTYPE_DES_MAC_K = 5,
+  CKSUMTYPE_RSA_MD4_DES_K = 6,
+  CKSUMTYPE_RSA_MD5 = 7,
+  CKSUMTYPE_RSA_MD5_DES = 8,
+  CKSUMTYPE_RSA_MD5_DES3 = 9,
+  CKSUMTYPE_HMAC_SHA1_DES3 = 12,
+  CKSUMTYPE_SHA1 = 1000,
+  CKSUMTYPE_GSSAPI = 32771,
+  CKSUMTYPE_HMAC_MD5 = -138,
+  CKSUMTYPE_HMAC_MD5_ENC = -1138
+} CKSUMTYPE;
+
+int    encode_CKSUMTYPE(unsigned char *, size_t, const CKSUMTYPE *, size_t *);
+int    decode_CKSUMTYPE(const unsigned char *, size_t, CKSUMTYPE *, size_t *);
+void   free_CKSUMTYPE  (CKSUMTYPE *);
+size_t length_CKSUMTYPE(const CKSUMTYPE *);
+int    copy_CKSUMTYPE  (const CKSUMTYPE *, CKSUMTYPE *);
+
+
+/*
+ENCTYPE ::= INTEGER
+*/
+
+typedef enum ENCTYPE {
+  ETYPE_NULL = 0,
+  ETYPE_DES_CBC_CRC = 1,
+  ETYPE_DES_CBC_MD4 = 2,
+  ETYPE_DES_CBC_MD5 = 3,
+  ETYPE_DES3_CBC_MD5 = 5,
+  ETYPE_OLD_DES3_CBC_SHA1 = 7,
+  ETYPE_SIGN_DSA_GENERATE = 8,
+  ETYPE_ENCRYPT_RSA_PRIV = 9,
+  ETYPE_ENCRYPT_RSA_PUB = 10,
+  ETYPE_DES3_CBC_SHA1 = 16,
+  ETYPE_ARCFOUR_HMAC_MD5 = 23,
+  ETYPE_ARCFOUR_HMAC_MD5_56 = 24,
+  ETYPE_ENCTYPE_PK_CROSS = 48,
+  ETYPE_DES_CBC_NONE = -4096,
+  ETYPE_DES3_CBC_NONE = -4097,
+  ETYPE_DES_CFB64_NONE = -4098,
+  ETYPE_DES_PCBC_NONE = -4099
+} ENCTYPE;
+
+int    encode_ENCTYPE(unsigned char *, size_t, const ENCTYPE *, size_t *);
+int    decode_ENCTYPE(const unsigned char *, size_t, ENCTYPE *, size_t *);
+void   free_ENCTYPE  (ENCTYPE *);
+size_t length_ENCTYPE(const ENCTYPE *);
+int    copy_ENCTYPE  (const ENCTYPE *, ENCTYPE *);
+
+
+/*
+UNSIGNED ::= UNSIGNED INTEGER
+*/
+
+typedef unsigned int UNSIGNED;
+
+int    encode_UNSIGNED(unsigned char *, size_t, const UNSIGNED *, size_t *);
+int    decode_UNSIGNED(const unsigned char *, size_t, UNSIGNED *, size_t *);
+void   free_UNSIGNED  (UNSIGNED *);
+size_t length_UNSIGNED(const UNSIGNED *);
+int    copy_UNSIGNED  (const UNSIGNED *, UNSIGNED *);
+
+
+/*
+Realm ::= GeneralString
+*/
+
+typedef general_string Realm;
+
+int    encode_Realm(unsigned char *, size_t, const Realm *, size_t *);
+int    decode_Realm(const unsigned char *, size_t, Realm *, size_t *);
+void   free_Realm  (Realm *);
+size_t length_Realm(const Realm *);
+int    copy_Realm  (const Realm *, Realm *);
+
+
+/*
+PrincipalName ::= SEQUENCE {
+  name-type[0]    NAME-TYPE,
+  name-string[1]  SEQUENCE OF GeneralString
+}
+*/
+
+typedef struct PrincipalName {
+  NAME_TYPE name_type;
+  struct  {
+    unsigned int len;
+    general_string *val;
+  } name_string;
+} PrincipalName;
+
+int    encode_PrincipalName(unsigned char *, size_t, const PrincipalName *, size_t *);
+int    decode_PrincipalName(const unsigned char *, size_t, PrincipalName *, size_t *);
+void   free_PrincipalName  (PrincipalName *);
+size_t length_PrincipalName(const PrincipalName *);
+int    copy_PrincipalName  (const PrincipalName *, PrincipalName *);
+
+
+/*
+Principal ::= SEQUENCE {
+  name[0]         PrincipalName,
+  realm[1]        Realm
+}
+*/
+
+typedef struct Principal {
+  PrincipalName name;
+  Realm realm;
+} Principal;
+
+int    encode_Principal(unsigned char *, size_t, const Principal *, size_t *);
+int    decode_Principal(const unsigned char *, size_t, Principal *, size_t *);
+void   free_Principal  (Principal *);
+size_t length_Principal(const Principal *);
+int    copy_Principal  (const Principal *, Principal *);
+
+
+/*
+HostAddress ::= SEQUENCE {
+  addr-type[0]    INTEGER,
+  address[1]      OCTET STRING
+}
+*/
+
+typedef struct HostAddress {
+  int addr_type;
+  octet_string address;
+} HostAddress;
+
+int    encode_HostAddress(unsigned char *, size_t, const HostAddress *, size_t *);
+int    decode_HostAddress(const unsigned char *, size_t, HostAddress *, size_t *);
+void   free_HostAddress  (HostAddress *);
+size_t length_HostAddress(const HostAddress *);
+int    copy_HostAddress  (const HostAddress *, HostAddress *);
+
+
+/*
+HostAddresses ::= SEQUENCE OF HostAddress
+*/
+
+typedef struct HostAddresses {
+  unsigned int len;
+  HostAddress *val;
+} HostAddresses;
+
+int    encode_HostAddresses(unsigned char *, size_t, const HostAddresses *, size_t *);
+int    decode_HostAddresses(const unsigned char *, size_t, HostAddresses *, size_t *);
+void   free_HostAddresses  (HostAddresses *);
+size_t length_HostAddresses(const HostAddresses *);
+int    copy_HostAddresses  (const HostAddresses *, HostAddresses *);
+
+
+/*
+KerberosTime ::= GeneralizedTime
+*/
+
+typedef time_t KerberosTime;
+
+int    encode_KerberosTime(unsigned char *, size_t, const KerberosTime *, size_t *);
+int    decode_KerberosTime(const unsigned char *, size_t, KerberosTime *, size_t *);
+void   free_KerberosTime  (KerberosTime *);
+size_t length_KerberosTime(const KerberosTime *);
+int    copy_KerberosTime  (const KerberosTime *, KerberosTime *);
+
+
+/*
+AuthorizationData ::= SEQUENCE OF SEQUENCE {
+  ad-type[0]      INTEGER,
+  ad-data[1]      OCTET STRING
+}
+*/
+
+typedef struct AuthorizationData {
+  unsigned int len;
+  struct  {
+    int ad_type;
+    octet_string ad_data;
+  } *val;
+} AuthorizationData;
+
+int    encode_AuthorizationData(unsigned char *, size_t, const AuthorizationData *, size_t *);
+int    decode_AuthorizationData(const unsigned char *, size_t, AuthorizationData *, size_t *);
+void   free_AuthorizationData  (AuthorizationData *);
+size_t length_AuthorizationData(const AuthorizationData *);
+int    copy_AuthorizationData  (const AuthorizationData *, AuthorizationData *);
+
+
+/*
+APOptions ::= BIT STRING {
+  reserved(0),
+  use-session-key(1),
+  mutual-required(2)
+}
+*/
+
+typedef struct APOptions {
+  unsigned int reserved:1;
+  unsigned int use_session_key:1;
+  unsigned int mutual_required:1;
+} APOptions;
+
+
+int    encode_APOptions(unsigned char *, size_t, const APOptions *, size_t *);
+int    decode_APOptions(const unsigned char *, size_t, APOptions *, size_t *);
+void   free_APOptions  (APOptions *);
+size_t length_APOptions(const APOptions *);
+int    copy_APOptions  (const APOptions *, APOptions *);
+unsigned APOptions2int(APOptions);
+APOptions int2APOptions(unsigned);
+
+/*
+TicketFlags ::= BIT STRING {
+  reserved(0),
+  forwardable(1),
+  forwarded(2),
+  proxiable(3),
+  proxy(4),
+  may-postdate(5),
+  postdated(6),
+  invalid(7),
+  renewable(8),
+  initial(9),
+  pre-authent(10),
+  hw-authent(11),
+  transited-policy-checked(12),
+  ok-as-delegate(13),
+  anonymous(14)
+}
+*/
+
+typedef struct TicketFlags {
+  unsigned int reserved:1;
+  unsigned int forwardable:1;
+  unsigned int forwarded:1;
+  unsigned int proxiable:1;
+  unsigned int proxy:1;
+  unsigned int may_postdate:1;
+  unsigned int postdated:1;
+  unsigned int invalid:1;
+  unsigned int renewable:1;
+  unsigned int initial:1;
+  unsigned int pre_authent:1;
+  unsigned int hw_authent:1;
+  unsigned int transited_policy_checked:1;
+  unsigned int ok_as_delegate:1;
+  unsigned int anonymous:1;
+} TicketFlags;
+
+
+int    encode_TicketFlags(unsigned char *, size_t, const TicketFlags *, size_t *);
+int    decode_TicketFlags(const unsigned char *, size_t, TicketFlags *, size_t *);
+void   free_TicketFlags  (TicketFlags *);
+size_t length_TicketFlags(const TicketFlags *);
+int    copy_TicketFlags  (const TicketFlags *, TicketFlags *);
+unsigned TicketFlags2int(TicketFlags);
+TicketFlags int2TicketFlags(unsigned);
+
+/*
+KDCOptions ::= BIT STRING {
+  reserved(0),
+  forwardable(1),
+  forwarded(2),
+  proxiable(3),
+  proxy(4),
+  allow-postdate(5),
+  postdated(6),
+  unused7(7),
+  renewable(8),
+  unused9(9),
+  unused10(10),
+  unused11(11),
+  request-anonymous(14),
+  canonicalize(15),
+  disable-transited-check(26),
+  renewable-ok(27),
+  enc-tkt-in-skey(28),
+  renew(30),
+  validate(31)
+}
+*/
+
+typedef struct KDCOptions {
+  unsigned int reserved:1;
+  unsigned int forwardable:1;
+  unsigned int forwarded:1;
+  unsigned int proxiable:1;
+  unsigned int proxy:1;
+  unsigned int allow_postdate:1;
+  unsigned int postdated:1;
+  unsigned int unused7:1;
+  unsigned int renewable:1;
+  unsigned int unused9:1;
+  unsigned int unused10:1;
+  unsigned int unused11:1;
+  unsigned int request_anonymous:1;
+  unsigned int canonicalize:1;
+  unsigned int disable_transited_check:1;
+  unsigned int renewable_ok:1;
+  unsigned int enc_tkt_in_skey:1;
+  unsigned int renew:1;
+  unsigned int validate:1;
+} KDCOptions;
+
+
+int    encode_KDCOptions(unsigned char *, size_t, const KDCOptions *, size_t *);
+int    decode_KDCOptions(const unsigned char *, size_t, KDCOptions *, size_t *);
+void   free_KDCOptions  (KDCOptions *);
+size_t length_KDCOptions(const KDCOptions *);
+int    copy_KDCOptions  (const KDCOptions *, KDCOptions *);
+unsigned KDCOptions2int(KDCOptions);
+KDCOptions int2KDCOptions(unsigned);
+
+/*
+LR-TYPE ::= INTEGER
+*/
+
+typedef enum LR_TYPE {
+  LR_NONE = 0,
+  LR_INITIAL_TGT = 1,
+  LR_INITIAL = 2,
+  LR_ISSUE_USE_TGT = 3,
+  LR_RENEWAL = 4,
+  LR_REQUEST = 5,
+  LR_PW_EXPTIME = 6,
+  LR_ACCT_EXPTIME = 7
+} LR_TYPE;
+
+int    encode_LR_TYPE(unsigned char *, size_t, const LR_TYPE *, size_t *);
+int    decode_LR_TYPE(const unsigned char *, size_t, LR_TYPE *, size_t *);
+void   free_LR_TYPE  (LR_TYPE *);
+size_t length_LR_TYPE(const LR_TYPE *);
+int    copy_LR_TYPE  (const LR_TYPE *, LR_TYPE *);
+
+
+/*
+LastReq ::= SEQUENCE OF SEQUENCE {
+  lr-type[0]      LR-TYPE,
+  lr-value[1]     KerberosTime
+}
+*/
+
+typedef struct LastReq {
+  unsigned int len;
+  struct  {
+    LR_TYPE lr_type;
+    KerberosTime lr_value;
+  } *val;
+} LastReq;
+
+int    encode_LastReq(unsigned char *, size_t, const LastReq *, size_t *);
+int    decode_LastReq(const unsigned char *, size_t, LastReq *, size_t *);
+void   free_LastReq  (LastReq *);
+size_t length_LastReq(const LastReq *);
+int    copy_LastReq  (const LastReq *, LastReq *);
+
+
+/*
+EncryptedData ::= SEQUENCE {
+  etype[0]        ENCTYPE,
+  kvno[1]         INTEGER OPTIONAL,
+  cipher[2]       OCTET STRING
+}
+*/
+
+typedef struct EncryptedData {
+  ENCTYPE etype;
+  int *kvno;
+  octet_string cipher;
+} EncryptedData;
+
+int    encode_EncryptedData(unsigned char *, size_t, const EncryptedData *, size_t *);
+int    decode_EncryptedData(const unsigned char *, size_t, EncryptedData *, size_t *);
+void   free_EncryptedData  (EncryptedData *);
+size_t length_EncryptedData(const EncryptedData *);
+int    copy_EncryptedData  (const EncryptedData *, EncryptedData *);
+
+
+/*
+EncryptionKey ::= SEQUENCE {
+  keytype[0]      INTEGER,
+  keyvalue[1]     OCTET STRING
+}
+*/
+
+typedef struct EncryptionKey {
+  int keytype;
+  octet_string keyvalue;
+} EncryptionKey;
+
+int    encode_EncryptionKey(unsigned char *, size_t, const EncryptionKey *, size_t *);
+int    decode_EncryptionKey(const unsigned char *, size_t, EncryptionKey *, size_t *);
+void   free_EncryptionKey  (EncryptionKey *);
+size_t length_EncryptionKey(const EncryptionKey *);
+int    copy_EncryptionKey  (const EncryptionKey *, EncryptionKey *);
+
+
+/*
+TransitedEncoding ::= SEQUENCE {
+  tr-type[0]      INTEGER,
+  contents[1]     OCTET STRING
+}
+*/
+
+typedef struct TransitedEncoding {
+  int tr_type;
+  octet_string contents;
+} TransitedEncoding;
+
+int    encode_TransitedEncoding(unsigned char *, size_t, const TransitedEncoding *, size_t *);
+int    decode_TransitedEncoding(const unsigned char *, size_t, TransitedEncoding *, size_t *);
+void   free_TransitedEncoding  (TransitedEncoding *);
+size_t length_TransitedEncoding(const TransitedEncoding *);
+int    copy_TransitedEncoding  (const TransitedEncoding *, TransitedEncoding *);
+
+
+/*
+Ticket ::= [APPLICATION 1] SEQUENCE {
+  tkt-vno[0]      INTEGER,
+  realm[1]        Realm,
+  sname[2]        PrincipalName,
+  enc-part[3]     EncryptedData
+}
+*/
+
+typedef struct  {
+  int tkt_vno;
+  Realm realm;
+  PrincipalName sname;
+  EncryptedData enc_part;
+} Ticket;
+
+int    encode_Ticket(unsigned char *, size_t, const Ticket *, size_t *);
+int    decode_Ticket(const unsigned char *, size_t, Ticket *, size_t *);
+void   free_Ticket  (Ticket *);
+size_t length_Ticket(const Ticket *);
+int    copy_Ticket  (const Ticket *, Ticket *);
+
+
+/*
+EncTicketPart ::= [APPLICATION 3] SEQUENCE {
+  flags[0]                TicketFlags,
+  key[1]                  EncryptionKey,
+  crealm[2]               Realm,
+  cname[3]                PrincipalName,
+  transited[4]            TransitedEncoding,
+  authtime[5]             KerberosTime,
+  starttime[6]            KerberosTime OPTIONAL,
+  endtime[7]              KerberosTime,
+  renew-till[8]           KerberosTime OPTIONAL,
+  caddr[9]                HostAddresses OPTIONAL,
+  authorization-data[10]  AuthorizationData OPTIONAL
+}
+*/
+
+typedef struct  {
+  TicketFlags flags;
+  EncryptionKey key;
+  Realm crealm;
+  PrincipalName cname;
+  TransitedEncoding transited;
+  KerberosTime authtime;
+  KerberosTime *starttime;
+  KerberosTime endtime;
+  KerberosTime *renew_till;
+  HostAddresses *caddr;
+  AuthorizationData *authorization_data;
+} EncTicketPart;
+
+int    encode_EncTicketPart(unsigned char *, size_t, const EncTicketPart *, size_t *);
+int    decode_EncTicketPart(const unsigned char *, size_t, EncTicketPart *, size_t *);
+void   free_EncTicketPart  (EncTicketPart *);
+size_t length_EncTicketPart(const EncTicketPart *);
+int    copy_EncTicketPart  (const EncTicketPart *, EncTicketPart *);
+
+
+/*
+Checksum ::= SEQUENCE {
+  cksumtype[0]    CKSUMTYPE,
+  checksum[1]     OCTET STRING
+}
+*/
+
+typedef struct Checksum {
+  CKSUMTYPE cksumtype;
+  octet_string checksum;
+} Checksum;
+
+int    encode_Checksum(unsigned char *, size_t, const Checksum *, size_t *);
+int    decode_Checksum(const unsigned char *, size_t, Checksum *, size_t *);
+void   free_Checksum  (Checksum *);
+size_t length_Checksum(const Checksum *);
+int    copy_Checksum  (const Checksum *, Checksum *);
+
+
+/*
+Authenticator ::= [APPLICATION 2] SEQUENCE {
+  authenticator-vno[0]   INTEGER,
+  crealm[1]              Realm,
+  cname[2]               PrincipalName,
+  cksum[3]               Checksum OPTIONAL,
+  cusec[4]               INTEGER,
+  ctime[5]               KerberosTime,
+  subkey[6]              EncryptionKey OPTIONAL,
+  seq-number[7]          UNSIGNED OPTIONAL,
+  authorization-data[8]  AuthorizationData OPTIONAL
+}
+*/
+
+typedef struct  {
+  int authenticator_vno;
+  Realm crealm;
+  PrincipalName cname;
+  Checksum *cksum;
+  int cusec;
+  KerberosTime ctime;
+  EncryptionKey *subkey;
+  UNSIGNED *seq_number;
+  AuthorizationData *authorization_data;
+} Authenticator;
+
+int    encode_Authenticator(unsigned char *, size_t, const Authenticator *, size_t *);
+int    decode_Authenticator(const unsigned char *, size_t, Authenticator *, size_t *);
+void   free_Authenticator  (Authenticator *);
+size_t length_Authenticator(const Authenticator *);
+int    copy_Authenticator  (const Authenticator *, Authenticator *);
+
+
+/*
+PA-DATA ::= SEQUENCE {
+  padata-type[1]   PADATA-TYPE,
+  padata-value[2]  OCTET STRING
+}
+*/
+
+typedef struct PA_DATA {
+  PADATA_TYPE padata_type;
+  octet_string padata_value;
+} PA_DATA;
+
+int    encode_PA_DATA(unsigned char *, size_t, const PA_DATA *, size_t *);
+int    decode_PA_DATA(const unsigned char *, size_t, PA_DATA *, size_t *);
+void   free_PA_DATA  (PA_DATA *);
+size_t length_PA_DATA(const PA_DATA *);
+int    copy_PA_DATA  (const PA_DATA *, PA_DATA *);
+
+
+/*
+ETYPE-INFO-ENTRY ::= SEQUENCE {
+  etype[0]        ENCTYPE,
+  salt[1]         OCTET STRING OPTIONAL,
+  salttype[2]     INTEGER OPTIONAL
+}
+*/
+
+typedef struct ETYPE_INFO_ENTRY {
+  ENCTYPE etype;
+  octet_string *salt;
+  int *salttype;
+} ETYPE_INFO_ENTRY;
+
+int    encode_ETYPE_INFO_ENTRY(unsigned char *, size_t, const ETYPE_INFO_ENTRY *, size_t *);
+int    decode_ETYPE_INFO_ENTRY(const unsigned char *, size_t, ETYPE_INFO_ENTRY *, size_t *);
+void   free_ETYPE_INFO_ENTRY  (ETYPE_INFO_ENTRY *);
+size_t length_ETYPE_INFO_ENTRY(const ETYPE_INFO_ENTRY *);
+int    copy_ETYPE_INFO_ENTRY  (const ETYPE_INFO_ENTRY *, ETYPE_INFO_ENTRY *);
+
+
+/*
+ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
+*/
+
+typedef struct ETYPE_INFO {
+  unsigned int len;
+  ETYPE_INFO_ENTRY *val;
+} ETYPE_INFO;
+
+int    encode_ETYPE_INFO(unsigned char *, size_t, const ETYPE_INFO *, size_t *);
+int    decode_ETYPE_INFO(const unsigned char *, size_t, ETYPE_INFO *, size_t *);
+void   free_ETYPE_INFO  (ETYPE_INFO *);
+size_t length_ETYPE_INFO(const ETYPE_INFO *);
+int    copy_ETYPE_INFO  (const ETYPE_INFO *, ETYPE_INFO *);
+
+
+/*
+METHOD-DATA ::= SEQUENCE OF PA-DATA
+*/
+
+typedef struct METHOD_DATA {
+  unsigned int len;
+  PA_DATA *val;
+} METHOD_DATA;
+
+int    encode_METHOD_DATA(unsigned char *, size_t, const METHOD_DATA *, size_t *);
+int    decode_METHOD_DATA(const unsigned char *, size_t, METHOD_DATA *, size_t *);
+void   free_METHOD_DATA  (METHOD_DATA *);
+size_t length_METHOD_DATA(const METHOD_DATA *);
+int    copy_METHOD_DATA  (const METHOD_DATA *, METHOD_DATA *);
+
+
+/*
+KDC-REQ-BODY ::= SEQUENCE {
+  kdc-options[0]              KDCOptions,
+  cname[1]                    PrincipalName OPTIONAL,
+  realm[2]                    Realm,
+  sname[3]                    PrincipalName OPTIONAL,
+  from[4]                     KerberosTime OPTIONAL,
+  till[5]                     KerberosTime OPTIONAL,
+  rtime[6]                    KerberosTime OPTIONAL,
+  nonce[7]                    INTEGER,
+  etype[8]                    SEQUENCE OF ENCTYPE,
+  addresses[9]                HostAddresses OPTIONAL,
+  enc-authorization-data[10]  EncryptedData OPTIONAL,
+  additional-tickets[11]      SEQUENCE OF Ticket OPTIONAL
+}
+*/
+
+typedef struct KDC_REQ_BODY {
+  KDCOptions kdc_options;
+  PrincipalName *cname;
+  Realm realm;
+  PrincipalName *sname;
+  KerberosTime *from;
+  KerberosTime *till;
+  KerberosTime *rtime;
+  int nonce;
+  struct  {
+    unsigned int len;
+    ENCTYPE *val;
+  } etype;
+  HostAddresses *addresses;
+  EncryptedData *enc_authorization_data;
+  struct  {
+    unsigned int len;
+    Ticket *val;
+  } *additional_tickets;
+} KDC_REQ_BODY;
+
+int    encode_KDC_REQ_BODY(unsigned char *, size_t, const KDC_REQ_BODY *, size_t *);
+int    decode_KDC_REQ_BODY(const unsigned char *, size_t, KDC_REQ_BODY *, size_t *);
+void   free_KDC_REQ_BODY  (KDC_REQ_BODY *);
+size_t length_KDC_REQ_BODY(const KDC_REQ_BODY *);
+int    copy_KDC_REQ_BODY  (const KDC_REQ_BODY *, KDC_REQ_BODY *);
+
+
+/*
+KDC-REQ ::= SEQUENCE {
+  pvno[1]         INTEGER,
+  msg-type[2]     MESSAGE-TYPE,
+  padata[3]       METHOD-DATA OPTIONAL,
+  req-body[4]     KDC-REQ-BODY
+}
+*/
+
+typedef struct KDC_REQ {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  METHOD_DATA *padata;
+  KDC_REQ_BODY req_body;
+} KDC_REQ;
+
+int    encode_KDC_REQ(unsigned char *, size_t, const KDC_REQ *, size_t *);
+int    decode_KDC_REQ(const unsigned char *, size_t, KDC_REQ *, size_t *);
+void   free_KDC_REQ  (KDC_REQ *);
+size_t length_KDC_REQ(const KDC_REQ *);
+int    copy_KDC_REQ  (const KDC_REQ *, KDC_REQ *);
+
+
+/*
+AS-REQ ::= [APPLICATION 10] KDC-REQ
+*/
+
+typedef KDC_REQ AS_REQ;
+
+int    encode_AS_REQ(unsigned char *, size_t, const AS_REQ *, size_t *);
+int    decode_AS_REQ(const unsigned char *, size_t, AS_REQ *, size_t *);
+void   free_AS_REQ  (AS_REQ *);
+size_t length_AS_REQ(const AS_REQ *);
+int    copy_AS_REQ  (const AS_REQ *, AS_REQ *);
+
+
+/*
+TGS-REQ ::= [APPLICATION 12] KDC-REQ
+*/
+
+typedef KDC_REQ TGS_REQ;
+
+int    encode_TGS_REQ(unsigned char *, size_t, const TGS_REQ *, size_t *);
+int    decode_TGS_REQ(const unsigned char *, size_t, TGS_REQ *, size_t *);
+void   free_TGS_REQ  (TGS_REQ *);
+size_t length_TGS_REQ(const TGS_REQ *);
+int    copy_TGS_REQ  (const TGS_REQ *, TGS_REQ *);
+
+
+/*
+PA-ENC-TS-ENC ::= SEQUENCE {
+  patimestamp[0]  KerberosTime,
+  pausec[1]       INTEGER OPTIONAL
+}
+*/
+
+typedef struct PA_ENC_TS_ENC {
+  KerberosTime patimestamp;
+  int *pausec;
+} PA_ENC_TS_ENC;
+
+int    encode_PA_ENC_TS_ENC(unsigned char *, size_t, const PA_ENC_TS_ENC *, size_t *);
+int    decode_PA_ENC_TS_ENC(const unsigned char *, size_t, PA_ENC_TS_ENC *, size_t *);
+void   free_PA_ENC_TS_ENC  (PA_ENC_TS_ENC *);
+size_t length_PA_ENC_TS_ENC(const PA_ENC_TS_ENC *);
+int    copy_PA_ENC_TS_ENC  (const PA_ENC_TS_ENC *, PA_ENC_TS_ENC *);
+
+
+/*
+KDC-REP ::= SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  padata[2]       METHOD-DATA OPTIONAL,
+  crealm[3]       Realm,
+  cname[4]        PrincipalName,
+  ticket[5]       Ticket,
+  enc-part[6]     EncryptedData
+}
+*/
+
+typedef struct KDC_REP {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  METHOD_DATA *padata;
+  Realm crealm;
+  PrincipalName cname;
+  Ticket ticket;
+  EncryptedData enc_part;
+} KDC_REP;
+
+int    encode_KDC_REP(unsigned char *, size_t, const KDC_REP *, size_t *);
+int    decode_KDC_REP(const unsigned char *, size_t, KDC_REP *, size_t *);
+void   free_KDC_REP  (KDC_REP *);
+size_t length_KDC_REP(const KDC_REP *);
+int    copy_KDC_REP  (const KDC_REP *, KDC_REP *);
+
+
+/*
+AS-REP ::= [APPLICATION 11] KDC-REP
+*/
+
+typedef KDC_REP AS_REP;
+
+int    encode_AS_REP(unsigned char *, size_t, const AS_REP *, size_t *);
+int    decode_AS_REP(const unsigned char *, size_t, AS_REP *, size_t *);
+void   free_AS_REP  (AS_REP *);
+size_t length_AS_REP(const AS_REP *);
+int    copy_AS_REP  (const AS_REP *, AS_REP *);
+
+
+/*
+TGS-REP ::= [APPLICATION 13] KDC-REP
+*/
+
+typedef KDC_REP TGS_REP;
+
+int    encode_TGS_REP(unsigned char *, size_t, const TGS_REP *, size_t *);
+int    decode_TGS_REP(const unsigned char *, size_t, TGS_REP *, size_t *);
+void   free_TGS_REP  (TGS_REP *);
+size_t length_TGS_REP(const TGS_REP *);
+int    copy_TGS_REP  (const TGS_REP *, TGS_REP *);
+
+
+/*
+EncKDCRepPart ::= SEQUENCE {
+  key[0]             EncryptionKey,
+  last-req[1]        LastReq,
+  nonce[2]           INTEGER,
+  key-expiration[3]  KerberosTime OPTIONAL,
+  flags[4]           TicketFlags,
+  authtime[5]        KerberosTime,
+  starttime[6]       KerberosTime OPTIONAL,
+  endtime[7]         KerberosTime,
+  renew-till[8]      KerberosTime OPTIONAL,
+  srealm[9]          Realm,
+  sname[10]          PrincipalName,
+  caddr[11]          HostAddresses OPTIONAL
+}
+*/
+
+typedef struct EncKDCRepPart {
+  EncryptionKey key;
+  LastReq last_req;
+  int nonce;
+  KerberosTime *key_expiration;
+  TicketFlags flags;
+  KerberosTime authtime;
+  KerberosTime *starttime;
+  KerberosTime endtime;
+  KerberosTime *renew_till;
+  Realm srealm;
+  PrincipalName sname;
+  HostAddresses *caddr;
+} EncKDCRepPart;
+
+int    encode_EncKDCRepPart(unsigned char *, size_t, const EncKDCRepPart *, size_t *);
+int    decode_EncKDCRepPart(const unsigned char *, size_t, EncKDCRepPart *, size_t *);
+void   free_EncKDCRepPart  (EncKDCRepPart *);
+size_t length_EncKDCRepPart(const EncKDCRepPart *);
+int    copy_EncKDCRepPart  (const EncKDCRepPart *, EncKDCRepPart *);
+
+
+/*
+EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
+*/
+
+typedef EncKDCRepPart EncASRepPart;
+
+int    encode_EncASRepPart(unsigned char *, size_t, const EncASRepPart *, size_t *);
+int    decode_EncASRepPart(const unsigned char *, size_t, EncASRepPart *, size_t *);
+void   free_EncASRepPart  (EncASRepPart *);
+size_t length_EncASRepPart(const EncASRepPart *);
+int    copy_EncASRepPart  (const EncASRepPart *, EncASRepPart *);
+
+
+/*
+EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
+*/
+
+typedef EncKDCRepPart EncTGSRepPart;
+
+int    encode_EncTGSRepPart(unsigned char *, size_t, const EncTGSRepPart *, size_t *);
+int    decode_EncTGSRepPart(const unsigned char *, size_t, EncTGSRepPart *, size_t *);
+void   free_EncTGSRepPart  (EncTGSRepPart *);
+size_t length_EncTGSRepPart(const EncTGSRepPart *);
+int    copy_EncTGSRepPart  (const EncTGSRepPart *, EncTGSRepPart *);
+
+
+/*
+AP-REQ ::= [APPLICATION 14] SEQUENCE {
+  pvno[0]           INTEGER,
+  msg-type[1]       MESSAGE-TYPE,
+  ap-options[2]     APOptions,
+  ticket[3]         Ticket,
+  authenticator[4]  EncryptedData
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  APOptions ap_options;
+  Ticket ticket;
+  EncryptedData authenticator;
+} AP_REQ;
+
+int    encode_AP_REQ(unsigned char *, size_t, const AP_REQ *, size_t *);
+int    decode_AP_REQ(const unsigned char *, size_t, AP_REQ *, size_t *);
+void   free_AP_REQ  (AP_REQ *);
+size_t length_AP_REQ(const AP_REQ *);
+int    copy_AP_REQ  (const AP_REQ *, AP_REQ *);
+
+
+/*
+AP-REP ::= [APPLICATION 15] SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  enc-part[2]     EncryptedData
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  EncryptedData enc_part;
+} AP_REP;
+
+int    encode_AP_REP(unsigned char *, size_t, const AP_REP *, size_t *);
+int    decode_AP_REP(const unsigned char *, size_t, AP_REP *, size_t *);
+void   free_AP_REP  (AP_REP *);
+size_t length_AP_REP(const AP_REP *);
+int    copy_AP_REP  (const AP_REP *, AP_REP *);
+
+
+/*
+EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
+  ctime[0]        KerberosTime,
+  cusec[1]        INTEGER,
+  subkey[2]       EncryptionKey OPTIONAL,
+  seq-number[3]   UNSIGNED OPTIONAL
+}
+*/
+
+typedef struct  {
+  KerberosTime ctime;
+  int cusec;
+  EncryptionKey *subkey;
+  UNSIGNED *seq_number;
+} EncAPRepPart;
+
+int    encode_EncAPRepPart(unsigned char *, size_t, const EncAPRepPart *, size_t *);
+int    decode_EncAPRepPart(const unsigned char *, size_t, EncAPRepPart *, size_t *);
+void   free_EncAPRepPart  (EncAPRepPart *);
+size_t length_EncAPRepPart(const EncAPRepPart *);
+int    copy_EncAPRepPart  (const EncAPRepPart *, EncAPRepPart *);
+
+
+/*
+KRB-SAFE-BODY ::= SEQUENCE {
+  user-data[0]    OCTET STRING,
+  timestamp[1]    KerberosTime OPTIONAL,
+  usec[2]         INTEGER OPTIONAL,
+  seq-number[3]   UNSIGNED OPTIONAL,
+  s-address[4]    HostAddress OPTIONAL,
+  r-address[5]    HostAddress OPTIONAL
+}
+*/
+
+typedef struct KRB_SAFE_BODY {
+  octet_string user_data;
+  KerberosTime *timestamp;
+  int *usec;
+  UNSIGNED *seq_number;
+  HostAddress *s_address;
+  HostAddress *r_address;
+} KRB_SAFE_BODY;
+
+int    encode_KRB_SAFE_BODY(unsigned char *, size_t, const KRB_SAFE_BODY *, size_t *);
+int    decode_KRB_SAFE_BODY(const unsigned char *, size_t, KRB_SAFE_BODY *, size_t *);
+void   free_KRB_SAFE_BODY  (KRB_SAFE_BODY *);
+size_t length_KRB_SAFE_BODY(const KRB_SAFE_BODY *);
+int    copy_KRB_SAFE_BODY  (const KRB_SAFE_BODY *, KRB_SAFE_BODY *);
+
+
+/*
+KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  safe-body[2]    KRB-SAFE-BODY,
+  cksum[3]        Checksum
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  KRB_SAFE_BODY safe_body;
+  Checksum cksum;
+} KRB_SAFE;
+
+int    encode_KRB_SAFE(unsigned char *, size_t, const KRB_SAFE *, size_t *);
+int    decode_KRB_SAFE(const unsigned char *, size_t, KRB_SAFE *, size_t *);
+void   free_KRB_SAFE  (KRB_SAFE *);
+size_t length_KRB_SAFE(const KRB_SAFE *);
+int    copy_KRB_SAFE  (const KRB_SAFE *, KRB_SAFE *);
+
+
+/*
+KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  enc-part[3]     EncryptedData
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  EncryptedData enc_part;
+} KRB_PRIV;
+
+int    encode_KRB_PRIV(unsigned char *, size_t, const KRB_PRIV *, size_t *);
+int    decode_KRB_PRIV(const unsigned char *, size_t, KRB_PRIV *, size_t *);
+void   free_KRB_PRIV  (KRB_PRIV *);
+size_t length_KRB_PRIV(const KRB_PRIV *);
+int    copy_KRB_PRIV  (const KRB_PRIV *, KRB_PRIV *);
+
+
+/*
+EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
+  user-data[0]    OCTET STRING,
+  timestamp[1]    KerberosTime OPTIONAL,
+  usec[2]         INTEGER OPTIONAL,
+  seq-number[3]   UNSIGNED OPTIONAL,
+  s-address[4]    HostAddress OPTIONAL,
+  r-address[5]    HostAddress OPTIONAL
+}
+*/
+
+typedef struct  {
+  octet_string user_data;
+  KerberosTime *timestamp;
+  int *usec;
+  UNSIGNED *seq_number;
+  HostAddress *s_address;
+  HostAddress *r_address;
+} EncKrbPrivPart;
+
+int    encode_EncKrbPrivPart(unsigned char *, size_t, const EncKrbPrivPart *, size_t *);
+int    decode_EncKrbPrivPart(const unsigned char *, size_t, EncKrbPrivPart *, size_t *);
+void   free_EncKrbPrivPart  (EncKrbPrivPart *);
+size_t length_EncKrbPrivPart(const EncKrbPrivPart *);
+int    copy_EncKrbPrivPart  (const EncKrbPrivPart *, EncKrbPrivPart *);
+
+
+/*
+KRB-CRED ::= [APPLICATION 22] SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  tickets[2]      SEQUENCE OF Ticket,
+  enc-part[3]     EncryptedData
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  struct  {
+    unsigned int len;
+    Ticket *val;
+  } tickets;
+  EncryptedData enc_part;
+} KRB_CRED;
+
+int    encode_KRB_CRED(unsigned char *, size_t, const KRB_CRED *, size_t *);
+int    decode_KRB_CRED(const unsigned char *, size_t, KRB_CRED *, size_t *);
+void   free_KRB_CRED  (KRB_CRED *);
+size_t length_KRB_CRED(const KRB_CRED *);
+int    copy_KRB_CRED  (const KRB_CRED *, KRB_CRED *);
+
+
+/*
+KrbCredInfo ::= SEQUENCE {
+  key[0]          EncryptionKey,
+  prealm[1]       Realm OPTIONAL,
+  pname[2]        PrincipalName OPTIONAL,
+  flags[3]        TicketFlags OPTIONAL,
+  authtime[4]     KerberosTime OPTIONAL,
+  starttime[5]    KerberosTime OPTIONAL,
+  endtime[6]      KerberosTime OPTIONAL,
+  renew-till[7]   KerberosTime OPTIONAL,
+  srealm[8]       Realm OPTIONAL,
+  sname[9]        PrincipalName OPTIONAL,
+  caddr[10]       HostAddresses OPTIONAL
+}
+*/
+
+typedef struct KrbCredInfo {
+  EncryptionKey key;
+  Realm *prealm;
+  PrincipalName *pname;
+  TicketFlags *flags;
+  KerberosTime *authtime;
+  KerberosTime *starttime;
+  KerberosTime *endtime;
+  KerberosTime *renew_till;
+  Realm *srealm;
+  PrincipalName *sname;
+  HostAddresses *caddr;
+} KrbCredInfo;
+
+int    encode_KrbCredInfo(unsigned char *, size_t, const KrbCredInfo *, size_t *);
+int    decode_KrbCredInfo(const unsigned char *, size_t, KrbCredInfo *, size_t *);
+void   free_KrbCredInfo  (KrbCredInfo *);
+size_t length_KrbCredInfo(const KrbCredInfo *);
+int    copy_KrbCredInfo  (const KrbCredInfo *, KrbCredInfo *);
+
+
+/*
+EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
+  ticket-info[0]  SEQUENCE OF KrbCredInfo,
+  nonce[1]        INTEGER OPTIONAL,
+  timestamp[2]    KerberosTime OPTIONAL,
+  usec[3]         INTEGER OPTIONAL,
+  s-address[4]    HostAddress OPTIONAL,
+  r-address[5]    HostAddress OPTIONAL
+}
+*/
+
+typedef struct  {
+  struct  {
+    unsigned int len;
+    KrbCredInfo *val;
+  } ticket_info;
+  int *nonce;
+  KerberosTime *timestamp;
+  int *usec;
+  HostAddress *s_address;
+  HostAddress *r_address;
+} EncKrbCredPart;
+
+int    encode_EncKrbCredPart(unsigned char *, size_t, const EncKrbCredPart *, size_t *);
+int    decode_EncKrbCredPart(const unsigned char *, size_t, EncKrbCredPart *, size_t *);
+void   free_EncKrbCredPart  (EncKrbCredPart *);
+size_t length_EncKrbCredPart(const EncKrbCredPart *);
+int    copy_EncKrbCredPart  (const EncKrbCredPart *, EncKrbCredPart *);
+
+
+/*
+KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+  pvno[0]         INTEGER,
+  msg-type[1]     MESSAGE-TYPE,
+  ctime[2]        KerberosTime OPTIONAL,
+  cusec[3]        INTEGER OPTIONAL,
+  stime[4]        KerberosTime,
+  susec[5]        INTEGER,
+  error-code[6]   INTEGER,
+  crealm[7]       Realm OPTIONAL,
+  cname[8]        PrincipalName OPTIONAL,
+  realm[9]        Realm,
+  sname[10]       PrincipalName,
+  e-text[11]      GeneralString OPTIONAL,
+  e-data[12]      OCTET STRING OPTIONAL
+}
+*/
+
+typedef struct  {
+  int pvno;
+  MESSAGE_TYPE msg_type;
+  KerberosTime *ctime;
+  int *cusec;
+  KerberosTime stime;
+  int susec;
+  int error_code;
+  Realm *crealm;
+  PrincipalName *cname;
+  Realm realm;
+  PrincipalName sname;
+  general_string *e_text;
+  octet_string *e_data;
+} KRB_ERROR;
+
+int    encode_KRB_ERROR(unsigned char *, size_t, const KRB_ERROR *, size_t *);
+int    decode_KRB_ERROR(const unsigned char *, size_t, KRB_ERROR *, size_t *);
+void   free_KRB_ERROR  (KRB_ERROR *);
+size_t length_KRB_ERROR(const KRB_ERROR *);
+int    copy_KRB_ERROR  (const KRB_ERROR *, KRB_ERROR *);
+
+
+enum { pvno = 5 };
+
+enum { DOMAIN_X500_COMPRESS = 1 };
+
+#endif /* __krb5_asn1_h__ */
index 8e7ce66..ec37b5e 100644 (file)
@@ -85,6 +85,8 @@ RXKADOBJS =\
        rxkad_server.o \
        rxkad_common.o \
        ticket.o \
+       ticket5.o \
+       crc.o \
        fcrypt.o \
        crypt_conn.o
 
@@ -190,6 +192,12 @@ rxkad_common.o: ${RXKAD}/rxkad_common.c
 ticket.o: ${RXKAD}/ticket.c
        ${CCRULE}
 
+ticket5.o: ${RXKAD}/ticket5.c
+       ${CCRULE}
+
+crc.o: ${RXKAD}/crc.c
+       ${CCRULE}
+
 fcrypt.o: ${RXKAD}/fcrypt.c
        ${CCRULE}