1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: x509_alt.c,v 1.12 2022/03/26 16:34:21 tb Exp $ */
28edacedfSDaniel Fojt /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
38edacedfSDaniel Fojt * project.
48edacedfSDaniel Fojt */
58edacedfSDaniel Fojt /* ====================================================================
68edacedfSDaniel Fojt * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
78edacedfSDaniel Fojt *
88edacedfSDaniel Fojt * Redistribution and use in source and binary forms, with or without
98edacedfSDaniel Fojt * modification, are permitted provided that the following conditions
108edacedfSDaniel Fojt * are met:
118edacedfSDaniel Fojt *
128edacedfSDaniel Fojt * 1. Redistributions of source code must retain the above copyright
138edacedfSDaniel Fojt * notice, this list of conditions and the following disclaimer.
148edacedfSDaniel Fojt *
158edacedfSDaniel Fojt * 2. Redistributions in binary form must reproduce the above copyright
168edacedfSDaniel Fojt * notice, this list of conditions and the following disclaimer in
178edacedfSDaniel Fojt * the documentation and/or other materials provided with the
188edacedfSDaniel Fojt * distribution.
198edacedfSDaniel Fojt *
208edacedfSDaniel Fojt * 3. All advertising materials mentioning features or use of this
218edacedfSDaniel Fojt * software must display the following acknowledgment:
228edacedfSDaniel Fojt * "This product includes software developed by the OpenSSL Project
238edacedfSDaniel Fojt * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
248edacedfSDaniel Fojt *
258edacedfSDaniel Fojt * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
268edacedfSDaniel Fojt * endorse or promote products derived from this software without
278edacedfSDaniel Fojt * prior written permission. For written permission, please contact
288edacedfSDaniel Fojt * licensing@OpenSSL.org.
298edacedfSDaniel Fojt *
308edacedfSDaniel Fojt * 5. Products derived from this software may not be called "OpenSSL"
318edacedfSDaniel Fojt * nor may "OpenSSL" appear in their names without prior written
328edacedfSDaniel Fojt * permission of the OpenSSL Project.
338edacedfSDaniel Fojt *
348edacedfSDaniel Fojt * 6. Redistributions of any form whatsoever must retain the following
358edacedfSDaniel Fojt * acknowledgment:
368edacedfSDaniel Fojt * "This product includes software developed by the OpenSSL Project
378edacedfSDaniel Fojt * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
388edacedfSDaniel Fojt *
398edacedfSDaniel Fojt * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
408edacedfSDaniel Fojt * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
418edacedfSDaniel Fojt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
428edacedfSDaniel Fojt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
438edacedfSDaniel Fojt * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
448edacedfSDaniel Fojt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
458edacedfSDaniel Fojt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
468edacedfSDaniel Fojt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
478edacedfSDaniel Fojt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
488edacedfSDaniel Fojt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
498edacedfSDaniel Fojt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
508edacedfSDaniel Fojt * OF THE POSSIBILITY OF SUCH DAMAGE.
518edacedfSDaniel Fojt * ====================================================================
528edacedfSDaniel Fojt *
538edacedfSDaniel Fojt * This product includes cryptographic software written by Eric Young
548edacedfSDaniel Fojt * (eay@cryptsoft.com). This product includes software written by Tim
558edacedfSDaniel Fojt * Hudson (tjh@cryptsoft.com).
568edacedfSDaniel Fojt *
578edacedfSDaniel Fojt */
588edacedfSDaniel Fojt
598edacedfSDaniel Fojt #include <stdio.h>
608edacedfSDaniel Fojt #include <string.h>
618edacedfSDaniel Fojt
628edacedfSDaniel Fojt #include <openssl/conf.h>
638edacedfSDaniel Fojt #include <openssl/err.h>
648edacedfSDaniel Fojt #include <openssl/x509v3.h>
658edacedfSDaniel Fojt
66*de0e0e4dSAntonio Huete Jimenez #include "x509_internal.h"
67*de0e0e4dSAntonio Huete Jimenez
688edacedfSDaniel Fojt static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
698edacedfSDaniel Fojt X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
708edacedfSDaniel Fojt static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
718edacedfSDaniel Fojt X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
728edacedfSDaniel Fojt static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
738edacedfSDaniel Fojt static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
748edacedfSDaniel Fojt static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
758edacedfSDaniel Fojt static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
768edacedfSDaniel Fojt
778edacedfSDaniel Fojt const X509V3_EXT_METHOD v3_alt[] = {
788edacedfSDaniel Fojt {
798edacedfSDaniel Fojt .ext_nid = NID_subject_alt_name,
808edacedfSDaniel Fojt .ext_flags = 0,
818edacedfSDaniel Fojt .it = &GENERAL_NAMES_it,
828edacedfSDaniel Fojt .ext_new = NULL,
838edacedfSDaniel Fojt .ext_free = NULL,
848edacedfSDaniel Fojt .d2i = NULL,
858edacedfSDaniel Fojt .i2d = NULL,
868edacedfSDaniel Fojt .i2s = NULL,
878edacedfSDaniel Fojt .s2i = NULL,
888edacedfSDaniel Fojt .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
898edacedfSDaniel Fojt .v2i = (X509V3_EXT_V2I)v2i_subject_alt,
908edacedfSDaniel Fojt .i2r = NULL,
918edacedfSDaniel Fojt .r2i = NULL,
928edacedfSDaniel Fojt .usr_data = NULL,
938edacedfSDaniel Fojt },
948edacedfSDaniel Fojt {
958edacedfSDaniel Fojt .ext_nid = NID_issuer_alt_name,
968edacedfSDaniel Fojt .ext_flags = 0,
978edacedfSDaniel Fojt .it = &GENERAL_NAMES_it,
988edacedfSDaniel Fojt .ext_new = NULL,
998edacedfSDaniel Fojt .ext_free = NULL,
1008edacedfSDaniel Fojt .d2i = NULL,
1018edacedfSDaniel Fojt .i2d = NULL,
1028edacedfSDaniel Fojt .i2s = NULL,
1038edacedfSDaniel Fojt .s2i = NULL,
1048edacedfSDaniel Fojt .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
1058edacedfSDaniel Fojt .v2i = (X509V3_EXT_V2I)v2i_issuer_alt,
1068edacedfSDaniel Fojt .i2r = NULL,
1078edacedfSDaniel Fojt .r2i = NULL,
1088edacedfSDaniel Fojt .usr_data = NULL,
1098edacedfSDaniel Fojt },
1108edacedfSDaniel Fojt {
1118edacedfSDaniel Fojt .ext_nid = NID_certificate_issuer,
1128edacedfSDaniel Fojt .ext_flags = 0,
1138edacedfSDaniel Fojt .it = &GENERAL_NAMES_it,
1148edacedfSDaniel Fojt .ext_new = NULL,
1158edacedfSDaniel Fojt .ext_free = NULL,
1168edacedfSDaniel Fojt .d2i = NULL,
1178edacedfSDaniel Fojt .i2d = NULL,
1188edacedfSDaniel Fojt .i2s = NULL,
1198edacedfSDaniel Fojt .s2i = NULL,
1208edacedfSDaniel Fojt .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
1218edacedfSDaniel Fojt .v2i = NULL,
1228edacedfSDaniel Fojt .i2r = NULL,
1238edacedfSDaniel Fojt .r2i = NULL,
1248edacedfSDaniel Fojt .usr_data = NULL,
1258edacedfSDaniel Fojt },
1268edacedfSDaniel Fojt };
1278edacedfSDaniel Fojt
STACK_OF(CONF_VALUE)1288edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *
1298edacedfSDaniel Fojt i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens,
1308edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *ret)
1318edacedfSDaniel Fojt {
1328edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *free_ret = NULL;
1338edacedfSDaniel Fojt GENERAL_NAME *gen;
1348edacedfSDaniel Fojt int i;
1358edacedfSDaniel Fojt
1368edacedfSDaniel Fojt if (ret == NULL) {
1378edacedfSDaniel Fojt if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
1388edacedfSDaniel Fojt return NULL;
1398edacedfSDaniel Fojt }
1408edacedfSDaniel Fojt
1418edacedfSDaniel Fojt for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1428edacedfSDaniel Fojt if ((gen = sk_GENERAL_NAME_value(gens, i)) == NULL)
1438edacedfSDaniel Fojt goto err;
1448edacedfSDaniel Fojt if ((ret = i2v_GENERAL_NAME(method, gen, ret)) == NULL)
1458edacedfSDaniel Fojt goto err;
1468edacedfSDaniel Fojt }
1478edacedfSDaniel Fojt
1488edacedfSDaniel Fojt return ret;
1498edacedfSDaniel Fojt
1508edacedfSDaniel Fojt err:
1518edacedfSDaniel Fojt sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
1528edacedfSDaniel Fojt
1538edacedfSDaniel Fojt return NULL;
1548edacedfSDaniel Fojt }
1558edacedfSDaniel Fojt
STACK_OF(CONF_VALUE)1568edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *
1578edacedfSDaniel Fojt i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen,
1588edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *ret)
1598edacedfSDaniel Fojt {
1608edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *free_ret = NULL;
1618edacedfSDaniel Fojt unsigned char *p;
1628edacedfSDaniel Fojt char oline[256], htmp[5];
1638edacedfSDaniel Fojt int i;
1648edacedfSDaniel Fojt
1658edacedfSDaniel Fojt if (ret == NULL) {
1668edacedfSDaniel Fojt if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
1678edacedfSDaniel Fojt return NULL;
1688edacedfSDaniel Fojt }
1698edacedfSDaniel Fojt
1708edacedfSDaniel Fojt switch (gen->type) {
1718edacedfSDaniel Fojt case GEN_OTHERNAME:
1728edacedfSDaniel Fojt if (!X509V3_add_value("othername", "<unsupported>", &ret))
1738edacedfSDaniel Fojt goto err;
1748edacedfSDaniel Fojt break;
1758edacedfSDaniel Fojt
1768edacedfSDaniel Fojt case GEN_X400:
1778edacedfSDaniel Fojt if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
1788edacedfSDaniel Fojt goto err;
1798edacedfSDaniel Fojt break;
1808edacedfSDaniel Fojt
1818edacedfSDaniel Fojt case GEN_EDIPARTY:
1828edacedfSDaniel Fojt if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
1838edacedfSDaniel Fojt goto err;
1848edacedfSDaniel Fojt break;
1858edacedfSDaniel Fojt
1868edacedfSDaniel Fojt case GEN_EMAIL:
1878edacedfSDaniel Fojt if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
1888edacedfSDaniel Fojt goto err;
1898edacedfSDaniel Fojt break;
1908edacedfSDaniel Fojt
1918edacedfSDaniel Fojt case GEN_DNS:
1928edacedfSDaniel Fojt if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
1938edacedfSDaniel Fojt goto err;
1948edacedfSDaniel Fojt break;
1958edacedfSDaniel Fojt
1968edacedfSDaniel Fojt case GEN_URI:
1978edacedfSDaniel Fojt if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
1988edacedfSDaniel Fojt goto err;
1998edacedfSDaniel Fojt break;
2008edacedfSDaniel Fojt
2018edacedfSDaniel Fojt case GEN_DIRNAME:
2028edacedfSDaniel Fojt if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL)
2038edacedfSDaniel Fojt goto err;
2048edacedfSDaniel Fojt if (!X509V3_add_value("DirName", oline, &ret))
2058edacedfSDaniel Fojt goto err;
2068edacedfSDaniel Fojt break;
2078edacedfSDaniel Fojt
2088edacedfSDaniel Fojt case GEN_IPADD: /* XXX */
2098edacedfSDaniel Fojt p = gen->d.ip->data;
2108edacedfSDaniel Fojt if (gen->d.ip->length == 4)
2118edacedfSDaniel Fojt (void) snprintf(oline, sizeof oline,
2128edacedfSDaniel Fojt "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
2138edacedfSDaniel Fojt else if (gen->d.ip->length == 16) {
2148edacedfSDaniel Fojt oline[0] = 0;
2158edacedfSDaniel Fojt for (i = 0; i < 8; i++) {
2168edacedfSDaniel Fojt (void) snprintf(htmp, sizeof htmp,
2178edacedfSDaniel Fojt "%X", p[0] << 8 | p[1]);
2188edacedfSDaniel Fojt p += 2;
2198edacedfSDaniel Fojt strlcat(oline, htmp, sizeof(oline));
2208edacedfSDaniel Fojt if (i != 7)
2218edacedfSDaniel Fojt strlcat(oline, ":", sizeof(oline));
2228edacedfSDaniel Fojt }
2238edacedfSDaniel Fojt } else {
2248edacedfSDaniel Fojt if (!X509V3_add_value("IP Address", "<invalid>", &ret))
2258edacedfSDaniel Fojt goto err;
2268edacedfSDaniel Fojt break;
2278edacedfSDaniel Fojt }
2288edacedfSDaniel Fojt if (!X509V3_add_value("IP Address", oline, &ret))
2298edacedfSDaniel Fojt goto err;
2308edacedfSDaniel Fojt break;
2318edacedfSDaniel Fojt
2328edacedfSDaniel Fojt case GEN_RID:
2338edacedfSDaniel Fojt if (!i2t_ASN1_OBJECT(oline, 256, gen->d.rid))
2348edacedfSDaniel Fojt goto err;
2358edacedfSDaniel Fojt if (!X509V3_add_value("Registered ID", oline, &ret))
2368edacedfSDaniel Fojt goto err;
2378edacedfSDaniel Fojt break;
2388edacedfSDaniel Fojt }
2398edacedfSDaniel Fojt
2408edacedfSDaniel Fojt return ret;
2418edacedfSDaniel Fojt
2428edacedfSDaniel Fojt err:
2438edacedfSDaniel Fojt sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
2448edacedfSDaniel Fojt
2458edacedfSDaniel Fojt return NULL;
2468edacedfSDaniel Fojt }
2478edacedfSDaniel Fojt
2488edacedfSDaniel Fojt int
GENERAL_NAME_print(BIO * out,GENERAL_NAME * gen)2498edacedfSDaniel Fojt GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
2508edacedfSDaniel Fojt {
2518edacedfSDaniel Fojt unsigned char *p;
2528edacedfSDaniel Fojt int i;
2538edacedfSDaniel Fojt
2548edacedfSDaniel Fojt switch (gen->type) {
2558edacedfSDaniel Fojt case GEN_OTHERNAME:
2568edacedfSDaniel Fojt BIO_printf(out, "othername:<unsupported>");
2578edacedfSDaniel Fojt break;
2588edacedfSDaniel Fojt
2598edacedfSDaniel Fojt case GEN_X400:
2608edacedfSDaniel Fojt BIO_printf(out, "X400Name:<unsupported>");
2618edacedfSDaniel Fojt break;
2628edacedfSDaniel Fojt
2638edacedfSDaniel Fojt case GEN_EDIPARTY:
2648edacedfSDaniel Fojt /* Maybe fix this: it is supported now */
2658edacedfSDaniel Fojt BIO_printf(out, "EdiPartyName:<unsupported>");
2668edacedfSDaniel Fojt break;
2678edacedfSDaniel Fojt
2688edacedfSDaniel Fojt case GEN_EMAIL:
269*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "email:%.*s", gen->d.ia5->length,
270*de0e0e4dSAntonio Huete Jimenez gen->d.ia5->data);
2718edacedfSDaniel Fojt break;
2728edacedfSDaniel Fojt
2738edacedfSDaniel Fojt case GEN_DNS:
274*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "DNS:%.*s", gen->d.ia5->length,
275*de0e0e4dSAntonio Huete Jimenez gen->d.ia5->data);
2768edacedfSDaniel Fojt break;
2778edacedfSDaniel Fojt
2788edacedfSDaniel Fojt case GEN_URI:
279*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "URI:%.*s", gen->d.ia5->length,
280*de0e0e4dSAntonio Huete Jimenez gen->d.ia5->data);
2818edacedfSDaniel Fojt break;
2828edacedfSDaniel Fojt
2838edacedfSDaniel Fojt case GEN_DIRNAME:
2848edacedfSDaniel Fojt BIO_printf(out, "DirName: ");
2858edacedfSDaniel Fojt X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
2868edacedfSDaniel Fojt break;
2878edacedfSDaniel Fojt
2888edacedfSDaniel Fojt case GEN_IPADD:
2898edacedfSDaniel Fojt p = gen->d.ip->data;
2908edacedfSDaniel Fojt if (gen->d.ip->length == 4)
2918edacedfSDaniel Fojt BIO_printf(out, "IP Address:%d.%d.%d.%d",
2928edacedfSDaniel Fojt p[0], p[1], p[2], p[3]);
2938edacedfSDaniel Fojt else if (gen->d.ip->length == 16) {
2948edacedfSDaniel Fojt BIO_printf(out, "IP Address");
2958edacedfSDaniel Fojt for (i = 0; i < 8; i++) {
2968edacedfSDaniel Fojt BIO_printf(out, ":%X", p[0] << 8 | p[1]);
2978edacedfSDaniel Fojt p += 2;
2988edacedfSDaniel Fojt }
2998edacedfSDaniel Fojt BIO_puts(out, "\n");
3008edacedfSDaniel Fojt } else {
3018edacedfSDaniel Fojt BIO_printf(out, "IP Address:<invalid>");
3028edacedfSDaniel Fojt break;
3038edacedfSDaniel Fojt }
3048edacedfSDaniel Fojt break;
3058edacedfSDaniel Fojt
3068edacedfSDaniel Fojt case GEN_RID:
3078edacedfSDaniel Fojt BIO_printf(out, "Registered ID");
3088edacedfSDaniel Fojt i2a_ASN1_OBJECT(out, gen->d.rid);
3098edacedfSDaniel Fojt break;
3108edacedfSDaniel Fojt }
3118edacedfSDaniel Fojt return 1;
3128edacedfSDaniel Fojt }
3138edacedfSDaniel Fojt
3148edacedfSDaniel Fojt static GENERAL_NAMES *
v2i_issuer_alt(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)3158edacedfSDaniel Fojt v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
3168edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *nval)
3178edacedfSDaniel Fojt {
3188edacedfSDaniel Fojt GENERAL_NAMES *gens = NULL;
3198edacedfSDaniel Fojt CONF_VALUE *cnf;
3208edacedfSDaniel Fojt int i;
3218edacedfSDaniel Fojt
3228edacedfSDaniel Fojt if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
3238edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
3248edacedfSDaniel Fojt return NULL;
3258edacedfSDaniel Fojt }
3268edacedfSDaniel Fojt for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
3278edacedfSDaniel Fojt cnf = sk_CONF_VALUE_value(nval, i);
3288edacedfSDaniel Fojt if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL &&
3298edacedfSDaniel Fojt strcmp(cnf->value, "copy") == 0) {
3308edacedfSDaniel Fojt if (!copy_issuer(ctx, gens))
3318edacedfSDaniel Fojt goto err;
3328edacedfSDaniel Fojt } else {
3338edacedfSDaniel Fojt GENERAL_NAME *gen;
3348edacedfSDaniel Fojt if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
3358edacedfSDaniel Fojt goto err;
3368edacedfSDaniel Fojt if (sk_GENERAL_NAME_push(gens, gen) == 0) {
3378edacedfSDaniel Fojt GENERAL_NAME_free(gen);
3388edacedfSDaniel Fojt goto err;
3398edacedfSDaniel Fojt }
3408edacedfSDaniel Fojt }
3418edacedfSDaniel Fojt }
3428edacedfSDaniel Fojt return gens;
3438edacedfSDaniel Fojt
3448edacedfSDaniel Fojt err:
3458edacedfSDaniel Fojt sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
3468edacedfSDaniel Fojt return NULL;
3478edacedfSDaniel Fojt }
3488edacedfSDaniel Fojt
3498edacedfSDaniel Fojt /* Append subject altname of issuer to issuer alt name of subject */
3508edacedfSDaniel Fojt
3518edacedfSDaniel Fojt static int
copy_issuer(X509V3_CTX * ctx,GENERAL_NAMES * gens)3528edacedfSDaniel Fojt copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
3538edacedfSDaniel Fojt {
3548edacedfSDaniel Fojt GENERAL_NAMES *ialt;
3558edacedfSDaniel Fojt GENERAL_NAME *gen;
3568edacedfSDaniel Fojt X509_EXTENSION *ext;
3578edacedfSDaniel Fojt int i;
3588edacedfSDaniel Fojt
3598edacedfSDaniel Fojt if (ctx && (ctx->flags == CTX_TEST))
3608edacedfSDaniel Fojt return 1;
3618edacedfSDaniel Fojt if (!ctx || !ctx->issuer_cert) {
3628edacedfSDaniel Fojt X509V3error(X509V3_R_NO_ISSUER_DETAILS);
3638edacedfSDaniel Fojt goto err;
3648edacedfSDaniel Fojt }
3658edacedfSDaniel Fojt i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
3668edacedfSDaniel Fojt if (i < 0)
3678edacedfSDaniel Fojt return 1;
3688edacedfSDaniel Fojt if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
3698edacedfSDaniel Fojt !(ialt = X509V3_EXT_d2i(ext))) {
3708edacedfSDaniel Fojt X509V3error(X509V3_R_ISSUER_DECODE_ERROR);
3718edacedfSDaniel Fojt goto err;
3728edacedfSDaniel Fojt }
3738edacedfSDaniel Fojt
3748edacedfSDaniel Fojt for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
3758edacedfSDaniel Fojt gen = sk_GENERAL_NAME_value(ialt, i);
3768edacedfSDaniel Fojt if (!sk_GENERAL_NAME_push(gens, gen)) {
3778edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
3788edacedfSDaniel Fojt goto err;
3798edacedfSDaniel Fojt }
3808edacedfSDaniel Fojt }
3818edacedfSDaniel Fojt sk_GENERAL_NAME_free(ialt);
3828edacedfSDaniel Fojt
3838edacedfSDaniel Fojt return 1;
3848edacedfSDaniel Fojt
3858edacedfSDaniel Fojt err:
3868edacedfSDaniel Fojt return 0;
3878edacedfSDaniel Fojt
3888edacedfSDaniel Fojt }
3898edacedfSDaniel Fojt
3908edacedfSDaniel Fojt static GENERAL_NAMES *
v2i_subject_alt(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)3918edacedfSDaniel Fojt v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
3928edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *nval)
3938edacedfSDaniel Fojt {
3948edacedfSDaniel Fojt GENERAL_NAMES *gens = NULL;
3958edacedfSDaniel Fojt CONF_VALUE *cnf;
3968edacedfSDaniel Fojt int i;
3978edacedfSDaniel Fojt
3988edacedfSDaniel Fojt if (!(gens = sk_GENERAL_NAME_new_null())) {
3998edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
4008edacedfSDaniel Fojt return NULL;
4018edacedfSDaniel Fojt }
4028edacedfSDaniel Fojt for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
4038edacedfSDaniel Fojt cnf = sk_CONF_VALUE_value(nval, i);
4048edacedfSDaniel Fojt if (!name_cmp(cnf->name, "email") && cnf->value &&
4058edacedfSDaniel Fojt !strcmp(cnf->value, "copy")) {
4068edacedfSDaniel Fojt if (!copy_email(ctx, gens, 0))
4078edacedfSDaniel Fojt goto err;
4088edacedfSDaniel Fojt } else if (!name_cmp(cnf->name, "email") && cnf->value &&
4098edacedfSDaniel Fojt !strcmp(cnf->value, "move")) {
4108edacedfSDaniel Fojt if (!copy_email(ctx, gens, 1))
4118edacedfSDaniel Fojt goto err;
4128edacedfSDaniel Fojt } else {
4138edacedfSDaniel Fojt GENERAL_NAME *gen;
4148edacedfSDaniel Fojt if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
4158edacedfSDaniel Fojt goto err;
4168edacedfSDaniel Fojt if (sk_GENERAL_NAME_push(gens, gen) == 0) {
4178edacedfSDaniel Fojt GENERAL_NAME_free(gen);
4188edacedfSDaniel Fojt goto err;
4198edacedfSDaniel Fojt }
4208edacedfSDaniel Fojt }
4218edacedfSDaniel Fojt }
4228edacedfSDaniel Fojt return gens;
4238edacedfSDaniel Fojt
4248edacedfSDaniel Fojt err:
4258edacedfSDaniel Fojt sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
4268edacedfSDaniel Fojt return NULL;
4278edacedfSDaniel Fojt }
4288edacedfSDaniel Fojt
4298edacedfSDaniel Fojt /* Copy any email addresses in a certificate or request to
4308edacedfSDaniel Fojt * GENERAL_NAMES
4318edacedfSDaniel Fojt */
4328edacedfSDaniel Fojt
4338edacedfSDaniel Fojt static int
copy_email(X509V3_CTX * ctx,GENERAL_NAMES * gens,int move_p)4348edacedfSDaniel Fojt copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
4358edacedfSDaniel Fojt {
4368edacedfSDaniel Fojt X509_NAME *nm;
4378edacedfSDaniel Fojt ASN1_IA5STRING *email = NULL;
4388edacedfSDaniel Fojt X509_NAME_ENTRY *ne;
4398edacedfSDaniel Fojt GENERAL_NAME *gen = NULL;
4408edacedfSDaniel Fojt int i;
4418edacedfSDaniel Fojt
4428edacedfSDaniel Fojt if (ctx != NULL && ctx->flags == CTX_TEST)
4438edacedfSDaniel Fojt return 1;
4448edacedfSDaniel Fojt if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
4458edacedfSDaniel Fojt X509V3error(X509V3_R_NO_SUBJECT_DETAILS);
4468edacedfSDaniel Fojt goto err;
4478edacedfSDaniel Fojt }
4488edacedfSDaniel Fojt /* Find the subject name */
4498edacedfSDaniel Fojt if (ctx->subject_cert)
4508edacedfSDaniel Fojt nm = X509_get_subject_name(ctx->subject_cert);
4518edacedfSDaniel Fojt else
4528edacedfSDaniel Fojt nm = X509_REQ_get_subject_name(ctx->subject_req);
4538edacedfSDaniel Fojt
4548edacedfSDaniel Fojt /* Now add any email address(es) to STACK */
4558edacedfSDaniel Fojt i = -1;
4568edacedfSDaniel Fojt while ((i = X509_NAME_get_index_by_NID(nm,
4578edacedfSDaniel Fojt NID_pkcs9_emailAddress, i)) >= 0) {
4588edacedfSDaniel Fojt ne = X509_NAME_get_entry(nm, i);
4598edacedfSDaniel Fojt email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
4608edacedfSDaniel Fojt if (move_p) {
4618edacedfSDaniel Fojt X509_NAME_delete_entry(nm, i);
4628edacedfSDaniel Fojt X509_NAME_ENTRY_free(ne);
4638edacedfSDaniel Fojt i--;
4648edacedfSDaniel Fojt }
4658edacedfSDaniel Fojt if (!email || !(gen = GENERAL_NAME_new())) {
4668edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
4678edacedfSDaniel Fojt goto err;
4688edacedfSDaniel Fojt }
4698edacedfSDaniel Fojt gen->d.ia5 = email;
4708edacedfSDaniel Fojt email = NULL;
4718edacedfSDaniel Fojt gen->type = GEN_EMAIL;
4728edacedfSDaniel Fojt if (!sk_GENERAL_NAME_push(gens, gen)) {
4738edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
4748edacedfSDaniel Fojt goto err;
4758edacedfSDaniel Fojt }
4768edacedfSDaniel Fojt gen = NULL;
4778edacedfSDaniel Fojt }
4788edacedfSDaniel Fojt
4798edacedfSDaniel Fojt return 1;
4808edacedfSDaniel Fojt
4818edacedfSDaniel Fojt err:
4828edacedfSDaniel Fojt GENERAL_NAME_free(gen);
4838edacedfSDaniel Fojt ASN1_IA5STRING_free(email);
4848edacedfSDaniel Fojt return 0;
4858edacedfSDaniel Fojt }
4868edacedfSDaniel Fojt
4878edacedfSDaniel Fojt GENERAL_NAMES *
v2i_GENERAL_NAMES(const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)4888edacedfSDaniel Fojt v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
4898edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *nval)
4908edacedfSDaniel Fojt {
4918edacedfSDaniel Fojt GENERAL_NAME *gen;
4928edacedfSDaniel Fojt GENERAL_NAMES *gens = NULL;
4938edacedfSDaniel Fojt CONF_VALUE *cnf;
4948edacedfSDaniel Fojt int i;
4958edacedfSDaniel Fojt
4968edacedfSDaniel Fojt if (!(gens = sk_GENERAL_NAME_new_null())) {
4978edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
4988edacedfSDaniel Fojt return NULL;
4998edacedfSDaniel Fojt }
5008edacedfSDaniel Fojt for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
5018edacedfSDaniel Fojt cnf = sk_CONF_VALUE_value(nval, i);
5028edacedfSDaniel Fojt if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
5038edacedfSDaniel Fojt goto err;
5048edacedfSDaniel Fojt if (sk_GENERAL_NAME_push(gens, gen) == 0) {
5058edacedfSDaniel Fojt GENERAL_NAME_free(gen);
5068edacedfSDaniel Fojt goto err;
5078edacedfSDaniel Fojt }
5088edacedfSDaniel Fojt }
5098edacedfSDaniel Fojt return gens;
5108edacedfSDaniel Fojt
5118edacedfSDaniel Fojt err:
5128edacedfSDaniel Fojt sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
5138edacedfSDaniel Fojt return NULL;
5148edacedfSDaniel Fojt }
5158edacedfSDaniel Fojt
5168edacedfSDaniel Fojt GENERAL_NAME *
v2i_GENERAL_NAME(const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,CONF_VALUE * cnf)5178edacedfSDaniel Fojt v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
5188edacedfSDaniel Fojt CONF_VALUE *cnf)
5198edacedfSDaniel Fojt {
5208edacedfSDaniel Fojt return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
5218edacedfSDaniel Fojt }
5228edacedfSDaniel Fojt
5238edacedfSDaniel Fojt GENERAL_NAME *
a2i_GENERAL_NAME(GENERAL_NAME * out,const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,int gen_type,const char * value,int is_nc)5248edacedfSDaniel Fojt a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
5258edacedfSDaniel Fojt X509V3_CTX *ctx, int gen_type, const char *value, int is_nc)
5268edacedfSDaniel Fojt {
5278edacedfSDaniel Fojt char is_string = 0;
5288edacedfSDaniel Fojt GENERAL_NAME *gen = NULL;
5298edacedfSDaniel Fojt
5308edacedfSDaniel Fojt if (!value) {
5318edacedfSDaniel Fojt X509V3error(X509V3_R_MISSING_VALUE);
5328edacedfSDaniel Fojt return NULL;
5338edacedfSDaniel Fojt }
5348edacedfSDaniel Fojt
5358edacedfSDaniel Fojt if (out)
5368edacedfSDaniel Fojt gen = out;
5378edacedfSDaniel Fojt else {
5388edacedfSDaniel Fojt gen = GENERAL_NAME_new();
5398edacedfSDaniel Fojt if (gen == NULL) {
5408edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
5418edacedfSDaniel Fojt return NULL;
5428edacedfSDaniel Fojt }
5438edacedfSDaniel Fojt }
5448edacedfSDaniel Fojt
5458edacedfSDaniel Fojt switch (gen_type) {
5468edacedfSDaniel Fojt case GEN_URI:
5478edacedfSDaniel Fojt case GEN_EMAIL:
5488edacedfSDaniel Fojt case GEN_DNS:
5498edacedfSDaniel Fojt is_string = 1;
5508edacedfSDaniel Fojt break;
5518edacedfSDaniel Fojt
5528edacedfSDaniel Fojt case GEN_RID:
5538edacedfSDaniel Fojt {
5548edacedfSDaniel Fojt ASN1_OBJECT *obj;
5558edacedfSDaniel Fojt if (!(obj = OBJ_txt2obj(value, 0))) {
5568edacedfSDaniel Fojt X509V3error(X509V3_R_BAD_OBJECT);
5578edacedfSDaniel Fojt ERR_asprintf_error_data("value=%s", value);
5588edacedfSDaniel Fojt goto err;
5598edacedfSDaniel Fojt }
5608edacedfSDaniel Fojt gen->d.rid = obj;
5618edacedfSDaniel Fojt }
5628edacedfSDaniel Fojt break;
5638edacedfSDaniel Fojt
5648edacedfSDaniel Fojt case GEN_IPADD:
5658edacedfSDaniel Fojt if (is_nc)
5668edacedfSDaniel Fojt gen->d.ip = a2i_IPADDRESS_NC(value);
5678edacedfSDaniel Fojt else
5688edacedfSDaniel Fojt gen->d.ip = a2i_IPADDRESS(value);
5698edacedfSDaniel Fojt if (gen->d.ip == NULL) {
5708edacedfSDaniel Fojt X509V3error(X509V3_R_BAD_IP_ADDRESS);
5718edacedfSDaniel Fojt ERR_asprintf_error_data("value=%s", value);
5728edacedfSDaniel Fojt goto err;
5738edacedfSDaniel Fojt }
5748edacedfSDaniel Fojt break;
5758edacedfSDaniel Fojt
5768edacedfSDaniel Fojt case GEN_DIRNAME:
5778edacedfSDaniel Fojt if (!do_dirname(gen, value, ctx)) {
5788edacedfSDaniel Fojt X509V3error(X509V3_R_DIRNAME_ERROR);
5798edacedfSDaniel Fojt goto err;
5808edacedfSDaniel Fojt }
5818edacedfSDaniel Fojt break;
5828edacedfSDaniel Fojt
5838edacedfSDaniel Fojt case GEN_OTHERNAME:
5848edacedfSDaniel Fojt if (!do_othername(gen, value, ctx)) {
5858edacedfSDaniel Fojt X509V3error(X509V3_R_OTHERNAME_ERROR);
5868edacedfSDaniel Fojt goto err;
5878edacedfSDaniel Fojt }
5888edacedfSDaniel Fojt break;
5898edacedfSDaniel Fojt
5908edacedfSDaniel Fojt default:
5918edacedfSDaniel Fojt X509V3error(X509V3_R_UNSUPPORTED_TYPE);
5928edacedfSDaniel Fojt goto err;
5938edacedfSDaniel Fojt }
5948edacedfSDaniel Fojt
5958edacedfSDaniel Fojt if (is_string) {
5968edacedfSDaniel Fojt if (!(gen->d.ia5 = ASN1_IA5STRING_new()) ||
5978edacedfSDaniel Fojt !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) {
5988edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
5998edacedfSDaniel Fojt goto err;
6008edacedfSDaniel Fojt }
6018edacedfSDaniel Fojt }
6028edacedfSDaniel Fojt
6038edacedfSDaniel Fojt gen->type = gen_type;
6048edacedfSDaniel Fojt
6058edacedfSDaniel Fojt return gen;
6068edacedfSDaniel Fojt
6078edacedfSDaniel Fojt err:
6088edacedfSDaniel Fojt if (out == NULL)
6098edacedfSDaniel Fojt GENERAL_NAME_free(gen);
6108edacedfSDaniel Fojt return NULL;
6118edacedfSDaniel Fojt }
6128edacedfSDaniel Fojt
6138edacedfSDaniel Fojt GENERAL_NAME *
v2i_GENERAL_NAME_ex(GENERAL_NAME * out,const X509V3_EXT_METHOD * method,X509V3_CTX * ctx,CONF_VALUE * cnf,int is_nc)6148edacedfSDaniel Fojt v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
6158edacedfSDaniel Fojt X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
6168edacedfSDaniel Fojt {
617*de0e0e4dSAntonio Huete Jimenez uint8_t *bytes = NULL;
6188edacedfSDaniel Fojt char *name, *value;
619*de0e0e4dSAntonio Huete Jimenez GENERAL_NAME *ret;
620*de0e0e4dSAntonio Huete Jimenez size_t len = 0;
621*de0e0e4dSAntonio Huete Jimenez int type;
6228edacedfSDaniel Fojt
6238edacedfSDaniel Fojt name = cnf->name;
6248edacedfSDaniel Fojt value = cnf->value;
6258edacedfSDaniel Fojt
6268edacedfSDaniel Fojt if (!value) {
6278edacedfSDaniel Fojt X509V3error(X509V3_R_MISSING_VALUE);
6288edacedfSDaniel Fojt return NULL;
6298edacedfSDaniel Fojt }
6308edacedfSDaniel Fojt
6318edacedfSDaniel Fojt if (!name_cmp(name, "email"))
6328edacedfSDaniel Fojt type = GEN_EMAIL;
6338edacedfSDaniel Fojt else if (!name_cmp(name, "URI"))
6348edacedfSDaniel Fojt type = GEN_URI;
6358edacedfSDaniel Fojt else if (!name_cmp(name, "DNS"))
6368edacedfSDaniel Fojt type = GEN_DNS;
6378edacedfSDaniel Fojt else if (!name_cmp(name, "RID"))
6388edacedfSDaniel Fojt type = GEN_RID;
6398edacedfSDaniel Fojt else if (!name_cmp(name, "IP"))
6408edacedfSDaniel Fojt type = GEN_IPADD;
6418edacedfSDaniel Fojt else if (!name_cmp(name, "dirName"))
6428edacedfSDaniel Fojt type = GEN_DIRNAME;
6438edacedfSDaniel Fojt else if (!name_cmp(name, "otherName"))
6448edacedfSDaniel Fojt type = GEN_OTHERNAME;
6458edacedfSDaniel Fojt else {
6468edacedfSDaniel Fojt X509V3error(X509V3_R_UNSUPPORTED_OPTION);
6478edacedfSDaniel Fojt ERR_asprintf_error_data("name=%s", name);
6488edacedfSDaniel Fojt return NULL;
6498edacedfSDaniel Fojt }
6508edacedfSDaniel Fojt
651*de0e0e4dSAntonio Huete Jimenez ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
652*de0e0e4dSAntonio Huete Jimenez if (ret == NULL)
653*de0e0e4dSAntonio Huete Jimenez return NULL;
654*de0e0e4dSAntonio Huete Jimenez
655*de0e0e4dSAntonio Huete Jimenez /*
656*de0e0e4dSAntonio Huete Jimenez * Validate what we have for sanity.
657*de0e0e4dSAntonio Huete Jimenez */
658*de0e0e4dSAntonio Huete Jimenez
659*de0e0e4dSAntonio Huete Jimenez if (is_nc) {
660*de0e0e4dSAntonio Huete Jimenez struct x509_constraints_name *constraints_name = NULL;
661*de0e0e4dSAntonio Huete Jimenez
662*de0e0e4dSAntonio Huete Jimenez if (!x509_constraints_validate(ret, &constraints_name, NULL)) {
663*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_BAD_OBJECT);
664*de0e0e4dSAntonio Huete Jimenez ERR_asprintf_error_data("name=%s", name);
665*de0e0e4dSAntonio Huete Jimenez goto err;
666*de0e0e4dSAntonio Huete Jimenez }
667*de0e0e4dSAntonio Huete Jimenez x509_constraints_name_free(constraints_name);
668*de0e0e4dSAntonio Huete Jimenez return ret;
669*de0e0e4dSAntonio Huete Jimenez }
670*de0e0e4dSAntonio Huete Jimenez
671*de0e0e4dSAntonio Huete Jimenez type = x509_constraints_general_to_bytes(ret, &bytes, &len);
672*de0e0e4dSAntonio Huete Jimenez switch (type) {
673*de0e0e4dSAntonio Huete Jimenez case GEN_DNS:
674*de0e0e4dSAntonio Huete Jimenez if (!x509_constraints_valid_sandns(bytes, len)) {
675*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_BAD_OBJECT);
676*de0e0e4dSAntonio Huete Jimenez ERR_asprintf_error_data("name=%s value='%.*s'", name,
677*de0e0e4dSAntonio Huete Jimenez (int)len, bytes);
678*de0e0e4dSAntonio Huete Jimenez goto err;
679*de0e0e4dSAntonio Huete Jimenez }
680*de0e0e4dSAntonio Huete Jimenez break;
681*de0e0e4dSAntonio Huete Jimenez case GEN_URI:
682*de0e0e4dSAntonio Huete Jimenez if (!x509_constraints_uri_host(bytes, len, NULL)) {
683*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_BAD_OBJECT);
684*de0e0e4dSAntonio Huete Jimenez ERR_asprintf_error_data("name=%s value='%.*s'", name,
685*de0e0e4dSAntonio Huete Jimenez (int)len, bytes);
686*de0e0e4dSAntonio Huete Jimenez goto err;
687*de0e0e4dSAntonio Huete Jimenez }
688*de0e0e4dSAntonio Huete Jimenez break;
689*de0e0e4dSAntonio Huete Jimenez case GEN_EMAIL:
690*de0e0e4dSAntonio Huete Jimenez if (!x509_constraints_parse_mailbox(bytes, len, NULL)) {
691*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_BAD_OBJECT);
692*de0e0e4dSAntonio Huete Jimenez ERR_asprintf_error_data("name=%s value='%.*s'", name,
693*de0e0e4dSAntonio Huete Jimenez (int)len, bytes);
694*de0e0e4dSAntonio Huete Jimenez goto err;
695*de0e0e4dSAntonio Huete Jimenez }
696*de0e0e4dSAntonio Huete Jimenez break;
697*de0e0e4dSAntonio Huete Jimenez case GEN_IPADD:
698*de0e0e4dSAntonio Huete Jimenez if (len != 4 && len != 16) {
699*de0e0e4dSAntonio Huete Jimenez X509V3error(X509V3_R_BAD_IP_ADDRESS);
700*de0e0e4dSAntonio Huete Jimenez ERR_asprintf_error_data("name=%s len=%zu", name, len);
701*de0e0e4dSAntonio Huete Jimenez goto err;
702*de0e0e4dSAntonio Huete Jimenez }
703*de0e0e4dSAntonio Huete Jimenez break;
704*de0e0e4dSAntonio Huete Jimenez default:
705*de0e0e4dSAntonio Huete Jimenez break;
706*de0e0e4dSAntonio Huete Jimenez }
707*de0e0e4dSAntonio Huete Jimenez return ret;
708*de0e0e4dSAntonio Huete Jimenez err:
709*de0e0e4dSAntonio Huete Jimenez if (out == NULL)
710*de0e0e4dSAntonio Huete Jimenez GENERAL_NAME_free(ret);
711*de0e0e4dSAntonio Huete Jimenez return NULL;
7128edacedfSDaniel Fojt }
7138edacedfSDaniel Fojt
7148edacedfSDaniel Fojt static int
do_othername(GENERAL_NAME * gen,const char * value,X509V3_CTX * ctx)7158edacedfSDaniel Fojt do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
7168edacedfSDaniel Fojt {
7178edacedfSDaniel Fojt char *objtmp = NULL, *p;
7188edacedfSDaniel Fojt int objlen;
7198edacedfSDaniel Fojt
7208edacedfSDaniel Fojt if (!(p = strchr(value, ';')))
7218edacedfSDaniel Fojt return 0;
7228edacedfSDaniel Fojt if (!(gen->d.otherName = OTHERNAME_new()))
7238edacedfSDaniel Fojt return 0;
7248edacedfSDaniel Fojt /* Free this up because we will overwrite it.
7258edacedfSDaniel Fojt * no need to free type_id because it is static
7268edacedfSDaniel Fojt */
7278edacedfSDaniel Fojt ASN1_TYPE_free(gen->d.otherName->value);
7288edacedfSDaniel Fojt if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
7298edacedfSDaniel Fojt return 0;
7308edacedfSDaniel Fojt objlen = p - value;
7318edacedfSDaniel Fojt objtmp = malloc(objlen + 1);
7328edacedfSDaniel Fojt if (objtmp) {
7338edacedfSDaniel Fojt strlcpy(objtmp, value, objlen + 1);
7348edacedfSDaniel Fojt gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
7358edacedfSDaniel Fojt free(objtmp);
7368edacedfSDaniel Fojt } else
7378edacedfSDaniel Fojt gen->d.otherName->type_id = NULL;
7388edacedfSDaniel Fojt if (!gen->d.otherName->type_id)
7398edacedfSDaniel Fojt return 0;
7408edacedfSDaniel Fojt return 1;
7418edacedfSDaniel Fojt }
7428edacedfSDaniel Fojt
7438edacedfSDaniel Fojt static int
do_dirname(GENERAL_NAME * gen,const char * value,X509V3_CTX * ctx)7448edacedfSDaniel Fojt do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
7458edacedfSDaniel Fojt {
7468edacedfSDaniel Fojt int ret;
7478edacedfSDaniel Fojt STACK_OF(CONF_VALUE) *sk;
7488edacedfSDaniel Fojt X509_NAME *nm;
7498edacedfSDaniel Fojt
7508edacedfSDaniel Fojt if (!(nm = X509_NAME_new()))
7518edacedfSDaniel Fojt return 0;
7528edacedfSDaniel Fojt sk = X509V3_get_section(ctx, value);
7538edacedfSDaniel Fojt if (!sk) {
7548edacedfSDaniel Fojt X509V3error(X509V3_R_SECTION_NOT_FOUND);
7558edacedfSDaniel Fojt ERR_asprintf_error_data("section=%s", value);
7568edacedfSDaniel Fojt X509_NAME_free(nm);
7578edacedfSDaniel Fojt return 0;
7588edacedfSDaniel Fojt }
7598edacedfSDaniel Fojt /* FIXME: should allow other character types... */
7608edacedfSDaniel Fojt ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
7618edacedfSDaniel Fojt if (!ret)
7628edacedfSDaniel Fojt X509_NAME_free(nm);
7638edacedfSDaniel Fojt gen->d.dirn = nm;
7648edacedfSDaniel Fojt X509V3_section_free(ctx, sk);
7658edacedfSDaniel Fojt
7668edacedfSDaniel Fojt return ret;
7678edacedfSDaniel Fojt }
768