Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <openssl/asn1.h>
  57. #include <time.h>
  58. #include <openssl/asn1t.h>
  59. #include <openssl/err.h>
  60. #include <openssl/obj.h>
  61. #include <openssl/mem.h>
  62. #include "asn1_locl.h"
  63. /*
  64. * Print routines.
  65. */
  66. /* ASN1_PCTX routines */
  67. static ASN1_PCTX default_pctx = {
  68. ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
  69. 0, /* nm_flags */
  70. 0, /* cert_flags */
  71. 0, /* oid_flags */
  72. 0 /* str_flags */
  73. };
  74. ASN1_PCTX *ASN1_PCTX_new(void)
  75. {
  76. ASN1_PCTX *ret;
  77. ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
  78. if (ret == NULL) {
  79. OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
  80. return NULL;
  81. }
  82. ret->flags = 0;
  83. ret->nm_flags = 0;
  84. ret->cert_flags = 0;
  85. ret->oid_flags = 0;
  86. ret->str_flags = 0;
  87. return ret;
  88. }
  89. void ASN1_PCTX_free(ASN1_PCTX *p)
  90. {
  91. OPENSSL_free(p);
  92. }
  93. unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
  94. {
  95. return p->flags;
  96. }
  97. void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
  98. {
  99. p->flags = flags;
  100. }
  101. unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
  102. {
  103. return p->nm_flags;
  104. }
  105. void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
  106. {
  107. p->nm_flags = flags;
  108. }
  109. unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
  110. {
  111. return p->cert_flags;
  112. }
  113. void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
  114. {
  115. p->cert_flags = flags;
  116. }
  117. unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
  118. {
  119. return p->oid_flags;
  120. }
  121. void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
  122. {
  123. p->oid_flags = flags;
  124. }
  125. unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
  126. {
  127. return p->str_flags;
  128. }
  129. void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
  130. {
  131. p->str_flags = flags;
  132. }
  133. /* Main print routines */
  134. static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
  135. const ASN1_ITEM *it,
  136. const char *fname, const char *sname,
  137. int nohdr, const ASN1_PCTX *pctx);
  138. int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
  139. const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
  140. static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
  141. const ASN1_ITEM *it, int indent,
  142. const char *fname, const char *sname,
  143. const ASN1_PCTX *pctx);
  144. static int asn1_print_fsname(BIO *out, int indent,
  145. const char *fname, const char *sname,
  146. const ASN1_PCTX *pctx);
  147. int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
  148. const ASN1_ITEM *it, const ASN1_PCTX *pctx)
  149. {
  150. const char *sname;
  151. if (pctx == NULL)
  152. pctx = &default_pctx;
  153. if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
  154. sname = NULL;
  155. else
  156. sname = it->sname;
  157. return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
  158. }
  159. static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
  160. const ASN1_ITEM *it,
  161. const char *fname, const char *sname,
  162. int nohdr, const ASN1_PCTX *pctx)
  163. {
  164. const ASN1_TEMPLATE *tt;
  165. const ASN1_EXTERN_FUNCS *ef;
  166. ASN1_VALUE **tmpfld;
  167. const ASN1_AUX *aux = it->funcs;
  168. ASN1_aux_cb *asn1_cb;
  169. ASN1_PRINT_ARG parg;
  170. int i;
  171. if (aux && aux->asn1_cb) {
  172. parg.out = out;
  173. parg.indent = indent;
  174. parg.pctx = pctx;
  175. asn1_cb = aux->asn1_cb;
  176. } else
  177. asn1_cb = 0;
  178. if (*fld == NULL) {
  179. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
  180. if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
  181. return 0;
  182. if (BIO_puts(out, "<ABSENT>\n") <= 0)
  183. return 0;
  184. }
  185. return 1;
  186. }
  187. switch (it->itype) {
  188. case ASN1_ITYPE_PRIMITIVE:
  189. if (it->templates) {
  190. if (!asn1_template_print_ctx(out, fld, indent,
  191. it->templates, pctx))
  192. return 0;
  193. break;
  194. }
  195. /* fall thru */
  196. case ASN1_ITYPE_MSTRING:
  197. if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
  198. return 0;
  199. break;
  200. case ASN1_ITYPE_EXTERN:
  201. if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
  202. return 0;
  203. /* Use new style print routine if possible */
  204. ef = it->funcs;
  205. if (ef && ef->asn1_ex_print) {
  206. i = ef->asn1_ex_print(out, fld, indent, "", pctx);
  207. if (!i)
  208. return 0;
  209. if ((i == 2) && (BIO_puts(out, "\n") <= 0))
  210. return 0;
  211. return 1;
  212. } else if (sname &&
  213. BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
  214. return 0;
  215. break;
  216. case ASN1_ITYPE_CHOICE:
  217. #if 0
  218. if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
  219. return 0;
  220. #endif
  221. /* CHOICE type, get selector */
  222. i = asn1_get_choice_selector(fld, it);
  223. /* This should never happen... */
  224. if ((i < 0) || (i >= it->tcount)) {
  225. if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
  226. return 0;
  227. return 1;
  228. }
  229. tt = it->templates + i;
  230. tmpfld = asn1_get_field_ptr(fld, tt);
  231. if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
  232. return 0;
  233. break;
  234. case ASN1_ITYPE_SEQUENCE:
  235. case ASN1_ITYPE_NDEF_SEQUENCE:
  236. if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
  237. return 0;
  238. if (fname || sname) {
  239. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
  240. if (BIO_puts(out, " {\n") <= 0)
  241. return 0;
  242. } else {
  243. if (BIO_puts(out, "\n") <= 0)
  244. return 0;
  245. }
  246. }
  247. if (asn1_cb) {
  248. i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
  249. if (i == 0)
  250. return 0;
  251. if (i == 2)
  252. return 1;
  253. }
  254. /* Print each field entry */
  255. for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
  256. const ASN1_TEMPLATE *seqtt;
  257. seqtt = asn1_do_adb(fld, tt, 1);
  258. if (!seqtt)
  259. return 0;
  260. tmpfld = asn1_get_field_ptr(fld, seqtt);
  261. if (!asn1_template_print_ctx(out, tmpfld,
  262. indent + 2, seqtt, pctx))
  263. return 0;
  264. }
  265. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
  266. if (BIO_printf(out, "%*s}\n", indent, "") < 0)
  267. return 0;
  268. }
  269. if (asn1_cb) {
  270. i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
  271. if (i == 0)
  272. return 0;
  273. }
  274. break;
  275. default:
  276. BIO_printf(out, "Unprocessed type %d\n", it->itype);
  277. return 0;
  278. }
  279. return 1;
  280. }
  281. int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
  282. const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
  283. {
  284. int flags;
  285. size_t i;
  286. const char *sname, *fname;
  287. flags = tt->flags;
  288. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
  289. sname = ASN1_ITEM_ptr(tt->item)->sname;
  290. else
  291. sname = NULL;
  292. if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
  293. fname = NULL;
  294. else
  295. fname = tt->field_name;
  296. if (flags & ASN1_TFLG_SK_MASK) {
  297. const char *tname;
  298. ASN1_VALUE *skitem;
  299. STACK_OF(ASN1_VALUE) *stack;
  300. /* SET OF, SEQUENCE OF */
  301. if (fname) {
  302. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
  303. if (flags & ASN1_TFLG_SET_OF)
  304. tname = "SET";
  305. else
  306. tname = "SEQUENCE";
  307. if (BIO_printf(out, "%*s%s OF %s {\n",
  308. indent, "", tname, tt->field_name) <= 0)
  309. return 0;
  310. } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
  311. return 0;
  312. }
  313. stack = (STACK_OF(ASN1_VALUE) *)*fld;
  314. for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
  315. if ((i > 0) && (BIO_puts(out, "\n") <= 0))
  316. return 0;
  317. skitem = sk_ASN1_VALUE_value(stack, i);
  318. if (!asn1_item_print_ctx(out, &skitem, indent + 2,
  319. ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
  320. pctx))
  321. return 0;
  322. }
  323. if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
  324. return 0;
  325. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
  326. if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
  327. return 0;
  328. }
  329. return 1;
  330. }
  331. return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
  332. fname, sname, 0, pctx);
  333. }
  334. static int asn1_print_fsname(BIO *out, int indent,
  335. const char *fname, const char *sname,
  336. const ASN1_PCTX *pctx)
  337. {
  338. static char spaces[] = " ";
  339. const int nspaces = sizeof(spaces) - 1;
  340. #if 0
  341. if (!sname && !fname)
  342. return 1;
  343. #endif
  344. while (indent > nspaces) {
  345. if (BIO_write(out, spaces, nspaces) != nspaces)
  346. return 0;
  347. indent -= nspaces;
  348. }
  349. if (BIO_write(out, spaces, indent) != indent)
  350. return 0;
  351. if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
  352. sname = NULL;
  353. if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
  354. fname = NULL;
  355. if (!sname && !fname)
  356. return 1;
  357. if (fname) {
  358. if (BIO_puts(out, fname) <= 0)
  359. return 0;
  360. }
  361. if (sname) {
  362. if (fname) {
  363. if (BIO_printf(out, " (%s)", sname) <= 0)
  364. return 0;
  365. } else {
  366. if (BIO_puts(out, sname) <= 0)
  367. return 0;
  368. }
  369. }
  370. if (BIO_write(out, ": ", 2) != 2)
  371. return 0;
  372. return 1;
  373. }
  374. static int asn1_print_boolean_ctx(BIO *out, int boolval,
  375. const ASN1_PCTX *pctx)
  376. {
  377. const char *str;
  378. switch (boolval) {
  379. case -1:
  380. str = "BOOL ABSENT";
  381. break;
  382. case 0:
  383. str = "FALSE";
  384. break;
  385. default:
  386. str = "TRUE";
  387. break;
  388. }
  389. if (BIO_puts(out, str) <= 0)
  390. return 0;
  391. return 1;
  392. }
  393. static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
  394. const ASN1_PCTX *pctx)
  395. {
  396. BIGNUM *bn = NULL;
  397. char *s = NULL;
  398. int ret = 1;
  399. bn = ASN1_INTEGER_to_BN(str, NULL);
  400. if (bn == NULL) {
  401. return 0;
  402. }
  403. s = BN_bn2dec(bn);
  404. BN_free(bn);
  405. if (s == NULL) {
  406. return 0;
  407. }
  408. if (BIO_puts(out, s) <= 0) {
  409. ret = 0;
  410. }
  411. OPENSSL_free(s);
  412. return ret;
  413. }
  414. static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
  415. const ASN1_PCTX *pctx)
  416. {
  417. char objbuf[80];
  418. const char *ln;
  419. ln = OBJ_nid2ln(OBJ_obj2nid(oid));
  420. if (!ln)
  421. ln = "";
  422. OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
  423. if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
  424. return 0;
  425. return 1;
  426. }
  427. static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
  428. const ASN1_PCTX *pctx)
  429. {
  430. if (str->type == V_ASN1_BIT_STRING) {
  431. if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
  432. return 0;
  433. } else if (BIO_puts(out, "\n") <= 0)
  434. return 0;
  435. if (str->length > 0
  436. && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
  437. return 0;
  438. }
  439. return 1;
  440. }
  441. static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
  442. const ASN1_ITEM *it, int indent,
  443. const char *fname, const char *sname,
  444. const ASN1_PCTX *pctx)
  445. {
  446. long utype;
  447. ASN1_STRING *str;
  448. int ret = 1, needlf = 1;
  449. const char *pname;
  450. const ASN1_PRIMITIVE_FUNCS *pf;
  451. pf = it->funcs;
  452. if (!asn1_print_fsname(out, indent, fname, sname, pctx))
  453. return 0;
  454. if (pf && pf->prim_print)
  455. return pf->prim_print(out, fld, it, indent, pctx);
  456. str = (ASN1_STRING *)*fld;
  457. if (it->itype == ASN1_ITYPE_MSTRING)
  458. utype = str->type & ~V_ASN1_NEG;
  459. else
  460. utype = it->utype;
  461. if (utype == V_ASN1_ANY) {
  462. ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
  463. utype = atype->type;
  464. fld = &atype->value.asn1_value;
  465. str = (ASN1_STRING *)*fld;
  466. if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
  467. pname = NULL;
  468. else
  469. pname = ASN1_tag2str(utype);
  470. } else {
  471. if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
  472. pname = ASN1_tag2str(utype);
  473. else
  474. pname = NULL;
  475. }
  476. if (utype == V_ASN1_NULL) {
  477. if (BIO_puts(out, "NULL\n") <= 0)
  478. return 0;
  479. return 1;
  480. }
  481. if (pname) {
  482. if (BIO_puts(out, pname) <= 0)
  483. return 0;
  484. if (BIO_puts(out, ":") <= 0)
  485. return 0;
  486. }
  487. switch (utype) {
  488. case V_ASN1_BOOLEAN:
  489. {
  490. int boolval = *(int *)fld;
  491. if (boolval == -1)
  492. boolval = it->size;
  493. ret = asn1_print_boolean_ctx(out, boolval, pctx);
  494. }
  495. break;
  496. case V_ASN1_INTEGER:
  497. case V_ASN1_ENUMERATED:
  498. ret = asn1_print_integer_ctx(out, str, pctx);
  499. break;
  500. case V_ASN1_UTCTIME:
  501. ret = ASN1_UTCTIME_print(out, str);
  502. break;
  503. case V_ASN1_GENERALIZEDTIME:
  504. ret = ASN1_GENERALIZEDTIME_print(out, str);
  505. break;
  506. case V_ASN1_OBJECT:
  507. ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
  508. break;
  509. case V_ASN1_OCTET_STRING:
  510. case V_ASN1_BIT_STRING:
  511. ret = asn1_print_obstring_ctx(out, str, indent, pctx);
  512. needlf = 0;
  513. break;
  514. case V_ASN1_SEQUENCE:
  515. case V_ASN1_SET:
  516. case V_ASN1_OTHER:
  517. if (BIO_puts(out, "\n") <= 0)
  518. return 0;
  519. if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
  520. ret = 0;
  521. needlf = 0;
  522. break;
  523. default:
  524. ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
  525. }
  526. if (!ret)
  527. return 0;
  528. if (needlf && BIO_puts(out, "\n") <= 0)
  529. return 0;
  530. return 1;
  531. }