Line data Source code
1 : /* channelpadding_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 "channelpadding_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 channelpaddingnegotiation_deadcode_dummy__ = 0; 19 : #define OR_DEADCODE_DUMMY || channelpaddingnegotiation_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 : channelpadding_negotiate_t * 32 10 : channelpadding_negotiate_new(void) 33 : { 34 10 : channelpadding_negotiate_t *val = trunnel_calloc(1, sizeof(channelpadding_negotiate_t)); 35 10 : if (NULL == val) 36 : return NULL; 37 10 : val->command = CHANNELPADDING_COMMAND_START; 38 10 : return val; 39 : } 40 : 41 : /** Release all storage held inside 'obj', but do not free 'obj'. 42 : */ 43 : static void 44 : channelpadding_negotiate_clear(channelpadding_negotiate_t *obj) 45 : { 46 : (void) obj; 47 : } 48 : 49 : void 50 10 : channelpadding_negotiate_free(channelpadding_negotiate_t *obj) 51 : { 52 10 : if (obj == NULL) 53 : return; 54 10 : channelpadding_negotiate_clear(obj); 55 10 : trunnel_memwipe(obj, sizeof(channelpadding_negotiate_t)); 56 10 : trunnel_free_(obj); 57 : } 58 : 59 : uint8_t 60 0 : channelpadding_negotiate_get_version(const channelpadding_negotiate_t *inp) 61 : { 62 0 : return inp->version; 63 : } 64 : int 65 0 : channelpadding_negotiate_set_version(channelpadding_negotiate_t *inp, uint8_t val) 66 : { 67 0 : if (! ((val == 0))) { 68 0 : TRUNNEL_SET_ERROR_CODE(inp); 69 0 : return -1; 70 : } 71 0 : inp->version = val; 72 0 : return 0; 73 : } 74 : uint8_t 75 0 : channelpadding_negotiate_get_command(const channelpadding_negotiate_t *inp) 76 : { 77 0 : return inp->command; 78 : } 79 : int 80 9 : channelpadding_negotiate_set_command(channelpadding_negotiate_t *inp, uint8_t val) 81 : { 82 9 : if (! ((val == CHANNELPADDING_COMMAND_START || val == CHANNELPADDING_COMMAND_STOP))) { 83 0 : TRUNNEL_SET_ERROR_CODE(inp); 84 0 : return -1; 85 : } 86 9 : inp->command = val; 87 9 : return 0; 88 : } 89 : uint16_t 90 0 : channelpadding_negotiate_get_ito_low_ms(const channelpadding_negotiate_t *inp) 91 : { 92 0 : return inp->ito_low_ms; 93 : } 94 : int 95 2 : channelpadding_negotiate_set_ito_low_ms(channelpadding_negotiate_t *inp, uint16_t val) 96 : { 97 2 : inp->ito_low_ms = val; 98 2 : return 0; 99 : } 100 : uint16_t 101 0 : channelpadding_negotiate_get_ito_high_ms(const channelpadding_negotiate_t *inp) 102 : { 103 0 : return inp->ito_high_ms; 104 : } 105 : int 106 2 : channelpadding_negotiate_set_ito_high_ms(channelpadding_negotiate_t *inp, uint16_t val) 107 : { 108 2 : inp->ito_high_ms = val; 109 2 : return 0; 110 : } 111 : const char * 112 10 : channelpadding_negotiate_check(const channelpadding_negotiate_t *obj) 113 : { 114 10 : if (obj == NULL) 115 : return "Object was NULL"; 116 10 : if (obj->trunnel_error_code_) 117 : return "A set function failed on this object"; 118 10 : if (! (obj->version == 0)) 119 : return "Integer out of bounds"; 120 9 : if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP)) 121 0 : return "Integer out of bounds"; 122 : return NULL; 123 : } 124 : 125 : ssize_t 126 0 : channelpadding_negotiate_encoded_len(const channelpadding_negotiate_t *obj) 127 : { 128 0 : ssize_t result = 0; 129 : 130 0 : if (NULL != channelpadding_negotiate_check(obj)) 131 0 : return -1; 132 : 133 : 134 : /* Length of u8 version IN [0] */ 135 : result += 1; 136 : 137 : /* Length of u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */ 138 : result += 1; 139 : 140 : /* Length of u16 ito_low_ms */ 141 : result += 2; 142 : 143 : /* Length of u16 ito_high_ms */ 144 0 : result += 2; 145 : return result; 146 : } 147 : int 148 0 : channelpadding_negotiate_clear_errors(channelpadding_negotiate_t *obj) 149 : { 150 0 : int r = obj->trunnel_error_code_; 151 0 : obj->trunnel_error_code_ = 0; 152 0 : return r; 153 : } 154 : ssize_t 155 10 : channelpadding_negotiate_encode(uint8_t *output, const size_t avail, const channelpadding_negotiate_t *obj) 156 : { 157 10 : ssize_t result = 0; 158 10 : size_t written = 0; 159 10 : uint8_t *ptr = output; 160 10 : const char *msg; 161 : #ifdef TRUNNEL_CHECK_ENCODED_LEN 162 : const ssize_t encoded_len = channelpadding_negotiate_encoded_len(obj); 163 : #endif 164 : 165 10 : if (NULL != (msg = channelpadding_negotiate_check(obj))) 166 1 : goto check_failed; 167 : 168 : #ifdef TRUNNEL_CHECK_ENCODED_LEN 169 : trunnel_assert(encoded_len >= 0); 170 : #endif 171 : 172 : /* Encode u8 version IN [0] */ 173 9 : trunnel_assert(written <= avail); 174 9 : if (avail - written < 1) 175 0 : goto truncated; 176 9 : trunnel_set_uint8(ptr, (obj->version)); 177 9 : written += 1; ptr += 1; 178 : 179 : /* Encode u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */ 180 9 : trunnel_assert(written <= avail); 181 9 : if (avail - written < 1) 182 0 : goto truncated; 183 9 : trunnel_set_uint8(ptr, (obj->command)); 184 9 : written += 1; ptr += 1; 185 : 186 : /* Encode u16 ito_low_ms */ 187 9 : trunnel_assert(written <= avail); 188 9 : if (avail - written < 2) 189 0 : goto truncated; 190 9 : trunnel_set_uint16(ptr, trunnel_htons(obj->ito_low_ms)); 191 9 : written += 2; ptr += 2; 192 : 193 : /* Encode u16 ito_high_ms */ 194 9 : trunnel_assert(written <= avail); 195 9 : if (avail - written < 2) 196 0 : goto truncated; 197 9 : trunnel_set_uint16(ptr, trunnel_htons(obj->ito_high_ms)); 198 9 : written += 2; ptr += 2; 199 : 200 : 201 9 : trunnel_assert(ptr == output + written); 202 : #ifdef TRUNNEL_CHECK_ENCODED_LEN 203 : { 204 : trunnel_assert(encoded_len >= 0); 205 : trunnel_assert((size_t)encoded_len == written); 206 : } 207 : 208 : #endif 209 : 210 : return written; 211 : 212 0 : truncated: 213 0 : result = -2; 214 0 : goto fail; 215 1 : check_failed: 216 1 : (void)msg; 217 1 : result = -1; 218 1 : goto fail; 219 : fail: 220 : trunnel_assert(result < 0); 221 : return result; 222 : } 223 : 224 : /** As channelpadding_negotiate_parse(), but do not allocate the 225 : * output object. 226 : */ 227 : static ssize_t 228 10 : channelpadding_negotiate_parse_into(channelpadding_negotiate_t *obj, const uint8_t *input, const size_t len_in) 229 : { 230 10 : const uint8_t *ptr = input; 231 10 : size_t remaining = len_in; 232 10 : ssize_t result = 0; 233 10 : (void)result; 234 : 235 : /* Parse u8 version IN [0] */ 236 10 : CHECK_REMAINING(1, truncated); 237 10 : obj->version = (trunnel_get_uint8(ptr)); 238 10 : remaining -= 1; ptr += 1; 239 10 : if (! (obj->version == 0)) 240 0 : goto fail; 241 : 242 : /* Parse u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */ 243 10 : CHECK_REMAINING(1, truncated); 244 10 : obj->command = (trunnel_get_uint8(ptr)); 245 10 : remaining -= 1; ptr += 1; 246 10 : if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP)) 247 1 : goto fail; 248 : 249 : /* Parse u16 ito_low_ms */ 250 9 : CHECK_REMAINING(2, truncated); 251 9 : obj->ito_low_ms = trunnel_ntohs(trunnel_get_uint16(ptr)); 252 9 : remaining -= 2; ptr += 2; 253 : 254 : /* Parse u16 ito_high_ms */ 255 9 : CHECK_REMAINING(2, truncated); 256 9 : obj->ito_high_ms = trunnel_ntohs(trunnel_get_uint16(ptr)); 257 9 : remaining -= 2; ptr += 2; 258 9 : trunnel_assert(ptr + remaining == input + len_in); 259 : return len_in - remaining; 260 : 261 : truncated: 262 : return -2; 263 : fail: 264 10 : result = -1; 265 : return result; 266 : } 267 : 268 : ssize_t 269 10 : channelpadding_negotiate_parse(channelpadding_negotiate_t **output, const uint8_t *input, const size_t len_in) 270 : { 271 10 : ssize_t result; 272 10 : *output = channelpadding_negotiate_new(); 273 10 : if (NULL == *output) 274 : return -1; 275 10 : result = channelpadding_negotiate_parse_into(*output, input, len_in); 276 10 : if (result < 0) { 277 1 : channelpadding_negotiate_free(*output); 278 1 : *output = NULL; 279 : } 280 : return result; 281 : }