Coverage Report

Created: 2026-08-28 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/asn1_gen.cc
Line
Count
Source
1
// Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
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/x509.h>
16
17
#include <assert.h>
18
#include <ctype.h>
19
#include <limits.h>
20
#include <string.h>
21
22
#include <openssl/asn1.h>
23
#include <openssl/bytestring.h>
24
#include <openssl/err.h>
25
#include <openssl/obj.h>
26
27
#include "../conf/internal.h"
28
#include "../internal.h"
29
#include "internal.h"
30
31
32
using namespace bssl;
33
34
// Although this file is in crypto/x509 for layering purposes, it emits
35
// errors from the ASN.1 module for OpenSSL compatibility.
36
37
// ASN1_GEN_MAX_DEPTH is the maximum number of nested TLVs allowed.
38
525k
#define ASN1_GEN_MAX_DEPTH 50
39
40
// ASN1_GEN_MAX_OUTPUT is the maximum output, in bytes, allowed. This limit is
41
// necessary because the SEQUENCE and SET section reference mechanism allows the
42
// output length to grow super-linearly with the input length.
43
745k
#define ASN1_GEN_MAX_OUTPUT (64 * 1024)
44
45
// ASN1_GEN_FORMAT_* are the values for the format modifiers.
46
795k
#define ASN1_GEN_FORMAT_ASCII 1
47
2.69k
#define ASN1_GEN_FORMAT_UTF8 2
48
687
#define ASN1_GEN_FORMAT_HEX 3
49
3.92k
#define ASN1_GEN_FORMAT_BITLIST 4
50
51
// generate_v3 converts `str` into an ASN.1 structure and writes the result to
52
// `cbb`. It returns one on success and zero on error. `depth` bounds recursion,
53
// and `format` specifies the current format modifier.
54
//
55
// If `tag` is non-zero, the structure is implicitly tagged with `tag`. `tag`
56
// must not have the constructed bit set.
57
static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf,
58
                       CBS_ASN1_TAG tag, int format, int depth);
