INTEGER_oer.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
  3. * All rights reserved.
  4. * Redistribution and modifications are permitted subject to BSD license.
  5. */
  6. #ifndef ASN_DISABLE_OER_SUPPORT
  7. #include <asn_internal.h>
  8. #include <INTEGER.h>
  9. #include <errno.h>
  10. asn_dec_rval_t
  11. INTEGER_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
  12. const asn_TYPE_descriptor_t *td,
  13. const asn_oer_constraints_t *constraints, void **sptr,
  14. const void *ptr, size_t size) {
  15. const asn_INTEGER_specifics_t *specs =
  16. (const asn_INTEGER_specifics_t *)td->specifics;
  17. asn_dec_rval_t rval = {RC_OK, 0};
  18. INTEGER_t *st = (INTEGER_t *)*sptr;
  19. struct asn_oer_constraint_number_s ct = {0, 0};
  20. size_t req_bytes;
  21. (void)opt_codec_ctx;
  22. (void)specs;
  23. if(!st) {
  24. st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
  25. if(!st) ASN__DECODE_FAILED;
  26. }
  27. FREEMEM(st->buf);
  28. st->buf = 0;
  29. st->size = 0;
  30. if(!constraints) constraints = td->encoding_constraints.oer_constraints;
  31. if(constraints) ct = constraints->value;
  32. if(ct.width) {
  33. req_bytes = ct.width;
  34. } else {
  35. /* No lower bound and no upper bound, effectively */
  36. ssize_t consumed = oer_fetch_length(ptr, size, &req_bytes);
  37. if(consumed == 0) {
  38. ASN__DECODE_STARVED;
  39. } else if(consumed == -1) {
  40. ASN__DECODE_FAILED;
  41. }
  42. rval.consumed += consumed;
  43. ptr = (const char *)ptr + consumed;
  44. size -= consumed;
  45. }
  46. if(req_bytes > size) {
  47. ASN__DECODE_STARVED;
  48. }
  49. if(ct.positive) {
  50. /* X.969 08/2015 10.2(a) */
  51. unsigned msb; /* Most significant bit */
  52. size_t useful_size;
  53. /* Check most significant bit */
  54. msb = *(const uint8_t *)ptr >> 7; /* yields 0 or 1 */
  55. useful_size = msb + req_bytes;
  56. st->buf = (uint8_t *)MALLOC(useful_size + 1);
  57. if(!st->buf) {
  58. ASN__DECODE_FAILED;
  59. }
  60. /*
  61. * Record a large unsigned in a way not to confuse it
  62. * with signed value.
  63. */
  64. st->buf[0] = '\0';
  65. memcpy(st->buf + msb, ptr, req_bytes);
  66. st->buf[useful_size] = '\0'; /* Just in case, 0-terminate */
  67. st->size = useful_size;
  68. rval.consumed += req_bytes;
  69. return rval;
  70. } else {
  71. /* X.969 08/2015 10.2(b) */
  72. st->buf = (uint8_t *)MALLOC(req_bytes + 1);
  73. if(!st->buf) {
  74. ASN__DECODE_FAILED;
  75. }
  76. memcpy(st->buf, ptr, req_bytes);
  77. st->buf[req_bytes] = '\0'; /* Just in case, 0-terminate */
  78. st->size = req_bytes;
  79. rval.consumed += req_bytes;
  80. return rval;
  81. }
  82. }
  83. /*
  84. * Encode as Canonical OER.
  85. */
  86. asn_enc_rval_t
  87. INTEGER_encode_oer(const asn_TYPE_descriptor_t *td,
  88. const asn_oer_constraints_t *constraints, const void *sptr,
  89. asn_app_consume_bytes_f *cb, void *app_key) {
  90. const INTEGER_t *st = sptr;
  91. asn_enc_rval_t er;
  92. struct asn_oer_constraint_number_s ct = {0, 0};
  93. const uint8_t *buf;
  94. const uint8_t *end;
  95. size_t useful_bytes;
  96. size_t req_bytes = 0;
  97. int sign = 0;
  98. if(!st || st->size == 0) ASN__ENCODE_FAILED;
  99. if(!constraints) constraints = td->encoding_constraints.oer_constraints;
  100. if(constraints) ct = constraints->value;
  101. er.encoded = 0;
  102. buf = st->buf;
  103. end = buf + st->size;
  104. sign = (buf && buf < end) ? buf[0] & 0x80 : 0;
  105. /* Ignore 9 leading zeroes or ones */
  106. if(ct.positive) {
  107. if(sign) {
  108. /* The value given is a signed value. Can't proceed. */
  109. ASN__ENCODE_FAILED;
  110. }
  111. /* Remove leading zeros. */
  112. for(; buf + 1 < end; buf++) {
  113. if(buf[0] != 0x0) break;
  114. }
  115. } else {
  116. for(; buf + 1 < end; buf++) {
  117. if(buf[0] == 0x0 && (buf[1] & 0x80) == 0) {
  118. continue;
  119. } else if(buf[0] == 0xff && (buf[1] & 0x80) != 0) {
  120. continue;
  121. }
  122. break;
  123. }
  124. }
  125. useful_bytes = end - buf;
  126. if(ct.width) {
  127. req_bytes = ct.width;
  128. } else {
  129. ssize_t r = oer_serialize_length(useful_bytes, cb, app_key);
  130. if(r < 0) {
  131. ASN__ENCODE_FAILED;
  132. }
  133. er.encoded += r;
  134. req_bytes = useful_bytes;
  135. }
  136. if(req_bytes < useful_bytes) {
  137. ASN__ENCODE_FAILED;
  138. }
  139. er.encoded += req_bytes;
  140. for(; req_bytes > useful_bytes; req_bytes--) {
  141. if(cb(sign?"\xff":"\0", 1, app_key) < 0) {
  142. ASN__ENCODE_FAILED;
  143. }
  144. }
  145. if(cb(buf, useful_bytes, app_key) < 0) {
  146. ASN__ENCODE_FAILED;
  147. }
  148. ASN__ENCODED_OK(er);
  149. }
  150. #endif /* ASN_DISABLE_OER_SUPPORT */