circpad_negotiation.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /* circpad_negotiation.c -- generated by Trunnel v1.5.3.
  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 "circpad_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 circpadnegotiation_deadcode_dummy__ = 0;
  16. #define OR_DEADCODE_DUMMY || circpadnegotiation_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. circpad_negotiate_t *
  27. circpad_negotiate_new(void)
  28. {
  29. circpad_negotiate_t *val = trunnel_calloc(1, sizeof(circpad_negotiate_t));
  30. if (NULL == val)
  31. return NULL;
  32. val->command = CIRCPAD_COMMAND_START;
  33. return val;
  34. }
  35. /** Release all storage held inside 'obj', but do not free 'obj'.
  36. */
  37. static void
  38. circpad_negotiate_clear(circpad_negotiate_t *obj)
  39. {
  40. (void) obj;
  41. }
  42. void
  43. circpad_negotiate_free(circpad_negotiate_t *obj)
  44. {
  45. if (obj == NULL)
  46. return;
  47. circpad_negotiate_clear(obj);
  48. trunnel_memwipe(obj, sizeof(circpad_negotiate_t));
  49. trunnel_free_(obj);
  50. }
  51. uint8_t
  52. circpad_negotiate_get_version(const circpad_negotiate_t *inp)
  53. {
  54. return inp->version;
  55. }
  56. int
  57. circpad_negotiate_set_version(circpad_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. circpad_negotiate_get_command(const circpad_negotiate_t *inp)
  68. {
  69. return inp->command;
  70. }
  71. int
  72. circpad_negotiate_set_command(circpad_negotiate_t *inp, uint8_t val)
  73. {
  74. if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) {
  75. TRUNNEL_SET_ERROR_CODE(inp);
  76. return -1;
  77. }
  78. inp->command = val;
  79. return 0;
  80. }
  81. uint8_t
  82. circpad_negotiate_get_machine_type(const circpad_negotiate_t *inp)
  83. {
  84. return inp->machine_type;
  85. }
  86. int
  87. circpad_negotiate_set_machine_type(circpad_negotiate_t *inp, uint8_t val)
  88. {
  89. inp->machine_type = val;
  90. return 0;
  91. }
  92. uint8_t
  93. circpad_negotiate_get_echo_request(const circpad_negotiate_t *inp)
  94. {
  95. return inp->echo_request;
  96. }
  97. int
  98. circpad_negotiate_set_echo_request(circpad_negotiate_t *inp, uint8_t val)
  99. {
  100. if (! ((val == 0 || val == 1))) {
  101. TRUNNEL_SET_ERROR_CODE(inp);
  102. return -1;
  103. }
  104. inp->echo_request = val;
  105. return 0;
  106. }
  107. const char *
  108. circpad_negotiate_check(const circpad_negotiate_t *obj)
  109. {
  110. if (obj == NULL)
  111. return "Object was NULL";
  112. if (obj->trunnel_error_code_)
  113. return "A set function failed on this object";
  114. if (! (obj->version == 0))
  115. return "Integer out of bounds";
  116. if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
  117. return "Integer out of bounds";
  118. if (! (obj->echo_request == 0 || obj->echo_request == 1))
  119. return "Integer out of bounds";
  120. return NULL;
  121. }
  122. ssize_t
  123. circpad_negotiate_encoded_len(const circpad_negotiate_t *obj)
  124. {
  125. ssize_t result = 0;
  126. if (NULL != circpad_negotiate_check(obj))
  127. return -1;
  128. /* Length of u8 version IN [0] */
  129. result += 1;
  130. /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  131. result += 1;
  132. /* Length of u8 machine_type */
  133. result += 1;
  134. /* Length of u8 echo_request IN [0, 1] */
  135. result += 1;
  136. return result;
  137. }
  138. int
  139. circpad_negotiate_clear_errors(circpad_negotiate_t *obj)
  140. {
  141. int r = obj->trunnel_error_code_;
  142. obj->trunnel_error_code_ = 0;
  143. return r;
  144. }
  145. ssize_t
  146. circpad_negotiate_encode(uint8_t *output, const size_t avail, const circpad_negotiate_t *obj)
  147. {
  148. ssize_t result = 0;
  149. size_t written = 0;
  150. uint8_t *ptr = output;
  151. const char *msg;
  152. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  153. const ssize_t encoded_len = circpad_negotiate_encoded_len(obj);
  154. #endif
  155. if (NULL != (msg = circpad_negotiate_check(obj)))
  156. goto check_failed;
  157. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  158. trunnel_assert(encoded_len >= 0);
  159. #endif
  160. /* Encode u8 version IN [0] */
  161. trunnel_assert(written <= avail);
  162. if (avail - written < 1)
  163. goto truncated;
  164. trunnel_set_uint8(ptr, (obj->version));
  165. written += 1; ptr += 1;
  166. /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  167. trunnel_assert(written <= avail);
  168. if (avail - written < 1)
  169. goto truncated;
  170. trunnel_set_uint8(ptr, (obj->command));
  171. written += 1; ptr += 1;
  172. /* Encode u8 machine_type */
  173. trunnel_assert(written <= avail);
  174. if (avail - written < 1)
  175. goto truncated;
  176. trunnel_set_uint8(ptr, (obj->machine_type));
  177. written += 1; ptr += 1;
  178. /* Encode u8 echo_request IN [0, 1] */
  179. trunnel_assert(written <= avail);
  180. if (avail - written < 1)
  181. goto truncated;
  182. trunnel_set_uint8(ptr, (obj->echo_request));
  183. written += 1; ptr += 1;
  184. trunnel_assert(ptr == output + written);
  185. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  186. {
  187. trunnel_assert(encoded_len >= 0);
  188. trunnel_assert((size_t)encoded_len == written);
  189. }
  190. #endif
  191. return written;
  192. truncated:
  193. result = -2;
  194. goto fail;
  195. check_failed:
  196. (void)msg;
  197. result = -1;
  198. goto fail;
  199. fail:
  200. trunnel_assert(result < 0);
  201. return result;
  202. }
  203. /** As circpad_negotiate_parse(), but do not allocate the output
  204. * object.
  205. */
  206. static ssize_t
  207. circpad_negotiate_parse_into(circpad_negotiate_t *obj, const uint8_t *input, const size_t len_in)
  208. {
  209. const uint8_t *ptr = input;
  210. size_t remaining = len_in;
  211. ssize_t result = 0;
  212. (void)result;
  213. /* Parse u8 version IN [0] */
  214. CHECK_REMAINING(1, truncated);
  215. obj->version = (trunnel_get_uint8(ptr));
  216. remaining -= 1; ptr += 1;
  217. if (! (obj->version == 0))
  218. goto fail;
  219. /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  220. CHECK_REMAINING(1, truncated);
  221. obj->command = (trunnel_get_uint8(ptr));
  222. remaining -= 1; ptr += 1;
  223. if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
  224. goto fail;
  225. /* Parse u8 machine_type */
  226. CHECK_REMAINING(1, truncated);
  227. obj->machine_type = (trunnel_get_uint8(ptr));
  228. remaining -= 1; ptr += 1;
  229. /* Parse u8 echo_request IN [0, 1] */
  230. CHECK_REMAINING(1, truncated);
  231. obj->echo_request = (trunnel_get_uint8(ptr));
  232. remaining -= 1; ptr += 1;
  233. if (! (obj->echo_request == 0 || obj->echo_request == 1))
  234. goto fail;
  235. trunnel_assert(ptr + remaining == input + len_in);
  236. return len_in - remaining;
  237. truncated:
  238. return -2;
  239. fail:
  240. result = -1;
  241. return result;
  242. }
  243. ssize_t
  244. circpad_negotiate_parse(circpad_negotiate_t **output, const uint8_t *input, const size_t len_in)
  245. {
  246. ssize_t result;
  247. *output = circpad_negotiate_new();
  248. if (NULL == *output)
  249. return -1;
  250. result = circpad_negotiate_parse_into(*output, input, len_in);
  251. if (result < 0) {
  252. circpad_negotiate_free(*output);
  253. *output = NULL;
  254. }
  255. return result;
  256. }
  257. circpad_negotiated_t *
  258. circpad_negotiated_new(void)
  259. {
  260. circpad_negotiated_t *val = trunnel_calloc(1, sizeof(circpad_negotiated_t));
  261. if (NULL == val)
  262. return NULL;
  263. val->command = CIRCPAD_COMMAND_START;
  264. val->response = CIRCPAD_RESPONSE_ERR;
  265. return val;
  266. }
  267. /** Release all storage held inside 'obj', but do not free 'obj'.
  268. */
  269. static void
  270. circpad_negotiated_clear(circpad_negotiated_t *obj)
  271. {
  272. (void) obj;
  273. }
  274. void
  275. circpad_negotiated_free(circpad_negotiated_t *obj)
  276. {
  277. if (obj == NULL)
  278. return;
  279. circpad_negotiated_clear(obj);
  280. trunnel_memwipe(obj, sizeof(circpad_negotiated_t));
  281. trunnel_free_(obj);
  282. }
  283. uint8_t
  284. circpad_negotiated_get_version(const circpad_negotiated_t *inp)
  285. {
  286. return inp->version;
  287. }
  288. int
  289. circpad_negotiated_set_version(circpad_negotiated_t *inp, uint8_t val)
  290. {
  291. if (! ((val == 0))) {
  292. TRUNNEL_SET_ERROR_CODE(inp);
  293. return -1;
  294. }
  295. inp->version = val;
  296. return 0;
  297. }
  298. uint8_t
  299. circpad_negotiated_get_command(const circpad_negotiated_t *inp)
  300. {
  301. return inp->command;
  302. }
  303. int
  304. circpad_negotiated_set_command(circpad_negotiated_t *inp, uint8_t val)
  305. {
  306. if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) {
  307. TRUNNEL_SET_ERROR_CODE(inp);
  308. return -1;
  309. }
  310. inp->command = val;
  311. return 0;
  312. }
  313. uint8_t
  314. circpad_negotiated_get_response(const circpad_negotiated_t *inp)
  315. {
  316. return inp->response;
  317. }
  318. int
  319. circpad_negotiated_set_response(circpad_negotiated_t *inp, uint8_t val)
  320. {
  321. if (! ((val == CIRCPAD_RESPONSE_ERR || val == CIRCPAD_RESPONSE_OK))) {
  322. TRUNNEL_SET_ERROR_CODE(inp);
  323. return -1;
  324. }
  325. inp->response = val;
  326. return 0;
  327. }
  328. uint8_t
  329. circpad_negotiated_get_machine_type(const circpad_negotiated_t *inp)
  330. {
  331. return inp->machine_type;
  332. }
  333. int
  334. circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val)
  335. {
  336. inp->machine_type = val;
  337. return 0;
  338. }
  339. const char *
  340. circpad_negotiated_check(const circpad_negotiated_t *obj)
  341. {
  342. if (obj == NULL)
  343. return "Object was NULL";
  344. if (obj->trunnel_error_code_)
  345. return "A set function failed on this object";
  346. if (! (obj->version == 0))
  347. return "Integer out of bounds";
  348. if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
  349. return "Integer out of bounds";
  350. if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
  351. return "Integer out of bounds";
  352. return NULL;
  353. }
  354. ssize_t
  355. circpad_negotiated_encoded_len(const circpad_negotiated_t *obj)
  356. {
  357. ssize_t result = 0;
  358. if (NULL != circpad_negotiated_check(obj))
  359. return -1;
  360. /* Length of u8 version IN [0] */
  361. result += 1;
  362. /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  363. result += 1;
  364. /* Length of u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
  365. result += 1;
  366. /* Length of u8 machine_type */
  367. result += 1;
  368. return result;
  369. }
  370. int
  371. circpad_negotiated_clear_errors(circpad_negotiated_t *obj)
  372. {
  373. int r = obj->trunnel_error_code_;
  374. obj->trunnel_error_code_ = 0;
  375. return r;
  376. }
  377. ssize_t
  378. circpad_negotiated_encode(uint8_t *output, const size_t avail, const circpad_negotiated_t *obj)
  379. {
  380. ssize_t result = 0;
  381. size_t written = 0;
  382. uint8_t *ptr = output;
  383. const char *msg;
  384. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  385. const ssize_t encoded_len = circpad_negotiated_encoded_len(obj);
  386. #endif
  387. if (NULL != (msg = circpad_negotiated_check(obj)))
  388. goto check_failed;
  389. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  390. trunnel_assert(encoded_len >= 0);
  391. #endif
  392. /* Encode u8 version IN [0] */
  393. trunnel_assert(written <= avail);
  394. if (avail - written < 1)
  395. goto truncated;
  396. trunnel_set_uint8(ptr, (obj->version));
  397. written += 1; ptr += 1;
  398. /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  399. trunnel_assert(written <= avail);
  400. if (avail - written < 1)
  401. goto truncated;
  402. trunnel_set_uint8(ptr, (obj->command));
  403. written += 1; ptr += 1;
  404. /* Encode u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
  405. trunnel_assert(written <= avail);
  406. if (avail - written < 1)
  407. goto truncated;
  408. trunnel_set_uint8(ptr, (obj->response));
  409. written += 1; ptr += 1;
  410. /* Encode u8 machine_type */
  411. trunnel_assert(written <= avail);
  412. if (avail - written < 1)
  413. goto truncated;
  414. trunnel_set_uint8(ptr, (obj->machine_type));
  415. written += 1; ptr += 1;
  416. trunnel_assert(ptr == output + written);
  417. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  418. {
  419. trunnel_assert(encoded_len >= 0);
  420. trunnel_assert((size_t)encoded_len == written);
  421. }
  422. #endif
  423. return written;
  424. truncated:
  425. result = -2;
  426. goto fail;
  427. check_failed:
  428. (void)msg;
  429. result = -1;
  430. goto fail;
  431. fail:
  432. trunnel_assert(result < 0);
  433. return result;
  434. }
  435. /** As circpad_negotiated_parse(), but do not allocate the output
  436. * object.
  437. */
  438. static ssize_t
  439. circpad_negotiated_parse_into(circpad_negotiated_t *obj, const uint8_t *input, const size_t len_in)
  440. {
  441. const uint8_t *ptr = input;
  442. size_t remaining = len_in;
  443. ssize_t result = 0;
  444. (void)result;
  445. /* Parse u8 version IN [0] */
  446. CHECK_REMAINING(1, truncated);
  447. obj->version = (trunnel_get_uint8(ptr));
  448. remaining -= 1; ptr += 1;
  449. if (! (obj->version == 0))
  450. goto fail;
  451. /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
  452. CHECK_REMAINING(1, truncated);
  453. obj->command = (trunnel_get_uint8(ptr));
  454. remaining -= 1; ptr += 1;
  455. if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
  456. goto fail;
  457. /* Parse u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
  458. CHECK_REMAINING(1, truncated);
  459. obj->response = (trunnel_get_uint8(ptr));
  460. remaining -= 1; ptr += 1;
  461. if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
  462. goto fail;
  463. /* Parse u8 machine_type */
  464. CHECK_REMAINING(1, truncated);
  465. obj->machine_type = (trunnel_get_uint8(ptr));
  466. remaining -= 1; ptr += 1;
  467. trunnel_assert(ptr + remaining == input + len_in);
  468. return len_in - remaining;
  469. truncated:
  470. return -2;
  471. fail:
  472. result = -1;
  473. return result;
  474. }
  475. ssize_t
  476. circpad_negotiated_parse(circpad_negotiated_t **output, const uint8_t *input, const size_t len_in)
  477. {
  478. ssize_t result;
  479. *output = circpad_negotiated_new();
  480. if (NULL == *output)
  481. return -1;
  482. result = circpad_negotiated_parse_into(*output, input, len_in);
  483. if (result < 0) {
  484. circpad_negotiated_free(*output);
  485. *output = NULL;
  486. }
  487. return result;
  488. }