Coverage Report

Created: 2025-11-17 06:18

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