59
60
static int bitstr_cb(const char *elem, size_t len, void *bitstr);
61
62
55.3k
ASN1_TYPE *bssl::ASN1_generate_v3(const char *str, const X509V3_CTX *cnf) {
63
55.3k
  ScopedCBB cbb;
64
55.3k
  if (!CBB_init(cbb.get(), 0) ||  //
65
55.3k
      !generate_v3(cbb.get(), str, cnf, /*tag=*/0, ASN1_GEN_FORMAT_ASCII,
66
55.3k
                   /*depth=*/0)) {
67
4.72k
    return nullptr;
68
4.72k
  }
69
70
  // While not strictly necessary to avoid a DoS (we rely on any super-linear
71
  // checks being performed internally), cap the overall output to
72
  // `ASN1_GEN_MAX_OUTPUT` so the externally-visible behavior is consistent.
73
50.5k
  if (CBB_len(cbb.get()) > ASN1_GEN_MAX_OUTPUT) {
74
7
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
75
7
    return nullptr;
76
7
  }
77
78
50.5k
  const uint8_t *der = CBB_data(cbb.get());
79
50.5k
  return d2i_ASN1_TYPE(nullptr, &der, CBB_len(cbb.get()));
80
50.5k
}
81
82
14.3M
static int cbs_str_equal(const CBS *cbs, const char *str) {
83
14.3M
  return CBS_len(cbs) == strlen(str) &&
84
3.36M
         OPENSSL_memcmp(CBS_data(cbs), str, strlen(str)) == 0;
85
14.3M
}
86
87
// parse_tag decodes a tag specifier in `cbs`. It returns the tag on success or
88
// zero on error.
89
11.2k
static CBS_ASN1_TAG parse_tag(const CBS *cbs) {
90
11.2k
  CBS copy = *cbs;
91
11.2k
  uint64_t num;
92
11.2k
  if (!CBS_get_u64_decimal(&copy, &num) || num > CBS_ASN1_TAG_NUMBER_MASK) {
93
127
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
94
127
    return 0;
95
127
  }
96
97
11.0k
  CBS_ASN1_TAG tag_class = CBS_ASN1_CONTEXT_SPECIFIC;
98
  // The tag may be suffixed by a class.
99
11.0k
  uint8_t c;
100
11.0k
  if (CBS_get_u8(&copy, &c)) {
101
6.03k
    switch (c) {
102
4.85k
      case 'U':
103
4.85k
        tag_class = CBS_ASN1_UNIVERSAL;
104
4.85k
        break;
105
394
      case 'A':
106
394
        tag_class = CBS_ASN1_APPLICATION;
107
394
        break;
108
392
      case 'P':
109
392
        tag_class = CBS_ASN1_PRIVATE;
110
392
        break;
111
396
      case 'C':
112
396
        tag_class = CBS_ASN1_CONTEXT_SPECIFIC;
113
396
        break;
114
3
      default: {
115
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
116
3
        return 0;
117
0
      }
118
6.03k
    }
119
6.03k
    if (CBS_len(&copy) != 0) {
120
17
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
121
17
      return 0;
122
17
    }
123
6.03k
  }
124
125
  // Tag [UNIVERSAL 0] is reserved for indefinite-length end-of-contents. We
126
  // also use zero in this file to indicator no explicit tagging.
127
11.0k
  if (tag_class == CBS_ASN1_UNIVERSAL && num == 0) {
128
5
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
129
5
    return 0;
130
5
  }
131
132
11.0k
  return tag_class | (CBS_ASN1_TAG)num;
133
11.0k
}
134
135
static int generate_wrapped(CBB *cbb, const char *str, const X509V3_CTX *cnf,
136
                            CBS_ASN1_TAG tag, int padding, int format,
137
8.72k
                            int depth) {
138
8.72k
  CBB child;
139
8.72k
  return CBB_add_asn1(cbb, &child, tag) &&
140
8.72k
         (!padding || CBB_add_u8(&child, 0)) &&
141
8.72k
         generate_v3(&child, str, cnf, /*tag=*/0, format, depth + 1) &&
142
4.90k
         CBB_flush(cbb);
143
8.72k
}
144
145
static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf,
146
525k
                       CBS_ASN1_TAG tag, int format, int depth) {
147
525k
  assert((tag & CBS_ASN1_CONSTRUCTED) == 0);
148
525k
  if (depth > ASN1_GEN_MAX_DEPTH) {
149
423
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
150
423
    return 0;
151
423
  }
152
153
  // Process modifiers. This function uses a mix of NUL-terminated strings and
154
  // `CBS`. Several functions only work with NUL-terminated strings, so we need
155
  // to keep track of when a slice spans the whole buffer.
156
535k
  for (;;) {
157
    // Skip whitespace.
158
1.11M
    while (*str != '\0' && OPENSSL_isspace((unsigned char)*str)) {
159
575k
      str++;
160
575k
    }
161
162
    // Modifiers end at commas.
163
535k
    const char *comma = strchr(str, ',');
164
535k
    if (comma == nullptr) {
165
381k
      break;
166
381k
    }
167
168
    // Remove trailing whitespace.
169
154k
    CBS modifier;
170
154k
    CBS_init(&modifier, (const uint8_t *)str, comma - str);
171
159k
    for (;;) {
172
159k
      uint8_t v;
173
159k
      CBS copy = modifier;
174
159k
      if (!CBS_get_last_u8(&copy, &v) || !OPENSSL_isspace(v)) {
175
154k
        break;
176
154k
      }
177
5.26k
      modifier = copy;
178
5.26k
    }
179
180
    // Advance the string past the modifier, but save the original value. We
181
    // will need to rewind if this is not a recognized modifier.
182
154k
    const char *str_old = str;
183
154k
    str = comma + 1;
184
185
    // Each modifier is either NAME:VALUE or NAME.
186
154k
    CBS name;
187
154k
    int has_value = CBS_get_until_first(&modifier, &name, ':');
188
154k
    if (has_value) {
189
150k
      CBS_skip(&modifier, 1);  // Skip the colon.
190
150k
    } else {
191
3.28k
      name = modifier;
192
3.28k
      CBS_init(&modifier, nullptr, 0);
193
3.28k
    }
194
195
154k
    if (cbs_str_equal(&name, "FORMAT") || cbs_str_equal(&name, "FORM")) {
196
3.80k
      if (cbs_str_equal(&modifier, "ASCII")) {
197
243
        format = ASN1_GEN_FORMAT_ASCII;
198
3.55k
      } else if (cbs_str_equal(&modifier, "UTF8")) {
199
1.55k
        format = ASN1_GEN_FORMAT_UTF8;
200
2.00k
      } else if (cbs_str_equal(&modifier, "HEX")) {
201
400
        format = ASN1_GEN_FORMAT_HEX;
202
1.60k
      } else if (cbs_str_equal(&modifier, "BITLIST")) {
203
1.50k
        format = ASN1_GEN_FORMAT_BITLIST;
204
1.50k
      } else {
205
105
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
206
105
        return 0;
207
105
      }
208
150k
    } else if (cbs_str_equal(&name, "IMP") ||
209
143k
               cbs_str_equal(&name, "IMPLICIT")) {
210
6.77k
      if (tag != 0) {
211
51
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
212
51
        return 0;
213
51
      }
214
6.72k
      tag = parse_tag(&modifier);
215
6.72k
      if (tag == 0) {
216
121
        return 0;
217
121
      }
218
143k
    } else if (cbs_str_equal(&name, "EXP") ||
219
139k
               cbs_str_equal(&name, "EXPLICIT")) {
220
      // It would actually be supportable, but OpenSSL does not allow wrapping
221
      // an explicit tag in an implicit tag.
222
4.52k
      if (tag != 0) {
223
49
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
224
49
        return 0;
225
49
      }
226
4.47k
      tag = parse_tag(&modifier);
227
4.47k
      return tag != 0 &&
228
4.44k
             generate_wrapped(cbb, str, cnf, tag | CBS_ASN1_CONSTRUCTED,
229
4.44k
                              /*padding=*/0, format, depth);
230
138k
    } else if (cbs_str_equal(&name, "OCTWRAP")) {
231
609
      tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag;
232
609
      return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
233
138k
    } else if (cbs_str_equal(&name, "BITWRAP")) {
234
1.94k
      tag = tag == 0 ? CBS_ASN1_BITSTRING : tag;
235
1.94k
      return generate_wrapped(cbb, str, cnf, tag, /*padding=*/1, format, depth);
236
136k
    } else if (cbs_str_equal(&name, "SEQWRAP")) {
237
600
      tag = tag == 0 ? CBS_ASN1_SEQUENCE : (tag | CBS_ASN1_CONSTRUCTED);
238
600
      tag |= CBS_ASN1_CONSTRUCTED;
239
600
      return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
240
135k
    } else if (cbs_str_equal(&name, "SETWRAP")) {
241
1.12k
      tag = tag == 0 ? CBS_ASN1_SET : (tag | CBS_ASN1_CONSTRUCTED);
242
1.12k
      return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
243
134k
    } else {
244
      // If this was not a recognized modifier, rewind `str` to before splitting
245
      // on the comma. The type itself consumes all remaining input.
246
134k
      str = str_old;
247
134k
      break;
248
134k
    }
249
154k
  }
250
251
  // The final element is, like modifiers, NAME:VALUE or NAME, but VALUE spans
252
  // the length of the string, including any commas.
253
516k
  const char *colon = strchr(str, ':');
254
516k
  CBS name;
255
516k
  const char *value;
256
516k
  int has_value = colon != nullptr;
257
516k
  if (has_value) {
258
495k
    CBS_init(&name, (const uint8_t *)str, colon - str);
259
495k
    value = colon + 1;
260
495k
  } else {
261
20.7k
    CBS_init(&name, (const uint8_t *)str, strlen(str));
262
20.7k
    value = "";  // Most types treat missing and empty value equivalently.
263
20.7k
  }
264
265
516k
  static const struct {
266
516k
    const char *name;
267
516k
    CBS_ASN1_TAG type;
268
516k
  } kTypes[] = {
269
516k
      {"BOOL", CBS_ASN1_BOOLEAN},
270
516k
      {"BOOLEAN", CBS_ASN1_BOOLEAN},
271
516k
      {"NULL", CBS_ASN1_NULL},
272
516k
      {"INT", CBS_ASN1_INTEGER},
273
516k
      {"INTEGER", CBS_ASN1_INTEGER},
274
516k
      {"ENUM", CBS_ASN1_ENUMERATED},
275
516k
      {"ENUMERATED", CBS_ASN1_ENUMERATED},
276
516k
      {"OID", CBS_ASN1_OBJECT},
277
516k
      {"OBJECT", CBS_ASN1_OBJECT},
278
516k
      {"UTCTIME", CBS_ASN1_UTCTIME},
279
516k
      {"UTC", CBS_ASN1_UTCTIME},
280
516k
      {"GENERALIZEDTIME", CBS_ASN1_GENERALIZEDTIME},
281
516k
      {"GENTIME", CBS_ASN1_GENERALIZEDTIME},
282
516k
      {"OCT", CBS_ASN1_OCTETSTRING},
283
516k
      {"OCTETSTRING", CBS_ASN1_OCTETSTRING},
284
516k
      {"BITSTR", CBS_ASN1_BITSTRING},
285
516k
      {"BITSTRING", CBS_ASN1_BITSTRING},
286
516k
      {"UNIVERSALSTRING", CBS_ASN1_UNIVERSALSTRING},
287
516k
      {"UNIV", CBS_ASN1_UNIVERSALSTRING},
288
516k
      {"IA5", CBS_ASN1_IA5STRING},
289
516k
      {"IA5STRING", CBS_ASN1_IA5STRING},
290
516k
      {"UTF8", CBS_ASN1_UTF8STRING},
291
516k
      {"UTF8String", CBS_ASN1_UTF8STRING},
292
516k
      {"BMP", CBS_ASN1_BMPSTRING},
293
516k
      {"BMPSTRING", CBS_ASN1_BMPSTRING},
294
516k
      {"PRINTABLESTRING", CBS_ASN1_PRINTABLESTRING},
295
516k
      {"PRINTABLE", CBS_ASN1_PRINTABLESTRING},
296
516k
      {"T61", CBS_ASN1_T61STRING},
297
516k
      {"T61STRING", CBS_ASN1_T61STRING},
298
516k
      {"TELETEXSTRING", CBS_ASN1_T61STRING},
299
516k
      {"SEQUENCE", CBS_ASN1_SEQUENCE},
300
516k
      {"SEQ", CBS_ASN1_SEQUENCE},
301
516k
      {"SET", CBS_ASN1_SET},
302
516k
  };
303
516k
  CBS_ASN1_TAG type = 0;
304
12.8M
  for (const auto &t : kTypes) {
305
12.8M
    if (cbs_str_equal(&name, t.name)) {
306
515k
      type = t.type;
307
515k
      break;
308
515k
    }
309
12.8M
  }
310
516k
  if (type == 0) {
311
1.08k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
312
1.08k
    return 0;
313
1.08k
  }
314
315
  // If there is an implicit tag, use the constructed bit from the base type.
316
515k
  tag = tag == 0 ? type : (tag | (type & CBS_ASN1_CONSTRUCTED));
317
515k
  CBB child;
318
515k
  if (!CBB_add_asn1(cbb, &child, tag)) {
319
0
    return 0;
320
0
  }
321
322
515k
  switch (type) {
323
2.66k
    case CBS_ASN1_NULL:
324
2.66k
      if (*value != '\0') {
325
8
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
326
8
        return 0;
327
8
      }
328
2.66k
      return CBB_flush(cbb);
329
330
3.24k
    case CBS_ASN1_BOOLEAN: {
331
3.24k
      if (format != ASN1_GEN_FORMAT_ASCII) {
332
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
333
3
        return 0;
334
3
      }
335
3.24k
      ASN1_BOOLEAN boolean;
336
3.24k
      if (!X509V3_bool_from_string(value, &boolean)) {
337
306
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
338
306
        return 0;
339
306
      }
340
2.93k
      return CBB_add_u8(&child, boolean ? 0xff : 0x00) && CBB_flush(cbb);
341
3.24k
    }
342
343
10.6k
    case CBS_ASN1_INTEGER:
344
11.0k
    case CBS_ASN1_ENUMERATED: {
345
11.0k
      if (format != ASN1_GEN_FORMAT_ASCII) {
346
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
347
3
        return 0;
348
3
      }
349
11.0k
      ASN1_INTEGER *obj = s2i_ASN1_INTEGER(nullptr, value);
350
11.0k
      if (obj == nullptr) {
351
282
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
352
282
        return 0;
353
282
      }
354
10.8k
      int len = i2c_ASN1_INTEGER(obj, nullptr);
355
10.8k
      uint8_t *out;
356
10.8k
      int ok = len > 0 &&  //
357
10.8k
               CBB_add_space(&child, &out, len) &&
358
10.8k
               i2c_ASN1_INTEGER(obj, &out) == len && CBB_flush(cbb);
359
10.8k
      ASN1_INTEGER_free(obj);
360
10.8k
      return ok;
361
11.0k
    }
362
363
1.74k
    case CBS_ASN1_OBJECT: {
364
1.74k
      if (format != ASN1_GEN_FORMAT_ASCII) {
365
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
366
3
        return 0;
367
3
      }
368
1.73k
      ASN1_OBJECT *obj = OBJ_txt2obj(value, /*dont_search_names=*/0);
369
1.73k
      if (obj == nullptr || obj->length == 0) {
370
73
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
371
73
        return 0;
372
73
      }
373
1.66k
      int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb);
374
1.66k
      ASN1_OBJECT_free(obj);
375
1.66k
      return ok;
376
1.73k
    }
377
378
3.75k
    case CBS_ASN1_UTCTIME:
379
4.25k
    case CBS_ASN1_GENERALIZEDTIME: {
380
4.25k
      if (format != ASN1_GEN_FORMAT_ASCII) {
381
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
382
3
        return 0;
383
3
      }
384
4.25k
      CBS value_cbs;
385
4.25k
      CBS_init(&value_cbs, (const uint8_t *)value, strlen(value));
386
4.25k
      int ok = type == CBS_ASN1_UTCTIME
387
4.25k
                   ? CBS_parse_utc_time(&value_cbs, nullptr,
388
3.75k
                                        /*allow_timezone_offset=*/0)
389
4.25k
                   : CBS_parse_generalized_time(&value_cbs, nullptr,
390
502
                                                /*allow_timezone_offset=*/0);
391
4.25k
      if (!ok) {
392
317
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
393
317
        return 0;
394
317
      }
395
3.93k
      return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) &&
396
3.93k
             CBB_flush(cbb);
397
4.25k
    }
