1*0Sstevel@tonic-gate /* v3_alt.c */ 2*0Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3*0Sstevel@tonic-gate * project 1999. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate /* ==================================================================== 6*0Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 9*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 10*0Sstevel@tonic-gate * are met: 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 13*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 16*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 17*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 18*0Sstevel@tonic-gate * distribution. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 21*0Sstevel@tonic-gate * software must display the following acknowledgment: 22*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 23*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*0Sstevel@tonic-gate * endorse or promote products derived from this software without 27*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 28*0Sstevel@tonic-gate * licensing@OpenSSL.org. 29*0Sstevel@tonic-gate * 30*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 31*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 32*0Sstevel@tonic-gate * permission of the OpenSSL Project. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 35*0Sstevel@tonic-gate * acknowledgment: 36*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 37*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 51*0Sstevel@tonic-gate * ==================================================================== 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 54*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 55*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include "cryptlib.h" 61*0Sstevel@tonic-gate #include <openssl/conf.h> 62*0Sstevel@tonic-gate #include <openssl/x509v3.h> 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 65*0Sstevel@tonic-gate static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 66*0Sstevel@tonic-gate static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); 67*0Sstevel@tonic-gate static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); 68*0Sstevel@tonic-gate X509V3_EXT_METHOD v3_alt[] = { 69*0Sstevel@tonic-gate { NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 70*0Sstevel@tonic-gate 0,0,0,0, 71*0Sstevel@tonic-gate 0,0, 72*0Sstevel@tonic-gate (X509V3_EXT_I2V)i2v_GENERAL_NAMES, 73*0Sstevel@tonic-gate (X509V3_EXT_V2I)v2i_subject_alt, 74*0Sstevel@tonic-gate NULL, NULL, NULL}, 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate { NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 77*0Sstevel@tonic-gate 0,0,0,0, 78*0Sstevel@tonic-gate 0,0, 79*0Sstevel@tonic-gate (X509V3_EXT_I2V)i2v_GENERAL_NAMES, 80*0Sstevel@tonic-gate (X509V3_EXT_V2I)v2i_issuer_alt, 81*0Sstevel@tonic-gate NULL, NULL, NULL}, 82*0Sstevel@tonic-gate }; 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 85*0Sstevel@tonic-gate GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret) 86*0Sstevel@tonic-gate { 87*0Sstevel@tonic-gate int i; 88*0Sstevel@tonic-gate GENERAL_NAME *gen; 89*0Sstevel@tonic-gate for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 90*0Sstevel@tonic-gate gen = sk_GENERAL_NAME_value(gens, i); 91*0Sstevel@tonic-gate ret = i2v_GENERAL_NAME(method, gen, ret); 92*0Sstevel@tonic-gate } 93*0Sstevel@tonic-gate if(!ret) return sk_CONF_VALUE_new_null(); 94*0Sstevel@tonic-gate return ret; 95*0Sstevel@tonic-gate } 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, 98*0Sstevel@tonic-gate GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) 99*0Sstevel@tonic-gate { 100*0Sstevel@tonic-gate unsigned char *p; 101*0Sstevel@tonic-gate char oline[256]; 102*0Sstevel@tonic-gate switch (gen->type) 103*0Sstevel@tonic-gate { 104*0Sstevel@tonic-gate case GEN_OTHERNAME: 105*0Sstevel@tonic-gate X509V3_add_value("othername","<unsupported>", &ret); 106*0Sstevel@tonic-gate break; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate case GEN_X400: 109*0Sstevel@tonic-gate X509V3_add_value("X400Name","<unsupported>", &ret); 110*0Sstevel@tonic-gate break; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate case GEN_EDIPARTY: 113*0Sstevel@tonic-gate X509V3_add_value("EdiPartyName","<unsupported>", &ret); 114*0Sstevel@tonic-gate break; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate case GEN_EMAIL: 117*0Sstevel@tonic-gate X509V3_add_value_uchar("email",gen->d.ia5->data, &ret); 118*0Sstevel@tonic-gate break; 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate case GEN_DNS: 121*0Sstevel@tonic-gate X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret); 122*0Sstevel@tonic-gate break; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate case GEN_URI: 125*0Sstevel@tonic-gate X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret); 126*0Sstevel@tonic-gate break; 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate case GEN_DIRNAME: 129*0Sstevel@tonic-gate X509_NAME_oneline(gen->d.dirn, oline, 256); 130*0Sstevel@tonic-gate X509V3_add_value("DirName",oline, &ret); 131*0Sstevel@tonic-gate break; 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate case GEN_IPADD: 134*0Sstevel@tonic-gate p = gen->d.ip->data; 135*0Sstevel@tonic-gate /* BUG: doesn't support IPV6 */ 136*0Sstevel@tonic-gate if(gen->d.ip->length != 4) { 137*0Sstevel@tonic-gate X509V3_add_value("IP Address","<invalid>", &ret); 138*0Sstevel@tonic-gate break; 139*0Sstevel@tonic-gate } 140*0Sstevel@tonic-gate BIO_snprintf(oline, sizeof oline, 141*0Sstevel@tonic-gate "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 142*0Sstevel@tonic-gate X509V3_add_value("IP Address",oline, &ret); 143*0Sstevel@tonic-gate break; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate case GEN_RID: 146*0Sstevel@tonic-gate i2t_ASN1_OBJECT(oline, 256, gen->d.rid); 147*0Sstevel@tonic-gate X509V3_add_value("Registered ID",oline, &ret); 148*0Sstevel@tonic-gate break; 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate return ret; 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 154*0Sstevel@tonic-gate { 155*0Sstevel@tonic-gate unsigned char *p; 156*0Sstevel@tonic-gate switch (gen->type) 157*0Sstevel@tonic-gate { 158*0Sstevel@tonic-gate case GEN_OTHERNAME: 159*0Sstevel@tonic-gate BIO_printf(out, "othername:<unsupported>"); 160*0Sstevel@tonic-gate break; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate case GEN_X400: 163*0Sstevel@tonic-gate BIO_printf(out, "X400Name:<unsupported>"); 164*0Sstevel@tonic-gate break; 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate case GEN_EDIPARTY: 167*0Sstevel@tonic-gate /* Maybe fix this: it is supported now */ 168*0Sstevel@tonic-gate BIO_printf(out, "EdiPartyName:<unsupported>"); 169*0Sstevel@tonic-gate break; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate case GEN_EMAIL: 172*0Sstevel@tonic-gate BIO_printf(out, "email:%s",gen->d.ia5->data); 173*0Sstevel@tonic-gate break; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate case GEN_DNS: 176*0Sstevel@tonic-gate BIO_printf(out, "DNS:%s",gen->d.ia5->data); 177*0Sstevel@tonic-gate break; 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate case GEN_URI: 180*0Sstevel@tonic-gate BIO_printf(out, "URI:%s",gen->d.ia5->data); 181*0Sstevel@tonic-gate break; 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate case GEN_DIRNAME: 184*0Sstevel@tonic-gate BIO_printf(out, "DirName: "); 185*0Sstevel@tonic-gate X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); 186*0Sstevel@tonic-gate break; 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate case GEN_IPADD: 189*0Sstevel@tonic-gate p = gen->d.ip->data; 190*0Sstevel@tonic-gate /* BUG: doesn't support IPV6 */ 191*0Sstevel@tonic-gate if(gen->d.ip->length != 4) { 192*0Sstevel@tonic-gate BIO_printf(out,"IP Address:<invalid>"); 193*0Sstevel@tonic-gate break; 194*0Sstevel@tonic-gate } 195*0Sstevel@tonic-gate BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 196*0Sstevel@tonic-gate break; 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate case GEN_RID: 199*0Sstevel@tonic-gate BIO_printf(out, "Registered ID"); 200*0Sstevel@tonic-gate i2a_ASN1_OBJECT(out, gen->d.rid); 201*0Sstevel@tonic-gate break; 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate return 1; 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 207*0Sstevel@tonic-gate X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 208*0Sstevel@tonic-gate { 209*0Sstevel@tonic-gate GENERAL_NAMES *gens = NULL; 210*0Sstevel@tonic-gate CONF_VALUE *cnf; 211*0Sstevel@tonic-gate int i; 212*0Sstevel@tonic-gate if(!(gens = sk_GENERAL_NAME_new_null())) { 213*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); 214*0Sstevel@tonic-gate return NULL; 215*0Sstevel@tonic-gate } 216*0Sstevel@tonic-gate for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 217*0Sstevel@tonic-gate cnf = sk_CONF_VALUE_value(nval, i); 218*0Sstevel@tonic-gate if(!name_cmp(cnf->name, "issuer") && cnf->value && 219*0Sstevel@tonic-gate !strcmp(cnf->value, "copy")) { 220*0Sstevel@tonic-gate if(!copy_issuer(ctx, gens)) goto err; 221*0Sstevel@tonic-gate } else { 222*0Sstevel@tonic-gate GENERAL_NAME *gen; 223*0Sstevel@tonic-gate if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 224*0Sstevel@tonic-gate goto err; 225*0Sstevel@tonic-gate sk_GENERAL_NAME_push(gens, gen); 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate } 228*0Sstevel@tonic-gate return gens; 229*0Sstevel@tonic-gate err: 230*0Sstevel@tonic-gate sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 231*0Sstevel@tonic-gate return NULL; 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate /* Append subject altname of issuer to issuer alt name of subject */ 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) 237*0Sstevel@tonic-gate { 238*0Sstevel@tonic-gate GENERAL_NAMES *ialt; 239*0Sstevel@tonic-gate GENERAL_NAME *gen; 240*0Sstevel@tonic-gate X509_EXTENSION *ext; 241*0Sstevel@tonic-gate int i; 242*0Sstevel@tonic-gate if(ctx && (ctx->flags == CTX_TEST)) return 1; 243*0Sstevel@tonic-gate if(!ctx || !ctx->issuer_cert) { 244*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS); 245*0Sstevel@tonic-gate goto err; 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); 248*0Sstevel@tonic-gate if(i < 0) return 1; 249*0Sstevel@tonic-gate if(!(ext = X509_get_ext(ctx->issuer_cert, i)) || 250*0Sstevel@tonic-gate !(ialt = X509V3_EXT_d2i(ext)) ) { 251*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR); 252*0Sstevel@tonic-gate goto err; 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { 256*0Sstevel@tonic-gate gen = sk_GENERAL_NAME_value(ialt, i); 257*0Sstevel@tonic-gate if(!sk_GENERAL_NAME_push(gens, gen)) { 258*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE); 259*0Sstevel@tonic-gate goto err; 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate sk_GENERAL_NAME_free(ialt); 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate return 1; 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate err: 267*0Sstevel@tonic-gate return 0; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 272*0Sstevel@tonic-gate X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 273*0Sstevel@tonic-gate { 274*0Sstevel@tonic-gate GENERAL_NAMES *gens = NULL; 275*0Sstevel@tonic-gate CONF_VALUE *cnf; 276*0Sstevel@tonic-gate int i; 277*0Sstevel@tonic-gate if(!(gens = sk_GENERAL_NAME_new_null())) { 278*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); 279*0Sstevel@tonic-gate return NULL; 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 282*0Sstevel@tonic-gate cnf = sk_CONF_VALUE_value(nval, i); 283*0Sstevel@tonic-gate if(!name_cmp(cnf->name, "email") && cnf->value && 284*0Sstevel@tonic-gate !strcmp(cnf->value, "copy")) { 285*0Sstevel@tonic-gate if(!copy_email(ctx, gens, 0)) goto err; 286*0Sstevel@tonic-gate } else if(!name_cmp(cnf->name, "email") && cnf->value && 287*0Sstevel@tonic-gate !strcmp(cnf->value, "move")) { 288*0Sstevel@tonic-gate if(!copy_email(ctx, gens, 1)) goto err; 289*0Sstevel@tonic-gate } else { 290*0Sstevel@tonic-gate GENERAL_NAME *gen; 291*0Sstevel@tonic-gate if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) 292*0Sstevel@tonic-gate goto err; 293*0Sstevel@tonic-gate sk_GENERAL_NAME_push(gens, gen); 294*0Sstevel@tonic-gate } 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate return gens; 297*0Sstevel@tonic-gate err: 298*0Sstevel@tonic-gate sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 299*0Sstevel@tonic-gate return NULL; 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate /* Copy any email addresses in a certificate or request to 303*0Sstevel@tonic-gate * GENERAL_NAMES 304*0Sstevel@tonic-gate */ 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) 307*0Sstevel@tonic-gate { 308*0Sstevel@tonic-gate X509_NAME *nm; 309*0Sstevel@tonic-gate ASN1_IA5STRING *email = NULL; 310*0Sstevel@tonic-gate X509_NAME_ENTRY *ne; 311*0Sstevel@tonic-gate GENERAL_NAME *gen = NULL; 312*0Sstevel@tonic-gate int i; 313*0Sstevel@tonic-gate if(ctx->flags == CTX_TEST) return 1; 314*0Sstevel@tonic-gate if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { 315*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); 316*0Sstevel@tonic-gate goto err; 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate /* Find the subject name */ 319*0Sstevel@tonic-gate if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert); 320*0Sstevel@tonic-gate else nm = X509_REQ_get_subject_name(ctx->subject_req); 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate /* Now add any email address(es) to STACK */ 323*0Sstevel@tonic-gate i = -1; 324*0Sstevel@tonic-gate while((i = X509_NAME_get_index_by_NID(nm, 325*0Sstevel@tonic-gate NID_pkcs9_emailAddress, i)) >= 0) { 326*0Sstevel@tonic-gate ne = X509_NAME_get_entry(nm, i); 327*0Sstevel@tonic-gate email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); 328*0Sstevel@tonic-gate if (move_p) 329*0Sstevel@tonic-gate { 330*0Sstevel@tonic-gate X509_NAME_delete_entry(nm, i); 331*0Sstevel@tonic-gate i--; 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate if(!email || !(gen = GENERAL_NAME_new())) { 334*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); 335*0Sstevel@tonic-gate goto err; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate gen->d.ia5 = email; 338*0Sstevel@tonic-gate email = NULL; 339*0Sstevel@tonic-gate gen->type = GEN_EMAIL; 340*0Sstevel@tonic-gate if(!sk_GENERAL_NAME_push(gens, gen)) { 341*0Sstevel@tonic-gate X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); 342*0Sstevel@tonic-gate goto err; 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate gen = NULL; 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate return 1; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate err: 351*0Sstevel@tonic-gate GENERAL_NAME_free(gen); 352*0Sstevel@tonic-gate M_ASN1_IA5STRING_free(email); 353*0Sstevel@tonic-gate return 0; 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate } 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, 358*0Sstevel@tonic-gate X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 359*0Sstevel@tonic-gate { 360*0Sstevel@tonic-gate GENERAL_NAME *gen; 361*0Sstevel@tonic-gate GENERAL_NAMES *gens = NULL; 362*0Sstevel@tonic-gate CONF_VALUE *cnf; 363*0Sstevel@tonic-gate int i; 364*0Sstevel@tonic-gate if(!(gens = sk_GENERAL_NAME_new_null())) { 365*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); 366*0Sstevel@tonic-gate return NULL; 367*0Sstevel@tonic-gate } 368*0Sstevel@tonic-gate for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 369*0Sstevel@tonic-gate cnf = sk_CONF_VALUE_value(nval, i); 370*0Sstevel@tonic-gate if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 371*0Sstevel@tonic-gate sk_GENERAL_NAME_push(gens, gen); 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate return gens; 374*0Sstevel@tonic-gate err: 375*0Sstevel@tonic-gate sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 376*0Sstevel@tonic-gate return NULL; 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate #if defined(_BOOT) 380*0Sstevel@tonic-gate /* stolen from bio/b_sock.c - XXXX - why steal it? */ 381*0Sstevel@tonic-gate /* The reason I have implemented this instead of using sscanf is because 382*0Sstevel@tonic-gate * Visual C 1.52c gives an unresolved external when linking a DLL :-( */ 383*0Sstevel@tonic-gate static int get_ip(const char *str, unsigned char ip[4]) 384*0Sstevel@tonic-gate { 385*0Sstevel@tonic-gate unsigned int tmp[4]; 386*0Sstevel@tonic-gate int num=0,c,ok=0; 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate tmp[0]=tmp[1]=tmp[2]=tmp[3]=0; 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate for (;;) 391*0Sstevel@tonic-gate { 392*0Sstevel@tonic-gate c= *(str++); 393*0Sstevel@tonic-gate if ((c >= '0') && (c <= '9')) 394*0Sstevel@tonic-gate { 395*0Sstevel@tonic-gate ok=1; 396*0Sstevel@tonic-gate tmp[num]=tmp[num]*10+c-'0'; 397*0Sstevel@tonic-gate if (tmp[num] > 255) return(0); 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate else if (c == '.') 400*0Sstevel@tonic-gate { 401*0Sstevel@tonic-gate if (!ok) return(-1); 402*0Sstevel@tonic-gate if (num == 3) return(0); 403*0Sstevel@tonic-gate num++; 404*0Sstevel@tonic-gate ok=0; 405*0Sstevel@tonic-gate } 406*0Sstevel@tonic-gate else if (c == '\0' && (num == 3) && ok) 407*0Sstevel@tonic-gate break; 408*0Sstevel@tonic-gate else 409*0Sstevel@tonic-gate return(0); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate ip[0]=tmp[0]; 412*0Sstevel@tonic-gate ip[1]=tmp[1]; 413*0Sstevel@tonic-gate ip[2]=tmp[2]; 414*0Sstevel@tonic-gate ip[3]=tmp[3]; 415*0Sstevel@tonic-gate return(1); 416*0Sstevel@tonic-gate } 417*0Sstevel@tonic-gate #endif /* _BOOT */ 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 420*0Sstevel@tonic-gate CONF_VALUE *cnf) 421*0Sstevel@tonic-gate { 422*0Sstevel@tonic-gate char is_string = 0; 423*0Sstevel@tonic-gate int type; 424*0Sstevel@tonic-gate GENERAL_NAME *gen = NULL; 425*0Sstevel@tonic-gate 426*0Sstevel@tonic-gate char *name, *value; 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate name = cnf->name; 429*0Sstevel@tonic-gate value = cnf->value; 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate if(!value) { 432*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); 433*0Sstevel@tonic-gate return NULL; 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate if(!(gen = GENERAL_NAME_new())) { 437*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); 438*0Sstevel@tonic-gate return NULL; 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate if(!name_cmp(name, "email")) { 442*0Sstevel@tonic-gate is_string = 1; 443*0Sstevel@tonic-gate type = GEN_EMAIL; 444*0Sstevel@tonic-gate } else if(!name_cmp(name, "URI")) { 445*0Sstevel@tonic-gate is_string = 1; 446*0Sstevel@tonic-gate type = GEN_URI; 447*0Sstevel@tonic-gate } else if(!name_cmp(name, "DNS")) { 448*0Sstevel@tonic-gate is_string = 1; 449*0Sstevel@tonic-gate type = GEN_DNS; 450*0Sstevel@tonic-gate } else if(!name_cmp(name, "RID")) { 451*0Sstevel@tonic-gate ASN1_OBJECT *obj; 452*0Sstevel@tonic-gate if(!(obj = OBJ_txt2obj(value,0))) { 453*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); 454*0Sstevel@tonic-gate ERR_add_error_data(2, "value=", value); 455*0Sstevel@tonic-gate goto err; 456*0Sstevel@tonic-gate } 457*0Sstevel@tonic-gate gen->d.rid = obj; 458*0Sstevel@tonic-gate type = GEN_RID; 459*0Sstevel@tonic-gate } else if(!name_cmp(name, "IP")) { 460*0Sstevel@tonic-gate int i1,i2,i3,i4; 461*0Sstevel@tonic-gate unsigned char ip[4]; 462*0Sstevel@tonic-gate 463*0Sstevel@tonic-gate #if defined(_BOOT) 464*0Sstevel@tonic-gate if (get_ip(value, ip) != 1) { 465*0Sstevel@tonic-gate #else /* _BOOT */ 466*0Sstevel@tonic-gate if ((sscanf(value, "%d.%d.%d.%d",&i1,&i2,&i3,&i4) != 4) || 467*0Sstevel@tonic-gate (i1 < 0) || (i1 > 255) || (i2 < 0) || (i2 > 255) || 468*0Sstevel@tonic-gate (i3 < 0) || (i3 > 255) || (i4 < 0) || (i4 > 255) ) { 469*0Sstevel@tonic-gate #endif /* _BOOT */ 470*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); 471*0Sstevel@tonic-gate ERR_add_error_data(2, "value=", value); 472*0Sstevel@tonic-gate goto err; 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate ip[0] = i1; ip[1] = i2 ; ip[2] = i3 ; ip[3] = i4; 475*0Sstevel@tonic-gate if(!(gen->d.ip = M_ASN1_OCTET_STRING_new()) || 476*0Sstevel@tonic-gate !ASN1_STRING_set(gen->d.ip, ip, 4)) { 477*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); 478*0Sstevel@tonic-gate goto err; 479*0Sstevel@tonic-gate } 480*0Sstevel@tonic-gate type = GEN_IPADD; 481*0Sstevel@tonic-gate } else { 482*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_OPTION); 483*0Sstevel@tonic-gate ERR_add_error_data(2, "name=", name); 484*0Sstevel@tonic-gate goto err; 485*0Sstevel@tonic-gate } 486*0Sstevel@tonic-gate 487*0Sstevel@tonic-gate if(is_string) { 488*0Sstevel@tonic-gate if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || 489*0Sstevel@tonic-gate !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, 490*0Sstevel@tonic-gate strlen(value))) { 491*0Sstevel@tonic-gate X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); 492*0Sstevel@tonic-gate goto err; 493*0Sstevel@tonic-gate } 494*0Sstevel@tonic-gate } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate gen->type = type; 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate return gen; 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate err: 501*0Sstevel@tonic-gate GENERAL_NAME_free(gen); 502*0Sstevel@tonic-gate return NULL; 503*0Sstevel@tonic-gate } 504