/*
- * Internal helper function used by WPACKET_close() and WPACKET_finish() to
- * close a sub-packet and write out its length if necessary.
+ * Internal helper function used by WPACKET_close(), WPACKET_finish() and
+ * WPACKET_fill_lengths() to close a sub-packet and write out its length if
+ * necessary. If |doclose| is 0 then it goes through the motions of closing
+ * (i.e. it fills in all the lengths), but doesn't actually close anything.
*/
-static int wpacket_intern_close(WPACKET *pkt)
+static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
{
- WPACKET_SUB *sub = pkt->subs;
size_t packlen = pkt->written - sub->pwritten;
if (packlen == 0
if (packlen == 0
&& sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {
+ /* We can't handle this case. Return an error */
+ if (!doclose)
+ return 0;
+
/* Deallocate any bytes allocated for the length of the WPACKET */
if ((pkt->curr - sub->lenbytes) == sub->packet_len) {
pkt->written -= sub->lenbytes;
sub->lenbytes))
return 0;
- pkt->subs = sub->parent;
- OPENSSL_free(sub);
+ if (doclose) {
+ pkt->subs = sub->parent;
+ OPENSSL_free(sub);
+ }
+
+ return 1;
+}
+
+int WPACKET_fill_lengths(WPACKET *pkt)
+{
+ WPACKET_SUB *sub;
+
+ assert(pkt->subs != NULL);
+ if (pkt->subs == NULL)
+ return 0;
+
+ sub = pkt->subs;
+ do {
+ if (!wpacket_intern_close(pkt, sub, 0))
+ return 0;
+ sub = sub->parent;
+ } while (sub != NULL);
return 1;
}
if (pkt->subs == NULL || pkt->subs->parent == NULL)
return 0;
- return wpacket_intern_close(pkt);
+ return wpacket_intern_close(pkt, pkt->subs, 1);
}
int WPACKET_finish(WPACKET *pkt)
if (pkt->subs == NULL || pkt->subs->parent != NULL)
return 0;
- ret = wpacket_intern_close(pkt);
+ ret = wpacket_intern_close(pkt, pkt->subs, 1);
if (ret) {
OPENSSL_free(pkt->subs);
pkt->subs = NULL;
*/
int WPACKET_finish(WPACKET *pkt);
+/*
+ * Iterates through all the sub-packets and writes out their lengths as if they
+ * were being closed. The lengths will be overwritten with the final lengths
+ * when the sub-packets are eventually closed (which may be different if more
+ * data is added to the WPACKET). This function will fail if a sub-packet is of
+ * 0 length and WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH is used.
+ */
+int WPACKET_fill_lengths(WPACKET *pkt);
+
/*
* Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated
* at the start of the sub-packet to store its length once we know it. Don't