bool_t xdr_CSSM_LIST(XDR *xdrs, CSSM_LIST *objp)
{
    if (!xdr_CSSM_LIST_TYPE(xdrs, &objp->ListType))
        return (FALSE);
    if (!sec_xdr_pointer(xdrs, (uint8_t**)&objp->Head, sizeof(CSSM_LIST_ELEMENT), (xdrproc_t)xdr_CSSM_LIST_ELEMENT))
        return (FALSE);
    // if we're restoring things, make sure to fix up Tail to point
    // to the right place
    if (xdrs->x_op == XDR_DECODE)
    {
        bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs);
        if (!size_alloc)
            for (objp->Tail = objp->Head; objp->Tail && objp->Tail->NextElement; objp->Tail = objp->Tail->NextElement);
    }
    return (TRUE);
}
/*
 * XDR an indirect pointer
 * xdr_reference is for recursively translating a structure that is
 * referenced by a pointer inside the structure that is currently being
 * translated.  pp references a pointer to storage. If *pp is null
 * the  necessary storage is allocated.
 * size is the sizeof the referneced structure.
 * proc is the routine to handle the referenced structure.
 */
bool_t
sec_xdr_reference(XDR *xdrs, uint8_t **pp, u_int size, xdrproc_t proc)
{
    uint8_t *loc = pp ? *pp : NULL;
    bool_t stat;

    if (size > 1024) {
        // Structure suspiciously large: 1024 is arbitrary upper bound
        // for struct sizes (non-nested size)
        assert(FALSE);
        return (FALSE);
    }
    uint8_t obj[size];

    bool_t sizeof_alloc = sec_xdr_arena_size_allocator(xdrs);

    if (loc == NULL)
            switch (xdrs->x_op) {
            case XDR_FREE:
                return (TRUE);
            case XDR_DECODE:
                {
                    if (!sec_mem_alloc(xdrs, size, &loc))
                        return (FALSE);
					if (!loc) {
                        memset(obj, 0, size);
						loc = &obj[0];
                    }
					if (!sizeof_alloc && pp != NULL)
						*pp = loc;
					break;
                }
            case XDR_ENCODE:
                break;
            }

    stat = (*proc)(xdrs, loc, 0);

    if (xdrs->x_op == XDR_FREE) {
        sec_mem_free(xdrs, loc, size);
        if(pp) {
            *pp = NULL;
        }
    }
    return (stat);
}
bool_t
sec_xdr_pointer(XDR *xdrs, uint8_t **objpp, u_int obj_size, xdrproc_t xdr_obj)
{
    bool_t more_data;

    more_data = (objpp ? (*objpp != NULL) : FALSE);
    if (! xdr_bool(xdrs,&more_data))
        return (FALSE);

    bool_t sizeof_alloc = sec_xdr_arena_size_allocator(xdrs);

    if (! more_data) {
        if ((xdrs->x_op == XDR_DECODE) && !sizeof_alloc && objpp != NULL)
            *objpp = NULL;
        return (TRUE);
    }
    return (sec_xdr_reference(xdrs,objpp,obj_size,xdr_obj));
}
// CSSM_DATA passed through in the following calls: findFirst, findNext and
// findRecordHandle actually contains a CSSM_KEY if the item is a key.  
// Since a key has byte order sensitive bits it needs to be encoded.
// At this level we can only guess based on the length of the CSSM_DATA passed in
// during encode, whether it's a CSSM_KEY, so we're currently letting securityd
// call xdr_CSSM_KEY_IN_DATA or xdr_CSSM_NO_KEY_IN_DATA to let us know.
bool_t xdr_CSSM_POSSIBLY_KEY_IN_DATA_WITH_BOOL(XDR *xdrs, CSSM_DATA *objp, bool_t in_iskey)
{
    bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs);
    bool_t is_key = FALSE; /* shut compiler up */
    if (xdrs->x_op == XDR_ENCODE)
	is_key = (in_iskey && objp->Length == sizeof(CSSM_KEY));
    if (!xdr_CSSM_BOOL(xdrs, &is_key))
        return (FALSE);
    if (is_key) {
        if (!xdr_CSSM_KEY_PTR(xdrs, (CSSM_KEY_PTR*)&objp->Data))
            return (FALSE);
        if (!size_alloc && (xdrs->x_op == XDR_DECODE))
            objp->Length = sizeof(CSSM_KEY);
    } else {
        if (!xdr_CSSM_DATA(xdrs, objp))
            return (FALSE);
    }
    return (TRUE);
}
static
bool_t xdr_CSSM_DATA_FLIPPED(XDR *xdrs, CSSM_DATA *objp)
{
	bool_t size_alloc = sec_xdr_arena_size_allocator(xdrs);
    if ((xdrs->x_op == XDR_ENCODE) && !size_alloc) {
        switch (objp->Length) {
        case sizeof(uint32_t): *(uint32_t*)objp->Data = htonl(*(uint32_t*)objp->Data); break;
        case sizeof(uint64_t): *(uint64_t*)objp->Data = OSSwapHostToBigInt64(*(uint64_t*)objp->Data); break;
		case sizeof(uint8_t): break;
        default: assert(FALSE); break;
        }
    }
    if (!xdr_CSSM_DATA(xdrs, objp))
        return (FALSE);
    if ((xdrs->x_op == XDR_DECODE) && !size_alloc) {
        switch (objp->Length) {
        case sizeof(uint32_t): *(uint32_t*)objp->Data = ntohl(*(uint32_t*)objp->Data); break;
        case sizeof(uint64_t): *(uint64_t*)objp->Data = OSSwapBigToHostInt64(*(uint64_t*)objp->Data); break;
		case sizeof(uint8_t): break;
        default: assert(FALSE); break;
        }
    }
    return (TRUE);
}
Esempio n. 6
0
/*
 * XDR an array of arbitrary elements
 * *addrp is a pointer to the array, *sizep is the number of elements.
 * If addrp is NULL (*sizep * elsize) bytes are allocated.
 * elsize is the size (in bytes) of each element, and elproc is the
 * xdr procedure to call to handle each element of the array.
 */
