From d0e361218b1a1e27b8525304928b1a121fe30c4c Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Wed, 11 Dec 2002 02:42:32 +0000 Subject: [PATCH] Initial revision --- src/cf/linux-test5.m4 | 71 ++ src/rxkad/README.v5 | 90 ++ src/rxkad/asn1-common.h | 21 + src/rxkad/asn1_err.h | 23 + src/rxkad/bg-fcrypt.c | 815 ++++++++++++ src/rxkad/crc.c | 109 ++ src/rxkad/der.h | 152 +++ src/rxkad/ticket5.c | 323 +++++ src/rxkad/v5der.c | 1243 ++++++++++++++++++ src/rxkad/v5gen-rewrite.h | 125 ++ src/rxkad/v5gen.c | 2490 +++++++++++++++++++++++++++++++++++++ src/rxkad/v5gen.h | 1272 +++++++++++++++++++ 12 files changed, 6734 insertions(+) create mode 100644 src/cf/linux-test5.m4 create mode 100644 src/rxkad/README.v5 create mode 100644 src/rxkad/asn1-common.h create mode 100644 src/rxkad/asn1_err.h create mode 100644 src/rxkad/bg-fcrypt.c create mode 100644 src/rxkad/crc.c create mode 100644 src/rxkad/der.h create mode 100644 src/rxkad/ticket5.c create mode 100644 src/rxkad/v5der.c create mode 100644 src/rxkad/v5gen-rewrite.h create mode 100644 src/rxkad/v5gen.c create mode 100644 src/rxkad/v5gen.h diff --git a/src/cf/linux-test5.m4 b/src/cf/linux-test5.m4 new file mode 100644 index 000000000..97ce80ba7 --- /dev/null +++ b/src/cf/linux-test5.m4 @@ -0,0 +1,71 @@ + +AC_DEFUN(OPENAFS_GCC_SUPPORTS_MARCH, [ +AC_MSG_CHECKING(if $CC accepts -march=pentium) +save_CFLAGS="$CFLAGS" +CFLAGS="-MARCH=pentium" +AC_CACHE_VAL(openafs_gcc_supports_march,[ +AC_TRY_COMPILE( +[], +[int x;], +openafs_gcc_supports_march=yes, +openafs_gcc_supports_march=no)]) +AC_MSG_RESULT($openafs_gcc_supports_march) +if test x$openafs_gcc_supports_march = xyes; then + P5PLUS_KOPTS="-march=pentium" +else + P5PLUS_KOPTS="-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2" +fi +CFLAGS="$save_CFLAGS" +]) + +AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRICT_ALIASING, [ +AC_MSG_CHECKING(if $CC needs -fno-strict-aliasing) +save_CFLAGS="$CFLAGS" +CFLAGS="-fno-strict-aliasing" +AC_CACHE_VAL(openafs_gcc_needs_no_strict_aliasing,[ +AC_TRY_COMPILE( +[], +[int x;], +openafs_gcc_needs_no_strict_aliasing=yes, +openafs_gcc_needs_no_strict_aliasing=no)]) +AC_MSG_RESULT($openafs_gcc_needs_no_strict_aliasing) +if test x$openafs_gcc_needs_no_strict_aliasing = xyes; then + LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strict-aliasing" +fi +CFLAGS="$save_CFLAGS" +]) + +AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRENGTH_REDUCE, [ +AC_MSG_CHECKING(if $CC needs -fno-strength-reduce) +save_CFLAGS="$CFLAGS" +CFLAGS="-fno-strength-reduce" +AC_CACHE_VAL(openafs_gcc_needs_no_strength_reduce,[ +AC_TRY_COMPILE( +[], +[int x;], +openafs_gcc_needs_no_strength_reduce=yes, +openafs_gcc_needs_no_strength_reduce=no)]) +AC_MSG_RESULT($openafs_gcc_needs_no_strength_reduce) +if test x$openafs_gcc_needs_no_strength_reduce = xyes; then + LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strength-reduce" +fi +CFLAGS="$save_CFLAGS" +]) + +AC_DEFUN(OPENAFS_GCC_SUPPORTS_NO_COMMON, [ +AC_MSG_CHECKING(if $CC supports -fno-common) +save_CFLAGS="$CFLAGS" +CFLAGS="-fno-common" +AC_CACHE_VAL(openafs_gcc_supports_no_common,[ +AC_TRY_COMPILE( +[], +[int x;], +openafs_gcc_supports_no_common=yes, +openafs_gcc_supports_no_common=no)]) +AC_MSG_RESULT($openafs_gcc_supports_no_common) +if test x$openafs_gcc_supports_no_common = xyes; then + LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-common" +fi +CFLAGS="$save_CFLAGS" +]) + diff --git a/src/rxkad/README.v5 b/src/rxkad/README.v5 new file mode 100644 index 000000000..379372f01 --- /dev/null +++ b/src/rxkad/README.v5 @@ -0,0 +1,90 @@ +# +# This code depends on heimdal's asn1_compile generated krb5 decoding +# stuff. The code is orignally from rxkad that Björn Grönvall +# 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 '; + 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 ' \ +| 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 ' \ + | grep -v 'include ' \ + | grep -v 'include ' \ + | perl \ + -e '$f=0; while(<>){$f=1 if(/struct units/);print if($f eq 0);$f=0 if(/^};/);}' \ + | cat > $otree/src/rxkad/v5gen.c + +( \ + perl -p -e 's/^(encode_|decode_|free_|copy_|length_)([^(]*)\([^)]*\)\n$/#define $1$2 _rxkad_v5_$1$2\n/' $otree/src/rxkad/v5gen.c ; \ + perl -p -e 's/^(der_|copy_|encode_|decode_|len_|length_|free_|fix_dce|time2generalizedtime)([^(]*).*/#define $1$2 _rxkad_v5_$1$2/' /sources/afs/openafs-krb5/src/rxkad/v5der.c ; \ + echo '#define TicketFlags2int _rxkad_v5_TicketFlags2int' ; \ + echo '#define int2TicketFlags _rxkad_v5_int2TicketFlags' ; \ + : ) | \ + (grep _rxkad_v5 ; \ + echo '#ifndef HAVE_TIMEGM' ; \ + echo '#define timegm _rxkad_timegm' ; \ + echo '#endif' ; \ + :) > $otree/src/rxkad/v5gen-rewrite.h diff --git a/src/rxkad/asn1-common.h b/src/rxkad/asn1-common.h new file mode 100644 index 000000000..694cc80b6 --- /dev/null +++ b/src/rxkad/asn1-common.h @@ -0,0 +1,21 @@ +/* $Id: asn1-common.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */ + +#include +#include + +#ifndef __asn1_common_definitions__ +#define __asn1_common_definitions__ + +typedef struct octet_string { + size_t length; + void *data; +} octet_string; + +typedef char *general_string; + +typedef struct oid { + size_t length; + unsigned *components; +} oid; + +#endif diff --git a/src/rxkad/asn1_err.h b/src/rxkad/asn1_err.h new file mode 100644 index 000000000..918508988 --- /dev/null +++ b/src/rxkad/asn1_err.h @@ -0,0 +1,23 @@ +/* Generated from ../../../lib/asn1/asn1_err.et */ +/* $Id: asn1_err.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */ + +#ifndef __asn1_err_h__ +#define __asn1_err_h__ + +typedef enum asn1_error_number{ + ERROR_TABLE_BASE_asn1 = 1859794432, + asn1_err_base = 1859794432, + ASN1_BAD_TIMEFORMAT = 1859794432, + ASN1_MISSING_FIELD = 1859794433, + ASN1_MISPLACED_FIELD = 1859794434, + ASN1_TYPE_MISMATCH = 1859794435, + ASN1_OVERFLOW = 1859794436, + ASN1_OVERRUN = 1859794437, + ASN1_BAD_ID = 1859794438, + ASN1_BAD_LENGTH = 1859794439, + ASN1_BAD_FORMAT = 1859794440, + ASN1_PARSE_ERROR = 1859794441, + asn1_num_errors = 10 +} asn1_error_number; + +#endif /* __asn1_err_h__ */ diff --git a/src/rxkad/bg-fcrypt.c b/src/rxkad/bg-fcrypt.c new file mode 100644 index 000000000..a549ea797 --- /dev/null +++ b/src/rxkad/bg-fcrypt.c @@ -0,0 +1,815 @@ +/* + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#ifdef KERNEL +#include "../afs/param.h" +#else +#include +#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 +#endif + +#include "../afs/longc_procs.h" +#include "../rx/rx.h" +#else /* KERNEL */ + +#include +#include +#ifdef AFS_NT40_ENV +#include +#else +#include +#endif +#include +#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) | ((hi & ((1<> n) | (t << (24-n)); } + +/* Rotate one 64 bit number as a 56 bit number */ +#define ROT56R64(k, n) { \ + k = (k >> n) | ((k & ((1<> 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 +#include + +#include + +const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0"; + +const unsigned char key1[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; +const char ciph1[] = { + 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, 0xee, 0xac, 0x98, 0x62, + 0x44, 0x51, 0xe4, 0x84, 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7, + 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, 0x23, 0xb5, 0x62, 0xd7, + 0xc, 0xf5, 0x27, 0xd1, 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef }; + +const unsigned char key2[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +const char ciph2[] = { + 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, 0x01, 0x88, 0x7f, 0x3e, + 0x31, 0x6e, 0x62, 0x9d, 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, + 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, 0x19, 0x89, 0x09, 0x1c, + 0x2a, 0x8e, 0x8c, 0x94, 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }; + +#ifdef TEST_KERNEL +#define fc_keysched _afs_QTKrFdpoFL +#define fc_ecb_encrypt _afs_sDLThwNLok +#define fc_cbc_encrypt _afs_fkyCWTvfRS +#define rxkad_DecryptPacket _afs_SRWEeqTXrS +#define rxkad_EncryptPacket _afs_bpwQbdoghO +#endif + +int rx_SlowPutInt32() { abort(); } + +int +main() +{ + afs_int32 sched[MAXROUNDS]; + char ciph[100], clear[100], tmp[100]; + afs_uint32 data[2]; + afs_uint32 iv[2]; + struct rx_packet packet; + + if (sizeof(afs_int32) != 4) + fprintf(stderr, "error: sizeof(afs_int32) != 4\n"); + if (sizeof(afs_uint32) != 4) + fprintf(stderr, "error: sizeof(afs_uint32) != 4\n"); + + /* + * Use key1 and key2 as iv */ + fc_keysched(key1, sched); + memcpy(iv, key2, sizeof(iv)); + fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT); + if (memcmp(ciph1, ciph, sizeof(ciph1)) != 0) + fprintf(stderr, "encrypt FAILED\n"); + memcpy(iv, key2, sizeof(iv)); + fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT); + if (strcmp(the_quick, clear) != 0) + fprintf(stderr, "crypt decrypt FAILED\n"); + + /* + * Use key2 and key1 as iv + */ + fc_keysched(key2, sched); + memcpy(iv, key1, sizeof(iv)); + fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT); + if (memcmp(ciph2, ciph, sizeof(ciph2)) != 0) + fprintf(stderr, "encrypt FAILED\n"); + memcpy(iv, key1, sizeof(iv)); + fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT); + if (strcmp(the_quick, clear) != 0) + fprintf(stderr, "crypt decrypt FAILED\n"); + + /* + * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv + */ + fc_keysched(key1, sched); + memcpy(iv, key2, sizeof(iv)); + strcpy(clear, the_quick); + packet.wirevec[1].iov_base = clear; + packet.wirevec[1].iov_len = sizeof(the_quick); + packet.wirevec[2].iov_len = 0; + + /* For unknown reasons bytes 4-7 are zeroed in rxkad_EncryptPacket */ + rxkad_EncryptPacket(tmp, sched, iv, sizeof(the_quick), &packet); + rxkad_DecryptPacket(tmp, sched, iv, sizeof(the_quick), &packet); + clear[4] ^= 'q'; + clear[5] ^= 'u'; + clear[6] ^= 'i'; + clear[7] ^= 'c'; + if (strcmp(the_quick, clear) != 0) + fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n"); + + { + struct timeval start, stop; + int i; + + fc_keysched(key1, sched); + gettimeofday(&start, 0); + for (i = 0; i < 1000000; i++) + fc_keysched(key1, sched); + gettimeofday(&stop, 0); + printf("fc_keysched = %2.2f us\n", + (stop.tv_sec - start.tv_sec + + (stop.tv_usec - start.tv_usec)/1e6)*1); + + fc_ecb_encrypt(data, data, sched, ENCRYPT); + gettimeofday(&start, 0); + for (i = 0; i < 1000000; i++) + fc_ecb_encrypt(data, data, sched, ENCRYPT); + gettimeofday(&stop, 0); + printf("fc_ecb_encrypt = %2.2f us\n", + (stop.tv_sec - start.tv_sec + + (stop.tv_usec - start.tv_usec)/1e6)*1); + + fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT); + gettimeofday(&start, 0); + for (i = 0; i < 100000; i++) + fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT); + gettimeofday(&stop, 0); + printf("fc_cbc_encrypt = %2.2f us\n", + (stop.tv_sec - start.tv_sec + + (stop.tv_usec - start.tv_usec)/1e6)*10); + + } + + exit(0); +} +#endif /* TEST */ diff --git a/src/rxkad/crc.c b/src/rxkad/crc.c new file mode 100644 index 000000000..846a9fef9 --- /dev/null +++ b/src/rxkad/crc.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* RCSID("$Heimdal: crc.c,v 1.9 2000/08/03 01:45:14 assar Exp $"); */ + +#include +#if defined(UKERNEL) +#include "../afs/param.h" +#else +#include +#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 +#include +#ifdef AFS_NT40_ENV +#include +#else +#include +#endif +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif +#include +#include +#include +#include "lifetimes.h" +#include "rxkad.h" +#endif /* defined(UKERNEL) */ + +static u_long table[256]; + +#define CRC_GEN 0xEDB88320L + +void +_rxkad_crc_init_table(void) +{ + static int flag = 0; + unsigned long crc, poly; + int i, j; + + if(flag) return; + poly = CRC_GEN; + for (i = 0; i < 256; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) { + crc = (crc >> 1) ^ poly; + } else { + crc >>= 1; + } + } + table[i] = crc; + } + flag = 1; +} + +afs_uint32 +_rxkad_crc_update (const char *p, size_t len, afs_uint32 res) +{ + while (len--) + res = table[(res ^ *p++) & 0xFF] ^ (res >> 8); + return res & 0xFFFFFFFF; +} diff --git a/src/rxkad/der.h b/src/rxkad/der.h new file mode 100644 index 000000000..17b295d45 --- /dev/null +++ b/src/rxkad/der.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: der.h,v 1.1 2002/12/11 02:44:46 hartmans Exp $ */ + +#ifndef __DER_H__ +#define __DER_H__ + +#include + +typedef enum {UNIV = 0, APPL = 1, Der_CONTEXT = 2 , PRIVATE = 3} Der_class; + +typedef enum {PRIM = 0, CONS = 1} Der_type; + +/* Universal tags */ + +enum { + UT_Boolean = 1, + UT_Integer = 2, + UT_BitString = 3, + UT_OctetString = 4, + UT_Null = 5, + UT_OID = 6, + UT_Enumerated = 10, + UT_Sequence = 16, + UT_Set = 17, + UT_PrintableString = 19, + UT_IA5String = 22, + UT_UTCTime = 23, + UT_GeneralizedTime = 24, + UT_VisibleString = 26, + UT_GeneralString = 27 +}; + +#define ASN1_INDEFINITE 0xdce0deed + +#ifndef HAVE_TIMEGM +time_t timegm (struct tm *); +#endif + +int time2generalizedtime (time_t t, octet_string *s); + +int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size); +int der_get_length (const unsigned char *p, size_t len, + size_t *val, size_t *size); +int der_get_general_string (const unsigned char *p, size_t len, + general_string *str, size_t *size); +int der_get_octet_string (const unsigned char *p, size_t len, + octet_string *data, size_t *size); +int der_get_oid (const unsigned char *p, size_t len, + oid *data, size_t *size); +int der_get_tag (const unsigned char *p, size_t len, + Der_class *class, Der_type *type, + int *tag, size_t *size); + +int der_match_tag (const unsigned char *p, size_t len, + Der_class class, Der_type type, + int tag, size_t *size); +int der_match_tag_and_length (const unsigned char *p, size_t len, + Der_class class, Der_type type, int tag, + size_t *length_ret, size_t *size); + +int decode_integer (const unsigned char*, size_t, int*, size_t*); +int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*); +int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*); +int decode_general_string (const unsigned char*, size_t, + general_string*, size_t*); +int decode_oid (const unsigned char *p, size_t len, + oid *k, size_t *size); +int decode_octet_string (const unsigned char*, size_t, octet_string*, size_t*); +int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*); + +int der_put_int (unsigned char *p, size_t len, int val, size_t*); +int der_put_length (unsigned char *p, size_t len, size_t val, size_t*); +int der_put_general_string (unsigned char *p, size_t len, + const general_string *str, size_t*); +int der_put_octet_string (unsigned char *p, size_t len, + const octet_string *data, size_t*); +int der_put_oid (unsigned char *p, size_t len, + const oid *data, size_t *size); +int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, + int tag, size_t*); +int der_put_length_and_tag (unsigned char*, size_t, size_t, + Der_class, Der_type, int, size_t*); + +int encode_integer (unsigned char *p, size_t len, + const int *data, size_t*); +int encode_unsigned (unsigned char *p, size_t len, + const unsigned *data, size_t*); +int encode_enumerated (unsigned char *p, size_t len, + const unsigned *data, size_t*); +int encode_general_string (unsigned char *p, size_t len, + const general_string *data, size_t*); +int encode_octet_string (unsigned char *p, size_t len, + const octet_string *k, size_t*); +int encode_oid (unsigned char *p, size_t len, + const oid *k, size_t*); +int encode_generalized_time (unsigned char *p, size_t len, + const time_t *t, size_t*); + +void free_integer (int *num); +void free_general_string (general_string *str); +void free_octet_string (octet_string *k); +void free_oid (oid *k); +void free_generalized_time (time_t *t); + +size_t length_len (size_t len); +size_t length_integer (const int *data); +size_t length_unsigned (const unsigned *data); +size_t length_enumerated (const unsigned *data); +size_t length_general_string (const general_string *data); +size_t length_octet_string (const octet_string *k); +size_t length_oid (const oid *k); +size_t length_generalized_time (const time_t *t); + +int copy_general_string (const general_string *from, general_string *to); +int copy_octet_string (const octet_string *from, octet_string *to); +int copy_oid (const oid *from, oid *to); + +int fix_dce(size_t reallen, size_t *len); + +#endif /* __DER_H__ */ diff --git a/src/rxkad/ticket5.c b/src/rxkad/ticket5.c new file mode 100644 index 000000000..d94f37746 --- /dev/null +++ b/src/rxkad/ticket5.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 1995, 1996, 1997, 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(UKERNEL) +#include "../afs/param.h" +#else +#include +#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 +#include +#ifdef AFS_NT40_ENV +#include +#else +#include +#endif +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif +#include +#include +#include +#include "lifetimes.h" +#include "rxkad.h" +#endif /* defined(UKERNEL) */ + +#include "v5gen-rewrite.h" +#include "asn1-common.h" +#include "der.h" +#include "v5gen.h" +#include "v5der.c" +#include "v5gen.c" + +static int +krb5_des_decrypt(struct ktc_encryptionKey *, + int, void *, size_t, void *, size_t *); + + + + +int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, + int (*get_key)(char *, int, struct ktc_encryptionKey *), + char *get_key_rock, + int serv_kvno, + char *name, + char *inst, + char *cell, + char *session_key, + afs_int32 *host, + afs_int32 *start, + afs_int32 *end) +{ + char plain[MAXKRB5TICKETLEN]; + struct ktc_encryptionKey serv_key; + Ticket t5; /* Must free */ + EncTicketPart decr_part; /* Must free */ + int code; + size_t siz, plainsiz; + int v5_serv_kvno; + + memset(&t5, 0, sizeof(t5)); + memset(&decr_part, 0, sizeof(decr_part)); + + *host = 0; + + if (ticket_len == 0) + return RXKADBADTICKET; /* no ticket */ + + if (serv_kvno == RXKAD_TKT_TYPE_KERBEROS_V5) { + code = decode_Ticket(ticket, ticket_len, &t5, &siz); + if (code != 0) + goto cleanup; + + if (t5.tkt_vno != 5) + goto bad_ticket; + } else { + code = decode_EncryptedData(ticket, ticket_len, &t5.enc_part, &siz); + if (code != 0) + goto cleanup; + } + + /* Find the real service key version number */ + if (t5.enc_part.kvno == NULL) + goto bad_ticket; + v5_serv_kvno = *t5.enc_part.kvno; + + + code = (*get_key)(get_key_rock, v5_serv_kvno, &serv_key); + if (code) + goto unknown_key; + + /* Check that the key type really fit into 8 bytes */ + switch (t5.enc_part.etype) { + case ETYPE_DES_CBC_CRC: + case ETYPE_DES_CBC_MD4: + case ETYPE_DES_CBC_MD5: + break; + default: + goto unknown_key; + } + + /* check ticket */ + if (t5.enc_part.cipher.length > sizeof(plain) || + t5.enc_part.cipher.length % 8 != 0) + goto bad_ticket; + + /* Decrypt data here, save in plain, assume it will shrink */ + code = krb5_des_decrypt(&serv_key, + t5.enc_part.etype, + t5.enc_part.cipher.data, + t5.enc_part.cipher.length, + plain, + &plainsiz); + if (code != 0) + goto bad_ticket; + + /* Decode ticket */ + code = decode_EncTicketPart(plain, plainsiz, &decr_part, &siz); + if (code != 0) + goto bad_ticket; + + /* Extract realm and principal */ + strncpy(cell, decr_part.crealm, MAXKTCNAMELEN); + cell[MAXKTCNAMELEN - 1] = '\0'; + inst[0] = '\0'; + switch (decr_part.cname.name_string.len) { + case 2: + strncpy(inst, decr_part.cname.name_string.val[1], MAXKTCNAMELEN); + inst[MAXKTCNAMELEN - 1] = '\0'; + case 1: + strncpy(name, decr_part.cname.name_string.val[0], MAXKTCNAMELEN); + name[MAXKTCNAMELEN - 1] = '\0'; + break; + default: + goto bad_ticket; + } + + /* + * If the first part of the name_string contains a dot, punt since + * then we can't see the diffrence between the kerberos 5 + * principals foo.root and foo/root later in the fileserver. + */ + if (strchr(decr_part.cname.name_string.val[0], '.') != NULL) + goto bad_ticket; + + /* Verify that decr_part.key is of right type */ + switch (decr_part.key.keytype) { + case ETYPE_DES_CBC_CRC: + case ETYPE_DES_CBC_MD4: + case ETYPE_DES_CBC_MD5: + break; + default: + goto bad_ticket; + } + + if (decr_part.key.keyvalue.length != 8) + goto bad_ticket; + + /* Extract session key */ + memcpy(session_key, decr_part.key.keyvalue.data, 8); + + /* Check lifetimes and host addresses, flags etc */ + { + time_t now = time(0); /* Use fast time package instead??? */ + *start = decr_part.authtime; + if (decr_part.starttime) + *start = *decr_part.starttime; +#if 0 + if (*start - now > CLOCK_SKEW || decr_part.flags.invalid) + goto no_auth; +#else + if (decr_part.flags.invalid) + goto no_auth; +#endif + if (now > decr_part.endtime) + goto tkt_expired; + *end = decr_part.endtime; + } + + cleanup: + if (serv_kvno == RXKAD_TKT_TYPE_KERBEROS_V5) + free_Ticket(&t5); + else + free_EncryptedData(&t5.enc_part); + free_EncTicketPart(&decr_part); + memset(&serv_key, 0, sizeof(serv_key)); + return code; + + unknown_key: + code = RXKADUNKNOWNKEY; + goto cleanup; + no_auth: + code = RXKADNOAUTH; + goto cleanup; + tkt_expired: + code = RXKADEXPIRED; + goto cleanup; + bad_ticket: + code = RXKADBADTICKET; + goto cleanup; + +} + +static int +verify_checksum_crc(void *data, size_t len, + void *cksum, size_t cksumsz, + struct ktc_encryptionKey *key) +{ + afs_uint32 crc; + char r[4]; + + _rxkad_crc_init_table (); + crc = _rxkad_crc_update (data, len, 0); + r[0] = crc & 0xff; + r[1] = (crc >> 8) & 0xff; + r[2] = (crc >> 16) & 0xff; + r[3] = (crc >> 24) & 0xff; + + if (memcmp(cksum, r, 4) != 0) + return 1; + return 0; +} + + +static int +krb5_des_decrypt(struct ktc_encryptionKey *key, + int etype, + void *in, size_t insz, + void *out, size_t *outsz) +{ + int (*cksum_func)(void *,size_t,void *,size_t,struct ktc_encryptionKey *); + des_cblock ivec; + des_key_schedule s; + char cksum[24]; + size_t cksumsz; + int ret; + + cksum_func = NULL; + + des_key_sched(key, &s); + +#define CONFOUNDERSZ 8 + + switch (etype) { + case ETYPE_DES_CBC_CRC: + memcpy(&ivec, key, sizeof(ivec)); + cksumsz = 4; + cksum_func = verify_checksum_crc; + break; + case ETYPE_DES_CBC_MD4: + memset(&ivec, 0, sizeof(ivec)); + cksumsz = 16; + /* FIXME: cksum_func = verify_checksum_md4 */; + break; + case ETYPE_DES_CBC_MD5: + memset(&ivec, 0, sizeof(ivec)); + cksumsz = 16; + /* FIXME: cksum_func = verify_checksum_md5 */; + break; + default: + abort(); + } + + des_cbc_encrypt(in, out, insz, s, &ivec, 0); + + memcpy(cksum, (char *)out + CONFOUNDERSZ, cksumsz); + memset((char *)out + CONFOUNDERSZ, 0, cksumsz); + + if (cksum_func) + ret = (*cksum_func)(out, insz, cksum, cksumsz, key); + + *outsz = insz - CONFOUNDERSZ - cksumsz; + memmove(out, (char *)out + CONFOUNDERSZ + cksumsz, *outsz); + + return ret; +} diff --git a/src/rxkad/v5der.c b/src/rxkad/v5der.c new file mode 100644 index 000000000..f149d3079 --- /dev/null +++ b/src/rxkad/v5der.c @@ -0,0 +1,1243 @@ +#include "asn1_err.h" +#include +/* + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $"); */ + + +/* + * All decoding functions take a pointer `p' to first position in + * which to read, from the left, `len' which means the maximum number + * of characters we are able to read, `ret' were the value will be + * returned and `size' where the number of used bytes is stored. + * Either 0 or an error code is returned. + */ + +static int +der_get_unsigned (const unsigned char *p, size_t len, + unsigned *ret, size_t *size) +{ + unsigned val = 0; + size_t oldlen = len; + + while (len--) + val = val * 256 + *p++; + *ret = val; + if(size) *size = oldlen; + return 0; +} + +int +der_get_int (const unsigned char *p, size_t len, + int *ret, size_t *size) +{ + int val = 0; + size_t oldlen = len; + + if (len > 0) { + val = (signed char)*p++; + while (--len) + val = val * 256 + *p++; + } + *ret = val; + if(size) *size = oldlen; + return 0; +} + +int +der_get_length (const unsigned char *p, size_t len, + size_t *val, size_t *size) +{ + size_t v; + + if (len <= 0) + return ASN1_OVERRUN; + --len; + v = *p++; + if (v < 128) { + *val = v; + if(size) *size = 1; + } else { + int e; + size_t l; + unsigned tmp; + + if(v == 0x80){ + *val = ASN1_INDEFINITE; + if(size) *size = 1; + return 0; + } + v &= 0x7F; + if (len < v) + return ASN1_OVERRUN; + e = der_get_unsigned (p, v, &tmp, &l); + if(e) return e; + *val = tmp; + if(size) *size = l + 1; + } + return 0; +} + +int +der_get_general_string (const unsigned char *p, size_t len, + general_string *str, size_t *size) +{ + char *s; + + s = malloc (len + 1); + if (s == NULL) + return ENOMEM; + memcpy (s, p, len); + s[len] = '\0'; + *str = s; + if(size) *size = len; + return 0; +} + +int +der_get_octet_string (const unsigned char *p, size_t len, + octet_string *data, size_t *size) +{ + data->length = len; + data->data = malloc(len); + if (data->data == NULL && data->length != 0) + return ENOMEM; + memcpy (data->data, p, len); + if(size) *size = len; + return 0; +} + +int +der_get_oid (const unsigned char *p, size_t len, + oid *data, size_t *size) +{ + int n; + size_t oldlen = len; + + if (len < 1) + return ASN1_OVERRUN; + + data->components = malloc(len * sizeof(*data->components)); + if (data->components == NULL && len != 0) + return ENOMEM; + data->components[0] = (*p) / 40; + data->components[1] = (*p) % 40; + --len; + ++p; + for (n = 2; len > 0; ++n) { + unsigned u = 0; + + do { + --len; + u = u * 128 + (*p++ % 128); + } while (len > 0 && p[-1] & 0x80); + data->components[n] = u; + } + if (p[-1] & 0x80) { + free_oid (data); + return ASN1_OVERRUN; + } + data->length = n; + if (size) + *size = oldlen; + return 0; +} + +int +der_get_tag (const unsigned char *p, size_t len, + Der_class *class, Der_type *type, + int *tag, size_t *size) +{ + if (len < 1) + return ASN1_OVERRUN; + *class = (Der_class)(((*p) >> 6) & 0x03); + *type = (Der_type)(((*p) >> 5) & 0x01); + *tag = (*p) & 0x1F; + if(size) *size = 1; + return 0; +} + +int +der_match_tag (const unsigned char *p, size_t len, + Der_class class, Der_type type, + int tag, size_t *size) +{ + size_t l; + Der_class thisclass; + Der_type thistype; + int thistag; + int e; + + e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l); + if (e) return e; + if (class != thisclass || type != thistype) + return ASN1_BAD_ID; + if(tag > thistag) + return ASN1_MISPLACED_FIELD; + if(tag < thistag) + return ASN1_MISSING_FIELD; + if(size) *size = l; + return 0; +} + +int +der_match_tag_and_length (const unsigned char *p, size_t len, + Der_class class, Der_type type, int tag, + size_t *length_ret, size_t *size) +{ + size_t l, ret = 0; + int e; + + e = der_match_tag (p, len, class, type, tag, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_length (p, len, length_ret, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_integer (const unsigned char *p, size_t len, + int *num, size_t *size) +{ + size_t ret = 0; + size_t l, reallen; + int e; + + e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_length (p, len, &reallen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (reallen > len) + return ASN1_OVERRUN; + e = der_get_int (p, reallen, num, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_unsigned (const unsigned char *p, size_t len, + unsigned *num, size_t *size) +{ + size_t ret = 0; + size_t l, reallen; + int e; + + e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_length (p, len, &reallen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (reallen > len) + return ASN1_OVERRUN; + e = der_get_unsigned (p, reallen, num, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_enumerated (const unsigned char *p, size_t len, + unsigned *num, size_t *size) +{ + size_t ret = 0; + size_t l, reallen; + int e; + + e = der_match_tag (p, len, UNIV, PRIM, UT_Enumerated, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_length (p, len, &reallen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_int (p, reallen, num, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_general_string (const unsigned char *p, size_t len, + general_string *str, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + size_t slen; + + e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + + e = der_get_length (p, len, &slen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (len < slen) + return ASN1_OVERRUN; + + e = der_get_general_string (p, slen, str, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_octet_string (const unsigned char *p, size_t len, + octet_string *k, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + size_t slen; + + e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + + e = der_get_length (p, len, &slen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (len < slen) + return ASN1_OVERRUN; + + e = der_get_octet_string (p, slen, k, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +int +decode_oid (const unsigned char *p, size_t len, + oid *k, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + size_t slen; + + e = der_match_tag (p, len, UNIV, PRIM, UT_OID, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + + e = der_get_length (p, len, &slen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (len < slen) + return ASN1_OVERRUN; + + e = der_get_oid (p, slen, k, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + +static void +generalizedtime2time (const char *s, time_t *t) +{ + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + sscanf (s, "%04d%02d%02d%02d%02d%02dZ", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec); + tm.tm_year -= 1900; + tm.tm_mon -= 1; + *t = timegm (&tm); +} + +int +decode_generalized_time (const unsigned char *p, size_t len, + time_t *t, size_t *size) +{ + octet_string k; + char *times; + size_t ret = 0; + size_t l; + int e; + size_t slen; + + e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + + e = der_get_length (p, len, &slen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if (len < slen) + return ASN1_OVERRUN; + e = der_get_octet_string (p, slen, &k, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + times = realloc(k.data, k.length + 1); + if (times == NULL){ + free(k.data); + return ENOMEM; + } + times[k.length] = 0; + generalizedtime2time (times, t); + free (times); + if(size) *size = ret; + return 0; +} + + +int +fix_dce(size_t reallen, size_t *len) +{ + if(reallen == ASN1_INDEFINITE) + return 1; + if(*len < reallen) + return -1; + *len = reallen; + return 0; +} +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: der_put.c,v 1.27 2001/09/25 23:37:25 assar Exp $"); */ + +/* + * All encoding functions take a pointer `p' to first position in + * which to write, from the right, `len' which means the maximum + * number of characters we are able to write. The function returns + * the number of characters written in `size' (if non-NULL). + * The return value is 0 or an error. + */ + +static int +der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size) +{ + unsigned char *base = p; + + if (val) { + while (len > 0 && val) { + *p-- = val % 256; + val /= 256; + --len; + } + if (val != 0) + return ASN1_OVERFLOW; + else { + *size = base - p; + return 0; + } + } else if (len < 1) + return ASN1_OVERFLOW; + else { + *p = 0; + *size = 1; + return 0; + } +} + +int +der_put_int (unsigned char *p, size_t len, int val, size_t *size) +{ + unsigned char *base = p; + + if(val >= 0) { + do { + if(len < 1) + return ASN1_OVERFLOW; + *p-- = val % 256; + len--; + val /= 256; + } while(val); + if(p[1] >= 128) { + if(len < 1) + return ASN1_OVERFLOW; + *p-- = 0; + len--; + } + } else { + val = ~val; + do { + if(len < 1) + return ASN1_OVERFLOW; + *p-- = ~(val % 256); + len--; + val /= 256; + } while(val); + if(p[1] < 128) { + if(len < 1) + return ASN1_OVERFLOW; + *p-- = 0xff; + len--; + } + } + *size = base - p; + return 0; +} + + +int +der_put_length (unsigned char *p, size_t len, size_t val, size_t *size) +{ + if (len < 1) + return ASN1_OVERFLOW; + if (val < 128) { + *p = val; + *size = 1; + return 0; + } else { + size_t l; + int e; + + e = der_put_unsigned (p, len - 1, val, &l); + if (e) + return e; + p -= l; + *p = 0x80 | l; + *size = l + 1; + return 0; + } +} + +int +der_put_general_string (unsigned char *p, size_t len, + const general_string *str, size_t *size) +{ + size_t slen = strlen(*str); + + if (len < slen) + return ASN1_OVERFLOW; + p -= slen; + len -= slen; + memcpy (p+1, *str, slen); + *size = slen; + return 0; +} + +int +der_put_octet_string (unsigned char *p, size_t len, + const octet_string *data, size_t *size) +{ + if (len < data->length) + return ASN1_OVERFLOW; + p -= data->length; + len -= data->length; + memcpy (p+1, data->data, data->length); + *size = data->length; + return 0; +} + +int +der_put_oid (unsigned char *p, size_t len, + const oid *data, size_t *size) +{ + unsigned char *base = p; + int n; + + for (n = data->length - 1; n >= 2; --n) { + unsigned u = data->components[n]; + + if (len < 1) + return ASN1_OVERFLOW; + *p-- = u % 128; + u /= 128; + --len; + while (u > 0) { + if (len < 1) + return ASN1_OVERFLOW; + *p-- = 128 + u % 128; + u /= 128; + --len; + } + } + if (len < 1) + return ASN1_OVERFLOW; + *p-- = 40 * data->components[0] + data->components[1]; + *size = base - p; + return 0; +} + +int +der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, + int tag, size_t *size) +{ + if (len < 1) + return ASN1_OVERFLOW; + *p = (class << 6) | (type << 5) | tag; /* XXX */ + *size = 1; + return 0; +} + +int +der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, + Der_class class, Der_type type, int tag, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + + e = der_put_length (p, len, len_val, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_tag (p, len, class, type, tag, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_integer (unsigned char *p, size_t len, const int *data, size_t *size) +{ + int num = *data; + size_t ret = 0; + size_t l; + int e; + + e = der_put_int (p, len, num, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_unsigned (unsigned char *p, size_t len, const unsigned *data, + size_t *size) +{ + unsigned num = *data; + size_t ret = 0; + size_t l; + int e; + + e = der_put_unsigned (p, len, num, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Integer, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_enumerated (unsigned char *p, size_t len, const unsigned *data, + size_t *size) +{ + unsigned num = *data; + size_t ret = 0; + size_t l; + int e; + + e = der_put_int (p, len, num, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Enumerated, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_general_string (unsigned char *p, size_t len, + const general_string *data, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + + e = der_put_general_string (p, len, data, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_GeneralString, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_octet_string (unsigned char *p, size_t len, + const octet_string *k, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + + e = der_put_octet_string (p, len, k, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OctetString, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +encode_oid(unsigned char *p, size_t len, + const oid *k, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + + e = der_put_oid (p, len, k, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OID, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + +int +time2generalizedtime (time_t t, octet_string *s) +{ + struct tm *tm; + + s->data = malloc(16); + if (s->data == NULL) + return ENOMEM; + s->length = 15; + tm = gmtime (&t); + sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + return 0; +} + +int +encode_generalized_time (unsigned char *p, size_t len, + const time_t *t, size_t *size) +{ + size_t ret = 0; + size_t l; + octet_string k; + int e; + + e = time2generalizedtime (*t, &k); + if (e) + return e; + e = der_put_octet_string (p, len, &k, &l); + free (k.data); + if (e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, k.length, UNIV, PRIM, + UT_GeneralizedTime, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: der_free.c,v 1.8 2001/09/25 13:39:26 assar Exp $"); */ + +void +free_general_string (general_string *str) +{ + free(*str); +} + +void +free_octet_string (octet_string *k) +{ + free(k->data); +} + +void +free_oid (oid *k) +{ + free(k->components); +} +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: der_length.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); */ + +static size_t +len_unsigned (unsigned val) +{ + size_t ret = 0; + + do { + ++ret; + val /= 256; + } while (val); + return ret; +} + +static size_t +len_int (int val) +{ + size_t ret = 0; + + if (val == 0) + return 1; + while (val > 255 || val < -255) { + ++ret; + val /= 256; + } + if (val != 0) { + ++ret; + if ((signed char)val != val) + ++ret; + val /= 256; + } + return ret; +} + +static size_t +len_oid (const oid *oid) +{ + size_t ret = 1; + int n; + + for (n = 2; n < oid->length; ++n) { + unsigned u = oid->components[n]; + + ++ret; + u /= 128; + while (u > 0) { + ++ret; + u /= 128; + } + } + return ret; +} + +size_t +length_len (size_t len) +{ + if (len < 128) + return 1; + else + return len_unsigned (len) + 1; +} + +size_t +length_integer (const int *data) +{ + size_t len = len_int (*data); + + return 1 + length_len(len) + len; +} + +size_t +length_unsigned (const unsigned *data) +{ + size_t len = len_unsigned (*data); + + return 1 + length_len(len) + len; +} + +size_t +length_enumerated (const unsigned *data) +{ + size_t len = len_int (*data); + + return 1 + length_len(len) + len; +} + +size_t +length_general_string (const general_string *data) +{ + char *str = *data; + size_t len = strlen(str); + return 1 + length_len(len) + len; +} + +size_t +length_octet_string (const octet_string *k) +{ + return 1 + length_len(k->length) + k->length; +} + +size_t +length_oid (const oid *k) +{ + size_t len = len_oid (k); + + return 1 + length_len(len) + len; +} + +size_t +length_generalized_time (const time_t *t) +{ + octet_string k; + size_t ret; + + time2generalizedtime (*t, &k); + ret = 1 + length_len(k.length) + k.length; + free (k.data); + return ret; +} +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: der_copy.c,v 1.9 2001/09/25 13:39:25 assar Exp $"); */ + +int +copy_general_string (const general_string *from, general_string *to) +{ + *to = malloc(strlen(*from) + 1); + if(*to == NULL) + return ENOMEM; + strcpy(*to, *from); + return 0; +} + +int +copy_octet_string (const octet_string *from, octet_string *to) +{ + to->length = from->length; + to->data = malloc(to->length); + if(to->length != 0 && to->data == NULL) + return ENOMEM; + memcpy(to->data, from->data, to->length); + return 0; +} + +int +copy_oid (const oid *from, oid *to) +{ + to->length = from->length; + to->components = malloc(to->length * sizeof(*to->components)); + if (to->length != 0 && to->components == NULL) + return ENOMEM; + memcpy(to->components, from->components, to->length); + return 0; +} +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* RCSID("Heimdal: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); */ + +#ifndef HAVE_TIMEGM + +static int +is_leap(unsigned y) +{ + y += 1900; + return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); +} + +time_t +timegm (struct tm *tm) +{ + static const unsigned ndays[2][12] ={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + time_t res = 0; + unsigned i; + + for (i = 70; i < tm->tm_year; ++i) + res += is_leap(i) ? 366 : 365; + + for (i = 0; i < tm->tm_mon; ++i) + res += ndays[is_leap(tm->tm_year)][i]; + res += tm->tm_mday - 1; + res *= 24; + res += tm->tm_hour; + res *= 60; + res += tm->tm_min; + res *= 60; + res += tm->tm_sec; + return res; +} + +#endif /* HAVE_TIMEGM */ diff --git a/src/rxkad/v5gen-rewrite.h b/src/rxkad/v5gen-rewrite.h new file mode 100644 index 000000000..6761af54d --- /dev/null +++ b/src/rxkad/v5gen-rewrite.h @@ -0,0 +1,125 @@ +#define encode_Ticket _rxkad_v5_encode_Ticket +#define decode_Ticket _rxkad_v5_decode_Ticket +#define free_Ticket _rxkad_v5_free_Ticket +#define length_Ticket _rxkad_v5_length_Ticket +#define copy_Ticket _rxkad_v5_copy_Ticket +#define encode_EncryptedData _rxkad_v5_encode_EncryptedData +#define decode_EncryptedData _rxkad_v5_decode_EncryptedData +#define free_EncryptedData _rxkad_v5_free_EncryptedData +#define length_EncryptedData _rxkad_v5_length_EncryptedData +#define copy_EncryptedData _rxkad_v5_copy_EncryptedData +#define encode_PrincipalName _rxkad_v5_encode_PrincipalName +#define decode_PrincipalName _rxkad_v5_decode_PrincipalName +#define free_PrincipalName _rxkad_v5_free_PrincipalName +#define length_PrincipalName _rxkad_v5_length_PrincipalName +#define copy_PrincipalName _rxkad_v5_copy_PrincipalName +#define encode_HostAddresses _rxkad_v5_encode_HostAddresses +#define decode_HostAddresses _rxkad_v5_decode_HostAddresses +#define free_HostAddresses _rxkad_v5_free_HostAddresses +#define length_HostAddresses _rxkad_v5_length_HostAddresses +#define copy_HostAddresses _rxkad_v5_copy_HostAddresses +#define encode_HostAddress _rxkad_v5_encode_HostAddress +#define decode_HostAddress _rxkad_v5_decode_HostAddress +#define free_HostAddress _rxkad_v5_free_HostAddress +#define length_HostAddress _rxkad_v5_length_HostAddress +#define copy_HostAddress _rxkad_v5_copy_HostAddress +#define encode_AuthorizationData _rxkad_v5_encode_AuthorizationData +#define decode_AuthorizationData _rxkad_v5_decode_AuthorizationData +#define free_AuthorizationData _rxkad_v5_free_AuthorizationData +#define length_AuthorizationData _rxkad_v5_length_AuthorizationData +#define copy_AuthorizationData _rxkad_v5_copy_AuthorizationData +#define encode_EncTicketPart _rxkad_v5_encode_EncTicketPart +#define decode_EncTicketPart _rxkad_v5_decode_EncTicketPart +#define free_EncTicketPart _rxkad_v5_free_EncTicketPart +#define length_EncTicketPart _rxkad_v5_length_EncTicketPart +#define copy_EncTicketPart _rxkad_v5_copy_EncTicketPart +#define encode_KerberosTime _rxkad_v5_encode_KerberosTime +#define decode_KerberosTime _rxkad_v5_decode_KerberosTime +#define free_KerberosTime _rxkad_v5_free_KerberosTime +#define length_KerberosTime _rxkad_v5_length_KerberosTime +#define copy_KerberosTime _rxkad_v5_copy_KerberosTime +#define encode_TransitedEncoding _rxkad_v5_encode_TransitedEncoding +#define decode_TransitedEncoding _rxkad_v5_decode_TransitedEncoding +#define free_TransitedEncoding _rxkad_v5_free_TransitedEncoding +#define length_TransitedEncoding _rxkad_v5_length_TransitedEncoding +#define copy_TransitedEncoding _rxkad_v5_copy_TransitedEncoding +#define encode_EncryptionKey _rxkad_v5_encode_EncryptionKey +#define decode_EncryptionKey _rxkad_v5_decode_EncryptionKey +#define free_EncryptionKey _rxkad_v5_free_EncryptionKey +#define length_EncryptionKey _rxkad_v5_length_EncryptionKey +#define copy_EncryptionKey _rxkad_v5_copy_EncryptionKey +#define encode_TicketFlags _rxkad_v5_encode_TicketFlags +#define decode_TicketFlags _rxkad_v5_decode_TicketFlags +#define free_TicketFlags _rxkad_v5_free_TicketFlags +#define length_TicketFlags _rxkad_v5_length_TicketFlags +#define copy_TicketFlags _rxkad_v5_copy_TicketFlags +#define encode_Realm _rxkad_v5_encode_Realm +#define decode_Realm _rxkad_v5_decode_Realm +#define free_Realm _rxkad_v5_free_Realm +#define length_Realm _rxkad_v5_length_Realm +#define copy_Realm _rxkad_v5_copy_Realm +#define encode_ENCTYPE _rxkad_v5_encode_ENCTYPE +#define decode_ENCTYPE _rxkad_v5_decode_ENCTYPE +#define free_ENCTYPE _rxkad_v5_free_ENCTYPE +#define length_ENCTYPE _rxkad_v5_length_ENCTYPE +#define copy_ENCTYPE _rxkad_v5_copy_ENCTYPE +#define encode_NAME_TYPE _rxkad_v5_encode_NAME_TYPE +#define decode_NAME_TYPE _rxkad_v5_decode_NAME_TYPE +#define free_NAME_TYPE _rxkad_v5_free_NAME_TYPE +#define length_NAME_TYPE _rxkad_v5_length_NAME_TYPE +#define copy_NAME_TYPE _rxkad_v5_copy_NAME_TYPE +#define der_get_unsigned _rxkad_v5_der_get_unsigned +#define der_get_int _rxkad_v5_der_get_int +#define der_get_length _rxkad_v5_der_get_length +#define der_get_general_string _rxkad_v5_der_get_general_string +#define der_get_octet_string _rxkad_v5_der_get_octet_string +#define der_get_oid _rxkad_v5_der_get_oid +#define der_get_tag _rxkad_v5_der_get_tag +#define der_match_tag _rxkad_v5_der_match_tag +#define der_match_tag_and_length _rxkad_v5_der_match_tag_and_length +#define decode_integer _rxkad_v5_decode_integer +#define decode_unsigned _rxkad_v5_decode_unsigned +#define decode_enumerated _rxkad_v5_decode_enumerated +#define decode_general_string _rxkad_v5_decode_general_string +#define decode_octet_string _rxkad_v5_decode_octet_string +#define decode_oid _rxkad_v5_decode_oid +#define decode_generalized_time _rxkad_v5_decode_generalized_time +#define fix_dce _rxkad_v5_fix_dce +#define der_put_unsigned _rxkad_v5_der_put_unsigned +#define der_put_int _rxkad_v5_der_put_int +#define der_put_length _rxkad_v5_der_put_length +#define der_put_general_string _rxkad_v5_der_put_general_string +#define der_put_octet_string _rxkad_v5_der_put_octet_string +#define der_put_oid _rxkad_v5_der_put_oid +#define der_put_tag _rxkad_v5_der_put_tag +#define der_put_length_and_tag _rxkad_v5_der_put_length_and_tag +#define encode_integer _rxkad_v5_encode_integer +#define encode_unsigned _rxkad_v5_encode_unsigned +#define encode_enumerated _rxkad_v5_encode_enumerated +#define encode_general_string _rxkad_v5_encode_general_string +#define encode_octet_string _rxkad_v5_encode_octet_string +#define encode_oid _rxkad_v5_encode_oid +#define time2generalizedtime _rxkad_v5_time2generalizedtime +#define encode_generalized_time _rxkad_v5_encode_generalized_time +#define free_general_string _rxkad_v5_free_general_string +#define free_octet_string _rxkad_v5_free_octet_string +#define free_oid _rxkad_v5_free_oid +#define len_unsigned _rxkad_v5_len_unsigned +#define len_int _rxkad_v5_len_int +#define len_oid _rxkad_v5_len_oid +#define length_len _rxkad_v5_length_len +#define length_integer _rxkad_v5_length_integer +#define length_unsigned _rxkad_v5_length_unsigned +#define length_enumerated _rxkad_v5_length_enumerated +#define length_general_string _rxkad_v5_length_general_string +#define length_octet_string _rxkad_v5_length_octet_string +#define length_oid _rxkad_v5_length_oid +#define length_generalized_time _rxkad_v5_length_generalized_time +#define copy_general_string _rxkad_v5_copy_general_string +#define copy_octet_string _rxkad_v5_copy_octet_string +#define copy_oid _rxkad_v5_copy_oid +#define TicketFlags2int _rxkad_v5_TicketFlags2int +#define int2TicketFlags _rxkad_v5_int2TicketFlags +#ifndef HAVE_TIMEGM +#define timegm _rxkad_timegm +#endif diff --git a/src/rxkad/v5gen.c b/src/rxkad/v5gen.c new file mode 100644 index 000000000..0380ec134 --- /dev/null +++ b/src/rxkad/v5gen.c @@ -0,0 +1,2490 @@ +/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */ +/* Do not edit */ + +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#define BACK if (e) return e; p -= l; len -= l; ret += l + +int +encode_NAME_TYPE(unsigned char *p, size_t len, const NAME_TYPE *data, size_t *size) +{ +size_t ret = 0; +size_t l; +int i, e; + +i = 0; +e = encode_integer(p, len, (const int*)data, &l); +BACK; +*size = ret; +return 0; +} + +#define FORW if(e) goto fail; p += l; len -= l; ret += l + +int +decode_NAME_TYPE(const unsigned char *p, size_t len, NAME_TYPE *data, size_t *size) +{ +size_t ret = 0, reallen; +size_t l; +int e; + +memset(data, 0, sizeof(*data)); +reallen = 0; +e = decode_integer(p, len, (int*)data, &l); +FORW; +if(size) *size = ret; +return 0; +fail: +free_NAME_TYPE(data); +return e; +} + +void +free_NAME_TYPE(NAME_TYPE *data) +{ +} + +size_t +length_NAME_TYPE(const NAME_TYPE *data) +{ +size_t ret = 0; +ret += length_integer((const int*)data); +return ret; +} + +int +copy_NAME_TYPE(const NAME_TYPE *from, NAME_TYPE *to) +{ +*(to) = *(from); +return 0; +} + diff --git a/src/rxkad/v5gen.h b/src/rxkad/v5gen.h new file mode 100644 index 000000000..163cdd8ca --- /dev/null +++ b/src/rxkad/v5gen.h @@ -0,0 +1,1272 @@ +/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */ +/* Do not edit */ + +#ifndef __krb5_asn1_h__ +#define __krb5_asn1_h__ + +#include +#include + +#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__ */ -- 2.39.5