From 898bf1e2f45c34371b42d83ece7200cb170b6582 Mon Sep 17 00:00:00 2001 From: Paul Park Date: Tue, 29 Aug 1995 18:39:10 +0000 Subject: [PATCH] Add serialization support for K5 data structures git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6622 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/.Sanitize | 10 + src/lib/krb5/krb/Makefile.in | 33 ++- src/lib/krb5/krb/ser_actx.c | 558 +++++++++++++++++++++++++++++++++++ src/lib/krb5/krb/ser_adata.c | 207 +++++++++++++ src/lib/krb5/krb/ser_addr.c | 209 +++++++++++++ src/lib/krb5/krb/ser_auth.c | 356 ++++++++++++++++++++++ src/lib/krb5/krb/ser_cksum.c | 210 +++++++++++++ src/lib/krb5/krb/ser_ctx.c | 468 +++++++++++++++++++++++++++++ src/lib/krb5/krb/ser_eblk.c | 266 +++++++++++++++++ src/lib/krb5/krb/ser_key.c | 217 ++++++++++++++ src/lib/krb5/krb/ser_princ.c | 189 ++++++++++++ src/lib/krb5/krb/serialize.c | 277 +++++++++++++++++ 12 files changed, 2997 insertions(+), 3 deletions(-) create mode 100644 src/lib/krb5/krb/ser_actx.c create mode 100644 src/lib/krb5/krb/ser_adata.c create mode 100644 src/lib/krb5/krb/ser_addr.c create mode 100644 src/lib/krb5/krb/ser_auth.c create mode 100644 src/lib/krb5/krb/ser_cksum.c create mode 100644 src/lib/krb5/krb/ser_ctx.c create mode 100644 src/lib/krb5/krb/ser_eblk.c create mode 100644 src/lib/krb5/krb/ser_key.c create mode 100644 src/lib/krb5/krb/ser_princ.c create mode 100644 src/lib/krb5/krb/serialize.c diff --git a/src/lib/krb5/krb/.Sanitize b/src/lib/krb5/krb/.Sanitize index 7ea502751..584394c76 100644 --- a/src/lib/krb5/krb/.Sanitize +++ b/src/lib/krb5/krb/.Sanitize @@ -88,6 +88,16 @@ rd_safe.c recvauth.c send_tgs.c sendauth.c +ser_actx.c +ser_addr.c +ser_adata.c +ser_auth.c +ser_cksum.c +ser_ctx.c +ser_eblk.c +ser_key.c +ser_princ.c +serialize.c srv_rcache.c t_walk_rtree.c t_kerb.c diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index 5ec8dc391..de0effd57 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -65,6 +65,16 @@ OBJS= addr_comp.$(OBJEXT) \ recvauth.$(OBJEXT) \ sendauth.$(OBJEXT) \ send_tgs.$(OBJEXT) \ + ser_actx.$(OBJEXT) \ + ser_adata.$(OBJEXT) \ + ser_addr.$(OBJEXT) \ + ser_auth.$(OBJEXT) \ + ser_cksum.$(OBJEXT) \ + ser_ctx.$(OBJEXT) \ + ser_eblk.$(OBJEXT) \ + ser_key.$(OBJEXT) \ + ser_princ.$(OBJEXT) \ + serialize.$(OBJEXT) \ srv_rcache.$(OBJEXT) \ tgtname.$(OBJEXT) \ unparse.$(OBJEXT) \ @@ -127,6 +137,16 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/recvauth.c \ $(srcdir)/sendauth.c \ $(srcdir)/send_tgs.c \ + $(srcdir)/ser_actx.c \ + $(srcdir)/ser_adata.c \ + $(srcdir)/ser_addr.c \ + $(srcdir)/ser_auth.c \ + $(srcdir)/ser_cksum.c \ + $(srcdir)/ser_ctx.c \ + $(srcdir)/ser_eblk.c \ + $(srcdir)/ser_key.c \ + $(srcdir)/ser_princ.c \ + $(srcdir)/serialize.c \ $(srcdir)/srv_rcache.c \ $(srcdir)/tgtname.c \ $(srcdir)/unparse.c \ @@ -150,13 +170,20 @@ T_WALK_RTREE_OBJS= t_walk_rtree.o walk_rtree.o tgtname.o unparse.o \ T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o \ $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(COMERRLIB) +T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \ + ser_ctx.o ser_eblk.o ser_key.o ser_princ.o serialize.o \ + $(TOPLIBD)/libkdb5.a $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(COMERRLIB) + t_walk_rtree: $(T_WALK_RTREE_OBJS) $(LD) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(LIBS) t_kerb: $(T_KERB_OBJS) $(LD) -o t_kerb $(T_KERB_OBJS) $(LIBS) -TEST_PROGS= t_walk_rtree t_kerb +t_ser: $(T_SER_OBJS) + $(LD) -o t_ser $(T_SER_OBJS) $(LIBS) + +TEST_PROGS= t_walk_rtree t_kerb t_ser check:: check-$(WHAT) @@ -172,8 +199,7 @@ check-unix:: $(TEST_PROGS) > test.out cmp test.out $(srcdir)/t_ref_kerb.out $(RM) test.out - - + ./t_ser check-mac:: $(TEST_PROGS) @@ -182,6 +208,7 @@ check-windows:: clean:: clean-$(WHAT) $(RM) t_walk_rtree$(EXEEXT) t_walk_rtree.$(OBJEXT) $(RM) t_kerb$(EXEEXT) t_kerb.$(OBJEXT) + $(RM) t_ser$(EXEEXT) t_ser.$(OBJEXT) clean-unix:: $(RM) shared/* diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c new file mode 100644 index 000000000..0b0cdd4c5 --- /dev/null +++ b/src/lib/krb5/krb/ser_actx.c @@ -0,0 +1,558 @@ +/* + * lib/krb5/krb/ser_actx.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_actx.c - Serialize krb5_auth_context structure. + */ +#include "k5-int.h" +#include "auth_con.h" + +#define TOKEN_RADDR 950916 +#define TOKEN_RPORT 950917 +#define TOKEN_LADDR 950918 +#define TOKEN_LPORT 950919 +#define TOKEN_KEYBLOCK 950920 +#define TOKEN_LSKBLOCK 950921 +#define TOKEN_RSKBLOCK 950922 + +/* + * Routines to deal with externalizing the krb5_auth_context: + * krb5_auth_context_size(); + * krb5_auth_context_externalize(); + * krb5_auth_context_internalize(); + */ +static krb5_error_code krb5_auth_context_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_auth_context_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_auth_context_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* + * Other metadata serialization initializers. + */ +krb5_error_code krb5_ser_authdata_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_address_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_authenticator_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_checksum_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_encrypt_block_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_keyblock_init KRB5_PROTOTYPE((krb5_context)); +krb5_error_code krb5_ser_principal_init KRB5_PROTOTYPE((krb5_context)); + +/* Local data */ +static const krb5_ser_entry krb5_auth_context_ser_entry = { + KV5M_AUTH_CONTEXT, /* Type */ + krb5_auth_context_size, /* Sizer routine */ + krb5_auth_context_externalize, /* Externalize routine */ + krb5_auth_context_internalize /* Internalize routine */ +}; + +/* + * krb5_auth_context_size() - Determine the size required to externalize + * the krb5_auth_context. + */ +static krb5_error_code +krb5_auth_context_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_auth_context auth_context; + size_t required; + + /* + * krb5_auth_context requires at minimum: + * krb5_int32 for KV5M_AUTH_CONTEXT + * krb5_int32 for auth_context_flags + * krb5_int32 for remote_seq_number + * krb5_int32 for local_seq_number + * krb5_int32 for cksumtype + * krb5_int32 for size of i_vector + * krb5_int32 for KV5M_AUTH_CONTEXT + */ + kret = EINVAL; + if ((auth_context = (krb5_auth_context) arg)) { + required = sizeof(krb5_int32)*7; + + kret = 0; + /* Calculate size required by i_vector - ptooey */ + if (auth_context->i_vector && auth_context->keyblock) + required += (size_t) + krb5_keytype_array[auth_context->keyblock->keytype]-> + system->block_length; + + /* Calculate size required by remote_addr, if appropriate */ + if (auth_context->remote_addr) { + kret = krb5_size_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) auth_context->remote_addr, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by remote_port, if appropriate */ + if (!kret && auth_context->remote_port) { + kret = krb5_size_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) auth_context->remote_port, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by local_addr, if appropriate */ + if (!kret && auth_context->local_addr) { + kret = krb5_size_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) auth_context->local_addr, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by local_port, if appropriate */ + if (!kret && auth_context->local_port) { + kret = krb5_size_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) auth_context->local_port, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by keyblock, if appropriate */ + if (!kret && auth_context->keyblock) { + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) auth_context->keyblock, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by local_subkey, if appropriate */ + if (!kret && auth_context->local_subkey) { + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) auth_context->local_subkey, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by remote_subkey, if appropriate */ + if (!kret && auth_context->remote_subkey) { + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) auth_context->remote_subkey, + &required); + if (!kret) + required += sizeof(krb5_int32); + } + + /* Calculate size required by authentp, if appropriate */ + if (!kret && auth_context->authentp) + kret = krb5_size_opaque(kcontext, + KV5M_AUTHENTICATOR, + (krb5_pointer) auth_context->authentp, + &required); + + } + if (!kret) + *sizep += required; + return(kret); +} + +/* + * krb5_auth_context_externalize() - Externalize the krb5_auth_context. + */ +static krb5_error_code +krb5_auth_context_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_auth_context auth_context; + size_t required; + krb5_octet *bp; + size_t remain; + krb5_int32 obuf; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((auth_context = (krb5_auth_context) arg)) { + kret = ENOMEM; + if (!krb5_auth_context_size(kcontext, arg, &required) && + (required <= remain)) { + + /* Write fixed portion */ + (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain); + (void) krb5_ser_pack_int32(auth_context->auth_context_flags, + &bp, &remain); + (void) krb5_ser_pack_int32(auth_context->remote_seq_number, + &bp, &remain); + (void) krb5_ser_pack_int32(auth_context->local_seq_number, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) auth_context->cksumtype, + &bp, &remain); + + /* Now figure out the number of bytes for i_vector and write it */ + obuf = (!auth_context->i_vector) ? 0 : (krb5_int32) + krb5_keytype_array[auth_context->keyblock->keytype]-> + system->block_length; + (void) krb5_ser_pack_int32(obuf, &bp, &remain); + + /* Now copy i_vector */ + if (auth_context->i_vector) + (void) krb5_ser_pack_bytes(auth_context->i_vector, + (size_t) obuf, + &bp, &remain); + kret = 0; + + /* Now handle remote_addr, if appropriate */ + if (!kret && auth_context->remote_addr) { + (void) krb5_ser_pack_int32(TOKEN_RADDR, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) + auth_context->remote_addr, + &bp, + &remain); + } + + /* Now handle remote_port, if appropriate */ + if (!kret && auth_context->remote_port) { + (void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) + auth_context->remote_addr, + &bp, + &remain); + } + + /* Now handle local_addr, if appropriate */ + if (!kret && auth_context->local_addr) { + (void) krb5_ser_pack_int32(TOKEN_LADDR, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) + auth_context->local_addr, + &bp, + &remain); + } + + /* Now handle local_port, if appropriate */ + if (!kret && auth_context->local_port) { + (void) krb5_ser_pack_int32(TOKEN_LPORT, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer) + auth_context->local_addr, + &bp, + &remain); + } + + /* Now handle keyblock, if appropriate */ + if (!kret && auth_context->keyblock) { + (void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) + auth_context->keyblock, + &bp, + &remain); + } + + /* Now handle subkey, if appropriate */ + if (!kret && auth_context->local_subkey) { + (void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) + auth_context->local_subkey, + &bp, + &remain); + } + + /* Now handle subkey, if appropriate */ + if (!kret && auth_context->remote_subkey) { + (void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain); + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) + auth_context->remote_subkey, + &bp, + &remain); + } + + /* Now handle authentp, if appropriate */ + if (!kret && auth_context->authentp) + kret = krb5_externalize_opaque(kcontext, + KV5M_AUTHENTICATOR, + (krb5_pointer) + auth_context->authentp, + &bp, + &remain); + + /* + * If we were successful, write trailer then update the pointer and + * remaining length; + */ + if (!kret) { + /* Write our trailer */ + (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain); + *buffer = bp; + *lenremain = remain; + } + } + } + return(kret); +} + +/* + * krb5_auth_context_internalize() - Internalize the krb5_auth_context. + */ +static krb5_error_code +krb5_auth_context_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_auth_context auth_context; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + krb5_int32 ivlen; + krb5_int32 tag; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_AUTH_CONTEXT) { + kret = ENOMEM; + + /* Get memory for the auth_context */ + if ((remain >= (5*sizeof(krb5_int32))) && + (auth_context = (krb5_auth_context) + malloc(sizeof(struct _krb5_auth_context)))) { + memset(auth_context, 0, sizeof(struct _krb5_auth_context)); + + /* Get auth_context_flags */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + auth_context->auth_context_flags = ibuf; + + /* Get remote_seq_number */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + auth_context->remote_seq_number = ibuf; + + /* Get local_seq_number */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + auth_context->local_seq_number = ibuf; + + /* Get cksumtype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + auth_context->cksumtype = (krb5_cksumtype) ibuf; + + /* Get length of i_vector */ + (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain); + + if (ivlen) { + if ((auth_context->i_vector = + (krb5_pointer) malloc((size_t)ivlen))) + kret = krb5_ser_unpack_bytes(auth_context->i_vector, + (size_t) ivlen, + &bp, + &remain); + else + kret = ENOMEM; + } + else + kret = 0; + + /* Peek at next token */ + tag = 0; + if (!kret) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + + /* This is the remote_addr */ + if (!kret && (tag == TOKEN_RADDR)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer *) + &auth_context-> + remote_addr, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the remote_port */ + if (!kret && (tag == TOKEN_RPORT)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer *) + &auth_context-> + remote_port, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the local_addr */ + if (!kret && (tag == TOKEN_LADDR)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer *) + &auth_context-> + local_addr, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the local_port */ + if (!kret && (tag == TOKEN_LPORT)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_ADDRESS, + (krb5_pointer *) + &auth_context-> + local_port, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the keyblock */ + if (!kret && (tag == TOKEN_KEYBLOCK)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) + &auth_context->keyblock, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the local_subkey */ + if (!kret && (tag == TOKEN_LSKBLOCK)) { + if (!(kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) + &auth_context-> + local_subkey, + &bp, + &remain))) + kret = krb5_ser_unpack_int32(&tag, &bp, &remain); + } + + /* This is the remote_subkey */ + if (!kret) { + if (tag == TOKEN_RSKBLOCK) { + kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) + &auth_context-> + remote_subkey, + &bp, + &remain); + } + else { + /* + * We read the next tag, but it's not of any use here, so + * we effectively 'unget' it here. + */ + bp -= sizeof(krb5_int32); + remain += sizeof(krb5_int32); + } + } + + /* Now find the authentp */ + if (!kret) { + if ((kret = krb5_internalize_opaque(kcontext, + KV5M_AUTHENTICATOR, + (krb5_pointer *) + &auth_context->authentp, + &bp, + &remain))) { + if (kret == EINVAL) + kret = 0; + } + } + + /* Finally, find the trailer */ + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf != KV5M_AUTH_CONTEXT)) + kret = EINVAL; + } + if (!kret) { + *buffer = bp; + *lenremain = remain; + auth_context->magic = KV5M_AUTH_CONTEXT; + *argp = (krb5_pointer) auth_context; + } + else + krb5_auth_con_free(kcontext, auth_context); + } + } + return(kret); +} + +/* + * Register the auth_context serializer. + */ +krb5_error_code +krb5_ser_auth_context_init(kcontext) + krb5_context kcontext; +{ + krb5_error_code kret; + kret = krb5_register_serializer(kcontext, &krb5_auth_context_ser_entry); + if (!kret) + kret = krb5_ser_authdata_init(kcontext); + if (!kret) + kret = krb5_ser_address_init(kcontext); + if (!kret) + kret = krb5_ser_authenticator_init(kcontext); + if (!kret) + kret = krb5_ser_checksum_init(kcontext); + if (!kret) + kret = krb5_ser_encrypt_block_init(kcontext); + if (!kret) + kret = krb5_ser_keyblock_init(kcontext); + if (!kret) + kret = krb5_ser_principal_init(kcontext); + return(kret); +} diff --git a/src/lib/krb5/krb/ser_adata.c b/src/lib/krb5/krb/ser_adata.c new file mode 100644 index 000000000..cfcced42b --- /dev/null +++ b/src/lib/krb5/krb/ser_adata.c @@ -0,0 +1,207 @@ +/* + * lib/krb5/krb/ser_adata.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_adata.c - Serialize a krb5_authdata structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_authdata: + * krb5_authdata_size(); + * krb5_authdata_externalize(); + * krb5_authdata_internalize(); + */ +static krb5_error_code krb5_authdata_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_authdata_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_authdata_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_authdata_ser_entry = { + KV5M_AUTHDATA, /* Type */ + krb5_authdata_size, /* Sizer routine */ + krb5_authdata_externalize, /* Externalize routine */ + krb5_authdata_internalize /* Internalize routine */ +}; + +/* + * krb5_authdata_esize() - Determine the size required to externalize + * the krb5_authdata. + */ +static krb5_error_code +krb5_authdata_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_authdata *authdata; + + /* + * krb5_authdata requires: + * krb5_int32 for KV5M_AUTHDATA + * krb5_int32 for ad_type + * krb5_int32 for length + * authdata->length for contents + * krb5_int32 for KV5M_AUTHDATA + */ + kret = EINVAL; + if ((authdata = (krb5_authdata *) arg)) { + *sizep += (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (size_t) authdata->length); + kret = 0; + } + return(kret); +} + +/* + * krb5_authdata_externalize() - Externalize the krb5_authdata. + */ +static krb5_error_code +krb5_authdata_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_authdata *authdata; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((authdata = (krb5_authdata *) arg)) { + kret = ENOMEM; + if (!krb5_authdata_size(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain); + + /* Our ad_type */ + (void) krb5_ser_pack_int32((krb5_int32) authdata->ad_type, + &bp, &remain); + + /* Our length */ + (void) krb5_ser_pack_int32((krb5_int32) authdata->length, + &bp, &remain); + + /* Our contents */ + (void) krb5_ser_pack_bytes(authdata->contents, + (size_t) authdata->length, + &bp, &remain); + + /* Finally, our trailer */ + (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain); + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + return(kret); +} + +/* + * krb5_authdata_internalize() - Internalize the krb5_authdata. + */ +static krb5_error_code +krb5_authdata_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_authdata *authdata; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_AUTHDATA) { + kret = ENOMEM; + + /* Get a authdata */ + if ((remain >= (2*sizeof(krb5_int32))) && + (authdata = (krb5_authdata *) malloc(sizeof(krb5_authdata)))) { + memset(authdata, 0, sizeof(krb5_authdata)); + + /* Get the ad_type */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + authdata->ad_type = (krb5_authdatatype) ibuf; + + /* Get the length */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + authdata->length = (int) ibuf; + + /* Get the string */ + if ((authdata->contents = (krb5_octet *) + malloc((size_t) (ibuf))) && + !(kret = krb5_ser_unpack_bytes(authdata->contents, + (size_t) ibuf, + &bp, &remain))) { + if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + ibuf = 0; + if (ibuf == KV5M_AUTHDATA) { + authdata->magic = KV5M_AUTHDATA; + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) authdata; + } + else + kret = EINVAL; + } + if (kret) { + if (authdata->contents) + free(authdata->contents); + free(authdata); + } + } + } + return(kret); +} + +/* + * Register the authdata serializer. + */ +krb5_error_code +krb5_ser_authdata_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_authdata_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_addr.c b/src/lib/krb5/krb/ser_addr.c new file mode 100644 index 000000000..6e08393f2 --- /dev/null +++ b/src/lib/krb5/krb/ser_addr.c @@ -0,0 +1,209 @@ +/* + * lib/krb5/krb/ser_addr.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_addr.c - Serialize a krb5_address structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_address: + * krb5_address_size(); + * krb5_address_externalize(); + * krb5_address_internalize(); + */ +static krb5_error_code krb5_address_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_address_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_address_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_address_ser_entry = { + KV5M_ADDRESS, /* Type */ + krb5_address_size, /* Sizer routine */ + krb5_address_externalize, /* Externalize routine */ + krb5_address_internalize /* Internalize routine */ +}; + +/* + * krb5_address_size() - Determine the size required to externalize + * the krb5_address. + */ +static krb5_error_code +krb5_address_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_address *address; + + /* + * krb5_address requires: + * krb5_int32 for KV5M_ADDRESS + * krb5_int32 for addrtype + * krb5_int32 for length + * address->length for contents + * krb5_int32 for KV5M_ADDRESS + */ + kret = EINVAL; + if ((address = (krb5_address *) arg)) { + *sizep += (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (size_t) address->length); + kret = 0; + } + return(kret); +} + +/* + * krb5_address_externalize() - Externalize the krb5_address. + */ +static krb5_error_code +krb5_address_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_address *address; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((address = (krb5_address *) arg)) { + kret = ENOMEM; + if (!krb5_address_size(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain); + + /* Our addrtype */ + (void) krb5_ser_pack_int32((krb5_int32) address->addrtype, + &bp, &remain); + + /* Our length */ + (void) krb5_ser_pack_int32((krb5_int32) address->length, + &bp, &remain); + + /* Our contents */ + (void) krb5_ser_pack_bytes(address->contents, + (size_t) address->length, + &bp, &remain); + + /* Finally, our trailer */ + (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain); + + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + return(kret); +} + +/* + * krb5_address_internalize() - Internalize the krb5_address. + */ +static krb5_error_code +krb5_address_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_address *address; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_ADDRESS) { + kret = ENOMEM; + + /* Get a address */ + if ((remain >= (2*sizeof(krb5_int32))) && + (address = (krb5_address *) malloc(sizeof(krb5_address)))) { + memset(address, 0, sizeof(krb5_address)); + + /* Get the addrtype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + address->addrtype = (krb5_addrtype) ibuf; + + /* Get the length */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + address->length = (int) ibuf; + + /* Get the string */ + if ((address->contents = (krb5_octet *) malloc((size_t) (ibuf))) && + !(kret = krb5_ser_unpack_bytes(address->contents, + (size_t) ibuf, + &bp, &remain))) { + /* Get the trailer */ + if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + ibuf = 0; + + if (!kret && (ibuf == KV5M_ADDRESS)) { + address->magic = KV5M_ADDRESS; + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) address; + } + else + kret = EINVAL; + } + if (kret) { + if (address->contents) + free(address->contents); + free(address); + } + } + } + return(kret); +} + +/* + * Register the address serializer. + */ +krb5_error_code +krb5_ser_address_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_address_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_auth.c b/src/lib/krb5/krb/ser_auth.c new file mode 100644 index 000000000..828012ce3 --- /dev/null +++ b/src/lib/krb5/krb/ser_auth.c @@ -0,0 +1,356 @@ +/* + * lib/krb5/krb/ser_auth.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_auth.c - Serialize krb5_authenticator structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_authenticator: + * krb5_authenticator_size(); + * krb5_authenticator_externalize(); + * krb5_authenticator_internalize(); + */ +static krb5_error_code krb5_authenticator_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_authenticator_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_authenticator_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_authenticator_ser_entry = { + KV5M_AUTHENTICATOR, /* Type */ + krb5_authenticator_size, /* Sizer routine */ + krb5_authenticator_externalize, /* Externalize routine */ + krb5_authenticator_internalize /* Internalize routine */ +}; + +/* + * krb5_authenticator_size() - Determine the size required to externalize + * the krb5_authenticator. + */ +static krb5_error_code +krb5_authenticator_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_authenticator *authenticator; + size_t required; + + /* + * krb5_authenticator requires at minimum: + * krb5_int32 for KV5M_AUTHENTICATOR + * krb5_int32 for seconds + * krb5_int32 for cusec + * krb5_int32 for seq_number + * krb5_int32 for number in authorization_data array. + * krb5_int32 for KV5M_AUTHENTICATOR + */ + kret = EINVAL; + if ((authenticator = (krb5_authenticator *) arg)) { + required = sizeof(krb5_int32)*6; + + /* Calculate size required by client, if appropriate */ + if (authenticator->client) + kret = krb5_size_opaque(kcontext, + KV5M_PRINCIPAL, + (krb5_pointer) authenticator->client, + &required); + else + kret = 0; + + /* Calculate size required by checksum, if appropriate */ + if (!kret && authenticator->checksum) + kret = krb5_size_opaque(kcontext, + KV5M_CHECKSUM, + (krb5_pointer) authenticator->checksum, + &required); + + /* Calculate size required by subkey, if appropriate */ + if (!kret && authenticator->subkey) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) authenticator->subkey, + &required); + + /* Calculate size required by authorization_data, if appropriate */ + if (!kret && authenticator->authorization_data) { + int i; + + for (i=0; !kret && authenticator->authorization_data[i]; i++) { + kret = krb5_size_opaque(kcontext, + KV5M_AUTHDATA, + (krb5_pointer) authenticator-> + authorization_data[i], + &required); + } + } + } + if (!kret) + *sizep += required; + return(kret); +} + +/* + * krb5_authenticator_externalize() - Externalize the krb5_authenticator. + */ +static krb5_error_code +krb5_authenticator_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_authenticator *authenticator; + size_t required; + krb5_octet *bp; + size_t remain; + int i; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((authenticator = (krb5_authenticator *) arg)) { + kret = ENOMEM; + if (!krb5_authenticator_size(kcontext, arg, &required) && + (required <= remain)) { + /* First write our magic number */ + (void) krb5_ser_pack_int32(KV5M_AUTHENTICATOR, &bp, &remain); + + /* Now ctime */ + (void) krb5_ser_pack_int32((krb5_int32) authenticator->ctime, + &bp, &remain); + + /* Now cusec */ + (void) krb5_ser_pack_int32((krb5_int32) authenticator->cusec, + &bp, &remain); + + /* Now seq_number */ + (void) krb5_ser_pack_int32(authenticator->seq_number, + &bp, &remain); + + /* Now handle client, if appropriate */ + if (authenticator->client) + kret = krb5_externalize_opaque(kcontext, + KV5M_PRINCIPAL, + (krb5_pointer) + authenticator->client, + &bp, + &remain); + else + kret = 0; + + /* Now handle checksum, if appropriate */ + if (!kret && authenticator->checksum) + kret = krb5_externalize_opaque(kcontext, + KV5M_CHECKSUM, + (krb5_pointer) + authenticator->checksum, + &bp, + &remain); + + /* Now handle subkey, if appropriate */ + if (!kret && authenticator->subkey) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) + authenticator->subkey, + &bp, + &remain); + + /* Now handle authorization_data, if appropriate */ + if (!kret) { + if (authenticator->authorization_data) + for (i=0; authenticator->authorization_data[i]; i++); + else + i = 0; + (void) krb5_ser_pack_int32((krb5_int32) i, &bp, &remain); + + /* Now pound out the authorization_data */ + if (authenticator->authorization_data) { + for (i=0; !kret && authenticator->authorization_data[i]; + i++) + kret = krb5_externalize_opaque(kcontext, + KV5M_AUTHDATA, + (krb5_pointer) + authenticator-> + authorization_data[i], + &bp, + &remain); + } + } + + /* + * If we were successful, write trailer then update the pointer and + * remaining length; + */ + if (!kret) { + /* Write our trailer */ + (void) krb5_ser_pack_int32(KV5M_AUTHENTICATOR, &bp, &remain); + *buffer = bp; + *lenremain = remain; + } + } + } + return(kret); +} + +/* + * krb5_authenticator_internalize() - Internalize the krb5_authenticator. + */ +static krb5_error_code +krb5_authenticator_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_authenticator *authenticator; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + int i; + krb5_int32 nadata; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_AUTHENTICATOR) { + kret = ENOMEM; + + /* Get memory for the authenticator */ + if ((remain >= (3*sizeof(krb5_int32))) && + (authenticator = (krb5_authenticator *) + malloc(sizeof(krb5_authenticator)))) { + memset(authenticator, 0, sizeof(krb5_authenticator)); + + /* Get ctime */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + authenticator->ctime = (krb5_timestamp) ibuf; + + /* Get cusec */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + authenticator->cusec = ibuf; + + /* Get seq_number */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + authenticator->seq_number = ibuf; + + kret = 0; + + /* Attempt to read in the client */ + kret = krb5_internalize_opaque(kcontext, + KV5M_PRINCIPAL, + (krb5_pointer *) + &authenticator->client, + &bp, + &remain); + if (kret == EINVAL) + kret = 0; + + /* Attempt to read in the checksum */ + if (!kret) { + kret = krb5_internalize_opaque(kcontext, + KV5M_CHECKSUM, + (krb5_pointer *) + &authenticator->checksum, + &bp, + &remain); + if (kret == EINVAL) + kret = 0; + } + + /* Attempt to read in the subkey */ + if (!kret) { + kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) + &authenticator->subkey, + &bp, + &remain); + if (kret == EINVAL) + kret = 0; + } + + /* Attempt to read in the authorization data count */ + if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) { + nadata = ibuf; + + /* Get memory for the authorization data pointers */ + if ((authenticator->authorization_data = (krb5_authdata **) + malloc(sizeof(krb5_authdata *) * (nadata+1)))) { + memset(authenticator->authorization_data, 0, + sizeof(krb5_authdata *) * (nadata+1)); + + for (i=0; !kret && (i + authorization_data[i], + &bp, + &remain); + } + + /* Finally, find the trailer */ + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_AUTHENTICATOR)) + authenticator->magic = KV5M_AUTHENTICATOR; + else + kret = EINVAL; + } + } + } + if (!kret) { + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) authenticator; + } + else + krb5_free_authenticator(kcontext, authenticator); + } + } + return(kret); +} + +/* + * Register the authenticator serializer. + */ +krb5_error_code +krb5_ser_authenticator_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_authenticator_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_cksum.c b/src/lib/krb5/krb/ser_cksum.c new file mode 100644 index 000000000..3fc9d5196 --- /dev/null +++ b/src/lib/krb5/krb/ser_cksum.c @@ -0,0 +1,210 @@ +/* + * lib/krb5/krb/ser_cksum.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_cksum.c - Serialize a krb5_checksum structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_checksum: + * krb5_checksum_esize(); + * krb5_checksum_externalize(); + * krb5_checksum_internalize(); + */ +static krb5_error_code krb5_checksum_esize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_checksum_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_checksum_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_checksum_ser_entry = { + KV5M_CHECKSUM, /* Type */ + krb5_checksum_esize, /* Sizer routine */ + krb5_checksum_externalize, /* Externalize routine */ + krb5_checksum_internalize /* Internalize routine */ +}; + +/* + * krb5_checksum_esize() - Determine the size required to externalize + * the krb5_checksum. + */ +static krb5_error_code +krb5_checksum_esize(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_checksum *checksum; + + /* + * krb5_checksum requires: + * krb5_int32 for KV5M_CHECKSUM + * krb5_int32 for checksum_type + * krb5_int32 for length + * krb5_int32 for KV5M_CHECKSUM + * checksum->length for contents + */ + kret = EINVAL; + if ((checksum = (krb5_checksum *) arg)) { + *sizep += (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (size_t) checksum->length); + kret = 0; + } + return(kret); +} + +/* + * krb5_checksum_externalize() - Externalize the krb5_checksum. + */ +static krb5_error_code +krb5_checksum_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_checksum *checksum; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((checksum = (krb5_checksum *) arg)) { + kret = ENOMEM; + if (!krb5_checksum_esize(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); + + /* Our checksum_type */ + (void) krb5_ser_pack_int32((krb5_int32) checksum->checksum_type, + &bp, &remain); + + /* Our length */ + (void) krb5_ser_pack_int32((krb5_int32) checksum->length, + &bp, &remain); + + /* Our contents */ + (void) krb5_ser_pack_bytes(checksum->contents, + (size_t) checksum->length, + &bp, &remain); + + /* Finally, our trailer */ + (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); + + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + return(kret); +} + +/* + * krb5_checksum_internalize() - Internalize the krb5_checksum. + */ +static krb5_error_code +krb5_checksum_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_checksum *checksum; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_CHECKSUM) { + kret = ENOMEM; + + /* Get a checksum */ + if ((remain >= (2*sizeof(krb5_int32))) && + (checksum = (krb5_checksum *) malloc(sizeof(krb5_checksum)))) { + memset(checksum, 0, sizeof(krb5_checksum)); + + /* Get the checksum_type */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + checksum->checksum_type = (krb5_cksumtype) ibuf; + + /* Get the length */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + checksum->length = (int) ibuf; + + /* Get the string */ + if (!ibuf || + ((checksum->contents = (krb5_octet *) + malloc((size_t) (ibuf))) && + !(kret = krb5_ser_unpack_bytes(checksum->contents, + (size_t) ibuf, + &bp, &remain)))) { + + /* Get the trailer */ + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_CHECKSUM)) { + checksum->magic = KV5M_CHECKSUM; + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) checksum; + } + else + kret = EINVAL; + } + if (kret) { + if (checksum->contents) + free(checksum->contents); + free(checksum); + } + } + } + return(kret); +} + +/* + * Register the checksum serializer. + */ +krb5_error_code +krb5_ser_checksum_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_checksum_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_ctx.c b/src/lib/krb5/krb/ser_ctx.c new file mode 100644 index 000000000..f317a519d --- /dev/null +++ b/src/lib/krb5/krb/ser_ctx.c @@ -0,0 +1,468 @@ +/* + * lib/krb5/krb/ser_ctx.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_ctx.c - Routines to deal with serializing the krb5_context and + * krb5_os_context structures. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_context: + * krb5_context_size(); + * krb5_context_externalize(); + * krb5_context_internalize(); + * + * Routines to deal with externalizing the krb5_os_context: + * krb5_oscontext_size(); + * krb5_oscontext_externalize(); + * krb5_oscontext_internalize(); + * + * Routines to deal with externalizing the profile. + * profile_ser_size(); + * profile_ser_externalize(); + * profile_ser_internalize(); + * + * Interface to initialize serializing of krb5_context and krb5_os_context: + * krb5_ser_context_init(); + */ +static krb5_error_code krb5_context_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_context_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_context_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); +static krb5_error_code krb5_oscontext_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_oscontext_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_oscontext_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); +krb5_error_code profile_ser_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +krb5_error_code profile_ser_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +krb5_error_code profile_ser_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_context_ser_entry = { + KV5M_CONTEXT, /* Type */ + krb5_context_size, /* Sizer routine */ + krb5_context_externalize, /* Externalize routine */ + krb5_context_internalize /* Internalize routine */ +}; +static const krb5_ser_entry krb5_oscontext_ser_entry = { + KV5M_OS_CONTEXT, /* Type */ + krb5_oscontext_size, /* Sizer routine */ + krb5_oscontext_externalize, /* Externalize routine */ + krb5_oscontext_internalize /* Internalize routine */ +}; +static const krb5_ser_entry krb5_profile_ser_entry = { + PROF_MAGIC_PROFILE, /* Type */ + profile_ser_size, /* Sizer routine */ + profile_ser_externalize, /* Externalize routine */ + profile_ser_internalize /* Internalize routine */ +}; + +/* + * krb5_context_size() - Determine the size required to externalize the + * krb5_context. + */ +static krb5_error_code +krb5_context_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + size_t required; + krb5_context context; + + /* + * The KRB5 context itself requires: + * krb5_int32 for KV5M_CONTEXT + * krb5_int32 for sizeof(default_realm) + * strlen(default_realm) for default_realm. + * krb5_int32 for netypes*sizeof(krb5_int32) + * netypes*sizeof(krb5_int32) for etypes. + * krb5_int32 for trailer. + */ + kret = EINVAL; + if ((context = (krb5_context) arg)) { + /* Calculate base length */ + required = (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (context->etype_count * sizeof(krb5_int32))); + + if (context->default_realm) + required += strlen(context->default_realm); + /* Calculate size required by os_context, if appropriate */ + if (context->os_context) + kret = krb5_size_opaque(kcontext, + KV5M_OS_CONTEXT, + (krb5_pointer) context->os_context, + &required); + + /* Calculate size required by db_context, if appropriate */ + if (!kret && context->db_context) + kret = krb5_size_opaque(kcontext, + KV5M_DB_CONTEXT, + (krb5_pointer) context->db_context, + &required); + + /* Finally, calculate size required by profile, if appropriate */ + if (!kret && context->profile) + kret = krb5_size_opaque(kcontext, + PROF_MAGIC_PROFILE, + (krb5_pointer) context->profile, + &required); + } + if (!kret) + *sizep += required; + return(kret); +} + +/* + * krb5_context_externalize() - Externalize the krb5_context. + */ +static krb5_error_code +krb5_context_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_context context; + size_t required; + krb5_octet *bp; + size_t remain; + int i; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((context = (krb5_context) arg)) { + kret = ENOMEM; + if (!krb5_context_size(kcontext, arg, &required) && + (required <= remain)) { + /* First write our magic number */ + (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain); + + /* Now sizeof default realm */ + (void) krb5_ser_pack_int32((context->default_realm) ? + (krb5_int32) strlen(context-> + default_realm) : 0, + &bp, &remain); + + /* Now default_realm bytes */ + if (context->default_realm) + (void) krb5_ser_pack_bytes((krb5_octet *) + context->default_realm, + strlen(context->default_realm), + &bp, &remain); + + /* Now number of etypes */ + (void) krb5_ser_pack_int32((krb5_int32) context->etype_count, + &bp, &remain); + + /* Now serialize etypes */ + for (i=0; ietype_count; i++) + (void) krb5_ser_pack_int32((krb5_int32) context->etypes[i], + &bp, &remain); + kret = 0; + + /* Now handle os_context, if appropriate */ + if (context->os_context) + kret = krb5_externalize_opaque(kcontext, + KV5M_OS_CONTEXT, + (krb5_pointer) + context->os_context, + &bp, + &remain); + + /* Now handle database context, if appropriate */ + if (!kret && context->db_context) + kret = krb5_externalize_opaque(kcontext, + KV5M_DB_CONTEXT, + (krb5_pointer) + context->db_context, + &bp, + &remain); + + /* Finally, handle profile, if appropriate */ + if (!kret && context->profile) + kret = krb5_externalize_opaque(kcontext, + PROF_MAGIC_PROFILE, + (krb5_pointer) + context->profile, + &bp, + &remain); + /* + * If we were successful, write trailer then update the pointer and + * remaining length; + */ + if (!kret) { + /* Write our trailer */ + (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain); + *buffer = bp; + *lenremain = remain; + } + } + } + return(kret); +} + +/* + * krb5_context_internalize() - Internalize the krb5_context. + */ +static krb5_error_code +krb5_context_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_context context; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + int i; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_CONTEXT) { + kret = ENOMEM; + + /* Get memory for the context */ + if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && + (context = (krb5_context) malloc(sizeof(struct _krb5_context)))) { + memset(context, 0, sizeof(struct _krb5_context)); + + if (!ibuf || + (context->default_realm = (char *) malloc((size_t) ibuf+1))) { + /* Copy in the default realm */ + if (ibuf) { + (void) krb5_ser_unpack_bytes((krb5_octet *) + context->default_realm, + (size_t) ibuf, + &bp, &remain); + context->default_realm[ibuf] = '\0'; + } + + /* Get the number of etypes */ + if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) { + /* Reduce it to a count */ + context->etype_count = ibuf; + if ((context->etypes = (krb5_enctype *) + malloc(sizeof(krb5_enctype) * + (context->etype_count+1)))) { + memset(context->etypes, + 0, + sizeof(krb5_enctype) * + (context->etype_count + 1)); + for (i=0; ietype_count; i++) { + if ((kret = krb5_ser_unpack_int32(&ibuf, + &bp, &remain))) + break; + context->etypes[i] = (krb5_enctype) ibuf; + } + } + } + + /* Attempt to read in the os_context */ + if (!kret) { + kret = krb5_internalize_opaque(kcontext, + KV5M_OS_CONTEXT, + (krb5_pointer *) + &context->os_context, + &bp, + &remain); + if ((kret == EINVAL) || (kret == ENOENT)) + kret = 0; + } + + /* Attempt to read in the db_context */ + if (!kret) { + kret = krb5_internalize_opaque(kcontext, + KV5M_DB_CONTEXT, + (krb5_pointer *) + &context->db_context, + &bp, + &remain); + if ((kret == EINVAL) || (kret == ENOENT)) + kret = 0; + } + + /* Attempt to read in the profile */ + if (!kret) { + kret = krb5_internalize_opaque(kcontext, + PROF_MAGIC_PROFILE, + (krb5_pointer *) + &context->profile, + &bp, + &remain); + if ((kret == EINVAL) || (kret == ENOENT)) + kret = 0; + } + + /* Finally, find the trailer */ + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_CONTEXT)) + context->magic = KV5M_CONTEXT; + else + kret = EINVAL; + } + } + if (!kret) { + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) context; + } + else + krb5_free_context(context); + } + } + return(kret); +} + +/* + * krb5_oscontext_size() - Determine the size required to externalize + * the krb5_os_context. + */ +static krb5_error_code +krb5_oscontext_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + *sizep += sizeof(krb5_int32); + return(0); +} + +/* + * krb5_oscontext_externalize() - Externalize the krb5_os_context. + */ +static krb5_error_code +krb5_oscontext_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_os_context os_ctx; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((os_ctx = (krb5_os_context) arg)) { + kret = ENOMEM; + if (!krb5_oscontext_size(kcontext, arg, &required) && + (required <= remain)) { + (void) krb5_ser_pack_int32(KV5M_OS_CONTEXT, &bp, &remain); + + /* Handle any other OS context here */ + kret = 0; + if (!kret) { + *buffer = bp; + *lenremain = remain; + } + } + } + return(kret); +} + +/* + * krb5_oscontext_internalize() - Internalize the krb5_os_context. + */ +static krb5_error_code +krb5_oscontext_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_os_context os_ctx; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_OS_CONTEXT) { + kret = ENOMEM; + + /* Get memory for the context */ + if ((os_ctx = (krb5_os_context) + malloc(sizeof(struct _krb5_os_context)))) { + memset(os_ctx, 0, sizeof(struct _krb5_os_context)); + os_ctx->magic = KV5M_OS_CONTEXT; + + /* Handle any more OS context here */ + + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + if (!kret) + *argp = (krb5_pointer) os_ctx; + return(kret); +} + +/* + * Register the context serializers. + */ +krb5_error_code +krb5_ser_context_init(kcontext) + krb5_context kcontext; +{ + krb5_error_code kret; + kret = krb5_register_serializer(kcontext, &krb5_context_ser_entry); + if (!kret) + kret = krb5_register_serializer(kcontext, &krb5_oscontext_ser_entry); + if (!kret) + kret = krb5_register_serializer(kcontext, &krb5_profile_ser_entry); + return(kret); +} diff --git a/src/lib/krb5/krb/ser_eblk.c b/src/lib/krb5/krb/ser_eblk.c new file mode 100644 index 000000000..791963e7d --- /dev/null +++ b/src/lib/krb5/krb/ser_eblk.c @@ -0,0 +1,266 @@ +/* + * lib/krb5/krb/ser_eblk.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_eblk.c - Serialize a krb5_encblock structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_encrypt_block: + * krb5_encrypt_block_size(); + * krb5_encrypt_block_externalize(); + * krb5_encrypt_block_internalize(); + */ +static krb5_error_code krb5_encrypt_block_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_encrypt_block_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_encrypt_block_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_encrypt_block_ser_entry = { + KV5M_ENCRYPT_BLOCK, /* Type */ + krb5_encrypt_block_size, /* Sizer routine */ + krb5_encrypt_block_externalize, /* Externalize routine */ + krb5_encrypt_block_internalize /* Internalize routine */ +}; + +/* + * krb5_encrypt_block_size() - Determine the size required to externalize + * the krb5_encrypt_block. + */ +static krb5_error_code +krb5_encrypt_block_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_encrypt_block *encrypt_block; + size_t required; + + /* + * NOTE: This ASSuMES that keytype and etype are sufficient to recreate + * the _krb5_cryptosystem_entry. If this is not true, then something else + * had better be encoded here. + * + * krb5_encrypt_block base requirements: + * krb5_int32 for KV5M_ENCRYPT_BLOCK + * krb5_int32 for keytype + * krb5_int32 for etype; + * krb5_int32 for private length + * encrypt_block->priv_size for private contents + * krb5_int32 for KV5M_ENCRYPT_BLOCK + */ + kret = EINVAL; + if ((encrypt_block = (krb5_encrypt_block *) arg)) { + required = (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (size_t) encrypt_block->priv_size); + if (encrypt_block->key) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) encrypt_block->key, + &required); + else + kret = 0; + if (!kret) + *sizep += required; + } + return(kret); +} + +/* + * krb5_encrypt_block_externalize() - Externalize the krb5_encrypt_block. + */ +static krb5_error_code +krb5_encrypt_block_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_encrypt_block *encrypt_block; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((encrypt_block = (krb5_encrypt_block *) arg)) { + kret = ENOMEM; + if (!krb5_encrypt_block_size(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_ENCRYPT_BLOCK, &bp, &remain); + + /* Our keytype */ + (void) krb5_ser_pack_int32((krb5_int32) encrypt_block-> + crypto_entry->proto_keytype, + &bp, &remain); + + /* Our etype */ + (void) krb5_ser_pack_int32((krb5_int32) encrypt_block-> + crypto_entry->proto_enctype, + &bp, &remain); + + /* Our length */ + (void) krb5_ser_pack_int32((krb5_int32) encrypt_block->priv_size, + &bp, &remain); + + /* Our private data */ + (void) krb5_ser_pack_bytes(encrypt_block->priv, + (size_t) encrypt_block->priv_size, + &bp, &remain); + + /* Finally, the key data */ + if (encrypt_block->key) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) + encrypt_block->key, + &bp, + &remain); + else + kret = 0; + + if (!kret) { + /* Write trailer */ + (void) krb5_ser_pack_int32(KV5M_ENCRYPT_BLOCK, &bp, &remain); + *buffer = bp; + *lenremain = remain; + } + } + } + return(kret); +} + +/* + * krb5_encrypt_block_internalize() - Internalize the krb5_encrypt_block. + */ +static krb5_error_code +krb5_encrypt_block_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_encrypt_block *encrypt_block; + krb5_int32 ibuf; + krb5_keytype ktype; + krb5_enctype etype; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_ENCRYPT_BLOCK) { + kret = ENOMEM; + + /* Get an encrypt_block */ + if ((remain >= (3*sizeof(krb5_int32))) && + (encrypt_block = (krb5_encrypt_block *) + malloc(sizeof(krb5_encrypt_block)))) { + memset(encrypt_block, 0, sizeof(krb5_encrypt_block)); + + /* Get the keytype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ktype = (krb5_keytype) ibuf; + + /* Get the etype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + etype = (krb5_enctype) ibuf; + + /* + * Use the etype to determine the crypto_system entry. In the + * future, we may need to use a combination of keytype/etype or + * just keytype here. + */ + krb5_use_cstype(kcontext, encrypt_block, etype); + + /* Get the length */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + encrypt_block->priv_size = (int) ibuf; + + /* Get the string */ + if (!ibuf || + ((encrypt_block->priv = (void *) malloc((size_t) (ibuf))) && + !(kret = krb5_ser_unpack_bytes((krb5_octet *) + encrypt_block->priv, + (size_t) + encrypt_block->priv_size, + &bp, &remain)))) { + kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) + &encrypt_block->key, + &bp, + &remain); + if (kret == EINVAL) + kret = 0; + + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_ENCRYPT_BLOCK)) { + *buffer = bp; + *lenremain = remain; + encrypt_block->magic = KV5M_ENCRYPT_BLOCK; + *argp = (krb5_pointer) encrypt_block; + } + else + kret = EINVAL; + } + } + if (kret) { + if (encrypt_block->priv) + free(encrypt_block->priv); + free(encrypt_block); + } + } + } + return(kret); +} + +/* + * Register the encblock serializer. + */ +krb5_error_code +krb5_ser_encrypt_block_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_encrypt_block_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_key.c b/src/lib/krb5/krb/ser_key.c new file mode 100644 index 000000000..eacbf011a --- /dev/null +++ b/src/lib/krb5/krb/ser_key.c @@ -0,0 +1,217 @@ +/* + * lib/krb5/krb/ser_key.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_key.c - Serialize a krb5_keyblock structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_keyblock: + * krb5_keyblock_size(); + * krb5_keyblock_externalize(); + * krb5_keyblock_internalize(); + */ +static krb5_error_code krb5_keyblock_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_keyblock_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_keyblock_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_keyblock_ser_entry = { + KV5M_KEYBLOCK, /* Type */ + krb5_keyblock_size, /* Sizer routine */ + krb5_keyblock_externalize, /* Externalize routine */ + krb5_keyblock_internalize /* Internalize routine */ +}; + +/* + * krb5_keyblock_size() - Determine the size required to externalize + * the krb5_keyblock. + */ +static krb5_error_code +krb5_keyblock_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_keyblock *keyblock; + + /* + * krb5_keyblock requires: + * krb5_int32 for KV5M_KEYBLOCK + * krb5_int32 for keytype + * krb5_int32 for etype; + * krb5_int32 for length + * keyblock->length for contents + * krb5_int32 for KV5M_KEYBLOCK + */ + kret = EINVAL; + if ((keyblock = (krb5_keyblock *) arg)) { + *sizep += (sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + sizeof(krb5_int32) + + (size_t) keyblock->length); + kret = 0; + } + return(kret); +} + +/* + * krb5_keyblock_externalize() - Externalize the krb5_keyblock. + */ +static krb5_error_code +krb5_keyblock_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_keyblock *keyblock; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((keyblock = (krb5_keyblock *) arg)) { + kret = ENOMEM; + if (!krb5_keyblock_size(kcontext, arg, &required) && + (required <= remain)) { + /* Our identifier */ + (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain); + + /* Our keytype */ + (void) krb5_ser_pack_int32((krb5_int32) keyblock->keytype, + &bp, &remain); + + /* Our etype */ + (void) krb5_ser_pack_int32((krb5_int32) keyblock->etype, + &bp, &remain); + + /* Our length */ + (void) krb5_ser_pack_int32((krb5_int32) keyblock->length, + &bp, &remain); + + /* Our contents */ + (void) krb5_ser_pack_bytes(keyblock->contents, + (size_t) keyblock->length, + &bp, &remain); + + /* Finally, our trailer */ + (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain); + + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + return(kret); +} + +/* + * krb5_keyblock_internalize() - Internalize the krb5_keyblock. + */ +static krb5_error_code +krb5_keyblock_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_keyblock *keyblock; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_KEYBLOCK) { + kret = ENOMEM; + + /* Get a keyblock */ + if ((remain >= (3*sizeof(krb5_int32))) && + (keyblock = (krb5_keyblock *) malloc(sizeof(krb5_keyblock)))) { + memset(keyblock, 0, sizeof(krb5_keyblock)); + + /* Get the keytype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + keyblock->keytype = (krb5_keytype) ibuf; + + /* Get the etype */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + keyblock->etype = (krb5_enctype) ibuf; + + /* Get the length */ + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + keyblock->length = (int) ibuf; + + /* Get the string */ + if ((keyblock->contents = (krb5_octet *) malloc((size_t) (ibuf)))&& + !(kret = krb5_ser_unpack_bytes(keyblock->contents, + (size_t) ibuf, + &bp, &remain))) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_KEYBLOCK)) { + kret = 0; + *buffer = bp; + *lenremain = remain; + keyblock->magic = KV5M_KEYBLOCK; + *argp = (krb5_pointer) keyblock; + } + else + kret = EINVAL; + } + if (kret) { + if (keyblock->contents) + free(keyblock->contents); + free(keyblock); + } + } + } + return(kret); +} + +/* + * Register the keyblock serializer. + */ +krb5_error_code +krb5_ser_keyblock_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_keyblock_ser_entry)); +} diff --git a/src/lib/krb5/krb/ser_princ.c b/src/lib/krb5/krb/ser_princ.c new file mode 100644 index 000000000..582875401 --- /dev/null +++ b/src/lib/krb5/krb/ser_princ.c @@ -0,0 +1,189 @@ +/* + * lib/krb5/krb/ser_princ.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * ser_princ.c - Serialize a krb5_principal structure. + */ +#include "k5-int.h" + +/* + * Routines to deal with externalizing the krb5_principal: + * krb5_principal_size(); + * krb5_principal_externalize(); + * krb5_principal_internalize(); + */ +static krb5_error_code krb5_principal_size + KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); +static krb5_error_code krb5_principal_externalize + KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); +static krb5_error_code krb5_principal_internalize + KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); + +/* Local data */ +static const krb5_ser_entry krb5_principal_ser_entry = { + KV5M_PRINCIPAL, /* Type */ + krb5_principal_size, /* Sizer routine */ + krb5_principal_externalize, /* Externalize routine */ + krb5_principal_internalize /* Internalize routine */ +}; + +/* + * krb5_principal_size() - Determine the size required to externalize + * the krb5_principal. + */ +static krb5_error_code +krb5_principal_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_principal principal; + char *fname; + + /* + * krb5_principal requires: + * krb5_int32 for KV5M_PRINCIPAL + * krb5_int32 for flattened name size + * strlen(name) for name. + * krb5_int32 for KV5M_PRINCIPAL + */ + kret = EINVAL; + if ((principal = (krb5_principal) arg) && + !(kret = krb5_unparse_name(kcontext, principal, &fname))) { + *sizep += (3*sizeof(krb5_int32)) + strlen(fname); + krb5_xfree(fname); + } + return(kret); +} + +/* + * krb5_principal_externalize() - Externalize the krb5_principal. + */ +static krb5_error_code +krb5_principal_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_principal principal; + size_t required; + krb5_octet *bp; + size_t remain; + char *fname; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((principal = (krb5_principal) arg)) { + kret = ENOMEM; + if (!krb5_principal_size(kcontext, arg, &required) && + (required <= remain)) { + if (!(kret = krb5_unparse_name(kcontext, principal, &fname))) { + + (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) strlen(fname), + &bp, &remain); + (void) krb5_ser_pack_bytes((krb5_octet *) fname, + strlen(fname), &bp, &remain); + (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain); + *buffer = bp; + *lenremain = remain; + + krb5_xfree(fname); + } + } + } + return(kret); +} + +/* + * krb5_principal_internalize() - Internalize the krb5_principal. + */ +static krb5_error_code +krb5_principal_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_principal principal; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + char *tmpname; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_PRINCIPAL) { + kret = ENOMEM; + + /* See if we have enough data for the length */ + if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) { + /* Get the string */ + if ((tmpname = (char *) malloc((size_t) (ibuf+1))) && + !(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname, + (size_t) ibuf, + &bp, &remain))) { + tmpname[ibuf] = '\0'; + + /* Parse the name to a principal structure */ + principal = (krb5_principal) NULL; + kret = krb5_parse_name(kcontext, tmpname, &principal); + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && (ibuf == KV5M_PRINCIPAL)) { + *buffer = bp; + *lenremain = remain; + *argp = principal; + } + else + kret = EINVAL; + } + if (kret && principal) + krb5_free_principal(kcontext, principal); + free(tmpname); + } + } + } + return(kret); +} + +/* + * Register the context serializer. + */ +krb5_error_code +krb5_ser_principal_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &krb5_principal_ser_entry)); +} diff --git a/src/lib/krb5/krb/serialize.c b/src/lib/krb5/krb/serialize.c new file mode 100644 index 000000000..20107c457 --- /dev/null +++ b/src/lib/krb5/krb/serialize.c @@ -0,0 +1,277 @@ +/* + * lib/krb5/krb/serialize.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * Base routines to deal with serialization of Kerberos metadata. + */ +#include "k5-int.h" + +/* + * krb5_find_serializer() - See if a particular type is registered. + */ +krb5_ser_handle +krb5_find_serializer(kcontext, odtype) + krb5_context kcontext; + krb5_magic odtype; +{ + krb5_ser_handle res; + krb5_ser_handle sctx; + int i; + + res = (krb5_ser_handle) NULL; + sctx = (krb5_ser_handle) kcontext->ser_ctx; + for (i=0; iser_ctx_count; i++) { + if (sctx[i].odtype == odtype) { + res = &sctx[i]; + break; + } + } + return(res); +} + +/* + * krb5_register_serializer() - Register a particular serializer. + */ +krb5_error_code +krb5_register_serializer(kcontext, entry) + krb5_context kcontext; + const krb5_ser_entry *entry; +{ + krb5_error_code kret; + krb5_ser_handle stable; + + kret = 0; + /* See if it's already there, if so, we're good to go. */ + if (!(stable = krb5_find_serializer(kcontext, entry->odtype))) { + /* + * Can't find our type. Create a new entry. + */ + if ((stable = (krb5_ser_handle) malloc(sizeof(krb5_ser_entry) * + (kcontext->ser_ctx_count+1)))) { + /* Copy in old table */ + memcpy(stable, kcontext->ser_ctx, + sizeof(krb5_ser_entry) * kcontext->ser_ctx_count); + /* Copy in new entry */ + memcpy(&stable[kcontext->ser_ctx_count], entry, + sizeof(krb5_ser_entry)); + krb5_xfree(kcontext->ser_ctx); + kcontext->ser_ctx = (void *) stable; + kcontext->ser_ctx_count++; + } + else + kret = ENOMEM; + } + else + memcpy(stable, entry, sizeof(krb5_ser_entry)); + return(kret); +} + +/* + * krb5_size_opaque() - Determine the size necessary to serialize a given + * piece of opaque data. + */ +krb5_error_code +krb5_size_opaque(kcontext, odtype, arg, sizep) + krb5_context kcontext; + krb5_magic odtype; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + krb5_ser_handle shandle; + + kret = ENOENT; + /* See if the type is supported, if so, do it */ + if ((shandle = krb5_find_serializer(kcontext, odtype))) + kret = (shandle->sizer) ? (*shandle->sizer)(kcontext, arg, sizep) : 0; + return(kret); +} + +/* + * krb5_externalize_opaque() - Externalize a piece of opaque data. + */ +krb5_error_code +krb5_externalize_opaque(kcontext, odtype, arg, bufpp, sizep) + krb5_context kcontext; + krb5_magic odtype; + krb5_pointer arg; + krb5_octet **bufpp; + size_t *sizep; +{ + krb5_error_code kret; + krb5_ser_handle shandle; + + kret = ENOENT; + /* See if the type is supported, if so, do it */ + if ((shandle = krb5_find_serializer(kcontext, odtype))) + kret = (shandle->externalizer) ? + (*shandle->externalizer)(kcontext, arg, bufpp, sizep) : 0; + return(kret); +} + +/* + * Externalize a piece of arbitrary data. + */ +krb5_error_code +krb5_externalize_data(kcontext, arg, bufpp, sizep) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **bufpp; + size_t *sizep; +{ + krb5_error_code kret; + krb5_magic *mp; + krb5_octet *buffer, *bp; + size_t bufsize, bsize; + + mp = (krb5_magic *) arg; + bufsize = 0; + if (!(kret = krb5_size_opaque(kcontext, *mp, arg, &bufsize))) { + if ((buffer = (krb5_octet *) malloc(bufsize))) { + bp = buffer; + bsize = bufsize; + if (!(kret = krb5_externalize_opaque(kcontext, + *mp, + arg, + &bp, + &bsize))) { + if (bsize != 0) + bufsize -= bsize; + *bufpp = buffer; + *sizep = bufsize; + } + } + else + kret = ENOMEM; + } + return(kret); +} + +/* + * krb5_internalize_opaque() - Convert external representation into a data + * structure. + */ +krb5_error_code +krb5_internalize_opaque(kcontext, odtype, argp, bufpp, sizep) + krb5_context kcontext; + krb5_magic odtype; + krb5_pointer *argp; + krb5_octet **bufpp; + size_t *sizep; +{ + krb5_error_code kret; + krb5_ser_handle shandle; + + kret = ENOENT; + /* See if the type is supported, if so, do it */ + if ((shandle = krb5_find_serializer(kcontext, odtype))) + kret = (shandle->internalizer) ? + (*shandle->internalizer)(kcontext, argp, bufpp, sizep) : 0; + return(kret); +} + +/* + * krb5_ser_pack_int32() - Pack a 4-byte integer if space is availble. + * Update buffer pointer and remaining space. + */ +krb5_error_code +krb5_ser_pack_int32(iarg, bufp, remainp) + krb5_int32 iarg; + krb5_octet **bufp; + size_t *remainp; +{ + if (*remainp >= sizeof(krb5_int32)) { + (*bufp)[0] = (krb5_octet) ((iarg >> 24) & 0xff); + (*bufp)[1] = (krb5_octet) ((iarg >> 16) & 0xff); + (*bufp)[2] = (krb5_octet) ((iarg >> 8) & 0xff); + (*bufp)[3] = (krb5_octet) (iarg & 0xff); + *bufp += sizeof(krb5_int32); + *remainp -= sizeof(krb5_int32); + return(0); + } + else + return(ENOMEM); +} + +/* + * krb5_ser_pack_bytes() - Pack a string of bytes. + */ +krb5_error_code +krb5_ser_pack_bytes(ostring, osize, bufp, remainp) + krb5_octet *ostring; + size_t osize; + krb5_octet **bufp; + size_t *remainp; +{ + if (*remainp >= osize) { + memcpy(*bufp, ostring, osize); + *bufp += osize; + *remainp -= osize; + return(0); + } + else + return(ENOMEM); +} + +/* + * krb5_ser_unpack_int32() - Unpack a 4-byte integer if it's there. + */ +krb5_error_code +krb5_ser_unpack_int32(intp, bufp, remainp) + krb5_int32 *intp; + krb5_octet **bufp; + size_t *remainp; +{ + if (*remainp >= sizeof(krb5_int32)) { + *intp = (((krb5_int32) ((unsigned char) (*bufp)[0]) << 24) | + ((krb5_int32) ((unsigned char) (*bufp)[1]) << 16) | + ((krb5_int32) ((unsigned char) (*bufp)[2]) << 8) | + ((krb5_int32) ((unsigned char) (*bufp)[3]))); + *bufp += sizeof(krb5_int32); + *remainp -= sizeof(krb5_int32); + return(0); + } + else + return(ENOMEM); +} + +/* + * krb5_ser_unpack_bytes() - Unpack a byte string if it's there. + */ +krb5_error_code +krb5_ser_unpack_bytes(istring, isize, bufp, remainp) + krb5_octet *istring; + size_t isize; + krb5_octet **bufp; + size_t *remainp; +{ + if (*remainp >= isize) { + memcpy(istring, *bufp, isize); + *bufp += isize; + *remainp -= isize; + return(0); + } + else + return(ENOMEM); +} -- 2.26.2