Give WPACKET the ability to have a NULL buffer underneath it
This means the WPACKET API can be used for calculating the number of bytes that would have been written if a non-NULL buffer had been used. This enables us to calculate the number of length bytes required when encoding ASN.1 Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9111)
This commit is contained in:
parent
8ae173bb57
commit
15cb0f0958
2 changed files with 53 additions and 11 deletions
|
@ -35,7 +35,10 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETBUF(p) (((p)->staticbuf != NULL) \
|
#define GETBUF(p) (((p)->staticbuf != NULL) \
|
||||||
? (p)->staticbuf : (unsigned char *)(p)->buf->data)
|
? (p)->staticbuf \
|
||||||
|
: ((p)->buf != NULL \
|
||||||
|
? (unsigned char *)(p)->buf->data \
|
||||||
|
: NULL))
|
||||||
|
|
||||||
int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
|
int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +49,7 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
|
||||||
if (pkt->maxsize - pkt->written < len)
|
if (pkt->maxsize - pkt->written < len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) {
|
if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) {
|
||||||
size_t newlen;
|
size_t newlen;
|
||||||
size_t reflen;
|
size_t reflen;
|
||||||
|
|
||||||
|
@ -74,7 +77,8 @@ int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
|
||||||
if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
|
if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*allocbytes += lenbytes;
|
if (*allocbytes != NULL)
|
||||||
|
*allocbytes += lenbytes;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +114,7 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes)
|
||||||
pkt->subs = NULL;
|
pkt->subs = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pkt->subs->packet_len = lenchars - GETBUF(pkt);
|
pkt->subs->packet_len = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +153,15 @@ int WPACKET_init(WPACKET *pkt, BUF_MEM *buf)
|
||||||
return WPACKET_init_len(pkt, buf, 0);
|
return WPACKET_init_len(pkt, buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WPACKET_init_null(WPACKET *pkt, size_t lenbytes)
|
||||||
|
{
|
||||||
|
pkt->staticbuf = NULL;
|
||||||
|
pkt->buf = NULL;
|
||||||
|
pkt->maxsize = maxmaxsize(lenbytes);
|
||||||
|
|
||||||
|
return wpacket_intern_init_len(pkt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
|
int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
|
||||||
{
|
{
|
||||||
/* Internal API, so should not fail */
|
/* Internal API, so should not fail */
|
||||||
|
@ -163,6 +176,9 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
|
||||||
/* Store the |value| of length |len| at location |data| */
|
/* Store the |value| of length |len| at location |data| */
|
||||||
static int put_value(unsigned char *data, size_t value, size_t len)
|
static int put_value(unsigned char *data, size_t value, size_t len)
|
||||||
{
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
for (data += len - 1; len > 0; len--) {
|
for (data += len - 1; len > 0; len--) {
|
||||||
*data = (unsigned char)(value & 0xff);
|
*data = (unsigned char)(value & 0xff);
|
||||||
data--;
|
data--;
|
||||||
|
@ -209,10 +225,14 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out the WPACKET length if needed */
|
/* Write out the WPACKET length if needed */
|
||||||
if (sub->lenbytes > 0
|
if (sub->lenbytes > 0) {
|
||||||
&& !put_value(&GETBUF(pkt)[sub->packet_len], packlen,
|
unsigned char *buf = GETBUF(pkt);
|
||||||
|
|
||||||
|
if (buf != NULL
|
||||||
|
&& !put_value(&buf[sub->packet_len], packlen,
|
||||||
sub->lenbytes))
|
sub->lenbytes))
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (doclose) {
|
if (doclose) {
|
||||||
pkt->subs = sub->parent;
|
pkt->subs = sub->parent;
|
||||||
|
@ -293,10 +313,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub->packet_len = pkt->written;
|
||||||
|
|
||||||
if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))
|
if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))
|
||||||
return 0;
|
return 0;
|
||||||
/* Convert to an offset in case the underlying BUF_MEM gets realloc'd */
|
|
||||||
sub->packet_len = lenchars - GETBUF(pkt);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +374,8 @@ int WPACKET_memset(WPACKET *pkt, int ch, size_t len)
|
||||||
if (!WPACKET_allocate_bytes(pkt, len, &dest))
|
if (!WPACKET_allocate_bytes(pkt, len, &dest))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(dest, ch, len);
|
if (dest != NULL)
|
||||||
|
memset(dest, ch, len);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -369,7 +390,8 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len)
|
||||||
if (!WPACKET_allocate_bytes(pkt, len, &dest))
|
if (!WPACKET_allocate_bytes(pkt, len, &dest))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(dest, src, len);
|
if (dest != NULL)
|
||||||
|
memcpy(dest, src, len);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +431,17 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len)
|
||||||
|
|
||||||
unsigned char *WPACKET_get_curr(WPACKET *pkt)
|
unsigned char *WPACKET_get_curr(WPACKET *pkt)
|
||||||
{
|
{
|
||||||
return GETBUF(pkt) + pkt->curr;
|
unsigned char *buf = GETBUF(pkt);
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return buf + pkt->curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WPACKET_is_null_buf(WPACKET *pkt)
|
||||||
|
{
|
||||||
|
return pkt->buf == NULL && pkt->staticbuf == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WPACKET_cleanup(WPACKET *pkt)
|
void WPACKET_cleanup(WPACKET *pkt)
|
||||||
|
|
|
@ -669,6 +669,13 @@ int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes);
|
||||||
*/
|
*/
|
||||||
int WPACKET_init(WPACKET *pkt, BUF_MEM *buf);
|
int WPACKET_init(WPACKET *pkt, BUF_MEM *buf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as WPACKET_init_len except there is no underlying buffer. No data is
|
||||||
|
* ever actually written. We just keep track of how much data would have been
|
||||||
|
* written if a buffer was there.
|
||||||
|
*/
|
||||||
|
int WPACKET_init_null(WPACKET *pkt, size_t lenbytes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Same as WPACKET_init_len except we do not use a growable BUF_MEM structure.
|
* Same as WPACKET_init_len except we do not use a growable BUF_MEM structure.
|
||||||
* A fixed buffer of memory |buf| of size |len| is used instead. A failure will
|
* A fixed buffer of memory |buf| of size |len| is used instead. A failure will
|
||||||
|
@ -868,6 +875,9 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len);
|
||||||
*/
|
*/
|
||||||
unsigned char *WPACKET_get_curr(WPACKET *pkt);
|
unsigned char *WPACKET_get_curr(WPACKET *pkt);
|
||||||
|
|
||||||
|
/* Returns true if the underlying buffer is actually NULL */
|
||||||
|
int WPACKET_is_null_buf(WPACKET *pkt);
|
||||||
|
|
||||||
/* Release resources in a WPACKET if a failure has occurred. */
|
/* Release resources in a WPACKET if a failure has occurred. */
|
||||||
void WPACKET_cleanup(WPACKET *pkt);
|
void WPACKET_cleanup(WPACKET *pkt);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue