summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-09-29 11:43:37 +0100
committerMatt Caswell <matt@openssl.org>2016-09-29 15:09:02 +0100
commit1ff8434040b35f35c27f77ef064481622490bba9 (patch)
tree32a48d1ef1a6bacb4311e2e6a7e2073cb53fac88 /ssl
parentac8cc3efb26fa91c4f29463044cfe9e7070ebc14 (diff)
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 <rsalz@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/packet.c33
-rw-r--r--ssl/packet_locl.h30
2 files changed, 55 insertions, 8 deletions
diff --git a/ssl/packet.c b/ssl/packet.c
index 4077de5c33..7c240a4a82 100644
--- a/ssl/packet.c
+++ b/ssl/packet.c
@@ -14,6 +14,27 @@
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);
if (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);
/*
@@ -701,6 +701,34 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
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
* accommodated in |bytes| storage, e.g. attempting to write the value 256 into