Update LibreSSL from version 2.4.4 => 2.9.1
[dragonfly.git] / crypto / libressl / ssl / bs_cbb.c
1 /*      $OpenBSD: bs_cbb.c,v 1.20 2019/01/23 22:20:40 beck Exp $        */
2 /*
3  * Copyright (c) 2014, Google Inc.
4  *
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.
8  *
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. */
16
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <openssl/opensslconf.h>
21
22 #include "bytestring.h"
23
24 #define CBB_INITIAL_SIZE 64
25
26 static int
27 cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
28 {
29         struct cbb_buffer_st *base;
30
31         base = malloc(sizeof(struct cbb_buffer_st));
32         if (base == NULL)
33                 return 0;
34
35         base->buf = buf;
36         base->len = 0;
37         base->cap = cap;
38         base->can_resize = 1;
39
40         cbb->base = base;
41         cbb->is_top_level = 1;
42
43         return 1;
44 }
45
46 int
47 CBB_init(CBB *cbb, size_t initial_capacity)
48 {
49         uint8_t *buf = NULL;
50
51         memset(cbb, 0, sizeof(*cbb));
52
53         if (initial_capacity == 0)
54                 initial_capacity = CBB_INITIAL_SIZE;
55
56         if ((buf = malloc(initial_capacity)) == NULL)
57                 return 0;
58
59         if (!cbb_init(cbb, buf, initial_capacity)) {
60                 free(buf);
61                 return 0;
62         }
63
64         return 1;
65 }
66
67 int
68 CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
69 {
70         memset(cbb, 0, sizeof(*cbb));
71
72         if (!cbb_init(cbb, buf, len))
73                 return 0;
74
75         cbb->base->can_resize = 0;
76
77         return 1;
78 }
79
80 void
81 CBB_cleanup(CBB *cbb)
82 {
83         if (cbb->base) {
84                 if (cbb->base->can_resize)
85                         freezero(cbb->base->buf, cbb->base->cap);
86                 free(cbb->base);
87         }
88         cbb->base = NULL;
89         cbb->child = NULL;
90 }
91
92 static int
93 cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
94 {
95         size_t newlen;
96
97         if (base == NULL)
98                 return 0;
99
100         newlen = base->len + len;
101         if (newlen < base->len)
102                 /* Overflow */
103                 return 0;
104
105         if (newlen > base->cap) {
106                 size_t newcap = base->cap * 2;
107                 uint8_t *newbuf;
108
109                 if (!base->can_resize)
110                         return 0;
111
112                 if (newcap < base->cap || newcap < newlen)
113                         newcap = newlen;
114
115                 newbuf = recallocarray(base->buf, base->cap, newcap, 1);
116                 if (newbuf == NULL)
117                         return 0;
118
119                 base->buf = newbuf;
120                 base->cap = newcap;
121         }
122
123         if (out)
124                 *out = base->buf + base->len;
125
126         base->len = newlen;
127         return 1;
128 }
129
130 static int
131 cbb_add_u(CBB *cbb, uint32_t v, size_t len_len)
132 {
133         uint8_t *buf;
134         size_t i;
135
136         if (len_len == 0)
137                 return 1;
138
139         if (len_len > 4)
140                 return 0;
141
142         if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len))
143                 return 0;
144
145         for (i = len_len - 1; i < len_len; i--) {
146                 buf[i] = v;
147                 v >>= 8;
148         }
149         return 1;
150 }
151
152 int
153 CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
154 {
155         if (!cbb->is_top_level)
156                 return 0;
157
158         if (!CBB_flush(cbb))
159                 return 0;
160
161         if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
162                 /*
163                  * |out_data| and |out_len| can only be NULL if the CBB is
164                  * fixed.
165                  */
166                 return 0;
167
168         if (out_data != NULL)
169                 *out_data = cbb->base->buf;
170
171         if (out_len != NULL)
172                 *out_len = cbb->base->len;
173
174         cbb->base->buf = NULL;
175         CBB_cleanup(cbb);
176         return 1;
177 }
178
179 /*
180  * CBB_flush recurses and then writes out any pending length prefix. The current
181  * length of the underlying base is taken to be the length of the
182  * length-prefixed data.
183  */
184 int
185 CBB_flush(CBB *cbb)
186 {
187         size_t child_start, i, len;
188
189         if (cbb->base == NULL)
190                 return 0;
191
192         if (cbb->child == NULL || cbb->pending_len_len == 0)
193                 return 1;
194
195         child_start = cbb->offset + cbb->pending_len_len;
196
197         if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
198             cbb->base->len < child_start)
199                 return 0;
200
201         len = cbb->base->len - child_start;
202
203         if (cbb->pending_is_asn1) {
204                 /*
205                  * For ASN.1, we assumed that we were using short form which
206                  * only requires a single byte for the length octet.
207                  *
208                  * If it turns out that we need long form, we have to move
209                  * the contents along in order to make space for more length
210                  * octets.
211                  */
212                 size_t len_len = 1;  /* total number of length octets */
213                 uint8_t initial_length_byte;
214
215                 /* We already wrote 1 byte for the length. */
216                 if (cbb->pending_len_len != 1)
217                         return 0;
218
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;
230
231                 if (len_len == 1) {
232                         /* For short form, the initial byte is the length. */
233                         initial_length_byte = len;
234                         len = 0;
235
236                 } else {
237                         /*
238                          * For long form, the initial byte is the number of
239                          * subsequent length octets (plus bit 8 set).
240                          */
241                         initial_length_byte = 0x80 | (len_len - 1);
242
243                         /*
244                          * We need to move the contents along in order to make
245                          * space for the long form length octets.
246                          */
247                         size_t extra_bytes = len_len - 1;
248                         if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
249                                 return 0;
250
251                         memmove(cbb->base->buf + child_start + extra_bytes,
252                             cbb->base->buf + child_start, len);
253                 }
254                 cbb->base->buf[cbb->offset++] = initial_length_byte;
255                 cbb->pending_len_len = len_len - 1;
256         }
257
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;
261         }
262         if (len != 0)
263                 return 0;
264
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;
270
271         return 1;
272 }
273
274 void
275 CBB_discard_child(CBB *cbb)
276 {
277         if (cbb->child == NULL)
278                 return;
279
280         cbb->base->len = cbb->offset;
281         
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;
287 }
288
289 static int
290 cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
291 {
292         uint8_t *prefix_bytes;
293
294         if (!CBB_flush(cbb))
295                 return 0;
296
297         cbb->offset = cbb->base->len;
298         if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
299                 return 0;
300
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;
307
308         return 1;
309 }
310
311 int
312 CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
313 {
314         return cbb_add_length_prefixed(cbb, out_contents, 1);
315 }
316
317 int
318 CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
319 {
320         return cbb_add_length_prefixed(cbb, out_contents, 2);
321 }
322
323 int
324 CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
325 {
326         return cbb_add_length_prefixed(cbb, out_contents, 3);
327 }
328
329 int
330 CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag)
331 {
332         if (tag > UINT8_MAX)
333                 return 0;
334
335         /* Long form identifier octets are not supported. */
336         if ((tag & 0x1f) == 0x1f)
337                 return 0;
338
339         /* Short-form identifier octet only needs a single byte */
340         if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
341                 return 0;
342
343         /*
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.
346          */
347         cbb->offset = cbb->base->len;
348         if (!CBB_add_u8(cbb, 0))
349                 return 0;
350
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;
356
357         return 1;
358 }
359
360 int
361 CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
362 {
363         uint8_t *dest;
364
365         if (!CBB_add_space(cbb, &dest, len))
366                 return 0;
367
368         memcpy(dest, data, len);
369         return 1;
370 }
371
372 int
373 CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
374 {
375         if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
376                 return 0;
377
378         return 1;
379 }
380
381 int
382 CBB_add_u8(CBB *cbb, size_t value)
383 {
384         if (value > UINT8_MAX)
385                 return 0;
386
387         return cbb_add_u(cbb, (uint32_t)value, 1);
388 }
389
390 int
391 CBB_add_u16(CBB *cbb, size_t value)
392 {
393         if (value > UINT16_MAX)
394                 return 0;
395
396         return cbb_add_u(cbb, (uint32_t)value, 2);
397 }
398
399 int
400 CBB_add_u24(CBB *cbb, size_t value)
401 {
402         if (value > 0xffffffUL)
403                 return 0;
404
405         return cbb_add_u(cbb, (uint32_t)value, 3);
406 }
407
408 int
409 CBB_add_u32(CBB *cbb, size_t value)
410 {
411         if (value > 0xffffffffUL)
412                 return 0;
413
414         return cbb_add_u(cbb, (uint32_t)value, 4);
415 }
416
417 int
418 CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
419 {
420         CBB child;
421         size_t i;
422         int started = 0;
423
424         if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
425                 return 0;
426
427         for (i = 0; i < 8; i++) {
428                 uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
429
430                 /*
431                  * ASN.1 restriction: first 9 bits cannot be all zeroes or
432                  * all ones.  Since this function only encodes unsigned
433                  * integers, the only concerns are not encoding leading
434                  * zeros and adding a padding byte if necessary.
435                  *
436                  * In practice, this means:
437                  * 1) Skip leading octets of all zero bits in the value
438                  * 2) After skipping the leading zero octets, if the next 9
439                  *    bits are all ones, add an all zero prefix octet (and
440                  *    set the high bit of the prefix octet if negative).
441                  *
442                  * Additionally, for an unsigned value, add an all zero
443                  * prefix if the high bit of the first octet would be one.
444                  */
445                 if (!started) {
446                         if (byte == 0)
447                                 /* Don't encode leading zeros. */
448                                 continue;
449
450                         /*
451                          * If the high bit is set, add a padding byte to make it
452                          * unsigned.
453                          */
454                         if ((byte & 0x80) && !CBB_add_u8(&child, 0))
455                                 return 0;
456
457                         started = 1;
458                 }
459                 if (!CBB_add_u8(&child, byte))
460                         return 0;
461         }
462
463         /* 0 is encoded as a single 0, not the empty string. */
464         if (!started && !CBB_add_u8(&child, 0))
465                 return 0;
466
467         return CBB_flush(cbb);
468 }