Add serialization support for K5 data structures
authorPaul Park <pjpark@mit.edu>
Tue, 29 Aug 1995 18:39:10 +0000 (18:39 +0000)
committerPaul Park <pjpark@mit.edu>
Tue, 29 Aug 1995 18:39:10 +0000 (18:39 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6622 dc483132-0cff-0310-8789-dd5450dbe970

12 files changed:
src/lib/krb5/krb/.Sanitize
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/ser_actx.c [new file with mode: 0644]
src/lib/krb5/krb/ser_adata.c [new file with mode: 0644]
src/lib/krb5/krb/ser_addr.c [new file with mode: 0644]
src/lib/krb5/krb/ser_auth.c [new file with mode: 0644]
src/lib/krb5/krb/ser_cksum.c [new file with mode: 0644]
src/lib/krb5/krb/ser_ctx.c [new file with mode: 0644]
src/lib/krb5/krb/ser_eblk.c [new file with mode: 0644]
src/lib/krb5/krb/ser_key.c [new file with mode: 0644]
src/lib/krb5/krb/ser_princ.c [new file with mode: 0644]
src/lib/krb5/krb/serialize.c [new file with mode: 0644]

index 7ea50275183beebf6fa795f50917b192b3e5cb5c..584394c7624262a4f8462532df3a9ad0285cf27b 100644 (file)
@@ -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
index 5ec8dc391490066af99c360cc085c846707a0ec9..de0effd57de60be7981d432ec86e5d636935786a 100644 (file)
@@ -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 (file)
index 0000000..0b0cdd4
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..cfcced4
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..6e08393
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..828012c
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..3fc9d51
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..f317a51
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..791963e
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..eacbf01
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..5828754
--- /dev/null
@@ -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  */
+};
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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 (file)
index 0000000..20107c4
--- /dev/null
@@ -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"
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}
+\f
+/*
+ * 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);
+}