BIT_STRING_oer.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 <BIT_STRING.h>
  9. #include <errno.h>
  10. asn_dec_rval_t
  11. BIT_STRING_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. BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
  16. const asn_oer_constraints_t *cts =
  17. constraints ? constraints : td->encoding_constraints.oer_constraints;
  18. ssize_t ct_size = cts ? cts->size : -1;
  19. asn_dec_rval_t rval = {RC_OK, 0};
  20. size_t expected_length = 0;
  21. (void)opt_codec_ctx;
  22. if(!st) {
  23. st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
  24. if(!st) ASN__DECODE_FAILED;
  25. }
  26. if(ct_size >= 0) {
  27. expected_length = (ct_size + 7) >> 3;
  28. st->bits_unused = (8 - (ct_size & 7)) & 7;
  29. } else {
  30. /*
  31. * X.696 (08/2015) #13.3.1
  32. * Encode length determinant as _number of octets_, but only
  33. * if upper bound is not equal to lower bound.
  34. */
  35. ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
  36. if(len_len > 0) {
  37. ptr = (const char *)ptr + len_len;
  38. size -= len_len;
  39. } else if(len_len == 0) {
  40. ASN__DECODE_STARVED;
  41. } else if(len_len < 0) {
  42. ASN__DECODE_FAILED;
  43. }
  44. if(expected_length < 1) {
  45. ASN__DECODE_FAILED;
  46. } else if(expected_length > size) {
  47. ASN__DECODE_STARVED;
  48. }
  49. st->bits_unused = ((const uint8_t *)ptr)[0];
  50. if(st->bits_unused & ~7) {
  51. ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name);
  52. ASN__DECODE_FAILED;
  53. }
  54. ptr = (const char *)ptr + 1;
  55. size--;
  56. expected_length--;
  57. rval.consumed = len_len + 1;
  58. }
  59. if(size < expected_length) {
  60. ASN__DECODE_STARVED;
  61. } else {
  62. uint8_t *buf = MALLOC(expected_length + 1);
  63. if(buf == NULL) {
  64. ASN__DECODE_FAILED;
  65. } else {
  66. memcpy(buf, ptr, expected_length);
  67. buf[expected_length] = '\0';
  68. }
  69. FREEMEM(st->buf);
  70. st->buf = buf;
  71. st->size = expected_length;
  72. if(expected_length > 0) {
  73. buf[expected_length - 1] &= (0xff << st->bits_unused);
  74. }
  75. rval.consumed += expected_length;
  76. return rval;
  77. }
  78. }
  79. /*
  80. * Encode as Canonical OER.
  81. */
  82. asn_enc_rval_t
  83. BIT_STRING_encode_oer(const asn_TYPE_descriptor_t *td,
  84. const asn_oer_constraints_t *constraints,
  85. const void *sptr, asn_app_consume_bytes_f *cb,
  86. void *app_key) {
  87. const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
  88. asn_enc_rval_t erval = {0, 0, 0};
  89. const asn_oer_constraints_t *cts =
  90. constraints ? constraints : td->encoding_constraints.oer_constraints;
  91. ssize_t ct_size = cts ? cts->size : -1;
  92. size_t trailing_zeros = 0;
  93. int fix_last_byte = 0;
  94. if(!st) ASN__ENCODE_FAILED;
  95. if(st->bits_unused & ~7) {
  96. ASN_DEBUG("BIT STRING unused bits %d out of 0..7 range",
  97. st->bits_unused);
  98. ASN__ENCODE_FAILED;
  99. }
  100. if(st->bits_unused && !(st->size && st->buf)) {
  101. ASN_DEBUG("BIT STRING %s size 0 can't support unused bits %d", td->name,
  102. st->bits_unused);
  103. ASN__ENCODE_FAILED;
  104. }
  105. if(ct_size >= 0) {
  106. size_t ct_bytes = (ct_size + 7) >> 3;
  107. if(st->size > ct_bytes) {
  108. ASN_DEBUG("More bits in BIT STRING %s (%" ASN_PRI_SSIZE ") than constrained %" ASN_PRI_SSIZE "",
  109. td->name, 8 * st->size - st->bits_unused, ct_size);
  110. ASN__ENCODE_FAILED;
  111. }
  112. trailing_zeros = ct_bytes - st->size; /* Allow larger constraint */
  113. } else {
  114. uint8_t ub = st->bits_unused & 7;
  115. ssize_t len_len = oer_serialize_length(1 + st->size, cb, app_key);
  116. if(len_len < 0) ASN__ENCODE_FAILED;
  117. if(cb(&ub, 1, app_key) < 0) {
  118. ASN__ENCODE_FAILED;
  119. }
  120. erval.encoded += len_len + 1;
  121. }
  122. if(st->bits_unused) {
  123. if(st->buf[st->size - 1] & (0xff << st->bits_unused)) {
  124. fix_last_byte = 1;
  125. }
  126. }
  127. if(cb(st->buf, st->size - fix_last_byte, app_key) < 0) {
  128. ASN__ENCODE_FAILED;
  129. }
  130. if(fix_last_byte) {
  131. uint8_t b = st->buf[st->size - 1] & (0xff << st->bits_unused);
  132. if(cb(&b, 1, app_key) < 0) {
  133. ASN__ENCODE_FAILED;
  134. }
  135. }
  136. erval.encoded += st->size;
  137. if(trailing_zeros) {
  138. static uint8_t zeros[16];
  139. while(trailing_zeros > 0) {
  140. int ret;
  141. if(trailing_zeros < sizeof(zeros)) {
  142. ret = cb(zeros, trailing_zeros, app_key);
  143. erval.encoded += trailing_zeros;
  144. } else {
  145. ret = cb(zeros, sizeof(zeros), app_key);
  146. erval.encoded += sizeof(zeros);
  147. }
  148. if(ret < 0) ASN__ENCODE_FAILED;
  149. }
  150. }
  151. return erval;
  152. }
  153. #endif /* ASN_DISABLE_OER_SUPPORT */