1 /* 2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include "crypto/x509.h" 13 #include <openssl/conf.h> 14 #include <openssl/x509v3.h> 15 #include <openssl/bio.h> 16 #include "ext_dat.h" 17 18 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 19 X509V3_CTX *ctx, 20 STACK_OF(CONF_VALUE) *nval); 21 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 22 X509V3_CTX *ctx, 23 STACK_OF(CONF_VALUE) *nval); 24 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); 25 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); 26 static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); 27 static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); 28 29 const X509V3_EXT_METHOD ossl_v3_alt[3] = { 30 {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 31 0, 0, 0, 0, 32 0, 0, 33 (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 34 (X509V3_EXT_V2I)v2i_subject_alt, 35 NULL, NULL, NULL}, 36 37 {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 38 0, 0, 0, 0, 39 0, 0, 40 (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 41 (X509V3_EXT_V2I)v2i_issuer_alt, 42 NULL, NULL, NULL}, 43 44 {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), 45 0, 0, 0, 0, 46 0, 0, 47 (X509V3_EXT_I2V) i2v_GENERAL_NAMES, 48 NULL, NULL, NULL, NULL}, 49 }; 50 51 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 52 GENERAL_NAMES *gens, 53 STACK_OF(CONF_VALUE) *ret) 54 { 55 int i; 56 GENERAL_NAME *gen; 57 STACK_OF(CONF_VALUE) *tmpret = NULL, *origret = ret; 58 59 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { 60 gen = sk_GENERAL_NAME_value(gens, i); 61 /* 62 * i2v_GENERAL_NAME allocates ret if it is NULL. If something goes 63 * wrong we need to free the stack - but only if it was empty when we 64 * originally entered this function. 65 */ 66 tmpret = i2v_GENERAL_NAME(method, gen, ret); 67 if (tmpret == NULL) { 68 if (origret == NULL) 69 sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); 70 return NULL; 71 } 72 ret = tmpret; 73 } 74 if (ret == NULL) 75 return sk_CONF_VALUE_new_null(); 76 return ret; 77 } 78 79 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, 80 GENERAL_NAME *gen, 81 STACK_OF(CONF_VALUE) *ret) 82 { 83 char othername[300]; 84 char oline[256], *tmp; 85 86 switch (gen->type) { 87 case GEN_OTHERNAME: 88 switch (OBJ_obj2nid(gen->d.otherName->type_id)) { 89 case NID_id_on_SmtpUTF8Mailbox: 90 if (gen->d.otherName->value->type != V_ASN1_UTF8STRING 91 || !x509v3_add_len_value_uchar("othername: SmtpUTF8Mailbox:", 92 gen->d.otherName->value->value.utf8string->data, 93 gen->d.otherName->value->value.utf8string->length, 94 &ret)) 95 return NULL; 96 break; 97 case NID_XmppAddr: 98 if (gen->d.otherName->value->type != V_ASN1_UTF8STRING 99 || !x509v3_add_len_value_uchar("othername: XmppAddr:", 100 gen->d.otherName->value->value.utf8string->data, 101 gen->d.otherName->value->value.utf8string->length, 102 &ret)) 103 return NULL; 104 break; 105 case NID_SRVName: 106 if (gen->d.otherName->value->type != V_ASN1_IA5STRING 107 || !x509v3_add_len_value_uchar("othername: SRVName:", 108 gen->d.otherName->value->value.ia5string->data, 109 gen->d.otherName->value->value.ia5string->length, 110 &ret)) 111 return NULL; 112 break; 113 case NID_ms_upn: 114 if (gen->d.otherName->value->type != V_ASN1_UTF8STRING 115 || !x509v3_add_len_value_uchar("othername: UPN:", 116 gen->d.otherName->value->value.utf8string->data, 117 gen->d.otherName->value->value.utf8string->length, 118 &ret)) 119 return NULL; 120 break; 121 case NID_NAIRealm: 122 if (gen->d.otherName->value->type != V_ASN1_UTF8STRING 123 || !x509v3_add_len_value_uchar("othername: NAIRealm:", 124 gen->d.otherName->value->value.utf8string->data, 125 gen->d.otherName->value->value.utf8string->length, 126 &ret)) 127 return NULL; 128 break; 129 default: 130 if (OBJ_obj2txt(oline, sizeof(oline), gen->d.otherName->type_id, 0) > 0) 131 BIO_snprintf(othername, sizeof(othername), "othername: %s:", 132 oline); 133 else 134 OPENSSL_strlcpy(othername, "othername:", sizeof(othername)); 135 136 /* check if the value is something printable */ 137 if (gen->d.otherName->value->type == V_ASN1_IA5STRING) { 138 if (x509v3_add_len_value_uchar(othername, 139 gen->d.otherName->value->value.ia5string->data, 140 gen->d.otherName->value->value.ia5string->length, 141 &ret)) 142 return ret; 143 } 144 if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { 145 if (x509v3_add_len_value_uchar(othername, 146 gen->d.otherName->value->value.utf8string->data, 147 gen->d.otherName->value->value.utf8string->length, 148 &ret)) 149 return ret; 150 } 151 if (!X509V3_add_value(othername, "<unsupported>", &ret)) 152 return NULL; 153 break; 154 } 155 break; 156 157 case GEN_X400: 158 if (!X509V3_add_value("X400Name", "<unsupported>", &ret)) 159 return NULL; 160 break; 161 162 case GEN_EDIPARTY: 163 if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret)) 164 return NULL; 165 break; 166 167 case GEN_EMAIL: 168 if (!x509v3_add_len_value_uchar("email", gen->d.ia5->data, 169 gen->d.ia5->length, &ret)) 170 return NULL; 171 break; 172 173 case GEN_DNS: 174 if (!x509v3_add_len_value_uchar("DNS", gen->d.ia5->data, 175 gen->d.ia5->length, &ret)) 176 return NULL; 177 break; 178 179 case GEN_URI: 180 if (!x509v3_add_len_value_uchar("URI", gen->d.ia5->data, 181 gen->d.ia5->length, &ret)) 182 return NULL; 183 break; 184 185 case GEN_DIRNAME: 186 if (X509_NAME_oneline(gen->d.dirn, oline, sizeof(oline)) == NULL 187 || !X509V3_add_value("DirName", oline, &ret)) 188 return NULL; 189 break; 190 191 case GEN_IPADD: 192 tmp = ossl_ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); 193 if (tmp == NULL || !X509V3_add_value("IP Address", tmp, &ret)) 194 ret = NULL; 195 OPENSSL_free(tmp); 196 break; 197 198 case GEN_RID: 199 i2t_ASN1_OBJECT(oline, 256, gen->d.rid); 200 if (!X509V3_add_value("Registered ID", oline, &ret)) 201 return NULL; 202 break; 203 } 204 return ret; 205 } 206 207 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) 208 { 209 char *tmp; 210 int nid; 211 212 switch (gen->type) { 213 case GEN_OTHERNAME: 214 nid = OBJ_obj2nid(gen->d.otherName->type_id); 215 /* Validate the types are as we expect before we use them */ 216 if ((nid == NID_SRVName 217 && gen->d.otherName->value->type != V_ASN1_IA5STRING) 218 || (nid != NID_SRVName 219 && gen->d.otherName->value->type != V_ASN1_UTF8STRING)) { 220 BIO_printf(out, "othername:<unsupported>"); 221 break; 222 } 223 224 switch (nid) { 225 case NID_id_on_SmtpUTF8Mailbox: 226 BIO_printf(out, "othername:SmtpUTF8Mailbox:%.*s", 227 gen->d.otherName->value->value.utf8string->length, 228 gen->d.otherName->value->value.utf8string->data); 229 break; 230 case NID_XmppAddr: 231 BIO_printf(out, "othername:XmppAddr:%.*s", 232 gen->d.otherName->value->value.utf8string->length, 233 gen->d.otherName->value->value.utf8string->data); 234 break; 235 case NID_SRVName: 236 BIO_printf(out, "othername:SRVName:%.*s", 237 gen->d.otherName->value->value.ia5string->length, 238 gen->d.otherName->value->value.ia5string->data); 239 break; 240 case NID_ms_upn: 241 BIO_printf(out, "othername:UPN:%.*s", 242 gen->d.otherName->value->value.utf8string->length, 243 gen->d.otherName->value->value.utf8string->data); 244 break; 245 case NID_NAIRealm: 246 BIO_printf(out, "othername:NAIRealm:%.*s", 247 gen->d.otherName->value->value.utf8string->length, 248 gen->d.otherName->value->value.utf8string->data); 249 break; 250 default: 251 BIO_printf(out, "othername:<unsupported>"); 252 break; 253 } 254 break; 255 256 case GEN_X400: 257 BIO_printf(out, "X400Name:<unsupported>"); 258 break; 259 260 case GEN_EDIPARTY: 261 /* Maybe fix this: it is supported now */ 262 BIO_printf(out, "EdiPartyName:<unsupported>"); 263 break; 264 265 case GEN_EMAIL: 266 BIO_printf(out, "email:"); 267 ASN1_STRING_print(out, gen->d.ia5); 268 break; 269 270 case GEN_DNS: 271 BIO_printf(out, "DNS:"); 272 ASN1_STRING_print(out, gen->d.ia5); 273 break; 274 275 case GEN_URI: 276 BIO_printf(out, "URI:"); 277 ASN1_STRING_print(out, gen->d.ia5); 278 break; 279 280 case GEN_DIRNAME: 281 BIO_printf(out, "DirName:"); 282 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); 283 break; 284 285 case GEN_IPADD: 286 tmp = ossl_ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); 287 if (tmp == NULL) 288 return 0; 289 BIO_printf(out, "IP Address:%s", tmp); 290 OPENSSL_free(tmp); 291 break; 292 293 case GEN_RID: 294 BIO_printf(out, "Registered ID:"); 295 i2a_ASN1_OBJECT(out, gen->d.rid); 296 break; 297 } 298 return 1; 299 } 300 301 static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, 302 X509V3_CTX *ctx, 303 STACK_OF(CONF_VALUE) *nval) 304 { 305 const int num = sk_CONF_VALUE_num(nval); 306 GENERAL_NAMES *gens = sk_GENERAL_NAME_new_reserve(NULL, num); 307 int i; 308 309 if (gens == NULL) { 310 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 311 sk_GENERAL_NAME_free(gens); 312 return NULL; 313 } 314 for (i = 0; i < num; i++) { 315 CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); 316 317 if (!ossl_v3_name_cmp(cnf->name, "issuer") 318 && cnf->value && strcmp(cnf->value, "copy") == 0) { 319 if (!copy_issuer(ctx, gens)) 320 goto err; 321 } else { 322 GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); 323 324 if (gen == NULL) 325 goto err; 326 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ 327 } 328 } 329 return gens; 330 err: 331 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 332 return NULL; 333 } 334 335 /* Append subject altname of issuer to issuer alt name of subject */ 336 337 static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) 338 { 339 GENERAL_NAMES *ialt; 340 GENERAL_NAME *gen; 341 X509_EXTENSION *ext; 342 int i, num; 343 344 if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) 345 return 1; 346 if (!ctx || !ctx->issuer_cert) { 347 ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS); 348 goto err; 349 } 350 i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); 351 if (i < 0) 352 return 1; 353 if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL 354 || (ialt = X509V3_EXT_d2i(ext)) == NULL) { 355 ERR_raise(ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR); 356 goto err; 357 } 358 359 num = sk_GENERAL_NAME_num(ialt); 360 if (!sk_GENERAL_NAME_reserve(gens, num)) { 361 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 362 goto err; 363 } 364 365 for (i = 0; i < num; i++) { 366 gen = sk_GENERAL_NAME_value(ialt, i); 367 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ 368 } 369 sk_GENERAL_NAME_free(ialt); 370 371 return 1; 372 373 err: 374 return 0; 375 376 } 377 378 static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, 379 X509V3_CTX *ctx, 380 STACK_OF(CONF_VALUE) *nval) 381 { 382 GENERAL_NAMES *gens; 383 CONF_VALUE *cnf; 384 const int num = sk_CONF_VALUE_num(nval); 385 int i; 386 387 gens = sk_GENERAL_NAME_new_reserve(NULL, num); 388 if (gens == NULL) { 389 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 390 sk_GENERAL_NAME_free(gens); 391 return NULL; 392 } 393 394 for (i = 0; i < num; i++) { 395 cnf = sk_CONF_VALUE_value(nval, i); 396 if (ossl_v3_name_cmp(cnf->name, "email") == 0 397 && cnf->value && strcmp(cnf->value, "copy") == 0) { 398 if (!copy_email(ctx, gens, 0)) 399 goto err; 400 } else if (ossl_v3_name_cmp(cnf->name, "email") == 0 401 && cnf->value && strcmp(cnf->value, "move") == 0) { 402 if (!copy_email(ctx, gens, 1)) 403 goto err; 404 } else { 405 GENERAL_NAME *gen; 406 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) 407 goto err; 408 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ 409 } 410 } 411 return gens; 412 err: 413 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 414 return NULL; 415 } 416 417 /* 418 * Copy any email addresses in a certificate or request to GENERAL_NAMES 419 */ 420 421 static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) 422 { 423 X509_NAME *nm; 424 ASN1_IA5STRING *email = NULL; 425 X509_NAME_ENTRY *ne; 426 GENERAL_NAME *gen = NULL; 427 int i = -1; 428 429 if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) 430 return 1; 431 if (ctx == NULL 432 || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { 433 ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS); 434 return 0; 435 } 436 /* Find the subject name */ 437 nm = ctx->subject_cert != NULL ? 438 X509_get_subject_name(ctx->subject_cert) : 439 X509_REQ_get_subject_name(ctx->subject_req); 440 441 /* Now add any email address(es) to STACK */ 442 while ((i = X509_NAME_get_index_by_NID(nm, 443 NID_pkcs9_emailAddress, i)) >= 0) { 444 ne = X509_NAME_get_entry(nm, i); 445 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); 446 if (move_p) { 447 X509_NAME_delete_entry(nm, i); 448 X509_NAME_ENTRY_free(ne); 449 i--; 450 } 451 if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { 452 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 453 goto err; 454 } 455 gen->d.ia5 = email; 456 email = NULL; 457 gen->type = GEN_EMAIL; 458 if (!sk_GENERAL_NAME_push(gens, gen)) { 459 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 460 goto err; 461 } 462 gen = NULL; 463 } 464 465 return 1; 466 467 err: 468 GENERAL_NAME_free(gen); 469 ASN1_IA5STRING_free(email); 470 return 0; 471 472 } 473 474 GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, 475 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 476 { 477 GENERAL_NAME *gen; 478 GENERAL_NAMES *gens; 479 CONF_VALUE *cnf; 480 const int num = sk_CONF_VALUE_num(nval); 481 int i; 482 483 gens = sk_GENERAL_NAME_new_reserve(NULL, num); 484 if (gens == NULL) { 485 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 486 sk_GENERAL_NAME_free(gens); 487 return NULL; 488 } 489 490 for (i = 0; i < num; i++) { 491 cnf = sk_CONF_VALUE_value(nval, i); 492 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) 493 goto err; 494 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ 495 } 496 return gens; 497 err: 498 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 499 return NULL; 500 } 501 502 GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, 503 X509V3_CTX *ctx, CONF_VALUE *cnf) 504 { 505 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); 506 } 507 508 GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, 509 const X509V3_EXT_METHOD *method, 510 X509V3_CTX *ctx, int gen_type, const char *value, 511 int is_nc) 512 { 513 char is_string = 0; 514 GENERAL_NAME *gen = NULL; 515 516 if (!value) { 517 ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE); 518 return NULL; 519 } 520 521 if (out) 522 gen = out; 523 else { 524 gen = GENERAL_NAME_new(); 525 if (gen == NULL) { 526 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 527 return NULL; 528 } 529 } 530 531 switch (gen_type) { 532 case GEN_URI: 533 case GEN_EMAIL: 534 case GEN_DNS: 535 is_string = 1; 536 break; 537 538 case GEN_RID: 539 { 540 ASN1_OBJECT *obj; 541 if ((obj = OBJ_txt2obj(value, 0)) == NULL) { 542 ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT, 543 "value=%s", value); 544 goto err; 545 } 546 gen->d.rid = obj; 547 } 548 break; 549 550 case GEN_IPADD: 551 if (is_nc) 552 gen->d.ip = a2i_IPADDRESS_NC(value); 553 else 554 gen->d.ip = a2i_IPADDRESS(value); 555 if (gen->d.ip == NULL) { 556 ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS, 557 "value=%s", value); 558 goto err; 559 } 560 break; 561 562 case GEN_DIRNAME: 563 if (!do_dirname(gen, value, ctx)) { 564 ERR_raise(ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR); 565 goto err; 566 } 567 break; 568 569 case GEN_OTHERNAME: 570 if (!do_othername(gen, value, ctx)) { 571 ERR_raise(ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR); 572 goto err; 573 } 574 break; 575 default: 576 ERR_raise(ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE); 577 goto err; 578 } 579 580 if (is_string) { 581 if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || 582 !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, 583 strlen(value))) { 584 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 585 goto err; 586 } 587 } 588 589 gen->type = gen_type; 590 591 return gen; 592 593 err: 594 if (!out) 595 GENERAL_NAME_free(gen); 596 return NULL; 597 } 598 599 GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, 600 const X509V3_EXT_METHOD *method, 601 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) 602 { 603 int type; 604 605 char *name, *value; 606 607 name = cnf->name; 608 value = cnf->value; 609 610 if (!value) { 611 ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE); 612 return NULL; 613 } 614 615 if (!ossl_v3_name_cmp(name, "email")) 616 type = GEN_EMAIL; 617 else if (!ossl_v3_name_cmp(name, "URI")) 618 type = GEN_URI; 619 else if (!ossl_v3_name_cmp(name, "DNS")) 620 type = GEN_DNS; 621 else if (!ossl_v3_name_cmp(name, "RID")) 622 type = GEN_RID; 623 else if (!ossl_v3_name_cmp(name, "IP")) 624 type = GEN_IPADD; 625 else if (!ossl_v3_name_cmp(name, "dirName")) 626 type = GEN_DIRNAME; 627 else if (!ossl_v3_name_cmp(name, "otherName")) 628 type = GEN_OTHERNAME; 629 else { 630 ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION, 631 "name=%s", name); 632 return NULL; 633 } 634 635 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); 636 637 } 638 639 static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) 640 { 641 char *objtmp = NULL, *p; 642 int objlen; 643 644 if ((p = strchr(value, ';')) == NULL) 645 return 0; 646 if ((gen->d.otherName = OTHERNAME_new()) == NULL) 647 return 0; 648 /* 649 * Free this up because we will overwrite it. no need to free type_id 650 * because it is static 651 */ 652 ASN1_TYPE_free(gen->d.otherName->value); 653 if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL) 654 return 0; 655 objlen = p - value; 656 objtmp = OPENSSL_strndup(value, objlen); 657 if (objtmp == NULL) 658 return 0; 659 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); 660 OPENSSL_free(objtmp); 661 if (!gen->d.otherName->type_id) 662 return 0; 663 return 1; 664 } 665 666 static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) 667 { 668 int ret = 0; 669 STACK_OF(CONF_VALUE) *sk = NULL; 670 X509_NAME *nm; 671 672 if ((nm = X509_NAME_new()) == NULL) 673 goto err; 674 sk = X509V3_get_section(ctx, value); 675 if (!sk) { 676 ERR_raise_data(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND, 677 "section=%s", value); 678 goto err; 679 } 680 /* FIXME: should allow other character types... */ 681 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); 682 if (!ret) 683 goto err; 684 gen->d.dirn = nm; 685 686 err: 687 if (ret == 0) 688 X509_NAME_free(nm); 689 X509V3_section_free(ctx, sk); 690 return ret; 691 } 692