398
399
215k
    case CBS_ASN1_UNIVERSALSTRING:
400
230k
    case CBS_ASN1_IA5STRING:
401
232k
    case CBS_ASN1_UTF8STRING:
402
243k
    case CBS_ASN1_BMPSTRING:
403
246k
    case CBS_ASN1_PRINTABLESTRING:
404
252k
    case CBS_ASN1_T61STRING: {
405
252k
      int encoding;
406
252k
      if (format == ASN1_GEN_FORMAT_ASCII) {
407
251k
        encoding = MBSTRING_ASC;
408
251k
      } else if (format == ASN1_GEN_FORMAT_UTF8) {
409
1.14k
        encoding = MBSTRING_UTF8;
410
1.14k
      } else {
411
3
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
412
3
        return 0;
413
3
      }
414
415
      // `maxsize` is measured in code points, rather than bytes, but pass it in
416
      // as a loose cap so fuzzers can exit from excessively long inputs
417
      // earlier. This limit is not load-bearing because `ASN1_mbstring_ncopy`'s
418
      // output is already linear in the input.
419
252k
      ASN1_STRING *obj = nullptr;
420
252k
      if (ASN1_mbstring_ncopy(&obj, (const uint8_t *)value, -1, encoding,
421
252k
                              ASN1_tag2bit(type), /*minsize=*/0,
422
252k
                              /*maxsize=*/ASN1_GEN_MAX_OUTPUT) <= 0) {
423
137
        return 0;
424
137
      }
425
252k
      int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb);
