xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/bytestring/cbb.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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