--- /dev/null
+
+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"
+])
+
--- /dev/null
+#
+# 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
--- /dev/null
+/* $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
--- /dev/null
+/* 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__ */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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 */
--- /dev/null
+#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
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* 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__ */