libressl: Fix validation errors in certificate chains with expired certificates
[dragonfly.git] / crypto / libressl / crypto / x509 / x509_alt.c
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
66 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
67     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
69     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
70 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
71 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
72 static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
73 static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
74
75 const 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
126 STACK_OF(CONF_VALUE) *
127 i2v_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
154 STACK_OF(CONF_VALUE) *
155 i2v_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
246 int
247 GENERAL_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
309 static GENERAL_NAMES *
310 v2i_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
339 err:
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
346 static int
347 copy_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
380 err:
381         return 0;
382
383 }
384
385 static GENERAL_NAMES *
386 v2i_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
419 err:
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
428 static int
429 copy_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
476 err:
477         GENERAL_NAME_free(gen);
478         ASN1_IA5STRING_free(email);
479         return 0;
480 }
481
482 GENERAL_NAMES *
483 v2i_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
506 err:
507         sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
508         return NULL;
509 }
510
511 GENERAL_NAME *
512 v2i_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
518 GENERAL_NAME *
519 a2i_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
602 err:
603         if (out == NULL)
604                 GENERAL_NAME_free(gen);
605         return NULL;
606 }
607
608 GENERAL_NAME *
609 v2i_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
646 static int
647 do_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
675 static int
676 do_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 }