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