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ů.
 
 
 
 
 
 

694 řádky
18 KiB

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