folding in Harry's changes
authorTom Yu <tlyu@mit.edu>
Wed, 29 Jun 1994 05:35:50 +0000 (05:35 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 29 Jun 1994 05:35:50 +0000 (05:35 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@3924 dc483132-0cff-0310-8789-dd5450dbe970

78 files changed:
src/aclocal.m4
src/admin/aname/Makefile.in
src/admin/convert/Makefile.in
src/admin/create/ChangeLog [new file with mode: 0644]
src/admin/create/Makefile.in
src/admin/create/kdb5_create.c
src/admin/destroy/ChangeLog [new file with mode: 0644]
src/admin/destroy/Makefile.in
src/admin/destroy/kdb5_destroy.c
src/admin/edit/Makefile.in
src/admin/stash/ChangeLog [new file with mode: 0644]
src/admin/stash/Makefile.in
src/admin/stash/kdb5_stash.c
src/appl/sample/sclient/Makefile.in
src/appl/sample/sserver/Makefile.in
src/appl/simple/client/Makefile.in
src/appl/simple/server/Makefile.in
src/appl/telnet/libtelnet/Makefile.in
src/appl/user_user/Makefile.in
src/clients/kdestroy/Makefile.in
src/clients/kinit/Makefile.in
src/clients/klist/Makefile.in
src/configure.in
src/include/krb5/ChangeLog
src/include/krb5/asn.1/ChangeLog [new file with mode: 0644]
src/include/krb5/asn.1/encode.h
src/include/krb5/asn.1/krb5_is.h [new file with mode: 0644]
src/include/krb5/asn1.h
src/include/krb5/configure.in
src/include/krb5/error_def.h
src/kadmin/client/Makefile.in
src/kadmin/kpasswd/Makefile.in
src/kadmin/server/ChangeLog
src/kadmin/server/adm_server.c
src/kdc/ChangeLog [new file with mode: 0644]
src/kdc/Makefile.in
src/kdc/configure.in
src/kdc/do_tgs_req.c
src/kdc/main.c
src/lib/krb5/asn.1/ChangeLog
src/lib/krb5/asn.1/Imakefile [new file with mode: 0644]
src/lib/krb5/asn.1/Makefile.in.isode [moved from src/lib/krb5/asn.1/Makefile.in with 100% similarity]
src/lib/krb5/asn.1/Makefile.in.sane [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_decode.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_decode.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_decode_k.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_decode_k.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_encode.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_encode.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_encode_k.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_encode_k.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_get.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_get.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_make.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_make.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_misc.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1_misc.h [new file with mode: 0644]
src/lib/krb5/asn.1/asn1buf.c [new file with mode: 0644]
src/lib/krb5/asn.1/asn1buf.h [new file with mode: 0644]
src/lib/krb5/asn.1/configure.in
src/lib/krb5/asn.1/krb5_decode.c [new file with mode: 0644]
src/lib/krb5/asn.1/krb5_decode.h [new file with mode: 0644]
src/lib/krb5/asn.1/krb5_encode.c [new file with mode: 0644]
src/lib/krb5/asn.1/krb5_encode.h [new file with mode: 0644]
src/lib/krb5/asn.1/krbasn1.h [new file with mode: 0644]
src/lib/krb5/error_tables/ChangeLog [new file with mode: 0644]
src/lib/krb5/error_tables/Makefile.in
src/lib/krb5/error_tables/asn1_err.et [new file with mode: 0644]
src/lib/krb5/error_tables/configure.in
src/lib/krb5/error_tables/init_ets.c
src/lib/krb5/krb/ChangeLog [new file with mode: 0644]
src/lib/krb5/krb/configure.in
src/lib/krb5/krb/decode_kdc.c
src/lib/krb5/krb/rd_req.c
src/lib/krb5/krb/rd_req_sim.c
src/slave/Makefile.in
src/tests/ChangeLog [new file with mode: 0644]
src/tests/test1.c

index a0e8cf05f4eba6a8238d7895756b6a84b5bae079..b51cdac7840390cba93580964bc455f6fbba4532 100644 (file)
@@ -391,7 +391,7 @@ dnl
 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
 
@@ -421,7 +421,10 @@ dnl
 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
@@ -453,3 +456,8 @@ fi
 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
index 25ce2bd43aff7a2d467ee712044246792a98f8ce..eb150e56fbb9790a3412c4ef9d19761f92b0f433 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
index a9899d90f4229612f88f0062bfcd198cbbe39a63..54cbf58270f9c102228d7fa139f82068a65f6ade 100644 (file)
@@ -29,7 +29,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a
diff --git a/src/admin/create/ChangeLog b/src/admin/create/ChangeLog
new file mode 100644 (file)
index 0000000..5a76f96
--- /dev/null
@@ -0,0 +1,5 @@
+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()
+
index 88fefa30efcfa2bfcf2f0fe56d645b099376ca4d..51ab59fd27339530e2f6d7b044e2c91fb80fc523 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
index 113d59988d47d9f551a43ed38bc4b7339958a3a9..2fc736e69946d59fd6c1e75468f2f973c0641823 100644 (file)
@@ -136,9 +136,7 @@ char *argv[];
     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;
diff --git a/src/admin/destroy/ChangeLog b/src/admin/destroy/ChangeLog
new file mode 100644 (file)
index 0000000..0b249c5
--- /dev/null
@@ -0,0 +1,4 @@
+Wed Jun 29 00:22:07 1994  Tom Yu  (tlyu at dragons-lair)
+
+       * kdb5_destroy.c: fix things to call krb5_init_ets
+
index aa51dbd85f74e5cf96e3faae5aae0a1986e8fdb8..a5135b5465c3aed689b148a71f2fd407aa7b4ac5 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
index 94e954fd6bf7d884f83e167e1ead75402f6ebff6..93dd6e70a6269dea8a57930af2f835ce65b344f8 100644 (file)
@@ -67,9 +67,7 @@ char *argv[];
     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;
index 06cc4e72a42e537410a1bc5c948f74e4ecd516e8..d4b50e86662b1f1f18c780194b9c90b5749dce24 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 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=
diff --git a/src/admin/stash/ChangeLog b/src/admin/stash/ChangeLog
new file mode 100644 (file)
index 0000000..1044c11
--- /dev/null
@@ -0,0 +1,4 @@
+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
+
index 9212f96a5a49a60de6e4438672737395f7b51146..e0e44a9c79ead7785293fdc82a847460af2c195b 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
index 634bb4fabd5d16f1d78fb4d75935690080f2b73a..758dec0d50fbe0beeaa14e410821347480a84cf1 100644 (file)
@@ -80,9 +80,7 @@ char *argv[];
     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) {
index 6011e99197512d744c853b2a7019e88b70bcad34..6033e99e015481b0b43541f92bf6f21422fcc317 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 8c3a0585b78a4efd326c23a0f3c890e864c1546e..ab21b52a16e7f87f85afbd6bcc5d45b282306d1a 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 00d339a5b76040d9fed6bda651049719b90b9e34..84dd58524c46cd2f8a8ee8a2ddae2dbc53505cb1 100644 (file)
@@ -13,7 +13,7 @@ LDFLAGS = -g
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index f2c094d604e46f9b898b3d298cc0ff746cfcd3ce..f9c2fe729cf2ace3fbdc9c4fc627662f17f29773 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index ea78f626326b57e48cde4018d9360c47cd417f4e..f64ee09fbd976cf0c866abb8b340e4fefc4378dd 100644 (file)
@@ -12,7 +12,7 @@ LDFLAGS = -g
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 7ff8ffa4d2ae10ffaa984f4629a97408d1dbc7a0..3c7ac48506fc33fafc26bc70e004a53d93cb8296 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 512ee22dcc573b8815ce21a6d67490ed6665a8f5..5792177b836d28f8160271d181fe6a598a25e087 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 8158ea7a6a6e576cdbbd06c37ff6240c4d86810a..6e43d45647db28c584a29b282052b604c9c5cefd 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index ba826681bc67ad8971413e5267b8137e71814682..6b118bbe286f8b70ede327447672fdfbaca7ffa6 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 
index 1c45d873f1e8a38529bab01251481055c2942f8a..1e1ff3663ea8d25aedd3947ce8e9480d16cc159a 100644 (file)
@@ -3,7 +3,8 @@ WITH_CCOPTS
 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)
index c32dab58a2abaa1ab67f34272f5c08640b610de4..6346e0629a633f1fa5b987a6cc5a9e1277fe3232 100644 (file)
@@ -1,3 +1,9 @@
+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
diff --git a/src/include/krb5/asn.1/ChangeLog b/src/include/krb5/asn.1/ChangeLog
new file mode 100644 (file)
index 0000000..dd11f83
--- /dev/null
@@ -0,0 +1,5 @@
+Tue Jun 28 23:20:58 1994  Tom Yu  (tlyu at dragons-lair)
+
+       * encode.h:
+       * krb5_is.h: ....folding in Harry's changes
+
index 028c59157547e56b42acf4a6c01ec3b504af5663..4197a8bb1bb13de4a323b81aee0b6e0f3cf60303 100644 (file)
@@ -30,6 +30,7 @@
 #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 * ));
@@ -370,4 +371,9 @@ krb5_error_code krb5_decode_generic
                                    (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__ */
diff --git a/src/include/krb5/asn.1/krb5_is.h b/src/include/krb5/asn.1/krb5_is.h
new file mode 100644 (file)
index 0000000..b548c06
--- /dev/null
@@ -0,0 +1,79 @@
+#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
index e8f53ba32998d564712c1e2b059c8cc12d3ec7e4..2bdfebbeb4b69303d8610f4ab163c9e44c872be8 100644 (file)
 #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__ */
index 3d70dc92faa8708f65c69402528d3cb7a10b1770..e6204a181a7a4364d13c5161f70bfa0c8a29806f 100644 (file)
@@ -1,6 +1,7 @@
 AC_INIT(acconfig.h)
 AC_SET_BUILDTOP
 CONFIG_RULES
+ISODE_DEFS
 AC_CONFIG_HEADER(autoconf.h)
 AC_PROG_LEX
 HAVE_YYLINENO
index f1cf2d2ab6a144abf00f688bd2f8a02118237862..31a296e8da62f355bdc35c2cbe1de56846586883 100644 (file)
 
 #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__ */
index 2e1694ad4f73cedebaa82268d82660ae6a14bff4..5ad562f0175500e20500e386b0b359940c699987 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 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=
index a7add62a46e9575b95898b3ca7a3b384e7dee3e6..39e7f0dfac03396e80737f7ef281d4108715c510 100644 (file)
@@ -28,7 +28,7 @@ LDFLAGS = -g
 
 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=
index e71cdd6baa071604acacdb9a189ef09cf1125a8c..a1ad0ea124e444841e8384ec75650068944739ae 100644 (file)
@@ -1,3 +1,7 @@
+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
index 7d2a3cb32d3789723e64cbf6e0e1c8629ecb4a0c..a660dade8fd30e7cb941bc6dff40c45de25395f8 100644 (file)
@@ -419,9 +419,7 @@ kdc_com_err_proc(whoami, code, format, pvar)
 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;
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog
new file mode 100644 (file)
index 0000000..18fb1e9
--- /dev/null
@@ -0,0 +1,7 @@
+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
+
index acb7aadb3577cd52d67cb8a3a65679484c866f02..24960cd8e87498f7b8e95827efc4d4ac92bd6f81 100644 (file)
@@ -30,7 +30,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
index 1797cd0926a68a50637589d5de54db53ef42e578..7ccf4edc394cfbb4313a5c760ee54e72f8e9b71b 100644 (file)
@@ -1,6 +1,7 @@
 AC_INIT(main.c)
 WITH_CCOPTS
 CONFIG_RULES
+ISODE_DEFS
 AC_SET_BUILDTOP
 AC_HAVE_LIBRARY(socket)
 AC_HAVE_LIBRARY(nsl)
index a96756e199c1973012bc81f8a548d3a8ad1f3984..73dc3fcbed6405ee6a8c525df1a13399c4bc236a 100644 (file)
@@ -400,7 +400,11 @@ tgt_again:
            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";
index 1dd6871ffa76156d089c05d2f4b818dc5314f1df..e896a4533494da8c9d0b622f65390224a9916880 100644 (file)
@@ -106,11 +106,8 @@ kdc_com_err_proc(whoami, code, format, pvar)
 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;
 }
index 82acf23e7ffe7d931f6a9950d7147885b67512f2..20b2691fc64ffc1a9794b3039cca58efa4a82f1c 100644 (file)
@@ -1,5 +1,5 @@
-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
 
diff --git a/src/lib/krb5/asn.1/Imakefile b/src/lib/krb5/asn.1/Imakefile
new file mode 100644 (file)
index 0000000..af7f12e
--- /dev/null
@@ -0,0 +1,80 @@
+#      $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::
diff --git a/src/lib/krb5/asn.1/Makefile.in.sane b/src/lib/krb5/asn.1/Makefile.in.sane
new file mode 100644 (file)
index 0000000..63d043f
--- /dev/null
@@ -0,0 +1,63 @@
+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
diff --git a/src/lib/krb5/asn.1/asn1_decode.c b/src/lib/krb5/asn.1/asn1_decode.c
new file mode 100644 (file)
index 0000000..7274ad5
--- /dev/null
@@ -0,0 +1,181 @@
+/* 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();
+}
diff --git a/src/lib/krb5/asn.1/asn1_decode.h b/src/lib/krb5/asn.1/asn1_decode.h
new file mode 100644 (file)
index 0000000..5769084
--- /dev/null
@@ -0,0 +1,62 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_decode_k.c b/src/lib/krb5/asn.1/asn1_decode_k.c
new file mode 100644 (file)
index 0000000..734d7aa
--- /dev/null
@@ -0,0 +1,678 @@
+#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);
+}
diff --git a/src/lib/krb5/asn.1/asn1_decode_k.h b/src/lib/krb5/asn.1/asn1_decode_k.h
new file mode 100644 (file)
index 0000000..efbb059
--- /dev/null
@@ -0,0 +1,136 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
new file mode 100644 (file)
index 0000000..6b9920f
--- /dev/null
@@ -0,0 +1,226 @@
+/* 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;
+}
diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h
new file mode 100644 (file)
index 0000000..0f79dce
--- /dev/null
@@ -0,0 +1,118 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_encode_k.c b/src/lib/krb5/asn.1/asn1_encode_k.c
new file mode 100644 (file)
index 0000000..f270e2a
--- /dev/null
@@ -0,0 +1,872 @@
+#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();
+}
diff --git a/src/lib/krb5/asn.1/asn1_encode_k.h b/src/lib/krb5/asn.1/asn1_encode_k.h
new file mode 100644 (file)
index 0000000..7a0f62a
--- /dev/null
@@ -0,0 +1,195 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_get.c b/src/lib/krb5/asn.1/asn1_get.c
new file mode 100644 (file)
index 0000000..67e74ce
--- /dev/null
@@ -0,0 +1,111 @@
+#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;
+}
diff --git a/src/lib/krb5/asn.1/asn1_get.h b/src/lib/krb5/asn.1/asn1_get.h
new file mode 100644 (file)
index 0000000..1e4896b
--- /dev/null
@@ -0,0 +1,55 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_make.c b/src/lib/krb5/asn.1/asn1_make.c
new file mode 100644 (file)
index 0000000..c4cbcf7
--- /dev/null
@@ -0,0 +1,177 @@
+#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;
+}
diff --git a/src/lib/krb5/asn.1/asn1_make.h b/src/lib/krb5/asn.1/asn1_make.h
new file mode 100644 (file)
index 0000000..527e93c
--- /dev/null
@@ -0,0 +1,109 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1_misc.c b/src/lib/krb5/asn.1/asn1_misc.c
new file mode 100644 (file)
index 0000000..80583c4
--- /dev/null
@@ -0,0 +1,15 @@
+#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;
+}
diff --git a/src/lib/krb5/asn.1/asn1_misc.h b/src/lib/krb5/asn.1/asn1_misc.h
new file mode 100644 (file)
index 0000000..38506e8
--- /dev/null
@@ -0,0 +1,13 @@
+#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
diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c
new file mode 100644 (file)
index 0000000..e3d610b
--- /dev/null
@@ -0,0 +1,350 @@
+/* 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;
+}
diff --git a/src/lib/krb5/asn.1/asn1buf.h b/src/lib/krb5/asn.1/asn1buf.h
new file mode 100644 (file)
index 0000000..b734f55
--- /dev/null
@@ -0,0 +1,182 @@
+/* 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
index efeec85256585da40343a9f28edd42b780da3891..13c826a0054243e7f6eb9cafe4f1745d207e7cc0 100644 (file)
@@ -2,13 +2,27 @@ AC_INIT(configure.in)
 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
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
new file mode 100644 (file)
index 0000000..4cd06b8
--- /dev/null
@@ -0,0 +1,577 @@
+#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();
+}
diff --git a/src/lib/krb5/asn.1/krb5_decode.h b/src/lib/krb5/asn.1/krb5_decode.h
new file mode 100644 (file)
index 0000000..671a794
--- /dev/null
@@ -0,0 +1,83 @@
+#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
diff --git a/src/lib/krb5/asn.1/krb5_encode.c b/src/lib/krb5/asn.1/krb5_encode.c
new file mode 100644 (file)
index 0000000..2c1e4de
--- /dev/null
@@ -0,0 +1,737 @@
+#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();
+}
diff --git a/src/lib/krb5/asn.1/krb5_encode.h b/src/lib/krb5/asn.1/krb5_encode.h
new file mode 100644 (file)
index 0000000..4841fd9
--- /dev/null
@@ -0,0 +1,83 @@
+#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
diff --git a/src/lib/krb5/asn.1/krbasn1.h b/src/lib/krb5/asn.1/krbasn1.h
new file mode 100644 (file)
index 0000000..b130503
--- /dev/null
@@ -0,0 +1,58 @@
+#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
diff --git a/src/lib/krb5/error_tables/ChangeLog b/src/lib/krb5/error_tables/ChangeLog
new file mode 100644 (file)
index 0000000..555036a
--- /dev/null
@@ -0,0 +1,7 @@
+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
+
index d14597080e8bb3f4da8fb2d81c343278cfc7afb3..2a5ccd66bfa9a95dc5566a13fe264285c75c695b 100644 (file)
@@ -6,6 +6,10 @@ DEFS = @DEFS@
 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
@@ -18,9 +22,9 @@ AWK = @AWK@
 
 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}
@@ -28,16 +32,17 @@ 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)
-
-
diff --git a/src/lib/krb5/error_tables/asn1_err.et b/src/lib/krb5/error_tables/asn1_err.et
new file mode 100644 (file)
index 0000000..9d823c1
--- /dev/null
@@ -0,0 +1,12 @@
+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
index 639300f496b1b00aa848b724dfae89109cc21c6a..dd8375b4071e6711161d5e09db375e09be8830f5 100644 (file)
@@ -1,13 +1,28 @@
 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])
index 2fdd4ec41592375b0ff2bd79ddcbc88df4ab367f..22005c289eb58257e834d722c86abb4dd0f3b7c3 100644 (file)
@@ -43,5 +43,9 @@ krb5_init_ets PROTOTYPE((void))
     initialized++;
     initialize_krb5_error_table();
     initialize_kdb5_error_table();
+#ifdef KRB5_USE_ISDOE
     initialize_isod_error_table();
+#else
+    initialize_asn1_error_table();
+#endif
 }
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
new file mode 100644 (file)
index 0000000..1d58ffc
--- /dev/null
@@ -0,0 +1,7 @@
+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
+
index f4046555a9e33a91a232372f10e1361641a0ca11..04bb442704fa975e980d3997191c3dce78648983 100644 (file)
@@ -1,6 +1,7 @@
 AC_INIT(configure.in)
 WITH_CCOPTS
 CONFIG_RULES
+ISODE_DEFS
 AC_SET_BUILDTOP
 AC_PROG_ARCHIVE
 AC_PROG_ARCHIVE_ADD
index a59013a89780f95fac22bbb3f9ed0ac9ad4ef02f..78515bbcd581f771283b19df3fd5bd626976aa3c 100644 (file)
@@ -44,7 +44,7 @@ static char rcsid_decode_kdc_c[] =
  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
  */
index 0dbf441844820a7efb28c4994ff2d321da9cf509..48dda1516f9068858533d80524ef74cb06674af7 100644 (file)
@@ -87,7 +87,11 @@ krb5_tkt_authent **authdat;
        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);
index 0e77cdf48b15de29fc7f9f72fec0835be95d2d3e..39a7e6599ad12b45e8e67475d3d7a548d6efd580 100644 (file)
@@ -68,7 +68,11 @@ krb5_tkt_authent **authdat;
        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);
