#include "k5-int.h"
krb5_ser_handle
krb5_find_serializer(krb5_context kcontext, krb5_magic odtype)
{
krb5_ser_handle res;
krb5_ser_handle sctx;
int i;
res = (krb5_ser_handle) NULL;
sctx = (krb5_ser_handle) kcontext->ser_ctx;
for (i=0; i<kcontext->ser_ctx_count; i++) {
if (sctx[i].odtype == odtype) {
res = &sctx[i];
break;
}
}
return(res);
}
krb5_error_code
krb5_register_serializer(krb5_context kcontext, const krb5_ser_entry *entry)
{
krb5_error_code kret;
krb5_ser_handle stable;
kret = 0;
if (!(stable = krb5_find_serializer(kcontext, entry->odtype))) {
if ((stable = (krb5_ser_handle) malloc(sizeof(krb5_ser_entry) *
(kcontext->ser_ctx_count+1)))) {
if (kcontext->ser_ctx_count)
memcpy(stable, kcontext->ser_ctx,
sizeof(krb5_ser_entry) * kcontext->ser_ctx_count);
memcpy(&stable[kcontext->ser_ctx_count], entry,
sizeof(krb5_ser_entry));
if (kcontext->ser_ctx) 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_error_code KRB5_CALLCONV
krb5_size_opaque(krb5_context kcontext, krb5_magic odtype, krb5_pointer arg, size_t *sizep)
{
krb5_error_code kret;
krb5_ser_handle shandle;
kret = ENOENT;
if ((shandle = krb5_find_serializer(kcontext, odtype)))
kret = (shandle->sizer) ? (*shandle->sizer)(kcontext, arg, sizep) : 0;
return(kret);
}
krb5_error_code KRB5_CALLCONV
krb5_externalize_opaque(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;
if ((shandle = krb5_find_serializer(kcontext, odtype)))
kret = (shandle->externalizer) ?
(*shandle->externalizer)(kcontext, arg, bufpp, sizep) : 0;
return(kret);
}
krb5_error_code
krb5_externalize_data(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_error_code KRB5_CALLCONV
krb5_internalize_opaque(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;
if ((shandle = krb5_find_serializer(kcontext, odtype)))
kret = (shandle->internalizer) ?
(*shandle->internalizer)(kcontext, argp, bufpp, sizep) : 0;
return(kret);
}
krb5_error_code KRB5_CALLCONV
krb5_ser_pack_int32(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_error_code KRB5_CALLCONV
krb5_ser_pack_bytes(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_error_code KRB5_CALLCONV
krb5_ser_unpack_int32(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_error_code KRB5_CALLCONV
krb5_ser_unpack_bytes(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);
}