From: Matt Caswell Date: Thu, 29 Sep 2016 10:43:37 +0000 (+0100) Subject: Add the WPACKET_reserve_bytes() function X-Git-Tag: OpenSSL_1_1_1-pre1~3431 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1ff8434040b35f35c27f77ef064481622490bba9;p=oweals%2Fopenssl.git 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: Rich Salz --- diff --git a/ssl/packet.c b/ssl/packet.c index 4077de5c33..7c240a4a82 100644 --- a/ssl/packet.c +++ b/ssl/packet.c @@ -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, - unsigned char **allocbytes, size_t lenbytes) +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; } diff --git a/ssl/packet_locl.h b/ssl/packet_locl.h index 44a8f82c7c..0e50c7ddae 100644 --- a/ssl/packet_locl.h +++ b/ssl/packet_locl.h @@ -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