1 /* $OpenBSD: bs_cbb.c,v 1.19 2018/08/16 18:39:37 jsing Exp $ */ 2 /* 3 * Copyright (c) 2014, Google Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 16 17 #include <assert.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #include <openssl/opensslconf.h> 22 23 #include "bytestring.h" 24 25 #define CBB_INITIAL_SIZE 64 26 27 static int 28 cbb_init(CBB *cbb, uint8_t *buf, size_t cap) 29 { 30 struct cbb_buffer_st *base; 31 32 base = malloc(sizeof(struct cbb_buffer_st)); 33 if (base == NULL) 34 return 0; 35 36 base->buf = buf; 37 base->len = 0; 38 base->cap = cap; 39 base->can_resize = 1; 40 41 cbb->base = base; 42 cbb->is_top_level = 1; 43 44 return 1; 45 } 46 47 int 48 CBB_init(CBB *cbb, size_t initial_capacity) 49 { 50 uint8_t *buf = NULL; 51 52 memset(cbb, 0, sizeof(*cbb)); 53 54 if (initial_capacity == 0) 55 initial_capacity = CBB_INITIAL_SIZE; 56 57 if ((buf = malloc(initial_capacity)) == NULL) 58 return 0; 59 60 if (!cbb_init(cbb, buf, initial_capacity)) { 61 free(buf); 62 return 0; 63 } 64 65 return 1; 66 } 67 68 int 69 CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) 70 { 71 memset(cbb, 0, sizeof(*cbb)); 72 73 if (!cbb_init(cbb, buf, len)) 74 return 0; 75 76 cbb->base->can_resize = 0; 77 78 return 1; 79 } 80 81 void 82 CBB_cleanup(CBB *cbb) 83 { 84 if (cbb->base) { 85 if (cbb->base->can_resize) 86 freezero(cbb->base->buf, cbb->base->cap); 87 free(cbb->base); 88 } 89 cbb->base = NULL; 90 cbb->child = NULL; 91 } 92 93 static int 94 cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len) 95 { 96 size_t newlen; 97 98 if (base == NULL) 99 return 0; 100 101 newlen = base->len + len; 102 if (newlen < base->len) 103 /* Overflow */ 104 return 0; 105 106 if (newlen > base->cap) { 107 size_t newcap = base->cap * 2; 108 uint8_t *newbuf; 109 110 if (!base->can_resize) 111 return 0; 112 113 if (newcap < base->cap || newcap < newlen) 114 newcap = newlen; 115 116 newbuf = recallocarray(base->buf, base->cap, newcap, 1); 117 if (newbuf == NULL) 118 return 0; 119 120 base->buf = newbuf; 121 base->cap = newcap; 122 } 123 124 if (out) 125 *out = base->buf + base->len; 126 127 base->len = newlen; 128 return 1; 129 } 130 131 static int 132 cbb_add_u(CBB *cbb, uint32_t v, size_t len_len) 133 { 134 uint8_t *buf; 135 size_t i; 136 137 if (len_len == 0) 138 return 1; 139 140 if (len_len > 4) 141 return 0; 142 143 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len)) 144 return 0; 145 146 for (i = len_len - 1; i < len_len; i--) { 147 buf[i] = v; 148 v >>= 8; 149 } 150 return 1; 151 } 152 153 int 154 CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) 155 { 156 if (!cbb->is_top_level) 157 return 0; 158 159 if (!CBB_flush(cbb)) 160 return 0; 161 162 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) 163 /* 164 * |out_data| and |out_len| can only be NULL if the CBB is 165 * fixed. 166 */ 167 return 0; 168 169 if (out_data != NULL) 170 *out_data = cbb->base->buf; 171 172 if (out_len != NULL) 173 *out_len = cbb->base->len; 174 175 cbb->base->buf = NULL; 176 CBB_cleanup(cbb); 177 return 1; 178 } 179 180 /* 181 * CBB_flush recurses and then writes out any pending length prefix. The current 182 * length of the underlying base is taken to be the length of the 183 * length-prefixed data. 184 */ 185 int 186 CBB_flush(CBB *cbb) 187 { 188 size_t child_start, i, len; 189 190 if (cbb->base == NULL) 191 return 0; 192 193 if (cbb->child == NULL || cbb->pending_len_len == 0) 194 return 1; 195 196 child_start = cbb->offset + cbb->pending_len_len; 197 198 if (!CBB_flush(cbb->child) || child_start < cbb->offset || 199 cbb->base->len < child_start) 200 return 0; 201 202 len = cbb->base->len - child_start; 203 204 if (cbb->pending_is_asn1) { 205 /* 206 * For ASN.1, we assumed that we were using short form which 207 * only requires a single byte for the length octet. 208 * 209 * If it turns out that we need long form, we have to move 210 * the contents along in order to make space for more length 211 * octets. 212 */ 213 size_t len_len = 1; /* total number of length octets */ 214 uint8_t initial_length_byte; 215 216 /* We already wrote 1 byte for the length. */ 217 assert (cbb->pending_len_len == 1); 218 219 /* Check for long form */ 220 if (len > 0xfffffffe) 221 return 0; /* 0xffffffff is reserved */ 222 else if (len > 0xffffff) 223 len_len = 5; 224 else if (len > 0xffff) 225 len_len = 4; 226 else if (len > 0xff) 227 len_len = 3; 228 else if (len > 0x7f) 229 len_len = 2; 230 231 if (len_len == 1) { 232 /* For short form, the initial byte is the length. */ 233 initial_length_byte = len; 234 len = 0; 235 236 } else { 237 /* 238 * For long form, the initial byte is the number of 239 * subsequent length octets (plus bit 8 set). 240 */ 241 initial_length_byte = 0x80 | (len_len - 1); 242 243 /* 244 * We need to move the contents along in order to make 245 * space for the long form length octets. 246 */ 247 size_t extra_bytes = len_len - 1; 248 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) 249 return 0; 250 251 memmove(cbb->base->buf + child_start + extra_bytes, 252 cbb->base->buf + child_start, len); 253 } 254 cbb->base->buf[cbb->offset++] = initial_length_byte; 255 cbb->pending_len_len = len_len - 1; 256 } 257 258 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { 259 cbb->base->buf[cbb->offset + i] = len; 260 len >>= 8; 261 } 262 if (len != 0) 263 return 0; 264 265 cbb->child->base = NULL; 266 cbb->child = NULL; 267 cbb->pending_len_len = 0; 268 cbb->pending_is_asn1 = 0; 269 cbb->offset = 0; 270 271 return 1; 272 } 273 274 void 275 CBB_discard_child(CBB *cbb) 276 { 277 if (cbb->child == NULL) 278 return; 279 280 cbb->base->len = cbb->offset; 281 282 cbb->child->base = NULL; 283 cbb->child = NULL; 284 cbb->pending_len_len = 0; 285 cbb->pending_is_asn1 = 0; 286 cbb->offset = 0; 287 } 288 289 static int 290 cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len) 291 { 292 uint8_t *prefix_bytes; 293 294 if (!CBB_flush(cbb)) 295 return 0; 296 297 cbb->offset = cbb->base->len; 298 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) 299 return 0; 300 301 memset(prefix_bytes, 0, len_len); 302 memset(out_contents, 0, sizeof(CBB)); 303 out_contents->base = cbb->base; 304 cbb->child = out_contents; 305 cbb->pending_len_len = len_len; 306 cbb->pending_is_asn1 = 0; 307 308 return 1; 309 } 310 311 int 312 CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) 313 { 314 return cbb_add_length_prefixed(cbb, out_contents, 1); 315 } 316 317 int 318 CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) 319 { 320 return cbb_add_length_prefixed(cbb, out_contents, 2); 321 } 322 323 int 324 CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) 325 { 326 return cbb_add_length_prefixed(cbb, out_contents, 3); 327 } 328 329 int 330 CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag) 331 { 332 if (tag > UINT8_MAX) 333 return 0; 334 335 /* Long form identifier octets are not supported. */ 336 if ((tag & 0x1f) == 0x1f) 337 return 0; 338 339 /* Short-form identifier octet only needs a single byte */ 340 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) 341 return 0; 342 343 /* 344 * Add 1 byte to cover the short-form length octet case. If it turns 345 * out we need long-form, it will be extended later. 346 */ 347 cbb->offset = cbb->base->len; 348 if (!CBB_add_u8(cbb, 0)) 349 return 0; 350 351 memset(out_contents, 0, sizeof(CBB)); 352 out_contents->base = cbb->base; 353 cbb->child = out_contents; 354 cbb->pending_len_len = 1; 355 cbb->pending_is_asn1 = 1; 356 357 return 1; 358 } 359 360 int 361 CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) 362 { 363 uint8_t *dest; 364 365 if (!CBB_add_space(cbb, &dest, len)) 366 return 0; 367 368 memcpy(dest, data, len); 369 return 1; 370 } 371 372 int 373 CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) 374 { 375 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len)) 376 return 0; 377 378 return 1; 379 } 380 381 int 382 CBB_add_u8(CBB *cbb, size_t value) 383 { 384 if (value > UINT8_MAX) 385 return 0; 386 387 return cbb_add_u(cbb, (uint32_t)value, 1); 388 } 389 390 int 391 CBB_add_u16(CBB *cbb, size_t value) 392 { 393 if (value > UINT16_MAX) 394 return 0; 395 396 return cbb_add_u(cbb, (uint32_t)value, 2); 397 } 398 399 int 400 CBB_add_u24(CBB *cbb, size_t value) 401 { 402 if (value > 0xffffffUL) 403 return 0; 404 405 return cbb_add_u(cbb, (uint32_t)value, 3); 406 } 407 408 int 409 CBB_add_u32(CBB *cbb, size_t value) 410 { 411 if (value > 0xffffffffUL) 412 return 0; 413 414 return cbb_add_u(cbb, (uint32_t)value, 4); 415 } 416 417 int 418 CBB_add_asn1_uint64(CBB *cbb, uint64_t value) 419 { 420 CBB child; 421 size_t i; 422 int started = 0; 423 424 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) 425 return 0; 426 427 for (i = 0; i < 8; i++) { 428 uint8_t byte = (value >> 8 * (7 - i)) & 0xff; 429 430 /* 431 * ASN.1 restriction: first 9 bits cannot be all zeroes or 432 * all ones. Since this function only encodes unsigned 433 * integers, the only concerns are not encoding leading 434 * zeros and adding a padding byte if necessary. 435 * 436 * In practice, this means: 437 * 1) Skip leading octets of all zero bits in the value 438 * 2) After skipping the leading zero octets, if the next 9 439 * bits are all ones, add an all zero prefix octet (and 440 * set the high bit of the prefix octet if negative). 441 * 442 * Additionally, for an unsigned value, add an all zero 443 * prefix if the high bit of the first octet would be one. 444 */ 445 if (!started) { 446 if (byte == 0) 447 /* Don't encode leading zeros. */ 448 continue; 449 450 /* 451 * If the high bit is set, add a padding byte to make it 452 * unsigned. 453 */ 454 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) 455 return 0; 456 457 started = 1; 458 } 459 if (!CBB_add_u8(&child, byte)) 460 return 0; 461 } 462 463 /* 0 is encoded as a single 0, not the empty string. */ 464 if (!started && !CBB_add_u8(&child, 0)) 465 return 0; 466 467 return CBB_flush(cbb); 468 } 469