Merge commit 'dfc115332c94a2f62058ac7f2bce7631fbd20b3d'
[unleashed/tickless.git] / lib / libssl / bs_cbb.c
blob1c02eaf0be62791e48322789aa0fed13c05998b2
1 /* $OpenBSD: bs_cbb.c,v 1.17.4.1 2017/12/09 13:43:25 jsing Exp $ */
2 /*
3 * Copyright (c) 2014, Google Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
17 #include <assert.h>
18 #include <stdlib.h>
19 #include <string.h>
21 #include <openssl/opensslconf.h>
23 #include "bytestring.h"
25 #define CBB_INITIAL_SIZE 64
27 static int
28 cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
30 struct cbb_buffer_st *base;
32 base = malloc(sizeof(struct cbb_buffer_st));
33 if (base == NULL)
34 return 0;
36 base->buf = buf;
37 base->len = 0;
38 base->cap = cap;
39 base->can_resize = 1;
41 cbb->base = base;
42 cbb->is_top_level = 1;
44 return 1;
47 int
48 CBB_init(CBB *cbb, size_t initial_capacity)
50 uint8_t *buf = NULL;
52 memset(cbb, 0, sizeof(*cbb));
54 if (initial_capacity == 0)
55 initial_capacity = CBB_INITIAL_SIZE;
57 if ((buf = malloc(initial_capacity)) == NULL)
58 return 0;
60 if (!cbb_init(cbb, buf, initial_capacity)) {
61 free(buf);
62 return 0;
65 return 1;
68 int
69 CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
71 memset(cbb, 0, sizeof(*cbb));
73 if (!cbb_init(cbb, buf, len))
74 return 0;
76 cbb->base->can_resize = 0;
78 return 1;
81 void
82 CBB_cleanup(CBB *cbb)
84 if (cbb->base) {
85 if (cbb->base->can_resize)
86 freezero(cbb->base->buf, cbb->base->cap);
87 free(cbb->base);
89 cbb->base = NULL;
90 cbb->child = NULL;
93 static int
94 cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
96 size_t newlen;
98 if (base == NULL)
99 return 0;
101 newlen = base->len + len;
102 if (newlen < base->len)
103 /* Overflow */
104 return 0;
106 if (newlen > base->cap) {
107 size_t newcap = base->cap * 2;
108 uint8_t *newbuf;
110 if (!base->can_resize)
111 return 0;
113 if (newcap < base->cap || newcap < newlen)
114 newcap = newlen;
116 newbuf = recallocarray(base->buf, base->cap, newcap, 1);
117 if (newbuf == NULL)
118 return 0;
120 base->buf = newbuf;
121 base->cap = newcap;
124 if (out)
125 *out = base->buf + base->len;
127 base->len = newlen;
128 return 1;
131 static int
132 cbb_add_u(CBB *cbb, uint32_t v, size_t len_len)
134 uint8_t *buf;
135 size_t i;
137 if (len_len == 0)
138 return 1;
140 if (len_len > 4)
141 return 0;
143 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len))
144 return 0;
146 for (i = len_len - 1; i < len_len; i--) {
147 buf[i] = v;
148 v >>= 8;
150 return 1;
154 CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
156 if (!cbb->is_top_level)
157 return 0;
159 if (!CBB_flush(cbb))
160 return 0;
162 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
164 * |out_data| and |out_len| can only be NULL if the CBB is
165 * fixed.
167 return 0;
169 if (out_data != NULL)
170 *out_data = cbb->base->buf;
172 if (out_len != NULL)
173 *out_len = cbb->base->len;
175 cbb->base->buf = NULL;
176 CBB_cleanup(cbb);
177 return 1;
181 * CBB_flush recurses and then writes out any pending length prefix. The current
182 * length of the underlying base is taken to be the length of the
183 * length-prefixed data.
186 CBB_flush(CBB *cbb)
188 size_t child_start, i, len;
190 if (cbb->base == NULL)
191 return 0;
193 if (cbb->child == NULL || cbb->pending_len_len == 0)
194 return 1;
196 child_start = cbb->offset + cbb->pending_len_len;
198 if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
199 cbb->base->len < child_start)
200 return 0;
202 len = cbb->base->len - child_start;
204 if (cbb->pending_is_asn1) {
206 * For ASN.1, we assumed that we were using short form which
207 * only requires a single byte for the length octet.
209 * If it turns out that we need long form, we have to move
210 * the contents along in order to make space for more length
211 * octets.
213 size_t len_len = 1; /* total number of length octets */
214 uint8_t initial_length_byte;
216 /* We already wrote 1 byte for the length. */
217 assert (cbb->pending_len_len == 1);
219 /* Check for long form */
220 if (len > 0xfffffffe)
221 return 0; /* 0xffffffff is reserved */
222 else if (len > 0xffffff)
223 len_len = 5;
224 else if (len > 0xffff)
225 len_len = 4;
226 else if (len > 0xff)
227 len_len = 3;
228 else if (len > 0x7f)
229 len_len = 2;
231 if (len_len == 1) {
232 /* For short form, the initial byte is the length. */
233 initial_length_byte = len;
234 len = 0;
236 } else {
238 * For long form, the initial byte is the number of
239 * subsequent length octets (plus bit 8 set).
241 initial_length_byte = 0x80 | (len_len - 1);
244 * We need to move the contents along in order to make
245 * space for the long form length octets.
247 size_t extra_bytes = len_len - 1;
248 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
249 return 0;
251 memmove(cbb->base->buf + child_start + extra_bytes,
252 cbb->base->buf + child_start, len);
254 cbb->base->buf[cbb->offset++] = initial_length_byte;
255 cbb->pending_len_len = len_len - 1;
258 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
259 cbb->base->buf[cbb->offset + i] = len;
260 len >>= 8;
262 if (len != 0)
263 return 0;
265 cbb->child->base = NULL;
266 cbb->child = NULL;
267 cbb->pending_len_len = 0;
268 cbb->pending_is_asn1 = 0;
269 cbb->offset = 0;
271 return 1;
274 void
275 CBB_discard_child(CBB *cbb)
277 if (cbb->child == NULL)
278 return;
280 cbb->base->len = cbb->offset;
282 cbb->child->base = NULL;
283 cbb->child = NULL;
284 cbb->pending_len_len = 0;
285 cbb->pending_is_asn1 = 0;
286 cbb->offset = 0;
289 static int
290 cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
292 uint8_t *prefix_bytes;
294 if (!CBB_flush(cbb))
295 return 0;
297 cbb->offset = cbb->base->len;
298 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
299 return 0;
301 memset(prefix_bytes, 0, len_len);
302 memset(out_contents, 0, sizeof(CBB));
303 out_contents->base = cbb->base;
304 cbb->child = out_contents;
305 cbb->pending_len_len = len_len;
306 cbb->pending_is_asn1 = 0;
308 return 1;
312 CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
314 return cbb_add_length_prefixed(cbb, out_contents, 1);
318 CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
320 return cbb_add_length_prefixed(cbb, out_contents, 2);
324 CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
326 return cbb_add_length_prefixed(cbb, out_contents, 3);
330 CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag)
332 if (tag > UINT8_MAX)
333 return 0;
335 /* Long form identifier octets are not supported. */
336 if ((tag & 0x1f) == 0x1f)
337 return 0;
339 /* Short-form identifier octet only needs a single byte */
340 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
341 return 0;
344 * Add 1 byte to cover the short-form length octet case. If it turns
345 * out we need long-form, it will be extended later.
347 cbb->offset = cbb->base->len;
348 if (!CBB_add_u8(cbb, 0))
349 return 0;
351 memset(out_contents, 0, sizeof(CBB));
352 out_contents->base = cbb->base;
353 cbb->child = out_contents;
354 cbb->pending_len_len = 1;
355 cbb->pending_is_asn1 = 1;
357 return 1;
361 CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
363 uint8_t *dest;
365 if (!CBB_add_space(cbb, &dest, len))
366 return 0;
368 memcpy(dest, data, len);
369 return 1;
373 CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
375 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
376 return 0;
378 return 1;
382 CBB_add_u8(CBB *cbb, size_t value)
384 if (value > UINT8_MAX)
385 return 0;
387 return cbb_add_u(cbb, (uint32_t)value, 1);
391 CBB_add_u16(CBB *cbb, size_t value)
393 if (value > UINT16_MAX)
394 return 0;
396 return cbb_add_u(cbb, (uint32_t)value, 2);
400 CBB_add_u24(CBB *cbb, size_t value)
402 if (value > 0xffffffUL)
403 return 0;
405 return cbb_add_u(cbb, (uint32_t)value, 3);
409 CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
411 CBB child;
412 size_t i;
413 int started = 0;
415 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
416 return 0;
418 for (i = 0; i < 8; i++) {
419 uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
422 * ASN.1 restriction: first 9 bits cannot be all zeroes or
423 * all ones. Since this function only encodes unsigned
424 * integers, the only concerns are not encoding leading
425 * zeros and adding a padding byte if necessary.
427 * In practice, this means:
428 * 1) Skip leading octets of all zero bits in the value
429 * 2) After skipping the leading zero octets, if the next 9
430 * bits are all ones, add an all zero prefix octet (and
431 * set the high bit of the prefix octet if negative).
433 * Additionally, for an unsigned value, add an all zero
434 * prefix if the high bit of the first octet would be one.
436 if (!started) {
437 if (byte == 0)
438 /* Don't encode leading zeros. */
439 continue;
442 * If the high bit is set, add a padding byte to make it
443 * unsigned.
445 if ((byte & 0x80) && !CBB_add_u8(&child, 0))
446 return 0;
448 started = 1;
450 if (!CBB_add_u8(&child, byte))
451 return 0;
454 /* 0 is encoded as a single 0, not the empty string. */
455 if (!started && !CBB_add_u8(&child, 0))
456 return 0;
458 return CBB_flush(cbb);