155714Skris/* v3_alt.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4160814Ssimon * project. 555714Skris */ 655714Skris/* ==================================================================== 7352193Sjkim * Copyright (c) 1999-2019 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 14280297Sjkim * 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 65280297Sjkimstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 66280297Sjkim X509V3_CTX *ctx, 67280297Sjkim STACK_OF(CONF_VALUE) *nval); 68280297Sjkimstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 69280297Sjkim X509V3_CTX *ctx, 70280297Sjkim 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[] = { 77280297Sjkim {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 78280297Sjkim 0, 0, 0, 0, 79280297Sjkim 0, 0, 80280297Sjkim (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 81280297Sjkim (X509V3_EXT_V2I)v2i_subject_alt, 82280297Sjkim NULL, NULL, NULL}, 83109998Smarkm 84280297Sjkim {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 85280297Sjkim 0, 0, 0, 0, 86280297Sjkim 0, 0, 87280297Sjkim (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 88280297Sjkim (X509V3_EXT_V2I)v2i_issuer_alt, 89280297Sjkim NULL, NULL, NULL}, 90238405Sjkim 91280297Sjkim {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), 92280297Sjkim 0, 0, 0, 0, 93280297Sjkim 0, 0, 94280297Sjkim (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 95280297Sjkim NULL, NULL, NULL, NULL}, 9655714Skris}; 9755714Skris 9855714SkrisSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 99280297Sjkim GENERAL_NAMES *gens, 100280297Sjkim STACK_OF(CONF_VALUE) *ret) 10155714Skris{ 102280297Sjkim int i; 103280297Sjkim GENERAL_NAME *gen; 104280297Sjkim for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 105280297Sjkim gen = sk_GENERAL_NAME_value(gens, i); 106280297Sjkim ret = i2v_GENERAL_NAME(method, gen, ret); 107280297Sjkim } 108280297Sjkim if (!ret) 109280297Sjkim return sk_CONF_VALUE_new_null(); 110280297Sjkim return ret; 11155714Skris} 11255714Skris 11355714SkrisSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, 114280297Sjkim GENERAL_NAME *gen, 115280297Sjkim STACK_OF(CONF_VALUE) *ret) 11655714Skris{ 117280297Sjkim unsigned char *p; 118280297Sjkim char oline[256], htmp[5]; 119280297Sjkim int i; 120280297Sjkim switch (gen->type) { 121280297Sjkim case GEN_OTHERNAME: 122325335Sjkim if (!X509V3_add_value("othername", "<unsupported>", &ret)) 123325335Sjkim return NULL; 124280297Sjkim break; 12555714Skris 126280297Sjkim case GEN_X400: 127325335Sjkim if (!X509V3_add_value("X400Name", "<unsupported>", &ret)) 128325335Sjkim return NULL; 129280297Sjkim break; 13055714Skris 131280297Sjkim case GEN_EDIPARTY: 132325335Sjkim if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret)) 133325335Sjkim return NULL; 134280297Sjkim break; 13555714Skris 136280297Sjkim case GEN_EMAIL: 137325335Sjkim if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) 138325335Sjkim return NULL; 139280297Sjkim break; 14055714Skris 141280297Sjkim case GEN_DNS: 142325335Sjkim if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) 143325335Sjkim return NULL; 144280297Sjkim break; 14555714Skris 146280297Sjkim case GEN_URI: 147325335Sjkim if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) 148325335Sjkim return NULL; 149280297Sjkim break; 15055714Skris 151280297Sjkim case GEN_DIRNAME: 152325335Sjkim if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL 153325335Sjkim || !X509V3_add_value("DirName", oline, &ret)) 154325335Sjkim return NULL; 155280297Sjkim break; 15655714Skris 157280297Sjkim case GEN_IPADD: 158280297Sjkim p = gen->d.ip->data; 159280297Sjkim if (gen->d.ip->length == 4) 160331638Sjkim BIO_snprintf(oline, sizeof(oline), 161280297Sjkim "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 162280297Sjkim else if (gen->d.ip->length == 16) { 163280297Sjkim oline[0] = 0; 164280297Sjkim for (i = 0; i < 8; i++) { 165331638Sjkim BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); 166280297Sjkim p += 2; 167280297Sjkim strcat(oline, htmp); 168280297Sjkim if (i != 7) 169280297Sjkim strcat(oline, ":"); 170280297Sjkim } 171280297Sjkim } else { 172325335Sjkim if (!X509V3_add_value("IP Address", "<invalid>", &ret)) 173325335Sjkim return NULL; 174280297Sjkim break; 175280297Sjkim } 176325335Sjkim if (!X509V3_add_value("IP Address", oline, &ret)) 177325335Sjkim return NULL; 178280297Sjkim break; 17955714Skris 180280297Sjkim case GEN_RID: 181280297Sjkim i2t_ASN1_OBJECT(oline, 256, gen->d.rid); 182325335Sjkim if (!X509V3_add_value("Registered ID", oline, &ret)) 183325335Sjkim return NULL; 184280297Sjkim break; 185280297Sjkim } 186280297Sjkim return ret; 18755714Skris} 18855714Skris 189109998Smarkmint GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 190109998Smarkm{ 191280297Sjkim unsigned char *p; 192280297Sjkim int i; 193280297Sjkim switch (gen->type) { 194280297Sjkim case GEN_OTHERNAME: 195280297Sjkim BIO_printf(out, "othername:<unsupported>"); 196280297Sjkim break; 197109998Smarkm 198280297Sjkim case GEN_X400: 199280297Sjkim BIO_printf(out, "X400Name:<unsupported>"); 200280297Sjkim break; 201109998Smarkm 202280297Sjkim case GEN_EDIPARTY: 203280297Sjkim /* Maybe fix this: it is supported now */ 204280297Sjkim BIO_printf(out, "EdiPartyName:<unsupported>"); 205280297Sjkim break; 206109998Smarkm 207280297Sjkim case GEN_EMAIL: 208352193Sjkim BIO_printf(out, "email:"); 209352193Sjkim ASN1_STRING_print(out, gen->d.ia5); 210280297Sjkim break; 211109998Smarkm 212280297Sjkim case GEN_DNS: 213352193Sjkim BIO_printf(out, "DNS:"); 214352193Sjkim ASN1_STRING_print(out, gen->d.ia5); 215280297Sjkim break; 216109998Smarkm 217280297Sjkim case GEN_URI: 218352193Sjkim BIO_printf(out, "URI:"); 219352193Sjkim ASN1_STRING_print(out, gen->d.ia5); 220280297Sjkim break; 221109998Smarkm 222280297Sjkim case GEN_DIRNAME: 223280297Sjkim BIO_printf(out, "DirName: "); 224280297Sjkim X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); 225280297Sjkim break; 226109998Smarkm 227280297Sjkim case GEN_IPADD: 228280297Sjkim p = gen->d.ip->data; 229280297Sjkim if (gen->d.ip->length == 4) 230280297Sjkim BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 231280297Sjkim else if (gen->d.ip->length == 16) { 232280297Sjkim BIO_printf(out, "IP Address"); 233280297Sjkim for (i = 0; i < 8; i++) { 234280297Sjkim BIO_printf(out, ":%X", p[0] << 8 | p[1]); 235280297Sjkim p += 2; 236280297Sjkim } 237280297Sjkim BIO_puts(out, "\n"); 238280297Sjkim } else { 239280297Sjkim BIO_printf(out, "IP Address:<invalid>"); 240280297Sjkim break; 241280297Sjkim } 242280297Sjkim break; 243109998Smarkm 244280297Sjkim case GEN_RID: 245280297Sjkim BIO_printf(out, "Registered ID"); 246280297Sjkim i2a_ASN1_OBJECT(out, gen->d.rid); 247280297Sjkim break; 248280297Sjkim } 249280297Sjkim return 1; 250109998Smarkm} 251109998Smarkm 252109998Smarkmstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 253280297Sjkim X509V3_CTX *ctx, 254280297Sjkim STACK_OF(CONF_VALUE) *nval) 25555714Skris{ 256280297Sjkim GENERAL_NAMES *gens = NULL; 257280297Sjkim CONF_VALUE *cnf; 258280297Sjkim int i; 259280297Sjkim if (!(gens = sk_GENERAL_NAME_new_null())) { 260280297Sjkim X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); 261280297Sjkim return NULL; 262280297Sjkim } 263280297Sjkim for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 264280297Sjkim cnf = sk_CONF_VALUE_value(nval, i); 265280297Sjkim if (!name_cmp(cnf->name, "issuer") && cnf->value && 266280297Sjkim !strcmp(cnf->value, "copy")) { 267280297Sjkim if (!copy_issuer(ctx, gens)) 268280297Sjkim goto err; 269280297Sjkim } else { 270280297Sjkim GENERAL_NAME *gen; 271280297Sjkim if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 272280297Sjkim goto err; 273280297Sjkim sk_GENERAL_NAME_push(gens, gen); 274280297Sjkim } 275280297Sjkim } 276280297Sjkim return gens; 277280297Sjkim err: 278280297Sjkim sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 279280297Sjkim return NULL; 28055714Skris} 28155714Skris 28255714Skris/* Append subject altname of issuer to issuer alt name of subject */ 28355714Skris 284109998Smarkmstatic int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) 28555714Skris{ 286280297Sjkim GENERAL_NAMES *ialt; 287280297Sjkim GENERAL_NAME *gen; 288280297Sjkim X509_EXTENSION *ext; 289280297Sjkim int i; 290280297Sjkim if (ctx && (ctx->flags == CTX_TEST)) 291280297Sjkim return 1; 292280297Sjkim if (!ctx || !ctx->issuer_cert) { 293280297Sjkim X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); 294280297Sjkim goto err; 295280297Sjkim } 296280297Sjkim i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); 297280297Sjkim if (i < 0) 298280297Sjkim return 1; 299280297Sjkim if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || 300280297Sjkim !(ialt = X509V3_EXT_d2i(ext))) { 301280297Sjkim X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); 302280297Sjkim goto err; 303280297Sjkim } 30455714Skris 305280297Sjkim for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { 306280297Sjkim gen = sk_GENERAL_NAME_value(ialt, i); 307280297Sjkim if (!sk_GENERAL_NAME_push(gens, gen)) { 308280297Sjkim X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); 309280297Sjkim goto err; 310280297Sjkim } 311280297Sjkim } 312280297Sjkim sk_GENERAL_NAME_free(ialt); 31355714Skris 314280297Sjkim return 1; 315280297Sjkim 316280297Sjkim err: 317280297Sjkim return 0; 318280297Sjkim 31955714Skris} 32055714Skris 321109998Smarkmstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 322280297Sjkim X509V3_CTX *ctx, 323280297Sjkim STACK_OF(CONF_VALUE) *nval) 32455714Skris{ 325280297Sjkim GENERAL_NAMES *gens = NULL; 326280297Sjkim CONF_VALUE *cnf; 327280297Sjkim int i; 328280297Sjkim if (!(gens = sk_GENERAL_NAME_new_null())) { 329280297Sjkim X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); 330280297Sjkim return NULL; 331280297Sjkim } 332280297Sjkim for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 333280297Sjkim cnf = sk_CONF_VALUE_value(nval, i); 334280297Sjkim if (!name_cmp(cnf->name, "email") && cnf->value && 335280297Sjkim !strcmp(cnf->value, "copy")) { 336280297Sjkim if (!copy_email(ctx, gens, 0)) 337280297Sjkim goto err; 338280297Sjkim } else if (!name_cmp(cnf->name, "email") && cnf->value && 339280297Sjkim !strcmp(cnf->value, "move")) { 340280297Sjkim if (!copy_email(ctx, gens, 1)) 341280297Sjkim goto err; 342280297Sjkim } else { 343280297Sjkim GENERAL_NAME *gen; 344280297Sjkim if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 345280297Sjkim goto err; 346280297Sjkim sk_GENERAL_NAME_push(gens, gen); 347280297Sjkim } 348280297Sjkim } 349280297Sjkim return gens; 350280297Sjkim err: 351280297Sjkim sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 352280297Sjkim return NULL; 35355714Skris} 35455714Skris 355280297Sjkim/* 356280297Sjkim * Copy any email addresses in a certificate or request to GENERAL_NAMES 35755714Skris */ 35855714Skris 359109998Smarkmstatic int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) 36055714Skris{ 361280297Sjkim X509_NAME *nm; 362280297Sjkim ASN1_IA5STRING *email = NULL; 363280297Sjkim X509_NAME_ENTRY *ne; 364280297Sjkim GENERAL_NAME *gen = NULL; 365280297Sjkim int i; 366280297Sjkim if (ctx != NULL && ctx->flags == CTX_TEST) 367280297Sjkim return 1; 368280297Sjkim if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { 369280297Sjkim X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); 370280297Sjkim goto err; 371280297Sjkim } 372280297Sjkim /* Find the subject name */ 373280297Sjkim if (ctx->subject_cert) 374280297Sjkim nm = X509_get_subject_name(ctx->subject_cert); 375280297Sjkim else 376280297Sjkim nm = X509_REQ_get_subject_name(ctx->subject_req); 37755714Skris 378280297Sjkim /* Now add any email address(es) to STACK */ 379280297Sjkim i = -1; 380280297Sjkim while ((i = X509_NAME_get_index_by_NID(nm, 381280297Sjkim NID_pkcs9_emailAddress, i)) >= 0) { 382280297Sjkim ne = X509_NAME_get_entry(nm, i); 383280297Sjkim email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); 384280297Sjkim if (move_p) { 385280297Sjkim X509_NAME_delete_entry(nm, i); 386280297Sjkim X509_NAME_ENTRY_free(ne); 387280297Sjkim i--; 388280297Sjkim } 389280297Sjkim if (!email || !(gen = GENERAL_NAME_new())) { 390280297Sjkim X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 391280297Sjkim goto err; 392280297Sjkim } 393280297Sjkim gen->d.ia5 = email; 394280297Sjkim email = NULL; 395280297Sjkim gen->type = GEN_EMAIL; 396280297Sjkim if (!sk_GENERAL_NAME_push(gens, gen)) { 397280297Sjkim X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 398280297Sjkim goto err; 399280297Sjkim } 400280297Sjkim gen = NULL; 401280297Sjkim } 40255714Skris 403280297Sjkim return 1; 404280297Sjkim 405280297Sjkim err: 406280297Sjkim GENERAL_NAME_free(gen); 407280297Sjkim M_ASN1_IA5STRING_free(email); 408280297Sjkim return 0; 409280297Sjkim 41055714Skris} 41155714Skris 412238405SjkimGENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, 413280297Sjkim X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 41455714Skris{ 415280297Sjkim GENERAL_NAME *gen; 416280297Sjkim GENERAL_NAMES *gens = NULL; 417280297Sjkim CONF_VALUE *cnf; 418280297Sjkim int i; 419280297Sjkim if (!(gens = sk_GENERAL_NAME_new_null())) { 420280297Sjkim X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); 421280297Sjkim return NULL; 422280297Sjkim } 423280297Sjkim for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 424280297Sjkim cnf = sk_CONF_VALUE_value(nval, i); 425280297Sjkim if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 426280297Sjkim goto err; 427280297Sjkim sk_GENERAL_NAME_push(gens, gen); 428280297Sjkim } 429280297Sjkim return gens; 430280297Sjkim err: 431280297Sjkim sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 432280297Sjkim return NULL; 43355714Skris} 43455714Skris 435280297SjkimGENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, 436280297Sjkim X509V3_CTX *ctx, CONF_VALUE *cnf) 437280297Sjkim{ 438280297Sjkim return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); 439280297Sjkim} 44055714Skris 441238405SjkimGENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, 442280297Sjkim const X509V3_EXT_METHOD *method, 443280297Sjkim X509V3_CTX *ctx, int gen_type, char *value, 444280297Sjkim int is_nc) 445280297Sjkim{ 446280297Sjkim char is_string = 0; 447280297Sjkim GENERAL_NAME *gen = NULL; 44855714Skris 449280297Sjkim if (!value) { 450280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); 451280297Sjkim return NULL; 452280297Sjkim } 45355714Skris 454280297Sjkim if (out) 455280297Sjkim gen = out; 456280297Sjkim else { 457280297Sjkim gen = GENERAL_NAME_new(); 458280297Sjkim if (gen == NULL) { 459280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); 460280297Sjkim return NULL; 461280297Sjkim } 462280297Sjkim } 463160814Ssimon 464280297Sjkim switch (gen_type) { 465280297Sjkim case GEN_URI: 466280297Sjkim case GEN_EMAIL: 467280297Sjkim case GEN_DNS: 468280297Sjkim is_string = 1; 469280297Sjkim break; 470238405Sjkim 471280297Sjkim case GEN_RID: 472280297Sjkim { 473280297Sjkim ASN1_OBJECT *obj; 474280297Sjkim if (!(obj = OBJ_txt2obj(value, 0))) { 475280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); 476280297Sjkim ERR_add_error_data(2, "value=", value); 477280297Sjkim goto err; 478280297Sjkim } 479280297Sjkim gen->d.rid = obj; 480280297Sjkim } 481280297Sjkim break; 482238405Sjkim 483280297Sjkim case GEN_IPADD: 484280297Sjkim if (is_nc) 485280297Sjkim gen->d.ip = a2i_IPADDRESS_NC(value); 486280297Sjkim else 487280297Sjkim gen->d.ip = a2i_IPADDRESS(value); 488280297Sjkim if (gen->d.ip == NULL) { 489280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); 490280297Sjkim ERR_add_error_data(2, "value=", value); 491280297Sjkim goto err; 492280297Sjkim } 493280297Sjkim break; 494238405Sjkim 495280297Sjkim case GEN_DIRNAME: 496280297Sjkim if (!do_dirname(gen, value, ctx)) { 497280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); 498280297Sjkim goto err; 499280297Sjkim } 500280297Sjkim break; 501160814Ssimon 502280297Sjkim case GEN_OTHERNAME: 503280297Sjkim if (!do_othername(gen, value, ctx)) { 504280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); 505280297Sjkim goto err; 506280297Sjkim } 507280297Sjkim break; 508280297Sjkim default: 509280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); 510280297Sjkim goto err; 511280297Sjkim } 512160814Ssimon 513280297Sjkim if (is_string) { 514280297Sjkim if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || 515280297Sjkim !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, 516280297Sjkim strlen(value))) { 517280297Sjkim X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); 518280297Sjkim goto err; 519280297Sjkim } 520280297Sjkim } 521160814Ssimon 522280297Sjkim gen->type = gen_type; 523160814Ssimon 524280297Sjkim return gen; 52555714Skris 526280297Sjkim err: 527280297Sjkim if (!out) 528280297Sjkim GENERAL_NAME_free(gen); 529280297Sjkim return NULL; 530280297Sjkim} 531280297Sjkim 532238405SjkimGENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, 533280297Sjkim const X509V3_EXT_METHOD *method, 534280297Sjkim X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) 535280297Sjkim{ 536280297Sjkim int type; 537238405Sjkim 538280297Sjkim char *name, *value; 539238405Sjkim 540280297Sjkim name = cnf->name; 541280297Sjkim value = cnf->value; 542238405Sjkim 543280297Sjkim if (!value) { 544280297Sjkim X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); 545280297Sjkim return NULL; 546280297Sjkim } 547238405Sjkim 548280297Sjkim if (!name_cmp(name, "email")) 549280297Sjkim type = GEN_EMAIL; 550280297Sjkim else if (!name_cmp(name, "URI")) 551280297Sjkim type = GEN_URI; 552280297Sjkim else if (!name_cmp(name, "DNS")) 553280297Sjkim type = GEN_DNS; 554280297Sjkim else if (!name_cmp(name, "RID")) 555280297Sjkim type = GEN_RID; 556280297Sjkim else if (!name_cmp(name, "IP")) 557280297Sjkim type = GEN_IPADD; 558280297Sjkim else if (!name_cmp(name, "dirName")) 559280297Sjkim type = GEN_DIRNAME; 560280297Sjkim else if (!name_cmp(name, "otherName")) 561280297Sjkim type = GEN_OTHERNAME; 562280297Sjkim else { 563280297Sjkim X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); 564280297Sjkim ERR_add_error_data(2, "name=", name); 565280297Sjkim return NULL; 566280297Sjkim } 567238405Sjkim 568280297Sjkim return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); 569238405Sjkim 570280297Sjkim} 571238405Sjkim 572160814Ssimonstatic int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 573280297Sjkim{ 574280297Sjkim char *objtmp = NULL, *p; 575280297Sjkim int objlen; 576280297Sjkim if (!(p = strchr(value, ';'))) 577280297Sjkim return 0; 578280297Sjkim if (!(gen->d.otherName = OTHERNAME_new())) 579280297Sjkim return 0; 580280297Sjkim /* 581280297Sjkim * Free this up because we will overwrite it. no need to free type_id 582280297Sjkim * because it is static 583280297Sjkim */ 584280297Sjkim ASN1_TYPE_free(gen->d.otherName->value); 585280297Sjkim if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) 586280297Sjkim return 0; 587280297Sjkim objlen = p - value; 588280297Sjkim objtmp = OPENSSL_malloc(objlen + 1); 589306195Sjkim if (objtmp == NULL) 590306195Sjkim return 0; 591280297Sjkim strncpy(objtmp, value, objlen); 592280297Sjkim objtmp[objlen] = 0; 593280297Sjkim gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); 594280297Sjkim OPENSSL_free(objtmp); 595280297Sjkim if (!gen->d.otherName->type_id) 596280297Sjkim return 0; 597280297Sjkim return 1; 598280297Sjkim} 59955714Skris 600160814Ssimonstatic int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 601280297Sjkim{ 602284283Sjkim int ret = 0; 603284283Sjkim STACK_OF(CONF_VALUE) *sk = NULL; 604284283Sjkim X509_NAME *nm = NULL; 605280297Sjkim if (!(nm = X509_NAME_new())) 606284283Sjkim goto err; 607280297Sjkim sk = X509V3_get_section(ctx, value); 608280297Sjkim if (!sk) { 609280297Sjkim X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); 610280297Sjkim ERR_add_error_data(2, "section=", value); 611284283Sjkim goto err; 612280297Sjkim } 613280297Sjkim /* FIXME: should allow other character types... */ 614280297Sjkim ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); 615280297Sjkim if (!ret) 616284283Sjkim goto err; 617284283Sjkim gen->d.dirn = nm; 618284283Sjkim 619284283Sjkimerr: 620284283Sjkim if (ret == 0) 621280297Sjkim X509_NAME_free(nm); 622280297Sjkim X509V3_section_free(ctx, sk); 623280297Sjkim return ret; 624280297Sjkim} 625