Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  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 <string.h>
  58. #include <openssl/asn1t.h>
  59. #include <openssl/mem.h>
  60. static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
  61. const ASN1_ITEM *it,
  62. int tag, int aclass);
  63. static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
  64. int skcontlen, const ASN1_ITEM *item,
  65. int do_sort, int iclass);
  66. static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
  67. const ASN1_TEMPLATE *tt,
  68. int tag, int aclass);
  69. static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
  70. const ASN1_ITEM *it, int flags);
  71. /* Top level i2d equivalents: the 'ndef' variant instructs the encoder
  72. * to use indefinite length constructed encoding, where appropriate
  73. */
  74. int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
  75. const ASN1_ITEM *it)
  76. {
  77. return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
  78. }
  79. int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
  80. {
  81. return asn1_item_flags_i2d(val, out, it, 0);
  82. }
  83. /* Encode an ASN1 item, this is use by the
  84. * standard 'i2d' function. 'out' points to
  85. * a buffer to output the data to.
  86. *
  87. * The new i2d has one additional feature. If the output
  88. * buffer is NULL (i.e. *out == NULL) then a buffer is
  89. * allocated and populated with the encoding.
  90. */
  91. static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
  92. const ASN1_ITEM *it, int flags)
  93. {
  94. if (out && !*out)
  95. {
  96. unsigned char *p, *buf;
  97. int len;
  98. len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
  99. if (len <= 0)
  100. return len;
  101. buf = OPENSSL_malloc(len);
  102. if (!buf)
  103. return -1;
  104. p = buf;
  105. ASN1_item_ex_i2d(&val, &p, it, -1, flags);
  106. *out = buf;
  107. return len;
  108. }
  109. return ASN1_item_ex_i2d(&val, out, it, -1, flags);
  110. }
  111. /* Encode an item, taking care of IMPLICIT tagging (if any).
  112. * This function performs the normal item handling: it can be
  113. * used in external types.
  114. */
  115. int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
  116. const ASN1_ITEM *it, int tag, int aclass)
  117. {
  118. const ASN1_TEMPLATE *tt = NULL;
  119. unsigned char *p = NULL;
  120. int i, seqcontlen, seqlen, ndef = 1;
  121. const ASN1_COMPAT_FUNCS *cf;
  122. const ASN1_EXTERN_FUNCS *ef;
  123. const ASN1_AUX *aux = it->funcs;
  124. ASN1_aux_cb *asn1_cb = 0;
  125. if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
  126. return 0;
  127. if (aux && aux->asn1_cb)
  128. asn1_cb = aux->asn1_cb;
  129. switch(it->itype)
  130. {
  131. case ASN1_ITYPE_PRIMITIVE:
  132. if (it->templates)
  133. return asn1_template_ex_i2d(pval, out, it->templates,
  134. tag, aclass);
  135. return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
  136. break;
  137. case ASN1_ITYPE_MSTRING:
  138. return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
  139. case ASN1_ITYPE_CHOICE:
  140. if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
  141. return 0;
  142. i = asn1_get_choice_selector(pval, it);
  143. if ((i >= 0) && (i < it->tcount))
  144. {
  145. ASN1_VALUE **pchval;
  146. const ASN1_TEMPLATE *chtt;
  147. chtt = it->templates + i;
  148. pchval = asn1_get_field_ptr(pval, chtt);
  149. return asn1_template_ex_i2d(pchval, out, chtt,
  150. -1, aclass);
  151. }
  152. /* Fixme: error condition if selector out of range */
  153. if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
  154. return 0;
  155. break;
  156. case ASN1_ITYPE_EXTERN:
  157. /* If new style i2d it does all the work */
  158. ef = it->funcs;
  159. return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
  160. case ASN1_ITYPE_COMPAT:
  161. /* old style hackery... */
  162. cf = it->funcs;
  163. if (out)
  164. p = *out;
  165. i = cf->asn1_i2d(*pval, out);
  166. /* Fixup for IMPLICIT tag: note this messes up for tags > 30,
  167. * but so did the old code. Tags > 30 are very rare anyway.
  168. */
  169. if (out && (tag != -1))
  170. *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
  171. return i;
  172. case ASN1_ITYPE_NDEF_SEQUENCE:
  173. /* Use indefinite length constructed if requested */
  174. if (aclass & ASN1_TFLG_NDEF) ndef = 2;
  175. /* fall through */
  176. case ASN1_ITYPE_SEQUENCE:
  177. i = asn1_enc_restore(&seqcontlen, out, pval, it);
  178. /* An error occurred */
  179. if (i < 0)
  180. return 0;
  181. /* We have a valid cached encoding... */
  182. if (i > 0)
  183. return seqcontlen;
  184. /* Otherwise carry on */
  185. seqcontlen = 0;
  186. /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
  187. if (tag == -1)
  188. {
  189. tag = V_ASN1_SEQUENCE;
  190. /* Retain any other flags in aclass */
  191. aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
  192. | V_ASN1_UNIVERSAL;
  193. }
  194. if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
  195. return 0;
  196. /* First work out sequence content length */
  197. for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
  198. {
  199. const ASN1_TEMPLATE *seqtt;
  200. ASN1_VALUE **pseqval;
  201. seqtt = asn1_do_adb(pval, tt, 1);
  202. if (!seqtt)
  203. return 0;
  204. pseqval = asn1_get_field_ptr(pval, seqtt);
  205. /* FIXME: check for errors in enhanced version */
  206. seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
  207. -1, aclass);
  208. }
  209. seqlen = ASN1_object_size(ndef, seqcontlen, tag);
  210. if (!out)
  211. return seqlen;
  212. /* Output SEQUENCE header */
  213. ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
  214. for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
  215. {
  216. const ASN1_TEMPLATE *seqtt;
  217. ASN1_VALUE **pseqval;
  218. seqtt = asn1_do_adb(pval, tt, 1);
  219. if (!seqtt)
  220. return 0;
  221. pseqval = asn1_get_field_ptr(pval, seqtt);
  222. /* FIXME: check for errors in enhanced version */
  223. asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
  224. }
  225. if (ndef == 2)
  226. ASN1_put_eoc(out);
  227. if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
  228. return 0;
  229. return seqlen;
  230. default:
  231. return 0;
  232. }
  233. return 0;
  234. }
  235. int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
  236. const ASN1_TEMPLATE *tt)
  237. {
  238. return asn1_template_ex_i2d(pval, out, tt, -1, 0);
  239. }
  240. static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
  241. const ASN1_TEMPLATE *tt, int tag, int iclass)
  242. {
  243. int i, ret, flags, ttag, tclass, ndef;
  244. size_t j;
  245. flags = tt->flags;
  246. /* Work out tag and class to use: tagging may come
  247. * either from the template or the arguments, not both
  248. * because this would create ambiguity. Additionally
  249. * the iclass argument may contain some additional flags
  250. * which should be noted and passed down to other levels.
  251. */
  252. if (flags & ASN1_TFLG_TAG_MASK)
  253. {
  254. /* Error if argument and template tagging */
  255. if (tag != -1)
  256. /* FIXME: error code here */
  257. return -1;
  258. /* Get tagging from template */
  259. ttag = tt->tag;
  260. tclass = flags & ASN1_TFLG_TAG_CLASS;
  261. }
  262. else if (tag != -1)
  263. {
  264. /* No template tagging, get from arguments */
  265. ttag = tag;
  266. tclass = iclass & ASN1_TFLG_TAG_CLASS;
  267. }
  268. else
  269. {
  270. ttag = -1;
  271. tclass = 0;
  272. }
  273. /*
  274. * Remove any class mask from iflag.
  275. */
  276. iclass &= ~ASN1_TFLG_TAG_CLASS;
  277. /* At this point 'ttag' contains the outer tag to use,
  278. * 'tclass' is the class and iclass is any flags passed
  279. * to this function.
  280. */
  281. /* if template and arguments require ndef, use it */
  282. if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
  283. ndef = 2;
  284. else ndef = 1;
  285. if (flags & ASN1_TFLG_SK_MASK)
  286. {
  287. /* SET OF, SEQUENCE OF */
  288. STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
  289. int isset, sktag, skaclass;
  290. int skcontlen, sklen;
  291. ASN1_VALUE *skitem;
  292. if (!*pval)
  293. return 0;
  294. if (flags & ASN1_TFLG_SET_OF)
  295. {
  296. isset = 1;
  297. /* 2 means we reorder */
  298. if (flags & ASN1_TFLG_SEQUENCE_OF)
  299. isset = 2;
  300. }
  301. else isset = 0;
  302. /* Work out inner tag value: if EXPLICIT
  303. * or no tagging use underlying type.
  304. */
  305. if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
  306. {
  307. sktag = ttag;
  308. skaclass = tclass;
  309. }
  310. else
  311. {
  312. skaclass = V_ASN1_UNIVERSAL;
  313. if (isset)
  314. sktag = V_ASN1_SET;
  315. else sktag = V_ASN1_SEQUENCE;
  316. }
  317. /* Determine total length of items */
  318. skcontlen = 0;
  319. for (j = 0; j < sk_ASN1_VALUE_num(sk); j++)
  320. {
  321. skitem = sk_ASN1_VALUE_value(sk, j);
  322. skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
  323. ASN1_ITEM_ptr(tt->item),
  324. -1, iclass);
  325. }
  326. sklen = ASN1_object_size(ndef, skcontlen, sktag);
  327. /* If EXPLICIT need length of surrounding tag */
  328. if (flags & ASN1_TFLG_EXPTAG)
  329. ret = ASN1_object_size(ndef, sklen, ttag);
  330. else ret = sklen;
  331. if (!out)
  332. return ret;
  333. /* Now encode this lot... */
  334. /* EXPLICIT tag */
  335. if (flags & ASN1_TFLG_EXPTAG)
  336. ASN1_put_object(out, ndef, sklen, ttag, tclass);
  337. /* SET or SEQUENCE and IMPLICIT tag */
  338. ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
  339. /* And the stuff itself */
  340. asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
  341. isset, iclass);
  342. if (ndef == 2)
  343. {
  344. ASN1_put_eoc(out);
  345. if (flags & ASN1_TFLG_EXPTAG)
  346. ASN1_put_eoc(out);
  347. }
  348. return ret;
  349. }
  350. if (flags & ASN1_TFLG_EXPTAG)
  351. {
  352. /* EXPLICIT tagging */
  353. /* Find length of tagged item */
  354. i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
  355. -1, iclass);
  356. if (!i)
  357. return 0;
  358. /* Find length of EXPLICIT tag */
  359. ret = ASN1_object_size(ndef, i, ttag);
  360. if (out)
  361. {
  362. /* Output tag and item */
  363. ASN1_put_object(out, ndef, i, ttag, tclass);
  364. ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
  365. -1, iclass);
  366. if (ndef == 2)
  367. ASN1_put_eoc(out);
  368. }
  369. return ret;
  370. }
  371. /* Either normal or IMPLICIT tagging: combine class and flags */
  372. return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
  373. ttag, tclass | iclass);
  374. }
  375. /* Temporary structure used to hold DER encoding of items for SET OF */
  376. typedef struct {
  377. unsigned char *data;
  378. int length;
  379. ASN1_VALUE *field;
  380. } DER_ENC;
  381. static int der_cmp(const void *a, const void *b)
  382. {
  383. const DER_ENC *d1 = a, *d2 = b;
  384. int cmplen, i;
  385. cmplen = (d1->length < d2->length) ? d1->length : d2->length;
  386. i = memcmp(d1->data, d2->data, cmplen);
  387. if (i)
  388. return i;
  389. return d1->length - d2->length;
  390. }
  391. /* Output the content octets of SET OF or SEQUENCE OF */
  392. static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
  393. int skcontlen, const ASN1_ITEM *item,
  394. int do_sort, int iclass)
  395. {
  396. size_t i;
  397. ASN1_VALUE *skitem;
  398. unsigned char *tmpdat = NULL, *p = NULL;
  399. DER_ENC *derlst = NULL, *tder;
  400. if (do_sort)
  401. {
  402. /* Don't need to sort less than 2 items */
  403. if (sk_ASN1_VALUE_num(sk) < 2)
  404. do_sort = 0;
  405. else
  406. {
  407. derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
  408. * sizeof(*derlst));
  409. if (!derlst)
  410. return 0;
  411. tmpdat = OPENSSL_malloc(skcontlen);
  412. if (!tmpdat)
  413. {
  414. OPENSSL_free(derlst);
  415. return 0;
  416. }
  417. }
  418. }
  419. /* If not sorting just output each item */
  420. if (!do_sort)
  421. {
  422. for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
  423. {
  424. skitem = sk_ASN1_VALUE_value(sk, i);
  425. ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
  426. }
  427. return 1;
  428. }
  429. p = tmpdat;
  430. /* Doing sort: build up a list of each member's DER encoding */
  431. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
  432. {
  433. skitem = sk_ASN1_VALUE_value(sk, i);
  434. tder->data = p;
  435. tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
  436. tder->field = skitem;
  437. }
  438. /* Now sort them */
  439. qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
  440. /* Output sorted DER encoding */
  441. p = *out;
  442. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
  443. {
  444. memcpy(p, tder->data, tder->length);
  445. p += tder->length;
  446. }
  447. *out = p;
  448. /* If do_sort is 2 then reorder the STACK */
  449. if (do_sort == 2)
  450. {
  451. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
  452. i++, tder++)
  453. (void)sk_ASN1_VALUE_set(sk, i, tder->field);
  454. }
  455. OPENSSL_free(derlst);
  456. OPENSSL_free(tmpdat);
  457. return 1;
  458. }
  459. static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
  460. const ASN1_ITEM *it, int tag, int aclass)
  461. {
  462. int len;
  463. int utype;
  464. int usetag;
  465. int ndef = 0;
  466. utype = it->utype;
  467. /* Get length of content octets and maybe find
  468. * out the underlying type.
  469. */
  470. len = asn1_ex_i2c(pval, NULL, &utype, it);
  471. /* If SEQUENCE, SET or OTHER then header is
  472. * included in pseudo content octets so don't
  473. * include tag+length. We need to check here
  474. * because the call to asn1_ex_i2c() could change
  475. * utype.
  476. */
  477. if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
  478. (utype == V_ASN1_OTHER))
  479. usetag = 0;
  480. else usetag = 1;
  481. /* -1 means omit type */
  482. if (len == -1)
  483. return 0;
  484. /* -2 return is special meaning use ndef */
  485. if (len == -2)
  486. {
  487. ndef = 2;
  488. len = 0;
  489. }
  490. /* If not implicitly tagged get tag from underlying type */
  491. if (tag == -1) tag = utype;
  492. /* Output tag+length followed by content octets */
  493. if (out)
  494. {
  495. if (usetag)
  496. ASN1_put_object(out, ndef, len, tag, aclass);
  497. asn1_ex_i2c(pval, *out, &utype, it);
  498. if (ndef)
  499. ASN1_put_eoc(out);
  500. else
  501. *out += len;
  502. }
  503. if (usetag)
  504. return ASN1_object_size(ndef, len, tag);
  505. return len;
  506. }
  507. /* Produce content octets from a structure */
  508. int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
  509. const ASN1_ITEM *it)
  510. {
  511. ASN1_BOOLEAN *tbool = NULL;
  512. ASN1_STRING *strtmp;
  513. ASN1_OBJECT *otmp;
  514. int utype;
  515. const unsigned char *cont;
  516. unsigned char c;
  517. int len;
  518. const ASN1_PRIMITIVE_FUNCS *pf;
  519. pf = it->funcs;
  520. if (pf && pf->prim_i2c)
  521. return pf->prim_i2c(pval, cout, putype, it);
  522. /* Should type be omitted? */
  523. if ((it->itype != ASN1_ITYPE_PRIMITIVE)
  524. || (it->utype != V_ASN1_BOOLEAN))
  525. {
  526. if (!*pval) return -1;
  527. }
  528. if (it->itype == ASN1_ITYPE_MSTRING)
  529. {
  530. /* If MSTRING type set the underlying type */
  531. strtmp = (ASN1_STRING *)*pval;
  532. utype = strtmp->type;
  533. *putype = utype;
  534. }
  535. else if (it->utype == V_ASN1_ANY)
  536. {
  537. /* If ANY set type and pointer to value */
  538. ASN1_TYPE *typ;
  539. typ = (ASN1_TYPE *)*pval;
  540. utype = typ->type;
  541. *putype = utype;
  542. pval = &typ->value.asn1_value;
  543. }
  544. else utype = *putype;
  545. switch(utype)
  546. {
  547. case V_ASN1_OBJECT:
  548. otmp = (ASN1_OBJECT *)*pval;
  549. cont = otmp->data;
  550. len = otmp->length;
  551. break;
  552. case V_ASN1_NULL:
  553. cont = NULL;
  554. len = 0;
  555. break;
  556. case V_ASN1_BOOLEAN:
  557. tbool = (ASN1_BOOLEAN *)pval;
  558. if (*tbool == -1)
  559. return -1;
  560. if (it->utype != V_ASN1_ANY)
  561. {
  562. /* Default handling if value == size field then omit */
  563. if (*tbool && (it->size > 0))
  564. return -1;
  565. if (!*tbool && !it->size)
  566. return -1;
  567. }
  568. c = (unsigned char)*tbool;
  569. cont = &c;
  570. len = 1;
  571. break;
  572. case V_ASN1_BIT_STRING:
  573. return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
  574. cout ? &cout : NULL);
  575. break;
  576. case V_ASN1_INTEGER:
  577. case V_ASN1_NEG_INTEGER:
  578. case V_ASN1_ENUMERATED:
  579. case V_ASN1_NEG_ENUMERATED:
  580. /* These are all have the same content format
  581. * as ASN1_INTEGER
  582. */
  583. return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
  584. cout ? &cout : NULL);
  585. break;
  586. case V_ASN1_OCTET_STRING:
  587. case V_ASN1_NUMERICSTRING:
  588. case V_ASN1_PRINTABLESTRING:
  589. case V_ASN1_T61STRING:
  590. case V_ASN1_VIDEOTEXSTRING:
  591. case V_ASN1_IA5STRING:
  592. case V_ASN1_UTCTIME:
  593. case V_ASN1_GENERALIZEDTIME:
  594. case V_ASN1_GRAPHICSTRING:
  595. case V_ASN1_VISIBLESTRING:
  596. case V_ASN1_GENERALSTRING:
  597. case V_ASN1_UNIVERSALSTRING:
  598. case V_ASN1_BMPSTRING:
  599. case V_ASN1_UTF8STRING:
  600. case V_ASN1_SEQUENCE:
  601. case V_ASN1_SET:
  602. default:
  603. /* All based on ASN1_STRING and handled the same */
  604. strtmp = (ASN1_STRING *)*pval;
  605. /* Special handling for NDEF */
  606. if ((it->size == ASN1_TFLG_NDEF)
  607. && (strtmp->flags & ASN1_STRING_FLAG_NDEF))
  608. {
  609. if (cout)
  610. {
  611. strtmp->data = cout;
  612. strtmp->length = 0;
  613. }
  614. /* Special return code */
  615. return -2;
  616. }
  617. cont = strtmp->data;
  618. len = strtmp->length;
  619. break;
  620. }
  621. if (cout && len)
  622. memcpy(cout, cont, len);
  623. return len;
  624. }