os/ossrv/ssl/libcrypto/src/crypto/x509v3/v3_alt.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/x509v3/v3_alt.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,612 @@
     1.4 +/* v3_alt.c */
     1.5 +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
     1.6 + * project.
     1.7 + */
     1.8 +/* ====================================================================
     1.9 + * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
    1.10 + *
    1.11 + * Redistribution and use in source and binary forms, with or without
    1.12 + * modification, are permitted provided that the following conditions
    1.13 + * are met:
    1.14 + *
    1.15 + * 1. Redistributions of source code must retain the above copyright
    1.16 + *    notice, this list of conditions and the following disclaimer. 
    1.17 + *
    1.18 + * 2. Redistributions in binary form must reproduce the above copyright
    1.19 + *    notice, this list of conditions and the following disclaimer in
    1.20 + *    the documentation and/or other materials provided with the
    1.21 + *    distribution.
    1.22 + *
    1.23 + * 3. All advertising materials mentioning features or use of this
    1.24 + *    software must display the following acknowledgment:
    1.25 + *    "This product includes software developed by the OpenSSL Project
    1.26 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
    1.27 + *
    1.28 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.29 + *    endorse or promote products derived from this software without
    1.30 + *    prior written permission. For written permission, please contact
    1.31 + *    licensing@OpenSSL.org.
    1.32 + *
    1.33 + * 5. Products derived from this software may not be called "OpenSSL"
    1.34 + *    nor may "OpenSSL" appear in their names without prior written
    1.35 + *    permission of the OpenSSL Project.
    1.36 + *
    1.37 + * 6. Redistributions of any form whatsoever must retain the following
    1.38 + *    acknowledgment:
    1.39 + *    "This product includes software developed by the OpenSSL Project
    1.40 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
    1.41 + *
    1.42 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.43 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.44 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.45 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.46 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.47 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.48 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    1.49 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.50 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    1.51 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.52 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    1.53 + * OF THE POSSIBILITY OF SUCH DAMAGE.
    1.54 + * ====================================================================
    1.55 + *
    1.56 + * This product includes cryptographic software written by Eric Young
    1.57 + * (eay@cryptsoft.com).  This product includes software written by Tim
    1.58 + * Hudson (tjh@cryptsoft.com).
    1.59 + *
    1.60 + */
    1.61 + /*
    1.62 + © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
    1.63 + */
    1.64 +
    1.65 +
    1.66 +#include <stdio.h>
    1.67 +#include "cryptlib.h"
    1.68 +#include <openssl/conf.h>
    1.69 +#include <openssl/x509v3.h>
    1.70 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
    1.71 +#include "libcrypto_wsd_macros.h"
    1.72 +#include "libcrypto_wsd.h"
    1.73 +#endif
    1.74 +
    1.75 +
    1.76 +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
    1.77 +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
    1.78 +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
    1.79 +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
    1.80 +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
    1.81 +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx);
    1.82 +
    1.83 +#ifndef EMULATOR
    1.84 +X509V3_EXT_METHOD v3_alt[] = {
    1.85 +{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
    1.86 +0,0,0,0,
    1.87 +0,0,
    1.88 +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
    1.89 +(X509V3_EXT_V2I)v2i_subject_alt,
    1.90 +NULL, NULL, NULL},
    1.91 +
    1.92 +{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
    1.93 +0,0,0,0,
    1.94 +0,0,
    1.95 +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
    1.96 +(X509V3_EXT_V2I)v2i_issuer_alt,
    1.97 +NULL, NULL, NULL},
    1.98 +};
    1.99 +#else
   1.100 +const X509V3_EXT_METHOD v3_alt[] = {
   1.101 +{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
   1.102 +0,0,0,0,
   1.103 +0,0,
   1.104 +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
   1.105 +(X509V3_EXT_V2I)v2i_subject_alt,
   1.106 +NULL, NULL, NULL},
   1.107 +
   1.108 +{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
   1.109 +0,0,0,0,
   1.110 +0,0,
   1.111 +(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
   1.112 +(X509V3_EXT_V2I)v2i_issuer_alt,
   1.113 +NULL, NULL, NULL},
   1.114 +};
   1.115 +
   1.116 +#endif
   1.117 +EXPORT_C STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
   1.118 +		GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret)
   1.119 +{
   1.120 +	int i;
   1.121 +	GENERAL_NAME *gen;
   1.122 +	for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
   1.123 +		gen = sk_GENERAL_NAME_value(gens, i);
   1.124 +		ret = i2v_GENERAL_NAME(method, gen, ret);
   1.125 +	}
   1.126 +	if(!ret) return sk_CONF_VALUE_new_null();
   1.127 +	return ret;
   1.128 +}
   1.129 +
   1.130 +EXPORT_C STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
   1.131 +				GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
   1.132 +{
   1.133 +	unsigned char *p;
   1.134 +	char oline[256], htmp[5];
   1.135 +	int i;
   1.136 +	switch (gen->type)
   1.137 +	{
   1.138 +		case GEN_OTHERNAME:
   1.139 +		X509V3_add_value("othername","<unsupported>", &ret);
   1.140 +		break;
   1.141 +
   1.142 +		case GEN_X400:
   1.143 +		X509V3_add_value("X400Name","<unsupported>", &ret);
   1.144 +		break;
   1.145 +
   1.146 +		case GEN_EDIPARTY:
   1.147 +		X509V3_add_value("EdiPartyName","<unsupported>", &ret);
   1.148 +		break;
   1.149 +
   1.150 +		case GEN_EMAIL:
   1.151 +		X509V3_add_value_uchar("email",gen->d.ia5->data, &ret);
   1.152 +		break;
   1.153 +
   1.154 +		case GEN_DNS:
   1.155 +		X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret);
   1.156 +		break;
   1.157 +
   1.158 +		case GEN_URI:
   1.159 +		X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret);
   1.160 +		break;
   1.161 +
   1.162 +		case GEN_DIRNAME:
   1.163 +		X509_NAME_oneline(gen->d.dirn, oline, 256);
   1.164 +		X509V3_add_value("DirName",oline, &ret);
   1.165 +		break;
   1.166 +
   1.167 +		case GEN_IPADD:
   1.168 +		p = gen->d.ip->data;
   1.169 +		if(gen->d.ip->length == 4)
   1.170 +			BIO_snprintf(oline, sizeof oline,
   1.171 +				     "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
   1.172 +		else if(gen->d.ip->length == 16)
   1.173 +			{
   1.174 +			oline[0] = 0;
   1.175 +			for (i = 0; i < 8; i++)
   1.176 +				{
   1.177 +				BIO_snprintf(htmp, sizeof htmp,
   1.178 +					     "%X", p[0] << 8 | p[1]);
   1.179 +				p += 2;
   1.180 +				strcat(oline, htmp);
   1.181 +				if (i != 7)
   1.182 +					strcat(oline, ":");
   1.183 +				}
   1.184 +			}
   1.185 +		else
   1.186 +			{
   1.187 +			X509V3_add_value("IP Address","<invalid>", &ret);
   1.188 +			break;
   1.189 +			}
   1.190 +		X509V3_add_value("IP Address",oline, &ret);
   1.191 +		break;
   1.192 +
   1.193 +		case GEN_RID:
   1.194 +		i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
   1.195 +		X509V3_add_value("Registered ID",oline, &ret);
   1.196 +		break;
   1.197 +	}
   1.198 +	return ret;
   1.199 +}
   1.200 +
   1.201 +EXPORT_C int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
   1.202 +{
   1.203 +	unsigned char *p;
   1.204 +	int i;
   1.205 +	switch (gen->type)
   1.206 +	{
   1.207 +		case GEN_OTHERNAME:
   1.208 +		BIO_printf(out, "othername:<unsupported>");
   1.209 +		break;
   1.210 +
   1.211 +		case GEN_X400:
   1.212 +		BIO_printf(out, "X400Name:<unsupported>");
   1.213 +		break;
   1.214 +
   1.215 +		case GEN_EDIPARTY:
   1.216 +		/* Maybe fix this: it is supported now */
   1.217 +		BIO_printf(out, "EdiPartyName:<unsupported>");
   1.218 +		break;
   1.219 +
   1.220 +		case GEN_EMAIL:
   1.221 +		BIO_printf(out, "email:%s",gen->d.ia5->data);
   1.222 +		break;
   1.223 +
   1.224 +		case GEN_DNS:
   1.225 +		BIO_printf(out, "DNS:%s",gen->d.ia5->data);
   1.226 +		break;
   1.227 +
   1.228 +		case GEN_URI:
   1.229 +		BIO_printf(out, "URI:%s",gen->d.ia5->data);
   1.230 +		break;
   1.231 +
   1.232 +		case GEN_DIRNAME:
   1.233 +		BIO_printf(out, "DirName: ");
   1.234 +		X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
   1.235 +		break;
   1.236 +
   1.237 +		case GEN_IPADD:
   1.238 +		p = gen->d.ip->data;
   1.239 +		if(gen->d.ip->length == 4)
   1.240 +			BIO_printf(out, "IP Address:%d.%d.%d.%d",
   1.241 +						p[0], p[1], p[2], p[3]);
   1.242 +		else if(gen->d.ip->length == 16)
   1.243 +			{
   1.244 +			BIO_printf(out, "IP Address");
   1.245 +			for (i = 0; i < 8; i++)
   1.246 +				{
   1.247 +				BIO_printf(out, ":%X", p[0] << 8 | p[1]);
   1.248 +				p += 2;
   1.249 +				}
   1.250 +			BIO_puts(out, "\n");
   1.251 +			}
   1.252 +		else
   1.253 +			{
   1.254 +			BIO_printf(out,"IP Address:<invalid>");
   1.255 +			break;
   1.256 +			}
   1.257 +		break;
   1.258 +
   1.259 +		case GEN_RID:
   1.260 +		BIO_printf(out, "Registered ID");
   1.261 +		i2a_ASN1_OBJECT(out, gen->d.rid);
   1.262 +		break;
   1.263 +	}
   1.264 +	return 1;
   1.265 +}
   1.266 +
   1.267 +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
   1.268 +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
   1.269 +{
   1.270 +	GENERAL_NAMES *gens = NULL;
   1.271 +	CONF_VALUE *cnf;
   1.272 +	int i;
   1.273 +	if(!(gens = sk_GENERAL_NAME_new_null())) {
   1.274 +		X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE);
   1.275 +		return NULL;
   1.276 +	}
   1.277 +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
   1.278 +		cnf = sk_CONF_VALUE_value(nval, i);
   1.279 +		if(!name_cmp(cnf->name, "issuer") && cnf->value &&
   1.280 +						!strcmp(cnf->value, "copy")) {
   1.281 +			if(!copy_issuer(ctx, gens)) goto err;
   1.282 +		} else {
   1.283 +			GENERAL_NAME *gen;
   1.284 +			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
   1.285 +								 goto err; 
   1.286 +			sk_GENERAL_NAME_push(gens, gen);
   1.287 +		}
   1.288 +	}
   1.289 +	return gens;
   1.290 +	err:
   1.291 +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
   1.292 +	return NULL;
   1.293 +}
   1.294 +
   1.295 +/* Append subject altname of issuer to issuer alt name of subject */
   1.296 +
   1.297 +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
   1.298 +{
   1.299 +	GENERAL_NAMES *ialt;
   1.300 +	GENERAL_NAME *gen;
   1.301 +	X509_EXTENSION *ext;
   1.302 +	int i;
   1.303 +	if(ctx && (ctx->flags == CTX_TEST)) return 1;
   1.304 +	if(!ctx || !ctx->issuer_cert) {
   1.305 +		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS);
   1.306 +		goto err;
   1.307 +	}
   1.308 +        i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
   1.309 +	if(i < 0) return 1;
   1.310 +        if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
   1.311 +                        !(ialt = X509V3_EXT_d2i(ext)) ) {
   1.312 +		X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR);
   1.313 +		goto err;
   1.314 +	}
   1.315 +
   1.316 +	for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
   1.317 +		gen = sk_GENERAL_NAME_value(ialt, i);
   1.318 +		if(!sk_GENERAL_NAME_push(gens, gen)) {
   1.319 +			X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE);
   1.320 +			goto err;
   1.321 +		}
   1.322 +	}
   1.323 +	sk_GENERAL_NAME_free(ialt);
   1.324 +
   1.325 +	return 1;
   1.326 +		
   1.327 +	err:
   1.328 +	return 0;
   1.329 +	
   1.330 +}
   1.331 +
   1.332 +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
   1.333 +				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
   1.334 +{
   1.335 +	GENERAL_NAMES *gens = NULL;
   1.336 +	CONF_VALUE *cnf;
   1.337 +	int i;
   1.338 +	if(!(gens = sk_GENERAL_NAME_new_null())) {
   1.339 +		X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE);
   1.340 +		return NULL;
   1.341 +	}
   1.342 +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
   1.343 +		cnf = sk_CONF_VALUE_value(nval, i);
   1.344 +		if(!name_cmp(cnf->name, "email") && cnf->value &&
   1.345 +						!strcmp(cnf->value, "copy")) {
   1.346 +			if(!copy_email(ctx, gens, 0)) goto err;
   1.347 +		} else if(!name_cmp(cnf->name, "email") && cnf->value &&
   1.348 +						!strcmp(cnf->value, "move")) {
   1.349 +			if(!copy_email(ctx, gens, 1)) goto err;
   1.350 +		} else {
   1.351 +			GENERAL_NAME *gen;
   1.352 +			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
   1.353 +								 goto err; 
   1.354 +			sk_GENERAL_NAME_push(gens, gen);
   1.355 +		}
   1.356 +	}
   1.357 +	return gens;
   1.358 +	err:
   1.359 +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
   1.360 +	return NULL;
   1.361 +}
   1.362 +
   1.363 +/* Copy any email addresses in a certificate or request to 
   1.364 + * GENERAL_NAMES
   1.365 + */
   1.366 +
   1.367 +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
   1.368 +{
   1.369 +	X509_NAME *nm;
   1.370 +	ASN1_IA5STRING *email = NULL;
   1.371 +	X509_NAME_ENTRY *ne;
   1.372 +	GENERAL_NAME *gen = NULL;
   1.373 +	int i;
   1.374 +	if(ctx != NULL && ctx->flags == CTX_TEST)
   1.375 +		return 1;
   1.376 +	if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
   1.377 +		X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS);
   1.378 +		goto err;
   1.379 +	}
   1.380 +	/* Find the subject name */
   1.381 +	if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert);
   1.382 +	else nm = X509_REQ_get_subject_name(ctx->subject_req);
   1.383 +
   1.384 +	/* Now add any email address(es) to STACK */
   1.385 +	i = -1;
   1.386 +	while((i = X509_NAME_get_index_by_NID(nm,
   1.387 +					 NID_pkcs9_emailAddress, i)) >= 0) {
   1.388 +		ne = X509_NAME_get_entry(nm, i);
   1.389 +		email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne));
   1.390 +                if (move_p)
   1.391 +                        {
   1.392 +                        X509_NAME_delete_entry(nm, i);
   1.393 +                        i--;
   1.394 +                        }
   1.395 +		if(!email || !(gen = GENERAL_NAME_new())) {
   1.396 +			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
   1.397 +			goto err;
   1.398 +		}
   1.399 +		gen->d.ia5 = email;
   1.400 +		email = NULL;
   1.401 +		gen->type = GEN_EMAIL;
   1.402 +		if(!sk_GENERAL_NAME_push(gens, gen)) {
   1.403 +			X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE);
   1.404 +			goto err;
   1.405 +		}
   1.406 +		gen = NULL;
   1.407 +	}
   1.408 +
   1.409 +	
   1.410 +	return 1;
   1.411 +		
   1.412 +	err:
   1.413 +	GENERAL_NAME_free(gen);
   1.414 +	M_ASN1_IA5STRING_free(email);
   1.415 +	return 0;
   1.416 +	
   1.417 +}
   1.418 +
   1.419 +EXPORT_C GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
   1.420 +				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
   1.421 +{
   1.422 +	GENERAL_NAME *gen;
   1.423 +	GENERAL_NAMES *gens = NULL;
   1.424 +	CONF_VALUE *cnf;
   1.425 +	int i;
   1.426 +	if(!(gens = sk_GENERAL_NAME_new_null())) {
   1.427 +		X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE);
   1.428 +		return NULL;
   1.429 +	}
   1.430 +	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
   1.431 +		cnf = sk_CONF_VALUE_value(nval, i);
   1.432 +		if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
   1.433 +		sk_GENERAL_NAME_push(gens, gen);
   1.434 +	}
   1.435 +	return gens;
   1.436 +	err:
   1.437 +	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
   1.438 +	return NULL;
   1.439 +}
   1.440 +
   1.441 +EXPORT_C GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
   1.442 +							 CONF_VALUE *cnf)
   1.443 +	{
   1.444 +	return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
   1.445 +	}
   1.446 +
   1.447 +EXPORT_C GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
   1.448 +				X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
   1.449 +						 CONF_VALUE *cnf, int is_nc)
   1.450 +	{
   1.451 +	char is_string = 0;
   1.452 +	int type;
   1.453 +	GENERAL_NAME *gen = NULL;
   1.454 +
   1.455 +	char *name, *value;
   1.456 +
   1.457 +	name = cnf->name;
   1.458 +	value = cnf->value;
   1.459 +
   1.460 +	if(!value)
   1.461 +		{
   1.462 +		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
   1.463 +		return NULL;
   1.464 +		}
   1.465 +
   1.466 +	if (out)
   1.467 +		gen = out;
   1.468 +	else
   1.469 +		{
   1.470 +		gen = GENERAL_NAME_new();
   1.471 +		if(gen == NULL)
   1.472 +			{
   1.473 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
   1.474 +			return NULL;
   1.475 +			}
   1.476 +		}
   1.477 +
   1.478 +	if(!name_cmp(name, "email"))
   1.479 +		{
   1.480 +		is_string = 1;
   1.481 +		type = GEN_EMAIL;
   1.482 +		}
   1.483 +	else if(!name_cmp(name, "URI"))
   1.484 +		{
   1.485 +		is_string = 1;
   1.486 +		type = GEN_URI;
   1.487 +		}
   1.488 +	else if(!name_cmp(name, "DNS"))
   1.489 +		{
   1.490 +		is_string = 1;
   1.491 +		type = GEN_DNS;
   1.492 +		}
   1.493 +	else if(!name_cmp(name, "RID"))
   1.494 +		{
   1.495 +		ASN1_OBJECT *obj;
   1.496 +		if(!(obj = OBJ_txt2obj(value,0)))
   1.497 +			{
   1.498 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_OBJECT);
   1.499 +			ERR_add_error_data(2, "value=", value);
   1.500 +			goto err;
   1.501 +			}
   1.502 +		gen->d.rid = obj;
   1.503 +		type = GEN_RID;
   1.504 +		}
   1.505 +	else if(!name_cmp(name, "IP"))
   1.506 +		{
   1.507 +		if (is_nc)
   1.508 +			gen->d.ip = a2i_IPADDRESS_NC(value);
   1.509 +		else
   1.510 +			gen->d.ip = a2i_IPADDRESS(value);
   1.511 +		if(gen->d.ip == NULL)
   1.512 +			{
   1.513 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_IP_ADDRESS);
   1.514 +			ERR_add_error_data(2, "value=", value);
   1.515 +			goto err;
   1.516 +			}
   1.517 +		type = GEN_IPADD;
   1.518 +		}
   1.519 +	else if(!name_cmp(name, "dirName"))
   1.520 +		{
   1.521 +		type = GEN_DIRNAME;
   1.522 +		if (!do_dirname(gen, value, ctx))
   1.523 +			{
   1.524 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_DIRNAME_ERROR);
   1.525 +			goto err;
   1.526 +			}
   1.527 +		}
   1.528 +	else if(!name_cmp(name, "otherName"))
   1.529 +		{
   1.530 +		if (!do_othername(gen, value, ctx))
   1.531 +			{
   1.532 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_OTHERNAME_ERROR);
   1.533 +			goto err;
   1.534 +			}
   1.535 +		type = GEN_OTHERNAME;
   1.536 +		}
   1.537 +	else
   1.538 +		{
   1.539 +		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
   1.540 +		ERR_add_error_data(2, "name=", name);
   1.541 +		goto err;
   1.542 +		}
   1.543 +
   1.544 +	if(is_string)
   1.545 +		{
   1.546 +		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
   1.547 +			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
   1.548 +					       strlen(value)))
   1.549 +			{
   1.550 +			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
   1.551 +			goto err;
   1.552 +			}
   1.553 +		}
   1.554 +
   1.555 +	gen->type = type;
   1.556 +
   1.557 +	return gen;
   1.558 +
   1.559 +	err:
   1.560 +	GENERAL_NAME_free(gen);
   1.561 +	return NULL;
   1.562 +	}
   1.563 +
   1.564 +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
   1.565 +	{
   1.566 +	char *objtmp = NULL, *p;
   1.567 +	int objlen;
   1.568 +	if (!(p = strchr(value, ';')))
   1.569 +		return 0;
   1.570 +	if (!(gen->d.otherName = OTHERNAME_new()))
   1.571 +		return 0;
   1.572 +	/* Free this up because we will overwrite it.
   1.573 +	 * no need to free type_id because it is static
   1.574 +	 */
   1.575 +	ASN1_TYPE_free(gen->d.otherName->value);
   1.576 +	if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
   1.577 +		return 0;
   1.578 +	objlen = p - value;
   1.579 +	objtmp = OPENSSL_malloc(objlen + 1);
   1.580 +#ifdef SYMBIAN
   1.581 +	if(objtmp==NULL)
   1.582 +	return 0;
   1.583 +#endif
   1.584 +	strncpy(objtmp, value, objlen);
   1.585 +	objtmp[objlen] = 0;
   1.586 +	gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
   1.587 +	OPENSSL_free(objtmp);	
   1.588 +	if (!gen->d.otherName->type_id)
   1.589 +		return 0;
   1.590 +	return 1;
   1.591 +	}
   1.592 +
   1.593 +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
   1.594 +	{
   1.595 +	int ret;
   1.596 +	STACK_OF(CONF_VALUE) *sk;
   1.597 +	X509_NAME *nm;
   1.598 +	if (!(nm = X509_NAME_new()))
   1.599 +		return 0;
   1.600 +	sk = X509V3_get_section(ctx, value);
   1.601 +	if (!sk)
   1.602 +		{
   1.603 +		X509V3err(X509V3_F_DO_DIRNAME,X509V3_R_SECTION_NOT_FOUND);
   1.604 +		ERR_add_error_data(2, "section=", value);
   1.605 +		X509_NAME_free(nm);
   1.606 +		return 0;
   1.607 +		}
   1.608 +	/* FIXME: should allow other character types... */
   1.609 +	ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
   1.610 +	if (!ret)
   1.611 +		X509_NAME_free(nm);
   1.612 +	gen->d.dirn = nm;
   1.613 +		
   1.614 +	return ret;
   1.615 +	}