426
252k
      ASN1_STRING_free(obj);
427
252k
      return ok;
428
252k
    }
429
430
2.42k
    case CBS_ASN1_BITSTRING:
431
2.42k
      if (format == ASN1_GEN_FORMAT_BITLIST) {
432
1.45k
        ASN1_BIT_STRING *obj = ASN1_BIT_STRING_new();
433
1.45k
        if (obj == nullptr) {
434
0
          return 0;
435
0
        }
436
1.45k
        if (!CONF_parse_list(value, ',', 1, bitstr_cb, obj)) {
437
231
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
438
231
          ASN1_BIT_STRING_free(obj);
439
231
          return 0;
440
231
        }
441
1.22k
        int len = i2c_ASN1_BIT_STRING(obj, nullptr);
442
1.22k
        uint8_t *out;
443
1.22k
        int ok = len > 0 &&  //
444
1.22k
                 CBB_add_space(&child, &out, len) &&
445
1.22k
                 i2c_ASN1_BIT_STRING(obj, &out) == len &&  //
446
1.22k
                 CBB_flush(cbb);
447
1.22k
        ASN1_BIT_STRING_free(obj);
448
1.22k
        return ok;
449
1.45k
      }
450
451
      // The other formats are the same as OCTET STRING, but with the leading
452
      // zero bytes.
