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