]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Initial revision
authorSam Hartman <hartmans@debian.org>
Wed, 11 Dec 2002 02:42:32 +0000 (02:42 +0000)
committerSam Hartman <hartmans@debian.org>
Wed, 11 Dec 2002 02:42:32 +0000 (02:42 +0000)
12 files changed:
src/cf/linux-test5.m4 [new file with mode: 0644]
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/bg-fcrypt.c [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/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]

diff --git a/src/cf/linux-test5.m4 b/src/cf/linux-test5.m4
new file mode 100644 (file)
index 0000000..97ce80b
--- /dev/null
@@ -0,0 +1,71 @@
+
+AC_DEFUN(OPENAFS_GCC_SUPPORTS_MARCH, [
+AC_MSG_CHECKING(if $CC accepts -march=pentium)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-MARCH=pentium"
+AC_CACHE_VAL(openafs_gcc_supports_march,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_supports_march=yes,
+openafs_gcc_supports_march=no)])
+AC_MSG_RESULT($openafs_gcc_supports_march)
+if test x$openafs_gcc_supports_march = xyes; then
+  P5PLUS_KOPTS="-march=pentium"
+else
+  P5PLUS_KOPTS="-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRICT_ALIASING, [
+AC_MSG_CHECKING(if $CC needs -fno-strict-aliasing)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-strict-aliasing"
+AC_CACHE_VAL(openafs_gcc_needs_no_strict_aliasing,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_needs_no_strict_aliasing=yes,
+openafs_gcc_needs_no_strict_aliasing=no)])
+AC_MSG_RESULT($openafs_gcc_needs_no_strict_aliasing)
+if test x$openafs_gcc_needs_no_strict_aliasing = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strict-aliasing"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRENGTH_REDUCE, [
+AC_MSG_CHECKING(if $CC needs -fno-strength-reduce)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-strength-reduce"
+AC_CACHE_VAL(openafs_gcc_needs_no_strength_reduce,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_needs_no_strength_reduce=yes,
+openafs_gcc_needs_no_strength_reduce=no)])
+AC_MSG_RESULT($openafs_gcc_needs_no_strength_reduce)
+if test x$openafs_gcc_needs_no_strength_reduce = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strength-reduce"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_SUPPORTS_NO_COMMON, [
+AC_MSG_CHECKING(if $CC supports -fno-common)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-common"
+AC_CACHE_VAL(openafs_gcc_supports_no_common,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_supports_no_common=yes,
+openafs_gcc_supports_no_common=no)])
+AC_MSG_RESULT($openafs_gcc_supports_no_common)
+if test x$openafs_gcc_supports_no_common = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-common"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
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..694cc80
--- /dev/null
@@ -0,0 +1,21 @@
+/* $Id: asn1-common.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */
+
+#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..9185089
--- /dev/null
@@ -0,0 +1,23 @@
+/* Generated from ../../../lib/asn1/asn1_err.et */
+/* $Id: asn1_err.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */
+
+#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/bg-fcrypt.c b/src/rxkad/bg-fcrypt.c
new file mode 100644 (file)
index 0000000..a549ea7
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+ * Copyright (c) 1995 - 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.
+ */
+#include <afsconfig.h>
+#ifdef KERNEL
+#include "../afs/param.h"
+#else
+#include <afs/param.h>
+#endif
+
+RCSID("$Header: /tmp/cvstemp/openafs/src/rxkad/bg-fcrypt.c,v 1.1 2002/12/11 02:44:46 hartmans Exp $");
+
+#define DEBUG 0
+#ifdef KERNEL
+#ifndef UKERNEL
+#include "../afs/stds.h"
+#include "../h/types.h"
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_OBSD_ENV)
+#include "../netinet/in.h"
+#endif
+#else /* UKERNEL */
+#include "../afs/sysincludes.h"
+#include "../afs/stds.h"
+#endif /* UKERNEL */
+#ifdef AFS_LINUX22_ENV
+#include <asm/byteorder.h>
+#endif
+
+#include "../afs/longc_procs.h"
+#include "../rx/rx.h"
+#else /* KERNEL */
+
+#include <afs/stds.h>
+#include <sys/types.h>
+#ifdef AFS_NT40_ENV
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+#include <rx/rx.h>
+#endif /* KERNEL */
+
+#include "fcrypt.h"
+#include "rxkad.h"
+#include "fcrypt.h"
+#include "private_data.h"
+
+#undef WORDS_BIGENDIAN
+#ifdef AFSBIG_ENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+
+/*
+ * Unrolling of the inner loops helps the most on pentium chips
+ * (ca 18%). On risc machines only expect a modest improvement (ca 5%).
+ * The cost for this is rougly 4k bytes.
+ */
+#define UNROLL_LOOPS 1
+/*
+ * Inline assembler gives a boost only to fc_keysched.
+ * On the pentium expect ca 28%.
+ */
+/*#define GNU_ASM 1 (now autoconfed) */
+
+#if !defined(inline) && !defined(__GNUC__)
+#define inline
+#endif
+
+/*
+ * There is usually no memcpy in kernels but gcc will inline all
+ * calls to memcpy in this code anyway.
+ */
+#if defined(KERNEL) && !defined(__GNUC__)
+#define memcpy(to, from, n) bcopy((from), (to), (n))
+#endif
+
+/* Rotate 32 bit word left */
+#define ROT32L(x, n) ((((afs_uint32) x) << (n)) | (((afs_uint32) x) >> (32-(n))))
+#define bswap32(x) (((ROT32L(x, 16) & 0x00ff00ff)<<8) | ((ROT32L(x, 16)>>8) & 0x00ff00ff))
+
+#if WORDS_BIGENDIAN
+#define NTOH(x) (x)
+#else
+#define NTOH(x) bswap32(x)
+#endif
+
+/*
+ * Try to use a good function for ntohl-ing.
+ *
+ * The choice is done by autoconf setting EFF_NTOHL to one of:
+ * CPU         function
+ * i386                ntohl
+ * i[4-9]86    bswap
+ * alpha       bswap32
+ * all else    ntohl
+ */
+
+#define EFF_NTOHL(x) ntohl(x)
+
+#if 0
+#if defined(__GNUC__) && (defined(i386) || defined(__i386__))
+static inline afs_uint32
+bswap(afs_uint32 x)
+{
+  asm("bswap %0" : "=r" (x) : "0" (x));
+  return x;
+}
+#endif
+#endif
+
+/*
+ * Sboxes for Feistel network derived from
+ * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
+ */
+
+#undef Z
+#define Z(x) NTOH(x << 3)
+static const afs_uint32 sbox0[256] = {
+  Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11), Z(0xcd), Z(0x86), Z(0x86),
+  Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5),
+  Z(0x28), Z(0x60), Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3), Z(0xd2),
+  Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), Z(0x35), Z(0xac), Z(0xaa), Z(0x5f),
+  Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32),
+  Z(0x10), Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd), Z(0x3b), Z(0x95),
+  Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f),
+  Z(0x26), Z(0x76), Z(0x15), Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7),
+  Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24), Z(0x0b), Z(0x8a), Z(0x83),
+  Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64),
+  Z(0xf0), Z(0x51), Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef), Z(0x10),
+  Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b),
+  Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2),
+  Z(0xb7), Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44), Z(0xb6), Z(0x69),
+  Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f),
+  Z(0x36), Z(0xba), Z(0x71), Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6),
+  Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95), Z(0x22), Z(0x99), Z(0xfd),
+  Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70),
+  Z(0xff), Z(0xc6), Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5), Z(0x36),
+  Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), Z(0x93), Z(0xc4), Z(0xaa), Z(0x26),
+  Z(0x49), Z(0xe0), Z(0x21), Z(0x64), Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9),
+  Z(0xd1), Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03), Z(0xe4), Z(0xb0),
+  Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c),
+  Z(0x0d), Z(0x42), Z(0x2e)};
+
+#undef Z
+#define Z(x) NTOH((x << 27) | (x >> 5))
+static const afs_uint32 sbox1[256] = {
+  Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e), Z(0x67), Z(0x6c), Z(0xa1),
+  Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3),
+  Z(0xf2), Z(0x89), Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39), Z(0x31),
+  Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), Z(0x23), Z(0x83), Z(0x98), Z(0x7d),
+  Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f),
+  Z(0xad), Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6), Z(0xb8), Z(0xa1),
+  Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23),
+  Z(0x17), Z(0x04), Z(0xfa), Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e),
+  Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc), Z(0xe2), Z(0xaf), Z(0x45),
+  Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18),
+  Z(0x60), Z(0x3d), Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b), Z(0x06),
+  Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1),
+  Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28),
+  Z(0x0a), Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a), Z(0x31), Z(0xf7),
+  Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57),
+  Z(0x25), Z(0xbe), Z(0x89), Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52),
+  Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8), Z(0x69), Z(0x10), Z(0x9d),
+  Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19),
+  Z(0xbd), Z(0x45), Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96), Z(0xef),
+  Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), Z(0x80), Z(0x48), Z(0x81), Z(0xb7),
+  Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57),
+  Z(0xc1), Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78), Z(0x16), Z(0x06),
+  Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96),
+  Z(0x91), Z(0x82), Z(0x80)};
+
+#undef Z
+#define Z(x) NTOH(x << 11)
+static const afs_uint32 sbox2[256] = {
+  Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86), Z(0xd1), Z(0xec), Z(0x50),
+  Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2),
+  Z(0xc5), Z(0x5d), Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24), Z(0xc8),
+  Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9),
+  Z(0x45), Z(0x20), Z(0x1b), Z(0xce), Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3),
+  Z(0xa9), Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68), Z(0x84), Z(0xbc),
+  Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95),
+  Z(0x02), Z(0xc0), Z(0xd0), Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17),
+  Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d), Z(0x6d), Z(0x1c), Z(0x6c),
+  Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12),
+  Z(0x19), Z(0x34), Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae), Z(0x2a),
+  Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b),
+  Z(0xb1), Z(0x85), Z(0x59), Z(0x80), Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48),
+  Z(0x40), Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e), Z(0xb7), Z(0x5e),
+  Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9),
+  Z(0xc7), Z(0x40), Z(0x45), Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99),
+  Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f), Z(0xdc), Z(0xff), Z(0xfd),
+  Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e),
+  Z(0x3d), Z(0xfd), Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f), Z(0x56),
+  Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), Z(0xf3), Z(0x8e), Z(0xde), Z(0xae),
+  Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15),
+  Z(0xd1), Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59), Z(0x56), Z(0x68),
+  Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76),
+  Z(0xb4), Z(0x10), Z(0x86)};
+
+#undef Z
+#define Z(x) NTOH(x << 19)
+static const afs_uint32 sbox3[256] = {
+  Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2), Z(0xb5), Z(0xb7), Z(0x42),
+  Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20),
+  Z(0x6d), Z(0x57), Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b), Z(0x53),
+  Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), Z(0xa1), Z(0x01), Z(0xa5), Z(0x41),
+  Z(0x97), Z(0x41), Z(0x31), Z(0x82), Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10),
+  Z(0xcc), Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16), Z(0x47), Z(0xf6),
+  Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01),
+  Z(0x54), Z(0x70), Z(0xa4), Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23),
+  Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2), Z(0x2a), Z(0x41), Z(0xb2),
+  Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc),
+  Z(0x60), Z(0x65), Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87), Z(0x96),
+  Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), Z(0x5a), Z(0x83), Z(0xbf), Z(0x92),
+  Z(0x1b), Z(0x94), Z(0x00), Z(0x42), Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76),
+  Z(0x5f), Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95), Z(0x17), Z(0xe4),
+  Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b),
+  Z(0x66), Z(0xa1), Z(0x34), Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05),
+  Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a), Z(0x19), Z(0xf1), Z(0xa1),
+  Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a),
+  Z(0x2d), Z(0x20), Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f), Z(0x47),
+  Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd),
+  Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0),
+  Z(0x11), Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f), Z(0xd8), Z(0xe1),
+  Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba),
+  Z(0xfc), Z(0x0e), Z(0x25)};
+
+/*
+ * This is a 16 round Feistel network with permutation F_ENCRYPT
+ */
+
+#define F_ENCRYPT(R, L, sched) { \
+ union lc4 { afs_uint32 l; unsigned char c[4]; } un; \
+ un.l = sched ^ R; \
+ L ^= sbox0[un.c[0]] ^ sbox1[un.c[1]] ^ sbox2[un.c[2]] ^ sbox3[un.c[3]]; }
+
+#ifndef WORDS_BIGENDIAN
+/* BEWARE: this code is endian dependent.
+ * This should really be inline assembler on the x86.
+ */
+#undef F_ENCRYPT
+#define FF(y, shiftN) (((y) >> shiftN) & 0xFF)
+#define F_ENCRYPT(R, L, sched) { \
+ afs_uint32 un; \
+ un = sched ^ R; \
+ L ^= sbox0[FF(un, 0)] ^ sbox1[FF(un, 8)] ^ sbox2[FF(un, 16)] ^ sbox3[FF(un, 24)];}
+#endif
+
+static inline
+void
+fc_ecb_enc(afs_uint32 l,
+          afs_uint32 r,
+          afs_uint32 out[2],
+          const afs_int32 sched[MAXROUNDS])
+{
+#if !defined(UNROLL_LOOPS)
+  {
+    int i;
+    for (i = 0; i < (MAXROUNDS/4); i++)
+      {
+       F_ENCRYPT(r, l, *sched++);
+       F_ENCRYPT(l, r, *sched++);
+       F_ENCRYPT(r, l, *sched++);
+       F_ENCRYPT(l, r, *sched++);
+      }
+  }
+#else
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+  F_ENCRYPT(r, l, *sched++);
+  F_ENCRYPT(l, r, *sched++);
+#endif /* UNROLL_LOOPS */
+
+  out[0] = l;
+  out[1] = r;
+}
+
+static inline
+void
+fc_ecb_dec(afs_uint32 l,
+          afs_uint32 r,
+          afs_uint32 out[2],
+          const afs_int32 sched[MAXROUNDS])
+{
+  sched = &sched[MAXROUNDS-1];
+
+#if !defined(UNROLL_LOOPS)
+  {
+    int i;
+    for (i = 0; i < (MAXROUNDS/4); i++)
+      {
+       F_ENCRYPT(l, r, *sched--);
+       F_ENCRYPT(r, l, *sched--);
+       F_ENCRYPT(l, r, *sched--);
+       F_ENCRYPT(r, l, *sched--);
+      }
+  }
+#else
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+  F_ENCRYPT(l, r, *sched--);
+  F_ENCRYPT(r, l, *sched--);
+#endif /* UNROLL_LOOPS */
+
+  out[0] = l;
+  out[1] = r;
+}
+
+static inline
+void
+fc_cbc_enc(const afs_uint32 *in,
+          afs_uint32 *out,
+          afs_int32 length,
+          const afs_int32 sched[MAXROUNDS],
+          afs_uint32 *iv)
+{
+  afs_int32 xor0 = iv[0], xor1 = iv[1];
+
+  for (; length > 0; length -= 8)
+    {
+      afs_uint32 b8[2];
+      /* If length < 8 we read to much, usally ok */
+      xor0 ^= in[0];
+      xor1 ^= in[1];
+      fc_ecb_enc(xor0, xor1, b8, sched);
+      xor0 = in[0] ^ b8[0];
+      xor1 = in[1] ^ b8[1];
+
+      /* Out is always a multiple of 8 */
+      memcpy(out, b8, 8);
+      out += 2;
+      in += 2;
+    }
+  iv[0] = xor0;
+  iv[1] = xor1;
+}
+
+static inline
+void
+fc_cbc_dec(const afs_uint32 *in,
+          afs_uint32 *out,
+          afs_int32 length,
+          const afs_int32 sched[MAXROUNDS],
+          afs_uint32 *iv)
+{
+  afs_int32 xor0 = iv[0], xor1 = iv[1];
+
+  for (; length > 0; length -= 8)
+    {
+      afs_uint32 b8[2];
+      /* In is always a multiple of 8 */
+      fc_ecb_dec(in[0], in[1], b8, sched);
+      b8[0] ^= xor0;
+      b8[1] ^= xor1;
+      xor0 = in[0] ^ b8[0];
+      xor1 = in[1] ^ b8[1];
+
+#if 0
+      if (length >= 8)
+       memcpy(out, b8, 8);
+      else
+       memcpy(out, b8, length); /* Don't write to much when length < 8 */
+#else
+      /* If length < 8 we write to much, this is not always ok */
+      memcpy(out, b8, 8);
+#endif
+      out += 2;
+      in += 2;
+    }
+  iv[0] = xor0;
+  iv[1] = xor1;
+}
+
+afs_int32
+fc_ecb_encrypt(afs_uint32 *in, afs_uint32 *out,
+              fc_KeySchedule sched,
+              int encrypt)
+{
+  LOCK_RXKAD_STATS
+  rxkad_stats.fc_encrypts[encrypt]++;
+  UNLOCK_RXKAD_STATS
+  if (encrypt) 
+    fc_ecb_enc(in[0], in[1], out, sched);
+  else
+    fc_ecb_dec(in[0], in[1], out, sched);
+  return 0;
+}
+
+afs_int32
+fc_cbc_encrypt(afs_uint32 *in, afs_uint32 *out,
+              afs_int32 length,
+              fc_KeySchedule sched,
+              afs_uint32 *iv,
+              int encrypt)
+{
+  if (encrypt)
+    fc_cbc_enc(in, out, length, sched, iv);
+  else
+    fc_cbc_dec(in, out, length, sched, iv);
+  return 0;
+}
+
+/* Rotate two 32 bit numbers as a 56 bit number */
+#define ROT56R(hi, lo, n) { \
+  afs_uint32 t = lo & ((1<<n)-1); \
+  lo = (lo >> n) | ((hi & ((1<<n)-1)) << (32-n)); \
+  hi = (hi >> n) | (t << (24-n)); }
+
+/* Rotate one 64 bit number as a 56 bit number */
+#define ROT56R64(k, n) { \
+  k = (k >> n) | ((k & ((1<<n) - 1)) << (56-n)); }
+
+/*
+ * Generate a key schedule from key, the least significant bit in each
+ * key byte is parity and shall be ignored. This leaves 56 significant
+ * bits in the key to scatter over the 16 key schedules. For each
+ * schedule extract the low order 32 bits and use as schedule, then
+ * rotate right by 11 bits.
+ *
+ * Note that this fc_keysched() generates a schedule in natural byte
+ * order, the Transarc function does not. Therefore it's *not*
+ * possible to mix fc_keysched, fc_ecb_encrypt and fc_cbc_encrypt
+ * from different implementations. Keep them in the same module!
+ */
+int
+fc_keysched(void *key_,
+           fc_KeySchedule sched)
+{
+  const unsigned char *key = key_;
+
+  /* Do we have 56 bit longs or even longer longs? */
+#if ((1ul << 31) << 1) && defined(ULONG_MAX) && ((ULONG_MAX >> 55) != 0) && ((1ul << 55) != 0)
+  unsigned long k;             /* k holds all 56 non parity bits */
+
+  /* Compress out parity bits */
+  k = (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key++) >> 1;
+  k <<= 7;
+  k |= (*key) >> 1;
+
+  /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+  ROT56R64(k, 11);
+  *sched++ = EFF_NTOHL((afs_uint32)k);
+#else
+  afs_uint32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */
+
+  /* Compress out parity bits */
+  lo = (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  hi = lo >> 4;
+  lo &= 0xf;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key++) >> 1;
+  lo <<= 7;
+  lo |= (*key) >> 1;
+
+  /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+  ROT56R(hi, lo, 11);
+  *sched++ = EFF_NTOHL(lo);
+#endif
+  LOCK_RXKAD_STATS
+  rxkad_stats.fc_key_scheds++;
+  UNLOCK_RXKAD_STATS
+  return 0;
+}
+
+/*
+ * Encryption/decryption of Rx packets is pretty straight forward. Run
+ * fc_cbc_encrypt over the packet fragments until len bytes have been
+ * processed. Skip the Rx packet header but not the security header.
+ */
+afs_int32
+rxkad_EncryptPacket(const struct rx_connection *rx_connection_not_used,
+                   const fc_KeySchedule *sched,
+                   const afs_uint32 *iv,
+                   int len,
+                   struct rx_packet *packet)
+{
+  afs_uint32 ivec[2];
+  struct iovec *frag;
+  struct rx_securityClass *obj;
+  struct rxkad_cprivate *tp;          /* s & c have type at same offset */
+
+  obj = rx_SecurityObjectOf(rx_connection_not_used);
+  tp = (struct rxkad_cprivate *)obj->privateData;
+  LOCK_RXKAD_STATS
+  rxkad_stats.bytesEncrypted[rxkad_TypeIndex(tp->type)] += len;
+  UNLOCK_RXKAD_STATS
+
+  {
+    /* What is this good for?
+     * It turns out that the security header for auth_enc is of
+     * size 8 bytes and the last 4 bytes are defined to be 0!
+     */
+    afs_uint32 *t = (afs_uint32 *)packet->wirevec[1].iov_base;
+    t[1] = 0;
+  }
+
+  memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
+  for (frag = &packet->wirevec[1]; len; frag++)
+    {
+      int      iov_len = frag->iov_len;
+      afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
+      if (iov_len == 0)
+       return RXKADDATALEN;    /* Length mismatch */
+      if (len < iov_len)
+       iov_len = len;          /* Don't process to much data */
+      fc_cbc_enc(iov_bas, iov_bas, iov_len, sched, ivec);
+      len -= iov_len;
+    }
+  return 0;
+}
+
+afs_int32
+rxkad_DecryptPacket(const struct rx_connection *rx_connection_not_used,
+                   const fc_KeySchedule *sched,
+                   const afs_uint32 *iv,
+                   int len,
+                   struct rx_packet *packet)
+{
+  afs_uint32 ivec[2];
+  struct iovec *frag;
+  struct rx_securityClass *obj;
+  struct rxkad_cprivate *tp;          /* s & c have type at same offset */
+
+  obj = rx_SecurityObjectOf(rx_connection_not_used);
+  tp = (struct rxkad_cprivate *)obj->privateData;
+  LOCK_RXKAD_STATS
+  rxkad_stats.bytesDecrypted[rxkad_TypeIndex(tp->type)] += len;
+  UNLOCK_RXKAD_STATS
+
+  memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
+  for (frag = &packet->wirevec[1]; len > 0; frag++)
+    {
+      int      iov_len = frag->iov_len;
+      afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
+      if (iov_len == 0)
+       return RXKADDATALEN;    /* Length mismatch */
+      if (len < iov_len)
+       iov_len = len;          /* Don't process to much data */
+      fc_cbc_dec(iov_bas, iov_bas, iov_len, sched, ivec);
+      len -= iov_len;
+    }
+  return 0;
+}
+
+#if defined(TEST) || defined(TEST_KERNEL)
+/*
+ * It is possible to link with the client kernel libafs.a to verify
+ * the test case. Use TEST_KERNEL to get the mangled names.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <time.h>
+
+const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0";
+
+const unsigned char key1[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+const char ciph1[] = {
+  0x00, 0xf0, 0xe,  0x11, 0x75, 0xe6, 0x23, 0x82, 0xee, 0xac, 0x98, 0x62,
+  0x44, 0x51, 0xe4, 0x84, 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
+  0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, 0x23, 0xb5, 0x62, 0xd7,
+  0xc,  0xf5, 0x27, 0xd1, 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef };
+
+const unsigned char key2[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+const char ciph2[] = {
+  0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, 0x01, 0x88, 0x7f, 0x3e,
+  0x31, 0x6e, 0x62, 0x9d, 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
+  0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, 0x19, 0x89, 0x09, 0x1c,
+  0x2a, 0x8e, 0x8c, 0x94, 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f };
+
+#ifdef TEST_KERNEL
+#define fc_keysched    _afs_QTKrFdpoFL
+#define fc_ecb_encrypt _afs_sDLThwNLok
+#define fc_cbc_encrypt _afs_fkyCWTvfRS
+#define rxkad_DecryptPacket _afs_SRWEeqTXrS
+#define rxkad_EncryptPacket _afs_bpwQbdoghO
+#endif
+
+int rx_SlowPutInt32() { abort(); }
+
+int
+main()
+{
+  afs_int32 sched[MAXROUNDS];
+  char ciph[100], clear[100], tmp[100];
+  afs_uint32 data[2];
+  afs_uint32 iv[2];
+  struct rx_packet packet;
+
+  if (sizeof(afs_int32) != 4)
+    fprintf(stderr, "error: sizeof(afs_int32) != 4\n");
+  if (sizeof(afs_uint32) != 4)
+    fprintf(stderr, "error: sizeof(afs_uint32) != 4\n");
+
+  /*
+   * Use key1 and key2 as iv */
+  fc_keysched(key1, sched);
+  memcpy(iv, key2, sizeof(iv));
+  fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
+  if (memcmp(ciph1, ciph, sizeof(ciph1)) != 0)
+    fprintf(stderr, "encrypt FAILED\n");
+  memcpy(iv, key2, sizeof(iv));
+  fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
+  if (strcmp(the_quick, clear) != 0)
+    fprintf(stderr, "crypt decrypt FAILED\n");
+
+  /*
+   * Use key2 and key1 as iv
+   */
+  fc_keysched(key2, sched);
+  memcpy(iv, key1, sizeof(iv));
+  fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
+  if (memcmp(ciph2, ciph, sizeof(ciph2)) != 0)
+    fprintf(stderr, "encrypt FAILED\n");
+  memcpy(iv, key1, sizeof(iv));
+  fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
+  if (strcmp(the_quick, clear) != 0)
+    fprintf(stderr, "crypt decrypt FAILED\n");
+
+  /*
+   * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv
+   */
+  fc_keysched(key1, sched);
+  memcpy(iv, key2, sizeof(iv));
+  strcpy(clear, the_quick);
+  packet.wirevec[1].iov_base = clear;
+  packet.wirevec[1].iov_len = sizeof(the_quick);
+  packet.wirevec[2].iov_len = 0;
+
+  /* For unknown reasons bytes 4-7 are zeroed in rxkad_EncryptPacket */
+  rxkad_EncryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
+  rxkad_DecryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
+  clear[4] ^= 'q';
+  clear[5] ^= 'u';
+  clear[6] ^= 'i';
+  clear[7] ^= 'c';
+  if (strcmp(the_quick, clear) != 0)
+    fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n");
+
+  {
+    struct timeval start, stop;
+    int i;
+    
+    fc_keysched(key1, sched);
+    gettimeofday(&start, 0);
+    for (i = 0; i < 1000000; i++)
+      fc_keysched(key1, sched);
+    gettimeofday(&stop, 0);
+    printf("fc_keysched    = %2.2f us\n",
+          (stop.tv_sec - start.tv_sec
+           + (stop.tv_usec - start.tv_usec)/1e6)*1);
+          
+    fc_ecb_encrypt(data, data, sched, ENCRYPT);
+    gettimeofday(&start, 0);
+    for (i = 0; i < 1000000; i++)
+      fc_ecb_encrypt(data, data, sched, ENCRYPT);
+    gettimeofday(&stop, 0);
+    printf("fc_ecb_encrypt = %2.2f us\n",
+          (stop.tv_sec - start.tv_sec
+           + (stop.tv_usec - start.tv_usec)/1e6)*1);
+          
+    fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
+    gettimeofday(&start, 0);
+    for (i = 0; i < 100000; i++)
+      fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
+    gettimeofday(&stop, 0);
+    printf("fc_cbc_encrypt = %2.2f us\n",
+          (stop.tv_sec - start.tv_sec
+           + (stop.tv_usec - start.tv_usec)/1e6)*10);
+          
+  }
+
+  exit(0);
+}
+#endif /* TEST */
diff --git a/src/rxkad/crc.c b/src/rxkad/crc.c
new file mode 100644 (file)
index 0000000..846a9fe
--- /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: /tmp/cvstemp/openafs/src/rxkad/crc.c,v 1.1 2002/12/11 02:44:46 hartmans Exp $");
+
+#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..17b295d
--- /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: der.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */
+
+#ifndef __DER_H__
+#define __DER_H__
+
+#include <time.h>
+
+typedef enum {UNIV = 0, APPL = 1, Der_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__ */
diff --git a/src/rxkad/ticket5.c b/src/rxkad/ticket5.c
new file mode 100644 (file)
index 0000000..d94f377
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * 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: /tmp/cvstemp/openafs/src/rxkad/ticket5.c,v 1.1 2002/12/11 02:44:48 hartmans Exp $");
+
+#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;
+    }
+    
+    /* 
+     * If the first part of the name_string contains a dot, punt since
+     * then we can't see the diffrence between the kerberos 5
+     * principals foo.root and foo/root later in the fileserver.
+     */
+     if (strchr(decr_part.cname.name_string.val[0], '.') != NULL) 
+        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..0380ec1
--- /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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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, Der_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__ */