453
967
      if (!CBB_add_u8(&child, 0)) {
454
0
        return 0;
455
0
      }
456
967
      [[fallthrough]];
457
458
5.24k
    case CBS_ASN1_OCTETSTRING:
459
5.24k
      if (format == ASN1_GEN_FORMAT_ASCII) {
460
4.95k
        return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) &&
461
4.95k
               CBB_flush(cbb);
462
4.95k
      }
463
287
      if (format == ASN1_GEN_FORMAT_HEX) {
464
284
        size_t len;
465
284
        uint8_t *data = x509v3_hex_to_bytes(value, &len);
466
284
        if (data == nullptr) {
467
3
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
468
3
          return 0;
469
3
        }
470
281
        int ok = CBB_add_bytes(&child, data, len) && CBB_flush(cbb);
471
281
        OPENSSL_free(data);
472
281
        return ok;
473
284
      }
474
475
3
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
476
3
      return 0;
477
478
39.6k
    case CBS_ASN1_SEQUENCE:
479
233k
    case CBS_ASN1_SET:
480
233k
      if (has_value) {
481
228k
        if (cnf == nullptr) {
482
0
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
483
0
          return 0;
484
0
        }
485
228k
        const STACK_OF(CONF_VALUE) *section = X509V3_get_section(cnf, value);
486
228k
        if (section == nullptr) {
487
1.48k
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
488
1.48k
          return 0;
489
1.48k
        }
490
669k
        for (size_t i = 0; i < sk_CONF_VALUE_num(section); i++) {
491
461k
          const CONF_VALUE *conf = sk_CONF_VALUE_value(section, i);
492
461k
          if (!generate_v3(&child, conf->value, cnf, /*tag=*/0,
493
461k
                           ASN1_GEN_FORMAT_ASCII, depth + 1)) {
494
19.3k
            return 0;
495
19.3k
          }
496
          // This recursive call, by referencing `section`, is the one place
497
          // where `generate_v3`'s output can be super-linear in the input.
498
          // Check bounds here.
499
442k
          if (CBB_len(&child) > ASN1_GEN_MAX_OUTPUT) {
500
4
            OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
501
4
            return 0;
502
4
          }
503
442k
        }
504
227k
      }
