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 + }