asn_application.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
  3. * Redistribution and modifications are permitted subject to BSD license.
  4. */
  5. #include <asn_internal.h>
  6. #include <asn_application.h>
  7. #include <errno.h>
  8. static asn_enc_rval_t asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
  9. enum asn_transfer_syntax syntax,
  10. const asn_TYPE_descriptor_t *td,
  11. const void *sptr,
  12. asn_app_consume_bytes_f *callback,
  13. void *callback_key);
  14. struct callback_count_bytes_key {
  15. asn_app_consume_bytes_f *callback;
  16. void *callback_key;
  17. size_t computed_size;
  18. };
  19. /*
  20. * Encoder which just counts bytes that come through it.
  21. */
  22. static int
  23. callback_count_bytes_cb(const void *data, size_t size, void *keyp) {
  24. struct callback_count_bytes_key *key = keyp;
  25. int ret;
  26. ret = key->callback(data, size, key->callback_key);
  27. if(ret >= 0) {
  28. key->computed_size += size;
  29. }
  30. return ret;
  31. }
  32. struct overrun_encoder_key {
  33. void *buffer;
  34. size_t buffer_size;
  35. size_t computed_size;
  36. };
  37. struct dynamic_encoder_key {
  38. void *buffer;
  39. size_t buffer_size;
  40. size_t computed_size;
  41. };
  42. struct callback_failure_catch_key {
  43. asn_app_consume_bytes_f *callback;
  44. void *callback_key;
  45. int callback_failed;
  46. };
  47. /*
  48. * Encoder which doesn't stop counting bytes
  49. * even if it reaches the end of the buffer.
  50. */
  51. static int
  52. overrun_encoder_cb(const void *data, size_t size, void *keyp) {
  53. struct overrun_encoder_key *key = keyp;
  54. if(key->computed_size + size > key->buffer_size) {
  55. /*
  56. * Avoid accident on the next call:
  57. * stop adding bytes to the buffer.
  58. */
  59. key->buffer_size = 0;
  60. } else {
  61. memcpy((char *)key->buffer + key->computed_size, data, size);
  62. }
  63. key->computed_size += size;
  64. return 0;
  65. }
  66. /*
  67. * Encoder which dynamically allocates output, and continues
  68. * to count even if allocation failed.
  69. */
  70. static int
  71. dynamic_encoder_cb(const void *data, size_t size, void *keyp) {
  72. struct dynamic_encoder_key *key = keyp;
  73. if(key->buffer) {
  74. if(key->computed_size + size >= key->buffer_size) {
  75. void *p;
  76. size_t new_size = key->buffer_size;
  77. do {
  78. new_size *= 2;
  79. } while(new_size <= key->computed_size + size);
  80. p = REALLOC(key->buffer, new_size);
  81. if(p) {
  82. key->buffer = p;
  83. key->buffer_size = new_size;
  84. } else {
  85. FREEMEM(key->buffer);
  86. key->buffer = 0;
  87. key->buffer_size = 0;
  88. key->computed_size += size;
  89. return 0;
  90. }
  91. }
  92. memcpy((char *)key->buffer + key->computed_size, data, size);
  93. }
  94. key->computed_size += size;
  95. return 0;
  96. }
  97. /*
  98. * Encoder which help convert the application level encoder failure into EIO.
  99. */
  100. static int
  101. callback_failure_catch_cb(const void *data, size_t size, void *keyp) {
  102. struct callback_failure_catch_key *key = keyp;
  103. int ret;
  104. ret = key->callback(data, size, key->callback_key);
  105. if(ret < 0) {
  106. key->callback_failed = 1;
  107. }
  108. return ret;
  109. }
  110. asn_enc_rval_t
  111. asn_encode(const asn_codec_ctx_t *opt_codec_ctx,
  112. enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,
  113. const void *sptr, asn_app_consume_bytes_f *callback, void *callback_key) {
  114. struct callback_failure_catch_key cb_key;
  115. asn_enc_rval_t er;
  116. if(!callback) {
  117. errno = EINVAL;
  118. ASN__ENCODE_FAILED;
  119. }
  120. cb_key.callback = callback;
  121. cb_key.callback_key = callback_key;
  122. cb_key.callback_failed = 0;
  123. er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
  124. callback_failure_catch_cb, &cb_key);
  125. if(cb_key.callback_failed) {
  126. assert(er.encoded == -1);
  127. assert(errno == EBADF);
  128. errno = EIO;
  129. }
  130. return er;
  131. }
  132. asn_enc_rval_t
  133. asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx,
  134. enum asn_transfer_syntax syntax,
  135. const asn_TYPE_descriptor_t *td, const void *sptr,
  136. void *buffer, size_t buffer_size) {
  137. struct overrun_encoder_key buf_key;
  138. asn_enc_rval_t er;
  139. if(buffer_size > 0 && !buffer) {
  140. errno = EINVAL;
  141. ASN__ENCODE_FAILED;
  142. }
  143. buf_key.buffer = buffer;
  144. buf_key.buffer_size = buffer_size;
  145. buf_key.computed_size = 0;
  146. er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
  147. overrun_encoder_cb, &buf_key);
  148. if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) {
  149. ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
  150. " yet produced %" ASN_PRI_SIZE " bytes",
  151. er.encoded, buf_key.computed_size);
  152. assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size);
  153. }
  154. return er;
  155. }
  156. asn_encode_to_new_buffer_result_t
  157. asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx,
  158. enum asn_transfer_syntax syntax,
  159. const asn_TYPE_descriptor_t *td, const void *sptr) {
  160. struct dynamic_encoder_key buf_key;
  161. asn_encode_to_new_buffer_result_t res;
  162. buf_key.buffer_size = 16;
  163. buf_key.buffer = MALLOC(buf_key.buffer_size);
  164. buf_key.computed_size = 0;
  165. res.result = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
  166. dynamic_encoder_cb, &buf_key);
  167. if(res.result.encoded >= 0
  168. && (size_t)res.result.encoded != buf_key.computed_size) {
  169. ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
  170. " yet produced %" ASN_PRI_SIZE " bytes",
  171. res.result.encoded, buf_key.computed_size);
  172. assert(res.result.encoded < 0
  173. || (size_t)res.result.encoded == buf_key.computed_size);
  174. }
  175. res.buffer = buf_key.buffer;
  176. /* 0-terminate just in case. */
  177. if(res.buffer) {
  178. assert(buf_key.computed_size < buf_key.buffer_size);
  179. ((char *)res.buffer)[buf_key.computed_size] = '\0';
  180. }
  181. return res;
  182. }
  183. static asn_enc_rval_t
  184. asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
  185. enum asn_transfer_syntax syntax,
  186. const asn_TYPE_descriptor_t *td, const void *sptr,
  187. asn_app_consume_bytes_f *callback, void *callback_key) {
  188. asn_enc_rval_t er;
  189. enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL;
  190. (void)opt_codec_ctx; /* Parameters are not checked on encode yet. */
  191. if(!td || !sptr) {
  192. errno = EINVAL;
  193. ASN__ENCODE_FAILED;
  194. }
  195. switch(syntax) {
  196. case ATS_NONSTANDARD_PLAINTEXT:
  197. if(td->op->print_struct) {
  198. struct callback_count_bytes_key cb_key;
  199. cb_key.callback = callback;
  200. cb_key.callback_key = callback_key;
  201. cb_key.computed_size = 0;
  202. if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb,
  203. &cb_key)
  204. < 0
  205. || callback_count_bytes_cb("\n", 1, &cb_key) < 0) {
  206. errno = EBADF; /* Structure has incorrect form. */
  207. er.encoded = -1;
  208. er.failed_type = td;
  209. er.structure_ptr = sptr;
  210. } else {
  211. er.encoded = cb_key.computed_size;
  212. er.failed_type = 0;
  213. er.structure_ptr = 0;
  214. }
  215. } else {
  216. errno = ENOENT; /* Transfer syntax is not defined for this type. */
  217. ASN__ENCODE_FAILED;
  218. }
  219. break;
  220. case ATS_RANDOM:
  221. errno = ENOENT; /* Randomization doesn't make sense on output. */
  222. ASN__ENCODE_FAILED;
  223. case ATS_BER:
  224. /* BER is a superset of DER. */
  225. /* Fall through. */
  226. case ATS_DER:
  227. if(td->op->der_encoder) {
  228. er = der_encode(td, sptr, callback, callback_key);
  229. if(er.encoded == -1) {
  230. if(er.failed_type && er.failed_type->op->der_encoder) {
  231. errno = EBADF; /* Structure has incorrect form. */
  232. } else {
  233. errno = ENOENT; /* DER is not defined for this type. */
  234. }
  235. }
  236. } else {
  237. errno = ENOENT; /* Transfer syntax is not defined for this type. */
  238. ASN__ENCODE_FAILED;
  239. }
  240. break;
  241. case ATS_CER:
  242. errno = ENOENT; /* Transfer syntax is not defined for any type. */
  243. ASN__ENCODE_FAILED;
  244. #ifdef ASN_DISABLE_OER_SUPPORT
  245. case ATS_BASIC_OER:
  246. case ATS_CANONICAL_OER:
  247. errno = ENOENT; /* PER is not defined. */
  248. ASN__ENCODE_FAILED;
  249. break;
  250. #else /* ASN_DISABLE_OER_SUPPORT */
  251. case ATS_BASIC_OER:
  252. /* CANONICAL-OER is a superset of BASIC-OER. */
  253. /* Fall through. */
  254. case ATS_CANONICAL_OER:
  255. if(td->op->oer_encoder) {
  256. er = oer_encode(td, sptr, callback, callback_key);
  257. if(er.encoded == -1) {
  258. if(er.failed_type && er.failed_type->op->oer_encoder) {
  259. errno = EBADF; /* Structure has incorrect form. */
  260. } else {
  261. errno = ENOENT; /* OER is not defined for this type. */
  262. }
  263. }
  264. } else {
  265. errno = ENOENT; /* Transfer syntax is not defined for this type. */
  266. ASN__ENCODE_FAILED;
  267. }
  268. break;
  269. #endif /* ASN_DISABLE_OER_SUPPORT */
  270. #ifdef ASN_DISABLE_PER_SUPPORT
  271. case ATS_UNALIGNED_BASIC_PER:
  272. case ATS_UNALIGNED_CANONICAL_PER:
  273. errno = ENOENT; /* PER is not defined. */
  274. ASN__ENCODE_FAILED;
  275. break;
  276. #else /* ASN_DISABLE_PER_SUPPORT */
  277. case ATS_UNALIGNED_BASIC_PER:
  278. /* CANONICAL-UPER is a superset of BASIC-UPER. */
  279. /* Fall through. */
  280. case ATS_UNALIGNED_CANONICAL_PER:
  281. if(td->op->uper_encoder) {
  282. er = uper_encode(td, 0, sptr, callback, callback_key);
  283. if(er.encoded == -1) {
  284. if(er.failed_type && er.failed_type->op->uper_encoder) {
  285. errno = EBADF; /* Structure has incorrect form. */
  286. } else {
  287. errno = ENOENT; /* UPER is not defined for this type. */
  288. }
  289. } else {
  290. ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
  291. if(er.encoded == 0) {
  292. /* Enforce "Complete Encoding" of X.691 #11.1 */
  293. if(callback("\0", 1, callback_key) < 0) {
  294. errno = EBADF;
  295. ASN__ENCODE_FAILED;
  296. }
  297. er.encoded = 8; /* Exactly 8 zero bits is added. */
  298. }
  299. /* Convert bits into bytes */
  300. er.encoded = (er.encoded + 7) >> 3;
  301. }
  302. } else {
  303. errno = ENOENT; /* Transfer syntax is not defined for this type. */
  304. ASN__ENCODE_FAILED;
  305. }
  306. break;
  307. #endif /* ASN_DISABLE_PER_SUPPORT */
  308. case ATS_BASIC_XER:
  309. /* CANONICAL-XER is a superset of BASIC-XER. */
  310. xer_flags &= ~XER_F_CANONICAL;
  311. xer_flags |= XER_F_BASIC;
  312. /* Fall through. */
  313. case ATS_CANONICAL_XER:
  314. if(td->op->xer_encoder) {
  315. er = xer_encode(td, sptr, xer_flags, callback, callback_key);
  316. if(er.encoded == -1) {
  317. if(er.failed_type && er.failed_type->op->xer_encoder) {
  318. errno = EBADF; /* Structure has incorrect form. */
  319. } else {
  320. errno = ENOENT; /* XER is not defined for this type. */
  321. }
  322. }
  323. } else {
  324. errno = ENOENT; /* Transfer syntax is not defined for this type. */
  325. ASN__ENCODE_FAILED;
  326. }
  327. break;
  328. default:
  329. errno = ENOENT;
  330. ASN__ENCODE_FAILED;
  331. }
  332. return er;
  333. }
  334. asn_dec_rval_t
  335. asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
  336. enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,
  337. void **sptr, const void *buffer, size_t size) {
  338. if(!td || !td->op || !sptr || (size && !buffer)) {
  339. ASN__DECODE_FAILED;
  340. }
  341. switch(syntax) {
  342. case ATS_CER:
  343. case ATS_NONSTANDARD_PLAINTEXT:
  344. default:
  345. errno = ENOENT;
  346. ASN__DECODE_FAILED;
  347. case ATS_RANDOM:
  348. if(!td->op->random_fill) {
  349. ASN__DECODE_FAILED;
  350. } else {
  351. if(asn_random_fill(td, sptr, 16000) == 0) {
  352. asn_dec_rval_t ret = {RC_OK, 0};
  353. return ret;
  354. } else {
  355. ASN__DECODE_FAILED;
  356. }
  357. }
  358. break;
  359. case ATS_DER:
  360. case ATS_BER:
  361. return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
  362. case ATS_BASIC_OER:
  363. case ATS_CANONICAL_OER:
  364. #ifdef ASN_DISABLE_OER_SUPPORT
  365. errno = ENOENT;
  366. ASN__DECODE_FAILED;
  367. #else
  368. return oer_decode(opt_codec_ctx, td, sptr, buffer, size);
  369. #endif
  370. case ATS_UNALIGNED_BASIC_PER:
  371. case ATS_UNALIGNED_CANONICAL_PER:
  372. #ifdef ASN_DISABLE_PER_SUPPORT
  373. errno = ENOENT;
  374. ASN__DECODE_FAILED;
  375. #else
  376. return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
  377. #endif
  378. case ATS_BASIC_XER:
  379. case ATS_CANONICAL_XER:
  380. return xer_decode(opt_codec_ctx, td, sptr, buffer, size);
  381. }
  382. }