505
212k
      if (type == CBS_ASN1_SET) {
506
        // The SET type here is a SET OF and must be sorted.
507
176k
        return CBB_flush_asn1_set_of(&child) && CBB_flush(cbb);
508
176k
      }
509
36.0k
      return CBB_flush(cbb);
510
511
0
    default:
512
0
      OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
513
0
      return 0;
514
515k
  }
515
515k
}
516
517
2.58k
static int bitstr_cb(const char *elem, size_t len, void *bitstr) {
518
2.58k
  CBS cbs;
519
2.58k
  CBS_init(&cbs, (const uint8_t *)elem, len);
520
2.58k
  uint64_t bitnum;
521
2.58k
  if (!CBS_get_u64_decimal(&cbs, &bitnum) || CBS_len(&cbs) != 0 ||
522
      // Cap the highest allowed bit so this mechanism cannot be used to create
523
      // extremely large allocations with short inputs. The highest named bit in
524
      // RFC 5280 is 8, so 256 should give comfortable margin but still only
525
      // allow a 32-byte allocation.
526
      //
527
      // We do not consider this function to be safe with untrusted inputs (even
528
      // without bugs, it is prone to string injection vulnerabilities), so DoS
529
      // is not truly a concern, but the limit is necessary to keep fuzzing
530
      // effective.
531
2.54k
      bitnum > 256) {
532
231
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
533
231
    return 0;
534
231
  }
535
2.35k
  if (!ASN1_BIT_STRING_set_bit(reinterpret_cast<ASN1_BIT_STRING *>(bitstr),
536
2.35k
                               (int)bitnum, 1)) {
537
0
    return 0;
538
0
  }
539
2.35k
  return 1;
540
2.35k
}