From: Tom Yu Date: Wed, 29 Jun 1994 05:35:50 +0000 (+0000) Subject: folding in Harry's changes X-Git-Tag: krb5-1.0-beta4.2~186 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ba0c614172f11219c430b17cd14602d9f7e629e3;p=krb5.git folding in Harry's changes git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@3924 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/aclocal.m4 b/src/aclocal.m4 index a0e8cf05f..b51cdac78 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -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 diff --git a/src/admin/aname/Makefile.in b/src/admin/aname/Makefile.in index 25ce2bd43..eb150e56f 100644 --- a/src/admin/aname/Makefile.in +++ b/src/admin/aname/Makefile.in @@ -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/admin/convert/Makefile.in b/src/admin/convert/Makefile.in index a9899d90f..54cbf5827 100644 --- a/src/admin/convert/Makefile.in +++ b/src/admin/convert/Makefile.in @@ -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 index 000000000..5a76f9635 --- /dev/null +++ b/src/admin/create/ChangeLog @@ -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() + diff --git a/src/admin/create/Makefile.in b/src/admin/create/Makefile.in index 88fefa30e..51ab59fd2 100644 --- a/src/admin/create/Makefile.in +++ b/src/admin/create/Makefile.in @@ -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/admin/create/kdb5_create.c b/src/admin/create/kdb5_create.c index 113d59988..2fc736e69 100644 --- a/src/admin/create/kdb5_create.c +++ b/src/admin/create/kdb5_create.c @@ -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 index 000000000..0b249c509 --- /dev/null +++ b/src/admin/destroy/ChangeLog @@ -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 + diff --git a/src/admin/destroy/Makefile.in b/src/admin/destroy/Makefile.in index aa51dbd85..a5135b546 100644 --- a/src/admin/destroy/Makefile.in +++ b/src/admin/destroy/Makefile.in @@ -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/admin/destroy/kdb5_destroy.c b/src/admin/destroy/kdb5_destroy.c index 94e954fd6..93dd6e70a 100644 --- a/src/admin/destroy/kdb5_destroy.c +++ b/src/admin/destroy/kdb5_destroy.c @@ -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; diff --git a/src/admin/edit/Makefile.in b/src/admin/edit/Makefile.in index 06cc4e72a..d4b50e866 100644 --- a/src/admin/edit/Makefile.in +++ b/src/admin/edit/Makefile.in @@ -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 index 000000000..1044c11ad --- /dev/null +++ b/src/admin/stash/ChangeLog @@ -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 + diff --git a/src/admin/stash/Makefile.in b/src/admin/stash/Makefile.in index 9212f96a5..e0e44a9c7 100644 --- a/src/admin/stash/Makefile.in +++ b/src/admin/stash/Makefile.in @@ -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/admin/stash/kdb5_stash.c b/src/admin/stash/kdb5_stash.c index 634bb4fab..758dec0d5 100644 --- a/src/admin/stash/kdb5_stash.c +++ b/src/admin/stash/kdb5_stash.c @@ -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) { diff --git a/src/appl/sample/sclient/Makefile.in b/src/appl/sample/sclient/Makefile.in index 6011e9919..6033e99e0 100644 --- a/src/appl/sample/sclient/Makefile.in +++ b/src/appl/sample/sclient/Makefile.in @@ -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= diff --git a/src/appl/sample/sserver/Makefile.in b/src/appl/sample/sserver/Makefile.in index 8c3a0585b..ab21b52a1 100644 --- a/src/appl/sample/sserver/Makefile.in +++ b/src/appl/sample/sserver/Makefile.in @@ -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= diff --git a/src/appl/simple/client/Makefile.in b/src/appl/simple/client/Makefile.in index 00d339a5b..84dd58524 100644 --- a/src/appl/simple/client/Makefile.in +++ b/src/appl/simple/client/Makefile.in @@ -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= diff --git a/src/appl/simple/server/Makefile.in b/src/appl/simple/server/Makefile.in index f2c094d60..f9c2fe729 100644 --- a/src/appl/simple/server/Makefile.in +++ b/src/appl/simple/server/Makefile.in @@ -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= diff --git a/src/appl/telnet/libtelnet/Makefile.in b/src/appl/telnet/libtelnet/Makefile.in index ea78f6263..f64ee09fb 100644 --- a/src/appl/telnet/libtelnet/Makefile.in +++ b/src/appl/telnet/libtelnet/Makefile.in @@ -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= diff --git a/src/appl/user_user/Makefile.in b/src/appl/user_user/Makefile.in index 7ff8ffa4d..3c7ac4850 100644 --- a/src/appl/user_user/Makefile.in +++ b/src/appl/user_user/Makefile.in @@ -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= diff --git a/src/clients/kdestroy/Makefile.in b/src/clients/kdestroy/Makefile.in index 512ee22dc..5792177b8 100644 --- a/src/clients/kdestroy/Makefile.in +++ b/src/clients/kdestroy/Makefile.in @@ -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= diff --git a/src/clients/kinit/Makefile.in b/src/clients/kinit/Makefile.in index 8158ea7a6..6e43d4564 100644 --- a/src/clients/kinit/Makefile.in +++ b/src/clients/kinit/Makefile.in @@ -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= diff --git a/src/clients/klist/Makefile.in b/src/clients/klist/Makefile.in index ba826681b..6b118bbe2 100644 --- a/src/clients/klist/Makefile.in +++ b/src/clients/klist/Makefile.in @@ -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= diff --git a/src/configure.in b/src/configure.in index 1c45d873f..1e1ff3663 100644 --- a/src/configure.in +++ b/src/configure.in @@ -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) diff --git a/src/include/krb5/ChangeLog b/src/include/krb5/ChangeLog index c32dab58a..6346e0629 100644 --- a/src/include/krb5/ChangeLog +++ b/src/include/krb5/ChangeLog @@ -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 index 000000000..dd11f8367 --- /dev/null +++ b/src/include/krb5/asn.1/ChangeLog @@ -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 + diff --git a/src/include/krb5/asn.1/encode.h b/src/include/krb5/asn.1/encode.h index 028c59157..4197a8bb1 100644 --- a/src/include/krb5/asn.1/encode.h +++ b/src/include/krb5/asn.1/encode.h @@ -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 +#include +#include +#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 index 000000000..b548c06b5 --- /dev/null +++ b/src/include/krb5/asn.1/krb5_is.h @@ -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 diff --git a/src/include/krb5/asn1.h b/src/include/krb5/asn1.h index e8f53ba32..2bdfebbeb 100644 --- a/src/include/krb5/asn1.h +++ b/src/include/krb5/asn1.h @@ -30,9 +30,11 @@ #ifndef KRB5_ASN1__ #define KRB5_ASN1__ +#ifdef KRB5_USE_ISODE #include #include #include +#endif #include #endif /* KRB5_ASN1__ */ diff --git a/src/include/krb5/configure.in b/src/include/krb5/configure.in index 3d70dc92f..e6204a181 100644 --- a/src/include/krb5/configure.in +++ b/src/include/krb5/configure.in @@ -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 diff --git a/src/include/krb5/error_def.h b/src/include/krb5/error_def.h index f1cf2d2ab..31a296e8d 100644 --- a/src/include/krb5/error_def.h +++ b/src/include/krb5/error_def.h @@ -32,7 +32,11 @@ #include #include +#ifndef KRB5_USE_ISODE +#include +#else #include +#endif #include #endif /* KRB5_ERROR_DEF__ */ diff --git a/src/kadmin/client/Makefile.in b/src/kadmin/client/Makefile.in index 2e1694ad4..5ad562f01 100644 --- a/src/kadmin/client/Makefile.in +++ b/src/kadmin/client/Makefile.in @@ -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/kadmin/kpasswd/Makefile.in b/src/kadmin/kpasswd/Makefile.in index a7add62a4..39e7f0dfa 100644 --- a/src/kadmin/kpasswd/Makefile.in +++ b/src/kadmin/kpasswd/Makefile.in @@ -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= diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog index e71cdd6ba..a1ad0ea12 100644 --- a/src/kadmin/server/ChangeLog +++ b/src/kadmin/server/ChangeLog @@ -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 diff --git a/src/kadmin/server/adm_server.c b/src/kadmin/server/adm_server.c index 7d2a3cb32..a660dade8 100644 --- a/src/kadmin/server/adm_server.c +++ b/src/kadmin/server/adm_server.c @@ -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 index 000000000..18fb1e92e --- /dev/null +++ b/src/kdc/ChangeLog @@ -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 + diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in index acb7aadb3..24960cd8e 100644 --- a/src/kdc/Makefile.in +++ b/src/kdc/Makefile.in @@ -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 diff --git a/src/kdc/configure.in b/src/kdc/configure.in index 1797cd092..7ccf4edc3 100644 --- a/src/kdc/configure.in +++ b/src/kdc/configure.in @@ -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) diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index a96756e19..73dc3fcbe 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -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"; diff --git a/src/kdc/main.c b/src/kdc/main.c index 1dd6871ff..e896a4533 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -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; } diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog index 82acf23e7..20b2691fc 100644 --- a/src/lib/krb5/asn.1/ChangeLog +++ b/src/lib/krb5/asn.1/ChangeLog @@ -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 index 000000000..af7f12eb7 --- /dev/null +++ b/src/lib/krb5/asn.1/Imakefile @@ -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 b/src/lib/krb5/asn.1/Makefile.in.isode similarity index 100% rename from src/lib/krb5/asn.1/Makefile.in rename to src/lib/krb5/asn.1/Makefile.in.isode diff --git a/src/lib/krb5/asn.1/Makefile.in.sane b/src/lib/krb5/asn.1/Makefile.in.sane new file mode 100644 index 000000000..63d043fa0 --- /dev/null +++ b/src/lib/krb5/asn.1/Makefile.in.sane @@ -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 index 000000000..7274ad56b --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_decode.c @@ -0,0 +1,181 @@ +/* ASN.1 primitive decoders */ +#include "asn1_decode.h" +#include "asn1_get.h" +#include + +#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 index 000000000..576908456 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_decode.h @@ -0,0 +1,62 @@ +#ifndef __ASN1_DECODE_H__ +#define __ASN1_DECODE_H__ + +#include +#include "krbasn1.h" +#include "asn1buf.h" + +/* + Overview + + These procedures take an asn1buf whose current position points + to the beginning of an ASN.1 primitive (). + 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 index 000000000..734d7aa41 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_decode_k.c @@ -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 index 000000000..efbb059b7 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_decode_k.h @@ -0,0 +1,136 @@ +#ifndef __ASN1_DECODE_KRB5_H__ +#define __ASN1_DECODE_KRB5_H__ + +#include +#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 ( ), + *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 ( ), + *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 ( ) + 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 index 000000000..6b9920f5f --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_encode.c @@ -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 index 000000000..0f79dcedb --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_encode.h @@ -0,0 +1,118 @@ +#ifndef __ASN1_ENCODE_H__ +#define __ASN1_ENCODE_H__ + +#include +#include +#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 index 000000000..f270e2aed --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_encode_k.c @@ -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 index 000000000..7a0f62a43 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_encode_k.h @@ -0,0 +1,195 @@ +#ifndef __ASN1_ENCODE_KRB5_H__ +#define __ASN1_ENCODE_KRB5_H__ + +#include +#include +#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 index 000000000..67e74ce88 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_get.c @@ -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 index 000000000..1e4896bc8 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_get.h @@ -0,0 +1,55 @@ +#ifndef __ASN1_GET_H__ +#define __ASN1_GET_H__ + +/* ASN.1 substructure decoding procedures */ + +#include +#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 index 000000000..c4cbcf7f9 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_make.c @@ -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 index 000000000..527e93c41 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_make.h @@ -0,0 +1,109 @@ +#ifndef __ASN1_MAKE_H__ +#define __ASN1_MAKE_H__ + +#include +#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 index 000000000..80583c416 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_misc.c @@ -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 index 000000000..38506e817 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1_misc.h @@ -0,0 +1,13 @@ +#ifndef __ASN1_MISC_H__ +#define __ASN1_MISC_H__ + +#include +#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 index 000000000..e3d610b61 --- /dev/null +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -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 + +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; inext)[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; inext)[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("")+1, sizeof(char)); + if(*s == NULL) return ENOMEM; + strcpy(*s,""); + }else if(buf->base == NULL){ + *s = calloc(sizeof("")+1, sizeof(char)); + if(*s == NULL) return ENOMEM; + strcpy(*s,""); + }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; ibase)[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("")+1, sizeof(char)); + if(*s == NULL) return ENOMEM; + strcpy(*s,""); + }else if(buf->base == NULL){ + *s = calloc(sizeof("")+1, sizeof(char)); + if(*s == NULL) return ENOMEM; + strcpy(*s,""); + }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 index 000000000..b734f55ee --- /dev/null +++ b/src/lib/krb5/asn.1/asn1buf.h @@ -0,0 +1,182 @@ +/* Coding Buffer Specifications */ +#ifndef __ASN1BUF_H__ +#define __ASN1BUF_H__ + +#include +#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 diff --git a/src/lib/krb5/asn.1/configure.in b/src/lib/krb5/asn.1/configure.in index efeec8525..13c826a00 100644 --- a/src/lib/krb5/asn.1/configure.in +++ b/src/lib/krb5/asn.1/configure.in @@ -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 index 000000000..4cd06b834 --- /dev/null +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -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]> ) + 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 index 000000000..671a794a0 --- /dev/null +++ b/src/lib/krb5/asn.1/krb5_decode.h @@ -0,0 +1,83 @@ +#ifndef __KRB5_DECODE_H__ +#define __KRB5_DECODE_H__ + +#include + +/* + 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 index 000000000..2c1e4de00 --- /dev/null +++ b/src/lib/krb5/asn.1/krb5_encode.c @@ -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 index 000000000..4841fd928 --- /dev/null +++ b/src/lib/krb5/asn.1/krb5_encode.h @@ -0,0 +1,83 @@ +#ifndef __KRB5_ENCODE_H__ +#define __KRB5_ENCODE_H__ + +#include + +/* + 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 index 000000000..b1305036e --- /dev/null +++ b/src/lib/krb5/asn.1/krbasn1.h @@ -0,0 +1,58 @@ +#ifndef __KRBASN1_H__ +#define __KRBASN1_H__ + +#include +#include +#include +#include + +/* 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 index 000000000..555036a1a --- /dev/null +++ b/src/lib/krb5/error_tables/ChangeLog @@ -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 + diff --git a/src/lib/krb5/error_tables/Makefile.in b/src/lib/krb5/error_tables/Makefile.in index d14597080..2a5ccd66b 100644 --- a/src/lib/krb5/error_tables/Makefile.in +++ b/src/lib/krb5/error_tables/Makefile.in @@ -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 index 000000000..9d823c1ab --- /dev/null +++ b/src/lib/krb5/error_tables/asn1_err.et @@ -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 diff --git a/src/lib/krb5/error_tables/configure.in b/src/lib/krb5/error_tables/configure.in index 639300f49..dd8375b40 100644 --- a/src/lib/krb5/error_tables/configure.in +++ b/src/lib/krb5/error_tables/configure.in @@ -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]) diff --git a/src/lib/krb5/error_tables/init_ets.c b/src/lib/krb5/error_tables/init_ets.c index 2fdd4ec41..22005c289 100644 --- a/src/lib/krb5/error_tables/init_ets.c +++ b/src/lib/krb5/error_tables/init_ets.c @@ -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 index 000000000..1d58ffc4f --- /dev/null +++ b/src/lib/krb5/krb/ChangeLog @@ -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 + diff --git a/src/lib/krb5/krb/configure.in b/src/lib/krb5/krb/configure.in index f4046555a..04bb44270 100644 --- a/src/lib/krb5/krb/configure.in +++ b/src/lib/krb5/krb/configure.in @@ -1,6 +1,7 @@ AC_INIT(configure.in) WITH_CCOPTS CONFIG_RULES +ISODE_DEFS AC_SET_BUILDTOP AC_PROG_ARCHIVE AC_PROG_ARCHIVE_ADD diff --git a/src/lib/krb5/krb/decode_kdc.c b/src/lib/krb5/krb/decode_kdc.c index a59013a89..78515bbcd 100644 --- a/src/lib/krb5/krb/decode_kdc.c +++ b/src/lib/krb5/krb/decode_kdc.c @@ -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 */ diff --git a/src/lib/krb5/krb/rd_req.c b/src/lib/krb5/krb/rd_req.c index 0dbf44184..48dda1516 100644 --- a/src/lib/krb5/krb/rd_req.c +++ b/src/lib/krb5/krb/rd_req.c @@ -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); diff --git a/src/lib/krb5/krb/rd_req_sim.c b/src/lib/krb5/krb/rd_req_sim.c index 0e77cdf48..39a7e6599 100644 --- a/src/lib/krb5/krb/rd_req_sim.c +++ b/src/lib/krb5/krb/rd_req_sim.c @@ -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); diff --git a/src/slave/Makefile.in b/src/slave/Makefile.in index c4fd6856a..b913c6315 100644 --- a/src/slave/Makefile.in +++ b/src/slave/Makefile.in @@ -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 index 000000000..ad6afa846 --- /dev/null +++ b/src/tests/ChangeLog @@ -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 + diff --git a/src/tests/test1.c b/src/tests/test1.c index 3b886b83c..412dfaae0 100644 --- a/src/tests/test1.c +++ b/src/tests/test1.c @@ -194,7 +194,6 @@ tkt_test_1() main() { - initialize_isod_error_table(); - initialize_krb5_error_table(); + krb5_init_ets(); tkt_test_1(); }