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