Commit 1ff84340 authored by Matt Caswell's avatar Matt Caswell
Browse files

Add the WPACKET_reserve_bytes() function



WPACKET_allocate_bytes() requires you to know the size of the data you
are allocating for, before you create it. Sometimes this isn't the case,
for example we know the maximum size that a signature will be before we
create it, but not the actual size. WPACKET_reserve_bytes() enables us to
reserve bytes in the WPACKET, but not count them as written yet. We then
subsequently need to acall WPACKET_allocate_bytes to actually count them as
written.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent ac8cc3ef
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -13,6 +13,27 @@
#define DEFAULT_BUF_SIZE    256

int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
{
    if (!WPACKET_reserve_bytes(pkt, len, allocbytes))
        return 0;
    pkt->written += len;
    pkt->curr += len;

    return 1;
}

int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
                                 unsigned char **allocbytes, size_t lenbytes)
{
    if (!WPACKET_start_sub_packet_len__(pkt, lenbytes)
            || !WPACKET_allocate_bytes(pkt, len, allocbytes)
            || !WPACKET_close(pkt))
        return 0;

    return 1;
}

int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
{
    /* Internal API, so should not fail */
    assert(pkt->subs != NULL && len != 0);
@@ -39,20 +60,18 @@ int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
            return 0;
    }
    *allocbytes = (unsigned char *)pkt->buf->data + pkt->curr;
    pkt->written += len;
    pkt->curr += len;

    return 1;
}

int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
                                unsigned char **allocbytes, size_t lenbytes)
{
    if (!WPACKET_start_sub_packet_len__(pkt, lenbytes)
            || !WPACKET_allocate_bytes(pkt, len, allocbytes)
            || !WPACKET_close(pkt))
    if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
        return 0;

    *allocbytes += lenbytes;

    return 1;
}

+29 −1
Original line number Diff line number Diff line
@@ -675,7 +675,7 @@ int WPACKET_start_sub_packet(WPACKET *pkt);
 * WPACKET_* calls. If not then the underlying buffer may be realloc'd and
 * change its location.
 */
int WPACKET_allocate_bytes(WPACKET *pkt, size_t bytes,
int WPACKET_allocate_bytes(WPACKET *pkt, size_t len,
                           unsigned char **allocbytes);

/*
@@ -700,6 +700,34 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
#define WPACKET_sub_allocate_bytes_u32(pkt, len, bytes) \
    WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 4)

/*
 * The same as WPACKET_allocate_bytes() except the reserved bytes are not
 * actually counted as written. Typically this will be for when we don't know
 * how big arbitrary data is going to be up front, but we do know what the
 * maximum size will be. If this function is used, then it should be immediately
 * followed by a WPACKET_allocate_bytes() call before any other WPACKET
 * functions are called (unless the write to the allocated bytes is abandoned).
 */
int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes);

/*
 * The "reserve_bytes" equivalent of WPACKET_sub_allocate_bytes__()
 */
int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
                                 unsigned char **allocbytes, size_t lenbytes);

/*
 * Convenience macros for  WPACKET_sub_reserve_bytes with different lengths
 */
#define WPACKET_sub_reserve_bytes_u8(pkt, len, bytes) \
    WPACKET_reserve_bytes__((pkt), (len), (bytes), 1)
#define WPACKET_sub_reserve_bytes_u16(pkt, len, bytes) \
    WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 2)
#define WPACKET_sub_reserve_bytes_u24(pkt, len, bytes) \
    WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 3)
#define WPACKET_sub_reserve_bytes_u32(pkt, len, bytes) \
    WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 4)

/*
 * Write the value stored in |val| into the WPACKET. The value will consume
 * |bytes| amount of storage. An error will occur if |val| cannot be