xref: /aosp_15_r20/external/boringssl/src/crypto/x509/asn1_gen.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson ([email protected]).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young ([email protected])"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson ([email protected])"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/x509.h>
58 
59 #include <assert.h>
60 #include <ctype.h>
61 #include <limits.h>
62 #include <string.h>
63 
64 #include <openssl/asn1.h>
65 #include <openssl/bytestring.h>
66 #include <openssl/err.h>
67 #include <openssl/obj.h>
68 
69 #include "../conf/internal.h"
70 #include "../internal.h"
71 #include "internal.h"
72 
73 
74 // Although this file is in crypto/x509 for layering purposes, it emits
75 // errors from the ASN.1 module for OpenSSL compatibility.
76 
77 // ASN1_GEN_MAX_DEPTH is the maximum number of nested TLVs allowed.
78 #define ASN1_GEN_MAX_DEPTH 50
79 
80 // ASN1_GEN_MAX_OUTPUT is the maximum output, in bytes, allowed. This limit is
81 // necessary because the SEQUENCE and SET section reference mechanism allows the
82 // output length to grow super-linearly with the input length.
83 #define ASN1_GEN_MAX_OUTPUT (64 * 1024)
84 
85 // ASN1_GEN_FORMAT_* are the values for the format modifiers.
86 #define ASN1_GEN_FORMAT_ASCII 1
87 #define ASN1_GEN_FORMAT_UTF8 2
88 #define ASN1_GEN_FORMAT_HEX 3
89 #define ASN1_GEN_FORMAT_BITLIST 4
90 
91 // generate_v3 converts |str| into an ASN.1 structure and writes the result to
92 // |cbb|. It returns one on success and zero on error. |depth| bounds recursion,
93 // and |format| specifies the current format modifier.
94 //
95 // If |tag| is non-zero, the structure is implicitly tagged with |tag|. |tag|
96 // must not have the constructed bit set.
97 static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf,
98                        CBS_ASN1_TAG tag, int format, int depth);
99 
100 static int bitstr_cb(const char *elem, size_t len, void *bitstr);
101 
ASN1_generate_v3(const char * str,const X509V3_CTX * cnf)102 ASN1_TYPE *ASN1_generate_v3(const char *str, const X509V3_CTX *cnf) {
103   CBB cbb;
104   if (!CBB_init(&cbb, 0) ||  //
105       !generate_v3(&cbb, str, cnf, /*tag=*/0, ASN1_GEN_FORMAT_ASCII,
106                    /*depth=*/0)) {
107     CBB_cleanup(&cbb);
108     return NULL;
109   }
110 
111   // While not strictly necessary to avoid a DoS (we rely on any super-linear
112   // checks being performed internally), cap the overall output to
113   // |ASN1_GEN_MAX_OUTPUT| so the externally-visible behavior is consistent.
114   if (CBB_len(&cbb) > ASN1_GEN_MAX_OUTPUT) {
115     OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
116     CBB_cleanup(&cbb);
117     return NULL;
118   }
119 
120   const uint8_t *der = CBB_data(&cbb);
121   ASN1_TYPE *ret = d2i_ASN1_TYPE(NULL, &der, CBB_len(&cbb));
122   CBB_cleanup(&cbb);
123   return ret;
124 }
125 
cbs_str_equal(const CBS * cbs,const char * str)126 static int cbs_str_equal(const CBS *cbs, const char *str) {
127   return CBS_len(cbs) == strlen(str) &&
128          OPENSSL_memcmp(CBS_data(cbs), str, strlen(str)) == 0;
129 }
130 
131 // parse_tag decodes a tag specifier in |cbs|. It returns the tag on success or
132 // zero on error.
parse_tag(const CBS * cbs)133 static CBS_ASN1_TAG parse_tag(const CBS *cbs) {
134   CBS copy = *cbs;
135   uint64_t num;
136   if (!CBS_get_u64_decimal(&copy, &num) ||
137       num > CBS_ASN1_TAG_NUMBER_MASK) {
138     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
139     return 0;
140   }
141 
142   CBS_ASN1_TAG tag_class = CBS_ASN1_CONTEXT_SPECIFIC;
143   // The tag may be suffixed by a class.
144   uint8_t c;
145   if (CBS_get_u8(&copy, &c)) {
146     switch (c) {
147       case 'U':
148         tag_class = CBS_ASN1_UNIVERSAL;
149         break;
150       case 'A':
151         tag_class = CBS_ASN1_APPLICATION;
152         break;
153       case 'P':
154         tag_class = CBS_ASN1_PRIVATE;
155         break;
156       case 'C':
157         tag_class = CBS_ASN1_CONTEXT_SPECIFIC;
158         break;
159       default: {
160         OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
161         return 0;
162       }
163     }
164     if (CBS_len(&copy) != 0) {
165       OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
166       return 0;
167     }
168   }
169 
170   // Tag [UNIVERSAL 0] is reserved for indefinite-length end-of-contents. We
171   // also use zero in this file to indicator no explicit tagging.
172   if (tag_class == CBS_ASN1_UNIVERSAL && num == 0) {
173     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
174     return 0;
175   }
176 
177   return tag_class | (CBS_ASN1_TAG)num;
178 }
179 
generate_wrapped(CBB * cbb,const char * str,const X509V3_CTX * cnf,CBS_ASN1_TAG tag,int padding,int format,int depth)180 static int generate_wrapped(CBB *cbb, const char *str, const X509V3_CTX *cnf,
181                             CBS_ASN1_TAG tag, int padding, int format,
182                             int depth) {
183   CBB child;
184   return CBB_add_asn1(cbb, &child, tag) &&
185          (!padding || CBB_add_u8(&child, 0)) &&
186          generate_v3(&child, str, cnf, /*tag=*/0, format, depth + 1) &&
187          CBB_flush(cbb);
188 }
189 
generate_v3(CBB * cbb,const char * str,const X509V3_CTX * cnf,CBS_ASN1_TAG tag,int format,int depth)190 static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf,
191                        CBS_ASN1_TAG tag, int format, int depth) {
192   assert((tag & CBS_ASN1_CONSTRUCTED) == 0);
193   if (depth > ASN1_GEN_MAX_DEPTH) {
194     OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
195     return 0;
196   }
197 
198   // Process modifiers. This function uses a mix of NUL-terminated strings and
199   // |CBS|. Several functions only work with NUL-terminated strings, so we need
200   // to keep track of when a slice spans the whole buffer.
201   for (;;) {
202     // Skip whitespace.
203     while (*str != '\0' && OPENSSL_isspace((unsigned char)*str)) {
204       str++;
205     }
206 
207     // Modifiers end at commas.
208     const char *comma = strchr(str, ',');
209     if (comma == NULL) {
210       break;
211     }
212 
213     // Remove trailing whitespace.
214     CBS modifier;
215     CBS_init(&modifier, (const uint8_t *)str, comma - str);
216     for (;;) {
217       uint8_t v;
218       CBS copy = modifier;
219       if (!CBS_get_last_u8(&copy, &v) || !OPENSSL_isspace(v)) {
220         break;
221       }
222       modifier = copy;
223     }
224 
225     // Advance the string past the modifier, but save the original value. We
226     // will need to rewind if this is not a recognized modifier.
227     const char *str_old = str;
228     str = comma + 1;
229 
230     // Each modifier is either NAME:VALUE or NAME.
231     CBS name;
232     int has_value = CBS_get_until_first(&modifier, &name, ':');
233     if (has_value) {
234       CBS_skip(&modifier, 1);  // Skip the colon.
235     } else {
236       name = modifier;
237       CBS_init(&modifier, NULL, 0);
238     }
239 
240     if (cbs_str_equal(&name, "FORMAT") || cbs_str_equal(&name, "FORM")) {
241       if (cbs_str_equal(&modifier, "ASCII")) {
242         format = ASN1_GEN_FORMAT_ASCII;
243       } else if (cbs_str_equal(&modifier, "UTF8")) {
244         format = ASN1_GEN_FORMAT_UTF8;
245       } else if (cbs_str_equal(&modifier, "HEX")) {
246         format = ASN1_GEN_FORMAT_HEX;
247       } else if (cbs_str_equal(&modifier, "BITLIST")) {
248         format = ASN1_GEN_FORMAT_BITLIST;
249       } else {
250         OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
251         return 0;
252       }
253     } else if (cbs_str_equal(&name, "IMP") ||
254                cbs_str_equal(&name, "IMPLICIT")) {
255       if (tag != 0) {
256         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
257         return 0;
258       }
259       tag = parse_tag(&modifier);
260       if (tag == 0) {
261         return 0;
262       }
263     } else if (cbs_str_equal(&name, "EXP") ||
264                cbs_str_equal(&name, "EXPLICIT")) {
265       // It would actually be supportable, but OpenSSL does not allow wrapping
266       // an explicit tag in an implicit tag.
267       if (tag != 0) {
268         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
269         return 0;
270       }
271       tag = parse_tag(&modifier);
272       return tag != 0 &&
273              generate_wrapped(cbb, str, cnf, tag | CBS_ASN1_CONSTRUCTED,
274                               /*padding=*/0, format, depth);
275     } else if (cbs_str_equal(&name, "OCTWRAP")) {
276       tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag;
277       return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
278     } else if (cbs_str_equal(&name, "BITWRAP")) {
279       tag = tag == 0 ? CBS_ASN1_BITSTRING : tag;
280       return generate_wrapped(cbb, str, cnf, tag, /*padding=*/1, format, depth);
281     } else if (cbs_str_equal(&name, "SEQWRAP")) {
282       tag = tag == 0 ? CBS_ASN1_SEQUENCE : (tag | CBS_ASN1_CONSTRUCTED);
283       tag |= CBS_ASN1_CONSTRUCTED;
284       return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
285     } else if (cbs_str_equal(&name, "SETWRAP")) {
286       tag = tag == 0 ? CBS_ASN1_SET : (tag | CBS_ASN1_CONSTRUCTED);
287       return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth);
288     } else {
289       // If this was not a recognized modifier, rewind |str| to before splitting
290       // on the comma. The type itself consumes all remaining input.
291       str = str_old;
292       break;
293     }
294   }
295 
296   // The final element is, like modifiers, NAME:VALUE or NAME, but VALUE spans
297   // the length of the string, including any commas.
298   const char *colon = strchr(str, ':');
299   CBS name;
300   const char *value;
301   int has_value = colon != NULL;
302   if (has_value) {
303     CBS_init(&name, (const uint8_t *)str, colon - str);
304     value = colon + 1;
305   } else {
306     CBS_init(&name, (const uint8_t *)str, strlen(str));
307     value = "";  // Most types treat missing and empty value equivalently.
308   }
309 
310   static const struct {
311     const char *name;
312     CBS_ASN1_TAG type;
313   } kTypes[] = {
314       {"BOOL", CBS_ASN1_BOOLEAN},
315       {"BOOLEAN", CBS_ASN1_BOOLEAN},
316       {"NULL", CBS_ASN1_NULL},
317       {"INT", CBS_ASN1_INTEGER},
318       {"INTEGER", CBS_ASN1_INTEGER},
319       {"ENUM", CBS_ASN1_ENUMERATED},
320       {"ENUMERATED", CBS_ASN1_ENUMERATED},
321       {"OID", CBS_ASN1_OBJECT},
322       {"OBJECT", CBS_ASN1_OBJECT},
323       {"UTCTIME", CBS_ASN1_UTCTIME},
324       {"UTC", CBS_ASN1_UTCTIME},
325       {"GENERALIZEDTIME", CBS_ASN1_GENERALIZEDTIME},
326       {"GENTIME", CBS_ASN1_GENERALIZEDTIME},
327       {"OCT", CBS_ASN1_OCTETSTRING},
328       {"OCTETSTRING", CBS_ASN1_OCTETSTRING},
329       {"BITSTR", CBS_ASN1_BITSTRING},
330       {"BITSTRING", CBS_ASN1_BITSTRING},
331       {"UNIVERSALSTRING", CBS_ASN1_UNIVERSALSTRING},
332       {"UNIV", CBS_ASN1_UNIVERSALSTRING},
333       {"IA5", CBS_ASN1_IA5STRING},
334       {"IA5STRING", CBS_ASN1_IA5STRING},
335       {"UTF8", CBS_ASN1_UTF8STRING},
336       {"UTF8String", CBS_ASN1_UTF8STRING},
337       {"BMP", CBS_ASN1_BMPSTRING},
338       {"BMPSTRING", CBS_ASN1_BMPSTRING},
339       {"PRINTABLESTRING", CBS_ASN1_PRINTABLESTRING},
340       {"PRINTABLE", CBS_ASN1_PRINTABLESTRING},
341       {"T61", CBS_ASN1_T61STRING},
342       {"T61STRING", CBS_ASN1_T61STRING},
343       {"TELETEXSTRING", CBS_ASN1_T61STRING},
344       {"SEQUENCE", CBS_ASN1_SEQUENCE},
345       {"SEQ", CBS_ASN1_SEQUENCE},
346       {"SET", CBS_ASN1_SET},
347   };
348   CBS_ASN1_TAG type = 0;
349   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTypes); i++) {
350     if (cbs_str_equal(&name, kTypes[i].name)) {
351       type = kTypes[i].type;
352       break;
353     }
354   }
355   if (type == 0) {
356     OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
357     return 0;
358   }
359 
360   // If there is an implicit tag, use the constructed bit from the base type.
361   tag = tag == 0 ? type : (tag | (type & CBS_ASN1_CONSTRUCTED));
362   CBB child;
363   if (!CBB_add_asn1(cbb, &child, tag)) {
364     return 0;
365   }
366 
367   switch (type) {
368     case CBS_ASN1_NULL:
369       if (*value != '\0') {
370         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
371         return 0;
372       }
373       return CBB_flush(cbb);
374 
375     case CBS_ASN1_BOOLEAN: {
376       if (format != ASN1_GEN_FORMAT_ASCII) {
377         OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
378         return 0;
379       }
380       ASN1_BOOLEAN boolean;
381       if (!X509V3_bool_from_string(value, &boolean)) {
382         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
383         return 0;
384       }
385       return CBB_add_u8(&child, boolean ? 0xff : 0x00) && CBB_flush(cbb);
386     }
387 
388     case CBS_ASN1_INTEGER:
389     case CBS_ASN1_ENUMERATED: {
390       if (format != ASN1_GEN_FORMAT_ASCII) {
391         OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
392         return 0;
393       }
394       ASN1_INTEGER *obj = s2i_ASN1_INTEGER(NULL, value);
395       if (obj == NULL) {
396         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
397         return 0;
398       }
399       int len = i2c_ASN1_INTEGER(obj, NULL);
400       uint8_t *out;
401       int ok = len > 0 &&  //
402                CBB_add_space(&child, &out, len) &&
403                i2c_ASN1_INTEGER(obj, &out) == len &&
404                CBB_flush(cbb);
405       ASN1_INTEGER_free(obj);
406       return ok;
407     }
408 
409     case CBS_ASN1_OBJECT: {
410       if (format != ASN1_GEN_FORMAT_ASCII) {
411         OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
412         return 0;
413       }
414       ASN1_OBJECT *obj = OBJ_txt2obj(value, /*dont_search_names=*/0);
415       if (obj == NULL || obj->length == 0) {
416         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
417         return 0;
418       }
419       int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb);
420       ASN1_OBJECT_free(obj);
421       return ok;
422     }
423 
424     case CBS_ASN1_UTCTIME:
425     case CBS_ASN1_GENERALIZEDTIME: {
426       if (format != ASN1_GEN_FORMAT_ASCII) {
427         OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
428         return 0;
429       }
430       CBS value_cbs;
431       CBS_init(&value_cbs, (const uint8_t*)value, strlen(value));
432       int ok = type == CBS_ASN1_UTCTIME
433                    ? CBS_parse_utc_time(&value_cbs, NULL,
434                                         /*allow_timezone_offset=*/0)
435                    : CBS_parse_generalized_time(&value_cbs, NULL,
436                                                 /*allow_timezone_offset=*/0);
437       if (!ok) {
438         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
439         return 0;
440       }
441       return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) &&
442              CBB_flush(cbb);
443     }
444 
445     case CBS_ASN1_UNIVERSALSTRING:
446     case CBS_ASN1_IA5STRING:
447     case CBS_ASN1_UTF8STRING:
448     case CBS_ASN1_BMPSTRING:
449     case CBS_ASN1_PRINTABLESTRING:
450     case CBS_ASN1_T61STRING: {
451       int encoding;
452       if (format == ASN1_GEN_FORMAT_ASCII) {
453         encoding = MBSTRING_ASC;
454       } else if (format == ASN1_GEN_FORMAT_UTF8) {
455         encoding = MBSTRING_UTF8;
456       } else {
457         OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
458         return 0;
459       }
460 
461       // |maxsize| is measured in code points, rather than bytes, but pass it in
462       // as a loose cap so fuzzers can exit from excessively long inputs
463       // earlier. This limit is not load-bearing because |ASN1_mbstring_ncopy|'s
464       // output is already linear in the input.
465       ASN1_STRING *obj = NULL;
466       if (ASN1_mbstring_ncopy(&obj, (const uint8_t *)value, -1, encoding,
467                               ASN1_tag2bit(type), /*minsize=*/0,
468                               /*maxsize=*/ASN1_GEN_MAX_OUTPUT) <= 0) {
469         return 0;
470       }
471       int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb);
472       ASN1_STRING_free(obj);
473       return ok;
474     }
475 
476     case CBS_ASN1_BITSTRING:
477       if (format == ASN1_GEN_FORMAT_BITLIST) {
478         ASN1_BIT_STRING *obj = ASN1_BIT_STRING_new();
479         if (obj == NULL) {
480           return 0;
481         }
482         if (!CONF_parse_list(value, ',', 1, bitstr_cb, obj)) {
483           OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
484           ASN1_BIT_STRING_free(obj);
485           return 0;
486         }
487         int len = i2c_ASN1_BIT_STRING(obj, NULL);
488         uint8_t *out;
489         int ok = len > 0 &&  //
490                  CBB_add_space(&child, &out, len) &&
491                  i2c_ASN1_BIT_STRING(obj, &out) == len &&  //
492                  CBB_flush(cbb);
493         ASN1_BIT_STRING_free(obj);
494         return ok;
495       }
496 
497       // The other formats are the same as OCTET STRING, but with the leading
498       // zero bytes.
499       if (!CBB_add_u8(&child, 0)) {
500         return 0;
501       }
502       OPENSSL_FALLTHROUGH;
503 
504     case CBS_ASN1_OCTETSTRING:
505       if (format == ASN1_GEN_FORMAT_ASCII) {
506         return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) &&
507                CBB_flush(cbb);
508       }
509       if (format == ASN1_GEN_FORMAT_HEX) {
510         size_t len;
511         uint8_t *data = x509v3_hex_to_bytes(value, &len);
512         if (data == NULL) {
513           OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
514           return 0;
515         }
516         int ok = CBB_add_bytes(&child, data, len) && CBB_flush(cbb);
517         OPENSSL_free(data);
518         return ok;
519       }
520 
521       OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
522       return 0;
523 
524     case CBS_ASN1_SEQUENCE:
525     case CBS_ASN1_SET:
526       if (has_value) {
527         if (cnf == NULL) {
528           OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
529           return 0;
530         }
531         const STACK_OF(CONF_VALUE) *section = X509V3_get_section(cnf, value);
532         if (section == NULL) {
533           OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
534           return 0;
535         }
536         for (size_t i = 0; i < sk_CONF_VALUE_num(section); i++) {
537           const CONF_VALUE *conf = sk_CONF_VALUE_value(section, i);
538           if (!generate_v3(&child, conf->value, cnf, /*tag=*/0,
539                            ASN1_GEN_FORMAT_ASCII, depth + 1)) {
540             return 0;
541           }
542           // This recursive call, by referencing |section|, is the one place
543           // where |generate_v3|'s output can be super-linear in the input.
544           // Check bounds here.
545           if (CBB_len(&child) > ASN1_GEN_MAX_OUTPUT) {
546             OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
547             return 0;
548           }
549         }
550       }
551       if (type == CBS_ASN1_SET) {
552         // The SET type here is a SET OF and must be sorted.
553         return CBB_flush_asn1_set_of(&child) && CBB_flush(cbb);
554       }
555       return CBB_flush(cbb);
556 
557     default:
558       OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
559       return 0;
560   }
561 }
562 
bitstr_cb(const char * elem,size_t len,void * bitstr)563 static int bitstr_cb(const char *elem, size_t len, void *bitstr) {
564   CBS cbs;
565   CBS_init(&cbs, (const uint8_t *)elem, len);
566   uint64_t bitnum;
567   if (!CBS_get_u64_decimal(&cbs, &bitnum) || CBS_len(&cbs) != 0 ||
568       // Cap the highest allowed bit so this mechanism cannot be used to create
569       // extremely large allocations with short inputs. The highest named bit in
570       // RFC 5280 is 8, so 256 should give comfortable margin but still only
571       // allow a 32-byte allocation.
572       //
573       // We do not consider this function to be safe with untrusted inputs (even
574       // without bugs, it is prone to string injection vulnerabilities), so DoS
575       // is not truly a concern, but the limit is necessary to keep fuzzing
576       // effective.
577       bitnum > 256) {
578     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
579     return 0;
580   }
581   if (!ASN1_BIT_STRING_set_bit(bitstr, (int)bitnum, 1)) {
582     return 0;
583   }
584   return 1;
585 }
586