channelpadding_negotiation.c (7295B)
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 channelpadding_negotiate_new(void) 33 { 34 channelpadding_negotiate_t *val = trunnel_calloc(1, sizeof(channelpadding_negotiate_t)); 35 if (NULL == val) 36 return NULL; 37 val->command = CHANNELPADDING_COMMAND_START; 38 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 channelpadding_negotiate_free(channelpadding_negotiate_t *obj) 51 { 52 if (obj == NULL) 53 return; 54 channelpadding_negotiate_clear(obj); 55 trunnel_memwipe(obj, sizeof(channelpadding_negotiate_t)); 56 trunnel_free_(obj); 57 } 58 59 uint8_t 60 channelpadding_negotiate_get_version(const channelpadding_negotiate_t *inp) 61 { 62 return inp->version; 63 } 64 int 65 channelpadding_negotiate_set_version(channelpadding_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 channelpadding_negotiate_get_command(const channelpadding_negotiate_t *inp) 76 { 77 return inp->command; 78 } 79 int 80 channelpadding_negotiate_set_command(channelpadding_negotiate_t *inp, uint8_t val) 81 { 82 if (! ((val == CHANNELPADDING_COMMAND_START || val == CHANNELPADDING_COMMAND_STOP))) { 83 TRUNNEL_SET_ERROR_CODE(inp); 84 return -1; 85 } 86 inp->command = val; 87 return 0; 88 } 89 uint16_t 90 channelpadding_negotiate_get_ito_low_ms(const channelpadding_negotiate_t *inp) 91 { 92 return inp->ito_low_ms; 93 } 94 int 95 channelpadding_negotiate_set_ito_low_ms(channelpadding_negotiate_t *inp, uint16_t val) 96 { 97 inp->ito_low_ms = val; 98 return 0; 99 } 100 uint16_t 101 channelpadding_negotiate_get_ito_high_ms(const channelpadding_negotiate_t *inp) 102 { 103 return inp->ito_high_ms; 104 } 105 int 106 channelpadding_negotiate_set_ito_high_ms(channelpadding_negotiate_t *inp, uint16_t val) 107 { 108 inp->ito_high_ms = val; 109 return 0; 110 } 111 const char * 112 channelpadding_negotiate_check(const channelpadding_negotiate_t *obj) 113 { 114 if (obj == NULL) 115 return "Object was NULL"; 116 if (obj->trunnel_error_code_) 117 return "A set function failed on this object"; 118 if (! (obj->version == 0)) 119 return "Integer out of bounds"; 120 if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP)) 121 return "Integer out of bounds"; 122 return NULL; 123 } 124 125 ssize_t 126 channelpadding_negotiate_encoded_len(const channelpadding_negotiate_t *obj) 127 { 128 ssize_t result = 0; 129 130 if (NULL != channelpadding_negotiate_check(obj)) 131 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 result += 2; 145 return result; 146 } 147 int 148 channelpadding_negotiate_clear_errors(channelpadding_negotiate_t *obj) 149 { 150 int r = obj->trunnel_error_code_; 151 obj->trunnel_error_code_ = 0; 152 return r; 153 } 154 ssize_t 155 channelpadding_negotiate_encode(uint8_t *output, const size_t avail, const channelpadding_negotiate_t *obj) 156 { 157 ssize_t result = 0; 158 size_t written = 0; 159 uint8_t *ptr = output; 160 const char *msg; 161 #ifdef TRUNNEL_CHECK_ENCODED_LEN 162 const ssize_t encoded_len = channelpadding_negotiate_encoded_len(obj); 163 #endif 164 165 if (NULL != (msg = channelpadding_negotiate_check(obj))) 166 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 trunnel_assert(written <= avail); 174 if (avail - written < 1) 175 goto truncated; 176 trunnel_set_uint8(ptr, (obj->version)); 177 written += 1; ptr += 1; 178 179 /* Encode u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */ 180 trunnel_assert(written <= avail); 181 if (avail - written < 1) 182 goto truncated; 183 trunnel_set_uint8(ptr, (obj->command)); 184 written += 1; ptr += 1; 185 186 /* Encode u16 ito_low_ms */ 187 trunnel_assert(written <= avail); 188 if (avail - written < 2) 189 goto truncated; 190 trunnel_set_uint16(ptr, trunnel_htons(obj->ito_low_ms)); 191 written += 2; ptr += 2; 192 193 /* Encode u16 ito_high_ms */ 194 trunnel_assert(written <= avail); 195 if (avail - written < 2) 196 goto truncated; 197 trunnel_set_uint16(ptr, trunnel_htons(obj->ito_high_ms)); 198 written += 2; ptr += 2; 199 200 201 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 truncated: 213 result = -2; 214 goto fail; 215 check_failed: 216 (void)msg; 217 result = -1; 218 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 channelpadding_negotiate_parse_into(channelpadding_negotiate_t *obj, const uint8_t *input, const size_t len_in) 229 { 230 const uint8_t *ptr = input; 231 size_t remaining = len_in; 232 ssize_t result = 0; 233 (void)result; 234 235 /* Parse u8 version IN [0] */ 236 CHECK_REMAINING(1, truncated); 237 obj->version = (trunnel_get_uint8(ptr)); 238 remaining -= 1; ptr += 1; 239 if (! (obj->version == 0)) 240 goto fail; 241 242 /* Parse u8 command IN [CHANNELPADDING_COMMAND_START, CHANNELPADDING_COMMAND_STOP] */ 243 CHECK_REMAINING(1, truncated); 244 obj->command = (trunnel_get_uint8(ptr)); 245 remaining -= 1; ptr += 1; 246 if (! (obj->command == CHANNELPADDING_COMMAND_START || obj->command == CHANNELPADDING_COMMAND_STOP)) 247 goto fail; 248 249 /* Parse u16 ito_low_ms */ 250 CHECK_REMAINING(2, truncated); 251 obj->ito_low_ms = trunnel_ntohs(trunnel_get_uint16(ptr)); 252 remaining -= 2; ptr += 2; 253 254 /* Parse u16 ito_high_ms */ 255 CHECK_REMAINING(2, truncated); 256 obj->ito_high_ms = trunnel_ntohs(trunnel_get_uint16(ptr)); 257 remaining -= 2; ptr += 2; 258 trunnel_assert(ptr + remaining == input + len_in); 259 return len_in - remaining; 260 261 truncated: 262 return -2; 263 fail: 264 result = -1; 265 return result; 266 } 267 268 ssize_t 269 channelpadding_negotiate_parse(channelpadding_negotiate_t **output, const uint8_t *input, const size_t len_in) 270 { 271 ssize_t result; 272 *output = channelpadding_negotiate_new(); 273 if (NULL == *output) 274 return -1; 275 result = channelpadding_negotiate_parse_into(*output, input, len_in); 276 if (result < 0) { 277 channelpadding_negotiate_free(*output); 278 *output = NULL; 279 } 280 return result; 281 }