xref: /dflybsd-src/crypto/libressl/crypto/x509/x509_alt.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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