aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5
diff options
context:
space:
mode:
authorPaul Park <pjpark@mit.edu>1995-08-29 18:39:10 +0000
committerPaul Park <pjpark@mit.edu>1995-08-29 18:39:10 +0000
commit898bf1e2f45c34371b42d83ece7200cb170b6582 (patch)
tree785a29f2a83c12deab91a88ded189e9b2afa667e /src/lib/krb5
parentf0bcdc5996b5176020d96e12ef477ed1acd1dd5c (diff)
downloadkrb5-898bf1e2f45c34371b42d83ece7200cb170b6582.zip
krb5-898bf1e2f45c34371b42d83ece7200cb170b6582.tar.gz
krb5-898bf1e2f45c34371b42d83ece7200cb170b6582.tar.bz2
Add serialization support for K5 data structures
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6622 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5')
-rw-r--r--src/lib/krb5/krb/.Sanitize10
-rw-r--r--src/lib/krb5/krb/Makefile.in33
-rw-r--r--src/lib/krb5/krb/ser_actx.c558
-rw-r--r--src/lib/krb5/krb/ser_adata.c207
-rw-r--r--src/lib/krb5/krb/ser_addr.c209
-rw-r--r--src/lib/krb5/krb/ser_auth.c356
-rw-r--r--src/lib/krb5/krb/ser_cksum.c210
-rw-r--r--src/lib/krb5/krb/ser_ctx.c468
-rw-r--r--src/lib/krb5/krb/ser_eblk.c266
-rw-r--r--src/lib/krb5/krb/ser_key.c217
-rw-r--r--src/lib/krb5/krb/ser_princ.c189
-rw-r--r--src/lib/krb5/krb/serialize.c277
12 files changed, 2997 insertions, 3 deletions
diff --git a/src/lib/krb5/krb/.Sanitize b/src/lib/krb5/krb/.Sanitize
index 7ea5027..584394c 100644
--- a/src/lib/krb5/krb/.Sanitize
+++ b/src/lib/krb5/krb/.Sanitize
@@ -88,6 +88,16 @@ rd_safe.c
recvauth.c
send_tgs.c
sendauth.c
+ser_actx.c
+ser_addr.c
+ser_adata.c
+ser_auth.c
+ser_cksum.c
+ser_ctx.c
+ser_eblk.c
+ser_key.c
+ser_princ.c
+serialize.c
srv_rcache.c
t_walk_rtree.c
t_kerb.c
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 5ec8dc3..de0effd 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -65,6 +65,16 @@ OBJS= addr_comp.$(OBJEXT) \
recvauth.$(OBJEXT) \
sendauth.$(OBJEXT) \
send_tgs.$(OBJEXT) \
+ ser_actx.$(OBJEXT) \
+ ser_adata.$(OBJEXT) \
+ ser_addr.$(OBJEXT) \
+ ser_auth.$(OBJEXT) \
+ ser_cksum.$(OBJEXT) \
+ ser_ctx.$(OBJEXT) \
+ ser_eblk.$(OBJEXT) \
+ ser_key.$(OBJEXT) \
+ ser_princ.$(OBJEXT) \
+ serialize.$(OBJEXT) \
srv_rcache.$(OBJEXT) \
tgtname.$(OBJEXT) \
unparse.$(OBJEXT) \
@@ -127,6 +137,16 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/recvauth.c \
$(srcdir)/sendauth.c \
$(srcdir)/send_tgs.c \
+ $(srcdir)/ser_actx.c \
+ $(srcdir)/ser_adata.c \
+ $(srcdir)/ser_addr.c \
+ $(srcdir)/ser_auth.c \
+ $(srcdir)/ser_cksum.c \
+ $(srcdir)/ser_ctx.c \
+ $(srcdir)/ser_eblk.c \
+ $(srcdir)/ser_key.c \
+ $(srcdir)/ser_princ.c \
+ $(srcdir)/serialize.c \
$(srcdir)/srv_rcache.c \
$(srcdir)/tgtname.c \
$(srcdir)/unparse.c \
@@ -150,13 +170,20 @@ T_WALK_RTREE_OBJS= t_walk_rtree.o walk_rtree.o tgtname.o unparse.o \
T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o \
$(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(COMERRLIB)
+T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \
+ ser_ctx.o ser_eblk.o ser_key.o ser_princ.o serialize.o \
+ $(TOPLIBD)/libkdb5.a $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(COMERRLIB)
+
t_walk_rtree: $(T_WALK_RTREE_OBJS)
$(LD) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(LIBS)
t_kerb: $(T_KERB_OBJS)
$(LD) -o t_kerb $(T_KERB_OBJS) $(LIBS)
-TEST_PROGS= t_walk_rtree t_kerb
+t_ser: $(T_SER_OBJS)
+ $(LD) -o t_ser $(T_SER_OBJS) $(LIBS)
+
+TEST_PROGS= t_walk_rtree t_kerb t_ser
check:: check-$(WHAT)
@@ -172,8 +199,7 @@ check-unix:: $(TEST_PROGS)
> test.out
cmp test.out $(srcdir)/t_ref_kerb.out
$(RM) test.out
-
-
+ ./t_ser
check-mac:: $(TEST_PROGS)
@@ -182,6 +208,7 @@ check-windows::
clean:: clean-$(WHAT)
$(RM) t_walk_rtree$(EXEEXT) t_walk_rtree.$(OBJEXT)
$(RM) t_kerb$(EXEEXT) t_kerb.$(OBJEXT)
+ $(RM) t_ser$(EXEEXT) t_ser.$(OBJEXT)
clean-unix::
$(RM) shared/*
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
new file mode 100644
index 0000000..0b0cdd4
--- /dev/null
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -0,0 +1,558 @@
+/*
+ * lib/krb5/krb/ser_actx.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_actx.c - Serialize krb5_auth_context structure.
+ */
+#include "k5-int.h"
+#include "auth_con.h"
+
+#define TOKEN_RADDR 950916
+#define TOKEN_RPORT 950917
+#define TOKEN_LADDR 950918
+#define TOKEN_LPORT 950919
+#define TOKEN_KEYBLOCK 950920
+#define TOKEN_LSKBLOCK 950921
+#define TOKEN_RSKBLOCK 950922
+
+/*
+ * Routines to deal with externalizing the krb5_auth_context:
+ * krb5_auth_context_size();
+ * krb5_auth_context_externalize();
+ * krb5_auth_context_internalize();
+ */
+static krb5_error_code krb5_auth_context_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_auth_context_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_auth_context_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/*
+ * Other metadata serialization initializers.
+ */
+krb5_error_code krb5_ser_authdata_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_address_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_authenticator_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_checksum_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_encrypt_block_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_keyblock_init KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_ser_principal_init KRB5_PROTOTYPE((krb5_context));
+
+/* Local data */
+static const krb5_ser_entry krb5_auth_context_ser_entry = {
+ KV5M_AUTH_CONTEXT, /* Type */
+ krb5_auth_context_size, /* Sizer routine */
+ krb5_auth_context_externalize, /* Externalize routine */
+ krb5_auth_context_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_auth_context_size() - Determine the size required to externalize
+ * the krb5_auth_context.
+ */
+static krb5_error_code
+krb5_auth_context_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_auth_context auth_context;
+ size_t required;
+
+ /*
+ * krb5_auth_context requires at minimum:
+ * krb5_int32 for KV5M_AUTH_CONTEXT
+ * krb5_int32 for auth_context_flags
+ * krb5_int32 for remote_seq_number
+ * krb5_int32 for local_seq_number
+ * krb5_int32 for cksumtype
+ * krb5_int32 for size of i_vector
+ * krb5_int32 for KV5M_AUTH_CONTEXT
+ */
+ kret = EINVAL;
+ if ((auth_context = (krb5_auth_context) arg)) {
+ required = sizeof(krb5_int32)*7;
+
+ kret = 0;
+ /* Calculate size required by i_vector - ptooey */
+ if (auth_context->i_vector && auth_context->keyblock)
+ required += (size_t)
+ krb5_keytype_array[auth_context->keyblock->keytype]->
+ system->block_length;
+
+ /* Calculate size required by remote_addr, if appropriate */
+ if (auth_context->remote_addr) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer) auth_context->remote_addr,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by remote_port, if appropriate */
+ if (!kret && auth_context->remote_port) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer) auth_context->remote_port,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by local_addr, if appropriate */
+ if (!kret && auth_context->local_addr) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer) auth_context->local_addr,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by local_port, if appropriate */
+ if (!kret && auth_context->local_port) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer) auth_context->local_port,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by keyblock, if appropriate */
+ if (!kret && auth_context->keyblock) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer) auth_context->keyblock,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by local_subkey, if appropriate */
+ if (!kret && auth_context->local_subkey) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer) auth_context->local_subkey,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by remote_subkey, if appropriate */
+ if (!kret && auth_context->remote_subkey) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer) auth_context->remote_subkey,
+ &required);
+ if (!kret)
+ required += sizeof(krb5_int32);
+ }
+
+ /* Calculate size required by authentp, if appropriate */
+ if (!kret && auth_context->authentp)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_AUTHENTICATOR,
+ (krb5_pointer) auth_context->authentp,
+ &required);
+
+ }
+ if (!kret)
+ *sizep += required;
+ return(kret);
+}
+
+/*
+ * krb5_auth_context_externalize() - Externalize the krb5_auth_context.
+ */
+static krb5_error_code
+krb5_auth_context_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_auth_context auth_context;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+ krb5_int32 obuf;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((auth_context = (krb5_auth_context) arg)) {
+ kret = ENOMEM;
+ if (!krb5_auth_context_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+
+ /* Write fixed portion */
+ (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain);
+ (void) krb5_ser_pack_int32(auth_context->auth_context_flags,
+ &bp, &remain);
+ (void) krb5_ser_pack_int32(auth_context->remote_seq_number,
+ &bp, &remain);
+ (void) krb5_ser_pack_int32(auth_context->local_seq_number,
+ &bp, &remain);
+ (void) krb5_ser_pack_int32((krb5_int32) auth_context->cksumtype,
+ &bp, &remain);
+
+ /* Now figure out the number of bytes for i_vector and write it */
+ obuf = (!auth_context->i_vector) ? 0 : (krb5_int32)
+ krb5_keytype_array[auth_context->keyblock->keytype]->
+ system->block_length;
+ (void) krb5_ser_pack_int32(obuf, &bp, &remain);
+
+ /* Now copy i_vector */
+ if (auth_context->i_vector)
+ (void) krb5_ser_pack_bytes(auth_context->i_vector,
+ (size_t) obuf,
+ &bp, &remain);
+ kret = 0;
+
+ /* Now handle remote_addr, if appropriate */
+ if (!kret && auth_context->remote_addr) {
+ (void) krb5_ser_pack_int32(TOKEN_RADDR, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer)
+ auth_context->remote_addr,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle remote_port, if appropriate */
+ if (!kret && auth_context->remote_port) {
+ (void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer)
+ auth_context->remote_addr,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle local_addr, if appropriate */
+ if (!kret && auth_context->local_addr) {
+ (void) krb5_ser_pack_int32(TOKEN_LADDR, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer)
+ auth_context->local_addr,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle local_port, if appropriate */
+ if (!kret && auth_context->local_port) {
+ (void) krb5_ser_pack_int32(TOKEN_LPORT, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer)
+ auth_context->local_addr,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle keyblock, if appropriate */
+ if (!kret && auth_context->keyblock) {
+ (void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer)
+ auth_context->keyblock,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle subkey, if appropriate */
+ if (!kret && auth_context->local_subkey) {
+ (void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer)
+ auth_context->local_subkey,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle subkey, if appropriate */
+ if (!kret && auth_context->remote_subkey) {
+ (void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain);
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer)
+ auth_context->remote_subkey,
+ &bp,
+ &remain);
+ }
+
+ /* Now handle authentp, if appropriate */
+ if (!kret && auth_context->authentp)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_AUTHENTICATOR,
+ (krb5_pointer)
+ auth_context->authentp,
+ &bp,
+ &remain);
+
+ /*
+ * If we were successful, write trailer then update the pointer and
+ * remaining length;
+ */
+ if (!kret) {
+ /* Write our trailer */
+ (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain);
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_auth_context_internalize() - Internalize the krb5_auth_context.
+ */
+static krb5_error_code
+krb5_auth_context_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_auth_context auth_context;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+ krb5_int32 ivlen;
+ krb5_int32 tag;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_AUTH_CONTEXT) {
+ kret = ENOMEM;
+
+ /* Get memory for the auth_context */
+ if ((remain >= (5*sizeof(krb5_int32))) &&
+ (auth_context = (krb5_auth_context)
+ malloc(sizeof(struct _krb5_auth_context)))) {
+ memset(auth_context, 0, sizeof(struct _krb5_auth_context));
+
+ /* Get auth_context_flags */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ auth_context->auth_context_flags = ibuf;
+
+ /* Get remote_seq_number */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ auth_context->remote_seq_number = ibuf;
+
+ /* Get local_seq_number */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ auth_context->local_seq_number = ibuf;
+
+ /* Get cksumtype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ auth_context->cksumtype = (krb5_cksumtype) ibuf;
+
+ /* Get length of i_vector */
+ (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain);
+
+ if (ivlen) {
+ if ((auth_context->i_vector =
+ (krb5_pointer) malloc((size_t)ivlen)))
+ kret = krb5_ser_unpack_bytes(auth_context->i_vector,
+ (size_t) ivlen,
+ &bp,
+ &remain);
+ else
+ kret = ENOMEM;
+ }
+ else
+ kret = 0;
+
+ /* Peek at next token */
+ tag = 0;
+ if (!kret)
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+
+ /* This is the remote_addr */
+ if (!kret && (tag == TOKEN_RADDR)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer *)
+ &auth_context->
+ remote_addr,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the remote_port */
+ if (!kret && (tag == TOKEN_RPORT)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer *)
+ &auth_context->
+ remote_port,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the local_addr */
+ if (!kret && (tag == TOKEN_LADDR)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer *)
+ &auth_context->
+ local_addr,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the local_port */
+ if (!kret && (tag == TOKEN_LPORT)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_ADDRESS,
+ (krb5_pointer *)
+ &auth_context->
+ local_port,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the keyblock */
+ if (!kret && (tag == TOKEN_KEYBLOCK)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer *)
+ &auth_context->keyblock,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the local_subkey */
+ if (!kret && (tag == TOKEN_LSKBLOCK)) {
+ if (!(kret = krb5_internalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer *)
+ &auth_context->
+ local_subkey,
+ &bp,
+ &remain)))
+ kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
+ }
+
+ /* This is the remote_subkey */
+ if (!kret) {
+ if (tag == TOKEN_RSKBLOCK) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer *)
+ &auth_context->
+ remote_subkey,
+ &bp,
+ &remain);
+ }
+ else {
+ /*
+ * We read the next tag, but it's not of any use here, so
+ * we effectively 'unget' it here.
+ */
+ bp -= sizeof(krb5_int32);
+ remain += sizeof(krb5_int32);
+ }
+ }
+
+ /* Now find the authentp */
+ if (!kret) {
+ if ((kret = krb5_internalize_opaque(kcontext,
+ KV5M_AUTHENTICATOR,
+ (krb5_pointer *)
+ &auth_context->authentp,
+ &bp,
+ &remain))) {
+ if (kret == EINVAL)
+ kret = 0;
+ }
+ }
+
+ /* Finally, find the trailer */
+ if (!kret) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf != KV5M_AUTH_CONTEXT))
+ kret = EINVAL;
+ }
+ if (!kret) {
+ *buffer = bp;
+ *lenremain = remain;
+ auth_context->magic = KV5M_AUTH_CONTEXT;
+ *argp = (krb5_pointer) auth_context;
+ }
+ else
+ krb5_auth_con_free(kcontext, auth_context);
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the auth_context serializer.
+ */
+krb5_error_code
+krb5_ser_auth_context_init(kcontext)
+ krb5_context kcontext;
+{
+ krb5_error_code kret;
+ kret = krb5_register_serializer(kcontext, &krb5_auth_context_ser_entry);
+ if (!kret)
+ kret = krb5_ser_authdata_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_address_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_authenticator_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_checksum_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_encrypt_block_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_keyblock_init(kcontext);
+ if (!kret)
+ kret = krb5_ser_principal_init(kcontext);
+ return(kret);
+}
diff --git a/src/lib/krb5/krb/ser_adata.c b/src/lib/krb5/krb/ser_adata.c
new file mode 100644
index 0000000..cfcced4
--- /dev/null
+++ b/src/lib/krb5/krb/ser_adata.c
@@ -0,0 +1,207 @@
+/*
+ * lib/krb5/krb/ser_adata.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_adata.c - Serialize a krb5_authdata structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_authdata:
+ * krb5_authdata_size();
+ * krb5_authdata_externalize();
+ * krb5_authdata_internalize();
+ */
+static krb5_error_code krb5_authdata_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_authdata_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_authdata_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_authdata_ser_entry = {
+ KV5M_AUTHDATA, /* Type */
+ krb5_authdata_size, /* Sizer routine */
+ krb5_authdata_externalize, /* Externalize routine */
+ krb5_authdata_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_authdata_esize() - Determine the size required to externalize
+ * the krb5_authdata.
+ */
+static krb5_error_code
+krb5_authdata_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_authdata *authdata;
+
+ /*
+ * krb5_authdata requires:
+ * krb5_int32 for KV5M_AUTHDATA
+ * krb5_int32 for ad_type
+ * krb5_int32 for length
+ * authdata->length for contents
+ * krb5_int32 for KV5M_AUTHDATA
+ */
+ kret = EINVAL;
+ if ((authdata = (krb5_authdata *) arg)) {
+ *sizep += (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (size_t) authdata->length);
+ kret = 0;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_authdata_externalize() - Externalize the krb5_authdata.
+ */
+static krb5_error_code
+krb5_authdata_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_authdata *authdata;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((authdata = (krb5_authdata *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_authdata_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* Our identifier */
+ (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain);
+
+ /* Our ad_type */
+ (void) krb5_ser_pack_int32((krb5_int32) authdata->ad_type,
+ &bp, &remain);
+
+ /* Our length */
+ (void) krb5_ser_pack_int32((krb5_int32) authdata->length,
+ &bp, &remain);
+
+ /* Our contents */
+ (void) krb5_ser_pack_bytes(authdata->contents,
+ (size_t) authdata->length,
+ &bp, &remain);
+
+ /* Finally, our trailer */
+ (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain);
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_authdata_internalize() - Internalize the krb5_authdata.
+ */
+static krb5_error_code
+krb5_authdata_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_authdata *authdata;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_AUTHDATA) {
+ kret = ENOMEM;
+
+ /* Get a authdata */
+ if ((remain >= (2*sizeof(krb5_int32))) &&
+ (authdata = (krb5_authdata *) malloc(sizeof(krb5_authdata)))) {
+ memset(authdata, 0, sizeof(krb5_authdata));
+
+ /* Get the ad_type */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ authdata->ad_type = (krb5_authdatatype) ibuf;
+
+ /* Get the length */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ authdata->length = (int) ibuf;
+
+ /* Get the string */
+ if ((authdata->contents = (krb5_octet *)
+ malloc((size_t) (ibuf))) &&
+ !(kret = krb5_ser_unpack_bytes(authdata->contents,
+ (size_t) ibuf,
+ &bp, &remain))) {
+ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+ ibuf = 0;
+ if (ibuf == KV5M_AUTHDATA) {
+ authdata->magic = KV5M_AUTHDATA;
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = (krb5_pointer) authdata;
+ }
+ else
+ kret = EINVAL;
+ }
+ if (kret) {
+ if (authdata->contents)
+ free(authdata->contents);
+ free(authdata);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the authdata serializer.
+ */
+krb5_error_code
+krb5_ser_authdata_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_authdata_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_addr.c b/src/lib/krb5/krb/ser_addr.c
new file mode 100644
index 0000000..6e08393
--- /dev/null
+++ b/src/lib/krb5/krb/ser_addr.c
@@ -0,0 +1,209 @@
+/*
+ * lib/krb5/krb/ser_addr.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_addr.c - Serialize a krb5_address structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_address:
+ * krb5_address_size();
+ * krb5_address_externalize();
+ * krb5_address_internalize();
+ */
+static krb5_error_code krb5_address_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_address_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_address_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_address_ser_entry = {
+ KV5M_ADDRESS, /* Type */
+ krb5_address_size, /* Sizer routine */
+ krb5_address_externalize, /* Externalize routine */
+ krb5_address_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_address_size() - Determine the size required to externalize
+ * the krb5_address.
+ */
+static krb5_error_code
+krb5_address_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_address *address;
+
+ /*
+ * krb5_address requires:
+ * krb5_int32 for KV5M_ADDRESS
+ * krb5_int32 for addrtype
+ * krb5_int32 for length
+ * address->length for contents
+ * krb5_int32 for KV5M_ADDRESS
+ */
+ kret = EINVAL;
+ if ((address = (krb5_address *) arg)) {
+ *sizep += (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (size_t) address->length);
+ kret = 0;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_address_externalize() - Externalize the krb5_address.
+ */
+static krb5_error_code
+krb5_address_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_address *address;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((address = (krb5_address *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_address_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* Our identifier */
+ (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain);
+
+ /* Our addrtype */
+ (void) krb5_ser_pack_int32((krb5_int32) address->addrtype,
+ &bp, &remain);
+
+ /* Our length */
+ (void) krb5_ser_pack_int32((krb5_int32) address->length,
+ &bp, &remain);
+
+ /* Our contents */
+ (void) krb5_ser_pack_bytes(address->contents,
+ (size_t) address->length,
+ &bp, &remain);
+
+ /* Finally, our trailer */
+ (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain);
+
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_address_internalize() - Internalize the krb5_address.
+ */
+static krb5_error_code
+krb5_address_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_address *address;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_ADDRESS) {
+ kret = ENOMEM;
+
+ /* Get a address */
+ if ((remain >= (2*sizeof(krb5_int32))) &&
+ (address = (krb5_address *) malloc(sizeof(krb5_address)))) {
+ memset(address, 0, sizeof(krb5_address));
+
+ /* Get the addrtype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ address->addrtype = (krb5_addrtype) ibuf;
+
+ /* Get the length */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ address->length = (int) ibuf;
+
+ /* Get the string */
+ if ((address->contents = (krb5_octet *) malloc((size_t) (ibuf))) &&
+ !(kret = krb5_ser_unpack_bytes(address->contents,
+ (size_t) ibuf,
+ &bp, &remain))) {
+ /* Get the trailer */
+ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+ ibuf = 0;
+
+ if (!kret && (ibuf == KV5M_ADDRESS)) {
+ address->magic = KV5M_ADDRESS;
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = (krb5_pointer) address;
+ }
+ else
+ kret = EINVAL;
+ }
+ if (kret) {
+ if (address->contents)
+ free(address->contents);
+ free(address);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the address serializer.
+ */
+krb5_error_code
+krb5_ser_address_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_address_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_auth.c b/src/lib/krb5/krb/ser_auth.c
new file mode 100644
index 0000000..828012c
--- /dev/null
+++ b/src/lib/krb5/krb/ser_auth.c
@@ -0,0 +1,356 @@
+/*
+ * lib/krb5/krb/ser_auth.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_auth.c - Serialize krb5_authenticator structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_authenticator:
+ * krb5_authenticator_size();
+ * krb5_authenticator_externalize();
+ * krb5_authenticator_internalize();
+ */
+static krb5_error_code krb5_authenticator_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_authenticator_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_authenticator_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_authenticator_ser_entry = {
+ KV5M_AUTHENTICATOR, /* Type */
+ krb5_authenticator_size, /* Sizer routine */
+ krb5_authenticator_externalize, /* Externalize routine */
+ krb5_authenticator_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_authenticator_size() - Determine the size required to externalize
+ * the krb5_authenticator.
+ */
+static krb5_error_code
+krb5_authenticator_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_authenticator *authenticator;
+ size_t required;
+
+ /*
+ * krb5_authenticator requires at minimum:
+ * krb5_int32 for KV5M_AUTHENTICATOR
+ * krb5_int32 for seconds
+ * krb5_int32 for cusec
+ * krb5_int32 for seq_number
+ * krb5_int32 for number in authorization_data array.
+ * krb5_int32 for KV5M_AUTHENTICATOR
+ */
+ kret = EINVAL;
+ if ((authenticator = (krb5_authenticator *) arg)) {
+ required = sizeof(krb5_int32)*6;
+
+ /* Calculate size required by client, if appropriate */
+ if (authenticator->client)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_PRINCIPAL,
+ (krb5_pointer) authenticator->client,
+ &required);
+ else
+ kret = 0;
+
+ /* Calculate size required by checksum, if appropriate */
+ if (!kret && authenticator->checksum)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_CHECKSUM,
+ (krb5_pointer) authenticator->checksum,
+ &required);
+
+ /* Calculate size required by subkey, if appropriate */
+ if (!kret && authenticator->subkey)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer) authenticator->subkey,
+ &required);
+
+ /* Calculate size required by authorization_data, if appropriate */
+ if (!kret && authenticator->authorization_data) {
+ int i;
+
+ for (i=0; !kret && authenticator->authorization_data[i]; i++) {
+ kret = krb5_size_opaque(kcontext,
+ KV5M_AUTHDATA,
+ (krb5_pointer) authenticator->
+ authorization_data[i],
+ &required);
+ }
+ }
+ }
+ if (!kret)
+ *sizep += required;
+ return(kret);
+}
+
+/*
+ * krb5_authenticator_externalize() - Externalize the krb5_authenticator.
+ */
+static krb5_error_code
+krb5_authenticator_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_authenticator *authenticator;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+ int i;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((authenticator = (krb5_authenticator *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_authenticator_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* First write our magic number */
+ (void) krb5_ser_pack_int32(KV5M_AUTHENTICATOR, &bp, &remain);
+
+ /* Now ctime */
+ (void) krb5_ser_pack_int32((krb5_int32) authenticator->ctime,
+ &bp, &remain);
+
+ /* Now cusec */
+ (void) krb5_ser_pack_int32((krb5_int32) authenticator->cusec,
+ &bp, &remain);
+
+ /* Now seq_number */
+ (void) krb5_ser_pack_int32(authenticator->seq_number,
+ &bp, &remain);
+
+ /* Now handle client, if appropriate */
+ if (authenticator->client)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_PRINCIPAL,
+ (krb5_pointer)
+ authenticator->client,
+ &bp,
+ &remain);
+ else
+ kret = 0;
+
+ /* Now handle checksum, if appropriate */
+ if (!kret && authenticator->checksum)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_CHECKSUM,
+ (krb5_pointer)
+ authenticator->checksum,
+ &bp,
+ &remain);
+
+ /* Now handle subkey, if appropriate */
+ if (!kret && authenticator->subkey)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer)
+ authenticator->subkey,
+ &bp,
+ &remain);
+
+ /* Now handle authorization_data, if appropriate */
+ if (!kret) {
+ if (authenticator->authorization_data)
+ for (i=0; authenticator->authorization_data[i]; i++);
+ else
+ i = 0;
+ (void) krb5_ser_pack_int32((krb5_int32) i, &bp, &remain);
+
+ /* Now pound out the authorization_data */
+ if (authenticator->authorization_data) {
+ for (i=0; !kret && authenticator->authorization_data[i];
+ i++)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_AUTHDATA,
+ (krb5_pointer)
+ authenticator->
+ authorization_data[i],
+ &bp,
+ &remain);
+ }
+ }
+
+ /*
+ * If we were successful, write trailer then update the pointer and
+ * remaining length;
+ */
+ if (!kret) {
+ /* Write our trailer */
+ (void) krb5_ser_pack_int32(KV5M_AUTHENTICATOR, &bp, &remain);
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_authenticator_internalize() - Internalize the krb5_authenticator.
+ */
+static krb5_error_code
+krb5_authenticator_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_authenticator *authenticator;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+ int i;
+ krb5_int32 nadata;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_AUTHENTICATOR) {
+ kret = ENOMEM;
+
+ /* Get memory for the authenticator */
+ if ((remain >= (3*sizeof(krb5_int32))) &&
+ (authenticator = (krb5_authenticator *)
+ malloc(sizeof(krb5_authenticator)))) {
+ memset(authenticator, 0, sizeof(krb5_authenticator));
+
+ /* Get ctime */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ authenticator->ctime = (krb5_timestamp) ibuf;
+
+ /* Get cusec */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ authenticator->cusec = ibuf;
+
+ /* Get seq_number */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ authenticator->seq_number = ibuf;
+
+ kret = 0;
+
+ /* Attempt to read in the client */
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_PRINCIPAL,
+ (krb5_pointer *)
+ &authenticator->client,
+ &bp,
+ &remain);
+ if (kret == EINVAL)
+ kret = 0;
+
+ /* Attempt to read in the checksum */
+ if (!kret) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_CHECKSUM,
+ (krb5_pointer *)
+ &authenticator->checksum,
+ &bp,
+ &remain);
+ if (kret == EINVAL)
+ kret = 0;
+ }
+
+ /* Attempt to read in the subkey */
+ if (!kret) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer *)
+ &authenticator->subkey,
+ &bp,
+ &remain);
+ if (kret == EINVAL)
+ kret = 0;
+ }
+
+ /* Attempt to read in the authorization data count */
+ if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
+ nadata = ibuf;
+
+ /* Get memory for the authorization data pointers */
+ if ((authenticator->authorization_data = (krb5_authdata **)
+ malloc(sizeof(krb5_authdata *) * (nadata+1)))) {
+ memset(authenticator->authorization_data, 0,
+ sizeof(krb5_authdata *) * (nadata+1));
+
+ for (i=0; !kret && (i<nadata); i++) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_AUTHDATA,
+ (krb5_pointer *)
+ &authenticator->
+ authorization_data[i],
+ &bp,
+ &remain);
+ }
+
+ /* Finally, find the trailer */
+ if (!kret) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_AUTHENTICATOR))
+ authenticator->magic = KV5M_AUTHENTICATOR;
+ else
+ kret = EINVAL;
+ }
+ }
+ }
+ if (!kret) {
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = (krb5_pointer) authenticator;
+ }
+ else
+ krb5_free_authenticator(kcontext, authenticator);
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the authenticator serializer.
+ */
+krb5_error_code
+krb5_ser_authenticator_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_authenticator_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_cksum.c b/src/lib/krb5/krb/ser_cksum.c
new file mode 100644
index 0000000..3fc9d51
--- /dev/null
+++ b/src/lib/krb5/krb/ser_cksum.c
@@ -0,0 +1,210 @@
+/*
+ * lib/krb5/krb/ser_cksum.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_cksum.c - Serialize a krb5_checksum structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_checksum:
+ * krb5_checksum_esize();
+ * krb5_checksum_externalize();
+ * krb5_checksum_internalize();
+ */
+static krb5_error_code krb5_checksum_esize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_checksum_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_checksum_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_checksum_ser_entry = {
+ KV5M_CHECKSUM, /* Type */
+ krb5_checksum_esize, /* Sizer routine */
+ krb5_checksum_externalize, /* Externalize routine */
+ krb5_checksum_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_checksum_esize() - Determine the size required to externalize
+ * the krb5_checksum.
+ */
+static krb5_error_code
+krb5_checksum_esize(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_checksum *checksum;
+
+ /*
+ * krb5_checksum requires:
+ * krb5_int32 for KV5M_CHECKSUM
+ * krb5_int32 for checksum_type
+ * krb5_int32 for length
+ * krb5_int32 for KV5M_CHECKSUM
+ * checksum->length for contents
+ */
+ kret = EINVAL;
+ if ((checksum = (krb5_checksum *) arg)) {
+ *sizep += (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (size_t) checksum->length);
+ kret = 0;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_checksum_externalize() - Externalize the krb5_checksum.
+ */
+static krb5_error_code
+krb5_checksum_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_checksum *checksum;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((checksum = (krb5_checksum *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_checksum_esize(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* Our identifier */
+ (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain);
+
+ /* Our checksum_type */
+ (void) krb5_ser_pack_int32((krb5_int32) checksum->checksum_type,
+ &bp, &remain);
+
+ /* Our length */
+ (void) krb5_ser_pack_int32((krb5_int32) checksum->length,
+ &bp, &remain);
+
+ /* Our contents */
+ (void) krb5_ser_pack_bytes(checksum->contents,
+ (size_t) checksum->length,
+ &bp, &remain);
+
+ /* Finally, our trailer */
+ (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain);
+
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_checksum_internalize() - Internalize the krb5_checksum.
+ */
+static krb5_error_code
+krb5_checksum_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_checksum *checksum;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_CHECKSUM) {
+ kret = ENOMEM;
+
+ /* Get a checksum */
+ if ((remain >= (2*sizeof(krb5_int32))) &&
+ (checksum = (krb5_checksum *) malloc(sizeof(krb5_checksum)))) {
+ memset(checksum, 0, sizeof(krb5_checksum));
+
+ /* Get the checksum_type */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ checksum->checksum_type = (krb5_cksumtype) ibuf;
+
+ /* Get the length */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ checksum->length = (int) ibuf;
+
+ /* Get the string */
+ if (!ibuf ||
+ ((checksum->contents = (krb5_octet *)
+ malloc((size_t) (ibuf))) &&
+ !(kret = krb5_ser_unpack_bytes(checksum->contents,
+ (size_t) ibuf,
+ &bp, &remain)))) {
+
+ /* Get the trailer */
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_CHECKSUM)) {
+ checksum->magic = KV5M_CHECKSUM;
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = (krb5_pointer) checksum;
+ }
+ else
+ kret = EINVAL;
+ }
+ if (kret) {
+ if (checksum->contents)
+ free(checksum->contents);
+ free(checksum);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the checksum serializer.
+ */
+krb5_error_code
+krb5_ser_checksum_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_checksum_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_ctx.c b/src/lib/krb5/krb/ser_ctx.c
new file mode 100644
index 0000000..f317a51
--- /dev/null
+++ b/src/lib/krb5/krb/ser_ctx.c
@@ -0,0 +1,468 @@
+/*
+ * lib/krb5/krb/ser_ctx.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_ctx.c - Routines to deal with serializing the krb5_context and
+ * krb5_os_context structures.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_context:
+ * krb5_context_size();
+ * krb5_context_externalize();
+ * krb5_context_internalize();
+ *
+ * Routines to deal with externalizing the krb5_os_context:
+ * krb5_oscontext_size();
+ * krb5_oscontext_externalize();
+ * krb5_oscontext_internalize();
+ *
+ * Routines to deal with externalizing the profile.
+ * profile_ser_size();
+ * profile_ser_externalize();
+ * profile_ser_internalize();
+ *
+ * Interface to initialize serializing of krb5_context and krb5_os_context:
+ * krb5_ser_context_init();
+ */
+static krb5_error_code krb5_context_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_context_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_context_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+static krb5_error_code krb5_oscontext_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_oscontext_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_oscontext_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+krb5_error_code profile_ser_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+krb5_error_code profile_ser_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+krb5_error_code profile_ser_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_context_ser_entry = {
+ KV5M_CONTEXT, /* Type */
+ krb5_context_size, /* Sizer routine */
+ krb5_context_externalize, /* Externalize routine */
+ krb5_context_internalize /* Internalize routine */
+};
+static const krb5_ser_entry krb5_oscontext_ser_entry = {
+ KV5M_OS_CONTEXT, /* Type */
+ krb5_oscontext_size, /* Sizer routine */
+ krb5_oscontext_externalize, /* Externalize routine */
+ krb5_oscontext_internalize /* Internalize routine */
+};
+static const krb5_ser_entry krb5_profile_ser_entry = {
+ PROF_MAGIC_PROFILE, /* Type */
+ profile_ser_size, /* Sizer routine */
+ profile_ser_externalize, /* Externalize routine */
+ profile_ser_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_context_size() - Determine the size required to externalize the
+ * krb5_context.
+ */
+static krb5_error_code
+krb5_context_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ size_t required;
+ krb5_context context;
+
+ /*
+ * The KRB5 context itself requires:
+ * krb5_int32 for KV5M_CONTEXT
+ * krb5_int32 for sizeof(default_realm)
+ * strlen(default_realm) for default_realm.
+ * krb5_int32 for netypes*sizeof(krb5_int32)
+ * netypes*sizeof(krb5_int32) for etypes.
+ * krb5_int32 for trailer.
+ */
+ kret = EINVAL;
+ if ((context = (krb5_context) arg)) {
+ /* Calculate base length */
+ required = (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (context->etype_count * sizeof(krb5_int32)));
+
+ if (context->default_realm)
+ required += strlen(context->default_realm);
+ /* Calculate size required by os_context, if appropriate */
+ if (context->os_context)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_OS_CONTEXT,
+ (krb5_pointer) context->os_context,
+ &required);
+
+ /* Calculate size required by db_context, if appropriate */
+ if (!kret && context->db_context)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_DB_CONTEXT,
+ (krb5_pointer) context->db_context,
+ &required);
+
+ /* Finally, calculate size required by profile, if appropriate */
+ if (!kret && context->profile)
+ kret = krb5_size_opaque(kcontext,
+ PROF_MAGIC_PROFILE,
+ (krb5_pointer) context->profile,
+ &required);
+ }
+ if (!kret)
+ *sizep += required;
+ return(kret);
+}
+
+/*
+ * krb5_context_externalize() - Externalize the krb5_context.
+ */
+static krb5_error_code
+krb5_context_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_context context;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+ int i;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((context = (krb5_context) arg)) {
+ kret = ENOMEM;
+ if (!krb5_context_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* First write our magic number */
+ (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
+
+ /* Now sizeof default realm */
+ (void) krb5_ser_pack_int32((context->default_realm) ?
+ (krb5_int32) strlen(context->
+ default_realm) : 0,
+ &bp, &remain);
+
+ /* Now default_realm bytes */
+ if (context->default_realm)
+ (void) krb5_ser_pack_bytes((krb5_octet *)
+ context->default_realm,
+ strlen(context->default_realm),
+ &bp, &remain);
+
+ /* Now number of etypes */
+ (void) krb5_ser_pack_int32((krb5_int32) context->etype_count,
+ &bp, &remain);
+
+ /* Now serialize etypes */
+ for (i=0; i<context->etype_count; i++)
+ (void) krb5_ser_pack_int32((krb5_int32) context->etypes[i],
+ &bp, &remain);
+ kret = 0;
+
+ /* Now handle os_context, if appropriate */
+ if (context->os_context)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_OS_CONTEXT,
+ (krb5_pointer)
+ context->os_context,
+ &bp,
+ &remain);
+
+ /* Now handle database context, if appropriate */
+ if (!kret && context->db_context)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_DB_CONTEXT,
+ (krb5_pointer)
+ context->db_context,
+ &bp,
+ &remain);
+
+ /* Finally, handle profile, if appropriate */
+ if (!kret && context->profile)
+ kret = krb5_externalize_opaque(kcontext,
+ PROF_MAGIC_PROFILE,
+ (krb5_pointer)
+ context->profile,
+ &bp,
+ &remain);
+ /*
+ * If we were successful, write trailer then update the pointer and
+ * remaining length;
+ */
+ if (!kret) {
+ /* Write our trailer */
+ (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_context_internalize() - Internalize the krb5_context.
+ */
+static krb5_error_code
+krb5_context_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_context context;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+ int i;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_CONTEXT) {
+ kret = ENOMEM;
+
+ /* Get memory for the context */
+ if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
+ (context = (krb5_context) malloc(sizeof(struct _krb5_context)))) {
+ memset(context, 0, sizeof(struct _krb5_context));
+
+ if (!ibuf ||
+ (context->default_realm = (char *) malloc((size_t) ibuf+1))) {
+ /* Copy in the default realm */
+ if (ibuf) {
+ (void) krb5_ser_unpack_bytes((krb5_octet *)
+ context->default_realm,
+ (size_t) ibuf,
+ &bp, &remain);
+ context->default_realm[ibuf] = '\0';
+ }
+
+ /* Get the number of etypes */
+ if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
+ /* Reduce it to a count */
+ context->etype_count = ibuf;
+ if ((context->etypes = (krb5_enctype *)
+ malloc(sizeof(krb5_enctype) *
+ (context->etype_count+1)))) {
+ memset(context->etypes,
+ 0,
+ sizeof(krb5_enctype) *
+ (context->etype_count + 1));
+ for (i=0; i<context->etype_count; i++) {
+ if ((kret = krb5_ser_unpack_int32(&ibuf,
+ &bp, &remain)))
+ break;
+ context->etypes[i] = (krb5_enctype) ibuf;
+ }
+ }
+ }
+
+ /* Attempt to read in the os_context */
+ if (!kret) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_OS_CONTEXT,
+ (krb5_pointer *)
+ &context->os_context,
+ &bp,
+ &remain);
+ if ((kret == EINVAL) || (kret == ENOENT))
+ kret = 0;
+ }
+
+ /* Attempt to read in the db_context */
+ if (!kret) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_DB_CONTEXT,
+ (krb5_pointer *)
+ &context->db_context,
+ &bp,
+ &remain);
+ if ((kret == EINVAL) || (kret == ENOENT))
+ kret = 0;
+ }
+
+ /* Attempt to read in the profile */
+ if (!kret) {
+ kret = krb5_internalize_opaque(kcontext,
+ PROF_MAGIC_PROFILE,
+ (krb5_pointer *)
+ &context->profile,
+ &bp,
+ &remain);
+ if ((kret == EINVAL) || (kret == ENOENT))
+ kret = 0;
+ }
+
+ /* Finally, find the trailer */
+ if (!kret) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_CONTEXT))
+ context->magic = KV5M_CONTEXT;
+ else
+ kret = EINVAL;
+ }
+ }
+ if (!kret) {
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = (krb5_pointer) context;
+ }
+ else
+ krb5_free_context(context);
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_oscontext_size() - Determine the size required to externalize
+ * the krb5_os_context.
+ */
+static krb5_error_code
+krb5_oscontext_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ *sizep += sizeof(krb5_int32);
+ return(0);
+}
+
+/*
+ * krb5_oscontext_externalize() - Externalize the krb5_os_context.
+ */
+static krb5_error_code
+krb5_oscontext_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_os_context os_ctx;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((os_ctx = (krb5_os_context) arg)) {
+ kret = ENOMEM;
+ if (!krb5_oscontext_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ (void) krb5_ser_pack_int32(KV5M_OS_CONTEXT, &bp, &remain);
+
+ /* Handle any other OS context here */
+ kret = 0;
+ if (!kret) {
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_oscontext_internalize() - Internalize the krb5_os_context.
+ */
+static krb5_error_code
+krb5_oscontext_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_os_context os_ctx;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_OS_CONTEXT) {
+ kret = ENOMEM;
+
+ /* Get memory for the context */
+ if ((os_ctx = (krb5_os_context)
+ malloc(sizeof(struct _krb5_os_context)))) {
+ memset(os_ctx, 0, sizeof(struct _krb5_os_context));
+ os_ctx->magic = KV5M_OS_CONTEXT;
+
+ /* Handle any more OS context here */
+
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ if (!kret)
+ *argp = (krb5_pointer) os_ctx;
+ return(kret);
+}
+
+/*
+ * Register the context serializers.
+ */
+krb5_error_code
+krb5_ser_context_init(kcontext)
+ krb5_context kcontext;
+{
+ krb5_error_code kret;
+ kret = krb5_register_serializer(kcontext, &krb5_context_ser_entry);
+ if (!kret)
+ kret = krb5_register_serializer(kcontext, &krb5_oscontext_ser_entry);
+ if (!kret)
+ kret = krb5_register_serializer(kcontext, &krb5_profile_ser_entry);
+ return(kret);
+}
diff --git a/src/lib/krb5/krb/ser_eblk.c b/src/lib/krb5/krb/ser_eblk.c
new file mode 100644
index 0000000..791963e
--- /dev/null
+++ b/src/lib/krb5/krb/ser_eblk.c
@@ -0,0 +1,266 @@
+/*
+ * lib/krb5/krb/ser_eblk.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_eblk.c - Serialize a krb5_encblock structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_encrypt_block:
+ * krb5_encrypt_block_size();
+ * krb5_encrypt_block_externalize();
+ * krb5_encrypt_block_internalize();
+ */
+static krb5_error_code krb5_encrypt_block_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_encrypt_block_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_encrypt_block_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_encrypt_block_ser_entry = {
+ KV5M_ENCRYPT_BLOCK, /* Type */
+ krb5_encrypt_block_size, /* Sizer routine */
+ krb5_encrypt_block_externalize, /* Externalize routine */
+ krb5_encrypt_block_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_encrypt_block_size() - Determine the size required to externalize
+ * the krb5_encrypt_block.
+ */
+static krb5_error_code
+krb5_encrypt_block_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_encrypt_block *encrypt_block;
+ size_t required;
+
+ /*
+ * NOTE: This ASSuMES that keytype and etype are sufficient to recreate
+ * the _krb5_cryptosystem_entry. If this is not true, then something else
+ * had better be encoded here.
+ *
+ * krb5_encrypt_block base requirements:
+ * krb5_int32 for KV5M_ENCRYPT_BLOCK
+ * krb5_int32 for keytype
+ * krb5_int32 for etype;
+ * krb5_int32 for private length
+ * encrypt_block->priv_size for private contents
+ * krb5_int32 for KV5M_ENCRYPT_BLOCK
+ */
+ kret = EINVAL;
+ if ((encrypt_block = (krb5_encrypt_block *) arg)) {
+ required = (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (size_t) encrypt_block->priv_size);
+ if (encrypt_block->key)
+ kret = krb5_size_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer) encrypt_block->key,
+ &required);
+ else
+ kret = 0;
+ if (!kret)
+ *sizep += required;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_encrypt_block_externalize() - Externalize the krb5_encrypt_block.
+ */
+static krb5_error_code
+krb5_encrypt_block_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_encrypt_block *encrypt_block;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((encrypt_block = (krb5_encrypt_block *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_encrypt_block_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* Our identifier */
+ (void) krb5_ser_pack_int32(KV5M_ENCRYPT_BLOCK, &bp, &remain);
+
+ /* Our keytype */
+ (void) krb5_ser_pack_int32((krb5_int32) encrypt_block->
+ crypto_entry->proto_keytype,
+ &bp, &remain);
+
+ /* Our etype */
+ (void) krb5_ser_pack_int32((krb5_int32) encrypt_block->
+ crypto_entry->proto_enctype,
+ &bp, &remain);
+
+ /* Our length */
+ (void) krb5_ser_pack_int32((krb5_int32) encrypt_block->priv_size,
+ &bp, &remain);
+
+ /* Our private data */
+ (void) krb5_ser_pack_bytes(encrypt_block->priv,
+ (size_t) encrypt_block->priv_size,
+ &bp, &remain);
+
+ /* Finally, the key data */
+ if (encrypt_block->key)
+ kret = krb5_externalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer)
+ encrypt_block->key,
+ &bp,
+ &remain);
+ else
+ kret = 0;
+
+ if (!kret) {
+ /* Write trailer */
+ (void) krb5_ser_pack_int32(KV5M_ENCRYPT_BLOCK, &bp, &remain);
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_encrypt_block_internalize() - Internalize the krb5_encrypt_block.
+ */
+static krb5_error_code
+krb5_encrypt_block_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_encrypt_block *encrypt_block;
+ krb5_int32 ibuf;
+ krb5_keytype ktype;
+ krb5_enctype etype;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_ENCRYPT_BLOCK) {
+ kret = ENOMEM;
+
+ /* Get an encrypt_block */
+ if ((remain >= (3*sizeof(krb5_int32))) &&
+ (encrypt_block = (krb5_encrypt_block *)
+ malloc(sizeof(krb5_encrypt_block)))) {
+ memset(encrypt_block, 0, sizeof(krb5_encrypt_block));
+
+ /* Get the keytype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ ktype = (krb5_keytype) ibuf;
+
+ /* Get the etype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ etype = (krb5_enctype) ibuf;
+
+ /*
+ * Use the etype to determine the crypto_system entry. In the
+ * future, we may need to use a combination of keytype/etype or
+ * just keytype here.
+ */
+ krb5_use_cstype(kcontext, encrypt_block, etype);
+
+ /* Get the length */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ encrypt_block->priv_size = (int) ibuf;
+
+ /* Get the string */
+ if (!ibuf ||
+ ((encrypt_block->priv = (void *) malloc((size_t) (ibuf))) &&
+ !(kret = krb5_ser_unpack_bytes((krb5_octet *)
+ encrypt_block->priv,
+ (size_t)
+ encrypt_block->priv_size,
+ &bp, &remain)))) {
+ kret = krb5_internalize_opaque(kcontext,
+ KV5M_KEYBLOCK,
+ (krb5_pointer *)
+ &encrypt_block->key,
+ &bp,
+ &remain);
+ if (kret == EINVAL)
+ kret = 0;
+
+ if (!kret) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_ENCRYPT_BLOCK)) {
+ *buffer = bp;
+ *lenremain = remain;
+ encrypt_block->magic = KV5M_ENCRYPT_BLOCK;
+ *argp = (krb5_pointer) encrypt_block;
+ }
+ else
+ kret = EINVAL;
+ }
+ }
+ if (kret) {
+ if (encrypt_block->priv)
+ free(encrypt_block->priv);
+ free(encrypt_block);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the encblock serializer.
+ */
+krb5_error_code
+krb5_ser_encrypt_block_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_encrypt_block_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_key.c b/src/lib/krb5/krb/ser_key.c
new file mode 100644
index 0000000..eacbf01
--- /dev/null
+++ b/src/lib/krb5/krb/ser_key.c
@@ -0,0 +1,217 @@
+/*
+ * lib/krb5/krb/ser_key.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_key.c - Serialize a krb5_keyblock structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_keyblock:
+ * krb5_keyblock_size();
+ * krb5_keyblock_externalize();
+ * krb5_keyblock_internalize();
+ */
+static krb5_error_code krb5_keyblock_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_keyblock_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_keyblock_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_keyblock_ser_entry = {
+ KV5M_KEYBLOCK, /* Type */
+ krb5_keyblock_size, /* Sizer routine */
+ krb5_keyblock_externalize, /* Externalize routine */
+ krb5_keyblock_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_keyblock_size() - Determine the size required to externalize
+ * the krb5_keyblock.
+ */
+static krb5_error_code
+krb5_keyblock_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_keyblock *keyblock;
+
+ /*
+ * krb5_keyblock requires:
+ * krb5_int32 for KV5M_KEYBLOCK
+ * krb5_int32 for keytype
+ * krb5_int32 for etype;
+ * krb5_int32 for length
+ * keyblock->length for contents
+ * krb5_int32 for KV5M_KEYBLOCK
+ */
+ kret = EINVAL;
+ if ((keyblock = (krb5_keyblock *) arg)) {
+ *sizep += (sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ sizeof(krb5_int32) +
+ (size_t) keyblock->length);
+ kret = 0;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_keyblock_externalize() - Externalize the krb5_keyblock.
+ */
+static krb5_error_code
+krb5_keyblock_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_keyblock *keyblock;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((keyblock = (krb5_keyblock *) arg)) {
+ kret = ENOMEM;
+ if (!krb5_keyblock_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ /* Our identifier */
+ (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain);
+
+ /* Our keytype */
+ (void) krb5_ser_pack_int32((krb5_int32) keyblock->keytype,
+ &bp, &remain);
+
+ /* Our etype */
+ (void) krb5_ser_pack_int32((krb5_int32) keyblock->etype,
+ &bp, &remain);
+
+ /* Our length */
+ (void) krb5_ser_pack_int32((krb5_int32) keyblock->length,
+ &bp, &remain);
+
+ /* Our contents */
+ (void) krb5_ser_pack_bytes(keyblock->contents,
+ (size_t) keyblock->length,
+ &bp, &remain);
+
+ /* Finally, our trailer */
+ (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain);
+
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_keyblock_internalize() - Internalize the krb5_keyblock.
+ */
+static krb5_error_code
+krb5_keyblock_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_keyblock *keyblock;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_KEYBLOCK) {
+ kret = ENOMEM;
+
+ /* Get a keyblock */
+ if ((remain >= (3*sizeof(krb5_int32))) &&
+ (keyblock = (krb5_keyblock *) malloc(sizeof(krb5_keyblock)))) {
+ memset(keyblock, 0, sizeof(krb5_keyblock));
+
+ /* Get the keytype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ keyblock->keytype = (krb5_keytype) ibuf;
+
+ /* Get the etype */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ keyblock->etype = (krb5_enctype) ibuf;
+
+ /* Get the length */
+ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ keyblock->length = (int) ibuf;
+
+ /* Get the string */
+ if ((keyblock->contents = (krb5_octet *) malloc((size_t) (ibuf)))&&
+ !(kret = krb5_ser_unpack_bytes(keyblock->contents,
+ (size_t) ibuf,
+ &bp, &remain))) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_KEYBLOCK)) {
+ kret = 0;
+ *buffer = bp;
+ *lenremain = remain;
+ keyblock->magic = KV5M_KEYBLOCK;
+ *argp = (krb5_pointer) keyblock;
+ }
+ else
+ kret = EINVAL;
+ }
+ if (kret) {
+ if (keyblock->contents)
+ free(keyblock->contents);
+ free(keyblock);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the keyblock serializer.
+ */
+krb5_error_code
+krb5_ser_keyblock_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_keyblock_ser_entry));
+}
diff --git a/src/lib/krb5/krb/ser_princ.c b/src/lib/krb5/krb/ser_princ.c
new file mode 100644
index 0000000..5828754
--- /dev/null
+++ b/src/lib/krb5/krb/ser_princ.c
@@ -0,0 +1,189 @@
+/*
+ * lib/krb5/krb/ser_princ.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * ser_princ.c - Serialize a krb5_principal structure.
+ */
+#include "k5-int.h"
+
+/*
+ * Routines to deal with externalizing the krb5_principal:
+ * krb5_principal_size();
+ * krb5_principal_externalize();
+ * krb5_principal_internalize();
+ */
+static krb5_error_code krb5_principal_size
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *));
+static krb5_error_code krb5_principal_externalize
+ KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *));
+static krb5_error_code krb5_principal_internalize
+ KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *));
+
+/* Local data */
+static const krb5_ser_entry krb5_principal_ser_entry = {
+ KV5M_PRINCIPAL, /* Type */
+ krb5_principal_size, /* Sizer routine */
+ krb5_principal_externalize, /* Externalize routine */
+ krb5_principal_internalize /* Internalize routine */
+};
+
+/*
+ * krb5_principal_size() - Determine the size required to externalize
+ * the krb5_principal.
+ */
+static krb5_error_code
+krb5_principal_size(kcontext, arg, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_principal principal;
+ char *fname;
+
+ /*
+ * krb5_principal requires:
+ * krb5_int32 for KV5M_PRINCIPAL
+ * krb5_int32 for flattened name size
+ * strlen(name) for name.
+ * krb5_int32 for KV5M_PRINCIPAL
+ */
+ kret = EINVAL;
+ if ((principal = (krb5_principal) arg) &&
+ !(kret = krb5_unparse_name(kcontext, principal, &fname))) {
+ *sizep += (3*sizeof(krb5_int32)) + strlen(fname);
+ krb5_xfree(fname);
+ }
+ return(kret);
+}
+
+/*
+ * krb5_principal_externalize() - Externalize the krb5_principal.
+ */
+static krb5_error_code
+krb5_principal_externalize(kcontext, arg, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_principal principal;
+ size_t required;
+ krb5_octet *bp;
+ size_t remain;
+ char *fname;
+
+ required = 0;
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ if ((principal = (krb5_principal) arg)) {
+ kret = ENOMEM;
+ if (!krb5_principal_size(kcontext, arg, &required) &&
+ (required <= remain)) {
+ if (!(kret = krb5_unparse_name(kcontext, principal, &fname))) {
+
+ (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
+ (void) krb5_ser_pack_int32((krb5_int32) strlen(fname),
+ &bp, &remain);
+ (void) krb5_ser_pack_bytes((krb5_octet *) fname,
+ strlen(fname), &bp, &remain);
+ (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
+ *buffer = bp;
+ *lenremain = remain;
+
+ krb5_xfree(fname);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * krb5_principal_internalize() - Internalize the krb5_principal.
+ */
+static krb5_error_code
+krb5_principal_internalize(kcontext, argp, buffer, lenremain)
+ krb5_context kcontext;
+ krb5_pointer *argp;
+ krb5_octet **buffer;
+ size_t *lenremain;
+{
+ krb5_error_code kret;
+ krb5_principal principal;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+ char *tmpname;
+
+ bp = *buffer;
+ remain = *lenremain;
+ kret = EINVAL;
+ /* Read our magic number */
+ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
+ ibuf = 0;
+ if (ibuf == KV5M_PRINCIPAL) {
+ kret = ENOMEM;
+
+ /* See if we have enough data for the length */
+ if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
+ /* Get the string */
+ if ((tmpname = (char *) malloc((size_t) (ibuf+1))) &&
+ !(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname,
+ (size_t) ibuf,
+ &bp, &remain))) {
+ tmpname[ibuf] = '\0';
+
+ /* Parse the name to a principal structure */
+ principal = (krb5_principal) NULL;
+ kret = krb5_parse_name(kcontext, tmpname, &principal);
+ if (!kret) {
+ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (!kret && (ibuf == KV5M_PRINCIPAL)) {
+ *buffer = bp;
+ *lenremain = remain;
+ *argp = principal;
+ }
+ else
+ kret = EINVAL;
+ }
+ if (kret && principal)
+ krb5_free_principal(kcontext, principal);
+ free(tmpname);
+ }
+ }
+ }
+ return(kret);
+}
+
+/*
+ * Register the context serializer.
+ */
+krb5_error_code
+krb5_ser_principal_init(kcontext)
+ krb5_context kcontext;
+{
+ return(krb5_register_serializer(kcontext, &krb5_principal_ser_entry));
+}
diff --git a/src/lib/krb5/krb/serialize.c b/src/lib/krb5/krb/serialize.c
new file mode 100644
index 0000000..20107c4
--- /dev/null
+++ b/src/lib/krb5/krb/serialize.c
@@ -0,0 +1,277 @@
+/*
+ * lib/krb5/krb/serialize.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * Base routines to deal with serialization of Kerberos metadata.
+ */
+#include "k5-int.h"
+
+/*
+ * krb5_find_serializer() - See if a particular type is registered.
+ */
+krb5_ser_handle
+krb5_find_serializer(kcontext, odtype)
+ krb5_context kcontext;
+ krb5_magic odtype;
+{
+ krb5_ser_handle res;
+ krb5_ser_handle sctx;
+ int i;
+
+ res = (krb5_ser_handle) NULL;
+ sctx = (krb5_ser_handle) kcontext->ser_ctx;
+ for (i=0; i<kcontext->ser_ctx_count; i++) {
+ if (sctx[i].odtype == odtype) {
+ res = &sctx[i];
+ break;
+ }
+ }
+ return(res);
+}
+
+/*
+ * krb5_register_serializer() - Register a particular serializer.
+ */
+krb5_error_code
+krb5_register_serializer(kcontext, entry)
+ krb5_context kcontext;
+ const krb5_ser_entry *entry;
+{
+ krb5_error_code kret;
+ krb5_ser_handle stable;
+
+ kret = 0;
+ /* See if it's already there, if so, we're good to go. */
+ if (!(stable = krb5_find_serializer(kcontext, entry->odtype))) {
+ /*
+ * Can't find our type. Create a new entry.
+ */
+ if ((stable = (krb5_ser_handle) malloc(sizeof(krb5_ser_entry) *
+ (kcontext->ser_ctx_count+1)))) {
+ /* Copy in old table */
+ memcpy(stable, kcontext->ser_ctx,
+ sizeof(krb5_ser_entry) * kcontext->ser_ctx_count);
+ /* Copy in new entry */
+ memcpy(&stable[kcontext->ser_ctx_count], entry,
+ sizeof(krb5_ser_entry));
+ krb5_xfree(kcontext->ser_ctx);
+ kcontext->ser_ctx = (void *) stable;
+ kcontext->ser_ctx_count++;
+ }
+ else
+ kret = ENOMEM;
+ }
+ else
+ memcpy(stable, entry, sizeof(krb5_ser_entry));
+ return(kret);
+}
+
+/*
+ * krb5_size_opaque() - Determine the size necessary to serialize a given
+ * piece of opaque data.
+ */
+krb5_error_code
+krb5_size_opaque(kcontext, odtype, arg, sizep)
+ krb5_context kcontext;
+ krb5_magic odtype;
+ krb5_pointer arg;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_ser_handle shandle;
+
+ kret = ENOENT;
+ /* See if the type is supported, if so, do it */
+ if ((shandle = krb5_find_serializer(kcontext, odtype)))
+ kret = (shandle->sizer) ? (*shandle->sizer)(kcontext, arg, sizep) : 0;
+ return(kret);
+}
+
+/*
+ * krb5_externalize_opaque() - Externalize a piece of opaque data.
+ */
+krb5_error_code
+krb5_externalize_opaque(kcontext, odtype, arg, bufpp, sizep)
+ krb5_context kcontext;
+ krb5_magic odtype;
+ krb5_pointer arg;
+ krb5_octet **bufpp;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_ser_handle shandle;
+
+ kret = ENOENT;
+ /* See if the type is supported, if so, do it */
+ if ((shandle = krb5_find_serializer(kcontext, odtype)))
+ kret = (shandle->externalizer) ?
+ (*shandle->externalizer)(kcontext, arg, bufpp, sizep) : 0;
+ return(kret);
+}
+
+/*
+ * Externalize a piece of arbitrary data.
+ */
+krb5_error_code
+krb5_externalize_data(kcontext, arg, bufpp, sizep)
+ krb5_context kcontext;
+ krb5_pointer arg;
+ krb5_octet **bufpp;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_magic *mp;
+ krb5_octet *buffer, *bp;
+ size_t bufsize, bsize;
+
+ mp = (krb5_magic *) arg;
+ bufsize = 0;
+ if (!(kret = krb5_size_opaque(kcontext, *mp, arg, &bufsize))) {
+ if ((buffer = (krb5_octet *) malloc(bufsize))) {
+ bp = buffer;
+ bsize = bufsize;
+ if (!(kret = krb5_externalize_opaque(kcontext,
+ *mp,
+ arg,
+ &bp,
+ &bsize))) {
+ if (bsize != 0)
+ bufsize -= bsize;
+ *bufpp = buffer;
+ *sizep = bufsize;
+ }
+ }
+ else
+ kret = ENOMEM;
+ }
+ return(kret);
+}
+
+/*
+ * krb5_internalize_opaque() - Convert external representation into a data
+ * structure.
+ */
+krb5_error_code
+krb5_internalize_opaque(kcontext, odtype, argp, bufpp, sizep)
+ krb5_context kcontext;
+ krb5_magic odtype;
+ krb5_pointer *argp;
+ krb5_octet **bufpp;
+ size_t *sizep;
+{
+ krb5_error_code kret;
+ krb5_ser_handle shandle;
+
+ kret = ENOENT;
+ /* See if the type is supported, if so, do it */
+ if ((shandle = krb5_find_serializer(kcontext, odtype)))
+ kret = (shandle->internalizer) ?
+ (*shandle->internalizer)(kcontext, argp, bufpp, sizep) : 0;
+ return(kret);
+}
+
+/*
+ * krb5_ser_pack_int32() - Pack a 4-byte integer if space is availble.
+ * Update buffer pointer and remaining space.
+ */
+krb5_error_code
+krb5_ser_pack_int32(iarg, bufp, remainp)
+ krb5_int32 iarg;
+ krb5_octet **bufp;
+ size_t *remainp;
+{
+ if (*remainp >= sizeof(krb5_int32)) {
+ (*bufp)[0] = (krb5_octet) ((iarg >> 24) & 0xff);
+ (*bufp)[1] = (krb5_octet) ((iarg >> 16) & 0xff);
+ (*bufp)[2] = (krb5_octet) ((iarg >> 8) & 0xff);
+ (*bufp)[3] = (krb5_octet) (iarg & 0xff);
+ *bufp += sizeof(krb5_int32);
+ *remainp -= sizeof(krb5_int32);
+ return(0);
+ }
+ else
+ return(ENOMEM);
+}
+
+/*
+ * krb5_ser_pack_bytes() - Pack a string of bytes.
+ */
+krb5_error_code
+krb5_ser_pack_bytes(ostring, osize, bufp, remainp)
+ krb5_octet *ostring;
+ size_t osize;
+ krb5_octet **bufp;
+ size_t *remainp;
+{
+ if (*remainp >= osize) {
+ memcpy(*bufp, ostring, osize);
+ *bufp += osize;
+ *remainp -= osize;
+ return(0);
+ }
+ else
+ return(ENOMEM);
+}
+
+/*
+ * krb5_ser_unpack_int32() - Unpack a 4-byte integer if it's there.
+ */
+krb5_error_code
+krb5_ser_unpack_int32(intp, bufp, remainp)
+ krb5_int32 *intp;
+ krb5_octet **bufp;
+ size_t *remainp;
+{
+ if (*remainp >= sizeof(krb5_int32)) {
+ *intp = (((krb5_int32) ((unsigned char) (*bufp)[0]) << 24) |
+ ((krb5_int32) ((unsigned char) (*bufp)[1]) << 16) |
+ ((krb5_int32) ((unsigned char) (*bufp)[2]) << 8) |
+ ((krb5_int32) ((unsigned char) (*bufp)[3])));
+ *bufp += sizeof(krb5_int32);
+ *remainp -= sizeof(krb5_int32);
+ return(0);
+ }
+ else
+ return(ENOMEM);
+}
+
+/*
+ * krb5_ser_unpack_bytes() - Unpack a byte string if it's there.
+ */
+krb5_error_code
+krb5_ser_unpack_bytes(istring, isize, bufp, remainp)
+ krb5_octet *istring;
+ size_t isize;
+ krb5_octet **bufp;
+ size_t *remainp;
+{
+ if (*remainp >= isize) {
+ memcpy(istring, *bufp, isize);
+ *bufp += isize;
+ *remainp -= isize;
+ return(0);
+ }
+ else
+ return(ENOMEM);
+}