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