xref: /openbsd/lib/libssl/bs_cbb.c (revision 42ccf58d)
1*42ccf58dSjsing /*	$OpenBSD: bs_cbb.c,v 1.14 2017/03/10 15:16:20 jsing Exp $	*/
2c4905cd3Sdoug /*
3c4905cd3Sdoug  * Copyright (c) 2014, Google Inc.
4c4905cd3Sdoug  *
5c4905cd3Sdoug  * Permission to use, copy, modify, and/or distribute this software for any
6c4905cd3Sdoug  * purpose with or without fee is hereby granted, provided that the above
7c4905cd3Sdoug  * copyright notice and this permission notice appear in all copies.
8c4905cd3Sdoug  *
9c4905cd3Sdoug  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10c4905cd3Sdoug  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11c4905cd3Sdoug  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12c4905cd3Sdoug  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13c4905cd3Sdoug  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14c4905cd3Sdoug  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15c4905cd3Sdoug  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16c4905cd3Sdoug 
17c4905cd3Sdoug #include <assert.h>
18c4905cd3Sdoug #include <stdlib.h>
19c4905cd3Sdoug #include <string.h>
20c4905cd3Sdoug 
21c4905cd3Sdoug #include <openssl/opensslconf.h>
22c4905cd3Sdoug 
23c4905cd3Sdoug #include "bytestring.h"
24c4905cd3Sdoug 
25732f1cb2Sdoug static int
26732f1cb2Sdoug cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
27732f1cb2Sdoug {
28c4905cd3Sdoug 	struct cbb_buffer_st *base;
29c4905cd3Sdoug 
30c4905cd3Sdoug 	base = malloc(sizeof(struct cbb_buffer_st));
31d7a08d8fSdoug 	if (base == NULL)
32c4905cd3Sdoug 		return 0;
33c4905cd3Sdoug 
34c4905cd3Sdoug 	base->buf = buf;
35c4905cd3Sdoug 	base->len = 0;
36c4905cd3Sdoug 	base->cap = cap;
37c4905cd3Sdoug 	base->can_resize = 1;
38c4905cd3Sdoug 
39c4905cd3Sdoug 	cbb->base = base;
40c4905cd3Sdoug 	cbb->is_top_level = 1;
4128a1f398Sjsing 
42c4905cd3Sdoug 	return 1;
43c4905cd3Sdoug }
44c4905cd3Sdoug 
45732f1cb2Sdoug int
46732f1cb2Sdoug CBB_init(CBB *cbb, size_t initial_capacity)
47732f1cb2Sdoug {
483a0c64b9Sdoug 	uint8_t *buf = NULL;
49c4905cd3Sdoug 
5028a1f398Sjsing 	memset(cbb, 0, sizeof(*cbb));
5128a1f398Sjsing 
523a0c64b9Sdoug 	if (initial_capacity > 0) {
533a0c64b9Sdoug 		if ((buf = malloc(initial_capacity)) == NULL)
54c4905cd3Sdoug 			return 0;
553a0c64b9Sdoug 	}
56c4905cd3Sdoug 
5741724196Sdoug 	if (!cbb_init(cbb, buf, initial_capacity)) {
5841724196Sdoug 		free(buf);
5941724196Sdoug 		return 0;
6041724196Sdoug 	}
6128a1f398Sjsing 
6241724196Sdoug 	return 1;
63c4905cd3Sdoug }
64c4905cd3Sdoug 
65732f1cb2Sdoug int
66732f1cb2Sdoug CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
67732f1cb2Sdoug {
6828a1f398Sjsing 	memset(cbb, 0, sizeof(*cbb));
6928a1f398Sjsing 
70732f1cb2Sdoug 	if (!cbb_init(cbb, buf, len))
71c4905cd3Sdoug 		return 0;
72c4905cd3Sdoug 
73c4905cd3Sdoug 	cbb->base->can_resize = 0;
7428a1f398Sjsing 
75c4905cd3Sdoug 	return 1;
76c4905cd3Sdoug }
77c4905cd3Sdoug 
78732f1cb2Sdoug void
79732f1cb2Sdoug CBB_cleanup(CBB *cbb)
80732f1cb2Sdoug {
81c4905cd3Sdoug 	if (cbb->base) {
823a0c64b9Sdoug 		if (cbb->base->can_resize)
83c4905cd3Sdoug 			free(cbb->base->buf);
84732f1cb2Sdoug 
85c4905cd3Sdoug 		free(cbb->base);
86c4905cd3Sdoug 	}
87c4905cd3Sdoug 	cbb->base = NULL;
88c4905cd3Sdoug }
89c4905cd3Sdoug 
90732f1cb2Sdoug static int
91732f1cb2Sdoug cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
92732f1cb2Sdoug {
93c4905cd3Sdoug 	size_t newlen;
94c4905cd3Sdoug 
95732f1cb2Sdoug 	if (base == NULL)
96c4905cd3Sdoug 		return 0;
97c4905cd3Sdoug 
98c4905cd3Sdoug 	newlen = base->len + len;
99732f1cb2Sdoug 	if (newlen < base->len)
100c4905cd3Sdoug 		/* Overflow */
101c4905cd3Sdoug 		return 0;
102c4905cd3Sdoug 
103c4905cd3Sdoug 	if (newlen > base->cap) {
104c4905cd3Sdoug 		size_t newcap = base->cap * 2;
105c4905cd3Sdoug 		uint8_t *newbuf;
106c4905cd3Sdoug 
107732f1cb2Sdoug 		if (!base->can_resize)
108c4905cd3Sdoug 			return 0;
109c4905cd3Sdoug 
110732f1cb2Sdoug 		if (newcap < base->cap || newcap < newlen)
111c4905cd3Sdoug 			newcap = newlen;
112732f1cb2Sdoug 
113*42ccf58dSjsing 		newbuf = recallocarray(base->buf, base->cap, newcap, 1);
114732f1cb2Sdoug 		if (newbuf == NULL)
115c4905cd3Sdoug 			return 0;
116c4905cd3Sdoug 
117c4905cd3Sdoug 		base->buf = newbuf;
118c4905cd3Sdoug 		base->cap = newcap;
119c4905cd3Sdoug 	}
120c4905cd3Sdoug 
121732f1cb2Sdoug 	if (out)
122c4905cd3Sdoug 		*out = base->buf + base->len;
123732f1cb2Sdoug 
124c4905cd3Sdoug 	base->len = newlen;
125c4905cd3Sdoug 	return 1;
126c4905cd3Sdoug }
127c4905cd3Sdoug 
128732f1cb2Sdoug static int
129f49f1317Sdoug cbb_add_u(CBB *cbb, uint32_t v, size_t len_len)
130732f1cb2Sdoug {
131c4905cd3Sdoug 	uint8_t *buf;
132c4905cd3Sdoug 	size_t i;
133c4905cd3Sdoug 
134732f1cb2Sdoug 	if (len_len == 0)
135c4905cd3Sdoug 		return 1;
136732f1cb2Sdoug 
137c2c0b151Sdoug 	if (len_len > 4)
138c2c0b151Sdoug 		return 0;
139c2c0b151Sdoug 
140f49f1317Sdoug 	if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len))
141c4905cd3Sdoug 		return 0;
142c4905cd3Sdoug 
143c4905cd3Sdoug 	for (i = len_len - 1; i < len_len; i--) {
144c4905cd3Sdoug 		buf[i] = v;
145c4905cd3Sdoug 		v >>= 8;
146c4905cd3Sdoug 	}
147c4905cd3Sdoug 	return 1;
148c4905cd3Sdoug }
149c4905cd3Sdoug 
150732f1cb2Sdoug int
151732f1cb2Sdoug CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
152732f1cb2Sdoug {
153732f1cb2Sdoug 	if (!cbb->is_top_level)
154c4905cd3Sdoug 		return 0;
155c4905cd3Sdoug 
156732f1cb2Sdoug 	if (!CBB_flush(cbb))
157c4905cd3Sdoug 		return 0;
158c4905cd3Sdoug 
159732f1cb2Sdoug 	if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
160d7a08d8fSdoug 		/*
161d7a08d8fSdoug 		 * |out_data| and |out_len| can only be NULL if the CBB is
162d7a08d8fSdoug 		 * fixed.
163d7a08d8fSdoug 		 */
164c4905cd3Sdoug 		return 0;
165c4905cd3Sdoug 
166732f1cb2Sdoug 	if (out_data != NULL)
167c4905cd3Sdoug 		*out_data = cbb->base->buf;
168732f1cb2Sdoug 
169732f1cb2Sdoug 	if (out_len != NULL)
170c4905cd3Sdoug 		*out_len = cbb->base->len;
171732f1cb2Sdoug 
172c4905cd3Sdoug 	cbb->base->buf = NULL;
173c4905cd3Sdoug 	CBB_cleanup(cbb);
174c4905cd3Sdoug 	return 1;
175c4905cd3Sdoug }
176c4905cd3Sdoug 
177732f1cb2Sdoug /*
178732f1cb2Sdoug  * CBB_flush recurses and then writes out any pending length prefix. The current
179732f1cb2Sdoug  * length of the underlying base is taken to be the length of the
180732f1cb2Sdoug  * length-prefixed data.
181732f1cb2Sdoug  */
182732f1cb2Sdoug int
183732f1cb2Sdoug CBB_flush(CBB *cbb)
184732f1cb2Sdoug {
185c4905cd3Sdoug 	size_t child_start, i, len;
186c4905cd3Sdoug 
187732f1cb2Sdoug 	if (cbb->base == NULL)
188c4905cd3Sdoug 		return 0;
189c4905cd3Sdoug 
190732f1cb2Sdoug 	if (cbb->child == NULL || cbb->pending_len_len == 0)
191c4905cd3Sdoug 		return 1;
192c4905cd3Sdoug 
193c4905cd3Sdoug 	child_start = cbb->offset + cbb->pending_len_len;
194c4905cd3Sdoug 
195732f1cb2Sdoug 	if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
196732f1cb2Sdoug 	    cbb->base->len < child_start)
197c4905cd3Sdoug 		return 0;
198c4905cd3Sdoug 
199c4905cd3Sdoug 	len = cbb->base->len - child_start;
200c4905cd3Sdoug 
201c4905cd3Sdoug 	if (cbb->pending_is_asn1) {
202d7a08d8fSdoug 		/*
2036ea8e45cSdoug 		 * For ASN.1, we assumed that we were using short form which
2046ea8e45cSdoug 		 * only requires a single byte for the length octet.
2056ea8e45cSdoug 		 *
2066ea8e45cSdoug 		 * If it turns out that we need long form, we have to move
2076ea8e45cSdoug 		 * the contents along in order to make space for more length
2086ea8e45cSdoug 		 * octets.
209d7a08d8fSdoug 		 */
2106ea8e45cSdoug 		size_t len_len = 1;  /* total number of length octets */
211c4905cd3Sdoug 		uint8_t initial_length_byte;
212c4905cd3Sdoug 
2136ea8e45cSdoug 		/* We already wrote 1 byte for the length. */
214c4905cd3Sdoug 		assert (cbb->pending_len_len == 1);
215c4905cd3Sdoug 
2166ea8e45cSdoug 		/* Check for long form */
2176ea8e45cSdoug 		if (len > 0xfffffffe)
2186ea8e45cSdoug 			return 0;	/* 0xffffffff is reserved */
2196ea8e45cSdoug 		else if (len > 0xffffff)
220c4905cd3Sdoug 			len_len = 5;
2216ea8e45cSdoug 		else if (len > 0xffff)
222c4905cd3Sdoug 			len_len = 4;
2236ea8e45cSdoug 		else if (len > 0xff)
224c4905cd3Sdoug 			len_len = 3;
2256ea8e45cSdoug 		else if (len > 0x7f)
226c4905cd3Sdoug 			len_len = 2;
2276ea8e45cSdoug 
2286ea8e45cSdoug 		if (len_len == 1) {
2296ea8e45cSdoug 			/* For short form, the initial byte is the length. */
230c4905cd3Sdoug 			initial_length_byte = len;
231c4905cd3Sdoug 			len = 0;
232c4905cd3Sdoug 
2336ea8e45cSdoug 		} else {
2346ea8e45cSdoug 			/*
2356ea8e45cSdoug 			 * For long form, the initial byte is the number of
2366ea8e45cSdoug 			 * subsequent length octets (plus bit 8 set).
2376ea8e45cSdoug 			 */
2386ea8e45cSdoug 			initial_length_byte = 0x80 | (len_len - 1);
2396ea8e45cSdoug 
240d7a08d8fSdoug 			/*
241d7a08d8fSdoug 			 * We need to move the contents along in order to make
2426ea8e45cSdoug 			 * space for the long form length octets.
243d7a08d8fSdoug 			 */
244c4905cd3Sdoug 			size_t extra_bytes = len_len - 1;
245732f1cb2Sdoug 			if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
246c4905cd3Sdoug 				return 0;
247732f1cb2Sdoug 
248c4905cd3Sdoug 			memmove(cbb->base->buf + child_start + extra_bytes,
249c4905cd3Sdoug 			    cbb->base->buf + child_start, len);
250c4905cd3Sdoug 		}
251c4905cd3Sdoug 		cbb->base->buf[cbb->offset++] = initial_length_byte;
252c4905cd3Sdoug 		cbb->pending_len_len = len_len - 1;
253c4905cd3Sdoug 	}
254c4905cd3Sdoug 
255c4905cd3Sdoug 	for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
256c4905cd3Sdoug 		cbb->base->buf[cbb->offset + i] = len;
257c4905cd3Sdoug 		len >>= 8;
258c4905cd3Sdoug 	}
259732f1cb2Sdoug 	if (len != 0)
260c4905cd3Sdoug 		return 0;
261c4905cd3Sdoug 
262c4905cd3Sdoug 	cbb->child->base = NULL;
263c4905cd3Sdoug 	cbb->child = NULL;
264c4905cd3Sdoug 	cbb->pending_len_len = 0;
265c4905cd3Sdoug 	cbb->pending_is_asn1 = 0;
266c4905cd3Sdoug 	cbb->offset = 0;
267c4905cd3Sdoug 
268c4905cd3Sdoug 	return 1;
269c4905cd3Sdoug }
270c4905cd3Sdoug 
271c4905cd3Sdoug 
272732f1cb2Sdoug static int
273732f1cb2Sdoug cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
274732f1cb2Sdoug {
275c4905cd3Sdoug 	uint8_t *prefix_bytes;
276c4905cd3Sdoug 
277732f1cb2Sdoug 	if (!CBB_flush(cbb))
278c4905cd3Sdoug 		return 0;
279c4905cd3Sdoug 
280c4905cd3Sdoug 	cbb->offset = cbb->base->len;
281732f1cb2Sdoug 	if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
282c4905cd3Sdoug 		return 0;
283c4905cd3Sdoug 
284c4905cd3Sdoug 	memset(prefix_bytes, 0, len_len);
285c4905cd3Sdoug 	memset(out_contents, 0, sizeof(CBB));
286c4905cd3Sdoug 	out_contents->base = cbb->base;
287c4905cd3Sdoug 	cbb->child = out_contents;
288c4905cd3Sdoug 	cbb->pending_len_len = len_len;
289c4905cd3Sdoug 	cbb->pending_is_asn1 = 0;
290c4905cd3Sdoug 
291c4905cd3Sdoug 	return 1;
292c4905cd3Sdoug }
293c4905cd3Sdoug 
294732f1cb2Sdoug int
295732f1cb2Sdoug CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
296732f1cb2Sdoug {
297c4905cd3Sdoug 	return cbb_add_length_prefixed(cbb, out_contents, 1);
298c4905cd3Sdoug }
299c4905cd3Sdoug 
300732f1cb2Sdoug int
301732f1cb2Sdoug CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
302732f1cb2Sdoug {
303c4905cd3Sdoug 	return cbb_add_length_prefixed(cbb, out_contents, 2);
304c4905cd3Sdoug }
305c4905cd3Sdoug 
306732f1cb2Sdoug int
307732f1cb2Sdoug CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
308732f1cb2Sdoug {
309c4905cd3Sdoug 	return cbb_add_length_prefixed(cbb, out_contents, 3);
310c4905cd3Sdoug }
311c4905cd3Sdoug 
312732f1cb2Sdoug int
3139d4b5ca7Sdoug CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag)
314732f1cb2Sdoug {
3159d4b5ca7Sdoug 	if (tag > UINT8_MAX)
3169d4b5ca7Sdoug 		return 0;
3179d4b5ca7Sdoug 
318d7a08d8fSdoug 	/* Long form identifier octets are not supported. */
319d7a08d8fSdoug 	if ((tag & 0x1f) == 0x1f)
320d7a08d8fSdoug 		return 0;
321d7a08d8fSdoug 
3226ea8e45cSdoug 	/* Short-form identifier octet only needs a single byte */
323732f1cb2Sdoug 	if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
324c4905cd3Sdoug 		return 0;
325c4905cd3Sdoug 
3266ea8e45cSdoug 	/*
3276ea8e45cSdoug 	 * Add 1 byte to cover the short-form length octet case.  If it turns
3286ea8e45cSdoug 	 * out we need long-form, it will be extended later.
3296ea8e45cSdoug 	 */
330c4905cd3Sdoug 	cbb->offset = cbb->base->len;
331732f1cb2Sdoug 	if (!CBB_add_u8(cbb, 0))
332c4905cd3Sdoug 		return 0;
333c4905cd3Sdoug 
334c4905cd3Sdoug 	memset(out_contents, 0, sizeof(CBB));
335c4905cd3Sdoug 	out_contents->base = cbb->base;
336c4905cd3Sdoug 	cbb->child = out_contents;
337c4905cd3Sdoug 	cbb->pending_len_len = 1;
338c4905cd3Sdoug 	cbb->pending_is_asn1 = 1;
339c4905cd3Sdoug 
340c4905cd3Sdoug 	return 1;
341c4905cd3Sdoug }
342c4905cd3Sdoug 
343732f1cb2Sdoug int
344732f1cb2Sdoug CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
345732f1cb2Sdoug {
346c4905cd3Sdoug 	uint8_t *dest;
347c4905cd3Sdoug 
34818f8c184Sdoug 	if (!CBB_add_space(cbb, &dest, len))
349c4905cd3Sdoug 		return 0;
350732f1cb2Sdoug 
351c4905cd3Sdoug 	memcpy(dest, data, len);
352c4905cd3Sdoug 	return 1;
353c4905cd3Sdoug }
354c4905cd3Sdoug 
355732f1cb2Sdoug int
356732f1cb2Sdoug CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
357732f1cb2Sdoug {
358732f1cb2Sdoug 	if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
359c4905cd3Sdoug 		return 0;
360732f1cb2Sdoug 
361c4905cd3Sdoug 	return 1;
362c4905cd3Sdoug }
363c4905cd3Sdoug 
364732f1cb2Sdoug int
3659d4b5ca7Sdoug CBB_add_u8(CBB *cbb, size_t value)
366732f1cb2Sdoug {
3679d4b5ca7Sdoug 	if (value > UINT8_MAX)
3689d4b5ca7Sdoug 		return 0;
3699d4b5ca7Sdoug 
3709d4b5ca7Sdoug 	return cbb_add_u(cbb, (uint32_t)value, 1);
371c4905cd3Sdoug }
372c4905cd3Sdoug 
373732f1cb2Sdoug int
3749d4b5ca7Sdoug CBB_add_u16(CBB *cbb, size_t value)
375732f1cb2Sdoug {
3769d4b5ca7Sdoug 	if (value > UINT16_MAX)
3779d4b5ca7Sdoug 		return 0;
3789d4b5ca7Sdoug 
3799d4b5ca7Sdoug 	return cbb_add_u(cbb, (uint32_t)value, 2);
380c4905cd3Sdoug }
381c4905cd3Sdoug 
382732f1cb2Sdoug int
3839d4b5ca7Sdoug CBB_add_u24(CBB *cbb, size_t value)
384732f1cb2Sdoug {
3859d4b5ca7Sdoug 	if (value > 0xffffffUL)
3869d4b5ca7Sdoug 		return 0;
3879d4b5ca7Sdoug 
3889d4b5ca7Sdoug 	return cbb_add_u(cbb, (uint32_t)value, 3);
389c4905cd3Sdoug }
390c4905cd3Sdoug 
391732f1cb2Sdoug int
392732f1cb2Sdoug CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
393732f1cb2Sdoug {
394c4905cd3Sdoug 	CBB child;
395c4905cd3Sdoug 	size_t i;
396c4905cd3Sdoug 	int started = 0;
397c4905cd3Sdoug 
398732f1cb2Sdoug 	if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
399c4905cd3Sdoug 		return 0;
400c4905cd3Sdoug 
401c4905cd3Sdoug 	for (i = 0; i < 8; i++) {
402c4905cd3Sdoug 		uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
403debb3ac7Sdoug 
404debb3ac7Sdoug 		/*
405debb3ac7Sdoug 		 * ASN.1 restriction: first 9 bits cannot be all zeroes or
406debb3ac7Sdoug 		 * all ones.  Since this function only encodes unsigned
407debb3ac7Sdoug 		 * integers, the only concerns are not encoding leading
408debb3ac7Sdoug 		 * zeros and adding a padding byte if necessary.
409debb3ac7Sdoug 		 *
410debb3ac7Sdoug 		 * In practice, this means:
411debb3ac7Sdoug 		 * 1) Skip leading octets of all zero bits in the value
412debb3ac7Sdoug 		 * 2) After skipping the leading zero octets, if the next 9
413debb3ac7Sdoug 		 *    bits are all ones, add an all zero prefix octet (and
414debb3ac7Sdoug 		 *    set the high bit of the prefix octet if negative).
415debb3ac7Sdoug 		 *
416debb3ac7Sdoug 		 * Additionally, for an unsigned value, add an all zero
417debb3ac7Sdoug 		 * prefix if the high bit of the first octet would be one.
418debb3ac7Sdoug 		 */
419c4905cd3Sdoug 		if (!started) {
420732f1cb2Sdoug 			if (byte == 0)
421c4905cd3Sdoug 				/* Don't encode leading zeros. */
422c4905cd3Sdoug 				continue;
423732f1cb2Sdoug 
424d7a08d8fSdoug 			/*
425d7a08d8fSdoug 			 * If the high bit is set, add a padding byte to make it
426d7a08d8fSdoug 			 * unsigned.
427d7a08d8fSdoug 			 */
428732f1cb2Sdoug 			if ((byte & 0x80) && !CBB_add_u8(&child, 0))
429c4905cd3Sdoug 				return 0;
430732f1cb2Sdoug 
431c4905cd3Sdoug 			started = 1;
432c4905cd3Sdoug 		}
433732f1cb2Sdoug 		if (!CBB_add_u8(&child, byte))
434c4905cd3Sdoug 			return 0;
435c4905cd3Sdoug 	}
436c4905cd3Sdoug 
437c4905cd3Sdoug 	/* 0 is encoded as a single 0, not the empty string. */
438732f1cb2Sdoug 	if (!started && !CBB_add_u8(&child, 0))
439c4905cd3Sdoug 		return 0;
440c4905cd3Sdoug 
441c4905cd3Sdoug 	return CBB_flush(cbb);
442c4905cd3Sdoug }
443