155714Skris/* v3_alt.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4160814Ssimon * project. 555714Skris */ 655714Skris/* ==================================================================== 7160814Ssimon * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1355714Skris * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 1555714Skris * 1655714Skris * 2. Redistributions in binary form must reproduce the above copyright 1755714Skris * notice, this list of conditions and the following disclaimer in 1855714Skris * the documentation and/or other materials provided with the 1955714Skris * distribution. 2055714Skris * 2155714Skris * 3. All advertising materials mentioning features or use of this 2255714Skris * software must display the following acknowledgment: 2355714Skris * "This product includes software developed by the OpenSSL Project 2455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2555714Skris * 2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2755714Skris * endorse or promote products derived from this software without 2855714Skris * prior written permission. For written permission, please contact 2955714Skris * licensing@OpenSSL.org. 3055714Skris * 3155714Skris * 5. Products derived from this software may not be called "OpenSSL" 3255714Skris * nor may "OpenSSL" appear in their names without prior written 3355714Skris * permission of the OpenSSL Project. 3455714Skris * 3555714Skris * 6. Redistributions of any form whatsoever must retain the following 3655714Skris * acknowledgment: 3755714Skris * "This product includes software developed by the OpenSSL Project 3855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3955714Skris * 4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5255714Skris * ==================================================================== 5355714Skris * 5455714Skris * This product includes cryptographic software written by Eric Young 5555714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5655714Skris * Hudson (tjh@cryptsoft.com). 5755714Skris * 5855714Skris */ 5955714Skris 6055714Skris#include <stdio.h> 6155714Skris#include "cryptlib.h" 6255714Skris#include <openssl/conf.h> 6355714Skris#include <openssl/x509v3.h> 6455714Skris 65296341Sdelphijstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 66296341Sdelphij X509V3_CTX *ctx, 67296341Sdelphij STACK_OF(CONF_VALUE) *nval); 68296341Sdelphijstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 69296341Sdelphij X509V3_CTX *ctx, 70296341Sdelphij STACK_OF(CONF_VALUE) *nval); 71109998Smarkmstatic int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); 72109998Smarkmstatic int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); 73160814Ssimonstatic int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); 74160814Ssimonstatic int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); 75160814Ssimon 76167612Ssimonconst X509V3_EXT_METHOD v3_alt[] = { 77296341Sdelphij {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 78296341Sdelphij 0, 0, 0, 0, 79296341Sdelphij 0, 0, 80296341Sdelphij (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 81296341Sdelphij (X509V3_EXT_V2I)v2i_subject_alt, 82296341Sdelphij NULL, NULL, NULL}, 83109998Smarkm 84296341Sdelphij {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 85296341Sdelphij 0, 0, 0, 0, 86296341Sdelphij 0, 0, 87296341Sdelphij (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 88296341Sdelphij (X509V3_EXT_V2I)v2i_issuer_alt, 89296341Sdelphij NULL, NULL, NULL}, 90238405Sjkim 91296341Sdelphij {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), 92296341Sdelphij 0, 0, 0, 0, 93296341Sdelphij 0, 0, 94296341Sdelphij (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 95296341Sdelphij NULL, NULL, NULL, NULL}, 9655714Skris}; 9755714Skris 9855714SkrisSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 99296341Sdelphij GENERAL_NAMES *gens, 100296341Sdelphij STACK_OF(CONF_VALUE) *ret) 10155714Skris{ 102296341Sdelphij int i; 103296341Sdelphij GENERAL_NAME *gen; 104296341Sdelphij for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 105296341Sdelphij gen = sk_GENERAL_NAME_value(gens, i); 106296341Sdelphij ret = i2v_GENERAL_NAME(method, gen, ret); 107296341Sdelphij } 108296341Sdelphij if (!ret) 109296341Sdelphij return sk_CONF_VALUE_new_null(); 110296341Sdelphij return ret; 11155714Skris} 11255714Skris 11355714SkrisSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, 114296341Sdelphij GENERAL_NAME *gen, 115296341Sdelphij STACK_OF(CONF_VALUE) *ret) 11655714Skris{ 117296341Sdelphij unsigned char *p; 118296341Sdelphij char oline[256], htmp[5]; 119296341Sdelphij int i; 120296341Sdelphij switch (gen->type) { 121296341Sdelphij case GEN_OTHERNAME: 122296341Sdelphij X509V3_add_value("othername", "<unsupported>", &ret); 123296341Sdelphij break; 12455714Skris 125296341Sdelphij case GEN_X400: 126296341Sdelphij X509V3_add_value("X400Name", "<unsupported>", &ret); 127296341Sdelphij break; 12855714Skris 129296341Sdelphij case GEN_EDIPARTY: 130296341Sdelphij X509V3_add_value("EdiPartyName", "<unsupported>", &ret); 131296341Sdelphij break; 13255714Skris 133296341Sdelphij case GEN_EMAIL: 134296341Sdelphij X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); 135296341Sdelphij break; 13655714Skris 137296341Sdelphij case GEN_DNS: 138296341Sdelphij X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); 139296341Sdelphij break; 14055714Skris 141296341Sdelphij case GEN_URI: 142296341Sdelphij X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); 143296341Sdelphij break; 14455714Skris 145296341Sdelphij case GEN_DIRNAME: 146296341Sdelphij X509_NAME_oneline(gen->d.dirn, oline, 256); 147296341Sdelphij X509V3_add_value("DirName", oline, &ret); 148296341Sdelphij break; 14955714Skris 150296341Sdelphij case GEN_IPADD: 151296341Sdelphij p = gen->d.ip->data; 152296341Sdelphij if (gen->d.ip->length == 4) 153296341Sdelphij BIO_snprintf(oline, sizeof oline, 154296341Sdelphij "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 155296341Sdelphij else if (gen->d.ip->length == 16) { 156296341Sdelphij oline[0] = 0; 157296341Sdelphij for (i = 0; i < 8; i++) { 158296341Sdelphij BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); 159296341Sdelphij p += 2; 160296341Sdelphij strcat(oline, htmp); 161296341Sdelphij if (i != 7) 162296341Sdelphij strcat(oline, ":"); 163296341Sdelphij } 164296341Sdelphij } else { 165296341Sdelphij X509V3_add_value("IP Address", "<invalid>", &ret); 166296341Sdelphij break; 167296341Sdelphij } 168296341Sdelphij X509V3_add_value("IP Address", oline, &ret); 169296341Sdelphij break; 17055714Skris 171296341Sdelphij case GEN_RID: 172296341Sdelphij i2t_ASN1_OBJECT(oline, 256, gen->d.rid); 173296341Sdelphij X509V3_add_value("Registered ID", oline, &ret); 174296341Sdelphij break; 175296341Sdelphij } 176296341Sdelphij return ret; 17755714Skris} 17855714Skris 179109998Smarkmint GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 180109998Smarkm{ 181296341Sdelphij unsigned char *p; 182296341Sdelphij int i; 183296341Sdelphij switch (gen->type) { 184296341Sdelphij case GEN_OTHERNAME: 185296341Sdelphij BIO_printf(out, "othername:<unsupported>"); 186296341Sdelphij break; 187109998Smarkm 188296341Sdelphij case GEN_X400: 189296341Sdelphij BIO_printf(out, "X400Name:<unsupported>"); 190296341Sdelphij break; 191109998Smarkm 192296341Sdelphij case GEN_EDIPARTY: 193296341Sdelphij /* Maybe fix this: it is supported now */ 194296341Sdelphij BIO_printf(out, "EdiPartyName:<unsupported>"); 195296341Sdelphij break; 196109998Smarkm 197296341Sdelphij case GEN_EMAIL: 198296341Sdelphij BIO_printf(out, "email:%s", gen->d.ia5->data); 199296341Sdelphij break; 200109998Smarkm 201296341Sdelphij case GEN_DNS: 202296341Sdelphij BIO_printf(out, "DNS:%s", gen->d.ia5->data); 203296341Sdelphij break; 204109998Smarkm 205296341Sdelphij case GEN_URI: 206296341Sdelphij BIO_printf(out, "URI:%s", gen->d.ia5->data); 207296341Sdelphij break; 208109998Smarkm 209296341Sdelphij case GEN_DIRNAME: 210296341Sdelphij BIO_printf(out, "DirName: "); 211296341Sdelphij X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); 212296341Sdelphij break; 213109998Smarkm 214296341Sdelphij case GEN_IPADD: 215296341Sdelphij p = gen->d.ip->data; 216296341Sdelphij if (gen->d.ip->length == 4) 217296341Sdelphij BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 218296341Sdelphij else if (gen->d.ip->length == 16) { 219296341Sdelphij BIO_printf(out, "IP Address"); 220296341Sdelphij for (i = 0; i < 8; i++) { 221296341Sdelphij BIO_printf(out, ":%X", p[0] << 8 | p[1]); 222296341Sdelphij p += 2; 223296341Sdelphij } 224296341Sdelphij BIO_puts(out, "\n"); 225296341Sdelphij } else { 226296341Sdelphij BIO_printf(out, "IP Address:<invalid>"); 227296341Sdelphij break; 228296341Sdelphij } 229296341Sdelphij break; 230109998Smarkm 231296341Sdelphij case GEN_RID: 232296341Sdelphij BIO_printf(out, "Registered ID"); 233296341Sdelphij i2a_ASN1_OBJECT(out, gen->d.rid); 234296341Sdelphij break; 235296341Sdelphij } 236296341Sdelphij return 1; 237109998Smarkm} 238109998Smarkm 239109998Smarkmstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 240296341Sdelphij X509V3_CTX *ctx, 241296341Sdelphij STACK_OF(CONF_VALUE) *nval) 24255714Skris{ 243296341Sdelphij GENERAL_NAMES *gens = NULL; 244296341Sdelphij CONF_VALUE *cnf; 245296341Sdelphij int i; 246296341Sdelphij if (!(gens = sk_GENERAL_NAME_new_null())) { 247296341Sdelphij X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); 248296341Sdelphij return NULL; 249296341Sdelphij } 250296341Sdelphij for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 251296341Sdelphij cnf = sk_CONF_VALUE_value(nval, i); 252296341Sdelphij if (!name_cmp(cnf->name, "issuer") && cnf->value && 253296341Sdelphij !strcmp(cnf->value, "copy")) { 254296341Sdelphij if (!copy_issuer(ctx, gens)) 255296341Sdelphij goto err; 256296341Sdelphij } else { 257296341Sdelphij GENERAL_NAME *gen; 258296341Sdelphij if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 259296341Sdelphij goto err; 260296341Sdelphij sk_GENERAL_NAME_push(gens, gen); 261296341Sdelphij } 262296341Sdelphij } 263296341Sdelphij return gens; 264296341Sdelphij err: 265296341Sdelphij sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 266296341Sdelphij return NULL; 26755714Skris} 26855714Skris 26955714Skris/* Append subject altname of issuer to issuer alt name of subject */ 27055714Skris 271109998Smarkmstatic int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) 27255714Skris{ 273296341Sdelphij GENERAL_NAMES *ialt; 274296341Sdelphij GENERAL_NAME *gen; 275296341Sdelphij X509_EXTENSION *ext; 276296341Sdelphij int i; 277296341Sdelphij if (ctx && (ctx->flags == CTX_TEST)) 278296341Sdelphij return 1; 279296341Sdelphij if (!ctx || !ctx->issuer_cert) { 280296341Sdelphij X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); 281296341Sdelphij goto err; 282296341Sdelphij } 283296341Sdelphij i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); 284296341Sdelphij if (i < 0) 285296341Sdelphij return 1; 286296341Sdelphij if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || 287296341Sdelphij !(ialt = X509V3_EXT_d2i(ext))) { 288296341Sdelphij X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); 289296341Sdelphij goto err; 290296341Sdelphij } 29155714Skris 292296341Sdelphij for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { 293296341Sdelphij gen = sk_GENERAL_NAME_value(ialt, i); 294296341Sdelphij if (!sk_GENERAL_NAME_push(gens, gen)) { 295296341Sdelphij X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); 296296341Sdelphij goto err; 297296341Sdelphij } 298296341Sdelphij } 299296341Sdelphij sk_GENERAL_NAME_free(ialt); 30055714Skris 301296341Sdelphij return 1; 302296341Sdelphij 303296341Sdelphij err: 304296341Sdelphij return 0; 305296341Sdelphij 30655714Skris} 30755714Skris 308109998Smarkmstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 309296341Sdelphij X509V3_CTX *ctx, 310296341Sdelphij STACK_OF(CONF_VALUE) *nval) 31155714Skris{ 312296341Sdelphij GENERAL_NAMES *gens = NULL; 313296341Sdelphij CONF_VALUE *cnf; 314296341Sdelphij int i; 315296341Sdelphij if (!(gens = sk_GENERAL_NAME_new_null())) { 316296341Sdelphij X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); 317296341Sdelphij return NULL; 318296341Sdelphij } 319296341Sdelphij for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 320296341Sdelphij cnf = sk_CONF_VALUE_value(nval, i); 321296341Sdelphij if (!name_cmp(cnf->name, "email") && cnf->value && 322296341Sdelphij !strcmp(cnf->value, "copy")) { 323296341Sdelphij if (!copy_email(ctx, gens, 0)) 324296341Sdelphij goto err; 325296341Sdelphij } else if (!name_cmp(cnf->name, "email") && cnf->value && 326296341Sdelphij !strcmp(cnf->value, "move")) { 327296341Sdelphij if (!copy_email(ctx, gens, 1)) 328296341Sdelphij goto err; 329296341Sdelphij } else { 330296341Sdelphij GENERAL_NAME *gen; 331296341Sdelphij if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 332296341Sdelphij goto err; 333296341Sdelphij sk_GENERAL_NAME_push(gens, gen); 334296341Sdelphij } 335296341Sdelphij } 336296341Sdelphij return gens; 337296341Sdelphij err: 338296341Sdelphij sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 339296341Sdelphij return NULL; 34055714Skris} 34155714Skris 342296341Sdelphij/* 343296341Sdelphij * Copy any email addresses in a certificate or request to GENERAL_NAMES 34455714Skris */ 34555714Skris 346109998Smarkmstatic int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) 34755714Skris{ 348296341Sdelphij X509_NAME *nm; 349296341Sdelphij ASN1_IA5STRING *email = NULL; 350296341Sdelphij X509_NAME_ENTRY *ne; 351296341Sdelphij GENERAL_NAME *gen = NULL; 352296341Sdelphij int i; 353296341Sdelphij if (ctx != NULL && ctx->flags == CTX_TEST) 354296341Sdelphij return 1; 355296341Sdelphij if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { 356296341Sdelphij X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); 357296341Sdelphij goto err; 358296341Sdelphij } 359296341Sdelphij /* Find the subject name */ 360296341Sdelphij if (ctx->subject_cert) 361296341Sdelphij nm = X509_get_subject_name(ctx->subject_cert); 362296341Sdelphij else 363296341Sdelphij nm = X509_REQ_get_subject_name(ctx->subject_req); 36455714Skris 365296341Sdelphij /* Now add any email address(es) to STACK */ 366296341Sdelphij i = -1; 367296341Sdelphij while ((i = X509_NAME_get_index_by_NID(nm, 368296341Sdelphij NID_pkcs9_emailAddress, i)) >= 0) { 369296341Sdelphij ne = X509_NAME_get_entry(nm, i); 370296341Sdelphij email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); 371296341Sdelphij if (move_p) { 372296341Sdelphij X509_NAME_delete_entry(nm, i); 373296341Sdelphij X509_NAME_ENTRY_free(ne); 374296341Sdelphij i--; 375296341Sdelphij } 376296341Sdelphij if (!email || !(gen = GENERAL_NAME_new())) { 377296341Sdelphij X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 378296341Sdelphij goto err; 379296341Sdelphij } 380296341Sdelphij gen->d.ia5 = email; 381296341Sdelphij email = NULL; 382296341Sdelphij gen->type = GEN_EMAIL; 383296341Sdelphij if (!sk_GENERAL_NAME_push(gens, gen)) { 384296341Sdelphij X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 385296341Sdelphij goto err; 386296341Sdelphij } 387296341Sdelphij gen = NULL; 388296341Sdelphij } 38955714Skris 390296341Sdelphij return 1; 391296341Sdelphij 392296341Sdelphij err: 393296341Sdelphij GENERAL_NAME_free(gen); 394296341Sdelphij M_ASN1_IA5STRING_free(email); 395296341Sdelphij return 0; 396296341Sdelphij 39755714Skris} 39855714Skris 399238405SjkimGENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, 400296341Sdelphij X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 40155714Skris{ 402296341Sdelphij GENERAL_NAME *gen; 403296341Sdelphij GENERAL_NAMES *gens = NULL; 404296341Sdelphij CONF_VALUE *cnf; 405296341Sdelphij int i; 406296341Sdelphij if (!(gens = sk_GENERAL_NAME_new_null())) { 407296341Sdelphij X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); 408296341Sdelphij return NULL; 409296341Sdelphij } 410296341Sdelphij for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 411296341Sdelphij cnf = sk_CONF_VALUE_value(nval, i); 412296341Sdelphij if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 413296341Sdelphij goto err; 414296341Sdelphij sk_GENERAL_NAME_push(gens, gen); 415296341Sdelphij } 416296341Sdelphij return gens; 417296341Sdelphij err: 418296341Sdelphij sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 419296341Sdelphij return NULL; 42055714Skris} 42155714Skris 422296341SdelphijGENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, 423296341Sdelphij X509V3_CTX *ctx, CONF_VALUE *cnf) 424296341Sdelphij{ 425296341Sdelphij return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); 426296341Sdelphij} 42755714Skris 428238405SjkimGENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, 429296341Sdelphij const X509V3_EXT_METHOD *method, 430296341Sdelphij X509V3_CTX *ctx, int gen_type, char *value, 431296341Sdelphij int is_nc) 432296341Sdelphij{ 433296341Sdelphij char is_string = 0; 434296341Sdelphij GENERAL_NAME *gen = NULL; 43555714Skris 436296341Sdelphij if (!value) { 437296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); 438296341Sdelphij return NULL; 439296341Sdelphij } 44055714Skris 441296341Sdelphij if (out) 442296341Sdelphij gen = out; 443296341Sdelphij else { 444296341Sdelphij gen = GENERAL_NAME_new(); 445296341Sdelphij if (gen == NULL) { 446296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); 447296341Sdelphij return NULL; 448296341Sdelphij } 449296341Sdelphij } 450160814Ssimon 451296341Sdelphij switch (gen_type) { 452296341Sdelphij case GEN_URI: 453296341Sdelphij case GEN_EMAIL: 454296341Sdelphij case GEN_DNS: 455296341Sdelphij is_string = 1; 456296341Sdelphij break; 457238405Sjkim 458296341Sdelphij case GEN_RID: 459296341Sdelphij { 460296341Sdelphij ASN1_OBJECT *obj; 461296341Sdelphij if (!(obj = OBJ_txt2obj(value, 0))) { 462296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); 463296341Sdelphij ERR_add_error_data(2, "value=", value); 464296341Sdelphij goto err; 465296341Sdelphij } 466296341Sdelphij gen->d.rid = obj; 467296341Sdelphij } 468296341Sdelphij break; 469238405Sjkim 470296341Sdelphij case GEN_IPADD: 471296341Sdelphij if (is_nc) 472296341Sdelphij gen->d.ip = a2i_IPADDRESS_NC(value); 473296341Sdelphij else 474296341Sdelphij gen->d.ip = a2i_IPADDRESS(value); 475296341Sdelphij if (gen->d.ip == NULL) { 476296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); 477296341Sdelphij ERR_add_error_data(2, "value=", value); 478296341Sdelphij goto err; 479296341Sdelphij } 480296341Sdelphij break; 481238405Sjkim 482296341Sdelphij case GEN_DIRNAME: 483296341Sdelphij if (!do_dirname(gen, value, ctx)) { 484296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); 485296341Sdelphij goto err; 486296341Sdelphij } 487296341Sdelphij break; 488160814Ssimon 489296341Sdelphij case GEN_OTHERNAME: 490296341Sdelphij if (!do_othername(gen, value, ctx)) { 491296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); 492296341Sdelphij goto err; 493296341Sdelphij } 494296341Sdelphij break; 495296341Sdelphij default: 496296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); 497296341Sdelphij goto err; 498296341Sdelphij } 499160814Ssimon 500296341Sdelphij if (is_string) { 501296341Sdelphij if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || 502296341Sdelphij !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, 503296341Sdelphij strlen(value))) { 504296341Sdelphij X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); 505296341Sdelphij goto err; 506296341Sdelphij } 507296341Sdelphij } 508160814Ssimon 509296341Sdelphij gen->type = gen_type; 510160814Ssimon 511296341Sdelphij return gen; 51255714Skris 513296341Sdelphij err: 514296341Sdelphij if (!out) 515296341Sdelphij GENERAL_NAME_free(gen); 516296341Sdelphij return NULL; 517296341Sdelphij} 518296341Sdelphij 519238405SjkimGENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, 520296341Sdelphij const X509V3_EXT_METHOD *method, 521296341Sdelphij X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) 522296341Sdelphij{ 523296341Sdelphij int type; 524238405Sjkim 525296341Sdelphij char *name, *value; 526238405Sjkim 527296341Sdelphij name = cnf->name; 528296341Sdelphij value = cnf->value; 529238405Sjkim 530296341Sdelphij if (!value) { 531296341Sdelphij X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); 532296341Sdelphij return NULL; 533296341Sdelphij } 534238405Sjkim 535296341Sdelphij if (!name_cmp(name, "email")) 536296341Sdelphij type = GEN_EMAIL; 537296341Sdelphij else if (!name_cmp(name, "URI")) 538296341Sdelphij type = GEN_URI; 539296341Sdelphij else if (!name_cmp(name, "DNS")) 540296341Sdelphij type = GEN_DNS; 541296341Sdelphij else if (!name_cmp(name, "RID")) 542296341Sdelphij type = GEN_RID; 543296341Sdelphij else if (!name_cmp(name, "IP")) 544296341Sdelphij type = GEN_IPADD; 545296341Sdelphij else if (!name_cmp(name, "dirName")) 546296341Sdelphij type = GEN_DIRNAME; 547296341Sdelphij else if (!name_cmp(name, "otherName")) 548296341Sdelphij type = GEN_OTHERNAME; 549296341Sdelphij else { 550296341Sdelphij X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); 551296341Sdelphij ERR_add_error_data(2, "name=", name); 552296341Sdelphij return NULL; 553296341Sdelphij } 554238405Sjkim 555296341Sdelphij return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); 556238405Sjkim 557296341Sdelphij} 558238405Sjkim 559160814Ssimonstatic int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 560296341Sdelphij{ 561296341Sdelphij char *objtmp = NULL, *p; 562296341Sdelphij int objlen; 563296341Sdelphij if (!(p = strchr(value, ';'))) 564296341Sdelphij return 0; 565296341Sdelphij if (!(gen->d.otherName = OTHERNAME_new())) 566296341Sdelphij return 0; 567296341Sdelphij /* 568296341Sdelphij * Free this up because we will overwrite it. no need to free type_id 569296341Sdelphij * because it is static 570296341Sdelphij */ 571296341Sdelphij ASN1_TYPE_free(gen->d.otherName->value); 572296341Sdelphij if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) 573296341Sdelphij return 0; 574296341Sdelphij objlen = p - value; 575296341Sdelphij objtmp = OPENSSL_malloc(objlen + 1); 576296341Sdelphij strncpy(objtmp, value, objlen); 577296341Sdelphij objtmp[objlen] = 0; 578296341Sdelphij gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); 579296341Sdelphij OPENSSL_free(objtmp); 580296341Sdelphij if (!gen->d.otherName->type_id) 581296341Sdelphij return 0; 582296341Sdelphij return 1; 583296341Sdelphij} 58455714Skris 585160814Ssimonstatic int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 586296341Sdelphij{ 587296341Sdelphij int ret = 0; 588296341Sdelphij STACK_OF(CONF_VALUE) *sk = NULL; 589296341Sdelphij X509_NAME *nm = NULL; 590296341Sdelphij if (!(nm = X509_NAME_new())) 591296341Sdelphij goto err; 592296341Sdelphij sk = X509V3_get_section(ctx, value); 593296341Sdelphij if (!sk) { 594296341Sdelphij X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); 595296341Sdelphij ERR_add_error_data(2, "section=", value); 596296341Sdelphij goto err; 597296341Sdelphij } 598296341Sdelphij /* FIXME: should allow other character types... */ 599296341Sdelphij ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); 600296341Sdelphij if (!ret) 601296341Sdelphij goto err; 602296341Sdelphij gen->d.dirn = nm; 603296341Sdelphij 604296341Sdelphijerr: 605296341Sdelphij if (ret == 0) 606296341Sdelphij X509_NAME_free(nm); 607296341Sdelphij X509V3_section_free(ctx, sk); 608296341Sdelphij return ret; 609296341Sdelphij} 610