Home | History | Annotate | Download | only in x509v3
      1 /* v3_alt.c */
      2 /*
      3  * Written by Dr Stephen N Henson (steve (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) 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 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
     68                                       X509V3_CTX *ctx,
     69                                       STACK_OF(CONF_VALUE) *nval);
     70 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
     71                                      X509V3_CTX *ctx,
     72                                      STACK_OF(CONF_VALUE) *nval);
     73 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
     74 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
     75 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
     76 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
     77 
     78 const X509V3_EXT_METHOD v3_alt[] = {
     79     {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
     80      0, 0, 0, 0,
     81      0, 0,
     82      (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
     83      (X509V3_EXT_V2I)v2i_subject_alt,
     84      NULL, NULL, NULL},
     85 
     86     {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
     87      0, 0, 0, 0,
     88      0, 0,
     89      (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
     90      (X509V3_EXT_V2I)v2i_issuer_alt,
     91      NULL, NULL, NULL},
     92 
     93     {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
     94      0, 0, 0, 0,
     95      0, 0,
     96      (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
     97      NULL, NULL, NULL, NULL},
     98 };
     99 
    100 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
    101                                         GENERAL_NAMES *gens,
    102                                         STACK_OF(CONF_VALUE) *ret)
    103 {
    104     size_t i;
    105     GENERAL_NAME *gen;
    106     for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
    107         gen = sk_GENERAL_NAME_value(gens, i);
    108         ret = i2v_GENERAL_NAME(method, gen, ret);
    109     }
    110     if (!ret)
    111         return sk_CONF_VALUE_new_null();
    112     return ret;
    113 }
    114 
    115 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
    116                                        GENERAL_NAME *gen,
    117                                        STACK_OF(CONF_VALUE) *ret)
    118 {
    119     unsigned char *p;
    120     char oline[256], htmp[5];
    121     int i;
    122     switch (gen->type) {
    123     case GEN_OTHERNAME:
    124         if (!X509V3_add_value("othername", "<unsupported>", &ret))
    125             return NULL;
    126         break;
    127 
    128     case GEN_X400:
    129         if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
    130             return NULL;
    131         break;
    132 
    133     case GEN_EDIPARTY:
    134         if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
    135             return NULL;
    136         break;
    137 
    138     case GEN_EMAIL:
    139         if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
    140             return NULL;
    141         break;
    142 
    143     case GEN_DNS:
    144         if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
    145             return NULL;
    146         break;
    147 
    148     case GEN_URI:
    149         if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
    150             return NULL;
    151         break;
    152 
    153     case GEN_DIRNAME:
    154         if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL
    155                 || !X509V3_add_value("DirName", oline, &ret))
    156             return NULL;
    157         break;
    158 
    159     case GEN_IPADD:
    160         p = gen->d.ip->data;
    161         if (gen->d.ip->length == 4)
    162             BIO_snprintf(oline, sizeof oline,
    163                          "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    164         else if (gen->d.ip->length == 16) {
    165             oline[0] = 0;
    166             for (i = 0; i < 8; i++) {
    167                 BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
    168                 p += 2;
    169                 BUF_strlcat(oline, htmp, sizeof(oline));
    170                 if (i != 7)
    171                     BUF_strlcat(oline, ":", sizeof(oline));
    172             }
    173         } else {
    174             if (!X509V3_add_value("IP Address", "<invalid>", &ret))
    175                 return NULL;
    176             break;
    177         }
    178         if (!X509V3_add_value("IP Address", oline, &ret))
    179             return NULL;
    180         break;
    181 
    182     case GEN_RID:
    183         i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
    184         if (!X509V3_add_value("Registered ID", oline, &ret))
    185             return NULL;
    186         break;
    187     }
    188     return ret;
    189 }
    190 
    191 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
    192 {
    193     unsigned char *p;
    194     int i;
    195     switch (gen->type) {
    196     case GEN_OTHERNAME:
    197         BIO_printf(out, "othername:<unsupported>");
    198         break;
    199 
    200     case GEN_X400:
    201         BIO_printf(out, "X400Name:<unsupported>");
    202         break;
    203 
    204     case GEN_EDIPARTY:
    205         /* Maybe fix this: it is supported now */
    206         BIO_printf(out, "EdiPartyName:<unsupported>");
    207         break;
    208 
    209     case GEN_EMAIL:
    210         BIO_printf(out, "email:%s", gen->d.ia5->data);
    211         break;
    212 
    213     case GEN_DNS:
    214         BIO_printf(out, "DNS:%s", gen->d.ia5->data);
    215         break;
    216 
    217     case GEN_URI:
    218         BIO_printf(out, "URI:%s", gen->d.ia5->data);
    219         break;
    220 
    221     case GEN_DIRNAME:
    222         BIO_printf(out, "DirName: ");
    223         X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
    224         break;
    225 
    226     case GEN_IPADD:
    227         p = gen->d.ip->data;
    228         if (gen->d.ip->length == 4)
    229             BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    230         else if (gen->d.ip->length == 16) {
    231             BIO_printf(out, "IP Address");
    232             for (i = 0; i < 8; i++) {
    233                 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
    234                 p += 2;
    235             }
    236             BIO_puts(out, "\n");
    237         } else {
    238             BIO_printf(out, "IP Address:<invalid>");
    239             break;
    240         }
    241         break;
    242 
    243     case GEN_RID:
    244         BIO_printf(out, "Registered ID");
    245         i2a_ASN1_OBJECT(out, gen->d.rid);
    246         break;
    247     }
    248     return 1;
    249 }
    250 
    251 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
    252                                      X509V3_CTX *ctx,
    253                                      STACK_OF(CONF_VALUE) *nval)
    254 {
    255     GENERAL_NAMES *gens = NULL;
    256     CONF_VALUE *cnf;
    257     size_t i;
    258     if (!(gens = sk_GENERAL_NAME_new_null())) {
    259         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    260         return NULL;
    261     }
    262     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
    263         cnf = sk_CONF_VALUE_value(nval, i);
    264         if (!name_cmp(cnf->name, "issuer") && cnf->value &&
    265             !strcmp(cnf->value, "copy")) {
    266             if (!copy_issuer(ctx, gens))
    267                 goto err;
    268         } else {
    269             GENERAL_NAME *gen;
    270             if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
    271                 goto err;
    272             sk_GENERAL_NAME_push(gens, gen);
    273         }
    274     }
    275     return gens;
    276  err:
    277     sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
    278     return NULL;
    279 }
    280 
    281 /* Append subject altname of issuer to issuer alt name of subject */
    282 
    283 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
    284 {
    285     GENERAL_NAMES *ialt;
    286     GENERAL_NAME *gen;
    287     X509_EXTENSION *ext;
    288     int i;
    289     size_t j;
    290     if (ctx && (ctx->flags == CTX_TEST))
    291         return 1;
    292     if (!ctx || !ctx->issuer_cert) {
    293         OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
    294         goto err;
    295     }
    296     i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
    297     if (i < 0)
    298         return 1;
    299     if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
    300         !(ialt = X509V3_EXT_d2i(ext))) {
    301         OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
    302         goto err;
    303     }
    304 
    305     for (j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
    306         gen = sk_GENERAL_NAME_value(ialt, j);
    307         if (!sk_GENERAL_NAME_push(gens, gen)) {
    308             OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    309             goto err;
    310         }
    311     }
    312     sk_GENERAL_NAME_free(ialt);
    313 
    314     return 1;
    315 
    316  err:
    317     return 0;
    318 
    319 }
    320 
    321 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
    322                                       X509V3_CTX *ctx,
    323                                       STACK_OF(CONF_VALUE) *nval)
    324 {
    325     GENERAL_NAMES *gens = NULL;
    326     CONF_VALUE *cnf;
    327     size_t i;
    328     if (!(gens = sk_GENERAL_NAME_new_null())) {
    329         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    330         return NULL;
    331     }
    332     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
    333         cnf = sk_CONF_VALUE_value(nval, i);
    334         if (!name_cmp(cnf->name, "email") && cnf->value &&
    335             !strcmp(cnf->value, "copy")) {
    336             if (!copy_email(ctx, gens, 0))
    337                 goto err;
    338         } else if (!name_cmp(cnf->name, "email") && cnf->value &&
    339                    !strcmp(cnf->value, "move")) {
    340             if (!copy_email(ctx, gens, 1))
    341                 goto err;
    342         } else {
    343             GENERAL_NAME *gen;
    344             if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
    345                 goto err;
    346             sk_GENERAL_NAME_push(gens, gen);
    347         }
    348     }
    349     return gens;
    350  err:
    351     sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
    352     return NULL;
    353 }
    354 
    355 /*
    356  * Copy any email addresses in a certificate or request to GENERAL_NAMES
    357  */
    358 
    359 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
    360 {
    361     X509_NAME *nm;
    362     ASN1_IA5STRING *email = NULL;
    363     X509_NAME_ENTRY *ne;
    364     GENERAL_NAME *gen = NULL;
    365     int i;
    366     if (ctx != NULL && ctx->flags == CTX_TEST)
    367         return 1;
    368     if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
    369         OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
    370         goto err;
    371     }
    372     /* Find the subject name */
    373     if (ctx->subject_cert)
    374         nm = X509_get_subject_name(ctx->subject_cert);
    375     else
    376         nm = X509_REQ_get_subject_name(ctx->subject_req);
    377 
    378     /* Now add any email address(es) to STACK */
    379     i = -1;
    380     while ((i = X509_NAME_get_index_by_NID(nm,
    381                                            NID_pkcs9_emailAddress, i)) >= 0) {
    382         ne = X509_NAME_get_entry(nm, i);
    383         email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
    384         if (move_p) {
    385             X509_NAME_delete_entry(nm, i);
    386             X509_NAME_ENTRY_free(ne);
    387             i--;
    388         }
    389         if (!email || !(gen = GENERAL_NAME_new())) {
    390             OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    391             goto err;
    392         }
    393         gen->d.ia5 = email;
    394         email = NULL;
    395         gen->type = GEN_EMAIL;
    396         if (!sk_GENERAL_NAME_push(gens, gen)) {
    397             OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    398             goto err;
    399         }
    400         gen = NULL;
    401     }
    402 
    403     return 1;
    404 
    405  err:
    406     GENERAL_NAME_free(gen);
    407     M_ASN1_IA5STRING_free(email);
    408     return 0;
    409 
    410 }
    411 
    412 GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
    413                                  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
    414 {
    415     GENERAL_NAME *gen;
    416     GENERAL_NAMES *gens = NULL;
    417     CONF_VALUE *cnf;
    418     size_t i;
    419     if (!(gens = sk_GENERAL_NAME_new_null())) {
    420         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    421         return NULL;
    422     }
    423     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
    424         cnf = sk_CONF_VALUE_value(nval, i);
    425         if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
    426             goto err;
    427         sk_GENERAL_NAME_push(gens, gen);
    428     }
    429     return gens;
    430  err:
    431     sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
    432     return NULL;
    433 }
    434 
    435 GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
    436                                X509V3_CTX *ctx, CONF_VALUE *cnf)
    437 {
    438     return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
    439 }
    440 
    441 GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
    442                                const X509V3_EXT_METHOD *method,
    443                                X509V3_CTX *ctx, int gen_type, char *value,
    444                                int is_nc)
    445 {
    446     char is_string = 0;
    447     GENERAL_NAME *gen = NULL;
    448 
    449     if (!value) {
    450         OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
    451         return NULL;
    452     }
    453 
    454     if (out)
    455         gen = out;
    456     else {
    457         gen = GENERAL_NAME_new();
    458         if (gen == NULL) {
    459             OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    460             return NULL;
    461         }
    462     }
    463 
    464     switch (gen_type) {
    465     case GEN_URI:
    466     case GEN_EMAIL:
    467     case GEN_DNS:
    468         is_string = 1;
    469         break;
    470 
    471     case GEN_RID:
    472         {
    473             ASN1_OBJECT *obj;
    474             if (!(obj = OBJ_txt2obj(value, 0))) {
    475                 OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
    476                 ERR_add_error_data(2, "value=", value);
    477                 goto err;
    478             }
    479             gen->d.rid = obj;
    480         }
    481         break;
    482 
    483     case GEN_IPADD:
    484         if (is_nc)
    485             gen->d.ip = a2i_IPADDRESS_NC(value);
    486         else
    487             gen->d.ip = a2i_IPADDRESS(value);
    488         if (gen->d.ip == NULL) {
    489             OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
    490             ERR_add_error_data(2, "value=", value);
    491             goto err;
    492         }
    493         break;
    494 
    495     case GEN_DIRNAME:
    496         if (!do_dirname(gen, value, ctx)) {
    497             OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
    498             goto err;
    499         }
    500         break;
    501 
    502     case GEN_OTHERNAME:
    503         if (!do_othername(gen, value, ctx)) {
    504             OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
    505             goto err;
    506         }
    507         break;
    508     default:
    509         OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
    510         goto err;
    511     }
    512 
    513     if (is_string) {
    514         if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
    515             !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
    516                              strlen(value))) {
    517             OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    518             goto err;
    519         }
    520     }
    521 
    522     gen->type = gen_type;
    523 
    524     return gen;
    525 
    526  err:
    527     if (!out)
    528         GENERAL_NAME_free(gen);
    529     return NULL;
    530 }
    531 
    532 GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
    533                                   const X509V3_EXT_METHOD *method,
    534                                   X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
    535 {
    536     int type;
    537 
    538     char *name, *value;
    539 
    540     name = cnf->name;
    541     value = cnf->value;
    542 
    543     if (!value) {
    544         OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
    545         return NULL;
    546     }
    547 
    548     if (!name_cmp(name, "email"))
    549         type = GEN_EMAIL;
    550     else if (!name_cmp(name, "URI"))
    551         type = GEN_URI;
    552     else if (!name_cmp(name, "DNS"))
    553         type = GEN_DNS;
    554     else if (!name_cmp(name, "RID"))
    555         type = GEN_RID;
    556     else if (!name_cmp(name, "IP"))
    557         type = GEN_IPADD;
    558     else if (!name_cmp(name, "dirName"))
    559         type = GEN_DIRNAME;
    560     else if (!name_cmp(name, "otherName"))
    561         type = GEN_OTHERNAME;
    562     else {
    563         OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
    564         ERR_add_error_data(2, "name=", name);
    565         return NULL;
    566     }
    567 
    568     return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
    569 
    570 }
    571 
    572 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
    573 {
    574     char *objtmp = NULL, *p;
    575     int objlen;
    576     if (!(p = strchr(value, ';')))
    577         return 0;
    578     if (!(gen->d.otherName = OTHERNAME_new()))
    579         return 0;
    580     /*
    581      * Free this up because we will overwrite it. no need to free type_id
    582      * because it is static
    583      */
    584     ASN1_TYPE_free(gen->d.otherName->value);
    585     if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
    586         return 0;
    587     objlen = p - value;
    588     objtmp = OPENSSL_malloc(objlen + 1);
    589     if (objtmp == NULL)
    590         return 0;
    591     BUF_strlcpy(objtmp, value, objlen + 1);
    592     gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
    593     OPENSSL_free(objtmp);
    594     if (!gen->d.otherName->type_id)
    595         return 0;
    596     return 1;
    597 }
    598 
    599 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
    600 {
    601     int ret = 0;
    602     STACK_OF(CONF_VALUE) *sk = NULL;
    603     X509_NAME *nm = X509_NAME_new();
    604     if (nm == NULL)
    605         goto err;
    606     sk = X509V3_get_section(ctx, value);
    607     if (sk == NULL) {
    608         OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
    609         ERR_add_error_data(2, "section=", value);
    610         goto err;
    611     }
    612     /* FIXME: should allow other character types... */
    613     if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
    614         goto err;
    615     gen->d.dirn = nm;
    616     ret = 1;
    617 
    618  err:
    619     if (!ret)
    620         X509_NAME_free(nm);
    621     X509V3_section_free(ctx, sk);
    622     return ret;
    623 }
    624