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 <limits.h>
19 #include <string.h>
20
21 #include <openssl/mem.h>
22 #include <openssl/err.h>
23
24 #include "../internal.h"
25
26
CBB_zero(CBB * cbb)27 void CBB_zero(CBB *cbb) {
28 OPENSSL_memset(cbb, 0, sizeof(CBB));
29 }
30
cbb_init(CBB * cbb,uint8_t * buf,size_t cap,int can_resize)31 static void cbb_init(CBB *cbb, uint8_t *buf, size_t cap, int can_resize) {
32 cbb->is_child = 0;
33 cbb->child = NULL;
34 cbb->u.base.buf = buf;
35 cbb->u.base.len = 0;
36 cbb->u.base.cap = cap;
37 cbb->u.base.can_resize = can_resize;
38 cbb->u.base.error = 0;
39 }
40
CBB_init(CBB * cbb,size_t initial_capacity)41 int CBB_init(CBB *cbb, size_t initial_capacity) {
42 CBB_zero(cbb);
43
44 uint8_t *buf = OPENSSL_malloc(initial_capacity);
45 if (initial_capacity > 0 && buf == NULL) {
46 return 0;
47 }
48
49 cbb_init(cbb, buf, initial_capacity, /*can_resize=*/1);
50 return 1;
51 }
52
CBB_init_fixed(CBB * cbb,uint8_t * buf,size_t len)53 int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
54 CBB_zero(cbb);
55 cbb_init(cbb, buf, len, /*can_resize=*/0);
56 return 1;
57 }
58
CBB_cleanup(CBB * cbb)59 void CBB_cleanup(CBB *cbb) {
60 // Child |CBB|s are non-owning. They are implicitly discarded and should not
61 // be used with |CBB_cleanup| or |ScopedCBB|.
62 assert(!cbb->is_child);
63 if (cbb->is_child) {
64 return;
65 }
66
67 if (cbb->u.base.can_resize) {
68 OPENSSL_free(cbb->u.base.buf);
69 }
70 }
71
cbb_buffer_reserve(struct cbb_buffer_st * base,uint8_t ** out,size_t len)72 static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
73 size_t len) {
74 if (base == NULL) {
75 return 0;
76 }
77
78 size_t newlen = base->len + len;
79 if (newlen < base->len) {
80 // Overflow
81 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
82 goto err;
83 }
84
85 if (newlen > base->cap) {
86 if (!base->can_resize) {
87 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
88 goto err;
89 }
90
91 size_t newcap = base->cap * 2;
92 if (newcap < base->cap || newcap < newlen) {
93 newcap = newlen;
94 }
95 uint8_t *newbuf = OPENSSL_realloc(base->buf, newcap);
96 if (newbuf == NULL) {
97 goto err;
98 }
99
100 base->buf = newbuf;
101 base->cap = newcap;
102 }
103
104 if (out) {
105 *out = base->buf + base->len;
106 }
107
108 return 1;
109
110 err:
111 base->error = 1;
112 return 0;
113 }
114
cbb_buffer_add(struct cbb_buffer_st * base,uint8_t ** out,size_t len)115 static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
116 size_t len) {
117 if (!cbb_buffer_reserve(base, out, len)) {
118 return 0;
119 }
120 // This will not overflow or |cbb_buffer_reserve| would have failed.
121 base->len += len;
122 return 1;
123 }
124
CBB_finish(CBB * cbb,uint8_t ** out_data,size_t * out_len)125 int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) {
126 if (cbb->is_child) {
127 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
128 return 0;
129 }
130
131 if (!CBB_flush(cbb)) {
132 return 0;
133 }
134
135 if (cbb->u.base.can_resize && (out_data == NULL || out_len == NULL)) {
136 // |out_data| and |out_len| can only be NULL if the CBB is fixed.
137 return 0;
138 }
139
140 if (out_data != NULL) {
141 *out_data = cbb->u.base.buf;
142 }
143 if (out_len != NULL) {
144 *out_len = cbb->u.base.len;
145 }
146 cbb->u.base.buf = NULL;
147 CBB_cleanup(cbb);
148 return 1;
149 }
150
cbb_get_base(CBB * cbb)151 static struct cbb_buffer_st *cbb_get_base(CBB *cbb) {
152 if (cbb->is_child) {
153 return cbb->u.child.base;
154 }
155 return &cbb->u.base;
156 }
157
cbb_on_error(CBB * cbb)158 static void cbb_on_error(CBB *cbb) {
159 // Due to C's lack of destructors and |CBB|'s auto-flushing API, a failing
160 // |CBB|-taking function may leave a dangling pointer to a child |CBB|. As a
161 // result, the convention is callers may not write to |CBB|s that have failed.
162 // But, as a safety measure, we lock the |CBB| into an error state. Once the
163 // error bit is set, |cbb->child| will not be read.
164 //
165 // TODO(davidben): This still isn't quite ideal. A |CBB| function *outside*
166 // this file may originate an error while the |CBB| points to a local child.
167 // In that case we don't set the error bit and are reliant on the error
168 // convention. Perhaps we allow |CBB_cleanup| on child |CBB|s and make every
169 // child's |CBB_cleanup| set the error bit if unflushed. That will be
170 // convenient for C++ callers, but very tedious for C callers. So C callers
171 // perhaps should get a |CBB_on_error| function that can be, less tediously,
172 // stuck in a |goto err| block.
173 cbb_get_base(cbb)->error = 1;
174
175 // Clearing the pointer is not strictly necessary, but GCC's dangling pointer
176 // warning does not know |cbb->child| will not be read once |error| is set
177 // above.
178 cbb->child = NULL;
179 }
180
181 // CBB_flush recurses and then writes out any pending length prefix. The
182 // current length of the underlying base is taken to be the length of the
183 // length-prefixed data.
CBB_flush(CBB * cbb)184 int CBB_flush(CBB *cbb) {
185 // If |base| has hit an error, the buffer is in an undefined state, so
186 // fail all following calls. In particular, |cbb->child| may point to invalid
187 // memory.
188 struct cbb_buffer_st *base = cbb_get_base(cbb);
189 if (base == NULL || base->error) {
190 return 0;
191 }
192
193 if (cbb->child == NULL) {
194 // Nothing to flush.
195 return 1;
196 }
197
198 assert(cbb->child->is_child);
199 struct cbb_child_st *child = &cbb->child->u.child;
200 assert(child->base == base);
201 size_t child_start = child->offset + child->pending_len_len;
202
203 if (!CBB_flush(cbb->child) ||
204 child_start < child->offset ||
205 base->len < child_start) {
206 goto err;
207 }
208
209 size_t len = base->len - child_start;
210
211 if (child->pending_is_asn1) {
212 // For ASN.1 we assume that we'll only need a single byte for the length.
213 // If that turned out to be incorrect, we have to move the contents along
214 // in order to make space.
215 uint8_t len_len;
216 uint8_t initial_length_byte;
217
218 assert (child->pending_len_len == 1);
219
220 if (len > 0xfffffffe) {
221 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
222 // Too large.
223 goto err;
224 } else if (len > 0xffffff) {
225 len_len = 5;
226 initial_length_byte = 0x80 | 4;
227 } else if (len > 0xffff) {
228 len_len = 4;
229 initial_length_byte = 0x80 | 3;
230 } else if (len > 0xff) {
231 len_len = 3;
232 initial_length_byte = 0x80 | 2;
233 } else if (len > 0x7f) {
234 len_len = 2;
235 initial_length_byte = 0x80 | 1;
236 } else {
237 len_len = 1;
238 initial_length_byte = (uint8_t)len;
239 len = 0;
240 }
241
242 if (len_len != 1) {
243 // We need to move the contents along in order to make space.
244 size_t extra_bytes = len_len - 1;
245 if (!cbb_buffer_add(base, NULL, extra_bytes)) {
246 goto err;
247 }
248 OPENSSL_memmove(base->buf + child_start + extra_bytes,
249 base->buf + child_start, len);
250 }
251 base->buf[child->offset++] = initial_length_byte;
252 child->pending_len_len = len_len - 1;
253 }
254
255 for (size_t i = child->pending_len_len - 1; i < child->pending_len_len; i--) {
256 base->buf[child->offset + i] = (uint8_t)len;
257 len >>= 8;
258 }
259 if (len != 0) {
260 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
261 goto err;
262 }
263
264 child->base = NULL;
265 cbb->child = NULL;
266
267 return 1;
268
269 err:
270 cbb_on_error(cbb);
271 return 0;
272 }
273
CBB_data(const CBB * cbb)274 const uint8_t *CBB_data(const CBB *cbb) {
275 assert(cbb->child == NULL);
276 if (cbb->is_child) {
277 return cbb->u.child.base->buf + cbb->u.child.offset +
278 cbb->u.child.pending_len_len;
279 }
280 return cbb->u.base.buf;
281 }
282
CBB_len(const CBB * cbb)283 size_t CBB_len(const CBB *cbb) {
284 assert(cbb->child == NULL);
285 if (cbb->is_child) {
286 assert(cbb->u.child.offset + cbb->u.child.pending_len_len <=
287 cbb->u.child.base->len);
288 return cbb->u.child.base->len - cbb->u.child.offset -
289 cbb->u.child.pending_len_len;
290 }
291 return cbb->u.base.len;
292 }
293
cbb_add_child(CBB * cbb,CBB * out_child,uint8_t len_len,int is_asn1)294 static int cbb_add_child(CBB *cbb, CBB *out_child, uint8_t len_len,
295 int is_asn1) {
296 assert(cbb->child == NULL);
297 assert(!is_asn1 || len_len == 1);
298 struct cbb_buffer_st *base = cbb_get_base(cbb);
299 size_t offset = base->len;
300
301 // Reserve space for the length prefix.
302 uint8_t *prefix_bytes;
303 if (!cbb_buffer_add(base, &prefix_bytes, len_len)) {
304 return 0;
305 }
306 OPENSSL_memset(prefix_bytes, 0, len_len);
307
308 CBB_zero(out_child);
309 out_child->is_child = 1;
310 out_child->u.child.base = base;
311 out_child->u.child.offset = offset;
312 out_child->u.child.pending_len_len = len_len;
313 out_child->u.child.pending_is_asn1 = is_asn1;
314 cbb->child = out_child;
315 return 1;
316 }
317
cbb_add_length_prefixed(CBB * cbb,CBB * out_contents,uint8_t len_len)318 static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
319 uint8_t len_len) {
320 if (!CBB_flush(cbb)) {
321 return 0;
322 }
323
324 return cbb_add_child(cbb, out_contents, len_len, /*is_asn1=*/0);
325 }
326
CBB_add_u8_length_prefixed(CBB * cbb,CBB * out_contents)327 int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) {
328 return cbb_add_length_prefixed(cbb, out_contents, 1);
329 }
330
CBB_add_u16_length_prefixed(CBB * cbb,CBB * out_contents)331 int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) {
332 return cbb_add_length_prefixed(cbb, out_contents, 2);
333 }
334
CBB_add_u24_length_prefixed(CBB * cbb,CBB * out_contents)335 int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
336 return cbb_add_length_prefixed(cbb, out_contents, 3);
337 }
338
339 // add_base128_integer encodes |v| as a big-endian base-128 integer where the
340 // high bit of each byte indicates where there is more data. This is the
341 // encoding used in DER for both high tag number form and OID components.
add_base128_integer(CBB * cbb,uint64_t v)342 static int add_base128_integer(CBB *cbb, uint64_t v) {
343 unsigned len_len = 0;
344 uint64_t copy = v;
345 while (copy > 0) {
346 len_len++;
347 copy >>= 7;
348 }
349 if (len_len == 0) {
350 len_len = 1; // Zero is encoded with one byte.
351 }
352 for (unsigned i = len_len - 1; i < len_len; i--) {
353 uint8_t byte = (v >> (7 * i)) & 0x7f;
354 if (i != 0) {
355 // The high bit denotes whether there is more data.
356 byte |= 0x80;
357 }
358 if (!CBB_add_u8(cbb, byte)) {
359 return 0;
360 }
361 }
362 return 1;
363 }
364
CBB_add_asn1(CBB * cbb,CBB * out_contents,CBS_ASN1_TAG tag)365 int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag) {
366 if (!CBB_flush(cbb)) {
367 return 0;
368 }
369
370 // Split the tag into leading bits and tag number.
371 uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0;
372 CBS_ASN1_TAG tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK;
373 if (tag_number >= 0x1f) {
374 // Set all the bits in the tag number to signal high tag number form.
375 if (!CBB_add_u8(cbb, tag_bits | 0x1f) ||
376 !add_base128_integer(cbb, tag_number)) {
377 return 0;
378 }
379 } else if (!CBB_add_u8(cbb, tag_bits | tag_number)) {
380 return 0;
381 }
382
383 // Reserve one byte of length prefix. |CBB_flush| will finish it later.
384 return cbb_add_child(cbb, out_contents, /*len_len=*/1, /*is_asn1=*/1);
385 }
386
CBB_add_bytes(CBB * cbb,const uint8_t * data,size_t len)387 int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
388 uint8_t *out;
389 if (!CBB_add_space(cbb, &out, len)) {
390 return 0;
391 }
392 OPENSSL_memcpy(out, data, len);
393 return 1;
394 }
395
CBB_add_zeros(CBB * cbb,size_t len)396 int CBB_add_zeros(CBB *cbb, size_t len) {
397 uint8_t *out;
398 if (!CBB_add_space(cbb, &out, len)) {
399 return 0;
400 }
401 OPENSSL_memset(out, 0, len);
402 return 1;
403 }
404
CBB_add_space(CBB * cbb,uint8_t ** out_data,size_t len)405 int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
406 if (!CBB_flush(cbb) ||
407 !cbb_buffer_add(cbb_get_base(cbb), out_data, len)) {
408 return 0;
409 }
410 return 1;
411 }
412
CBB_reserve(CBB * cbb,uint8_t ** out_data,size_t len)413 int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) {
414 if (!CBB_flush(cbb) ||
415 !cbb_buffer_reserve(cbb_get_base(cbb), out_data, len)) {
416 return 0;
417 }
418 return 1;
419 }
420
CBB_did_write(CBB * cbb,size_t len)421 int CBB_did_write(CBB *cbb, size_t len) {
422 struct cbb_buffer_st *base = cbb_get_base(cbb);
423 size_t newlen = base->len + len;
424 if (cbb->child != NULL ||
425 newlen < base->len ||
426 newlen > base->cap) {
427 return 0;
428 }
429 base->len = newlen;
430 return 1;
431 }
432
cbb_add_u(CBB * cbb,uint64_t v,size_t len_len)433 static int cbb_add_u(CBB *cbb, uint64_t v, size_t len_len) {
434 uint8_t *buf;
435 if (!CBB_add_space(cbb, &buf, len_len)) {
436 return 0;
437 }
438
439 for (size_t i = len_len - 1; i < len_len; i--) {
440 buf[i] = v;
441 v >>= 8;
442 }
443
444 // |v| must fit in |len_len| bytes.
445 if (v != 0) {
446 cbb_on_error(cbb);
447 return 0;
448 }
449
450 return 1;
451 }
452
CBB_add_u8(CBB * cbb,uint8_t value)453 int CBB_add_u8(CBB *cbb, uint8_t value) {
454 return cbb_add_u(cbb, value, 1);
455 }
456
CBB_add_u16(CBB * cbb,uint16_t value)457 int CBB_add_u16(CBB *cbb, uint16_t value) {
458 return cbb_add_u(cbb, value, 2);
459 }
460
CBB_add_u16le(CBB * cbb,uint16_t value)461 int CBB_add_u16le(CBB *cbb, uint16_t value) {
462 return CBB_add_u16(cbb, CRYPTO_bswap2(value));
463 }
464
CBB_add_u24(CBB * cbb,uint32_t value)465 int CBB_add_u24(CBB *cbb, uint32_t value) {
466 return cbb_add_u(cbb, value, 3);
467 }
468
CBB_add_u32(CBB * cbb,uint32_t value)469 int CBB_add_u32(CBB *cbb, uint32_t value) {
470 return cbb_add_u(cbb, value, 4);
471 }
472
CBB_add_u32le(CBB * cbb,uint32_t value)473 int CBB_add_u32le(CBB *cbb, uint32_t value) {
474 return CBB_add_u32(cbb, CRYPTO_bswap4(value));
475 }
476
CBB_add_u64(CBB * cbb,uint64_t value)477 int CBB_add_u64(CBB *cbb, uint64_t value) {
478 return cbb_add_u(cbb, value, 8);
479 }
480
CBB_add_u64le(CBB * cbb,uint64_t value)481 int CBB_add_u64le(CBB *cbb, uint64_t value) {
482 return CBB_add_u64(cbb, CRYPTO_bswap8(value));
483 }
484
CBB_discard_child(CBB * cbb)485 void CBB_discard_child(CBB *cbb) {
486 if (cbb->child == NULL) {
487 return;
488 }
489
490 struct cbb_buffer_st *base = cbb_get_base(cbb);
491 assert(cbb->child->is_child);
492 base->len = cbb->child->u.child.offset;
493
494 cbb->child->u.child.base = NULL;
495 cbb->child = NULL;
496 }
497
CBB_add_asn1_uint64(CBB * cbb,uint64_t value)498 int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
499 return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER);
500 }
501
CBB_add_asn1_uint64_with_tag(CBB * cbb,uint64_t value,CBS_ASN1_TAG tag)502 int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, CBS_ASN1_TAG tag) {
503 CBB child;
504 if (!CBB_add_asn1(cbb, &child, tag)) {
505 goto err;
506 }
507
508 int started = 0;
509 for (size_t i = 0; i < 8; i++) {
510 uint8_t byte = (value >> 8*(7-i)) & 0xff;
511 if (!started) {
512 if (byte == 0) {
513 // Don't encode leading zeros.
514 continue;
515 }
516 // If the high bit is set, add a padding byte to make it
517 // unsigned.
518 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) {
519 goto err;
520 }
521 started = 1;
522 }
523 if (!CBB_add_u8(&child, byte)) {
524 goto err;
525 }
526 }
527
528 // 0 is encoded as a single 0, not the empty string.
529 if (!started && !CBB_add_u8(&child, 0)) {
530 goto err;
531 }
532
533 return CBB_flush(cbb);
534
535 err:
536 cbb_on_error(cbb);
537 return 0;
538 }
539
CBB_add_asn1_int64(CBB * cbb,int64_t value)540 int CBB_add_asn1_int64(CBB *cbb, int64_t value) {
541 return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER);
542 }
543
CBB_add_asn1_int64_with_tag(CBB * cbb,int64_t value,CBS_ASN1_TAG tag)544 int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, CBS_ASN1_TAG tag) {
545 if (value >= 0) {
546 return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag);
547 }
548
549 uint8_t bytes[sizeof(int64_t)];
550 memcpy(bytes, &value, sizeof(value));
551 int start = 7;
552 // Skip leading sign-extension bytes unless they are necessary.
553 while (start > 0 && (bytes[start] == 0xff && (bytes[start - 1] & 0x80))) {
554 start--;
555 }
556
557 CBB child;
558 if (!CBB_add_asn1(cbb, &child, tag)) {
559 goto err;
560 }
561 for (int i = start; i >= 0; i--) {
562 if (!CBB_add_u8(&child, bytes[i])) {
563 goto err;
564 }
565 }
566 return CBB_flush(cbb);
567
568 err:
569 cbb_on_error(cbb);
570 return 0;
571 }
572
CBB_add_asn1_octet_string(CBB * cbb,const uint8_t * data,size_t data_len)573 int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) {
574 CBB child;
575 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) ||
576 !CBB_add_bytes(&child, data, data_len) ||
577 !CBB_flush(cbb)) {
578 cbb_on_error(cbb);
579 return 0;
580 }
581
582 return 1;
583 }
584
CBB_add_asn1_bool(CBB * cbb,int value)585 int CBB_add_asn1_bool(CBB *cbb, int value) {
586 CBB child;
587 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) ||
588 !CBB_add_u8(&child, value != 0 ? 0xff : 0) ||
589 !CBB_flush(cbb)) {
590 cbb_on_error(cbb);
591 return 0;
592 }
593
594 return 1;
595 }
596
597 // parse_dotted_decimal parses one decimal component from |cbs|, where |cbs| is
598 // an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the
599 // component and the dot, so |cbs| may be passed into the function again for the
600 // next value.
parse_dotted_decimal(CBS * cbs,uint64_t * out)601 static int parse_dotted_decimal(CBS *cbs, uint64_t *out) {
602 if (!CBS_get_u64_decimal(cbs, out)) {
603 return 0;
604 }
605
606 // The integer must have either ended at the end of the string, or a
607 // non-terminal dot, which should be consumed. If the string ends with a dot,
608 // this is not a valid OID string.
609 uint8_t dot;
610 return !CBS_get_u8(cbs, &dot) || (dot == '.' && CBS_len(cbs) > 0);
611 }
612
CBB_add_asn1_oid_from_text(CBB * cbb,const char * text,size_t len)613 int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) {
614 if (!CBB_flush(cbb)) {
615 return 0;
616 }
617
618 CBS cbs;
619 CBS_init(&cbs, (const uint8_t *)text, len);
620
621 // OIDs must have at least two components.
622 uint64_t a, b;
623 if (!parse_dotted_decimal(&cbs, &a) ||
624 !parse_dotted_decimal(&cbs, &b)) {
625 return 0;
626 }
627
628 // The first component is encoded as 40 * |a| + |b|. This assumes that |a| is
629 // 0, 1, or 2 and that, when it is 0 or 1, |b| is at most 39.
630 if (a > 2 ||
631 (a < 2 && b > 39) ||
632 b > UINT64_MAX - 80 ||
633 !add_base128_integer(cbb, 40u * a + b)) {
634 return 0;
635 }
636
637 // The remaining components are encoded unmodified.
638 while (CBS_len(&cbs) > 0) {
639 if (!parse_dotted_decimal(&cbs, &a) ||
640 !add_base128_integer(cbb, a)) {
641 return 0;
642 }
643 }
644
645 return 1;
646 }
647
compare_set_of_element(const void * a_ptr,const void * b_ptr)648 static int compare_set_of_element(const void *a_ptr, const void *b_ptr) {
649 // See X.690, section 11.6 for the ordering. They are sorted in ascending
650 // order by their DER encoding.
651 const CBS *a = a_ptr, *b = b_ptr;
652 size_t a_len = CBS_len(a), b_len = CBS_len(b);
653 size_t min_len = a_len < b_len ? a_len : b_len;
654 int ret = OPENSSL_memcmp(CBS_data(a), CBS_data(b), min_len);
655 if (ret != 0) {
656 return ret;
657 }
658 if (a_len == b_len) {
659 return 0;
660 }
661 // If one is a prefix of the other, the shorter one sorts first. (This is not
662 // actually reachable. No DER encoding is a prefix of another DER encoding.)
663 return a_len < b_len ? -1 : 1;
664 }
665
CBB_flush_asn1_set_of(CBB * cbb)666 int CBB_flush_asn1_set_of(CBB *cbb) {
667 if (!CBB_flush(cbb)) {
668 return 0;
669 }
670
671 CBS cbs;
672 size_t num_children = 0;
673 CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb));
674 while (CBS_len(&cbs) != 0) {
675 if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) {
676 OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
677 return 0;
678 }
679 num_children++;
680 }
681
682 if (num_children < 2) {
683 return 1; // Nothing to do. This is the common case for X.509.
684 }
685
686 // Parse out the children and sort. We alias them into a copy of so they
687 // remain valid as we rewrite |cbb|.
688 int ret = 0;
689 size_t buf_len = CBB_len(cbb);
690 uint8_t *buf = OPENSSL_memdup(CBB_data(cbb), buf_len);
691 CBS *children = OPENSSL_calloc(num_children, sizeof(CBS));
692 if (buf == NULL || children == NULL) {
693 goto err;
694 }
695 CBS_init(&cbs, buf, buf_len);
696 for (size_t i = 0; i < num_children; i++) {
697 if (!CBS_get_any_asn1_element(&cbs, &children[i], NULL, NULL)) {
698 goto err;
699 }
700 }
701 qsort(children, num_children, sizeof(CBS), compare_set_of_element);
702
703 // Write the contents back in the new order.
704 uint8_t *out = (uint8_t *)CBB_data(cbb);
705 size_t offset = 0;
706 for (size_t i = 0; i < num_children; i++) {
707 OPENSSL_memcpy(out + offset, CBS_data(&children[i]), CBS_len(&children[i]));
708 offset += CBS_len(&children[i]);
709 }
710 assert(offset == buf_len);
711
712 ret = 1;
713
714 err:
715 OPENSSL_free(buf);
716 OPENSSL_free(children);
717 return ret;
718 }
719