v3_alt.c revision 296465
15455Sdg/* v3_alt.c */ 21541Srgrimes/* 31541Srgrimes * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 41549Srgrimes * project. 51549Srgrimes */ 61549Srgrimes/* ==================================================================== 71549Srgrimes * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. 81541Srgrimes * 91549Srgrimes * Redistribution and use in source and binary forms, with or without 101541Srgrimes * modification, are permitted provided that the following conditions 111541Srgrimes * are met: 121541Srgrimes * 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 161541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171541Srgrimes * notice, this list of conditions and the following disclaimer in 181541Srgrimes * the documentation and/or other materials provided with the 191541Srgrimes * distribution. 201541Srgrimes * 211541Srgrimes * 3. All advertising materials mentioning features or use of this 2258705Scharnier * software must display the following acknowledgment: 231541Srgrimes * "This product includes software developed by the OpenSSL Project 241541Srgrimes * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 251541Srgrimes * 261541Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 271541Srgrimes * endorse or promote products derived from this software without 281541Srgrimes * prior written permission. For written permission, please contact 291541Srgrimes * licensing@OpenSSL.org. 301541Srgrimes * 311541Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 321541Srgrimes * nor may "OpenSSL" appear in their names without prior written 331541Srgrimes * permission of the OpenSSL Project. 341541Srgrimes * 351541Srgrimes * 6. Redistributions of any form whatsoever must retain the following 361541Srgrimes * acknowledgment: 371541Srgrimes * "This product includes software developed by the OpenSSL Project 381541Srgrimes * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 391541Srgrimes * 401541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 411817Sdg * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 431541Srgrimes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 441541Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 451541Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 461541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 471541Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 485455Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 491541Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 501541Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 511541Srgrimes * OF THE POSSIBILITY OF SUCH DAMAGE. 521541Srgrimes * ==================================================================== 531541Srgrimes * 545455Sdg * This product includes cryptographic software written by Eric Young 555455Sdg * (eay@cryptsoft.com). This product includes software written by Tim 565455Sdg * Hudson (tjh@cryptsoft.com). 571541Srgrimes * 585455Sdg */ 591541Srgrimes 601541Srgrimes#include <stdio.h> 611541Srgrimes#include "cryptlib.h" 621541Srgrimes#include <openssl/conf.h> 631541Srgrimes#include <openssl/x509v3.h> 641541Srgrimes 651541Srgrimesstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 661541Srgrimes X509V3_CTX *ctx, 671541Srgrimes STACK_OF(CONF_VALUE) *nval); 681541Srgrimesstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 691541Srgrimes X509V3_CTX *ctx, 701541Srgrimes STACK_OF(CONF_VALUE) *nval); 711541Srgrimesstatic int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); 721541Srgrimesstatic int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); 73116226Sobrienstatic int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); 74116226Sobrienstatic int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); 75116226Sobrien 76116226Sobrienconst X509V3_EXT_METHOD v3_alt[] = { 771541Srgrimes {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 781541Srgrimes 0, 0, 0, 0, 7976949Sjhb 0, 0, 8076166Smarkm (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 8176166Smarkm (X509V3_EXT_V2I)v2i_subject_alt, 821549Srgrimes NULL, NULL, NULL}, 831549Srgrimes 8476949Sjhb {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 8512662Sdg 0, 0, 0, 0, 8676949Sjhb 0, 0, 871541Srgrimes (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 881541Srgrimes (X509V3_EXT_V2I)v2i_issuer_alt, 8912662Sdg NULL, NULL, NULL}, 9012662Sdg}; 9112662Sdg 9212662SdgSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 931541Srgrimes GENERAL_NAMES *gens, 941541Srgrimes STACK_OF(CONF_VALUE) *ret) 954207Sdg{ 969507Sdg int i; 979507Sdg GENERAL_NAME *gen; 9812662Sdg for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 991541Srgrimes gen = sk_GENERAL_NAME_value(gens, i); 10092727Salfred ret = i2v_GENERAL_NAME(method, gen, ret); 1011549Srgrimes } 10232585Sdyson if (!ret) 10332585Sdyson return sk_CONF_VALUE_new_null(); 1041549Srgrimes return ret; 1051549Srgrimes} 10634202Sdyson 10734202SdysonSTACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, 10834202Sdyson GENERAL_NAME *gen, 10934202Sdyson STACK_OF(CONF_VALUE) *ret) 11034202Sdyson{ 11134202Sdyson unsigned char *p; 11234202Sdyson char oline[256], htmp[5]; 11334202Sdyson int i; 11434202Sdyson switch (gen->type) { 11592588Sgreen case GEN_OTHERNAME: 11634202Sdyson X509V3_add_value("othername", "<unsupported>", &ret); 11734202Sdyson break; 11834202Sdyson 11942957Sdillon case GEN_X400: 12034202Sdyson X509V3_add_value("X400Name", "<unsupported>", &ret); 12134202Sdyson break; 122100456Salc 12338799Sdfr case GEN_EDIPARTY: 12434202Sdyson X509V3_add_value("EdiPartyName", "<unsupported>", &ret); 125100456Salc break; 12634202Sdyson 12734202Sdyson case GEN_EMAIL: 12834202Sdyson X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); 12942957Sdillon break; 13034202Sdyson 13134202Sdyson case GEN_DNS: 13292588Sgreen X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); 13334202Sdyson break; 13492588Sgreen 13534202Sdyson case GEN_URI: 13634202Sdyson X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); 13734202Sdyson break; 13834202Sdyson 13934202Sdyson case GEN_DIRNAME: 14034202Sdyson X509_NAME_oneline(gen->d.dirn, oline, 256); 14179224Sdillon X509V3_add_value("DirName", oline, &ret); 142113761Salc break; 14334202Sdyson 144113761Salc case GEN_IPADD: 14534202Sdyson p = gen->d.ip->data; 146113761Salc if (gen->d.ip->length == 4) 147100456Salc BIO_snprintf(oline, sizeof oline, 14834202Sdyson "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 149100456Salc else if (gen->d.ip->length == 16) { 15034202Sdyson oline[0] = 0; 151113761Salc for (i = 0; i < 8; i++) { 15234202Sdyson BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); 15334202Sdyson p += 2; 15434202Sdyson strcat(oline, htmp); 15534202Sdyson if (i != 7) 15634202Sdyson strcat(oline, ":"); 15734202Sdyson } 15834202Sdyson } else { 15979224Sdillon X509V3_add_value("IP Address", "<invalid>", &ret); 16034202Sdyson break; 16134202Sdyson } 16234202Sdyson X509V3_add_value("IP Address", oline, &ret); 16334202Sdyson break; 16434202Sdyson 16534202Sdyson case GEN_RID: 16634202Sdyson i2t_ASN1_OBJECT(oline, 256, gen->d.rid); 1671541Srgrimes X509V3_add_value("Registered ID", oline, &ret); 16851488Sdillon break; 16951488Sdillon } 17051488Sdillon return ret; 17151488Sdillon} 17251488Sdillon 17351488Sdillonint GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 17451488Sdillon{ 17551488Sdillon unsigned char *p; 17651488Sdillon int i; 1771541Srgrimes switch (gen->type) { 1781541Srgrimes case GEN_OTHERNAME: 17958634Scharnier BIO_printf(out, "othername:<unsupported>"); 1801541Srgrimes break; 1811541Srgrimes 1821541Srgrimes case GEN_X400: 1831541Srgrimes BIO_printf(out, "X400Name:<unsupported>"); 1841541Srgrimes break; 1851541Srgrimes 1861541Srgrimes case GEN_EDIPARTY: 1871541Srgrimes /* Maybe fix this: it is supported now */ 1881541Srgrimes BIO_printf(out, "EdiPartyName:<unsupported>"); 1891541Srgrimes break; 1901541Srgrimes 1911541Srgrimes case GEN_EMAIL: 19279224Sdillon BIO_printf(out, "email:%s", gen->d.ia5->data); 1931541Srgrimes break; 1941541Srgrimes 19576827Salfred case GEN_DNS: 19676827Salfred BIO_printf(out, "DNS:%s", gen->d.ia5->data); 1971541Srgrimes break; 1985455Sdg 199116650Salc case GEN_URI: 20094977Salc BIO_printf(out, "URI:%s", gen->d.ia5->data); 20132702Sdyson break; 2025455Sdg 2035455Sdg case GEN_DIRNAME: 20434202Sdyson BIO_printf(out, "DirName: "); 20532702Sdyson X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); 20634202Sdyson break; 2071541Srgrimes 20834202Sdyson case GEN_IPADD: 20994977Salc p = gen->d.ip->data; 21095021Salc if (gen->d.ip->length == 4) 2111541Srgrimes BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 21295021Salc else if (gen->d.ip->length == 16) { 2135455Sdg BIO_printf(out, "IP Address"); 2141541Srgrimes for (i = 0; i < 8; i++) { 2151541Srgrimes BIO_printf(out, ":%X", p[0] << 8 | p[1]); 2165455Sdg p += 2; 2175455Sdg } 2181541Srgrimes BIO_puts(out, "\n"); 21951488Sdillon } else { 22095021Salc BIO_printf(out, "IP Address:<invalid>"); 22195021Salc break; 22295021Salc } 22395021Salc break; 22495021Salc 22594977Salc case GEN_RID: 22694977Salc BIO_printf(out, "Registered ID"); 22794977Salc i2a_ASN1_OBJECT(out, gen->d.rid); 22895764Salc break; 22995764Salc } 23094977Salc return 1; 23195764Salc} 23294977Salc 23394977Salcstatic GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 23494977Salc X509V3_CTX *ctx, 23595764Salc STACK_OF(CONF_VALUE) *nval) 23695021Salc{ 23732585Sdyson GENERAL_NAMES *gens = NULL; 23832585Sdyson CONF_VALUE *cnf; 23932585Sdyson int i; 24032585Sdyson if (!(gens = sk_GENERAL_NAME_new_null())) { 24132585Sdyson X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); 24232585Sdyson return NULL; 24332585Sdyson } 24432585Sdyson for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 24532585Sdyson cnf = sk_CONF_VALUE_value(nval, i); 24634202Sdyson if (!name_cmp(cnf->name, "issuer") && cnf->value && 24732585Sdyson !strcmp(cnf->value, "copy")) { 24834202Sdyson if (!copy_issuer(ctx, gens)) 24932585Sdyson goto err; 25095764Salc } else { 25195764Salc GENERAL_NAME *gen; 25232585Sdyson if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 25332585Sdyson goto err; 25432585Sdyson sk_GENERAL_NAME_push(gens, gen); 25532585Sdyson } 25632585Sdyson } 25732585Sdyson return gens; 25894981Salc err: 25994981Salc sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 26094981Salc return NULL; 26132585Sdyson} 26234202Sdyson 26334202Sdyson/* Append subject altname of issuer to issuer alt name of subject */ 2641541Srgrimes 2657695Sdgstatic int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) 26634202Sdyson{ 26732702Sdyson GENERAL_NAMES *ialt; 26834202Sdyson GENERAL_NAME *gen; 26920054Sdyson X509_EXTENSION *ext; 27037563Sbde int i; 27120054Sdyson if (ctx && (ctx->flags == CTX_TEST)) 27220054Sdyson return 1; 27320449Sdyson if (!ctx || !ctx->issuer_cert) { 27432286Sdyson X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); 27532286Sdyson goto err; 27632286Sdyson } 27732286Sdyson i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); 27886236Sdillon if (i < 0) 27986236Sdillon return 1; 28086236Sdillon if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || 28186236Sdillon !(ialt = X509V3_EXT_d2i(ext))) { 28295701Salc X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); 28395701Salc goto err; 28432286Sdyson } 28534202Sdyson 28686236Sdillon for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { 287113739Salc gen = sk_GENERAL_NAME_value(ialt, i); 28838135Sdfr if (!sk_GENERAL_NAME_push(gens, gen)) { 289113739Salc X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); 29032286Sdyson goto err; 29192588Sgreen } 2921541Srgrimes } 2931541Srgrimes sk_GENERAL_NAME_free(ialt); 2941541Srgrimes 2951541Srgrimes return 1; 29634202Sdyson 2971541Srgrimes err: 2985455Sdg return 0; 2995455Sdg 3001541Srgrimes} 30134202Sdyson 30234202Sdysonstatic GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 3031541Srgrimes X509V3_CTX *ctx, 30442957Sdillon STACK_OF(CONF_VALUE) *nval) 30542957Sdillon{ 30642957Sdillon GENERAL_NAMES *gens = NULL; 30734202Sdyson CONF_VALUE *cnf; 30834202Sdyson int i; 30995764Salc if (!(gens = sk_GENERAL_NAME_new_null())) { 31032585Sdyson X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); 31132585Sdyson return NULL; 31242957Sdillon } 31342957Sdillon for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 31442957Sdillon cnf = sk_CONF_VALUE_value(nval, i); 31542957Sdillon if (!name_cmp(cnf->name, "email") && cnf->value && 31634202Sdyson !strcmp(cnf->value, "copy")) { 31734202Sdyson if (!copy_email(ctx, gens, 0)) 31841322Sdg goto err; 31998849Sken } else if (!name_cmp(cnf->name, "email") && cnf->value && 32098849Sken !strcmp(cnf->value, "move")) { 321111977Sken if (!copy_email(ctx, gens, 1)) 322111977Sken goto err; 323111977Sken } else { 324111977Sken GENERAL_NAME *gen; 325111977Sken if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 326111977Sken goto err; 327111977Sken sk_GENERAL_NAME_push(gens, gen); 32898849Sken } 329105466Salc } 33098849Sken return gens; 331111977Sken err: 332111977Sken sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 33398849Sken return NULL; 33498849Sken} 33598849Sken 336105466Salc/* 337116552Salc * Copy any email addresses in a certificate or request to GENERAL_NAMES 33898849Sken */ 33998849Sken 34098849Skenstatic int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) 3411541Srgrimes{ 34242957Sdillon X509_NAME *nm; 34342957Sdillon ASN1_IA5STRING *email = NULL; 34442957Sdillon X509_NAME_ENTRY *ne; 34542957Sdillon GENERAL_NAME *gen = NULL; 34642957Sdillon int i; 34758634Scharnier if (ctx != NULL && ctx->flags == CTX_TEST) 34842957Sdillon return 1; 34942957Sdillon if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { 35042957Sdillon X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); 35142957Sdillon goto err; 35242957Sdillon } 35342957Sdillon /* Find the subject name */ 35442957Sdillon if (ctx->subject_cert) 35542957Sdillon nm = X509_get_subject_name(ctx->subject_cert); 3561541Srgrimes else 35742957Sdillon nm = X509_REQ_get_subject_name(ctx->subject_req); 358100742Salc 35934202Sdyson /* Now add any email address(es) to STACK */ 360108068Salc i = -1; 361108068Salc while ((i = X509_NAME_get_index_by_NID(nm, 362108068Salc NID_pkcs9_emailAddress, i)) >= 0) { 36342957Sdillon ne = X509_NAME_get_entry(nm, i); 36434202Sdyson email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); 3651541Srgrimes if (move_p) { 3661541Srgrimes X509_NAME_delete_entry(nm, i); 36792029Seivind X509_NAME_ENTRY_free(ne); 3687695Sdg i--; 36941322Sdg } 37079263Sdillon if (!email || !(gen = GENERAL_NAME_new())) { 37141322Sdg X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 37216268Sdyson goto err; 37351488Sdillon } 37434202Sdyson gen->d.ia5 = email; 375100742Salc email = NULL; 37634202Sdyson gen->type = GEN_EMAIL; 37790935Ssilby if (!sk_GENERAL_NAME_push(gens, gen)) { 3785455Sdg X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); 3795455Sdg goto err; 38043086Sdillon } 38142957Sdillon gen = NULL; 38242957Sdillon } 38342957Sdillon 38442957Sdillon return 1; 38542957Sdillon 38642957Sdillon err: 38738799Sdfr GENERAL_NAME_free(gen); 388100742Salc M_ASN1_IA5STRING_free(email); 38934202Sdyson return 0; 39034202Sdyson 3915455Sdg} 3925455Sdg 39333936SdysonGENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, 3941541Srgrimes X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 3951541Srgrimes{ 39642957Sdillon GENERAL_NAME *gen; 39742957Sdillon GENERAL_NAMES *gens = NULL; 39851488Sdillon CONF_VALUE *cnf; 39951488Sdillon int i; 40042957Sdillon if (!(gens = sk_GENERAL_NAME_new_null())) { 40151488Sdillon X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); 40234202Sdyson return NULL; 40334202Sdyson } 40495764Salc for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 4058585Sdg cnf = sk_CONF_VALUE_value(nval, i); 4068585Sdg if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 40710988Sdyson goto err; 4081541Srgrimes sk_GENERAL_NAME_push(gens, gen); 4095455Sdg } 4101541Srgrimes return gens; 41151488Sdillon err: 41251488Sdillon sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 41351488Sdillon return NULL; 41451488Sdillon} 41551488Sdillon 41634202SdysonGENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 41734202Sdyson CONF_VALUE *cnf) 41890935Ssilby{ 4191541Srgrimes return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); 4201541Srgrimes} 4211541Srgrimes 42232585SdysonGENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, 4235455Sdg X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 42442957Sdillon CONF_VALUE *cnf, int is_nc) 42551488Sdillon{ 42651488Sdillon char is_string = 0; 42751488Sdillon int type; 42851488Sdillon GENERAL_NAME *gen = NULL; 42951488Sdillon 43051488Sdillon char *name, *value; 43151488Sdillon 43242957Sdillon name = cnf->name; 43351488Sdillon value = cnf->value; 4341541Srgrimes 4351549Srgrimes if (!value) { 43615819Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); 43749338Salc return NULL; 4381541Srgrimes } 43949338Salc 44015819Sdyson if (out) 44115819Sdyson gen = out; 44232702Sdyson else { 44334202Sdyson gen = GENERAL_NAME_new(); 44432702Sdyson if (gen == NULL) { 44532702Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, ERR_R_MALLOC_FAILURE); 44632702Sdyson return NULL; 44734202Sdyson } 44832702Sdyson } 44932702Sdyson 45015819Sdyson if (!name_cmp(name, "email")) { 45115819Sdyson is_string = 1; 45234202Sdyson type = GEN_EMAIL; 45351488Sdillon } else if (!name_cmp(name, "URI")) { 45451488Sdillon is_string = 1; 45551488Sdillon type = GEN_URI; 45651488Sdillon } else if (!name_cmp(name, "DNS")) { 45751488Sdillon is_string = 1; 45815819Sdyson type = GEN_DNS; 45951488Sdillon } else if (!name_cmp(name, "RID")) { 46051488Sdillon ASN1_OBJECT *obj; 46115819Sdyson if (!(obj = OBJ_txt2obj(value, 0))) { 46215819Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_BAD_OBJECT); 46351488Sdillon ERR_add_error_data(2, "value=", value); 46415819Sdyson goto err; 465100413Salc } 46646349Salc gen->d.rid = obj; 46746349Salc type = GEN_RID; 46846349Salc } else if (!name_cmp(name, "IP")) { 46946349Salc if (is_nc) 47046349Salc gen->d.ip = a2i_IPADDRESS_NC(value); 47192029Seivind else 47224678Speter gen->d.ip = a2i_IPADDRESS(value); 47315819Sdyson if (gen->d.ip == NULL) { 47415819Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_BAD_IP_ADDRESS); 47592029Seivind ERR_add_error_data(2, "value=", value); 47692029Seivind goto err; 47715819Sdyson } 47815819Sdyson type = GEN_IPADD; 47916058Sdyson } else if (!name_cmp(name, "dirName")) { 48061081Sdillon type = GEN_DIRNAME; 48116058Sdyson if (!do_dirname(gen, value, ctx)) { 48215819Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_DIRNAME_ERROR); 48315819Sdyson goto err; 48415819Sdyson } 48515819Sdyson } else if (!name_cmp(name, "otherName")) { 48615819Sdyson if (!do_othername(gen, value, ctx)) { 487106981Salc X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_OTHERNAME_ERROR); 48815819Sdyson goto err; 48915819Sdyson } 49015819Sdyson type = GEN_OTHERNAME; 49115819Sdyson } else { 49215819Sdyson X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); 493100413Salc ERR_add_error_data(2, "name=", name); 49415819Sdyson goto err; 49515819Sdyson } 49615819Sdyson 49715819Sdyson if (is_string) { 4981541Srgrimes if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || 4995455Sdg !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, 5005455Sdg strlen(value))) { 5015455Sdg X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, ERR_R_MALLOC_FAILURE); 5025455Sdg goto err; 5035455Sdg } 5045455Sdg } 5055455Sdg 5065455Sdg gen->type = type; 5075455Sdg 5085455Sdg return gen; 50942957Sdillon 51042957Sdillon err: 51195701Salc if (!out) 51295701Salc GENERAL_NAME_free(gen); 51395701Salc return NULL; 5141549Srgrimes} 5153449Sphk 51634202Sdysonstatic int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 5171541Srgrimes{ 5181541Srgrimes char *objtmp = NULL, *p; 51951488Sdillon int objlen; 52051488Sdillon if (!(p = strchr(value, ';'))) 52195701Salc return 0; 52295701Salc if (!(gen->d.otherName = OTHERNAME_new())) 52395701Salc return 0; 52451488Sdillon /* 52551488Sdillon * Free this up because we will overwrite it. no need to free type_id 52651488Sdillon * because it is static 52751488Sdillon */ 5285455Sdg ASN1_TYPE_free(gen->d.otherName->value); 52942957Sdillon if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) 53042957Sdillon return 0; 5311541Srgrimes objlen = p - value; 53234202Sdyson objtmp = OPENSSL_malloc(objlen + 1); 5331541Srgrimes strncpy(objtmp, value, objlen); 5341549Srgrimes objtmp[objlen] = 0; 53534202Sdyson gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); 5369507Sdg OPENSSL_free(objtmp); 53710988Sdyson if (!gen->d.otherName->type_id) 5381541Srgrimes return 0; 5391541Srgrimes return 1; 54017312Sdyson} 54117312Sdyson 54217312Sdysonstatic int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 54317312Sdyson{ 54417312Sdyson int ret; 5455455Sdg STACK_OF(CONF_VALUE) *sk; 5465455Sdg X509_NAME *nm; 5475455Sdg if (!(nm = X509_NAME_new())) 5481541Srgrimes return 0; 54934202Sdyson sk = X509V3_get_section(ctx, value); 55092029Seivind if (!sk) { 55134202Sdyson X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); 55217312Sdyson ERR_add_error_data(2, "section=", value); 5537695Sdg X509_NAME_free(nm); 5548876Srgrimes return 0; 5551549Srgrimes } 55642957Sdillon /* FIXME: should allow other character types... */ 5571541Srgrimes ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); 5581541Srgrimes if (!ret) 5595455Sdg X509_NAME_free(nm); 5605455Sdg gen->d.dirn = nm; 5615455Sdg 5628876Srgrimes X509V3_section_free(ctx, sk); 5639507Sdg 5645455Sdg return ret; 5658876Srgrimes} 5665455Sdg