Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

665 lignes
21 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 <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. static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
  232. const ASN1_TEMPLATE *tt, int tag, int iclass)
  233. {
  234. int i, ret, flags, ttag, tclass, ndef;
  235. size_t j;
  236. flags = tt->flags;
  237. /*
  238. * Work out tag and class to use: tagging may come either from the
  239. * template or the arguments, not both because this would create
  240. * ambiguity. Additionally the iclass argument may contain some
  241. * additional flags which should be noted and passed down to other
  242. * levels.
  243. */
  244. if (flags & ASN1_TFLG_TAG_MASK) {
  245. /* Error if argument and template tagging */
  246. if (tag != -1)
  247. /* FIXME: error code here */
  248. return -1;
  249. /* Get tagging from template */
  250. ttag = tt->tag;
  251. tclass = flags & ASN1_TFLG_TAG_CLASS;
  252. } else if (tag != -1) {
  253. /* No template tagging, get from arguments */
  254. ttag = tag;
  255. tclass = iclass & ASN1_TFLG_TAG_CLASS;
  256. } else {
  257. ttag = -1;
  258. tclass = 0;
  259. }
  260. /*
  261. * Remove any class mask from iflag.
  262. */
  263. iclass &= ~ASN1_TFLG_TAG_CLASS;
  264. /*
  265. * At this point 'ttag' contains the outer tag to use, 'tclass' is the
  266. * class and iclass is any flags passed to this function.
  267. */
  268. /* if template and arguments require ndef, use it */
  269. if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
  270. ndef = 2;
  271. else
  272. ndef = 1;
  273. if (flags & ASN1_TFLG_SK_MASK) {
  274. /* SET OF, SEQUENCE OF */
  275. STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
  276. int isset, sktag, skaclass;
  277. int skcontlen, sklen;
  278. ASN1_VALUE *skitem;
  279. if (!*pval)
  280. return 0;
  281. if (flags & ASN1_TFLG_SET_OF) {
  282. isset = 1;
  283. /* 2 means we reorder */
  284. if (flags & ASN1_TFLG_SEQUENCE_OF)
  285. isset = 2;
  286. } else
  287. isset = 0;
  288. /*
  289. * Work out inner tag value: if EXPLICIT or no tagging use underlying
  290. * type.
  291. */
  292. if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
  293. sktag = ttag;
  294. skaclass = tclass;
  295. } else {
  296. skaclass = V_ASN1_UNIVERSAL;
  297. if (isset)
  298. sktag = V_ASN1_SET;
  299. else
  300. sktag = V_ASN1_SEQUENCE;
  301. }
  302. /* Determine total length of items */
  303. skcontlen = 0;
  304. for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
  305. int tmplen;
  306. skitem = sk_ASN1_VALUE_value(sk, j);
  307. tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
  308. -1, iclass);
  309. if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
  310. return -1;
  311. skcontlen += tmplen;
  312. }
  313. sklen = ASN1_object_size(ndef, skcontlen, sktag);
  314. if (sklen == -1)
  315. return -1;
  316. /* If EXPLICIT need length of surrounding tag */
  317. if (flags & ASN1_TFLG_EXPTAG)
  318. ret = ASN1_object_size(ndef, sklen, ttag);
  319. else
  320. ret = sklen;
  321. if (!out || ret == -1)
  322. return ret;
  323. /* Now encode this lot... */
  324. /* EXPLICIT tag */
  325. if (flags & ASN1_TFLG_EXPTAG)
  326. ASN1_put_object(out, ndef, sklen, ttag, tclass);
  327. /* SET or SEQUENCE and IMPLICIT tag */
  328. ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
  329. /* And the stuff itself */
  330. asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
  331. isset, iclass);
  332. if (ndef == 2) {
  333. ASN1_put_eoc(out);
  334. if (flags & ASN1_TFLG_EXPTAG)
  335. ASN1_put_eoc(out);
  336. }
  337. return ret;
  338. }
  339. if (flags & ASN1_TFLG_EXPTAG) {
  340. /* EXPLICIT tagging */
  341. /* Find length of tagged item */
  342. i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
  343. if (!i)
  344. return 0;
  345. /* Find length of EXPLICIT tag */
  346. ret = ASN1_object_size(ndef, i, ttag);
  347. if (out && ret != -1) {
  348. /* Output tag and item */
  349. ASN1_put_object(out, ndef, i, ttag, tclass);
  350. ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
  351. if (ndef == 2)
  352. ASN1_put_eoc(out);
  353. }
  354. return ret;
  355. }
  356. /* Either normal or IMPLICIT tagging: combine class and flags */
  357. return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
  358. ttag, tclass | iclass);
  359. }
  360. /* Temporary structure used to hold DER encoding of items for SET OF */
  361. typedef struct {
  362. unsigned char *data;
  363. int length;
  364. ASN1_VALUE *field;
  365. } DER_ENC;
  366. static int der_cmp(const void *a, const void *b)
  367. {
  368. const DER_ENC *d1 = a, *d2 = b;
  369. int cmplen, i;
  370. cmplen = (d1->length < d2->length) ? d1->length : d2->length;
  371. i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
  372. if (i)
  373. return i;
  374. return d1->length - d2->length;
  375. }
  376. /* Output the content octets of SET OF or SEQUENCE OF */
  377. static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
  378. int skcontlen, const ASN1_ITEM *item,
  379. int do_sort, int iclass)
  380. {
  381. size_t i;
  382. ASN1_VALUE *skitem;
  383. unsigned char *tmpdat = NULL, *p = NULL;
  384. DER_ENC *derlst = NULL, *tder;
  385. if (do_sort) {
  386. /* Don't need to sort less than 2 items */
  387. if (sk_ASN1_VALUE_num(sk) < 2)
  388. do_sort = 0;
  389. else {
  390. derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
  391. * sizeof(*derlst));
  392. if (!derlst)
  393. return 0;
  394. tmpdat = OPENSSL_malloc(skcontlen);
  395. if (!tmpdat) {
  396. OPENSSL_free(derlst);
  397. return 0;
  398. }
  399. }
  400. }
  401. /* If not sorting just output each item */
  402. if (!do_sort) {
  403. for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
  404. skitem = sk_ASN1_VALUE_value(sk, i);
  405. ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
  406. }
  407. return 1;
  408. }
  409. p = tmpdat;
  410. /* Doing sort: build up a list of each member's DER encoding */
  411. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
  412. skitem = sk_ASN1_VALUE_value(sk, i);
  413. tder->data = p;
  414. tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
  415. tder->field = skitem;
  416. }
  417. /* Now sort them */
  418. qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
  419. /* Output sorted DER encoding */
  420. p = *out;
  421. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
  422. OPENSSL_memcpy(p, tder->data, tder->length);
  423. p += tder->length;
  424. }
  425. *out = p;
  426. /* If do_sort is 2 then reorder the STACK */
  427. if (do_sort == 2) {
  428. for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
  429. (void)sk_ASN1_VALUE_set(sk, i, tder->field);
  430. }
  431. OPENSSL_free(derlst);
  432. OPENSSL_free(tmpdat);
  433. return 1;
  434. }
  435. static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
  436. const ASN1_ITEM *it, int tag, int aclass)
  437. {
  438. int len;
  439. int utype;
  440. int usetag;
  441. int ndef = 0;
  442. utype = it->utype;
  443. /*
  444. * Get length of content octets and maybe find out the underlying type.
  445. */
  446. len = asn1_ex_i2c(pval, NULL, &utype, it);
  447. /*
  448. * If SEQUENCE, SET or OTHER then header is included in pseudo content
  449. * octets so don't include tag+length. We need to check here because the
  450. * call to asn1_ex_i2c() could change utype.
  451. */
  452. if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
  453. (utype == V_ASN1_OTHER))
  454. usetag = 0;
  455. else
  456. usetag = 1;
  457. /* -1 means omit type */
  458. if (len == -1)
  459. return 0;
  460. /* -2 return is special meaning use ndef */
  461. if (len == -2) {
  462. ndef = 2;
  463. len = 0;
  464. }
  465. /* If not implicitly tagged get tag from underlying type */
  466. if (tag == -1)
  467. tag = utype;
  468. /* Output tag+length followed by content octets */
  469. if (out) {
  470. if (usetag)
  471. ASN1_put_object(out, ndef, len, tag, aclass);
  472. asn1_ex_i2c(pval, *out, &utype, it);
  473. if (ndef)
  474. ASN1_put_eoc(out);
  475. else
  476. *out += len;
  477. }
  478. if (usetag)
  479. return ASN1_object_size(ndef, len, tag);
  480. return len;
  481. }
  482. /* Produce content octets from a structure */
  483. int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
  484. const ASN1_ITEM *it)
  485. {
  486. ASN1_BOOLEAN *tbool = NULL;
  487. ASN1_STRING *strtmp;
  488. ASN1_OBJECT *otmp;
  489. int utype;
  490. const unsigned char *cont;
  491. unsigned char c;
  492. int len;
  493. const ASN1_PRIMITIVE_FUNCS *pf;
  494. pf = it->funcs;
  495. if (pf && pf->prim_i2c)
  496. return pf->prim_i2c(pval, cout, putype, it);
  497. /* Should type be omitted? */
  498. if ((it->itype != ASN1_ITYPE_PRIMITIVE)
  499. || (it->utype != V_ASN1_BOOLEAN)) {
  500. if (!*pval)
  501. return -1;
  502. }
  503. if (it->itype == ASN1_ITYPE_MSTRING) {
  504. /* If MSTRING type set the underlying type */
  505. strtmp = (ASN1_STRING *)*pval;
  506. utype = strtmp->type;
  507. *putype = utype;
  508. } else if (it->utype == V_ASN1_ANY) {
  509. /* If ANY set type and pointer to value */
  510. ASN1_TYPE *typ;
  511. typ = (ASN1_TYPE *)*pval;
  512. utype = typ->type;
  513. *putype = utype;
  514. pval = &typ->value.asn1_value;
  515. } else
  516. utype = *putype;
  517. switch (utype) {
  518. case V_ASN1_OBJECT:
  519. otmp = (ASN1_OBJECT *)*pval;
  520. cont = otmp->data;
  521. len = otmp->length;
  522. if (cont == NULL || len == 0)
  523. return -1;
  524. break;
  525. case V_ASN1_NULL:
  526. cont = NULL;
  527. len = 0;
  528. break;
  529. case V_ASN1_BOOLEAN:
  530. tbool = (ASN1_BOOLEAN *)pval;
  531. if (*tbool == -1)
  532. return -1;
  533. if (it->utype != V_ASN1_ANY) {
  534. /*
  535. * Default handling if value == size field then omit
  536. */
  537. if (*tbool && (it->size > 0))
  538. return -1;
  539. if (!*tbool && !it->size)
  540. return -1;
  541. }
  542. c = (unsigned char)*tbool;
  543. cont = &c;
  544. len = 1;
  545. break;
  546. case V_ASN1_BIT_STRING:
  547. return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
  548. cout ? &cout : NULL);
  549. break;
  550. case V_ASN1_INTEGER:
  551. case V_ASN1_ENUMERATED:
  552. /*
  553. * These are all have the same content format as ASN1_INTEGER
  554. */
  555. return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
  556. break;
  557. case V_ASN1_OCTET_STRING:
  558. case V_ASN1_NUMERICSTRING:
  559. case V_ASN1_PRINTABLESTRING:
  560. case V_ASN1_T61STRING:
  561. case V_ASN1_VIDEOTEXSTRING:
  562. case V_ASN1_IA5STRING:
  563. case V_ASN1_UTCTIME:
  564. case V_ASN1_GENERALIZEDTIME:
  565. case V_ASN1_GRAPHICSTRING:
  566. case V_ASN1_VISIBLESTRING:
  567. case V_ASN1_GENERALSTRING:
  568. case V_ASN1_UNIVERSALSTRING:
  569. case V_ASN1_BMPSTRING:
  570. case V_ASN1_UTF8STRING:
  571. case V_ASN1_SEQUENCE:
  572. case V_ASN1_SET:
  573. default:
  574. /* All based on ASN1_STRING and handled the same */
  575. strtmp = (ASN1_STRING *)*pval;
  576. /* Special handling for NDEF */
  577. if ((it->size == ASN1_TFLG_NDEF)
  578. && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
  579. if (cout) {
  580. strtmp->data = cout;
  581. strtmp->length = 0;
  582. }
  583. /* Special return code */
  584. return -2;
  585. }
  586. cont = strtmp->data;
  587. len = strtmp->length;
  588. break;
  589. }
  590. if (cout && len)
  591. OPENSSL_memcpy(cout, cont, len);
  592. return len;
  593. }