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(©, &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(©, &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(©) != 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(©, &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