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