tasn_enc.c 21 KB

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