index c4fd6856add5d683b2ca251755aeec110d64dbfa..b913c631584177b13d27ca4e9a87ec459e3ba340 100644 (file)
@@ -28,7 +28,7 @@ KRB5_INCSUBDIRS = \
 
 SRCTOP = $(srcdir)/$(BUILDTOP)
 TOPLIBD = $(BUILDTOP)/lib
-ISODELIB=$(TOPLIBD)/libisode.a
+ISODELIB=@ISODELIB@
 COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
 DBMLIB=
 KDBLIB=$(TOPLIBD)/libkdb5.a 
diff --git a/src/tests/ChangeLog b/src/tests/ChangeLog
new file mode 100644 (file)
index 0000000..ad6afa8
--- /dev/null
@@ -0,0 +1,4 @@
+Wed Jun 29 00:26:31 1994  Tom Yu  (tlyu at dragons-lair)
+
+       * test1.c: added call to krb5_init_ets
+
index 3b886b83c56ce68c306f79501293a4dc491ebfb0..412dfaae02c0ec9244bc4c86c9e5e9d3a3875d98 100644 (file)
@@ -194,7 +194,6 @@ tkt_test_1()
 
 main()
 {
-    initialize_isod_error_table();
-    initialize_krb5_error_table();
+    krb5_init_ets();
     tkt_test_1();
 }