NativeInteger.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /*-
  2. * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
  3. * All rights reserved.
  4. * Redistribution and modifications are permitted subject to BSD license.
  5. */
  6. /*
  7. * Read the NativeInteger.h for the explanation wrt. differences between
  8. * INTEGER and NativeInteger.
  9. * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
  10. * implementation deals with the standard (machine-specific) representation
  11. * of them instead of using the platform-independent buffer.
  12. */
  13. #include <asn_internal.h>
  14. #include <NativeInteger.h>
  15. /*
  16. * NativeInteger basic type description.
  17. */
  18. static const ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
  19. (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
  20. };
  21. asn_TYPE_operation_t asn_OP_NativeInteger = {
  22. NativeInteger_free,
  23. NativeInteger_print,
  24. NativeInteger_compare,
  25. NativeInteger_decode_ber,
  26. NativeInteger_encode_der,
  27. NativeInteger_decode_xer,
  28. NativeInteger_encode_xer,
  29. #ifdef ASN_DISABLE_OER_SUPPORT
  30. 0,
  31. 0,
  32. #else
  33. NativeInteger_decode_oer, /* OER decoder */
  34. NativeInteger_encode_oer, /* Canonical OER encoder */
  35. #endif /* ASN_DISABLE_OER_SUPPORT */
  36. #ifdef ASN_DISABLE_PER_SUPPORT
  37. 0,
  38. 0,
  39. #else
  40. NativeInteger_decode_uper, /* Unaligned PER decoder */
  41. NativeInteger_encode_uper, /* Unaligned PER encoder */
  42. #endif /* ASN_DISABLE_PER_SUPPORT */
  43. NativeInteger_random_fill,
  44. 0 /* Use generic outmost tag fetcher */
  45. };
  46. asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
  47. "INTEGER", /* The ASN.1 type is still INTEGER */
  48. "INTEGER",
  49. &asn_OP_NativeInteger,
  50. asn_DEF_NativeInteger_tags,
  51. sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
  52. asn_DEF_NativeInteger_tags, /* Same as above */
  53. sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
  54. { 0, 0, asn_generic_no_constraint },
  55. 0, 0, /* No members */
  56. 0 /* No specifics */
  57. };
  58. /*
  59. * Decode INTEGER type.
  60. */
  61. asn_dec_rval_t
  62. NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
  63. const asn_TYPE_descriptor_t *td, void **nint_ptr,
  64. const void *buf_ptr, size_t size, int tag_mode) {
  65. const asn_INTEGER_specifics_t *specs =
  66. (const asn_INTEGER_specifics_t *)td->specifics;
  67. long *native = (long *)*nint_ptr;
  68. asn_dec_rval_t rval;
  69. ber_tlv_len_t length;
  70. /*
  71. * If the structure is not there, allocate it.
  72. */
  73. if(native == NULL) {
  74. native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
  75. if(native == NULL) {
  76. rval.code = RC_FAIL;
  77. rval.consumed = 0;
  78. return rval;
  79. }
  80. }
  81. ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
  82. td->name, tag_mode);
  83. /*
  84. * Check tags.
  85. */
  86. rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
  87. tag_mode, 0, &length, 0);
  88. if(rval.code != RC_OK)
  89. return rval;
  90. ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
  91. /*
  92. * Make sure we have this length.
  93. */
  94. buf_ptr = ((const char *)buf_ptr) + rval.consumed;
  95. size -= rval.consumed;
  96. if(length > (ber_tlv_len_t)size) {
  97. rval.code = RC_WMORE;
  98. rval.consumed = 0;
  99. return rval;
  100. }
  101. /*
  102. * ASN.1 encoded INTEGER: buf_ptr, length
  103. * Fill the native, at the same time checking for overflow.
  104. * If overflow occurred, return with RC_FAIL.
  105. */
  106. {
  107. INTEGER_t tmp;
  108. union {
  109. const void *constbuf;
  110. void *nonconstbuf;
  111. } unconst_buf;
  112. long l;
  113. unconst_buf.constbuf = buf_ptr;
  114. tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
  115. tmp.size = length;
  116. if((specs&&specs->field_unsigned)
  117. ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
  118. : asn_INTEGER2long(&tmp, &l)) {
  119. rval.code = RC_FAIL;
  120. rval.consumed = 0;
  121. return rval;
  122. }
  123. *native = l;
  124. }
  125. rval.code = RC_OK;
  126. rval.consumed += length;
  127. ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
  128. (long)rval.consumed, (long)length, td->name, (long)*native);
  129. return rval;
  130. }
  131. /*
  132. * Encode the NativeInteger using the standard INTEGER type DER encoder.
  133. */
  134. asn_enc_rval_t
  135. NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr,
  136. int tag_mode, ber_tlv_tag_t tag,
  137. asn_app_consume_bytes_f *cb, void *app_key) {
  138. unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */
  139. asn_enc_rval_t erval;
  140. INTEGER_t tmp;
  141. #ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
  142. tmp.buf = (uint8_t *)&native;
  143. tmp.size = sizeof(native);
  144. #else /* Works even if WORDS_BIGENDIAN is not set where should've been */
  145. uint8_t buf[sizeof(native)];
  146. uint8_t *p;
  147. /* Prepare a fake INTEGER */
  148. for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
  149. *p = (uint8_t)native;
  150. tmp.buf = buf;
  151. tmp.size = sizeof(buf);
  152. #endif /* WORDS_BIGENDIAN */
  153. /* Encode fake INTEGER */
  154. erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
  155. if(erval.structure_ptr == &tmp) {
  156. erval.structure_ptr = ptr;
  157. }
  158. return erval;
  159. }
  160. /*
  161. * Decode the chunk of XML text encoding INTEGER.
  162. */
  163. asn_dec_rval_t
  164. NativeInteger_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
  165. const asn_TYPE_descriptor_t *td, void **sptr,
  166. const char *opt_mname, const void *buf_ptr,
  167. size_t size) {
  168. const asn_INTEGER_specifics_t *specs =
  169. (const asn_INTEGER_specifics_t *)td->specifics;
  170. asn_dec_rval_t rval;
  171. INTEGER_t st;
  172. void *st_ptr = (void *)&st;
  173. long *native = (long *)*sptr;
  174. if(!native) {
  175. native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
  176. if(!native) ASN__DECODE_FAILED;
  177. }
  178. memset(&st, 0, sizeof(st));
  179. rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
  180. opt_mname, buf_ptr, size);
  181. if(rval.code == RC_OK) {
  182. long l;
  183. if((specs&&specs->field_unsigned)
  184. ? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
  185. : asn_INTEGER2long(&st, &l)) {
  186. rval.code = RC_FAIL;
  187. rval.consumed = 0;
  188. } else {
  189. *native = l;
  190. }
  191. } else {
  192. /*
  193. * Cannot restart from the middle;
  194. * there is no place to save state in the native type.
  195. * Request a continuation from the very beginning.
  196. */
  197. rval.consumed = 0;
  198. }
  199. ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
  200. return rval;
  201. }
  202. asn_enc_rval_t
  203. NativeInteger_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
  204. int ilevel, enum xer_encoder_flags_e flags,
  205. asn_app_consume_bytes_f *cb, void *app_key) {
  206. const asn_INTEGER_specifics_t *specs =
  207. (const asn_INTEGER_specifics_t *)td->specifics;
  208. char scratch[32]; /* Enough for 64-bit int */
  209. asn_enc_rval_t er;
  210. const long *native = (const long *)sptr;
  211. (void)ilevel;
  212. (void)flags;
  213. if(!native) ASN__ENCODE_FAILED;
  214. er.encoded = snprintf(scratch, sizeof(scratch),
  215. (specs && specs->field_unsigned)
  216. ? "%lu" : "%ld", *native);
  217. if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
  218. || cb(scratch, er.encoded, app_key) < 0)
  219. ASN__ENCODE_FAILED;
  220. ASN__ENCODED_OK(er);
  221. }
  222. #ifndef ASN_DISABLE_PER_SUPPORT
  223. asn_dec_rval_t
  224. NativeInteger_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
  225. const asn_TYPE_descriptor_t *td,
  226. const asn_per_constraints_t *constraints, void **sptr,
  227. asn_per_data_t *pd) {
  228. const asn_INTEGER_specifics_t *specs =
  229. (const asn_INTEGER_specifics_t *)td->specifics;
  230. asn_dec_rval_t rval;
  231. long *native = (long *)*sptr;
  232. INTEGER_t tmpint;
  233. void *tmpintptr = &tmpint;
  234. (void)opt_codec_ctx;
  235. ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
  236. if(!native) {
  237. native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
  238. if(!native) ASN__DECODE_FAILED;
  239. }
  240. memset(&tmpint, 0, sizeof tmpint);
  241. rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
  242. &tmpintptr, pd);
  243. if(rval.code == RC_OK) {
  244. if((specs&&specs->field_unsigned)
  245. ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
  246. : asn_INTEGER2long(&tmpint, native))
  247. rval.code = RC_FAIL;
  248. else
  249. ASN_DEBUG("NativeInteger %s got value %ld",
  250. td->name, *native);
  251. }
  252. ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
  253. return rval;
  254. }
  255. asn_enc_rval_t
  256. NativeInteger_encode_uper(const asn_TYPE_descriptor_t *td,
  257. const asn_per_constraints_t *constraints,
  258. const void *sptr, asn_per_outp_t *po) {
  259. const asn_INTEGER_specifics_t *specs =
  260. (const asn_INTEGER_specifics_t *)td->specifics;
  261. asn_enc_rval_t er;
  262. long native;
  263. INTEGER_t tmpint;
  264. if(!sptr) ASN__ENCODE_FAILED;
  265. native = *(const long *)sptr;
  266. ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
  267. memset(&tmpint, 0, sizeof(tmpint));
  268. if((specs&&specs->field_unsigned)
  269. ? asn_ulong2INTEGER(&tmpint, native)
  270. : asn_long2INTEGER(&tmpint, native))
  271. ASN__ENCODE_FAILED;
  272. er = INTEGER_encode_uper(td, constraints, &tmpint, po);
  273. ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
  274. return er;
  275. }
  276. #endif /* ASN_DISABLE_PER_SUPPORT */
  277. /*
  278. * INTEGER specific human-readable output.
  279. */
  280. int
  281. NativeInteger_print(const asn_TYPE_descriptor_t *td, const void *sptr,
  282. int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
  283. const asn_INTEGER_specifics_t *specs =
  284. (const asn_INTEGER_specifics_t *)td->specifics;
  285. const long *native = (const long *)sptr;
  286. char scratch[32]; /* Enough for 64-bit int */
  287. int ret;
  288. (void)td; /* Unused argument */
  289. (void)ilevel; /* Unused argument */
  290. if(native) {
  291. long value = *native;
  292. ret = snprintf(scratch, sizeof(scratch),
  293. (specs && specs->field_unsigned) ? "%lu" : "%ld", value);
  294. assert(ret > 0 && (size_t)ret < sizeof(scratch));
  295. if(cb(scratch, ret, app_key) < 0) return -1;
  296. if(specs && (value >= 0 || !specs->field_unsigned)) {
  297. const asn_INTEGER_enum_map_t *el =
  298. INTEGER_map_value2enum(specs, value);
  299. if(el) {
  300. if(cb(" (", 2, app_key) < 0) return -1;
  301. if(cb(el->enum_name, el->enum_len, app_key) < 0) return -1;
  302. if(cb(")", 1, app_key) < 0) return -1;
  303. }
  304. }
  305. return 0;
  306. } else {
  307. return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
  308. }
  309. }
  310. void
  311. NativeInteger_free(const asn_TYPE_descriptor_t *td, void *ptr,
  312. enum asn_struct_free_method method) {
  313. if(!td || !ptr)
  314. return;
  315. ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
  316. td->name, method, ptr);
  317. switch(method) {
  318. case ASFM_FREE_EVERYTHING:
  319. FREEMEM(ptr);
  320. break;
  321. case ASFM_FREE_UNDERLYING:
  322. break;
  323. case ASFM_FREE_UNDERLYING_AND_RESET:
  324. memset(ptr, 0, sizeof(long));
  325. break;
  326. }
  327. }
  328. int
  329. NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) {
  330. (void)td;
  331. if(aptr && bptr) {
  332. const asn_INTEGER_specifics_t *specs =
  333. (const asn_INTEGER_specifics_t *)td->specifics;
  334. if(specs && specs->field_unsigned) {
  335. const unsigned long *a = aptr;
  336. const unsigned long *b = bptr;
  337. if(*a < *b) {
  338. return -1;
  339. } else if(*a > *b) {
  340. return 1;
  341. } else {
  342. return 0;
  343. }
  344. } else {
  345. const long *a = aptr;
  346. const long *b = bptr;
  347. if(*a < *b) {
  348. return -1;
  349. } else if(*a > *b) {
  350. return 1;
  351. } else {
  352. return 0;
  353. }
  354. }
  355. } else if(!aptr) {
  356. return -1;
  357. } else {
  358. return 1;
  359. }
  360. }
  361. asn_random_fill_result_t
  362. NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
  363. const asn_encoding_constraints_t *constraints,
  364. size_t max_length) {
  365. const asn_INTEGER_specifics_t *specs =
  366. (const asn_INTEGER_specifics_t *)td->specifics;
  367. asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
  368. asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
  369. asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
  370. long *st = *sptr;
  371. const asn_INTEGER_enum_map_t *emap;
  372. size_t emap_len;
  373. intmax_t value;
  374. int find_inside_map;
  375. if(max_length == 0) return result_skipped;
  376. if(st == NULL) {
  377. st = (long *)CALLOC(1, sizeof(*st));
  378. if(st == NULL) {
  379. return result_failed;
  380. }
  381. }
  382. if(specs) {
  383. emap = specs->value2enum;
  384. emap_len = specs->map_count;
  385. if(specs->strict_enumeration) {
  386. find_inside_map = emap_len > 0;
  387. } else {
  388. find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
  389. }
  390. } else {
  391. emap = 0;
  392. emap_len = 0;
  393. find_inside_map = 0;
  394. }
  395. if(find_inside_map) {
  396. assert(emap_len > 0);
  397. value = emap[asn_random_between(0, emap_len - 1)].nat_value;
  398. } else {
  399. const asn_per_constraints_t *ct;
  400. static const long variants[] = {
  401. -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
  402. -16383, -257, -256, -255, -254, -129, -128, -127,
  403. -126, -1, 0, 1, 126, 127, 128, 129,
  404. 254, 255, 256, 257, 16383, 16384, 16385, 32767,
  405. 32768, 32769, 65534, 65535, 65536, 65537};
  406. if(specs && specs->field_unsigned) {
  407. assert(variants[18] == 0);
  408. value = variants[asn_random_between(
  409. 18, sizeof(variants) / sizeof(variants[0]) - 1)];
  410. } else {
  411. value = variants[asn_random_between(
  412. 0, sizeof(variants) / sizeof(variants[0]) - 1)];
  413. }
  414. if(!constraints) constraints = &td->encoding_constraints;
  415. ct = constraints ? constraints->per_constraints : 0;
  416. if(ct && (ct->value.flags & APC_CONSTRAINED)) {
  417. if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
  418. value = asn_random_between(ct->value.lower_bound,
  419. ct->value.upper_bound);
  420. }
  421. }
  422. }
  423. *sptr = st;
  424. *st = value;
  425. return result_ok;
  426. }