Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

615 rindas
18 KiB

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