1 /* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/bytestring.h>
16
17 #include <assert.h>
18 #include <string.h>
19
20 #include <openssl/mem.h>
21
22 #include "../internal.h"
23
24
CBB_zero(CBB * cbb)25 void CBB_zero(CBB *cbb) {
26 OPENSSL_memset(cbb, 0, sizeof(CBB));
27 }
28
cbb_init(CBB * cbb,uint8_t * buf,size_t cap)29 static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
30 /* This assumes that |cbb| has already been zeroed. */
31 struct cbb_buffer_st *base;
32
33 base = OPENSSL_malloc(sizeof(struct cbb_buffer_st));
34 if (base == NULL) {
35 return 0;
36 }
37
38 base->buf = buf;
39 base->len = 0;
40 base->cap = cap;
41 base->can_resize = 1;
42 base->error = 0;
43
44 cbb->base = base;
45 cbb->is_top_level = 1;
46 return 1;
47 }
48
CBB_init(CBB * cbb,size_t initial_capacity)49 int CBB_init(CBB *cbb, size_t initial_capacity) {
50 CBB_zero(cbb);
51
52 uint8_t *buf = OPENSSL_malloc(initial_capacity);
53 if (initial_capacity > 0 && buf == NULL) {
54 return 0;
55 }
56
57 if (!cbb_init(cbb, buf, initial_capacity)) {
58 OPENSSL_free(buf);
59 return 0;
60 }
61
62 return 1;
63 }
64
CBB_init_fixed(CBB * cbb,uint8_t * buf,size_t len)65 int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
66 CBB_zero(cbb);
67
68 if (!cbb_init(cbb, buf, len)) {
69 return 0;
70 }
71
72 cbb->base->can_resize = 0;
73 return 1;
74 }
75
CBB_cleanup(CBB * cbb)76 void CBB_cleanup(CBB *cbb) {
77 if (cbb->base) {
78 /* Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They
79 * are implicitly discarded when the parent is flushed or cleaned up. */
80 assert(cbb->is_top_level);
81
82 if (cbb->base->can_resize) {
83 OPENSSL_free(cbb->base->buf);
84 }
85 OPENSSL_free(cbb->base);
86 }
87 cbb->base = NULL;
88 }
89
cbb_buffer_reserve(struct cbb_buffer_st * base,uint8_t ** out,size_t len)90 static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
91 size_t len) {
92 size_t newlen;
93
94 if (base == NULL) {
95 return 0;
96 }
97
98 newlen = base->len + len;
99 if (newlen < base->len) {
100 /* Overflow */
101 goto err;
102 }
103
104 if (newlen > base->cap) {
105 size_t newcap = base->cap * 2;
106 uint8_t *newbuf;
107
108 if (!base->can_resize) {
109 goto err;
110 }
111
112 if (newcap < base->cap || newcap < newlen) {
113 newcap = newlen;
114 }
115 newbuf = OPENSSL_realloc(base->buf, newcap);
116 if (newbuf == NULL) {
117 goto err;
118 }
119
120 base->buf = newbuf;
121 base->cap = newcap;
122 }
123
124 if (out) {
125 *out = base->buf + base->len;
126 }
127
128 return 1;
129
130 err:
131 base->error = 1;
132 return 0;
133 }
134
cbb_buffer_add(struct cbb_buffer_st * base,uint8_t ** out,size_t len)135 static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
136 size_t len) {
137 if (!cbb_buffer_reserve(base, out, len)) {
138 return 0;
139 }
140 /* This will not overflow or |cbb_buffer_reserve| would have failed. */
141 base->len += len;
142 return 1;
143 }
144
cbb_buffer_add_u(struct cbb_buffer_st * base,uint32_t v,size_t len_len)145 static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v,
146 size_t len_len) {
147 if (len_len == 0) {
148 return 1;
149 }
150
151 uint8_t *buf;
152 if (!cbb_buffer_add(base, &buf, len_len)) {
153 return 0;
154 }
155
156 for (size_t i = len_len - 1; i < len_len; i--) {
157 buf[i] = v;
158 v >>= 8;
159 }
160
161 if (v != 0) {
162 base->error = 1;
163 return 0;
164 }
165
166 return 1;
167 }
168
CBB_finish(CBB * cbb,uint8_t ** out_data,size_t * out_len)169 int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
170 if (!cbb->is_top_level) {
171 return 0;
172 }
173
174 if (!CBB_flush(cbb)) {
175 return 0;
176 }
177
178 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) {
179 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */
180 return 0;
181 }
182
183 if (out_data != NULL) {
184 *out_data = cbb->base->buf;
185 }
186 if (out_len != NULL) {
187 *out_len = cbb->base->len;
188 }
189 cbb->base->buf = NULL;
190 CBB_cleanup(cbb);
191 return 1;
192 }
193
194 /* CBB_flush recurses and then writes out any pending length prefix. The
195 * current length of the underlying base is taken to be the length of the
196 * length-prefixed data. */
CBB_flush(CBB * cbb)197 int CBB_flush(CBB *cbb) {
198 size_t child_start, i, len;
199
200 /* If |cbb->base| has hit an error, the buffer is in an undefined state, so
201 * fail all following calls. In particular, |cbb->child| may point to invalid
202 * memory. */
203 if (cbb->base == NULL || cbb->base->error) {
204 return 0;
205 }
206
207 if (cbb->child == NULL || cbb->child->pending_len_len == 0) {
208 return 1;
209 }
210
211 child_start = cbb->child->offset + cbb->child->pending_len_len;
212
213 if (!CBB_flush(cbb->child) ||
214 child_start < cbb->child->offset ||
215 cbb->base->len < child_start) {
216 goto err;
217 }
218
219 len = cbb->base->len - child_start;
220
221 if (cbb->child->pending_is_asn1) {
222 /* For ASN.1 we assume that we'll only need a single byte for the length.
223 * If that turned out to be incorrect, we have to move the contents along
224 * in order to make space. */
225 uint8_t len_len;
226 uint8_t initial_length_byte;
227
228 assert (cbb->child->pending_len_len == 1);
229
230 if (len > 0xfffffffe) {
231 /* Too large. */
232 goto err;
233 } else if (len > 0xffffff) {
234 len_len = 5;
235 initial_length_byte = 0x80 | 4;
236 } else if (len > 0xffff) {
237 len_len = 4;
238 initial_length_byte = 0x80 | 3;
239 } else if (len > 0xff) {
240 len_len = 3;
241 initial_length_byte = 0x80 | 2;
242 } else if (len > 0x7f) {
243 len_len = 2;
244 initial_length_byte = 0x80 | 1;
245 } else {
246 len_len = 1;
247 initial_length_byte = (uint8_t)len;
248 len = 0;
249 }
250
251 if (len_len != 1) {
252 /* We need to move the contents along in order to make space. */
253 size_t extra_bytes = len_len - 1;
254 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) {
255 goto err;
256 }
257 OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes,
258 cbb->base->buf + child_start, len);
259 }
260 cbb->base->buf[cbb->child->offset++] = initial_length_byte;
261 cbb->child->pending_len_len = len_len - 1;
262 }
263
264 for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len;
265 i--) {
266 cbb->base->buf[cbb->child->offset + i] = (uint8_t)len;
267 len >>= 8;
268 }
269 if (len != 0) {
270 goto err;
271 }
272
273 cbb->child->base = NULL;
274 cbb->child = NULL;
275
276 return 1;
277
278 err:
279 cbb->base->error = 1;
280 return 0;
281 }
282
CBB_data(const CBB * cbb)283 const uint8_t *CBB_data(const CBB *cbb) {
284 assert(cbb->child == NULL);
285 return cbb->base->buf + cbb->offset + cbb->pending_len_len;
286 }
287
CBB_len(const CBB * cbb)288 size_t CBB_len(const CBB *cbb) {
289 assert(cbb->child == NULL);
290 assert(cbb->offset + cbb->pending_len_len <= cbb->base->len);
291
292 return cbb->base->len - cbb->offset - cbb->pending_len_len;
293 }
294
cbb_add_length_prefixed(CBB * cbb,CBB * out_contents,uint8_t len_len)295 static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
296 uint8_t len_len) {
297 uint8_t *prefix_bytes;
298
299 if (!CBB_flush(cbb)) {
300 return 0;
301 }
302
303 size_t offset = cbb->base->len;
304 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
305 return 0;
306 }
307
308 OPENSSL_memset(prefix_bytes, 0, len_len);
309 OPENSSL_memset(out_contents, 0, sizeof(CBB));
310 out_contents->base = cbb->base;
311 cbb->child = out_contents;
312 cbb->child->offset = offset;
313 cbb->child->pending_len_len = len_len;
314 cbb->child->pending_is_asn1 = 0;
315
316 return 1;
317 }
318
CBB_add_u8_length_prefixed(CBB * cbb,CBB * out_contents)319 int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) {
320 return cbb_add_length_prefixed(cbb, out_contents, 1);
321 }
322
CBB_add_u16_length_prefixed(CBB * cbb,CBB * out_contents)323 int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) {
324 return cbb_add_length_prefixed(cbb, out_contents, 2);
325 }
326
CBB_add_u24_length_prefixed(CBB * cbb,CBB * out_contents)327 int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
328 return cbb_add_length_prefixed(cbb, out_contents, 3);
329 }
330
CBB_add_asn1(CBB * cbb,CBB * out_contents,unsigned tag)331 int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) {
332 if (tag > 0xff ||
333 (tag & 0x1f) == 0x1f) {
334 /* Long form identifier octets are not supported. Further, all current valid
335 * tag serializations are 8 bits. */
336 cbb->base->error = 1;
337 return 0;
338 }
339
340 if (!CBB_flush(cbb) ||
341 /* |tag|'s representation matches the DER encoding. */
342 !CBB_add_u8(cbb, (uint8_t)tag)) {
343 return 0;
344 }
345
346 size_t offset = cbb->base->len;
347 if (!CBB_add_u8(cbb, 0)) {
348 return 0;
349 }
350
351 OPENSSL_memset(out_contents, 0, sizeof(CBB));
352 out_contents->base = cbb->base;
353 cbb->child = out_contents;
354 cbb->child->offset = offset;
355 cbb->child->pending_len_len = 1;
356 cbb->child->pending_is_asn1 = 1;
357
358 return 1;
359 }
360
CBB_add_bytes(CBB * cbb,const uint8_t * data,size_t len)361 int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
362 uint8_t *dest;
363
364 if (!CBB_flush(cbb) ||
365 !cbb_buffer_add(cbb->base, &dest, len)) {
366 return 0;
367 }
368 OPENSSL_memcpy(dest, data, len);
369 return 1;
370 }
371
CBB_add_space(CBB * cbb,uint8_t ** out_data,size_t len)372 int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
373 if (!CBB_flush(cbb) ||
374 !cbb_buffer_add(cbb->base, out_data, len)) {
375 return 0;
376 }
377 return 1;
378 }
379
CBB_reserve(CBB * cbb,uint8_t ** out_data,size_t len)380 int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) {
381 if (!CBB_flush(cbb) ||
382 !cbb_buffer_reserve(cbb->base, out_data, len)) {
383 return 0;
384 }
385 return 1;
386 }
387
CBB_did_write(CBB * cbb,size_t len)388 int CBB_did_write(CBB *cbb, size_t len) {
389 size_t newlen = cbb->base->len + len;
390 if (cbb->child != NULL ||
391 newlen < cbb->base->len ||
392 newlen > cbb->base->cap) {
393 return 0;
394 }
395 cbb->base->len = newlen;
396 return 1;
397 }
398
CBB_add_u8(CBB * cbb,uint8_t value)399 int CBB_add_u8(CBB *cbb, uint8_t value) {
400 if (!CBB_flush(cbb)) {
401 return 0;
402 }
403
404 return cbb_buffer_add_u(cbb->base, value, 1);
405 }
406
CBB_add_u16(CBB * cbb,uint16_t value)407 int CBB_add_u16(CBB *cbb, uint16_t value) {
408 if (!CBB_flush(cbb)) {
409 return 0;
410 }
411
412 return cbb_buffer_add_u(cbb->base, value, 2);
413 }
414
CBB_add_u24(CBB * cbb,uint32_t value)415 int CBB_add_u24(CBB *cbb, uint32_t value) {
416 if (!CBB_flush(cbb)) {
417 return 0;
418 }
419
420 return cbb_buffer_add_u(cbb->base, value, 3);
421 }
422
CBB_add_u32(CBB * cbb,uint32_t value)423 int CBB_add_u32(CBB *cbb, uint32_t value) {
424 if (!CBB_flush(cbb)) {
425 return 0;
426 }
427
428 return cbb_buffer_add_u(cbb->base, value, 4);
429 }
430
CBB_discard_child(CBB * cbb)431 void CBB_discard_child(CBB *cbb) {
432 if (cbb->child == NULL) {
433 return;
434 }
435
436 cbb->base->len = cbb->child->offset;
437
438 cbb->child->base = NULL;
439 cbb->child = NULL;
440 }
441
CBB_add_asn1_uint64(CBB * cbb,uint64_t value)442 int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
443 CBB child;
444 int started = 0;
445
446 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
447 return 0;
448 }
449
450 for (size_t i = 0; i < 8; i++) {
451 uint8_t byte = (value >> 8*(7-i)) & 0xff;
452 if (!started) {
453 if (byte == 0) {
454 /* Don't encode leading zeros. */
455 continue;
456 }
457 /* If the high bit is set, add a padding byte to make it
458 * unsigned. */
459 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) {
460 return 0;
461 }
462 started = 1;
463 }
464 if (!CBB_add_u8(&child, byte)) {
465 return 0;
466 }
467 }
468
469 /* 0 is encoded as a single 0, not the empty string. */
470 if (!started && !CBB_add_u8(&child, 0)) {
471 return 0;
472 }
473
474 return CBB_flush(cbb);
475 }
476