define(PepsyTarget,[
divert(9)
.SUFFIXES: .py
-$1_defs.h $1_pre_defs.h $1-types.h $1_tables.c: $1-asn.py
+$1_defs.h $1_pre_defs.h $1-types.h $1_tables.c:: $1-asn.py
@echo '***Ignore the warning message "Warning: Can'"'"'t find UNIV.ph failed"'
[$](PEPSY) [$](PSYFLAGS) [$](srcdir)/$1-asn.py
dnl ISODE/pepsy includes are used -- ISODE_INCLUDE
dnl
define(ISODE_INCLUDE,[
-ADD_DEF([-I${SRCTOP}/isode/h -I${BUILDTOP}/isode/h])dnl
+AC_ENABLE([isode],
+ISODELIB='[$(TOPLIBD)/libisode.a]'
+ADD_DEF([-I${SRCTOP}/isode/h -I${BUILDTOP}/isode/h]),ISODELIB=)dnl
+AC_SUBST([ISODELIB])dnl
])dnl
dnl
dnl check for yylineno -- HAVE_YYLINENO
AC_VERBOSE(setting LEXLIB to $LEXLIB)
AC_SUBST(LEX)AC_SUBST(LEXLIB)])dnl
dnl
+dnl
+dnl allow for compilation with isode (yuck!)
+dnl
+define(ISODE_DEFS,
+[AC_ENABLE([isode],[ADD_DEF(KRB5_USE_ISODE)],)])dnl
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
--- /dev/null
+Wed Jun 29 00:19:17 1994 Tom Yu (tlyu at dragons-lair)
+
+ * kdb5_create.c: fixed up something that should have been a call
+ to init_ets()
+
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
int keytypedone = 0;
krb5_enctype etype = 0xffff;
- initialize_krb5_error_table();
- initialize_kdb5_error_table();
- initialize_isod_error_table();
+ krb5_init_ets();
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
--- /dev/null
+Wed Jun 29 00:22:07 1994 Tom Yu (tlyu at dragons-lair)
+
+ * kdb5_destroy.c: fix things to call krb5_init_ets
+
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
char dbfilename[MAXPATHLEN];
krb5_error_code retval;
- initialize_krb5_error_table();
- initialize_kdb5_error_table();
- initialize_isod_error_table();
+ krb5_init_ets();
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
SSLIB=$(BUILDTOP)/util/ss/libss.a
DBMLIB=
--- /dev/null
+Wed Jun 29 00:23:09 1994 Tom Yu (tlyu at dragons-lair)
+
+ * kdb5_stash.c: fix things that should have been krb5_init_ets
+
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
- initialize_krb5_error_table();
- initialize_kdb5_error_table();
- initialize_isod_error_table();
+ krb5_init_ets();
while ((optchar = getopt(argc, argv, "d:r:k:M:e:f:")) != EOF) {
switch(optchar) {
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
CONFIG_RULES
AC_SET_BUILDTOP
WITH_KRB5ROOT
-CONFIG_DIRS(util include isode lib kdc admin kadmin slave clients appl)
+AC_ENABLE([isode],isode=isode,)
+CONFIG_DIRS(util include $isode lib kdc admin kadmin slave clients appl)
MAKE_SUBDIRS("making",all)
MAKE_SUBDIRS("cleaning",clean)
MAKE_SUBDIRS("installing",install)
+Tue Jun 28 19:09:21 1994 Tom Yu (tlyu at dragons-lair)
+
+ * error_def.h: folding in Harry's changes
+ * asn1.h: ditto
+ * configure.in: adding ISODE_DEFS, fixing ISODE_INCLUDE to dtrt
+
Tue Jun 21 23:54:40 1994 Tom Yu (tlyu at dragons-lair)
* pulling SEEK_SET, etc. out to avoid redef'ing in unistd.h
--- /dev/null
+Tue Jun 28 23:20:58 1994 Tom Yu (tlyu at dragons-lair)
+
+ * encode.h:
+ * krb5_is.h: ....folding in Harry's changes
+
#ifndef KRB5_ENCODE_DEFS__
#define KRB5_ENCODE_DEFS__
+#ifdef KRB5_USE_ISODE
typedef int (*encoder_func) PROTOTYPE((PE *, int, int, char *, krb5_pointer));
typedef void (*free_func) PROTOTYPE((krb5_pointer ));
typedef krb5_pointer (*translator_func) PROTOTYPE((krb5_const_pointer, int * ));
(dat)->data[0] == 0x5e))
+#else /* KRB5_USE_ISODE */
+#include <krb5/asn.1/krb5_encode.h>
+#include <krb5/asn.1/krb5_decode.h>
+#include <krb5/asn.1/krb5_is.h>
+#endif /* KRB5_USE_ISODE */
#endif /* KRB5_ENCODE_DEFS__ */
--- /dev/null
+#ifndef __KRB5_IS_H__
+#define __KRB5_IS_H__
+
+/* ASN.1 encoding knowledge; KEEP IN SYNC WITH ASN.1 defs! */
+/* here we use some knowledge of ASN.1 encodings */
+/*
+ Ticket is APPLICATION 1.
+ Authenticator is APPLICATION 2.
+ AS_REQ is APPLICATION 10.
+ AS_REP is APPLICATION 11.
+ TGS_REQ is APPLICATION 12.
+ TGS_REP is APPLICATION 13.
+ AP_REQ is APPLICATION 14.
+ AP_REP is APPLICATION 15.
+ KRB_SAFE is APPLICATION 20.
+ KRB_PRIV is APPLICATION 21.
+ KRB_CRED is APPLICATION 22.
+ EncASRepPart is APPLICATION 25.
+ EncTGSRepPart is APPLICATION 26.
+ EncAPRepPart is APPLICATION 27.
+ EncKrbPrivPart is APPLICATION 28.
+ EncKrbCredPart is APPLICATION 29.
+ KRB_ERROR is APPLICATION 30.
+ */
+/* allow either constructed or primitive encoding, so check for bit 6
+ set or reset */
+#define krb5_is_krb_ticket(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x61 ||\
+ (dat)->data[0] == 0x41))
+#define krb5_is_krb_authenticator(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x62 ||\
+ (dat)->data[0] == 0x42))
+#define krb5_is_as_req(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6a ||\
+ (dat)->data[0] == 0x4a))
+#define krb5_is_as_rep(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6b ||\
+ (dat)->data[0] == 0x4b))
+#define krb5_is_tgs_req(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6c ||\
+ (dat)->data[0] == 0x4c))
+#define krb5_is_tgs_rep(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6d ||\
+ (dat)->data[0] == 0x4d))
+#define krb5_is_ap_req(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6e ||\
+ (dat)->data[0] == 0x4e))
+#define krb5_is_ap_rep(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x6f ||\
+ (dat)->data[0] == 0x4f))
+#define krb5_is_krb_safe(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x74 ||\
+ (dat)->data[0] == 0x54))
+#define krb5_is_krb_priv(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x75 ||\
+ (dat)->data[0] == 0x55))
+#define krb5_is_krb_cred(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x76 ||\
+ (dat)->data[0] == 0x56))
+#define krb5_is_krb_enc_as_rep_part(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x79 ||\
+ (dat)->data[0] == 0x59))
+#define krb5_is_krb_enc_tgs_rep_part(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7a ||\
+ (dat)->data[0] == 0x5a))
+#define krb5_is_krb_enc_ap_rep_part(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7b ||\
+ (dat)->data[0] == 0x5b))
+#define krb5_is_krb_enc_krb_priv_part(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7c ||\
+ (dat)->data[0] == 0x5c))
+#define krb5_is_krb_enc_krb_cred_part(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7d ||\
+ (dat)->data[0] == 0x5d))
+#define krb5_is_krb_error(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
+ (dat)->data[0] == 0x5e))
+
+#endif
#ifndef KRB5_ASN1__
#define KRB5_ASN1__
+#ifdef KRB5_USE_ISODE
#include <krb5/asn.1/KRB5-types.h>
#include <krb5/asn.1/asn1defs.h>
#include <krb5/asn.1/KRB5-types-aux.h>
+#endif
#include <krb5/asn.1/encode.h>
#endif /* KRB5_ASN1__ */
AC_INIT(acconfig.h)
AC_SET_BUILDTOP
CONFIG_RULES
+ISODE_DEFS
AC_CONFIG_HEADER(autoconf.h)
AC_PROG_LEX
HAVE_YYLINENO
#include <krb5/krb5_err.h>
#include <krb5/kdb5_err.h>
+#ifndef KRB5_USE_ISODE
+#include <krb5/asn1_err.h>
+#else
#include <krb5/isode_err.h>
+#endif
#include <errno.h>
#endif /* KRB5_ERROR_DEF__ */
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
SSLIB=$(BUILDTOP)/util/ss/libss.a
DBMLIB=
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
SSLIB=$(BUILDTOP)/util/ss/libss.a
DBMLIB=
+Wed Jun 29 00:25:29 1994 Tom Yu (tlyu at dragons-lair)
+
+ * adm_server.c: fixed error table calls to use krb5_init_ets
+
Fri Jun 24 20:39:37 1994 Theodore Y. Ts'o (tytso at tsx-11)
* adm_process.c (cpw_keyproc): return error codes on failure
void
setup_com_err()
{
- initialize_krb5_error_table();
- initialize_kdb5_error_table();
- initialize_isod_error_table();
+ krb5_init_ets();
(void) set_com_err_hook(kdc_com_err_proc);
return;
--- /dev/null
+Tue Jun 28 19:43:54 1994 Tom Yu (tlyu at dragons-lair)
+
+ * main.c: fix explicit calls to initialize_foo_error_table
+
+ * do_tgs_req.c:
+ * configure.in: folding in Harry's changes
+
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
AC_INIT(main.c)
WITH_CCOPTS
CONFIG_RULES
+ISODE_DEFS
AC_SET_BUILDTOP
AC_HAVE_LIBRARY(socket)
AC_HAVE_LIBRARY(nsl)
goto cleanup;
}
/* scratch now has the authorization data, so we decode it */
+#ifdef KRB5_USE_ISODE
retval = decode_krb5_authdata(&scratch, request->unenc_authdata);
+#else
+ retval = decode_krb5_authdata(&scratch, &(request->unenc_authdata));
+#endif
free(scratch.data);
if (retval) {
status = "AUTH_DECODE";
void
setup_com_err()
{
- initialize_krb5_error_table();
+ krb5_init_ets();
initialize_kdb5_error_table();
- initialize_kdc5_error_table();
- initialize_isod_error_table();
-
(void) set_com_err_hook(kdc_com_err_proc);
return;
}
-Fri Jun 17 18:22:32 1994 Theodore Y. Ts'o (tytso at tsx-11)
+Tue Jun 28 19:57:28 1994 Tom Yu (tlyu at dragons-lair)
- * Fixed bug in crep2kcrep.c which caused ticket forwarding to
- break. The wrong ISODE optional field flag was being tested.
+ * configure.in:
+ * Makefile.in: autoconf frobbage
--- /dev/null
+# $Source$
+# $Author$
+# $Id$
+#
+# Copyright 1990,1991 by the Massachusetts Institute of Technology.
+# All Rights Reserved.
+#
+# Export of this software from the United States of America may
+# require a specific license from the United States Government.
+# It is the responsibility of any person or organization contemplating
+# export to obtain such a license before exporting.
+#
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of M.I.T. not be used in advertising or publicity pertaining
+# to distribution of the software without specific, written prior
+# permission. M.I.T. makes no representations about the suitability of
+# this software for any purpose. It is provided "as is" without express
+# or implied warranty.
+#
+#
+NormalLibraryObjectRule()
+
+EHDRDIR=$(TOP)/include/krb5/asn.1
+
+SRCS= \
+ $(SRCDIR)asn1_decode.c\
+ $(SRCDIR)asn1_decode_k.c\
+ $(SRCDIR)asn1_encode.c\
+ $(SRCDIR)asn1_get.c\
+ $(SRCDIR)asn1_make.c\
+ $(SRCDIR)asn1buf.c\
+ $(SRCDIR)krb5_decode.c\
+ $(SRCDIR)krb5_encode.c\
+ $(SRCDIR)asn1_encode_k.c\
+ $(SRCDIR)asn1_misc.c
+
+OBJS= \
+ asn1_decode.o\
+ asn1_decode_k.o\
+ asn1_encode.o\
+ asn1_get.o\
+ asn1_make.o\
+ asn1buf.o\
+ krb5_decode.o\
+ krb5_encode.o\
+ asn1_encode_k.o\
+ asn1_misc.o
+
+all:: depend includes
+
+SubdirLibraryRule($(OBJS))
+
+CopyHeader(krb5_encode.h,$(EHDRDIR))
+CopyHeader(krb5_decode.h,$(EHDRDIR))
+
+Krb5InstallHeaders(krb5_encode.h krb5_decode.h, $(KRB5_INCDIR)/krb5/asn.1)
+
+DependTarget()
+
+#ifdef UseSedHack
+
+#define IHaveSpecialMakefileTarget
+
+Makefile:: $(SRCDIR)Imakefile
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) $(SRCSUBDIR)Imakefile -s Makefile.new
+ $(MAKE) -f Makefile.new noop
+ -@if [ -f Makefile ]; then \
+ echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak";\
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak;\
+ fi
+ sed 's/^@/ @/' Makefile.new > Makefile || $(MV) Makefile.new Makefile
+ -$(RM) Makefile.new
+
+#endif
+
+noop::
--- /dev/null
+BUILDTOP=@BUILDTOP@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+DEFS = @DEFS@
+CC = @CC@
+CCOPTS = @CCOPTS@
+LIBS = @LIBS@
+
+CFLAGS=$(CCOPTS) $(DEFS)
+LDFLAGS = -g
+
+RM = rm -f
+CP = cp
+
+
+PEPSY = @PEPSY@
+PSYFLAGS = @PSYFLAGS@
+
+KRB5ROOT = @KRB5ROOT@
+
+KRB5_INCDIR = $(KRB5ROOT)/include
+
+all::
+
+SRCTOP=$(srcdir)/$(BUILDTOP)
+
+EHDRDIR=$(BUILDTOP)/include/krb5/asn.1
+
+SRCS= \
+ $(srcdir)asn1_decode.c\
+ $(srcdir)asn1_decode_k.c\
+ $(srcdir)asn1_encode.c\
+ $(srcdir)asn1_get.c\
+ $(srcdir)asn1_make.c\
+ $(srcdir)asn1buf.c\
+ $(srcdir)krb5_decode.c\
+ $(srcdir)krb5_encode.c\
+ $(srcdir)asn1_encode_k.c\
+ $(srcdir)asn1_misc.c
+
+OBJS= \
+ asn1_decode.o\
+ asn1_decode_k.o\
+ asn1_encode.o\
+ asn1_get.o\
+ asn1_make.o\
+ asn1buf.o\
+ krb5_decode.o\
+ krb5_encode.o\
+ asn1_encode_k.o\
+ asn1_misc.o
+
+all:: includes
+
+clean::
+ $(RM) $(OBJS)
+
+KRB5.ph KRB5_defs.h KRB5_pre_defs.h KRB5-types.h KRB5_tables.c::
+ echo '/* isode sucks */' > $@
+
+clean::
+ $(RM) KRB5.ph KRB5_defs.h KRB5_pre_defs.h KRB5-types.h KRB5_tables.c
--- /dev/null
+/* ASN.1 primitive decoders */
+#include "asn1_decode.h"
+#include "asn1_get.h"
+#include <time.h>
+
+#define setup()\
+asn1_error_code retval;\
+asn1_class class;\
+asn1_construction construction;\
+asn1_tagnum tagnum;\
+int length
+
+#define tag(type)\
+retval = asn1_get_tag(buf,&class,&construction,&tagnum,&length);\
+if(retval) return retval;\
+if(class != UNIVERSAL || construction != PRIMITIVE || tagnum != type)\
+ return ASN1_BAD_ID
+
+#define cleanup()\
+return 0
+
+asn1_error_code asn1_decode_integer(DECLARG(asn1buf *, buf),
+ DECLARG(long *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(long *, val)
+{
+ setup();
+ asn1_octet o;
+ unsigned long n;
+
+ tag(ASN1_INTEGER);
+
+ for(n=0; length > 0; length--){
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ n = (n<<8) + (unsigned int)o;
+ }
+ *val = n;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_unsigned_integer(DECLARG(asn1buf *, buf),
+ DECLARG(unsigned long *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(unsigned long *, val)
+{
+ setup();
+ asn1_octet o;
+ unsigned long n;
+
+ tag(ASN1_INTEGER);
+
+ for(n=0; length > 0; length--){
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ n = (n<<8) + (unsigned int)o;
+ }
+ *val = n;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_octetstring(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen),
+ DECLARG(asn1_octet **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+ OLDDECLARG(asn1_octet **, val)
+{
+ setup();
+ tag(ASN1_OCTETSTRING);
+ retval = asn1buf_remove_octetstring(buf,length,val);
+ if(retval) return retval;
+ *retlen = length;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_charstring(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen),
+ DECLARG(char **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+ OLDDECLARG(char **, val)
+{
+ setup();
+ tag(ASN1_OCTETSTRING);
+ retval = asn1buf_remove_charstring(buf,length,val);
+ if(retval) return retval;
+ *retlen = length;
+ cleanup();
+}
+
+
+asn1_error_code asn1_decode_generalstring(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen),
+ DECLARG(char **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+ OLDDECLARG(char **, val)
+{
+ setup();
+ tag(ASN1_GENERALSTRING);
+ retval = asn1buf_remove_charstring(buf,length,val);
+ if(retval) return retval;
+ *retlen = length;
+ cleanup();
+}
+
+
+asn1_error_code asn1_decode_null(DECLARG(asn1buf *, buf))
+ OLDDECLARG(asn1buf *, buf)
+{
+ setup();
+ tag(ASN1_NULL);
+ if(length != 0) return ASN1_BAD_LENGTH;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_printablestring(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen),
+ DECLARG(char **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+ OLDDECLARG(char **, val)
+{
+ setup();
+ tag(ASN1_PRINTABLESTRING);
+ retval = asn1buf_remove_charstring(buf,length,val);
+ if(retval) return retval;
+ *retlen = length;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_ia5string(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen),
+ DECLARG(char **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+ OLDDECLARG(char **, val)
+{
+ setup();
+ tag(ASN1_IA5STRING);
+ retval = asn1buf_remove_charstring(buf,length,val);
+ if(retval) return retval;
+ *retlen = length;
+ cleanup();
+}
+
+asn1_error_code asn1_decode_generaltime(DECLARG(asn1buf *, buf),
+ DECLARG(time_t *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(time_t *, val)
+{
+ setup();
+ char *s;
+ struct tm ts;
+ time_t t;
+
+ tag(ASN1_GENERALTIME);
+
+ if(length != 15) return ASN1_BAD_LENGTH;
+ retval = asn1buf_remove_charstring(buf,15,&s);
+ /* Time encoding: YYYYMMDDhhmmssZ */
+ if(s[14] != 'Z') return ASN1_BAD_FORMAT;
+#define c2i(c) ((c)-'0')
+ ts.tm_year = 1000*c2i(s[0]) + 100*c2i(s[1]) + 10*c2i(s[2]) + c2i(s[3])
+ - 1900;
+ ts.tm_mon = 10*c2i(s[4]) + c2i(s[5]) - 1;
+ ts.tm_mday = 10*c2i(s[6]) + c2i(s[7]);
+ ts.tm_hour = 10*c2i(s[8]) + c2i(s[9]);
+ ts.tm_min = 10*c2i(s[10]) + c2i(s[11]);
+ ts.tm_sec = 10*c2i(s[12]) + c2i(s[13]);
+ ts.tm_isdst = -1;
+ t = mktime(&ts);
+ if(t == -1) return ASN1_BAD_TIMEFORMAT;
+ t += ts.tm_gmtoff; /* Convert back to UTC timezone */
+ /* !!!WARNING!!! tm_gmtoff is non-ANSI,
+ although it should exist in both
+ BSD and SYSV. */
+ *val = t;
+ cleanup();
+}
--- /dev/null
+#ifndef __ASN1_DECODE_H__
+#define __ASN1_DECODE_H__
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+#include "asn1buf.h"
+
+/*
+ Overview
+
+ These procedures take an asn1buf whose current position points
+ to the beginning of an ASN.1 primitive (<id><length><contents>).
+ The primitive is removed from the buffer and decoded.
+
+ Operations
+
+ asn1_decode_integer
+ asn1_decode_unsigned_integer
+ asn1_decode_octetstring
+ asn1_decode_charstring
+ asn1_decode_generalstring
+ asn1_decode_null
+ asn1_decode_printablestring
+ asn1_decode_ia5string
+ asn1_decode_generaltime
+*/
+
+/* asn1_error_code asn1_decode_type(asn1buf *buf, ctype *val); */
+/* requires *buf is allocated
+ modifies *buf, *len
+ effects Decodes the octet string in *buf into *val.
+ Returns ENOMEM if memory is exhausted.
+ Returns asn1 errors. */
+
+asn1_error_code asn1_decode_integer
+ PROTOTYPE((asn1buf *buf, long *val));
+asn1_error_code asn1_decode_unsigned_integer
+ PROTOTYPE((asn1buf *buf, unsigned long *val));
+asn1_error_code asn1_decode_null
+ PROTOTYPE((asn1buf *buf));
+
+asn1_error_code asn1_decode_octetstring
+ PROTOTYPE((asn1buf *buf, int *retlen, asn1_octet **val));
+asn1_error_code asn1_decode_generalstring
+ PROTOTYPE((asn1buf *buf, int *retlen, char **val));
+asn1_error_code asn1_decode_charstring
+ PROTOTYPE((asn1buf *buf, int *retlen, char **val));
+/* Note: A charstring is a special hack to account for the fact that
+ krb5 structures store some OCTET STRING values in krb5_octet
+ arrays and others in krb5_data structures
+ PROTOTYPE((which use char arrays).
+ From the ASN.1 point of view, the two string types are the same,
+ only the receptacles differ. */
+asn1_error_code asn1_decode_printablestring
+ PROTOTYPE((asn1buf *buf, int *retlen, char **val));
+asn1_error_code asn1_decode_ia5string
+ PROTOTYPE((asn1buf *buf, int *retlen, char **val));
+
+asn1_error_code asn1_decode_generaltime
+ PROTOTYPE((asn1buf *buf, time_t *val));
+
+#endif
--- /dev/null
+#include "asn1_decode_k.h"
+#include "asn1_decode.h"
+#include "asn1_get.h"
+#include "asn1_misc.h"
+
+#define setup()\
+asn1_error_code retval;\
+asn1_class class;\
+asn1_construction construction;\
+asn1_tagnum tagnum;\
+int length
+
+#define next_tag()\
+retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,NULL);\
+if(retval) return retval;\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ return ASN1_BAD_ID
+
+#define alloc_field(var,type)\
+var = (type*)calloc(1,sizeof(type));\
+if((var) == NULL) return ENOMEM
+
+
+#define apptag(tagexpect)\
+retval = asn1_get_tag(buf,&class,&construction,&tagnum,NULL);\
+if(retval) return retval;\
+if(class != APPLICATION || construction != CONSTRUCTED ||\
+ tagnum != (tagexpect)) return ASN1_BAD_ID
+
+/**** normal fields ****/
+#define get_field_body(var,decoder)\
+retval = decoder(&subbuf,&(var));\
+if(retval) return retval;\
+next_tag()
+
+#define get_field(var,tagexpect,decoder)\
+if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
+if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+get_field_body(var,decoder)
+
+#define opt_field(var,tagexpect,decoder,optvalue)\
+if(tagnum == (tagexpect)){\
+ get_field_body(var,decoder); }\
+else var = optvalue
+
+/**** fields w/ length ****/
+#define get_lenfield_body(len,var,decoder)\
+retval = decoder(&subbuf,&(len),&(var));\
+if(retval) return retval;\
+next_tag()
+
+#define get_lenfield(len,var,tagexpect,decoder)\
+if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
+if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+get_lenfield_body(len,var,decoder)
+
+
+
+#define begin_structure()\
+asn1buf subbuf;\
+retval = asn1_get_tag(buf,&class,&construction,&tagnum,&length);\
+if(retval) return retval;\
+if(class != UNIVERSAL || construction != CONSTRUCTED ||\
+ tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID;\
+retval = asn1buf_imbed(&subbuf,buf,length);\
+if(retval) return retval;\
+next_tag()
+
+#define end_structure()\
+asn1buf_sync(buf,&subbuf)
+
+#define sequence_of(buf)\
+int size=0;\
+asn1buf seqbuf;\
+int length;\
+retval = asn1_get_sequence(buf,&length);\
+if(retval) return retval;\
+retval = asn1buf_imbed(&seqbuf,buf,length);\
+if(retval) return retval
+
+#define end_sequence_of(buf)\
+asn1buf_sync(buf,&seqbuf)
+
+#define cleanup()\
+return 0
+
+
+
+/* scalars */
+asn1_error_code asn1_decode_kerberos_time(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_timestamp *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_timestamp *, val)
+{
+ return asn1_decode_generaltime(buf,val);
+}
+
+#define integer_convert(fname,ktype)\
+asn1_error_code fname(DECLARG(asn1buf *, buf),\
+ DECLARG(ktype *, val))\
+ OLDDECLARG(asn1buf *, buf)\
+ OLDDECLARG(ktype *, val)\
+{\
+ asn1_error_code retval;\
+ long n;\
+ retval = asn1_decode_integer(buf,&n);\
+ if(retval) return retval;\
+ *val = (ktype)n;\
+ return 0;\
+}
+#define unsigned_integer_convert(fname,ktype)\
+asn1_error_code fname(DECLARG(asn1buf *, buf),\
+ DECLARG(ktype *, val))\
+ OLDDECLARG(asn1buf *, buf)\
+ OLDDECLARG(ktype *, val)\
+{\
+ asn1_error_code retval;\
+ unsigned long n;\
+ retval = asn1_decode_unsigned_integer(buf,&n);\
+ if(retval) return retval;\
+ *val = (ktype)n;\
+ return 0;\
+}
+integer_convert(asn1_decode_int,int)
+integer_convert(asn1_decode_int32,krb5_int32)
+integer_convert(asn1_decode_kvno,krb5_kvno)
+integer_convert(asn1_decode_keytype,krb5_keytype)
+integer_convert(asn1_decode_cksumtype,krb5_cksumtype)
+integer_convert(asn1_decode_enctype,krb5_enctype)
+integer_convert(asn1_decode_octet,krb5_octet)
+integer_convert(asn1_decode_addrtype,krb5_addrtype)
+integer_convert(asn1_decode_authdatatype,krb5_authdatatype)
+unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2)
+unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4)
+
+asn1_error_code asn1_decode_msgtype(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_msgtype *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_msgtype *, val)
+{
+ asn1_error_code retval;
+ unsigned long n;
+ retval = asn1_decode_unsigned_integer(buf,&n);
+ if(retval) return retval;
+ switch(n){
+ case ASN1_KRB_AS_REQ:
+ *val = KRB5_AS_REQ;
+ break;
+ case ASN1_KRB_AS_REP:
+ *val = KRB5_AS_REP;
+ break;
+ case ASN1_KRB_TGS_REQ:
+ *val = KRB5_TGS_REQ;
+ break;
+ case ASN1_KRB_TGS_REP:
+ *val = KRB5_TGS_REP;
+ break;
+ case ASN1_KRB_AP_REQ:
+ *val = KRB5_AP_REQ;
+ break;
+ case ASN1_KRB_AP_REP:
+ *val = KRB5_AP_REP;
+ break;
+ case ASN1_KRB_SAFE:
+ *val = KRB5_SAFE;
+ break;
+ case ASN1_KRB_PRIV:
+ *val = KRB5_PRIV;
+ break;
+ case ASN1_KRB_CRED:
+ *val = KRB5_CRED;
+ break;
+ case ASN1_KRB_ERROR:
+ *val = KRB5_ERROR;
+ break;
+ default:
+ return KRB5_BADMSGTYPE;
+ }
+ return 0;
+}
+
+
+/* structures */
+asn1_error_code asn1_decode_realm(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_principal *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_principal *, val)
+{
+ return asn1_decode_generalstring(buf,
+ &((*val)->realm.length),
+ &((*val)->realm.data));
+}
+
+asn1_error_code asn1_decode_principal_name(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_principal *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_principal *, val)
+{
+ setup();
+ { begin_structure();
+ get_field((*val)->type,0,asn1_decode_int32);
+
+ { sequence_of(&subbuf);
+ while(asn1buf_remains(&seqbuf)){
+ size++;
+ (*val)->data = (krb5_data*)realloc((*val)->data,
+ size*sizeof(krb5_data));
+ if((*val)->data == NULL) return ENOMEM;
+ retval = asn1_decode_generalstring(&seqbuf,
+ &((*val)->data[size-1].length),
+ &((*val)->data[size-1].data));
+ if(retval) return retval;
+ }
+ (*val)->length = size;
+ end_sequence_of(&subbuf);
+ }
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_checksum(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_checksum *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_checksum *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->checksum_type,0,asn1_decode_cksumtype);
+ get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_encryption_key(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_keyblock *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_keyblock *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->keytype,0,asn1_decode_keytype);
+ get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_encrypted_data(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_enc_data *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_enc_data *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->etype,0,asn1_decode_enctype);
+ opt_field(val->kvno,1,asn1_decode_kvno,5);
+ get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_krb5_flags(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_flags *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_flags *, val)
+{
+ setup();
+ asn1_octet o;
+ int i;
+ krb5_flags f=0;
+
+ retval = asn1_get_tag(buf,&class,&construction,&tagnum,&length);
+ if(retval) return retval;
+ if(class != UNIVERSAL || construction != PRIMITIVE ||
+ tagnum != ASN1_BITSTRING) return ASN1_BAD_ID;
+ if(length != 5) return ASN1_BAD_LENGTH;
+
+ retval = asn1buf_remove_octet(buf,&o); /* # of padding bits */
+ if(retval) return retval; /* should be 0 */
+ if(o != 0) return ASN1_BAD_FORMAT;
+
+ for(i=0; i<4; i++){
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ f = (f<<8) | ((krb5_flags)o&0xFF);
+ }
+ *val = f;
+ return 0;
+}
+
+asn1_error_code asn1_decode_ticket_flags(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_flags *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_flags *, val)
+{ return asn1_decode_krb5_flags(buf,val); }
+
+asn1_error_code asn1_decode_ap_options(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_flags *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_flags *, val)
+{ return asn1_decode_krb5_flags(buf,val); }
+
+asn1_error_code asn1_decode_kdc_options(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_flags *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_flags *, val)
+{ return asn1_decode_krb5_flags(buf,val); }
+
+asn1_error_code asn1_decode_transited_encoding(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_transited *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_transited *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->tr_type,0,asn1_decode_octet);
+ get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_enc_kdc_rep_part(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_enc_kdc_rep_part *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_enc_kdc_rep_part *, val)
+{
+ setup();
+ { begin_structure();
+ alloc_field(val->session,krb5_keyblock);
+ get_field(*(val->session),0,asn1_decode_encryption_key);
+ get_field(val->last_req,1,asn1_decode_last_req);
+ get_field(val->nonce,2,asn1_decode_int32);
+ opt_field(val->key_exp,3,asn1_decode_kerberos_time,0);
+ get_field(val->flags,4,asn1_decode_ticket_flags);
+ get_field(val->times.authtime,5,asn1_decode_kerberos_time);
+ opt_field(val->times.starttime,6,asn1_decode_kerberos_time,0);
+ get_field(val->times.endtime,7,asn1_decode_kerberos_time);
+ opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0);
+ alloc_field(val->server,krb5_principal_data);
+ get_field(val->server,9,asn1_decode_realm);
+ get_field(val->server,10,asn1_decode_principal_name);
+ opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_ticket(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_ticket *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_ticket *, val)
+{
+ setup();
+ apptag(1);
+ { begin_structure();
+ { krb5_kvno vno;
+ get_field(vno,0,asn1_decode_kvno);
+ if(vno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ alloc_field(val->server,krb5_principal_data);
+ get_field(val->server,1,asn1_decode_realm);
+ get_field(val->server,2,asn1_decode_principal_name);
+ get_field(val->enc_part,3,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_kdc_req(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_kdc_req *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_kdc_req *, val)
+{
+ setup();
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,1,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ get_field(val->msg_type,2,asn1_decode_msgtype);
+ opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL);
+ get_field(*val,4,asn1_decode_kdc_req_body);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_kdc_req_body(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_kdc_req *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_kdc_req *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->kdc_options,0,asn1_decode_kdc_options);
+ if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); }
+ opt_field(val->client,1,asn1_decode_principal_name,NULL);
+ alloc_field(val->server,krb5_principal_data);
+ get_field(val->server,2,asn1_decode_realm);
+ if(val->client != NULL){
+ retval = asn1_krb5_realm_copy(val->client,val->server);
+ if(retval) return retval; }
+ opt_field(val->server,3,asn1_decode_principal_name,NULL);
+ opt_field(val->from,4,asn1_decode_kerberos_time,0);
+ get_field(val->till,5,asn1_decode_kerberos_time);
+ opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
+ get_field(val->nonce,7,asn1_decode_int32);
+ get_lenfield(val->netypes,val->etype,8,asn1_decode_sequence_of_enctype);
+ opt_field(val->addresses,9,asn1_decode_host_addresses,0);
+ if(tagnum == 10){
+ get_field(val->authorization_data,10,asn1_decode_encrypted_data); }
+ else{
+ val->authorization_data.etype = 0;
+ val->authorization_data.kvno = KVNO;
+ val->authorization_data.ciphertext.data = NULL;
+ val->authorization_data.ciphertext.length = 0;
+ }
+ opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_krb_safe_body(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_safe *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_safe *, val)
+{
+ setup();
+ { begin_structure();
+ get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
+ opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
+ opt_field(val->usec,2,asn1_decode_int32,0);
+ opt_field(val->seq_number,3,asn1_decode_int32,0);
+ alloc_field(val->s_address,krb5_address);
+ get_field(*(val->s_address),4,asn1_decode_host_address);
+ if(tagnum == 5){
+ alloc_field(val->r_address,krb5_address);
+ get_field(*(val->r_address),5,asn1_decode_host_address);
+ } else val->r_address = NULL;
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_host_address(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_address *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_address *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->addrtype,0,asn1_decode_addrtype);
+ get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_kdc_rep(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_kdc_rep *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_kdc_rep *, val)
+{
+ setup();
+ { begin_structure();
+ { krb5_kvno pvno;
+ get_field(pvno,0,asn1_decode_kvno);
+ if(pvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ get_field(val->msg_type,1,asn1_decode_msgtype);
+ opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL);
+ alloc_field(val->client,krb5_principal_data);
+ get_field(val->client,3,asn1_decode_realm);
+ get_field(val->client,4,asn1_decode_principal_name);
+ alloc_field(val->ticket,krb5_ticket);
+ get_field(*(val->ticket),5,asn1_decode_ticket);
+ get_field(val->enc_part,6,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+
+/* arrays */
+#define get_element(element,decoder)\
+retval = decoder(&seqbuf,element);\
+if(retval) return retval
+
+#define array_append(array,size,element,type)\
+size++;\
+*(array) = (type**)realloc(*(array),\
+ (size+1)*sizeof(type*));\
+if(*(array) == NULL) return ENOMEM;\
+(*(array))[(size)-1] = elt
+
+#define decode_array_body(type,decoder)\
+ asn1_error_code retval;\
+ type *elt;\
+\
+ { sequence_of(buf);\
+ while(asn1buf_remains(&seqbuf) > 0){\
+ alloc_field(elt,type);\
+ get_element(elt,decoder);\
+ array_append(val,size,elt,type);\
+ }\
+ (*val)[size] = NULL;\
+ end_sequence_of(buf);\
+ }\
+ cleanup()
+
+
+asn1_error_code asn1_decode_authorization_data(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_authdata ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_authdata ***, val)
+{
+ decode_array_body(krb5_authdata,asn1_decode_authdata_elt);
+}
+
+asn1_error_code asn1_decode_authdata_elt(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_authdata *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_authdata *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->ad_type,0,asn1_decode_authdatatype);
+ get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_host_addresses(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_address ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_address ***, val)
+{
+ decode_array_body(krb5_address,asn1_decode_host_address);
+}
+
+asn1_error_code asn1_decode_sequence_of_ticket(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_ticket ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_ticket ***, val)
+{
+ decode_array_body(krb5_ticket,asn1_decode_ticket);
+}
+
+asn1_error_code asn1_decode_sequence_of_krb_cred_info(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_cred_info ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_cred_info ***, val)
+{
+ decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info);
+}
+
+asn1_error_code asn1_decode_krb_cred_info(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_cred_info *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_cred_info *, val)
+{
+ setup();
+ { begin_structure();
+ alloc_field(val->session,krb5_keyblock);
+ get_field(*(val->session),0,asn1_decode_encryption_key);
+ if(tagnum == 1){
+ alloc_field(val->client,krb5_principal_data);
+ opt_field(val->client,1,asn1_decode_realm,NULL);
+ opt_field(val->client,2,asn1_decode_principal_name,NULL); }
+ opt_field(val->flags,3,asn1_decode_ticket_flags,0);
+ opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0);
+ opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0);
+ opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0);
+ opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0);
+ if(tagnum == 8){
+ alloc_field(val->server,krb5_principal_data);
+ opt_field(val->server,8,asn1_decode_realm,NULL);
+ opt_field(val->server,9,asn1_decode_principal_name,NULL); }
+ opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_pa_data(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_pa_data ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_pa_data ***, val)
+{
+ decode_array_body(krb5_pa_data,asn1_decode_pa_data);
+}
+
+asn1_error_code asn1_decode_pa_data(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_pa_data *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_pa_data *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->pa_type,1,asn1_decode_ui_2);
+ get_lenfield(val->length,val->contents,2,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_last_req(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_last_req_entry ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_last_req_entry ***, val)
+{
+ decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry);
+}
+
+asn1_error_code asn1_decode_last_req_entry(DECLARG(asn1buf *, buf),
+ DECLARG(krb5_last_req_entry *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(krb5_last_req_entry *, val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->lr_type,0,asn1_decode_octet);
+ get_field(val->value,1,asn1_decode_kerberos_time);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_enctype(DECLARG(asn1buf *, buf),
+ DECLARG(int *, num),
+ DECLARG(krb5_enctype **, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, num)
+ OLDDECLARG(krb5_enctype **, val)
+{
+ asn1_error_code retval;
+ { sequence_of(buf);
+ while(asn1buf_remains(&seqbuf) > 0){
+ size++;
+ *val = (krb5_enctype*)realloc(*val,size*sizeof(krb5_enctype));
+ if(*val == NULL) return ENOMEM;
+ retval = asn1_decode_enctype(&seqbuf,&((*val)[size-1]));
+ if(retval) return retval;
+ }
+ *num = size;
+ end_sequence_of(buf);
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_passwdsequence(DECLARG(asn1buf *, buf),
+ DECLARG(passwd_phrase_element *, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(passwd_phrase_element *, val)
+{
+ setup();
+ { begin_structure();
+ alloc_field(val->passwd,krb5_data);
+ get_lenfield(val->passwd->length,val->passwd->data,
+ 0,asn1_decode_charstring);
+ alloc_field(val->phrase,krb5_data);
+ get_lenfield(val->phrase->length,val->phrase->data,
+ 1,asn1_decode_charstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_passwdsequence(DECLARG(asn1buf *, buf),
+ DECLARG(passwd_phrase_element ***, val))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(passwd_phrase_element ***, val)
+{
+ decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence);
+}
--- /dev/null
+#ifndef __ASN1_DECODE_KRB5_H__
+#define __ASN1_DECODE_KRB5_H__
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+#include "asn1buf.h"
+
+/* asn1_error_code asn1_decode_scalar_type(asn1buf *buf, krb5_scalar *val); */
+/* requires *buf is allocated, *buf's current position points to the
+ beginning of an encoding (<id> <len> <contents>),
+ *val is allocated
+ effects Decodes the encoding in *buf, returning the result in *val.
+ Returns ASN1_BAD_ID if the encoded id does not
+ indicate the proper type.
+ Returns ASN1_OVERRUN if the encoded length exceeds
+ the bounds of *buf */
+
+
+/* asn1_error_code asn1_decode_structure_type(asn1buf *buf,
+ krb5_structure *val); */
+/* requires *buf is allocated, *buf's current position points to the
+ beginning of an encoding (<id> <len> <contents>),
+ *val is allocated
+ Assumes that *val is a freshly-allocated structure (i.e.
+ does not attempt to clean up or free *val).
+ effects Decodes the encoding in *buf, returning the result in *val.
+ Returns ASN1_BAD_ID if the encoded id does not
+ indicate the proper type.
+ Returns ASN1_OVERRUN if the encoded length exceeds
+ the bounds of *buf */
+
+/* asn1_error_code asn1_decode_array_type(asn1buf *buf, krb5_scalar ***val); */
+/* requires *buf is allocated, *buf's current position points to the
+ beginning of an encoding (<id> <len> <contents>)
+ Assumes that *val is empty (i.e. does not attempt to
+ clean up or free *val).
+ effects Decodes the encoding in *buf, returning the result in *val.
+ Returns ASN1_BAD_ID if the encoded id does not
+ indicate the proper type.
+ Returns ASN1_OVERRUN if the encoded length exceeds
+ the bounds of *buf */
+
+/* scalars */
+asn1_error_code asn1_decode_int
+ PROTOTYPE((asn1buf *buf, int *val));
+asn1_error_code asn1_decode_int32
+ PROTOTYPE((asn1buf *buf, krb5_int32 *val));
+asn1_error_code asn1_decode_kvno
+ PROTOTYPE((asn1buf *buf, krb5_kvno *val));
+asn1_error_code asn1_decode_keytype
+ PROTOTYPE((asn1buf *buf, krb5_keytype *val));
+asn1_error_code asn1_decode_msgtype
+ PROTOTYPE((asn1buf *buf, krb5_msgtype *val));
+asn1_error_code asn1_decode_cksumtype
+ PROTOTYPE((asn1buf *buf, krb5_cksumtype *val));
+asn1_error_code asn1_decode_enctype
+ PROTOTYPE((asn1buf *buf, krb5_enctype *val));
+asn1_error_code asn1_decode_kvno
+ PROTOTYPE((asn1buf *buf, krb5_kvno *val));
+asn1_error_code asn1_decode_octet
+ PROTOTYPE((asn1buf *buf, krb5_octet *val));
+asn1_error_code asn1_decode_addrtype
+ PROTOTYPE((asn1buf *buf, krb5_addrtype *val));
+asn1_error_code asn1_decode_authdatatype
+ PROTOTYPE((asn1buf *buf, krb5_authdatatype *val));
+asn1_error_code asn1_decode_ui_2
+ PROTOTYPE((asn1buf *buf, krb5_ui_2 *val));
+asn1_error_code asn1_decode_ui_4
+ PROTOTYPE((asn1buf *buf, krb5_ui_4 *val));
+asn1_error_code asn1_decode_kerberos_time
+ PROTOTYPE((asn1buf *buf, krb5_timestamp *val));
+
+/* structures */
+asn1_error_code asn1_decode_realm
+ PROTOTYPE((asn1buf *buf, krb5_principal *val));
+asn1_error_code asn1_decode_principal_name
+ PROTOTYPE((asn1buf *buf, krb5_principal *val));
+asn1_error_code asn1_decode_checksum
+ PROTOTYPE((asn1buf *buf, krb5_checksum *val));
+asn1_error_code asn1_decode_encryption_key
+ PROTOTYPE((asn1buf *buf, krb5_keyblock *val));
+asn1_error_code asn1_decode_encrypted_data
+ PROTOTYPE((asn1buf *buf, krb5_enc_data *val));
+asn1_error_code asn1_decode_ticket_flags
+ PROTOTYPE((asn1buf *buf, krb5_flags *val));
+asn1_error_code asn1_decode_transited_encoding
+ PROTOTYPE((asn1buf *buf, krb5_transited *val));
+asn1_error_code asn1_decode_enc_kdc_rep_part
+ PROTOTYPE((asn1buf *buf, krb5_enc_kdc_rep_part *val));
+asn1_error_code asn1_decode_krb5_flags
+ PROTOTYPE((asn1buf *buf, krb5_flags *val));
+asn1_error_code asn1_decode_ap_options
+ PROTOTYPE((asn1buf *buf, krb5_flags *val));
+asn1_error_code asn1_decode_kdc_options
+ PROTOTYPE((asn1buf *buf, krb5_flags *val));
+asn1_error_code asn1_decode_ticket
+ PROTOTYPE((asn1buf *buf, krb5_ticket *val));
+asn1_error_code asn1_decode_kdc_req
+ PROTOTYPE((asn1buf *buf, krb5_kdc_req *val));
+asn1_error_code asn1_decode_kdc_req_body
+ PROTOTYPE((asn1buf *buf, krb5_kdc_req *val));
+asn1_error_code asn1_decode_krb_safe_body
+ PROTOTYPE((asn1buf *buf, krb5_safe *val));
+asn1_error_code asn1_decode_host_address
+ PROTOTYPE((asn1buf *buf, krb5_address *val));
+asn1_error_code asn1_decode_kdc_rep
+ PROTOTYPE((asn1buf *buf, krb5_kdc_rep *val));
+asn1_error_code asn1_decode_krb_safe_body
+ PROTOTYPE((asn1buf *buf, krb5_safe *val));
+asn1_error_code asn1_decode_last_req_entry
+ PROTOTYPE((asn1buf *buf, krb5_last_req_entry *val));
+asn1_error_code asn1_decode_authdata_elt
+ PROTOTYPE((asn1buf *buf, krb5_authdata *val));
+asn1_error_code asn1_decode_krb_cred_info
+ PROTOTYPE((asn1buf *buf, krb5_cred_info *val));
+asn1_error_code asn1_decode_pa_data
+ PROTOTYPE((asn1buf *buf, krb5_pa_data *val));
+
+/* arrays */
+asn1_error_code asn1_decode_authorization_data
+ PROTOTYPE((asn1buf *buf, krb5_authdata ***val));
+asn1_error_code asn1_decode_host_addresses
+ PROTOTYPE((asn1buf *buf, krb5_address ***val));
+asn1_error_code asn1_decode_sequence_of_ticket
+ PROTOTYPE((asn1buf *buf, krb5_ticket ***val));
+asn1_error_code asn1_decode_sequence_of_krb_cred_info
+ PROTOTYPE((asn1buf *buf, krb5_cred_info ***val));
+asn1_error_code asn1_decode_sequence_of_pa_data
+ PROTOTYPE((asn1buf *buf, krb5_pa_data ***val));
+asn1_error_code asn1_decode_last_req
+ PROTOTYPE((asn1buf *buf, krb5_last_req_entry ***val));
+
+asn1_error_code asn1_decode_sequence_of_enctype
+ PROTOTYPE((asn1buf *buf, int *num, krb5_enctype **val));
+
+#endif
--- /dev/null
+/* ASN.1 primitive encoders */
+
+#include "asn1_encode.h"
+#include "asn1_make.h"
+
+asn1_error_code asn1_encode_integer(DECLARG(asn1buf *, buf),
+ DECLARG(const long , val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const long , val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length = 0, partlen;
+ long valcopy;
+ int digit;
+
+ valcopy = val;
+ do {
+ digit = valcopy&0xFF;
+ retval = asn1buf_insert_octet(buf,digit);
+ if(retval) return retval;
+ length++;
+ valcopy = valcopy >> 8;
+ } while (valcopy != 0 && valcopy != ~0);
+
+ if((val > 0) && ((digit&0x80) == 0x80)) { /* make sure the high bit is */
+ retval = asn1buf_insert_octet(buf,0); /* of the proper signed-ness */
+ if(retval) return retval;
+ length++;
+ }else if((val < 0) && ((digit&0x80) != 0x80)){
+ retval = asn1buf_insert_octet(buf,0xFF);
+ if(retval) return retval;
+ length++;
+ }
+
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_INTEGER,length, &partlen);
+ if(retval) return retval;
+ length += partlen;
+
+ *retlen = length;
+ return 0;
+}
+
+asn1_error_code asn1_encode_unsigned_integer(DECLARG(asn1buf *, buf),
+ DECLARG(const unsigned long , val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const unsigned long , val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length = 0, partlen;
+ unsigned long valcopy;
+ int digit;
+
+ valcopy = val;
+ do {
+ digit = valcopy&0xFF;
+ retval = asn1buf_insert_octet(buf,digit);
+ if(retval) return retval;
+ length++;
+ valcopy = valcopy >> 8;
+ } while (valcopy != 0 && valcopy != ~0);
+
+ if(digit&0x80) { /* make sure the high bit is */
+ retval = asn1buf_insert_octet(buf,0); /* of the proper signed-ness */
+ if(retval) return retval;
+ length++;
+ }
+
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_INTEGER,length, &partlen);
+ if(retval) return retval;
+ length += partlen;
+
+ *retlen = length;
+ return 0;
+}
+
+asn1_error_code asn1_encode_octetstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const asn1_octet *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const asn1_octet *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_insert_octetstring(buf,len,val);
+ if(retval) return retval;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_OCTETSTRING,len,&length);
+ if(retval) return retval;
+
+ *retlen = len + length;
+ return 0;
+}
+
+asn1_error_code asn1_encode_charstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const char *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const char *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_insert_charstring(buf,len,val);
+ if(retval) return retval;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_OCTETSTRING,len,&length);
+ if(retval) return retval;
+
+ *retlen = len + length;
+ return 0;
+}
+
+asn1_encode_null(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+
+ retval = asn1buf_insert_octet(buf,0x00);
+ if(retval) return retval;
+ retval = asn1buf_insert_octet(buf,0x05);
+ if(retval) return retval;
+
+ *retlen = 2;
+ return 0;
+}
+
+asn1_error_code asn1_encode_printablestring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const char *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const char *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_insert_charstring(buf,len,val);
+ if(retval) return retval;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_PRINTABLESTRING,len, &length);
+ if(retval) return retval;
+
+ *retlen = len + length;
+ return 0;
+}
+
+asn1_error_code asn1_encode_ia5string(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const char *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const char *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_insert_charstring(buf,len,val);
+ if(retval) return retval;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_IA5STRING,len, &length);
+ if(retval) return retval;
+
+ *retlen = len + length;
+ return 0;
+}
+
+asn1_error_code asn1_encode_generaltime(DECLARG(asn1buf *, buf),
+ DECLARG(const time_t , val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const time_t , val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ struct tm *time = gmtime(&val);
+ char s[16];
+ int length, sum=0;
+
+ /* Time encoding: YYYYMMDDhhmmssZ */
+ if(!strftime(s,16,"%Y%m%d%H%M%SZ",time)) return ASN1_BAD_TIMEFORMAT;
+ retval = asn1buf_insert_charstring(buf,15,s);
+ if(retval) return retval;
+ sum = 15;
+
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_GENERALTIME,sum,&length);
+ if(retval) return retval;
+ sum += length;
+
+ *retlen = sum;
+ return 0;
+}
+
+asn1_error_code asn1_encode_generalstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const char *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const char *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_insert_charstring(buf,len,val);
+ if(retval) return retval;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_GENERALSTRING,len,
+ &length);
+ if(retval) return retval;
+
+ *retlen = len + length;
+ return 0;
+}
--- /dev/null
+#ifndef __ASN1_ENCODE_H__
+#define __ASN1_ENCODE_H__
+
+#include <krb5/krb5.h>
+#include <time.h>
+#include "krbasn1.h"
+#include "asn1buf.h"
+
+/*
+ Overview
+
+ Each of these procedures inserts the encoding of an ASN.1
+ primitive in a coding buffer.
+
+ Operations
+
+ asn1_encode_integer
+ asn1_encode_octetstring
+ asn1_encode_null
+ asn1_encode_printablestring
+ asn1_encode_ia5string
+ asn1_encode_generaltime
+ asn1_encode_generalstring
+*/
+
+asn1_error_code asn1_encode_integer
+ PROTOTYPE((asn1buf *buf, const long val, int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_unsigned_integer
+ PROTOTYPE((asn1buf *buf, const unsigned long val, int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_octetstring
+ PROTOTYPE((asn1buf *buf,
+ const int len, const asn1_octet *val,
+ int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_charstring
+ PROTOTYPE((asn1buf *buf,
+ const int len, const char *val,
+ int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_null
+ PROTOTYPE((asn1buf *buf, int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of NULL into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_printablestring
+ PROTOTYPE((asn1buf *buf,
+ const int len, const char *val,
+ int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_ia5string
+ PROTOTYPE((asn1buf *buf,
+ const int len, const char *val,
+ int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+asn1_error_code asn1_encode_generaltime
+ PROTOTYPE((asn1buf *buf, const time_t val, int *retlen));
+/* requires *buf is allocated
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer.
+ Note: The encoding of GeneralizedTime is YYYYMMDDhhmmZ */
+
+asn1_error_code asn1_encode_generalstring
+ PROTOTYPE((asn1buf *buf,
+ const int len, const char *val,
+ int *retlen));
+/* requires *buf is allocated, val has a length of len characters
+ modifies *buf, *retlen
+ effects Inserts the encoding of val into *buf and returns
+ the length of the encoding in *retlen.
+ Returns ENOMEM to signal an unsuccesful attempt
+ to expand the buffer. */
+
+#endif
--- /dev/null
+#include "asn1_encode_k.h"
+#include "krb5_encode.h"
+#include "asn1_make.h"
+#include "asn1_encode.h"
+
+/**** asn1 macros ****/
+#if 0
+ How to write an asn1 encoder function using these macros:
+
+ asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf,
+ const krb5_type *val,
+ int *retlen)
+ {
+ asn1_setup();
+
+ asn1_addfield(val->last_field, n, asn1_type);
+ asn1_addfield(rep->next_to_last_field, n-1, asn1_type);
+ ...
+
+ /* for OPTIONAL fields */
+ if(rep->field_i == should_not_be_omitted)
+ asn1_addfield(rep->field_i, i, asn1_type);
+
+ /* for string fields (these encoders take an additional argument,
+ the length of the string) */
+ addlenfield(rep->field_length, rep->field, i-1, asn1_type);
+
+ /* if you really have to do things yourself... */
+ retval = asn1_encode_asn1_type(buf,rep->field,&length);
+ if(retval) return retval;
+ sum += length;
+ retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length,
+ &length);
+ if(retval) return retval;
+ sum += length;
+
+ ...
+ asn1_addfield(rep->second_field, 1, asn1_type);
+ asn1_addfield(rep->first_field, 0, asn1_type);
+ asn1_makeseq();
+
+ asn1_cleanup();
+ }
+#endif
+
+/* setup() -- create and initialize bookkeeping variables
+ retval: stores error codes returned from subroutines
+ length: length of the most-recently produced encoding
+ sum: cumulative length of the entire encoding */
+#define asn1_setup()\
+ asn1_error_code retval;\
+ int length, sum=0
+
+/* asn1_addfield -- add a field, or component, to the encoding */
+#define asn1_addfield(value,tag,encoder)\
+{ retval = encoder(buf,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* asn1_addlenfield -- add a field whose length must be separately specified */
+#define asn1_addlenfield(len,value,tag,encoder)\
+{ retval = encoder(buf,len,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* form a sequence (by adding a sequence header to the current encoding) */
+#define asn1_makeseq()\
+ retval = asn1_make_sequence(buf,sum,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length
+
+/* add an APPLICATION class tag to the current encoding */
+#define asn1_apptag(num)\
+ retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length
+
+/* produce the final output and clean up the workspace */
+#define asn1_cleanup()\
+ *retlen = sum;\
+ return 0
+
+asn1_error_code asn1_encode_ui_4(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_ui_4, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_ui_4, val)
+ OLDDECLARG(int *, retlen)
+{
+ return asn1_encode_unsigned_integer(buf,val,retlen);
+}
+
+
+asn1_error_code asn1_encode_msgtype(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_msgtype, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_msgtype, val)
+ OLDDECLARG(int *, retlen)
+{
+ switch(val){
+ case KRB5_AS_REQ:
+ return asn1_encode_integer(buf,ASN1_KRB_AS_REQ,retlen);
+ case KRB5_AS_REP:
+ return asn1_encode_integer(buf,ASN1_KRB_AS_REP,retlen);
+ case KRB5_TGS_REQ:
+ return asn1_encode_integer(buf,ASN1_KRB_TGS_REQ,retlen);
+ case KRB5_TGS_REP:
+ return asn1_encode_integer(buf,ASN1_KRB_TGS_REP,retlen);
+ case KRB5_AP_REQ:
+ return asn1_encode_integer(buf,ASN1_KRB_AP_REQ,retlen);
+ case KRB5_AP_REP:
+ return asn1_encode_integer(buf,ASN1_KRB_AP_REP,retlen);
+ case KRB5_SAFE:
+ return asn1_encode_integer(buf,ASN1_KRB_SAFE,retlen);
+ case KRB5_PRIV:
+ return asn1_encode_integer(buf,ASN1_KRB_PRIV,retlen);
+ case KRB5_CRED:
+ return asn1_encode_integer(buf,ASN1_KRB_CRED,retlen);
+ case KRB5_ERROR:
+ return asn1_encode_integer(buf,ASN1_KRB_ERROR,retlen);
+ default:
+ return KRB5_BADMSGTYPE;
+ }
+}
+
+asn1_error_code asn1_encode_realm(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_principal, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_principal, val)
+ OLDDECLARG(int *, retlen)
+{
+ if(val == NULL || val->realm.data == NULL) return ASN1_MISSING_FIELD;
+ return asn1_encode_generalstring(buf,val->realm.length,val->realm.data,
+ retlen);
+}
+
+asn1_error_code asn1_encode_principal_name(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_principal, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_principal, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int n;
+
+ if(val == NULL || val->data == NULL) return ASN1_MISSING_FIELD;
+
+ for(n = (val->length)-1; n >= 0; n--){
+ if(val->data[n].data == NULL) return ASN1_MISSING_FIELD;
+ retval = asn1_encode_generalstring(buf,
+ (val->data)[n].length,
+ (val->data)[n].data,
+ &length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,1,sum,&length);
+ if(retval) return retval;
+ sum += length;
+
+ asn1_addfield(val->type,0,asn1_encode_integer);
+
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kerberos_time(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_timestamp, val),
+ DECLARG(int *, retlen))
+
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_timestamp, val)
+ OLDDECLARG(int *, retlen)
+
+{
+ return asn1_encode_generaltime(buf,val,retlen);
+}
+
+asn1_error_code asn1_encode_host_address(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_address *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_address *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring);
+ asn1_addfield(val->addrtype,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_host_addresses(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_address **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_address **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++); /* go to end of array */
+ for(i--; i>=0; i--){
+ retval = asn1_encode_host_address(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_encrypted_data(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_enc_data *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_enc_data *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->ciphertext.data == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_encode_charstring);
+ if(val->kvno)
+ asn1_addfield(val->kvno,1,asn1_encode_integer);
+ asn1_addfield(val->etype,0,asn1_encode_integer);
+
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_krb5_flags(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_flags, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_flags, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ krb5_flags valcopy = val;
+ int i;
+
+ for(i=0; i<4; i++){
+ retval = asn1buf_insert_octet(buf,valcopy&0xFF);
+ if(retval) return retval;
+ valcopy >>= 8;
+ }
+ retval = asn1buf_insert_octet(buf,0); /* 0 padding bits */
+ if(retval) return retval;
+ sum = 5;
+
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_BITSTRING,sum,
+ &length);
+ if(retval) return retval;
+ sum += length;
+
+ *retlen = sum;
+ return 0;
+}
+
+asn1_error_code asn1_encode_ap_options(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_flags, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_flags, val)
+ OLDDECLARG(int *, retlen)
+{
+ return asn1_encode_krb5_flags(buf,val,retlen);
+}
+
+asn1_error_code asn1_encode_ticket_flags(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_flags, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_flags, val)
+ OLDDECLARG(int *, retlen)
+{
+ return asn1_encode_krb5_flags(buf,val,retlen);
+}
+
+asn1_error_code asn1_encode_kdc_options(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_flags, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_flags, val)
+ OLDDECLARG(int *, retlen)
+{
+ return asn1_encode_krb5_flags(buf,val,retlen);
+}
+
+asn1_error_code asn1_encode_authorization_data(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_authdata **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_authdata **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++); /* get to the end of the array */
+ for(i--; i>=0; i--){
+ retval = asn1_encode_krb5_authdata_elt(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_krb5_authdata_elt(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_authdata *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_authdata *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD;
+
+ /* ad-data[1] OCTET STRING */
+ asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring);
+ /* ad-type[0] INTEGER */
+ asn1_addfield(val->ad_type,0,asn1_encode_integer);
+ /* SEQUENCE */
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kdc_rep(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_kdc_rep *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_kdc_rep *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addfield(&(val->enc_part),6,asn1_encode_encrypted_data);
+ asn1_addfield(val->ticket,5,asn1_encode_ticket);
+ asn1_addfield(val->client,4,asn1_encode_principal_name);
+ asn1_addfield(val->client,3,asn1_encode_realm);
+ if(val->padata != NULL && val->padata[0] != NULL)
+ asn1_addfield((const krb5_pa_data**)val->padata,2,asn1_encode_sequence_of_pa_data);
+ asn1_addfield(val->msg_type,1,asn1_encode_msgtype);
+ asn1_addfield(KVNO,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_enc_kdc_rep_part(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_enc_kdc_rep_part *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_enc_kdc_rep_part *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ /* caddr[11] HostAddresses OPTIONAL */
+ if(val->caddrs != NULL && val->caddrs[0] != NULL)
+ asn1_addfield((const krb5_address**)(val->caddrs),11,asn1_encode_host_addresses);
+
+ /* sname[10] PrincipalName */
+ asn1_addfield(val->server,10,asn1_encode_principal_name);
+
+ /* srealm[9] Realm */
+ asn1_addfield(val->server,9,asn1_encode_realm);
+
+ /* renew-till[8] KerberosTime OPTIONAL */
+ if(val->flags & TKT_FLG_RENEWABLE)
+ asn1_addfield(val->times.renew_till,8,asn1_encode_kerberos_time);
+
+ /* endtime[7] KerberosTime */
+ asn1_addfield(val->times.endtime,7,asn1_encode_kerberos_time);
+
+ /* starttime[6] KerberosTime OPTIONAL */
+ if(val->times.starttime)
+ asn1_addfield(val->times.starttime,6,asn1_encode_kerberos_time);
+
+ /* authtime[5] KerberosTime */
+ asn1_addfield(val->times.authtime,5,asn1_encode_kerberos_time);
+
+ /* flags[4] TicketFlags */
+ asn1_addfield(val->flags,4,asn1_encode_ticket_flags);
+
+ /* key-expiration[3] KerberosTime OPTIONAL */
+ if(val->key_exp)
+ asn1_addfield(val->key_exp,3,asn1_encode_kerberos_time);
+
+ /* nonce[2] INTEGER */
+ asn1_addfield(val->nonce,2,asn1_encode_integer);
+
+ /* last-req[1] LastReq */
+ asn1_addfield((const krb5_last_req_entry**)val->last_req,1,asn1_encode_last_req);
+
+ /* key[0] EncryptionKey */
+ asn1_addfield(val->session,0,asn1_encode_encryption_key);
+
+ /* EncKDCRepPart ::= SEQUENCE */
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kdc_req_body(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_kdc_req *, rep),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_kdc_req *, rep)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(rep == NULL) return ASN1_MISSING_FIELD;
+
+ /* additional-tickets[11] SEQUENCE OF Ticket OPTIONAL */
+ if(rep->second_ticket != NULL && rep->second_ticket[0] != NULL)
+ asn1_addfield((const krb5_ticket**)rep->second_ticket,
+ 11,asn1_encode_sequence_of_ticket);
+
+ /* enc-authorization-data[10] EncryptedData OPTIONAL, */
+ /* -- Encrypted AuthorizationData encoding */
+ if(rep->authorization_data.ciphertext.data != NULL)
+ asn1_addfield(&(rep->authorization_data),10,asn1_encode_encrypted_data);
+
+ /* addresses[9] HostAddresses OPTIONAL, */
+ if(rep->addresses != NULL && rep->addresses[0] != NULL)
+ asn1_addfield((const krb5_address**)rep->addresses,9,asn1_encode_host_addresses);
+
+ /* etype[8] SEQUENCE OF INTEGER, -- EncryptionType, */
+ /* -- in preference order */
+ asn1_addlenfield(rep->netypes,rep->etype,8,asn1_encode_sequence_of_enctype);
+
+ /* nonce[7] INTEGER, */
+ asn1_addfield(rep->nonce,7,asn1_encode_integer);
+
+ /* rtime[6] KerberosTime OPTIONAL, */
+ if(rep->rtime)
+ asn1_addfield(rep->rtime,6,asn1_encode_kerberos_time);
+
+ /* till[5] KerberosTime, */
+ asn1_addfield(rep->till,5,asn1_encode_kerberos_time);
+
+ /* from[4] KerberosTime OPTIONAL, */
+ if(rep->from)
+ asn1_addfield(rep->from,4,asn1_encode_kerberos_time);
+
+ /* sname[3] PrincipalName OPTIONAL, */
+ if(rep->server != NULL)
+ asn1_addfield(rep->server,3,asn1_encode_principal_name);
+
+ /* realm[2] Realm, -- Server's realm */
+ /* -- Also client's in AS-REQ */
+ if(rep->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY){
+ if(rep->second_ticket != NULL && rep->second_ticket[0] != NULL){
+ asn1_addfield(rep->second_ticket[0]->server,2,asn1_encode_realm)
+ } else return ASN1_MISSING_FIELD;
+ }else if(rep->server != NULL){
+ asn1_addfield(rep->server,2,asn1_encode_realm);
+ }else return ASN1_MISSING_FIELD;
+
+ /* cname[1] PrincipalName OPTIONAL, */
+ /* -- Used only in AS-REQ */
+ if(rep->client != NULL)
+ asn1_addfield(rep->client,1,asn1_encode_principal_name);
+
+ /* kdc-options[0] KDCOptions, */
+ asn1_addfield(rep->kdc_options,0,asn1_encode_kdc_options);
+
+ /* KDC-REQ-BODY ::= SEQUENCE */
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_encryption_key(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_keyblock *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_keyblock *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring);
+ asn1_addfield(val->keytype,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_checksum(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_checksum *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_checksum *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring);
+ asn1_addfield(val->checksum_type,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_transited_encoding(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_transited *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_transited *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->tr_contents.data == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->tr_contents.length,val->tr_contents.data,
+ 1,asn1_encode_charstring);
+ asn1_addfield(val->tr_type,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_last_req(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_last_req_entry **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_last_req_entry **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++); /* go to end of array */
+ for(i--; i>=0; i--){
+ retval = asn1_encode_last_req_entry(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_last_req_entry(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_last_req_entry *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_last_req_entry *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addfield(val->value,1,asn1_encode_kerberos_time);
+ asn1_addfield(val->lr_type,0,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_pa_data(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_pa_data **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_pa_data **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_pa_data(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_data(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_pa_data *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_pa_data *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addlenfield(val->length,val->contents,2,asn1_encode_octetstring);
+ asn1_addfield(val->pa_type,1,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_ticket(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_ticket **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_ticket **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_ticket(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_ticket(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_ticket *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_ticket *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addfield(&(val->enc_part),3,asn1_encode_encrypted_data);
+ asn1_addfield(val->server,2,asn1_encode_principal_name);
+ asn1_addfield(val->server,1,asn1_encode_realm);
+ asn1_addfield(KVNO,0,asn1_encode_integer);
+ asn1_makeseq();
+ asn1_apptag(1);
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_enctype(DECLARG(asn1buf *, buf),
+ DECLARG(const int, len),
+ DECLARG(const krb5_enctype *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int, len)
+ OLDDECLARG(const krb5_enctype *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=len-1; i>=0; i--){
+ retval = asn1_encode_integer(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kdc_req(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_kdc_req *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_kdc_req *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ asn1_addfield(val,4,asn1_encode_kdc_req_body);
+ if(val->padata != NULL && val->padata[0] != NULL)
+ asn1_addfield((const krb5_pa_data**)val->padata,3,asn1_encode_sequence_of_pa_data);
+ if(val->msg_type == KRB5_AS_REQ){
+ asn1_addfield(ASN1_KRB_AS_REQ,2,asn1_encode_integer);
+ }else if(val->msg_type == KRB5_TGS_REQ){
+ asn1_addfield(ASN1_KRB_TGS_REQ,2,asn1_encode_integer);
+ }else return KRB5_BADMSGTYPE;
+ asn1_addfield(KVNO,1,asn1_encode_integer);
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_krb_safe_body(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_safe *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_safe *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ if(val->r_address != NULL)
+ asn1_addfield(val->r_address,5,asn1_encode_host_address);
+ asn1_addfield(val->s_address,4,asn1_encode_host_address);
+ if(val->seq_number)
+ asn1_addfield(val->seq_number,3,asn1_encode_integer);
+ if(val->timestamp){
+ asn1_addfield(val->usec,2,asn1_encode_integer);
+ asn1_addfield(val->timestamp,1,asn1_encode_kerberos_time);
+ }
+ if(val->user_data.data == NULL) return ASN1_MISSING_FIELD;
+ asn1_addlenfield(val->user_data.length,val->user_data.data,0,asn1_encode_charstring)
+;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_krb_cred_info(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_cred_info **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_cred_info **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_krb_cred_info(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_krb_cred_info(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_cred_info *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_cred_info *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+
+ if(val == NULL) return ASN1_MISSING_FIELD;
+
+ if(val->caddrs != NULL && val->caddrs[0] != NULL)
+ asn1_addfield((const krb5_address**)val->caddrs,10,asn1_encode_host_addresses);
+ if(val->server != NULL){
+ asn1_addfield(val->server,9,asn1_encode_principal_name);
+ asn1_addfield(val->server,8,asn1_encode_realm);
+ }
+ if(val->times.renew_till)
+ asn1_addfield(val->times.renew_till,7,asn1_encode_kerberos_time);
+ if(val->times.endtime)
+ asn1_addfield(val->times.endtime,6,asn1_encode_kerberos_time);
+ if(val->times.starttime)
+ asn1_addfield(val->times.starttime,5,asn1_encode_kerberos_time);
+ if(val->times.authtime)
+ asn1_addfield(val->times.authtime,4,asn1_encode_kerberos_time);
+ if(val->flags)
+ asn1_addfield(val->flags,3,asn1_encode_ticket_flags);
+ if(val->client != NULL){
+ asn1_addfield(val->client,2,asn1_encode_principal_name);
+ asn1_addfield(val->client,1,asn1_encode_realm);
+ }
+ asn1_addfield(val->session,0,asn1_encode_encryption_key);
+
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_passwdsequence(DECLARG(asn1buf *, buf),
+ DECLARG(const passwd_phrase_element **, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *,buf)
+ OLDDECLARG(const passwd_phrase_element **, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++); /* get to the end of the array */
+ for(i--; i>=0; i--){
+ retval = asn1_encode_passwdsequence(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_passwdsequence(DECLARG(asn1buf *, buf),
+ DECLARG(const passwd_phrase_element *, val),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *,buf)
+ OLDDECLARG(const passwd_phrase_element *, val)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_setup();
+ asn1_addlenfield(val->phrase->length,val->phrase->data,1,asn1_encode_charstring);
+ asn1_addlenfield(val->passwd->length,val->passwd->data,0,asn1_encode_charstring);
+ asn1_makeseq();
+ asn1_cleanup();
+}
--- /dev/null
+#ifndef __ASN1_ENCODE_KRB5_H__
+#define __ASN1_ENCODE_KRB5_H__
+
+#include <krb5/krb5.h>
+#include <stdlib.h>
+#include "asn1buf.h"
+
+/*
+ Overview
+
+ Encoding routines for various ASN.1 "substructures" as defined in
+ the krb5 protocol.
+
+ Operations
+
+ asn1_encode_krb5_flags
+ asn1_encode_ap_options
+ asn1_encode_ticket_flags
+ asn1_encode_kdc_options
+ asn1_encode_kerberos_time
+
+ asn1_encode_realm
+ asn1_encode_principal_name
+ asn1_encode_encrypted_data
+ asn1_encode_authorization_data
+ asn1_encode_krb5_authdata_elt
+ asn1_encode_kdc_rep
+ asn1_encode_enc_kdc_rep_part
+ asn1_encode_ticket
+ asn1_encode_encryption_key
+ asn1_encode_checksum
+ asn1_encode_host_address
+ asn1_encode_transited_encoding
+ asn1_encode_enc_kdc_rep_part
+ asn1_encode_kdc_req
+ asn1_encode_kdc_req_body
+ asn1_encode_krb_safe_body
+ asn1_encode_krb_cred_info
+ asn1_encode_last_req_entry
+ asn1_encode_pa_data
+
+ asn1_encode_host_addresses
+ asn1_encode_last_req
+ asn1_encode_sequence_of_pa_data
+ asn1_encode_sequence_of_ticket
+ asn1_encode_sequence_of_enctype
+ asn1_encode_sequence_of_krb_cred_info
+*/
+
+/*
+**** for simple val's ****
+asn1_error_code asn1_encode_asn1_type(asn1buf *buf,
+ const krb5_type val,
+ int *retlen);
+ requires *buf is allocated
+ effects Inserts the encoding of val into *buf and
+ returns the length of this encoding in *retlen.
+ Returns ASN1_MISSING_FIELD if a required field is empty in val.
+ Returns ENOMEM if memory runs out.
+
+**** for struct val's ****
+asn1_error_code asn1_encode_asn1_type(asn1buf *buf,
+ const krb5_type *val,
+ int *retlen);
+ requires *buf is allocated
+ effects Inserts the encoding of *val into *buf and
+ returns the length of this encoding in *retlen.
+ Returns ASN1_MISSING_FIELD if a required field is empty in val.
+ Returns ENOMEM if memory runs out.
+
+**** for array val's ****
+asn1_error_code asn1_encode_asn1_type(asn1buf *buf,
+ const krb5_type **val,
+ int *retlen);
+ requires *buf is allocated, **val != NULL, *val[0] != NULL,
+ **val is a NULL-terminated array of pointers to krb5_type
+ effects Inserts the encoding of **val into *buf and
+ returns the length of this encoding in *retlen.
+ Returns ASN1_MISSING_FIELD if a required field is empty in val.
+ Returns ENOMEM if memory runs out.
+*/
+
+asn1_error_code asn1_encode_ui_4 PROTOTYPE((asn1buf *buf,
+ const /*krb5_ui_4*/int val,
+ int *retlen));
+
+asn1_error_code asn1_encode_msgtype PROTOTYPE((asn1buf *buf,
+ const /*krb5_msgtype*/int val,
+ int *retlen));
+
+asn1_error_code asn1_encode_realm
+ PROTOTYPE((asn1buf *buf, const krb5_principal val, int *retlen));
+
+asn1_error_code asn1_encode_principal_name
+ PROTOTYPE((asn1buf *buf, const krb5_principal val, int *retlen));
+
+asn1_error_code asn1_encode_encrypted_data
+ PROTOTYPE((asn1buf *buf, const krb5_enc_data *val, int *retlen));
+
+asn1_error_code asn1_encode_krb5_flags
+ PROTOTYPE((asn1buf *buf, const krb5_flags val, int *retlen));
+
+asn1_error_code asn1_encode_ap_options
+ PROTOTYPE((asn1buf *buf, const krb5_flags val, int *retlen));
+
+asn1_error_code asn1_encode_ticket_flags
+ PROTOTYPE((asn1buf *buf, const krb5_flags val, int *retlen));
+
+asn1_error_code asn1_encode_kdc_options
+ PROTOTYPE((asn1buf *buf, const krb5_flags val, int *retlen));
+
+asn1_error_code asn1_encode_authorization_data
+ PROTOTYPE((asn1buf *buf, const krb5_authdata **val, int *retlen));
+
+asn1_error_code asn1_encode_krb5_authdata_elt
+ PROTOTYPE((asn1buf *buf, const krb5_authdata *val, int *retlen));
+
+asn1_error_code asn1_encode_kdc_rep
+ PROTOTYPE((asn1buf *buf, const krb5_kdc_rep *val, int *retlen));
+
+asn1_error_code asn1_encode_enc_kdc_rep_part
+ PROTOTYPE((asn1buf *buf, const krb5_enc_kdc_rep_part *val,
+ int *retlen));
+
+asn1_error_code asn1_encode_ticket
+ PROTOTYPE((asn1buf *buf, const krb5_ticket *val, int *retlen));
+
+asn1_error_code asn1_encode_encryption_key
+ PROTOTYPE((asn1buf *buf, const krb5_keyblock *val, int *retlen));
+
+asn1_error_code asn1_encode_kerberos_time
+ PROTOTYPE((asn1buf *buf, const krb5_timestamp val, int *retlen));
+
+asn1_error_code asn1_encode_checksum
+ PROTOTYPE((asn1buf *buf, const krb5_checksum *val, int *retlen));
+
+asn1_error_code asn1_encode_host_address
+ PROTOTYPE((asn1buf *buf, const krb5_address *val, int *retlen));
+
+asn1_error_code asn1_encode_host_addresses
+ PROTOTYPE((asn1buf *buf, const krb5_address **val, int *retlen));
+
+asn1_error_code asn1_encode_transited_encoding
+ PROTOTYPE((asn1buf *buf, const krb5_transited *val, int *retlen));
+
+asn1_error_code asn1_encode_last_req
+ PROTOTYPE((asn1buf *buf, const krb5_last_req_entry **val,
+ int *retlen));
+
+asn1_error_code asn1_encode_enc_kdc_rep_part
+ PROTOTYPE((asn1buf *buf, const krb5_enc_kdc_rep_part *val,
+ int *retlen));
+
+asn1_error_code asn1_encode_sequence_of_pa_data
+ PROTOTYPE((asn1buf *buf, const krb5_pa_data **val, int *retlen));
+
+asn1_error_code asn1_encode_sequence_of_ticket
+ PROTOTYPE((asn1buf *buf, const krb5_ticket **val, int *retlen));
+
+asn1_error_code asn1_encode_sequence_of_enctype
+ PROTOTYPE((asn1buf *buf,
+ const int len, const krb5_enctype *val,
+ int *retlen));
+
+asn1_error_code asn1_encode_kdc_req
+ PROTOTYPE((asn1buf *buf,
+ const krb5_kdc_req *val,
+ int *retlen));
+
+asn1_error_code asn1_encode_kdc_req_body
+ PROTOTYPE((asn1buf *buf, const krb5_kdc_req *val, int *retlen));
+
+asn1_error_code asn1_encode_krb_safe_body
+ PROTOTYPE((asn1buf *buf, const krb5_safe *val, int *retlen));
+
+asn1_error_code asn1_encode_sequence_of_krb_cred_info
+ PROTOTYPE((asn1buf *buf, const krb5_cred_info **val, int *retlen));
+
+asn1_error_code asn1_encode_krb_cred_info
+ PROTOTYPE((asn1buf *buf, const krb5_cred_info *val, int *retlen));
+
+asn1_error_code asn1_encode_last_req_entry
+ PROTOTYPE((asn1buf *buf, const krb5_last_req_entry *val,
+ int *retlen));
+
+asn1_error_code asn1_encode_pa_data
+ PROTOTYPE((asn1buf *buf, const krb5_pa_data *val, int *retlen));
+
+asn1_error_code asn1_encode_passwdsequence
+ PROTOTYPE((asn1buf *buf, const passwd_phrase_element *val, int *retlen));
+
+asn1_error_code asn1_encode_sequence_of_passwdsequence
+ PROTOTYPE((asn1buf *buf, const passwd_phrase_element **val, int *retlen));
+
+#endif
--- /dev/null
+#include "asn1_get.h"
+
+asn1_error_code asn1_get_tag(DECLARG(asn1buf *, buf),
+ DECLARG(asn1_class *, class),
+ DECLARG(asn1_construction *, construction),
+ DECLARG(asn1_tagnum *, tagnum),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(asn1_class *, class)
+ OLDDECLARG(asn1_construction *, construction)
+ OLDDECLARG(asn1_tagnum *, tagnum)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+
+ if(asn1buf_remains(buf) <= 0){
+ *tagnum = ASN1_TAGNUM_CEILING;
+ return 0;
+ }
+ retval = asn1_get_id(buf,class,construction,tagnum);
+ if(retval) return retval;
+ retval = asn1_get_length(buf,retlen);
+ if(retval) return retval;
+ return 0;
+}
+
+asn1_error_code asn1_get_sequence(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ asn1_class class;
+ asn1_construction construction;
+ asn1_tagnum tagnum;
+
+ retval = asn1_get_tag(buf,&class,&construction,&tagnum,retlen);
+ if(retval) return retval;
+ if(retval) return (krb5_error_code)retval;
+ if(class != UNIVERSAL || construction != CONSTRUCTED ||
+ tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID;
+ return 0;
+}
+
+/****************************************************************/
+/* Private Procedures */
+
+asn1_error_code asn1_get_id(DECLARG(asn1buf *, buf),
+ DECLARG(asn1_class *, class),
+ DECLARG(asn1_construction *, construction),
+ DECLARG(asn1_tagnum *, tagnum))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(asn1_class *, class)
+ OLDDECLARG(asn1_construction *, construction)
+ OLDDECLARG(asn1_tagnum *, tagnum)
+{
+ asn1_error_code retval;
+ asn1_tagnum tn=0;
+ asn1_octet o;
+
+#define ASN1_CLASS_MASK 0xC0
+#define ASN1_CONSTRUCTION_MASK 0x20
+#define ASN1_TAG_NUMBER_MASK 0x1F
+
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+
+ if(class != NULL)
+ *class = (asn1_class)(o&ASN1_CLASS_MASK);
+ if(construction != NULL)
+ *construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK);
+ if((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){
+ /* low-tag-number form */
+ if(tagnum != NULL) *tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK);
+ }else{
+ /* high-tag-number form */
+ do{
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ tn = (tn<<7) + (asn1_tagnum)(o&0x7F);
+ }while(tn&0x80);
+ if(tagnum != NULL) *tagnum = tn;
+ }
+ return 0;
+}
+
+asn1_error_code asn1_get_length(DECLARG(asn1buf *, buf),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ asn1_octet o;
+
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ if((o&0x80) == 0){
+ if(retlen != NULL) *retlen = (int)(o&0x7F);
+ }else{
+ int num;
+ int len=0;
+
+ for(num = (int)(o&0x7F); num>0; num--){
+ retval = asn1buf_remove_octet(buf,&o);
+ if(retval) return retval;
+ len = (len<<8) + (int)o;
+ }
+ if(retlen != NULL) *retlen = len;
+ }
+ return 0;
+}
--- /dev/null
+#ifndef __ASN1_GET_H__
+#define __ASN1_GET_H__
+
+/* ASN.1 substructure decoding procedures */
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+#include "asn1buf.h"
+
+asn1_error_code asn1_get_tag
+ PROTOTYPE((asn1buf *buf,
+ asn1_class *class,
+ asn1_construction *construction,
+ asn1_tagnum *tagnum,
+ int *retlen));
+/* requires *buf is allocated
+ effects Decodes the tag in *buf. If class != NULL, returns
+ the class in *class. Similarly, the construction,
+ tag number, and length are returned in *construction,
+ *tagnum, and *retlen, respectively.
+ If *buf is empty to begin with,
+ *tagnum is set to ASN1_TAGNUM_CEILING.
+ Returns ASN1_OVERRUN if *buf is exhausted during the parse. */
+
+asn1_error_code asn1_get_sequence
+ PROTOTYPE((asn1buf *buf, int *retlen));
+/* requires *buf is allocated
+ effects Decodes a tag from *buf and returns ASN1_BAD_ID if it
+ doesn't have a sequence ID. If retlen != NULL, the
+ associated length is returned in *retlen. */
+
+/****************************************************************/
+/* Private Procedures */
+
+asn1_error_code asn1_get_id
+ PROTOTYPE((asn1buf *buf,
+ asn1_class *class,
+ asn1_construction *construction,
+ asn1_tagnum *tagnum));
+/* requires *buf is allocated
+ effects Decodes the group of identifier octets at *buf's
+ current position. If class != NULL, returns the class
+ in *class. Similarly, the construction and tag number
+ are returned in *construction and *tagnum, respectively.
+ Returns ASN1_OVERRUN if *buf is exhausted. */
+
+asn1_error_code asn1_get_length
+ PROTOTYPE((asn1buf *buf, int *retlen));
+/* requires *buf is allocated
+ effects Decodes the group of length octets at *buf's
+ current position. If retlen != NULL, the
+ length is returned in *retlen.
+ Returns ASN1_OVERRUN if *buf is exhausted. */
+
+#endif
--- /dev/null
+#include "asn1_make.h"
+
+asn1_error_code asn1_make_etag(DECLARG(asn1buf *, buf),
+ DECLARG(const asn1_class , class),
+ DECLARG(const asn1_tagnum , tagnum),
+ DECLARG(const int , in_len),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const asn1_class , class)
+ OLDDECLARG(const asn1_tagnum , tagnum)
+ OLDDECLARG(const int , in_len)
+ OLDDECLARG(int *, retlen)
+{
+ return asn1_make_tag(buf,class,CONSTRUCTED,tagnum,in_len,retlen);
+}
+
+asn1_error_code asn1_make_tag(DECLARG(asn1buf *, buf),
+ DECLARG(const asn1_class , class),
+ DECLARG(const asn1_construction , construction),
+ DECLARG(const asn1_tagnum , tagnum),
+ DECLARG(const int , in_len),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const asn1_class , class)
+ OLDDECLARG(const asn1_construction , construction)
+ OLDDECLARG(const asn1_tagnum , tagnum)
+ OLDDECLARG(const int , in_len)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int sumlen=0, length;
+
+ if(tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW;
+
+ retval = asn1_make_length(buf,in_len, &length);
+ if(retval) return retval;
+ sumlen += length;
+ retval = asn1_make_id(buf,class,construction,tagnum,&length);
+ if(retval) return retval;
+ sumlen += length;
+
+ *retlen = sumlen;
+ return 0;
+}
+
+asn1_error_code asn1_make_length(DECLARG(asn1buf *, buf),
+ DECLARG(const int , in_len),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , in_len)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+
+ if(in_len < 128){
+ retval = asn1buf_insert_octet(buf, (asn1_octet)(in_len&0x7F));
+ if(retval) return retval;
+ *retlen = 1;
+ }else{
+ int in_copy=in_len, length=0;
+
+ while(in_copy != 0){
+ retval = asn1buf_insert_octet(buf, (asn1_octet)(in_copy&0xFF));
+ if(retval) return retval;
+ in_copy = in_copy >> 8;
+ length++;
+ }
+ retval = asn1buf_insert_octet(buf, 0x80 | (asn1_octet)(length&0x7F));
+ if(retval) return retval;
+ length++;
+ *retlen = length;
+ }
+
+ return 0;
+}
+
+asn1_error_code asn1_make_id(DECLARG(asn1buf *, buf),
+ DECLARG(const asn1_class , class),
+ DECLARG(const asn1_construction , construction),
+ DECLARG(const asn1_tagnum , tagnum),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const asn1_class , class)
+ OLDDECLARG(const asn1_construction , construction)
+ OLDDECLARG(const asn1_tagnum , tagnum)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+
+ if(tagnum < 31) {
+ retval = asn1buf_insert_octet(buf, class | construction |
+ (asn1_octet)tagnum);
+ if(retval) return retval;
+ *retlen = 1;
+ }else{
+ asn1_tagnum tagcopy = tagnum;
+ int length = 0;
+
+ retval = asn1buf_insert_octet(buf, (asn1_octet)(tagcopy&0x7F));
+ if(retval) return retval;
+ tagcopy >>= 7;
+ length++;
+
+ for(; tagcopy != 0; tagcopy >>= 7){
+ retval = asn1buf_insert_octet(buf, 0x80 | (asn1_octet)(tagcopy&0x7F));
+ if(retval) return retval;
+ length++;
+ }
+
+ retval = asn1buf_insert_octet(buf, class | construction | 0x1F);
+ if(retval) return retval;
+ length++;
+ *retlen = length;
+ }
+
+ return 0;
+}
+
+asn1_error_code asn1_make_sequence(DECLARG(asn1buf *, buf),
+ DECLARG(const int , seq_len),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , seq_len)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int len, sum=0;
+
+ retval = asn1_make_length(buf,seq_len,&len);
+ if(retval) return retval;
+ sum += len;
+ retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SEQUENCE,&len);
+ if(retval) return retval;
+ sum += len;
+
+ *retlen = sum;
+ return 0;
+}
+
+asn1_error_code asn1_make_set(DECLARG(asn1buf *, buf),
+ DECLARG(const int , set_len),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , set_len)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+ int len, sum=0;
+
+ retval = asn1_make_length(buf,set_len,&len);
+ if(retval) return retval;
+ sum += len;
+ retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SET,&len);
+ if(retval) return retval;
+ sum += len;
+
+ *retlen = sum;
+ return 0;
+}
+
+asn1_error_code asn1_make_string(DECLARG(asn1buf *, buf),
+ DECLARG(const int , length),
+ DECLARG(const char *, string),
+ DECLARG(int *, retlen))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , length)
+ OLDDECLARG(const char *, string)
+ OLDDECLARG(int *, retlen)
+{
+ asn1_error_code retval;
+
+ retval = asn1buf_insert_charstring(buf,length,string);
+ if(retval) return retval;
+
+ *retlen = length;
+ return 0;
+}
--- /dev/null
+#ifndef __ASN1_MAKE_H__
+#define __ASN1_MAKE_H__
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+#include "asn1buf.h"
+
+/*
+ Overview
+
+ Each of these procedures constructs a subpart of an ASN.1
+ primitive in a coding buffer.
+
+ Operations
+
+ asn1_make_etag
+ asn1_make_sequence
+ asn1_make_set
+ asn1_make_tag
+ asn1_make_string
+*/
+
+asn1_error_code asn1_make_etag
+ PROTOTYPE((asn1buf *buf,
+ const asn1_class class,
+ const asn1_tagnum tagnum,
+ const int in_len,
+ int *retlen));
+/* requires *buf is allocated, in_len is the length of an ASN.1 encoding
+ which has just been inserted in *buf
+ modifies *buf, *retlen
+ effects Inserts an explicit tag with class = class, id# = tag
+ length = in_len into *buf.
+ Returns the length of this encoding in *retlen.
+ Returns ENOMEM if memory runs out. */
+
+asn1_error_code asn1_make_tag
+ PROTOTYPE((asn1buf *buf, const asn1_class class,
+ const asn1_construction construction,
+ const asn1_tagnum tagnum,
+ const int in_len,
+ int *retlen));
+/* requires *buf is allocated, in_len is the length of an ASN.1 encoding
+ which has just been inserted in *buf
+ modifies *buf, *retlen
+ effects Inserts the encoding of a tag with class = class,
+ primitive/constructed staus = construction,
+ id# = tag and length = in_len into *buf.
+ Returns the length of this encoding in *retlen.
+ Returns ENOMEM if memory runs out.
+ Returns ASN1_OVERFLOW if tagnum exceeds the limits of
+ the implementation. */
+
+asn1_error_code asn1_make_sequence
+ PROTOTYPE((asn1buf *buf, const int seq_len, int *len));
+/* requires *buf is allocated, seq_len is the length of a series of
+ sequence components which have just been inserted in *buf
+ modifies *buf, *retlen
+ effects Inserts the sequence header for a sequence of length seq_len
+ in *buf. Returns the length of this encoding in *retlen.
+ Returns ENOMEM if memory runs out. */
+
+asn1_error_code asn1_make_set
+ PROTOTYPE((asn1buf *buf, const int set_len, int *retlen));
+/* requires *buf is allocated, seq_len is the length of a series of
+ sequence components which have just been inserted in *buf
+ modifies *buf, *retlen
+ effects Inserts the set header for a set of length set_len in *buf.
+ Returns the length of this encoding in *retlen.
+ Returns ENOMEM if memory runs out. */
+
+asn1_error_code asn1_make_string
+ PROTOTYPE((asn1buf *buf,
+ const int len, const char *string,
+ int *retlen));
+/* requires *buf is allocated, len is the length of *string
+ effects Inserts the encoding of *string
+ PROTOTYPE((a series of octets) in *buf.
+ Returns the length of this encoding in *retlen.
+ Returns ENOMEM if memory runs out. */
+
+
+/****************************************************************/
+/* Private procedures */
+
+/* "helper" procedure for asn1_make_tag */
+asn1_error_code asn1_make_length
+ PROTOTYPE((asn1buf *buf, const int in_len, int *retlen));
+/* requires *buf is allocated, in_len is the length of an ASN.1 encoding
+ which has just been inserted in *buf
+ modifies *buf, *retlen
+ effects inserts length octet
+ PROTOTYPE((s) for in_len into *buf */
+
+/* "helper" procedure for asn1_make_tag */
+asn1_error_code asn1_make_id
+ PROTOTYPE((asn1buf *buf,
+ const asn1_class class,
+ const asn1_construction construction,
+ const asn1_tagnum tagnum,
+ int *retlen));
+/* requires *buf is allocated, class and tagnum are appropriate for
+ the ASN.1 encoding which has just been inserted in *buf
+ modifies *buf, *retlen
+ effects Inserts id octet
+ PROTOTYPE((s) of class class and tag number tagnum
+ into *buf */
+
+#endif
--- /dev/null
+#include "asn1_misc.h"
+
+asn1_error_code asn1_krb5_realm_copy(DECLARG(krb5_principal, target),
+ DECLARG(krb5_principal, source))
+ OLDDECLARG(krb5_principal, target)
+ OLDDECLARG(krb5_principal, source)
+{
+ target->realm.length = source->realm.length;
+ target->realm.data = (char*)calloc(target->realm.length,
+ sizeof(char)); /* copy realm */
+ if(target->realm.data == NULL) return ENOMEM;
+ memcpy(target->realm.data,source->realm.data, /* to client */
+ target->realm.length);
+ return 0;
+}
--- /dev/null
+#ifndef __ASN1_MISC_H__
+#define __ASN1_MISC_H__
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+
+asn1_error_code asn1_krb5_realm_copy
+ PROTOTYPE((krb5_principal target, krb5_principal source));
+/* requires target, source, and source->realm are allocated
+ effects Copies source->realm into target->realm.
+ Returns ENOMEM if memory is exhausted. */
+
+#endif
--- /dev/null
+/* Coding Buffer Implementation */
+
+/*
+ Implementation
+
+ Encoding mode
+
+ The encoding buffer is filled from bottom (lowest address) to top
+ (highest address). This makes it easier to expand the buffer,
+ since realloc preserves the existing portion of the buffer.
+
+ Note: Since ASN.1 encoding must be done in reverse, this means
+ that you can't simply memcpy out the buffer data, since it will be
+ backwards. You need to reverse-iterate through it, instead.
+
+ ***This decision may have been a mistake. In practice, the
+ implementation will probably be tuned such that reallocation is
+ rarely necessary. Also, the realloc probably has recopy the
+ buffer itself, so we don't really gain that much by avoiding an
+ explicit copy of the buffer. --Keep this in mind for future reference.
+
+
+ Decoding mode
+
+ The decoding buffer is in normal order and is created by wrapping
+ an asn1buf around a krb5_data structure.
+ */
+
+/* Abstraction Function
+
+ Programs should use just pointers to asn1buf's (e.g. asn1buf *mybuf).
+ These pointers must always point to a valid, allocated asn1buf
+ structure or be NULL.
+
+ The contents of the asn1buf represent an octet string. This string
+ begins at base and continues to the octet immediately preceding next.
+ If next == base or mybuf == NULL, then the asn1buf represents an empty
+ octet string. */
+
+/* Representation Invariant
+
+ Pointers to asn1buf's must always point to a valid, allocated
+ asn1buf structure or be NULL.
+
+ base points to a valid, allocated octet array or is NULL
+ next >= base
+ next <= bound+2 (i.e. next should be able to step just past the bound,
+ but no further. (The bound should move out in response
+ to being crossed by next.)) */
+
+#include "asn1buf.h"
+#include <stdlib.h>
+
+asn1_error_code asn1buf_create(DECLARG(asn1buf **, buf))
+ OLDDECLARG(asn1buf **, buf)
+{
+ *buf = (asn1buf*)calloc(1,sizeof(asn1buf));
+ if (*buf == NULL) return ENOMEM;
+ (*buf)->base = NULL;
+ (*buf)->bound = NULL;
+ (*buf)->next = NULL;
+ return 0;
+}
+
+asn1_error_code asn1buf_wrap_data(DECLARG(asn1buf *, buf),
+ DECLARG(const krb5_data *, code))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const krb5_data *, code)
+{
+ if(code == NULL || code->data == NULL) return ASN1_MISSING_FIELD;
+ buf->next = buf->base = code->data;
+ buf->bound = code->data + code->length - 1;
+ return 0;
+}
+
+asn1_error_code asn1buf_imbed(DECLARG(asn1buf *, subbuf),
+ DECLARG(const asn1buf *, buf),
+ DECLARG(const int , length))
+ OLDDECLARG(asn1buf *, subbuf)
+ OLDDECLARG(const asn1buf *, buf)
+ OLDDECLARG(const int , length)
+{
+ subbuf->base = subbuf->next = buf->next;
+ subbuf->bound = subbuf->base + length - 1;
+ if(subbuf->bound > buf->bound) return ASN1_OVERRUN;
+ return 0;
+}
+
+void asn1buf_sync(DECLARG(asn1buf *, buf),
+ DECLARG(asn1buf *, subbuf))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(asn1buf *, subbuf)
+{
+ buf->next = subbuf->next;
+}
+
+asn1_error_code asn1buf_destroy(DECLARG(asn1buf **, buf))
+ OLDDECLARG(asn1buf **, buf)
+{
+ if (*buf != NULL) {
+ if ((*buf)->base != NULL) free((*buf)->base);
+ free(*buf);
+ *buf = NULL;
+ }
+ return 0;
+}
+
+asn1_error_code asn1buf_insert_octet(DECLARG(asn1buf *, buf),
+ DECLARG(const asn1_octet , o))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const asn1_octet , o)
+{
+ asn1_error_code retval;
+
+ retval = asn1buf_ensure_space(buf,1);
+ if(retval) return retval;
+ *(buf->next) = (char)o;
+ (buf->next)++;
+ return 0;
+}
+
+asn1_error_code asn1buf_insert_octetstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const krb5_octet *, s))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const krb5_octet *, s)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_ensure_space(buf,len);
+ if(retval) return retval;
+ for(length=1; length<=len; length++,(buf->next)++)
+ *(buf->next) = (char)(s[len-length]);
+ return 0;
+}
+
+asn1_error_code asn1buf_insert_charstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(const char *, s))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(const char *, s)
+{
+ asn1_error_code retval;
+ int length;
+
+ retval = asn1buf_ensure_space(buf,len);
+ if(retval) return retval;
+ for(length=1; length<=len; length++,(buf->next)++)
+ *(buf->next) = (char)(s[len-length]);
+ return 0;
+}
+
+asn1_error_code asn1buf_remove_octet(DECLARG(asn1buf *, buf),
+ DECLARG(asn1_octet *, o))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(asn1_octet *, o)
+{
+ if(buf->next > buf->bound) return ASN1_OVERRUN;
+ *o = (asn1_octet)(*((buf->next)++));
+ return 0;
+}
+
+asn1_error_code asn1buf_remove_octetstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(asn1_octet **, s))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(asn1_octet **, s)
+{
+ int i;
+
+ if(buf->next + len - 1 > buf->bound) return ASN1_OVERRUN;
+ *s = (asn1_octet*)calloc(len,sizeof(asn1_octet));
+ if(*s == NULL) return ENOMEM;
+ for(i=0; i<len; i++)
+ (*s)[i] = (asn1_octet)(buf->next)[i];
+ buf->next += len;
+ return 0;
+}
+
+asn1_error_code asn1buf_remove_charstring(DECLARG(asn1buf *, buf),
+ DECLARG(const int , len),
+ DECLARG(char **, s))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , len)
+ OLDDECLARG(char **, s)
+{
+ int i;
+
+ if(buf->next + len - 1 > buf->bound) return ASN1_OVERRUN;
+ *s = (char*)calloc(len,sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ for(i=0; i<len; i++)
+ (*s)[i] = (char)(buf->next)[i];
+ buf->next += len;
+ return 0;
+}
+
+int asn1buf_remains(DECLARG(const asn1buf *, buf))
+ OLDDECLARG(const asn1buf *, buf)
+{
+ if(buf == NULL || buf->base == NULL) return 0;
+ else return buf->bound - buf->next + 1;
+}
+
+asn1_error_code asn12krb5_buf(DECLARG(const asn1buf *, buf),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const asn1buf *, buf)
+ OLDDECLARG(krb5_data **, code)
+{
+ int i;
+ *code = (krb5_data*)calloc(1,sizeof(krb5_data));
+ if(*code == NULL) return ENOMEM;
+ (*code)->data = NULL;
+ (*code)->length = 0;
+ (*code)->length = asn1buf_len(buf);
+ (*code)->data = (char*)calloc(((*code)->length)+1,sizeof(char));
+ for(i=0; i < (*code)->length; i++)
+ ((*code)->data)[i] = (buf->base)[((*code)->length)-i-1];
+ ((*code)->data)[(*code)->length] = '\0';
+ return 0;
+}
+
+
+
+/* These parse and unparse procedures should be moved out. They're
+ useful only for debugging and superfluous in the production version. */
+
+asn1_error_code asn1buf_unparse(DECLARG(const asn1buf *, buf),
+ DECLARG(char **, s))
+ OLDDECLARG(const asn1buf *, buf)
+ OLDDECLARG(char **, s)
+{
+ if(*s != NULL) free(*s);
+ if(buf == NULL){
+ *s = calloc(sizeof("<NULL>")+1, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ strcpy(*s,"<NULL>");
+ }else if(buf->base == NULL){
+ *s = calloc(sizeof("<EMPTY>")+1, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ strcpy(*s,"<EMPTY>");
+ }else{
+ int length = asn1buf_len(buf);
+ int i;
+
+ *s = calloc(length+1, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ (*s)[length] = '\0';
+ for(i=0; i<length; i++)
+ OLDDECLARG( (*s)[i] = , (buf->base)[length-i-1])
+ }
+ return 0;
+}
+
+asn1_error_code asn1buf_hex_unparse(DECLARG(const asn1buf *, buf),
+ DECLARG(char **, s))
+ OLDDECLARG(const asn1buf *, buf)
+ OLDDECLARG(char **, s)
+{
+#define hexchar(d) ((d)<=9 ? ('0'+(d)) :\
+ ((d)<=15 ? ('A'+(d)-10) :\
+ 'X'))
+
+ if(*s != NULL) free(*s);
+
+ if(buf == NULL){
+ *s = calloc(sizeof("<NULL>")+1, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ strcpy(*s,"<NULL>");
+ }else if(buf->base == NULL){
+ *s = calloc(sizeof("<EMPTY>")+1, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ strcpy(*s,"<EMPTY>");
+ }else{
+ int length = asn1buf_len(buf);
+ int i;
+
+ *s = calloc(3*length, sizeof(char));
+ if(*s == NULL) return ENOMEM;
+ for(i = length-1; i >= 0; i--){
+ (*s)[3*(length-i-1)] = hexchar(((buf->base)[i]&0xF0)>>4);
+ (*s)[3*(length-i-1)+1] = hexchar((buf->base)[i]&0x0F);
+ (*s)[3*(length-i-1)+2] = ' ';
+ }
+ (*s)[3*length-1] = '\0';
+ }
+ return 0;
+}
+
+/****************************************************************/
+/* Private Procedures */
+
+int asn1buf_size(DECLARG(const asn1buf *, buf))
+ OLDDECLARG(const asn1buf *, buf)
+{
+ if(buf == NULL || buf->base == NULL) return 0;
+ return buf->bound - buf->base + 1;
+}
+
+int asn1buf_free(DECLARG(const asn1buf *, buf))
+ OLDDECLARG(const asn1buf *, buf)
+{
+ if(buf == NULL || buf->base == NULL) return 0;
+ else return buf->bound - buf->next + 1;
+}
+
+asn1_error_code asn1buf_ensure_space(DECLARG(asn1buf *, buf),
+ DECLARG(const int , amount))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , amount)
+{
+ int free = asn1buf_free(buf);
+ if(free < amount){
+ asn1_error_code retval = asn1buf_expand(buf, amount-free);
+ if(retval) return retval;
+ }
+ return 0;
+}
+
+asn1_error_code asn1buf_expand(DECLARG(asn1buf *, buf),
+ DECLARG(const int , inc))
+ OLDDECLARG(asn1buf *, buf)
+ OLDDECLARG(const int , inc)
+{
+#define STANDARD_INCREMENT 200
+ int next_offset = buf->next - buf->base;
+ int bound_offset;
+ if(buf->base == NULL) bound_offset = -1;
+ else bound_offset = buf->bound - buf->base;
+
+
+ buf->base = realloc(buf->base,
+ (asn1buf_size(buf)+(inc>STANDARD_INCREMENT ?
+ inc : STANDARD_INCREMENT))
+ * sizeof(asn1_octet));
+ if(buf->base == NULL) return ENOMEM;
+ buf->bound = (buf->base) + bound_offset + inc;
+ buf->next = (buf->base) + next_offset;
+ return 0;
+}
+
+int asn1buf_len(DECLARG(const asn1buf *, buf))
+ OLDDECLARG(const asn1buf *, buf)
+{
+ return buf->next - buf->base;
+}
--- /dev/null
+/* Coding Buffer Specifications */
+#ifndef __ASN1BUF_H__
+#define __ASN1BUF_H__
+
+#include <krb5/krb5.h>
+#include "krbasn1.h"
+
+typedef struct code_buffer_rep {
+ char *base, *bound, *next;
+} asn1buf;
+
+/*
+ Overview
+
+ The coding buffer is an array of char (to match a krb5_data structure)
+ with 3 reference pointers:
+ 1) base - The bottom of the octet array. Used for memory management
+ operations on the array (e.g. alloc, realloc, free).
+ 2) next - Points to the next available octet position in the array.
+ During encoding, this is the next free position, and it
+ advances as octets are added to the array.
+ During decoding, this is the next unread position, and it
+ advances as octets are read from the array.
+ 3) bound - Points to the top of the array. Used for bounds-checking.
+
+ All pointers to encoding buffers should be initalized to NULL.
+
+ Operations
+
+ asn1buf_create
+ asn1buf_wrap_data
+ asn1buf_destroy
+ asn1buf_insert_octet
+ asn1buf_insert_charstring
+ asn1buf_remove_octet
+ asn1buf_remove_charstring
+ asn1buf_unparse
+ asn1buf_hex_unparse
+ asn12krb5_buf
+ asn1buf_remains
+
+ (asn1buf_size)
+ (asn1buf_free)
+ (asn1buf_ensure_space)
+ (asn1buf_expand)
+ (asn1buf_len)
+*/
+
+asn1_error_code asn1buf_create
+ PROTOTYPE((asn1buf **buf));
+/* effects Creates a new encoding buffer pointed to by *buf.
+ Returns ENOMEM if the buffer can't be created. */
+
+asn1_error_code asn1buf_wrap_data
+ PROTOTYPE((asn1buf *buf, const krb5_data *code));
+/* requires *buf has already been allocated
+ effects Turns *buf into a "wrapper" for *code. i.e. *buf is set up
+ such that its bottom is the beginning of *code, and its top
+ is the top of *code.
+ Returns ASN1_MISSING_FIELD if code is empty. */
+
+asn1_error_code asn1buf_imbed
+ PROTOTYPE((asn1buf *subbuf, const asn1buf *buf, const int length));
+/* requires *subbuf and *buf are allocated
+ effects *subbuf becomes a sub-buffer of *buf. *subbuf begins
+ at *buf's current position and is length octets long.
+ (Unless this would exceed the bounds of *buf -- in
+ that case, ASN1_OVERRUN is returned) *subbuf's current
+ position starts at the beginning of *subbuf. */
+
+void asn1buf_sync
+ PROTOTYPE((asn1buf *buf, asn1buf *subbuf));
+/* requires *subbuf is a sub-buffer of *buf, as created by asn1buf_imbed.
+ effects Synchronizes *buf's current position to match that of *subbuf. */
+
+asn1_error_code asn1buf_destroy
+ PROTOTYPE((asn1buf **buf));
+/* effects Deallocates **buf, sets *buf to NULL. */
+
+asn1_error_code asn1buf_insert_octet
+ PROTOTYPE((asn1buf *buf, const /*asn1_octet*/int o));
+/* requires *buf is allocated
+ effects Inserts o into the buffer *buf, expanding the buffer if
+ necessary. Returns ENOMEM memory is exhausted. */
+
+asn1_error_code asn1buf_insert_octetstring
+ PROTOTYPE((asn1buf *buf, const int len, const asn1_octet *s));
+/* requires *buf is allocated
+ modifies *buf
+ effects Inserts the contents of s (an octet array of length len)
+ into the buffer *buf, expanding the buffer if necessary.
+ Returns ENOMEM if memory is exhausted. */
+
+asn1_error_code asn1buf_insert_charstring
+ PROTOTYPE((asn1buf *buf, const int len, const char *s));
+/* requires *buf is allocated
+ modifies *buf
+ effects Inserts the contents of s (a character array of length len)
+ into the buffer *buf, expanding the buffer if necessary.
+ Returns ENOMEM if memory is exhuasted. */
+
+asn1_error_code asn1buf_remove_octet
+ PROTOTYPE((asn1buf *buf, asn1_octet *o));
+/* requires *buf is allocated
+ effects Returns *buf's current octet in *o and advances to
+ the next octet.
+ Returns ASN1_OVERRUN if *buf has already been exhuasted. */
+
+asn1_error_code asn1buf_remove_octetstring
+ PROTOTYPE((asn1buf *buf, const int len, asn1_octet **s));
+/* requires *buf is allocated
+ effects Removes the next len octets of *buf and returns them in **s.
+ Returns ASN1_OVERRUN if there are fewer than len unread octets
+ left in *buf.
+ Returns ENOMEM if *s could not be allocated. */
+
+asn1_error_code asn1buf_remove_charstring
+ PROTOTYPE((asn1buf *buf, const int len,
+ char **s));
+/* requires *buf is allocated
+ effects Removes the next len octets of *buf and returns them in **s.
+ Returns ASN1_OVERRUN if there are fewer than len unread octets
+ left in *buf.
+ Returns ENOMEM if *s could not be allocated. */
+
+asn1_error_code asn1buf_unparse
+ PROTOTYPE((const asn1buf *buf, char **s));
+/* modifies *s
+ effects Returns a human-readable representation of *buf in *s,
+ where each octet in *buf is represented by a character in *s. */
+
+asn1_error_code asn1buf_hex_unparse
+ PROTOTYPE((const asn1buf *buf, char **s));
+/* modifies *s
+ effects Returns a human-readable representation of *buf in *s,
+ where each octet in *buf is represented by a 2-digit
+ hexadecimal number in *s. */
+
+asn1_error_code asn12krb5_buf
+ PROTOTYPE((const asn1buf *buf, krb5_data **code));
+/* modifies *code
+ effects Instantiates **code with the krb5_data representation of **buf. */
+
+
+int asn1buf_remains
+ PROTOTYPE((const asn1buf *buf));
+/* effects Returns the number of unprocessed octets remaining in *buf. */
+
+/**************** Private Procedures ****************/
+
+int asn1buf_size
+ PROTOTYPE((const asn1buf *buf));
+/* requires *buf has been created and not destroyed
+ effects Returns the total size
+ PROTOTYPE((in octets) of buf's octet buffer. */
+
+int asn1buf_free
+ PROTOTYPE((const asn1buf *buf));
+/* requires *buf is allocated
+ effects Returns the number of unused, allocated octets in *buf. */
+
+asn1_error_code asn1buf_ensure_space
+ PROTOTYPE((asn1buf *buf, const int amount));
+/* requires *buf is allocated
+ modifies *buf
+ effects If buf has less than amount octets of free space, then it is
+ expanded to have at least amount octets of free space.
+ Returns ENOMEM memory is exhausted. */
+
+asn1_error_code asn1buf_expand
+ PROTOTYPE((asn1buf *buf, const int inc));
+/* requires *buf is allocated
+ modifies *buf
+ effects Expands *buf by allocating space for inc more octets.
+ Returns ENOMEM if memory is exhausted. */
+
+int asn1buf_len
+ PROTOTYPE((const asn1buf *buf));
+/* requires *buf is allocated
+ effects Returns the length of the encoding in *buf. */
+
+#endif
WITH_CCOPTS
CONFIG_RULES
AC_SET_BUILDTOP
-UsePepsy
SubdirLibraryRule([${OBJS}])
+AC_ENABLE([isode],[
+UsePepsy
+PepsyTarget(KRB5)
+cp ${srcdir}/Makefile.in.isode Makefile.in],[
+PEPSY='@echo'
+PSYFLAGS='not using pepsy'
+AC_SUBST(PEPSY)dnl
+AC_SUBST(PSYFLAGS)dnl
+cp ${srcdir}/Makefile.in.sane Makefile.in])
CopyHeader(KRB5-types.h,[$(EHDRDIR)])
CopyHeader(KRB5_defs.h,[$(EHDRDIR)])
CopyHeader(KRB5_pre_defs.h,[$(EHDRDIR)])
Krb5InstallHeaders(KRB5_defs.h KRB5_pre_defs.h KRB5-types.h, [$(KRB5_INCDIR)/krb5/asn.1])
-PepsyTarget(KRB5)
+dnl
+dnl ok this is broken but necessary because we're using autoconf
+dnl ...and we can't conditionalize the generation of make rules
+dnl
+CopyHeader(krb5_encode.h,[$(EHDRDIR)])
+CopyHeader(krb5_decode.h,[$(EHDRDIR)])
+Krb5InstallHeaders(krb5_encode.h krb5_decode.h, [$(KRB5_INCDIR)/krb5/asn.1])
KRB_INCLUDE
ISODE_INCLUDE
WITH_KRB5ROOT
--- /dev/null
+#include "krb5_decode.h"
+#include "krbasn1.h"
+#include "asn1_decode_k.h"
+#include "asn1_decode.h"
+#include "asn1_get.h"
+
+/* setup *********************************************************/
+/* set up variables */
+#define setup()\
+asn1_error_code retval;\
+asn1buf buf;\
+asn1_class class;\
+asn1_construction construction;\
+asn1_tagnum tagnum;\
+int length;\
+\
+retval = asn1buf_wrap_data(&buf,code);\
+if(retval) return retval
+
+#define setup_no_length()\
+asn1_error_code retval;\
+asn1buf buf;\
+asn1_class class;\
+asn1_construction construction;\
+asn1_tagnum tagnum;\
+\
+retval = asn1buf_wrap_data(&buf,code);\
+if(retval) return retval
+
+#define setup_no_tagnum()\
+asn1_error_code retval;\
+asn1buf buf;\
+asn1_class class;\
+asn1_construction construction;\
+\
+retval = asn1buf_wrap_data(&buf,code);\
+if(retval) return retval
+
+#define alloc_field(var,type)\
+var = (type*)calloc(1,sizeof(type));\
+if((var) == NULL) return ENOMEM
+
+#define setup_buf_only()\
+asn1_error_code retval;\
+asn1buf buf;\
+retval = asn1buf_wrap_data(&buf,code);\
+if(retval) return retval
+
+
+/* process encoding header ***************************************/
+/* decode tag and check that it == [APPLICATION tagnum] */
+#define check_apptag(tagexpect)\
+retval = asn1_get_tag(&buf,&class,&construction,&tagnum,NULL);\
+if(retval) return retval;\
+if(class != APPLICATION || construction != CONSTRUCTED) return ASN1_BAD_ID;\
+if(tagnum != (tagexpect)) return KRB5_BADMSGTYPE
+
+
+
+/* process a structure *******************************************/
+
+/* decode an explicit tag and place the number in tagnum */
+#define next_tag()\
+retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,NULL);\
+if(retval) return retval;\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ return ASN1_BAD_ID
+
+/* decode sequence header and initialize tagnum with the first field */
+#define begin_structure()\
+asn1buf subbuf;\
+retval = asn1_get_tag(&buf,&class,&construction,&tagnum,&length);\
+if(retval) return retval;\
+if(class != UNIVERSAL || construction != CONSTRUCTED ||\
+ tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID;\
+retval = asn1buf_imbed(&subbuf,&buf,length);\
+if(retval) return retval;\
+next_tag()
+
+#define end_structure()\
+asn1buf_sync(&buf,&subbuf)
+
+/* process fields *******************************************/
+/* normal fields ************************/
+#define get_field_body(var,decoder)\
+retval = decoder(&subbuf,&(var));\
+if(retval) return (krb5_error_code)retval;\
+next_tag()
+
+/* decode a field (<[UNIVERSAL id]> <length> <contents>)
+ check that the id number == tagexpect then
+ decode into var
+ get the next tag */
+#define get_field(var,tagexpect,decoder)\
+if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
+if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+get_field_body(var,decoder)
+
+/* decode (or skip, if not present) an optional field */
+#define opt_field(var,tagexpect,decoder)\
+if(tagnum == (tagexpect)){ get_field_body(var,decoder); }
+
+/* field w/ accompanying length *********/
+#define get_lenfield_body(len,var,decoder)\
+retval = decoder(&subbuf,&(len),&(var));\
+if(retval) return (krb5_error_code)retval;\
+next_tag()
+
+/* decode a field w/ its length (for string types) */
+#define get_lenfield(len,var,tagexpect,decoder)\
+if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
+if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+get_lenfield_body(len,var,decoder)
+
+/* decode an optional field w/ length */
+#define opt_lenfield(len,var,tagexpect,decoder)\
+if(tagnum == (tagexpect)){\
+ get_lenfield_body(len,var,decoder);\
+}
+
+
+/* clean up ******************************************************/
+/* finish up */
+#define cleanup()\
+return 0
+
+krb5_error_code decode_krb5_authenticator(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_authenticator **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_authenticator **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_authenticator);
+
+ check_apptag(2);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ alloc_field((*rep)->client,krb5_principal_data);
+ get_field((*rep)->client,1,asn1_decode_realm);
+ get_field((*rep)->client,2,asn1_decode_principal_name);
+ if(tagnum == 3){
+ alloc_field((*rep)->checksum,krb5_checksum);
+ get_field(*((*rep)->checksum),3,asn1_decode_checksum); }
+ get_field((*rep)->cusec,4,asn1_decode_int32);
+ get_field((*rep)->ctime,5,asn1_decode_kerberos_time);
+ if(tagnum == 6){ alloc_field((*rep)->subkey,krb5_keyblock); }
+ opt_field(*((*rep)->subkey),6,asn1_decode_encryption_key);
+ opt_field((*rep)->seq_number,7,asn1_decode_int32);
+ opt_field((*rep)->authorization_data,8,asn1_decode_authorization_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_ticket(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_ticket **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_ticket **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_ticket);
+
+ check_apptag(1);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO;
+ }
+ alloc_field((*rep)->server,krb5_principal_data);
+ get_field((*rep)->server,1,asn1_decode_realm);
+ get_field((*rep)->server,2,asn1_decode_principal_name);
+ get_field((*rep)->enc_part,3,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_encryption_key(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_keyblock **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_keyblock **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_keyblock);
+
+ { begin_structure();
+ get_field((*rep)->keytype,0,asn1_decode_keytype);
+ get_lenfield((*rep)->length,(*rep)->contents,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_enc_tkt_part(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_enc_tkt_part **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_enc_tkt_part **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_enc_tkt_part);
+
+ check_apptag(3);
+ { begin_structure();
+ get_field((*rep)->flags,0,asn1_decode_ticket_flags);
+ alloc_field((*rep)->session,krb5_keyblock);
+ get_field(*((*rep)->session),1,asn1_decode_encryption_key);
+ alloc_field((*rep)->client,krb5_principal_data);
+ get_field((*rep)->client,2,asn1_decode_realm);
+ get_field((*rep)->client,3,asn1_decode_principal_name);
+ get_field((*rep)->transited,4,asn1_decode_transited_encoding);
+ get_field((*rep)->times.authtime,5,asn1_decode_kerberos_time);
+ opt_field((*rep)->times.starttime,6,asn1_decode_kerberos_time);
+ get_field((*rep)->times.endtime,7,asn1_decode_kerberos_time);
+ opt_field((*rep)->times.renew_till,8,asn1_decode_kerberos_time);
+ opt_field((*rep)->caddrs,9,asn1_decode_host_addresses);
+ opt_field((*rep)->authorization_data,10,asn1_decode_authorization_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_enc_kdc_rep_part(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_enc_kdc_rep_part **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_enc_kdc_rep_part **, rep)
+{
+ setup_no_length();
+ alloc_field(*rep,krb5_enc_kdc_rep_part);
+
+#ifndef ENCKRB5KDCREPPART_HAS_MSGTYPE
+ check_apptag(26);
+#else
+ retval = asn1_get_tag(&buf,&class,&construction,&tagnum,NULL);
+ if(retval) return retval;
+ if(class != APPLICATION || construction != CONSTRUCTED) return ASN1_BAD_ID;
+ if(tagnum == 25) (*rep)->msg_type = KRB5_AS_REP;
+ else if(tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP;
+ else return KRB5_BADMSGTYPE;
+#endif
+ retval = asn1_decode_enc_kdc_rep_part(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_as_rep(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_kdc_rep **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_kdc_rep **, rep)
+{
+ setup_no_length();
+ alloc_field(*rep,krb5_kdc_rep);
+
+ check_apptag(11);
+ retval = asn1_decode_kdc_rep(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+ if((*rep)->msg_type != KRB5_AS_REP) return KRB5_BADMSGTYPE;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_tgs_rep(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_kdc_rep **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_kdc_rep **, rep)
+{
+ setup_no_length();
+ alloc_field(*rep,krb5_kdc_rep);
+
+ check_apptag(13);
+ retval = asn1_decode_kdc_rep(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+ if((*rep)->msg_type != KRB5_TGS_REP) return KRB5_BADMSGTYPE;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_ap_req(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_ap_req **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_ap_req **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_ap_req);
+
+ check_apptag(14);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_AP_REQ) return KRB5_BADMSGTYPE; }
+ get_field((*rep)->ap_options,2,asn1_decode_ap_options);
+ alloc_field((*rep)->ticket,krb5_ticket);
+ get_field(*((*rep)->ticket),3,asn1_decode_ticket);
+ get_field((*rep)->authenticator,4,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_ap_rep(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_ap_rep **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_ap_rep **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_ap_rep);
+
+ check_apptag(15);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_AP_REP) return KRB5_BADMSGTYPE; }
+ get_field((*rep)->enc_part,2,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_ap_rep_enc_part(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_ap_rep_enc_part **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_ap_rep_enc_part **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_ap_rep_enc_part);
+
+ check_apptag(27);
+ { begin_structure();
+ get_field((*rep)->ctime,0,asn1_decode_kerberos_time);
+ get_field((*rep)->cusec,1,asn1_decode_int32);
+ if(tagnum == 2){ alloc_field((*rep)->subkey,krb5_keyblock); }
+ opt_field(*((*rep)->subkey),2,asn1_decode_encryption_key);
+ opt_field((*rep)->seq_number,3,asn1_decode_int32);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_as_req(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_kdc_req **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_kdc_req **, rep)
+{
+ setup_no_length();
+ alloc_field(*rep,krb5_kdc_req);
+
+ check_apptag(10);
+ retval = asn1_decode_kdc_req(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+ if((*rep)->msg_type != KRB5_AS_REQ) return KRB5_BADMSGTYPE;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_tgs_req(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_kdc_req **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_kdc_req **, rep)
+{
+ setup_no_length();
+ alloc_field(*rep,krb5_kdc_req);
+
+ check_apptag(12);
+ retval = asn1_decode_kdc_req(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+ if((*rep)->msg_type != KRB5_TGS_REQ) return KRB5_BADMSGTYPE;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_kdc_req_body(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_kdc_req **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_kdc_req **, rep)
+{
+ setup_buf_only();
+ alloc_field(*rep,krb5_kdc_req);
+
+ retval = asn1_decode_kdc_req_body(&buf,*rep);
+ if(retval) return (krb5_error_code)retval;
+
+ cleanup();
+}
+
+krb5_error_code decode_krb5_safe(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_safe **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_safe **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_safe);
+
+ check_apptag(20);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_SAFE) return KRB5_BADMSGTYPE; }
+ get_field(**rep,2,asn1_decode_krb_safe_body);
+ alloc_field((*rep)->checksum,krb5_checksum);
+ get_field(*((*rep)->checksum),3,asn1_decode_checksum);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_priv(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_priv **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_priv **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_priv);
+
+ check_apptag(21);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_PRIV) return KRB5_BADMSGTYPE; }
+ get_field((*rep)->enc_part,3,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_enc_priv_part(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_priv_enc_part **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_priv_enc_part **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_priv_enc_part);
+
+ check_apptag(28);
+ { begin_structure();
+ get_lenfield((*rep)->user_data.length,(*rep)->user_data.data,0,asn1_decode_charstring);
+ opt_field((*rep)->timestamp,1,asn1_decode_kerberos_time);
+ opt_field((*rep)->usec,2,asn1_decode_int32);
+ opt_field((*rep)->seq_number,3,asn1_decode_int32);
+ alloc_field((*rep)->s_address,krb5_address);
+ get_field(*((*rep)->s_address),4,asn1_decode_host_address);
+ if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); }
+ opt_field(*((*rep)->r_address),5,asn1_decode_host_address);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_cred(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_cred **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_cred **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_cred);
+
+ check_apptag(22);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_CRED) return KRB5_BADMSGTYPE; }
+ get_field((*rep)->tickets,2,asn1_decode_sequence_of_ticket);
+ get_field((*rep)->enc_part,3,asn1_decode_encrypted_data);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_enc_cred_part(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_cred_enc_part **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_cred_enc_part **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_cred_enc_part);
+
+ check_apptag(29);
+ { begin_structure();
+ get_field((*rep)->ticket_info,0,asn1_decode_sequence_of_krb_cred_info);
+ opt_field((*rep)->nonce,1,asn1_decode_int32);
+ opt_field((*rep)->timestamp,2,asn1_decode_kerberos_time);
+ opt_field((*rep)->usec,3,asn1_decode_int32);
+ if(tagnum == 4){ alloc_field((*rep)->s_address,krb5_address); }
+ opt_field(*((*rep)->s_address),4,asn1_decode_host_address);
+ if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); }
+ opt_field(*((*rep)->r_address),5,asn1_decode_host_address);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_error(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_error **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_error **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_error);
+
+ check_apptag(30);
+ { begin_structure();
+ { krb5_kvno kvno;
+ get_field(kvno,0,asn1_decode_kvno);
+ if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
+ { krb5_msgtype msg_type;
+ get_field(msg_type,1,asn1_decode_msgtype);
+ if(msg_type != KRB5_ERROR) return KRB5_BADMSGTYPE; }
+ opt_field((*rep)->ctime,2,asn1_decode_kerberos_time);
+ opt_field((*rep)->cusec,3,asn1_decode_int32);
+ get_field((*rep)->stime,4,asn1_decode_kerberos_time);
+ get_field((*rep)->susec,5,asn1_decode_int32);
+ get_field((*rep)->error,6,asn1_decode_ui_4);
+ if(tagnum == 7){ alloc_field((*rep)->client,krb5_principal_data); }
+ opt_field((*rep)->client,7,asn1_decode_realm);
+ opt_field((*rep)->client,8,asn1_decode_principal_name);
+ alloc_field((*rep)->server,krb5_principal_data);
+ get_field((*rep)->server,9,asn1_decode_realm);
+ get_field((*rep)->server,10,asn1_decode_principal_name);
+ opt_lenfield((*rep)->text.length,(*rep)->text.data,11,asn1_decode_generalstring);
+ opt_lenfield((*rep)->e_data.length,(*rep)->e_data.data,12,asn1_decode_charstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+krb5_error_code decode_krb5_authdata(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_authdata ***, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_authdata ***, rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_authorization_data(&buf,rep);
+ if(retval) return (krb5_error_code)retval;
+ cleanup();
+}
+
+krb5_error_code decode_krb5_pwd_sequence(DECLARG(const krb5_data *, code),
+ DECLARG(passwd_phrase_element **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(passwd_phrase_element **, rep)
+{
+ setup_buf_only();
+ alloc_field(*rep,passwd_phrase_element);
+ retval = asn1_decode_passwdsequence(&buf,*rep);
+ if(retval) return retval;
+ cleanup();
+}
+
+krb5_error_code decode_krb5_pwd_data(DECLARG(const krb5_data *, code),
+ DECLARG(krb5_pwd_data **, rep))
+ OLDDECLARG(const krb5_data *, code)
+ OLDDECLARG(krb5_pwd_data **, rep)
+{
+ setup();
+ alloc_field(*rep,krb5_pwd_data);
+ { begin_structure();
+ get_field((*rep)->sequence_count,0,asn1_decode_int);
+ get_field((*rep)->element,1,asn1_decode_sequence_of_passwdsequence);
+ end_structure (); }
+ cleanup();
+}
--- /dev/null
+#ifndef __KRB5_DECODE_H__
+#define __KRB5_DECODE_H__
+
+#include <krb5/krb5.h>
+
+/*
+ krb5_error_code decode_krb5_structure(const krb5_data *code,
+ krb5_structure **rep);
+
+ requires Expects **rep to not have been allocated;
+ a new *rep is allocated regardless of the old value.
+ effects Decodes *code into **rep.
+ Returns ENOMEM if memory is exhausted.
+ Returns asn1 and krb5 errors.
+*/
+
+krb5_error_code decode_krb5_authenticator
+ PROTOTYPE((const krb5_data *code, krb5_authenticator **rep));
+
+krb5_error_code decode_krb5_ticket
+ PROTOTYPE((const krb5_data *code, krb5_ticket **rep));
+
+krb5_error_code decode_krb5_encryption_key
+ PROTOTYPE((const krb5_data *output, krb5_keyblock **rep));
+
+krb5_error_code decode_krb5_enc_tkt_part
+ PROTOTYPE((const krb5_data *output, krb5_enc_tkt_part **rep));
+
+krb5_error_code decode_krb5_enc_kdc_rep_part
+ PROTOTYPE((const krb5_data *output, krb5_enc_kdc_rep_part **rep));
+
+krb5_error_code decode_krb5_as_rep
+ PROTOTYPE((const krb5_data *output, krb5_kdc_rep **rep));
+
+krb5_error_code decode_krb5_tgs_rep
+ PROTOTYPE((const krb5_data *output, krb5_kdc_rep **rep));
+
+krb5_error_code decode_krb5_ap_req
+ PROTOTYPE((const krb5_data *output, krb5_ap_req **rep));
+
+krb5_error_code decode_krb5_ap_rep
+ PROTOTYPE((const krb5_data *output, krb5_ap_rep **rep));
+
+krb5_error_code decode_krb5_ap_rep_enc_part
+ PROTOTYPE((const krb5_data *output, krb5_ap_rep_enc_part **rep));
+
+krb5_error_code decode_krb5_as_req
+ PROTOTYPE((const krb5_data *output, krb5_kdc_req **rep));
+
+krb5_error_code decode_krb5_tgs_req
+ PROTOTYPE((const krb5_data *output, krb5_kdc_req **rep));
+
+krb5_error_code decode_krb5_kdc_req_body
+ PROTOTYPE((const krb5_data *output, krb5_kdc_req **rep));
+
+krb5_error_code decode_krb5_safe
+ PROTOTYPE((const krb5_data *output, krb5_safe **rep));
+
+krb5_error_code decode_krb5_priv
+ PROTOTYPE((const krb5_data *output, krb5_priv **rep));
+
+krb5_error_code decode_krb5_enc_priv_part
+ PROTOTYPE((const krb5_data *output, krb5_priv_enc_part **rep));
+
+krb5_error_code decode_krb5_cred
+ PROTOTYPE((const krb5_data *output, krb5_cred **rep));
+
+krb5_error_code decode_krb5_enc_cred_part
+ PROTOTYPE((const krb5_data *output, krb5_cred_enc_part **rep));
+
+krb5_error_code decode_krb5_error
+ PROTOTYPE((const krb5_data *output, krb5_error **rep));
+
+krb5_error_code decode_krb5_authdata
+ PROTOTYPE((const krb5_data *output, krb5_authdata ***rep));
+
+krb5_error_code decode_krb5_pwd_sequence
+ PROTOTYPE((const krb5_data *output, passwd_phrase_element **rep));
+
+krb5_error_code decode_krb5_pwd_data
+ PROTOTYPE((const krb5_data *output, krb5_pwd_data **rep));
+
+#endif
--- /dev/null
+#include "krb5_encode.h"
+#include "asn1_encode_k.h"
+#include "asn1_encode.h"
+#include "krbasn1.h"
+#include "asn1buf.h"
+#include "asn1_make.h"
+
+/**************** Macros (these save a lot of typing) ****************/
+
+/**** krb5 macros ****/
+#if 0
+ How to write a krb5 encoder function using these macros:
+
+ asn1_error_code encode_krb5_structure(const krb5_type *rep,
+ krb5_data **code)
+ {
+ krb5_setup();
+
+ krb5_addfield(rep->last_field, n, asn1_type);
+ krb5_addfield(rep->next_to_last_field, n-1, asn1_type);
+ ...
+
+ /* for OPTIONAL fields */
+ if(rep->field_i == should_not_be_omitted)
+ krb5_addfield(rep->field_i, i, asn1_type);
+
+ /* for string fields (these encoders take an additional argument,
+ the length of the string) */
+ addlenfield(rep->field_length, rep->field, i-1, asn1_type);
+
+ /* if you really have to do things yourself... */
+ retval = asn1_encode_asn1_type(buf,rep->field,&length);
+ if(retval) return retval;
+ sum += length;
+ retval = asn1_make_etag(buf,
+ [UNIVERSAL/APPLICATION/CONTEXT_SPECIFIC/PRIVATE],
+ tag_number, length, &length);
+ if(retval) return retval;
+ sum += length;
+
+ ...
+ krb5_addfield(rep->second_field, 1, asn1_type);
+ krb5_addfield(rep->first_field, 0, asn1_type);
+ krb5_makeseq();
+ krb5_apptag(tag_number);
+
+ krb5_cleanup();
+ }
+#endif
+
+/* setup() -- create and initialize bookkeeping variables
+ retval: stores error codes returned from subroutines
+ buf: the coding buffer
+ length: length of the most-recently produced encoding
+ sum: cumulative length of the entire encoding */
+#define krb5_setup()\
+ asn1_error_code retval;\
+ asn1buf *buf=NULL;\
+ int length, sum=0;\
+\
+ if(rep == NULL) return ASN1_MISSING_FIELD;\
+\
+ retval = asn1buf_create(&buf);\
+ if(retval) return retval
+
+/* krb5_addfield -- add a field, or component, to the encoding */
+#define krb5_addfield(value,tag,encoder)\
+{ retval = encoder(buf,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* krb5_addlenfield -- add a field whose length must be separately specified */
+#define krb5_addlenfield(len,value,tag,encoder)\
+{ retval = encoder(buf,len,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* form a sequence (by adding a sequence header to the current encoding) */
+#define krb5_makeseq()\
+ retval = asn1_make_sequence(buf,sum,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length
+
+/* add an APPLICATION class tag to the current encoding */
+#define krb5_apptag(num)\
+ retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length
+
+/* produce the final output and clean up the workspace */
+#define krb5_cleanup()\
+ retval = asn12krb5_buf(buf,code);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ retval = asn1buf_destroy(&buf);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+\
+ return 0
+
+krb5_error_code encode_krb5_authenticator(DECLARG(const krb5_authenticator *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_authenticator *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* authorization-data[8] AuthorizationData OPTIONAL */
+ if(rep->authorization_data != NULL &&
+ rep->authorization_data[0] != NULL){
+ retval = asn1_encode_authorization_data(buf, (const krb5_authdata **)
+ rep->authorization_data,
+ &length);
+ if(retval){
+ asn1buf_destroy(&buf);
+ return retval; }
+ sum += length;
+ retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,8,length,&length);
+ if(retval){
+ asn1buf_destroy(&buf);
+ return retval; }
+ sum += length;
+ }
+
+ /* seq-number[7] INTEGER OPTIONAL */
+ if(rep->seq_number != 0)
+ krb5_addfield(rep->seq_number,7,asn1_encode_integer);
+
+ /* subkey[6] EncryptionKey OPTIONAL */
+ if(rep->subkey != NULL)
+ krb5_addfield(rep->subkey,6,asn1_encode_encryption_key);
+
+ /* ctime[5] KerberosTime */
+ krb5_addfield(rep->ctime,5,asn1_encode_kerberos_time);
+
+ /* cusec[4] INTEGER */
+ krb5_addfield(rep->cusec,4,asn1_encode_integer);
+
+ /* cksum[3] Checksum OPTIONAL */
+ if(rep->checksum != NULL)
+ krb5_addfield(rep->checksum,3,asn1_encode_checksum);
+
+ /* cname[2] PrincipalName */
+ krb5_addfield(rep->client,2,asn1_encode_principal_name);
+
+ /* crealm[1] Realm */
+ krb5_addfield(rep->client,1,asn1_encode_realm);
+
+ /* authenticator-vno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* Authenticator ::= [APPLICATION 2] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(2);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_ticket(DECLARG(const krb5_ticket *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_ticket *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* enc-part[3] EncryptedData */
+ krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
+
+ /* sname [2] PrincipalName */
+ krb5_addfield(rep->server,2,asn1_encode_principal_name);
+
+ /* realm [1] Realm */
+ krb5_addfield(rep->server,1,asn1_encode_realm);
+
+ /* tkt-vno [0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* Ticket ::= [APPLICATION 1] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(1);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_encryption_key(DECLARG(const krb5_keyblock *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_keyblock *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* keyvalue[1] OCTET STRING */
+ krb5_addlenfield(rep->length,rep->contents,1,asn1_encode_octetstring);
+
+ /* keytype[0] INTEGER */
+ krb5_addfield(rep->keytype,0,asn1_encode_integer);
+
+ /* EncryptionKey ::= SEQUENCE */
+ krb5_makeseq();
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_enc_tkt_part(DECLARG(const krb5_enc_tkt_part *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_enc_tkt_part *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* authorization-data[10] AuthorizationData OPTIONAL */
+ if(rep->authorization_data != NULL &&
+ rep->authorization_data[0] != NULL)
+ krb5_addfield((const krb5_authdata**)rep->authorization_data,
+ 10,asn1_encode_authorization_data);
+
+ /* caddr[9] HostAddresses OPTIONAL */
+ if(rep->caddrs != NULL && rep->caddrs[0] != NULL)
+ krb5_addfield((const krb5_address**)rep->caddrs,9,asn1_encode_host_addresses);
+
+ /* renew-till[8] KerberosTime OPTIONAL */
+ if(rep->times.renew_till)
+ krb5_addfield(rep->times.renew_till,8,asn1_encode_kerberos_time);
+
+ /* endtime[7] KerberosTime */
+ krb5_addfield(rep->times.endtime,7,asn1_encode_kerberos_time);
+
+ /* starttime[6] KerberosTime OPTIONAL */
+ if(rep->times.starttime)
+ krb5_addfield(rep->times.starttime,6,asn1_encode_kerberos_time);
+
+ /* authtime[5] KerberosTime */
+ krb5_addfield(rep->times.authtime,5,asn1_encode_kerberos_time);
+
+ /* transited[4] TransitedEncoding */
+ krb5_addfield(&(rep->transited),4,asn1_encode_transited_encoding);
+
+ /* cname[3] PrincipalName */
+ krb5_addfield(rep->client,3,asn1_encode_principal_name);
+
+ /* crealm[2] Realm */
+ krb5_addfield(rep->client,2,asn1_encode_realm);
+
+ /* key[1] EncryptionKey */
+ krb5_addfield(rep->session,1,asn1_encode_encryption_key);
+
+ /* flags[0] TicketFlags */
+ krb5_addfield(rep->flags,0,asn1_encode_ticket_flags);
+
+ /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(3);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_enc_kdc_rep_part(DECLARG(const krb5_enc_kdc_rep_part *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_enc_kdc_rep_part *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ asn1_error_code retval;
+ asn1buf *buf=NULL;
+ int length, sum=0;
+
+ if(rep == NULL) return ASN1_MISSING_FIELD;
+
+ retval = asn1buf_create(&buf);
+ if(retval) return retval;
+
+ retval = asn1_encode_enc_kdc_rep_part(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+#ifndef ENCKRB5KDCREPPART_HAS_MSGTYPE
+ krb5_apptag(26);
+#else
+ if(rep->msg_type = KRB5_AS_REP){ krb5_apptag(ASN1_KRB_AS_REP); }
+ else if(rep->msg_type = KRB5_TGS_REP){ krb5_apptag(ASN1_KRB_TGS_REP); }
+ else return KRB5_BADMSGTYPE;
+#endif
+ krb5_cleanup();
+}
+
+/* yes, the translation is identical to that used for KDC__REP */
+krb5_error_code encode_krb5_as_rep(DECLARG(const krb5_kdc_rep *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_kdc_rep *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* Not all applications set this. The sample app "sclient", for
+ example. So I guess it should just be ignored. */
+/* if(rep->msg_type != KRB5_AS_REP) return KRB5_BADMSGTYPE;*/
+ /* In fact, I may have to be even more forgiving in order for the
+ encoding to come out properly. I'm explicitly fixing up the
+ msg_type here. */
+ rep->msg_type = KRB5_AS_REP;
+
+ /* AS-REP ::= [APPLICATION 11] KDC-REP */
+ retval = asn1_encode_kdc_rep(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+ krb5_apptag(11);
+
+ krb5_cleanup();
+}
+
+/* yes, the translation is identical to that used for KDC__REP */
+krb5_error_code encode_krb5_tgs_rep(DECLARG(const krb5_kdc_rep *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_kdc_rep *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+/* if(rep->msg_type != KRB5_TGS_REP) return KRB5_BADMSGTYPE;*/
+ rep->msg_type = KRB5_TGS_REP;
+
+ /* TGS-REP ::= [APPLICATION 13] KDC-REP */
+ retval = asn1_encode_kdc_rep(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+ krb5_apptag(13);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_ap_req(DECLARG(const krb5_ap_req *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_ap_req *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* authenticator[4] EncryptedData */
+ krb5_addfield(&(rep->authenticator),4,asn1_encode_encrypted_data);
+
+ /* ticket[3] Ticket */
+ krb5_addfield(rep->ticket,3,asn1_encode_ticket);
+
+ /* ap-options[2] APOptions */
+ krb5_addfield(rep->ap_options,2,asn1_encode_ap_options);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_AP_REQ,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* AP-REQ ::= [APPLICATION 14] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(14);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_ap_rep(DECLARG(const krb5_ap_rep *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_ap_rep *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* enc-part[2] EncryptedData */
+ krb5_addfield(&(rep->enc_part),2,asn1_encode_encrypted_data);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_AP_REP,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* AP-REP ::= [APPLICATION 15] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(15);
+
+ krb5_cleanup();
+}
+
+
+krb5_error_code encode_krb5_ap_rep_enc_part(DECLARG(const krb5_ap_rep_enc_part *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_ap_rep_enc_part *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* seq-number[3] INTEGER OPTIONAL */
+ if(rep->seq_number)
+ krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+
+ /* subkey[2] EncryptionKey OPTIONAL */
+ if(rep->subkey != NULL)
+ krb5_addfield(rep->subkey,2,asn1_encode_encryption_key);
+
+ /* cusec[1] INTEGER */
+ krb5_addfield(rep->cusec,1,asn1_encode_integer);
+
+ /* ctime[0] KerberosTime */
+ krb5_addfield(rep->ctime,0,asn1_encode_kerberos_time);
+
+ /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(27);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_as_req(DECLARG(const krb5_kdc_req *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_kdc_req *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+/* if(rep->msg_type != KRB5_AS_REQ) return KRB5_BADMSGTYPE;*/
+ rep->msg_type = KRB5_AS_REQ;
+
+ /* AS-REQ ::= [APPLICATION 10] KDC-REQ */
+ retval = asn1_encode_kdc_req(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+ krb5_apptag(10);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_tgs_req(DECLARG(const krb5_kdc_req *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_kdc_req *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+/* if(rep->msg_type != KRB5_TGS_REQ) return KRB5_BADMSGTYPE;*/
+ rep->msg_type = KRB5_TGS_REQ;
+
+ /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */
+ retval = asn1_encode_kdc_req(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+ krb5_apptag(12);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_kdc_req_body(DECLARG(const krb5_kdc_req *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_kdc_req *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ retval = asn1_encode_kdc_req_body(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+
+ krb5_cleanup();
+}
+
+
+krb5_error_code encode_krb5_safe(DECLARG(const krb5_safe *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_safe *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* cksum[3] Checksum */
+ krb5_addfield(rep->checksum,3,asn1_encode_checksum);
+
+ /* safe-body[2] KRB-SAFE-BODY */
+ krb5_addfield(rep,2,asn1_encode_krb_safe_body);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(20);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_priv(DECLARG(const krb5_priv *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_priv *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* enc-part[3] EncryptedData */
+ krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_PRIV,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(21);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_enc_priv_part(DECLARG(const krb5_priv_enc_part *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_priv_enc_part *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* r-address[5] HostAddress OPTIONAL -- recip's addr */
+ if(rep->r_address)
+ krb5_addfield(rep->r_address,5,asn1_encode_host_address);
+
+ /* s-address[4] HostAddress -- sender's addr */
+ krb5_addfield(rep->s_address,4,asn1_encode_host_address);
+
+ /* seq-number[3] INTEGER OPTIONAL */
+ if(rep->seq_number)
+ krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+
+ /* usec[2] INTEGER OPTIONAL */
+ if(rep->timestamp){
+ krb5_addfield(rep->usec,2,asn1_encode_integer);
+ /* timestamp[1] KerberosTime OPTIONAL */
+ krb5_addfield(rep->timestamp,1,asn1_encode_kerberos_time);
+ }
+
+ /* user-data[0] OCTET STRING */
+ krb5_addlenfield(rep->user_data.length,rep->user_data.data,0,asn1_encode_charstring);
+
+ /* EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(28);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_cred(DECLARG(const krb5_cred *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_cred *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* enc-part[3] EncryptedData */
+ krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
+
+ /* tickets[2] SEQUENCE OF Ticket */
+ krb5_addfield((const krb5_ticket**)rep->tickets,2,asn1_encode_sequence_of_ticket);
+
+ /* msg-type[1] INTEGER, -- KRB_CRED */
+ krb5_addfield(ASN1_KRB_CRED,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(22);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_enc_cred_part(DECLARG(const krb5_cred_enc_part *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_cred_enc_part *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* r-address[5] HostAddress OPTIONAL */
+ if(rep->r_address != NULL)
+ krb5_addfield(rep->r_address,5,asn1_encode_host_address);
+
+ /* s-address[4] HostAddress OPTIONAL */
+ if(rep->s_address != NULL)
+ krb5_addfield(rep->s_address,4,asn1_encode_host_address);
+
+ /* usec[3] INTEGER OPTIONAL */
+ if(rep->timestamp){
+ krb5_addfield(rep->usec,3,asn1_encode_integer);
+ /* timestamp[2] KerberosTime OPTIONAL */
+ krb5_addfield(rep->timestamp,2,asn1_encode_kerberos_time);
+ }
+
+ /* nonce[1] INTEGER OPTIONAL */
+ if(rep->nonce)
+ krb5_addfield(rep->nonce,1,asn1_encode_integer);
+
+ /* ticket-info[0] SEQUENCE OF KrbCredInfo */
+ krb5_addfield((const krb5_cred_info**)rep->ticket_info,
+ 0,asn1_encode_sequence_of_krb_cred_info);
+
+ /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(29);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_error(DECLARG(const krb5_error *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_error *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+
+ /* e-data[12] OCTET STRING OPTIONAL */
+ if(rep->e_data.data != NULL && rep->e_data.length > 0)
+ krb5_addlenfield(rep->e_data.length,rep->e_data.data,12,asn1_encode_charstring);
+
+ /* e-text[11] GeneralString OPTIONAL */
+ if(rep->text.data != NULL && rep->text.length > 0)
+ krb5_addlenfield(rep->text.length,rep->text.data,11,asn1_encode_generalstring);
+
+ /* sname[10] PrincipalName -- Correct name */
+ krb5_addfield(rep->server,10,asn1_encode_principal_name);
+
+ /* realm[9] Realm -- Correct realm */
+ krb5_addfield(rep->server,9,asn1_encode_realm);
+
+ /* cname[8] PrincipalName OPTIONAL */
+ if(rep->client != NULL){
+ krb5_addfield(rep->client,8,asn1_encode_principal_name);
+ /* crealm[7] Realm OPTIONAL */
+ krb5_addfield(rep->client,7,asn1_encode_realm);
+ }
+
+ /* error-code[6] INTEGER */
+ krb5_addfield(rep->error,6,asn1_encode_ui_4);
+
+ /* susec[5] INTEGER */
+ krb5_addfield(rep->susec,5,asn1_encode_integer);
+
+ /* stime[4] KerberosTime */
+ krb5_addfield(rep->stime,4,asn1_encode_kerberos_time);
+
+ /* cusec[3] INTEGER OPTIONAL */
+ if(rep->cusec)
+ krb5_addfield(rep->cusec,3,asn1_encode_integer);
+
+ /* ctime[2] KerberosTime OPTIONAL */
+ if(rep->ctime)
+ krb5_addfield(rep->ctime,2,asn1_encode_kerberos_time);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_ERROR,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(30);
+
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_authdata(DECLARG(const krb5_authdata **, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_authdata **, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ asn1_error_code retval;
+ asn1buf *buf=NULL;
+ int length;
+
+ if(rep == NULL) return ASN1_MISSING_FIELD;
+
+ retval = asn1buf_create(&buf);
+ if(retval) return retval;
+
+ retval = asn1_encode_authorization_data(buf,(const krb5_authdata**)rep,
+ &length);
+ if(retval) return retval;
+
+ krb5_cleanup();
+}
+
+/* Sandia Additions */
+krb5_error_code encode_krb5_pwd_sequence(DECLARG(const passwd_phrase_element *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const passwd_phrase_element *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+ retval = asn1_encode_passwdsequence(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pwd_data(DECLARG(const krb5_pwd_data *, rep),
+ DECLARG(krb5_data **, code))
+ OLDDECLARG(const krb5_pwd_data *, rep)
+ OLDDECLARG(krb5_data **, code)
+{
+ krb5_setup();
+ krb5_addfield((const passwd_phrase_element**)rep->element,1,asn1_encode_sequence_of_passwdsequence);
+ krb5_addfield(rep->sequence_count,0,asn1_encode_integer);
+ krb5_makeseq();
+ krb5_cleanup();
+}
--- /dev/null
+#ifndef __KRB5_ENCODE_H__
+#define __KRB5_ENCODE_H__
+
+#include <krb5/krb5.h>
+
+/*
+ krb5_error_code encode_krb5_structure(const krb5_structure *rep,
+ krb5_data **code);
+ modifies *code
+ effects Returns the ASN.1 encoding of *rep in **code.
+ Returns ASN1_MISSING_FIELD if a required field is emtpy in *rep.
+ Returns ENOMEM if memory runs out.
+*/
+
+krb5_error_code encode_krb5_authenticator
+ PROTOTYPE((const krb5_authenticator *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_ticket
+ PROTOTYPE((const krb5_ticket *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_encryption_key
+ PROTOTYPE((const krb5_keyblock *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_enc_tkt_part
+ PROTOTYPE((const krb5_enc_tkt_part *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_enc_kdc_rep_part
+ PROTOTYPE((const krb5_enc_kdc_rep_part *rep, krb5_data **code));
+
+/* yes, the translation is identical to that used for KDC__REP */
+krb5_error_code encode_krb5_as_rep
+ PROTOTYPE((const krb5_kdc_rep *rep, krb5_data **code));
+
+/* yes, the translation is identical to that used for KDC__REP */
+krb5_error_code encode_krb5_tgs_rep
+ PROTOTYPE((const krb5_kdc_rep *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_ap_req
+ PROTOTYPE((const krb5_ap_req *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_ap_rep
+ PROTOTYPE((const krb5_ap_rep *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_ap_rep_enc_part
+ PROTOTYPE((const krb5_ap_rep_enc_part *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_as_req
+ PROTOTYPE((const krb5_kdc_req *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_tgs_req
+ PROTOTYPE((const krb5_kdc_req *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_kdc_req_body
+ PROTOTYPE((const krb5_kdc_req *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_safe
+ PROTOTYPE((const krb5_safe *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_priv
+ PROTOTYPE((const krb5_priv *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_enc_priv_part
+ PROTOTYPE((const krb5_priv_enc_part *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_cred
+ PROTOTYPE((const krb5_cred *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_enc_cred_part
+ PROTOTYPE((const krb5_cred_enc_part *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_error
+ PROTOTYPE((const krb5_error *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_authdata
+ PROTOTYPE((const krb5_authdata **rep, krb5_data **code));
+
+krb5_error_code encode_krb5_pwd_sequence
+ PROTOTYPE((const passwd_phrase_element *rep, krb5_data **code));
+
+krb5_error_code encode_krb5_pwd_data
+ PROTOTYPE((const krb5_pwd_data *rep, krb5_data **code));
+
+#endif
--- /dev/null
+#ifndef __KRBASN1_H__
+#define __KRBASN1_H__
+
+#include <krb5/krb5.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+/* The current version of {en,de}code_krb5_enc_kdc_rep_part has a
+ problem in that there's no way to know the message type (AS/TGS) of
+ a krb5_enc_kdc_rep_part. This should be fixed in the next version
+ by including a msg_type field in krb5_enc_kdc_rep_part. When that
+ happens, #defining ENCKRB5KDCREPPART_HAS_MSGTYPE will activate the
+ code that uses it. */
+/* #define ENCKRB5KDCREPPART_HAS_MSGTYPE */
+
+typedef krb5_octet asn1_octet;
+typedef krb5_error_code asn1_error_code;
+
+typedef enum { PRIMITIVE = 0x00, CONSTRUCTED = 0x20 } asn1_construction;
+
+typedef enum { UNIVERSAL = 0x00, APPLICATION = 0x40,
+ CONTEXT_SPECIFIC = 0x80, PRIVATE = 0xC0 } asn1_class;
+
+typedef int asn1_tagnum;
+#define ASN1_TAGNUM_CEILING INT_MAX
+#define ASN1_TAGNUM_MAX (ASN1_TAGNUM_CEILING-1)
+
+/* This is Kerberos Version 5 */
+#define KVNO 5
+
+/* Universal Tag Numbers */
+#define ASN1_INTEGER 2
+#define ASN1_BITSTRING 3
+#define ASN1_OCTETSTRING 4
+#define ASN1_NULL 5
+#define ASN1_OBJECTIDENTIFIER 6
+#define ASN1_SEQUENCE 16
+#define ASN1_SET 17
+#define ASN1_PRINTABLESTRING 19
+#define ASN1_IA5STRING 22
+#define ASN1_UTCTIME 23
+#define ASN1_GENERALTIME 24
+#define ASN1_GENERALSTRING 27
+
+/* Kerberos Message Types */
+#define ASN1_KRB_AS_REQ 10
+#define ASN1_KRB_AS_REP 11
+#define ASN1_KRB_TGS_REQ 12
+#define ASN1_KRB_TGS_REP 13
+#define ASN1_KRB_AP_REQ 14
+#define ASN1_KRB_AP_REP 15
+#define ASN1_KRB_SAFE 20
+#define ASN1_KRB_PRIV 21
+#define ASN1_KRB_CRED 22
+#define ASN1_KRB_ERROR 30
+
+#endif
--- /dev/null
+Tue Jun 28 19:11:43 1994 Tom Yu (tlyu at dragons-lair)
+
+ * Makefile.in: doing the right thing with new error tables
+
+ * configure.in: adding ISODE_DEFS
+ * init_ets.c: folding in Harry's changes
+
CC = @CC@
CCOPTS = @CCOPTS@
LIBS = @LIBS@
+ASN1_HDRS=@ASN1_HDRS@
+ASN1_OBJS=@ASN1_OBJS@
+ASN1_SRCS=@ASN1_SRCS@
+BOGUS=@BOGUS@
CFLAGS = $(CCOPTS) $(DEFS)
LDFLAGS = -g
EHDRDIR=$(BUILDTOP)/include/krb5
-HDRS=isode_err.h kdb5_err.h krb5_err.h adm_err.h
-OBJS=isode_err.o kdb5_err.o krb5_err.o adm_err.o init_ets.o
-ETSRCS=isode_err.c kdb5_err.c krb5_err.c adm_err.c
+HDRS=$(ASN1_SRCS) kdb5_err.h krb5_err.h adm_err.h
+OBJS=$(ASN1_OBJS) kdb5_err.o krb5_err.o adm_err.o init_ets.o
+ETSRCS=$(ASN1_SRCS) kdb5_err.c krb5_err.c adm_err.c
SRCS=$(ETSRCS) $(srcdir)/init_ets.c
all:: ${HDRS} includes ${OBJS}
#
# dependencies for traditional makes
#
+asn1_err.o: asn1_err.c
isode_err.o: isode_err.c
kdb5_err.o: kdb5_err.c
krb5_err.o: krb5_err.c
adm_err.o: adm_err.c
+$(BOGUS)::
+ echo '/* not using isode */' > $@
clean::
$(RM) $(HDRS) $(ETSRCS)
clean::
$(RM) $(OBJS)
-
-
--- /dev/null
+error_table asn1
+error_code ASN1_BAD_TIMEFORMAT, "ASN.1 failed call to system time library"
+error_code ASN1_MISSING_FIELD, "ASN.1 structure is missing a required field"
+error_code ASN1_MISPLACED_FIELD, "ASN.1 unexpected field number"
+error_code ASN1_TYPE_MISMATCH, "ASN.1 type numbers are inconsistent"
+error_code ASN1_OVERFLOW, "ASN.1 value too large"
+error_code ASN1_OVERRUN, "ASN.1 encoding ended unexpectedly"
+error_code ASN1_BAD_ID, "ASN.1 identifier doesn't match expected value"
+error_code ASN1_BAD_LENGTH, "ASN.1 length doesn't match expected value"
+error_code ASN1_BAD_FORMAT, "ASN.1 badly-formatted encoding"
+error_code ASN1_PARSE_ERROR, "ASN.1 parse error"
+end
AC_INIT(configure.in)
WITH_CCOPTS
+ISODE_DEFS
CONFIG_RULES
AC_SET_BUILDTOP
ET_RULES
SS_RULES
KRB_INCLUDE
+AC_ENABLE([isode],[
+ASN1_HDRS=isode_err.h
+ASN1_OBJS=isode_err.o
+ASN1_SRCS=isode_err.c
+BOGUS=nosuchtarget],[
+ASN1_HDRS=asn1_err.h
+ASN1_OBJS=asn1_err.o
+ASN1_SRCS=asn1_err.c
+BOGUS="isode_err.c isode_err.h"])
+AC_SUBST(ASN1_HDRS)
+AC_SUBST(ASN1_OBJS)
+AC_SUBST(ASN1_SRCS)
+AC_SUBST(BOGUS)
SubdirLibraryRule([${OBJS}])
CopyHeader(isode_err.h,[$(EHDRDIR)])
CopyHeader(krb5_err.h,[$(EHDRDIR)])
CopyHeader(kdb5_err.h,[$(EHDRDIR)])
CopyHeader(adm_err.h,[$(EHDRDIR)])
+CopyHeader(asn1_err.h,[$(EHDRDIR)])
AC_OUTPUT(Makefile,[EXTRA_RULES])
initialized++;
initialize_krb5_error_table();
initialize_kdb5_error_table();
+#ifdef KRB5_USE_ISDOE
initialize_isod_error_table();
+#else
+ initialize_asn1_error_table();
+#endif
}
--- /dev/null
+Tue Jun 28 19:35:07 1994 Tom Yu (tlyu at dragons-lair)
+
+ * decode_kdc.c: folding in Harry's changes
+ * rd_req.c: ditto
+ * rd_req_sim.c: ditto
+ * configure.in: adding ISODE_DEFS
+
AC_INIT(configure.in)
WITH_CCOPTS
CONFIG_RULES
+ISODE_DEFS
AC_SET_BUILDTOP
AC_PROG_ARCHIVE
AC_PROG_ARCHIVE_ADD
when finished with the response.
If the response isn't a KDC_REP (tgs or as), it returns an error from
- the decoding routines (usually ISODE_50_LOCAL_ERR_BADDECODE).
+ the decoding routines.
returns errors from encryption routines, system errors
*/
return KRB5KRB_AP_ERR_MSG_TYPE;
if (retval = decode_krb5_ap_req(inbuf, &request)) {
switch (retval) {
+#ifdef KRB5_USE_ISDOE
case ISODE_50_LOCAL_ERR_BADMSGTYPE:
+#else
+ case KRB5_BADMSGTYPE:
+#endif
return KRB5KRB_AP_ERR_BADVERSION;
default:
return(retval);
return KRB5KRB_AP_ERR_MSG_TYPE;
if (retval = decode_krb5_ap_req(inbuf, &request)) {
switch (retval) {
+#ifdef KRB5_USE_ISDOE
case ISODE_50_LOCAL_ERR_BADMSGTYPE:
+#else
+ case KRB5_BADMSGTYPE:
+#endif
return KRB5KRB_AP_ERR_BADVERSION;
default:
return(retval);
SRCTOP = $(srcdir)/$(BUILDTOP)
TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
DBMLIB=
KDBLIB=$(TOPLIBD)/libkdb5.a
--- /dev/null
+Wed Jun 29 00:26:31 1994 Tom Yu (tlyu at dragons-lair)
+
+ * test1.c: added call to krb5_init_ets
+
main()
{
- initialize_isod_error_table();
- initialize_krb5_error_table();
+ krb5_init_ets();
tkt_test_1();
}