circpad_negotiation.c (14696B)
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 8 #include "circpad_negotiation.h" 9 10 #define TRUNNEL_SET_ERROR_CODE(obj) \ 11 do { \ 12 (obj)->trunnel_error_code_ = 1; \ 13 } while (0) 14 15 #if defined(__COVERITY__) || defined(__clang_analyzer__) 16 /* If we're running a static analysis tool, we don't want it to complain 17 * that some of our remaining-bytes checks are dead-code. */ 18 int circpadnegotiation_deadcode_dummy__ = 0; 19 #define OR_DEADCODE_DUMMY || circpadnegotiation_deadcode_dummy__ 20 #else 21 #define OR_DEADCODE_DUMMY 22 #endif 23 24 #define CHECK_REMAINING(nbytes, label) \ 25 do { \ 26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \ 27 goto label; \ 28 } \ 29 } while (0) 30 31 circpad_negotiate_t * 32 circpad_negotiate_new(void) 33 { 34 circpad_negotiate_t *val = trunnel_calloc(1, sizeof(circpad_negotiate_t)); 35 if (NULL == val) 36 return NULL; 37 val->command = CIRCPAD_COMMAND_START; 38 return val; 39 } 40 41 /** Release all storage held inside 'obj', but do not free 'obj'. 42 */ 43 static void 44 circpad_negotiate_clear(circpad_negotiate_t *obj) 45 { 46 (void) obj; 47 } 48 49 void 50 circpad_negotiate_free(circpad_negotiate_t *obj) 51 { 52 if (obj == NULL) 53 return; 54 circpad_negotiate_clear(obj); 55 trunnel_memwipe(obj, sizeof(circpad_negotiate_t)); 56 trunnel_free_(obj); 57 } 58 59 uint8_t 60 circpad_negotiate_get_version(const circpad_negotiate_t *inp) 61 { 62 return inp->version; 63 } 64 int 65 circpad_negotiate_set_version(circpad_negotiate_t *inp, uint8_t val) 66 { 67 if (! ((val == 0))) { 68 TRUNNEL_SET_ERROR_CODE(inp); 69 return -1; 70 } 71 inp->version = val; 72 return 0; 73 } 74 uint8_t 75 circpad_negotiate_get_command(const circpad_negotiate_t *inp) 76 { 77 return inp->command; 78 } 79 int 80 circpad_negotiate_set_command(circpad_negotiate_t *inp, uint8_t val) 81 { 82 if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) { 83 TRUNNEL_SET_ERROR_CODE(inp); 84 return -1; 85 } 86 inp->command = val; 87 return 0; 88 } 89 uint8_t 90 circpad_negotiate_get_machine_type(const circpad_negotiate_t *inp) 91 { 92 return inp->machine_type; 93 } 94 int 95 circpad_negotiate_set_machine_type(circpad_negotiate_t *inp, uint8_t val) 96 { 97 inp->machine_type = val; 98 return 0; 99 } 100 uint8_t 101 circpad_negotiate_get_echo_request(const circpad_negotiate_t *inp) 102 { 103 return inp->echo_request; 104 } 105 int 106 circpad_negotiate_set_echo_request(circpad_negotiate_t *inp, uint8_t val) 107 { 108 if (! ((val == 0 || val == 1))) { 109 TRUNNEL_SET_ERROR_CODE(inp); 110 return -1; 111 } 112 inp->echo_request = val; 113 return 0; 114 } 115 uint32_t 116 circpad_negotiate_get_machine_ctr(const circpad_negotiate_t *inp) 117 { 118 return inp->machine_ctr; 119 } 120 int 121 circpad_negotiate_set_machine_ctr(circpad_negotiate_t *inp, uint32_t val) 122 { 123 inp->machine_ctr = val; 124 return 0; 125 } 126 const char * 127 circpad_negotiate_check(const circpad_negotiate_t *obj) 128 { 129 if (obj == NULL) 130 return "Object was NULL"; 131 if (obj->trunnel_error_code_) 132 return "A set function failed on this object"; 133 if (! (obj->version == 0)) 134 return "Integer out of bounds"; 135 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP)) 136 return "Integer out of bounds"; 137 if (! (obj->echo_request == 0 || obj->echo_request == 1)) 138 return "Integer out of bounds"; 139 return NULL; 140 } 141 142 ssize_t 143 circpad_negotiate_encoded_len(const circpad_negotiate_t *obj) 144 { 145 ssize_t result = 0; 146 147 if (NULL != circpad_negotiate_check(obj)) 148 return -1; 149 150 151 /* Length of u8 version IN [0] */ 152 result += 1; 153 154 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 155 result += 1; 156 157 /* Length of u8 machine_type */ 158 result += 1; 159 160 /* Length of u8 echo_request IN [0, 1] */ 161 result += 1; 162 163 /* Length of u32 machine_ctr */ 164 result += 4; 165 return result; 166 } 167 int 168 circpad_negotiate_clear_errors(circpad_negotiate_t *obj) 169 { 170 int r = obj->trunnel_error_code_; 171 obj->trunnel_error_code_ = 0; 172 return r; 173 } 174 ssize_t 175 circpad_negotiate_encode(uint8_t *output, const size_t avail, const circpad_negotiate_t *obj) 176 { 177 ssize_t result = 0; 178 size_t written = 0; 179 uint8_t *ptr = output; 180 const char *msg; 181 #ifdef TRUNNEL_CHECK_ENCODED_LEN 182 const ssize_t encoded_len = circpad_negotiate_encoded_len(obj); 183 #endif 184 185 if (NULL != (msg = circpad_negotiate_check(obj))) 186 goto check_failed; 187 188 #ifdef TRUNNEL_CHECK_ENCODED_LEN 189 trunnel_assert(encoded_len >= 0); 190 #endif 191 192 /* Encode u8 version IN [0] */ 193 trunnel_assert(written <= avail); 194 if (avail - written < 1) 195 goto truncated; 196 trunnel_set_uint8(ptr, (obj->version)); 197 written += 1; ptr += 1; 198 199 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 200 trunnel_assert(written <= avail); 201 if (avail - written < 1) 202 goto truncated; 203 trunnel_set_uint8(ptr, (obj->command)); 204 written += 1; ptr += 1; 205 206 /* Encode u8 machine_type */ 207 trunnel_assert(written <= avail); 208 if (avail - written < 1) 209 goto truncated; 210 trunnel_set_uint8(ptr, (obj->machine_type)); 211 written += 1; ptr += 1; 212 213 /* Encode u8 echo_request IN [0, 1] */ 214 trunnel_assert(written <= avail); 215 if (avail - written < 1) 216 goto truncated; 217 trunnel_set_uint8(ptr, (obj->echo_request)); 218 written += 1; ptr += 1; 219 220 /* Encode u32 machine_ctr */ 221 trunnel_assert(written <= avail); 222 if (avail - written < 4) 223 goto truncated; 224 trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr)); 225 written += 4; ptr += 4; 226 227 228 trunnel_assert(ptr == output + written); 229 #ifdef TRUNNEL_CHECK_ENCODED_LEN 230 { 231 trunnel_assert(encoded_len >= 0); 232 trunnel_assert((size_t)encoded_len == written); 233 } 234 235 #endif 236 237 return written; 238 239 truncated: 240 result = -2; 241 goto fail; 242 check_failed: 243 (void)msg; 244 result = -1; 245 goto fail; 246 fail: 247 trunnel_assert(result < 0); 248 return result; 249 } 250 251 /** As circpad_negotiate_parse(), but do not allocate the output 252 * object. 253 */ 254 static ssize_t 255 circpad_negotiate_parse_into(circpad_negotiate_t *obj, const uint8_t *input, const size_t len_in) 256 { 257 const uint8_t *ptr = input; 258 size_t remaining = len_in; 259 ssize_t result = 0; 260 (void)result; 261 262 /* Parse u8 version IN [0] */ 263 CHECK_REMAINING(1, truncated); 264 obj->version = (trunnel_get_uint8(ptr)); 265 remaining -= 1; ptr += 1; 266 if (! (obj->version == 0)) 267 goto fail; 268 269 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 270 CHECK_REMAINING(1, truncated); 271 obj->command = (trunnel_get_uint8(ptr)); 272 remaining -= 1; ptr += 1; 273 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP)) 274 goto fail; 275 276 /* Parse u8 machine_type */ 277 CHECK_REMAINING(1, truncated); 278 obj->machine_type = (trunnel_get_uint8(ptr)); 279 remaining -= 1; ptr += 1; 280 281 /* Parse u8 echo_request IN [0, 1] */ 282 CHECK_REMAINING(1, truncated); 283 obj->echo_request = (trunnel_get_uint8(ptr)); 284 remaining -= 1; ptr += 1; 285 if (! (obj->echo_request == 0 || obj->echo_request == 1)) 286 goto fail; 287 288 /* Parse u32 machine_ctr */ 289 CHECK_REMAINING(4, truncated); 290 obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr)); 291 remaining -= 4; ptr += 4; 292 trunnel_assert(ptr + remaining == input + len_in); 293 return len_in - remaining; 294 295 truncated: 296 return -2; 297 fail: 298 result = -1; 299 return result; 300 } 301 302 ssize_t 303 circpad_negotiate_parse(circpad_negotiate_t **output, const uint8_t *input, const size_t len_in) 304 { 305 ssize_t result; 306 *output = circpad_negotiate_new(); 307 if (NULL == *output) 308 return -1; 309 result = circpad_negotiate_parse_into(*output, input, len_in); 310 if (result < 0) { 311 circpad_negotiate_free(*output); 312 *output = NULL; 313 } 314 return result; 315 } 316 circpad_negotiated_t * 317 circpad_negotiated_new(void) 318 { 319 circpad_negotiated_t *val = trunnel_calloc(1, sizeof(circpad_negotiated_t)); 320 if (NULL == val) 321 return NULL; 322 val->command = CIRCPAD_COMMAND_START; 323 val->response = CIRCPAD_RESPONSE_ERR; 324 return val; 325 } 326 327 /** Release all storage held inside 'obj', but do not free 'obj'. 328 */ 329 static void 330 circpad_negotiated_clear(circpad_negotiated_t *obj) 331 { 332 (void) obj; 333 } 334 335 void 336 circpad_negotiated_free(circpad_negotiated_t *obj) 337 { 338 if (obj == NULL) 339 return; 340 circpad_negotiated_clear(obj); 341 trunnel_memwipe(obj, sizeof(circpad_negotiated_t)); 342 trunnel_free_(obj); 343 } 344 345 uint8_t 346 circpad_negotiated_get_version(const circpad_negotiated_t *inp) 347 { 348 return inp->version; 349 } 350 int 351 circpad_negotiated_set_version(circpad_negotiated_t *inp, uint8_t val) 352 { 353 if (! ((val == 0))) { 354 TRUNNEL_SET_ERROR_CODE(inp); 355 return -1; 356 } 357 inp->version = val; 358 return 0; 359 } 360 uint8_t 361 circpad_negotiated_get_command(const circpad_negotiated_t *inp) 362 { 363 return inp->command; 364 } 365 int 366 circpad_negotiated_set_command(circpad_negotiated_t *inp, uint8_t val) 367 { 368 if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) { 369 TRUNNEL_SET_ERROR_CODE(inp); 370 return -1; 371 } 372 inp->command = val; 373 return 0; 374 } 375 uint8_t 376 circpad_negotiated_get_response(const circpad_negotiated_t *inp) 377 { 378 return inp->response; 379 } 380 int 381 circpad_negotiated_set_response(circpad_negotiated_t *inp, uint8_t val) 382 { 383 if (! ((val == CIRCPAD_RESPONSE_ERR || val == CIRCPAD_RESPONSE_OK))) { 384 TRUNNEL_SET_ERROR_CODE(inp); 385 return -1; 386 } 387 inp->response = val; 388 return 0; 389 } 390 uint8_t 391 circpad_negotiated_get_machine_type(const circpad_negotiated_t *inp) 392 { 393 return inp->machine_type; 394 } 395 int 396 circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val) 397 { 398 inp->machine_type = val; 399 return 0; 400 } 401 uint32_t 402 circpad_negotiated_get_machine_ctr(const circpad_negotiated_t *inp) 403 { 404 return inp->machine_ctr; 405 } 406 int 407 circpad_negotiated_set_machine_ctr(circpad_negotiated_t *inp, uint32_t val) 408 { 409 inp->machine_ctr = val; 410 return 0; 411 } 412 const char * 413 circpad_negotiated_check(const circpad_negotiated_t *obj) 414 { 415 if (obj == NULL) 416 return "Object was NULL"; 417 if (obj->trunnel_error_code_) 418 return "A set function failed on this object"; 419 if (! (obj->version == 0)) 420 return "Integer out of bounds"; 421 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP)) 422 return "Integer out of bounds"; 423 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK)) 424 return "Integer out of bounds"; 425 return NULL; 426 } 427 428 ssize_t 429 circpad_negotiated_encoded_len(const circpad_negotiated_t *obj) 430 { 431 ssize_t result = 0; 432 433 if (NULL != circpad_negotiated_check(obj)) 434 return -1; 435 436 437 /* Length of u8 version IN [0] */ 438 result += 1; 439 440 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 441 result += 1; 442 443 /* Length of u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */ 444 result += 1; 445 446 /* Length of u8 machine_type */ 447 result += 1; 448 449 /* Length of u32 machine_ctr */ 450 result += 4; 451 return result; 452 } 453 int 454 circpad_negotiated_clear_errors(circpad_negotiated_t *obj) 455 { 456 int r = obj->trunnel_error_code_; 457 obj->trunnel_error_code_ = 0; 458 return r; 459 } 460 ssize_t 461 circpad_negotiated_encode(uint8_t *output, const size_t avail, const circpad_negotiated_t *obj) 462 { 463 ssize_t result = 0; 464 size_t written = 0; 465 uint8_t *ptr = output; 466 const char *msg; 467 #ifdef TRUNNEL_CHECK_ENCODED_LEN 468 const ssize_t encoded_len = circpad_negotiated_encoded_len(obj); 469 #endif 470 471 if (NULL != (msg = circpad_negotiated_check(obj))) 472 goto check_failed; 473 474 #ifdef TRUNNEL_CHECK_ENCODED_LEN 475 trunnel_assert(encoded_len >= 0); 476 #endif 477 478 /* Encode u8 version IN [0] */ 479 trunnel_assert(written <= avail); 480 if (avail - written < 1) 481 goto truncated; 482 trunnel_set_uint8(ptr, (obj->version)); 483 written += 1; ptr += 1; 484 485 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 486 trunnel_assert(written <= avail); 487 if (avail - written < 1) 488 goto truncated; 489 trunnel_set_uint8(ptr, (obj->command)); 490 written += 1; ptr += 1; 491 492 /* Encode u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */ 493 trunnel_assert(written <= avail); 494 if (avail - written < 1) 495 goto truncated; 496 trunnel_set_uint8(ptr, (obj->response)); 497 written += 1; ptr += 1; 498 499 /* Encode u8 machine_type */ 500 trunnel_assert(written <= avail); 501 if (avail - written < 1) 502 goto truncated; 503 trunnel_set_uint8(ptr, (obj->machine_type)); 504 written += 1; ptr += 1; 505 506 /* Encode u32 machine_ctr */ 507 trunnel_assert(written <= avail); 508 if (avail - written < 4) 509 goto truncated; 510 trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr)); 511 written += 4; ptr += 4; 512 513 514 trunnel_assert(ptr == output + written); 515 #ifdef TRUNNEL_CHECK_ENCODED_LEN 516 { 517 trunnel_assert(encoded_len >= 0); 518 trunnel_assert((size_t)encoded_len == written); 519 } 520 521 #endif 522 523 return written; 524 525 truncated: 526 result = -2; 527 goto fail; 528 check_failed: 529 (void)msg; 530 result = -1; 531 goto fail; 532 fail: 533 trunnel_assert(result < 0); 534 return result; 535 } 536 537 /** As circpad_negotiated_parse(), but do not allocate the output 538 * object. 539 */ 540 static ssize_t 541 circpad_negotiated_parse_into(circpad_negotiated_t *obj, const uint8_t *input, const size_t len_in) 542 { 543 const uint8_t *ptr = input; 544 size_t remaining = len_in; 545 ssize_t result = 0; 546 (void)result; 547 548 /* Parse u8 version IN [0] */ 549 CHECK_REMAINING(1, truncated); 550 obj->version = (trunnel_get_uint8(ptr)); 551 remaining -= 1; ptr += 1; 552 if (! (obj->version == 0)) 553 goto fail; 554 555 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */ 556 CHECK_REMAINING(1, truncated); 557 obj->command = (trunnel_get_uint8(ptr)); 558 remaining -= 1; ptr += 1; 559 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP)) 560 goto fail; 561 562 /* Parse u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */ 563 CHECK_REMAINING(1, truncated); 564 obj->response = (trunnel_get_uint8(ptr)); 565 remaining -= 1; ptr += 1; 566 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK)) 567 goto fail; 568 569 /* Parse u8 machine_type */ 570 CHECK_REMAINING(1, truncated); 571 obj->machine_type = (trunnel_get_uint8(ptr)); 572 remaining -= 1; ptr += 1; 573 574 /* Parse u32 machine_ctr */ 575 CHECK_REMAINING(4, truncated); 576 obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr)); 577 remaining -= 4; ptr += 4; 578 trunnel_assert(ptr + remaining == input + len_in); 579 return len_in - remaining; 580 581 truncated: 582 return -2; 583 fail: 584 result = -1; 585 return result; 586 } 587 588 ssize_t 589 circpad_negotiated_parse(circpad_negotiated_t **output, const uint8_t *input, const size_t len_in) 590 { 591 ssize_t result; 592 *output = circpad_negotiated_new(); 593 if (NULL == *output) 594 return -1; 595 result = circpad_negotiated_parse_into(*output, input, len_in); 596 if (result < 0) { 597 circpad_negotiated_free(*output); 598 *output = NULL; 599 } 600 return result; 601 }