You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

621 lines
16 KiB

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