Coverage Report

Created: 2026-10-27 07:01

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