bool_t
sec_xdr_array(XDR *xdrs, uint8_t **addrp, u_int *sizep, u_int maxsize, u_int elsize, xdrproc_t elproc)
{
    u_int i;
    bool_t stat = TRUE;

    u_int c = sizep ? *sizep : 0;  /* the actual element count */
    /* like strings, arrays are really counted arrays */
    if (!xdr_u_int(xdrs, &c))
        return (FALSE);

    if (sizep && (xdrs->x_op == XDR_DECODE))
        *sizep = c;

    // XXX/cs on decode if c == 0 return

    if ((c > maxsize || UINT_MAX/elsize < c) && (xdrs->x_op != XDR_FREE))
        return (FALSE);

    if (elsize > 1024) {
        // Structure suspiciously large: 1024 is arbitrary upper bound
        // for struct sizes (non-nested size)
        assert(FALSE);
        return (FALSE);
    }

    u_int nodesize = c * elsize;
    uint8_t *target = addrp ? *addrp : NULL;

    uint8_t obj[elsize];

    bool_t sizeof_alloc = sec_xdr_arena_size_allocator(xdrs);

    /*
     * if we are deserializing, we may need to allocate an array.
     * We also save time by checking for a null array if we are freeing.
     */
    if (target == NULL) {
        switch (xdrs->x_op) {
        case XDR_DECODE:
            if (c == 0)
                return (TRUE);
            if (!sec_mem_alloc(xdrs, nodesize, &target))
                return (FALSE);
            if (!target)
                target = &obj[0];
            if (!sizeof_alloc)
                *addrp = target;
            break;

        case XDR_FREE:
            return (TRUE);

        case XDR_ENCODE:
            break;
        }
    }

    /*
     * now we xdr each element of array
     */
    for (i = 0; (i < c) && stat; i++) {
        if ((xdrs->x_op == XDR_DECODE) && sizeof_alloc)
            memset(obj, 0, elsize);
        stat = (*elproc)(xdrs, target, 0);
        if ((xdrs->x_op == XDR_ENCODE) || !sizeof_alloc)
            target += elsize;
    }

    /*
     * the array may need freeing
     */
    if (xdrs->x_op == XDR_FREE) {
        sec_mem_free(xdrs, *addrp, nodesize);
        *addrp = NULL;
    }
    return (stat);
}