summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_alt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_alt.c')
-rw-r--r--src/lib/libcrypto/x509/x509_alt.c699
1 files changed, 699 insertions, 0 deletions
diff --git a/src/lib/libcrypto/x509/x509_alt.c b/src/lib/libcrypto/x509/x509_alt.c
new file mode 100644
index 0000000000..45aaec24c0
--- /dev/null
+++ b/src/lib/libcrypto/x509/x509_alt.c
@@ -0,0 +1,699 @@
1/* $OpenBSD: x509_alt.c,v 1.1 2020/06/04 15:19:31 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/conf.h>
63#include <openssl/err.h>
64#include <openssl/x509v3.h>
65
66static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
69 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
70static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
71static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
72static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
73static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
74
75const X509V3_EXT_METHOD v3_alt[] = {
76 {
77 .ext_nid = NID_subject_alt_name,
78 .ext_flags = 0,
79 .it = &GENERAL_NAMES_it,
80 .ext_new = NULL,
81 .ext_free = NULL,
82 .d2i = NULL,
83 .i2d = NULL,
84 .i2s = NULL,
85 .s2i = NULL,
86 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
87 .v2i = (X509V3_EXT_V2I)v2i_subject_alt,
88 .i2r = NULL,
89 .r2i = NULL,
90 .usr_data = NULL,
91 },
92 {
93 .ext_nid = NID_issuer_alt_name,
94 .ext_flags = 0,
95 .it = &GENERAL_NAMES_it,
96 .ext_new = NULL,
97 .ext_free = NULL,
98 .d2i = NULL,
99 .i2d = NULL,
100 .i2s = NULL,
101 .s2i = NULL,
102 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
103 .v2i = (X509V3_EXT_V2I)v2i_issuer_alt,
104 .i2r = NULL,
105 .r2i = NULL,
106 .usr_data = NULL,
107 },
108 {
109 .ext_nid = NID_certificate_issuer,
110 .ext_flags = 0,
111 .it = &GENERAL_NAMES_it,
112 .ext_new = NULL,
113 .ext_free = NULL,
114 .d2i = NULL,
115 .i2d = NULL,
116 .i2s = NULL,
117 .s2i = NULL,
118 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
119 .v2i = NULL,
120 .i2r = NULL,
121 .r2i = NULL,
122 .usr_data = NULL,
123 },
124};
125
126STACK_OF(CONF_VALUE) *
127i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens,
128 STACK_OF(CONF_VALUE) *ret)
129{
130 STACK_OF(CONF_VALUE) *free_ret = NULL;
131 GENERAL_NAME *gen;
132 int i;
133
134 if (ret == NULL) {
135 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
136 return NULL;
137 }
138
139 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
140 if ((gen = sk_GENERAL_NAME_value(gens, i)) == NULL)
141 goto err;
142 if ((ret = i2v_GENERAL_NAME(method, gen, ret)) == NULL)
143 goto err;
144 }
145
146 return ret;
147
148 err:
149 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
150
151 return NULL;
152}
153
154STACK_OF(CONF_VALUE) *
155i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen,
156 STACK_OF(CONF_VALUE) *ret)
157{
158 STACK_OF(CONF_VALUE) *free_ret = NULL;
159 unsigned char *p;
160 char oline[256], htmp[5];
161 int i;
162
163 if (ret == NULL) {
164 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
165 return NULL;
166 }
167
168 switch (gen->type) {
169 case GEN_OTHERNAME:
170 if (!X509V3_add_value("othername", "<unsupported>", &ret))
171 goto err;
172 break;
173
174 case GEN_X400:
175 if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
176 goto err;
177 break;
178
179 case GEN_EDIPARTY:
180 if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
181 goto err;
182 break;
183
184 case GEN_EMAIL:
185 if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
186 goto err;
187 break;
188
189 case GEN_DNS:
190 if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
191 goto err;
192 break;
193
194 case GEN_URI:
195 if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
196 goto err;
197 break;
198
199 case GEN_DIRNAME:
200 if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL)
201 goto err;
202 if (!X509V3_add_value("DirName", oline, &ret))
203 goto err;
204 break;
205
206 case GEN_IPADD: /* XXX */
207 p = gen->d.ip->data;
208 if (gen->d.ip->length == 4)
209 (void) snprintf(oline, sizeof oline,
210 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
211 else if (gen->d.ip->length == 16) {
212 oline[0] = 0;
213 for (i = 0; i < 8; i++) {
214 (void) snprintf(htmp, sizeof htmp,
215 "%X", p[0] << 8 | p[1]);
216 p += 2;
217 strlcat(oline, htmp, sizeof(oline));
218 if (i != 7)
219 strlcat(oline, ":", sizeof(oline));
220 }
221 } else {
222 if (!X509V3_add_value("IP Address", "<invalid>", &ret))
223 goto err;
224 break;
225 }
226 if (!X509V3_add_value("IP Address", oline, &ret))
227 goto err;
228 break;
229
230 case GEN_RID:
231 if (!i2t_ASN1_OBJECT(oline, 256, gen->d.rid))
232 goto err;
233 if (!X509V3_add_value("Registered ID", oline, &ret))
234 goto err;
235 break;
236 }
237
238 return ret;
239
240 err:
241 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
242
243 return NULL;
244}
245
246int
247GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
248{
249 unsigned char *p;
250 int i;
251
252 switch (gen->type) {
253 case GEN_OTHERNAME:
254 BIO_printf(out, "othername:<unsupported>");
255 break;
256
257 case GEN_X400:
258 BIO_printf(out, "X400Name:<unsupported>");
259 break;
260
261 case GEN_EDIPARTY:
262 /* Maybe fix this: it is supported now */
263 BIO_printf(out, "EdiPartyName:<unsupported>");
264 break;
265
266 case GEN_EMAIL:
267 BIO_printf(out, "email:%s", gen->d.ia5->data);
268 break;
269
270 case GEN_DNS:
271 BIO_printf(out, "DNS:%s", gen->d.ia5->data);
272 break;
273
274 case GEN_URI:
275 BIO_printf(out, "URI:%s", gen->d.ia5->data);
276 break;
277
278 case GEN_DIRNAME:
279 BIO_printf(out, "DirName: ");
280 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
281 break;
282
283 case GEN_IPADD:
284 p = gen->d.ip->data;
285 if (gen->d.ip->length == 4)
286 BIO_printf(out, "IP Address:%d.%d.%d.%d",
287 p[0], p[1], p[2], p[3]);
288 else if (gen->d.ip->length == 16) {
289 BIO_printf(out, "IP Address");
290 for (i = 0; i < 8; i++) {
291 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
292 p += 2;
293 }
294 BIO_puts(out, "\n");
295 } else {
296 BIO_printf(out, "IP Address:<invalid>");
297 break;
298 }
299 break;
300
301 case GEN_RID:
302 BIO_printf(out, "Registered ID");
303 i2a_ASN1_OBJECT(out, gen->d.rid);
304 break;
305 }
306 return 1;
307}
308
309static GENERAL_NAMES *
310v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
311 STACK_OF(CONF_VALUE) *nval)
312{
313 GENERAL_NAMES *gens = NULL;
314 CONF_VALUE *cnf;
315 int i;
316
317 if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
318 X509V3error(ERR_R_MALLOC_FAILURE);
319 return NULL;
320 }
321 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
322 cnf = sk_CONF_VALUE_value(nval, i);
323 if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL &&
324 strcmp(cnf->value, "copy") == 0) {
325 if (!copy_issuer(ctx, gens))
326 goto err;
327 } else {
328 GENERAL_NAME *gen;
329 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
330 goto err;
331 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
332 GENERAL_NAME_free(gen);
333 goto err;
334 }
335 }
336 }
337 return gens;
338
339err:
340 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
341 return NULL;
342}
343
344/* Append subject altname of issuer to issuer alt name of subject */
345
346static int
347copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
348{
349 GENERAL_NAMES *ialt;
350 GENERAL_NAME *gen;
351 X509_EXTENSION *ext;
352 int i;
353
354 if (ctx && (ctx->flags == CTX_TEST))
355 return 1;
356 if (!ctx || !ctx->issuer_cert) {
357 X509V3error(X509V3_R_NO_ISSUER_DETAILS);
358 goto err;
359 }
360 i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
361 if (i < 0)
362 return 1;
363 if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
364 !(ialt = X509V3_EXT_d2i(ext))) {
365 X509V3error(X509V3_R_ISSUER_DECODE_ERROR);
366 goto err;
367 }
368
369 for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
370 gen = sk_GENERAL_NAME_value(ialt, i);
371 if (!sk_GENERAL_NAME_push(gens, gen)) {
372 X509V3error(ERR_R_MALLOC_FAILURE);
373 goto err;
374 }
375 }
376 sk_GENERAL_NAME_free(ialt);
377
378 return 1;
379
380err:
381 return 0;
382
383}
384
385static GENERAL_NAMES *
386v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
387 STACK_OF(CONF_VALUE) *nval)
388{
389 GENERAL_NAMES *gens = NULL;
390 CONF_VALUE *cnf;
391 int i;
392
393 if (!(gens = sk_GENERAL_NAME_new_null())) {
394 X509V3error(ERR_R_MALLOC_FAILURE);
395 return NULL;
396 }
397 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
398 cnf = sk_CONF_VALUE_value(nval, i);
399 if (!name_cmp(cnf->name, "email") && cnf->value &&
400 !strcmp(cnf->value, "copy")) {
401 if (!copy_email(ctx, gens, 0))
402 goto err;
403 } else if (!name_cmp(cnf->name, "email") && cnf->value &&
404 !strcmp(cnf->value, "move")) {
405 if (!copy_email(ctx, gens, 1))
406 goto err;
407 } else {
408 GENERAL_NAME *gen;
409 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
410 goto err;
411 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
412 GENERAL_NAME_free(gen);
413 goto err;
414 }
415 }
416 }
417 return gens;
418
419err:
420 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
421 return NULL;
422}
423
424/* Copy any email addresses in a certificate or request to
425 * GENERAL_NAMES
426 */
427
428static int
429copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
430{
431 X509_NAME *nm;
432 ASN1_IA5STRING *email = NULL;
433 X509_NAME_ENTRY *ne;
434 GENERAL_NAME *gen = NULL;
435 int i;
436
437 if (ctx != NULL && ctx->flags == CTX_TEST)
438 return 1;
439 if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
440 X509V3error(X509V3_R_NO_SUBJECT_DETAILS);
441 goto err;
442 }
443 /* Find the subject name */
444 if (ctx->subject_cert)
445 nm = X509_get_subject_name(ctx->subject_cert);
446 else
447 nm = X509_REQ_get_subject_name(ctx->subject_req);
448
449 /* Now add any email address(es) to STACK */
450 i = -1;
451 while ((i = X509_NAME_get_index_by_NID(nm,
452 NID_pkcs9_emailAddress, i)) >= 0) {
453 ne = X509_NAME_get_entry(nm, i);
454 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
455 if (move_p) {
456 X509_NAME_delete_entry(nm, i);
457 X509_NAME_ENTRY_free(ne);
458 i--;
459 }
460 if (!email || !(gen = GENERAL_NAME_new())) {
461 X509V3error(ERR_R_MALLOC_FAILURE);
462 goto err;
463 }
464 gen->d.ia5 = email;
465 email = NULL;
466 gen->type = GEN_EMAIL;
467 if (!sk_GENERAL_NAME_push(gens, gen)) {
468 X509V3error(ERR_R_MALLOC_FAILURE);
469 goto err;
470 }
471 gen = NULL;
472 }
473
474 return 1;
475
476err:
477 GENERAL_NAME_free(gen);
478 ASN1_IA5STRING_free(email);
479 return 0;
480}
481
482GENERAL_NAMES *
483v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
484 STACK_OF(CONF_VALUE) *nval)
485{
486 GENERAL_NAME *gen;
487 GENERAL_NAMES *gens = NULL;
488 CONF_VALUE *cnf;
489 int i;
490
491 if (!(gens = sk_GENERAL_NAME_new_null())) {
492 X509V3error(ERR_R_MALLOC_FAILURE);
493 return NULL;
494 }
495 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
496 cnf = sk_CONF_VALUE_value(nval, i);
497 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
498 goto err;
499 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
500 GENERAL_NAME_free(gen);
501 goto err;
502 }
503 }
504 return gens;
505
506err:
507 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
508 return NULL;
509}
510
511GENERAL_NAME *
512v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
513 CONF_VALUE *cnf)
514{
515 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
516}
517
518GENERAL_NAME *
519a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
520 X509V3_CTX *ctx, int gen_type, const char *value, int is_nc)
521{
522 char is_string = 0;
523 GENERAL_NAME *gen = NULL;
524
525 if (!value) {
526 X509V3error(X509V3_R_MISSING_VALUE);
527 return NULL;
528 }
529
530 if (out)
531 gen = out;
532 else {
533 gen = GENERAL_NAME_new();
534 if (gen == NULL) {
535 X509V3error(ERR_R_MALLOC_FAILURE);
536 return NULL;
537 }
538 }
539
540 switch (gen_type) {
541 case GEN_URI:
542 case GEN_EMAIL:
543 case GEN_DNS:
544 is_string = 1;
545 break;
546
547 case GEN_RID:
548 {
549 ASN1_OBJECT *obj;
550 if (!(obj = OBJ_txt2obj(value, 0))) {
551 X509V3error(X509V3_R_BAD_OBJECT);
552 ERR_asprintf_error_data("value=%s", value);
553 goto err;
554 }
555 gen->d.rid = obj;
556 }
557 break;
558
559 case GEN_IPADD:
560 if (is_nc)
561 gen->d.ip = a2i_IPADDRESS_NC(value);
562 else
563 gen->d.ip = a2i_IPADDRESS(value);
564 if (gen->d.ip == NULL) {
565 X509V3error(X509V3_R_BAD_IP_ADDRESS);
566 ERR_asprintf_error_data("value=%s", value);
567 goto err;
568 }
569 break;
570
571 case GEN_DIRNAME:
572 if (!do_dirname(gen, value, ctx)) {
573 X509V3error(X509V3_R_DIRNAME_ERROR);
574 goto err;
575 }
576 break;
577
578 case GEN_OTHERNAME:
579 if (!do_othername(gen, value, ctx)) {
580 X509V3error(X509V3_R_OTHERNAME_ERROR);
581 goto err;
582 }
583 break;
584
585 default:
586 X509V3error(X509V3_R_UNSUPPORTED_TYPE);
587 goto err;
588 }
589
590 if (is_string) {
591 if (!(gen->d.ia5 = ASN1_IA5STRING_new()) ||
592 !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) {
593 X509V3error(ERR_R_MALLOC_FAILURE);
594 goto err;
595 }
596 }
597
598 gen->type = gen_type;
599
600 return gen;
601
602err:
603 if (out == NULL)
604 GENERAL_NAME_free(gen);
605 return NULL;
606}
607
608GENERAL_NAME *
609v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
610 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
611{
612 int type;
613 char *name, *value;
614
615 name = cnf->name;
616 value = cnf->value;
617
618 if (!value) {
619 X509V3error(X509V3_R_MISSING_VALUE);
620 return NULL;
621 }
622
623 if (!name_cmp(name, "email"))
624 type = GEN_EMAIL;
625 else if (!name_cmp(name, "URI"))
626 type = GEN_URI;
627 else if (!name_cmp(name, "DNS"))
628 type = GEN_DNS;
629 else if (!name_cmp(name, "RID"))
630 type = GEN_RID;
631 else if (!name_cmp(name, "IP"))
632 type = GEN_IPADD;
633 else if (!name_cmp(name, "dirName"))
634 type = GEN_DIRNAME;
635 else if (!name_cmp(name, "otherName"))
636 type = GEN_OTHERNAME;
637 else {
638 X509V3error(X509V3_R_UNSUPPORTED_OPTION);
639 ERR_asprintf_error_data("name=%s", name);
640 return NULL;
641 }
642
643 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
644}
645
646static int
647do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
648{
649 char *objtmp = NULL, *p;
650 int objlen;
651
652 if (!(p = strchr(value, ';')))
653 return 0;
654 if (!(gen->d.otherName = OTHERNAME_new()))
655 return 0;
656 /* Free this up because we will overwrite it.
657 * no need to free type_id because it is static
658 */
659 ASN1_TYPE_free(gen->d.otherName->value);
660 if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
661 return 0;
662 objlen = p - value;
663 objtmp = malloc(objlen + 1);
664 if (objtmp) {
665 strlcpy(objtmp, value, objlen + 1);
666 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
667 free(objtmp);
668 } else
669 gen->d.otherName->type_id = NULL;
670 if (!gen->d.otherName->type_id)
671 return 0;
672 return 1;
673}
674
675static int
676do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
677{
678 int ret;
679 STACK_OF(CONF_VALUE) *sk;
680 X509_NAME *nm;
681
682 if (!(nm = X509_NAME_new()))
683 return 0;
684 sk = X509V3_get_section(ctx, value);
685 if (!sk) {
686 X509V3error(X509V3_R_SECTION_NOT_FOUND);
687 ERR_asprintf_error_data("section=%s", value);
688 X509_NAME_free(nm);
689 return 0;
690 }
691 /* FIXME: should allow other character types... */
692 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
693 if (!ret)
694 X509_NAME_free(nm);
695 gen->d.dirn = nm;
696 X509V3_section_free(ctx, sk);
697
698 return ret;
699}