channelpadding_negotiation.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* channelpadding_negotiation.c -- generated by Trunnel v1.5.2.
  2. * https://gitweb.torproject.org/trunnel.git
  3. * You probably shouldn't edit this file.
  4. */
  5. #include <stdlib.h>
  6. #include "trunnel-impl.h"
  7. #include "channelpadding_negotiation.h"
  8. #define TRUNNEL_SET_ERROR_CODE(obj) \
  9. do { \
  10. (obj)->trunnel_error_code_ = 1; \
  11. } while (0)
  12. #if defined(__COVERITY__) || defined(__clang_analyzer__)
  13. /* If we're running a static analysis tool, we don't want it to complain
  14. * that some of our remaining-bytes checks are dead-code. */
  15. int channelpaddingnegotiation_deadcode_dummy__ = 0;
  16. #define OR_DEADCODE_DUMMY || channelpaddingnegotiation_deadcode_dummy__
  17. #else
  18. #define OR_DEADCODE_DUMMY
  19. #endif
  20. #define CHECK_REMAINING(nbytes, label) \
  21. do { \
  22. if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
  23. goto label; \
  24. } \
  25. } while (0)
  26. channelpadding_negotiate_t *
  27. channelpadding_negotiate_new(void)
  28. {
  29. channelpadding_negotiate_t *val = trunnel_calloc(1, sizeof(channelpadding_negotiate_t));
  30. if (NULL == val)
  31. return NULL;
  32. val->command = CHANNELPADDING_COMMAND_START;
  33. return val;
  34. }
  35. /** Release all storage held inside 'obj', but do not free 'obj'.
  36. */
  37. static void
  38. channelpadding_negotiate_clear(channelpadding_negotiate_t *obj)
  39. {
  40. (void) obj;
  41. }
  42. void
  43. channelpadding_negotiate_free(channelpadding_negotiate_t *obj)
  44. {
  45. if (obj == NULL)
  46. return;
  47. channelpadding_negotiate_clear(obj);
  48. trunnel_memwipe(obj, sizeof(channelpadding_negotiate_t));
  49. trunnel_free_(obj);
  50. }
  51. uint8_t
  52. channelpadding_negotiate_get_version(const channelpadding_negotiate_t *inp)
  53. {
  54. return inp->version;
  55. }
  56. int
  57. channelpadding_negotiate_set_version(channelpadding_negotiate_t *inp, uint8_t val)
  58. {
  59. if (! ((val == 0))) {
  60. TRUNNEL_SET_ERROR_CODE(inp);
  61. return -1;
  62. }
  63. inp->version = val;
  64. return 0;
  65. }
  66. uint8_t
  67. channelpadding_negotiate_get_command(const channelpadding_negotiate_t *inp)
  68. {
  69. return inp->command;
  70. }
  71. int
  72. channelpadding_negotiate_set_command(channelpadding_negotiate_t *inp, uint8_t val)
  73. {
  74. if (! ((val == CHANNELPADDING_COMMAND_START || val == CHANNELPADDING_COMMAND_STOP))) {
  75. TRUNNEL_SET_ERROR_CODE(inp);
  76. return -1;
  77. }
  78. inp->command = val;
  79. return 0;
  80. }
  81. uint16_t
  82. channelpadding_negotiate_get_ito_low_ms(const channelpadding_negotiate_t *inp)
  83. {
  84. return inp->ito_low_ms;
  85. }
  86. int
  87. channelpadding_negotiate_set_ito_low_ms(channelpadding_negotiate_t *inp, uint16_t val)
  88. {
  89. inp->ito_low_ms = val;
  90. return 0;
  91. }
  92. uint16_t
  93. channelpadding_negotiate_get_ito_high_ms(const channelpadding_negotiate_t *inp)
  94. {
  95. return inp->ito_high_ms;
  96. }
  97. int
  98. channelpadding_negotiate_set_ito_high_ms(channelpadding_negotiate_t *inp, uint16_t val)
  99. {
  100. inp->ito_high_ms = val;
  101. return 0;
  102. }
  103. const char *
  104. channelpadding_negotiate_check(const channelpadding_negotiate_t *obj)
  105. {
  106. if (obj == NULL)
  107. return "Object was NULL";
  108. if (obj->trunnel_error_code_)
  109. return "A set function failed on this object";
  110. if (! (obj->version == 0))
  111. return "Integer out of bounds";
  112. if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP))
  113. return "Integer out of bounds";
  114. return NULL;
  115. }
  116. ssize_t
  117. channelpadding_negotiate_encoded_len(const channelpadding_negotiate_t *obj)
  118. {
  119. ssize_t result = 0;
  120. if (NULL != channelpadding_negotiate_check(obj))
  121. return -1;
  122. /* Length of u8 version IN [0] */
  123. result += 1;
  124. /* Length of u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */
  125. result += 1;
  126. /* Length of u16 ito_low_ms */
  127. result += 2;
  128. /* Length of u16 ito_high_ms */
  129. result += 2;
  130. return result;
  131. }
  132. int
  133. channelpadding_negotiate_clear_errors(channelpadding_negotiate_t *obj)
  134. {
  135. int r = obj->trunnel_error_code_;
  136. obj->trunnel_error_code_ = 0;
  137. return r;
  138. }
  139. ssize_t
  140. channelpadding_negotiate_encode(uint8_t *output, const size_t avail, const channelpadding_negotiate_t *obj)
  141. {
  142. ssize_t result = 0;
  143. size_t written = 0;
  144. uint8_t *ptr = output;
  145. const char *msg;
  146. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  147. const ssize_t encoded_len = channelpadding_negotiate_encoded_len(obj);
  148. #endif
  149. if (NULL != (msg = channelpadding_negotiate_check(obj)))
  150. goto check_failed;
  151. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  152. trunnel_assert(encoded_len >= 0);
  153. #endif
  154. /* Encode u8 version IN [0] */
  155. trunnel_assert(written <= avail);
  156. if (avail - written < 1)
  157. goto truncated;
  158. trunnel_set_uint8(ptr, (obj->version));
  159. written += 1; ptr += 1;
  160. /* Encode u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */
  161. trunnel_assert(written <= avail);
  162. if (avail - written < 1)
  163. goto truncated;
  164. trunnel_set_uint8(ptr, (obj->command));
  165. written += 1; ptr += 1;
  166. /* Encode u16 ito_low_ms */
  167. trunnel_assert(written <= avail);
  168. if (avail - written < 2)
  169. goto truncated;
  170. trunnel_set_uint16(ptr, trunnel_htons(obj->ito_low_ms));
  171. written += 2; ptr += 2;
  172. /* Encode u16 ito_high_ms */
  173. trunnel_assert(written <= avail);
  174. if (avail - written < 2)
  175. goto truncated;
  176. trunnel_set_uint16(ptr, trunnel_htons(obj->ito_high_ms));
  177. written += 2; ptr += 2;
  178. trunnel_assert(ptr == output + written);
  179. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  180. {
  181. trunnel_assert(encoded_len >= 0);
  182. trunnel_assert((size_t)encoded_len == written);
  183. }
  184. #endif
  185. return written;
  186. truncated:
  187. result = -2;
  188. goto fail;
  189. check_failed:
  190. (void)msg;
  191. result = -1;
  192. goto fail;
  193. fail:
  194. trunnel_assert(result < 0);
  195. return result;
  196. }
  197. /** As channelpadding_negotiate_parse(), but do not allocate the
  198. * output object.
  199. */
  200. static ssize_t
  201. channelpadding_negotiate_parse_into(channelpadding_negotiate_t *obj, const uint8_t *input, const size_t len_in)
  202. {
  203. const uint8_t *ptr = input;
  204. size_t remaining = len_in;
  205. ssize_t result = 0;
  206. (void)result;
  207. /* Parse u8 version IN [0] */
  208. CHECK_REMAINING(1, truncated);
  209. obj->version = (trunnel_get_uint8(ptr));
  210. remaining -= 1; ptr += 1;
  211. if (! (obj->version == 0))
  212. goto fail;
  213. /* Parse u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */
  214. CHECK_REMAINING(1, truncated);
  215. obj->command = (trunnel_get_uint8(ptr));
  216. remaining -= 1; ptr += 1;
  217. if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP))
  218. goto fail;
  219. /* Parse u16 ito_low_ms */
  220. CHECK_REMAINING(2, truncated);
  221. obj->ito_low_ms = trunnel_ntohs(trunnel_get_uint16(ptr));
  222. remaining -= 2; ptr += 2;
  223. /* Parse u16 ito_high_ms */
  224. CHECK_REMAINING(2, truncated);
  225. obj->ito_high_ms = trunnel_ntohs(trunnel_get_uint16(ptr));
  226. remaining -= 2; ptr += 2;
  227. trunnel_assert(ptr + remaining == input + len_in);
  228. return len_in - remaining;
  229. truncated:
  230. return -2;
  231. fail:
  232. result = -1;
  233. return result;
  234. }
  235. ssize_t
  236. channelpadding_negotiate_parse(channelpadding_negotiate_t **output, const uint8_t *input, const size_t len_in)
  237. {
  238. ssize_t result;
  239. *output = channelpadding_negotiate_new();
  240. if (NULL == *output)
  241. return -1;
  242. result = channelpadding_negotiate_parse_into(*output, input, len_in);
  243. if (result < 0) {
  244. channelpadding_negotiate_free(*output);
  245. *output = NULL;
  246. }
  247. return result;
  248. }