1 /* Copyright (c) 2014, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #include <openssl/bytestring.h> 16 17 #include <assert.h> 18 #include <string.h> 19 20 #include <openssl/mem.h> 21 22 23 static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { 24 struct cbb_buffer_st *base; 25 26 base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); 27 if (base == NULL) { 28 return 0; 29 } 30 31 base->buf = buf; 32 base->len = 0; 33 base->cap = cap; 34 base->can_resize = 1; 35 36 memset(cbb, 0, sizeof(CBB)); 37 cbb->base = base; 38 cbb->is_top_level = 1; 39 return 1; 40 } 41 42 int CBB_init(CBB *cbb, size_t initial_capacity) { 43 uint8_t *buf; 44 45 buf = OPENSSL_malloc(initial_capacity); 46 if (initial_capacity > 0 && buf == NULL) { 47 return 0; 48 } 49 50 if (!cbb_init(cbb, buf, initial_capacity)) { 51 OPENSSL_free(buf); 52 return 0; 53 } 54 55 return 1; 56 } 57 58 int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { 59 if (!cbb_init(cbb, buf, len)) { 60 return 0; 61 } 62 63 cbb->base->can_resize = 0; 64 return 1; 65 } 66 67 void CBB_cleanup(CBB *cbb) { 68 if (cbb->base) { 69 if (cbb->base->can_resize) { 70 OPENSSL_free(cbb->base->buf); 71 } 72 OPENSSL_free(cbb->base); 73 } 74 cbb->base = NULL; 75 } 76 77 static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, 78 size_t len) { 79 size_t newlen; 80 81 if (base == NULL) { 82 return 0; 83 } 84 85 newlen = base->len + len; 86 if (newlen < base->len) { 87 /* Overflow */ 88 return 0; 89 } 90 91 if (newlen > base->cap) { 92 size_t newcap = base->cap * 2; 93 uint8_t *newbuf; 94 95 if (!base->can_resize) { 96 return 0; 97 } 98 99 if (newcap < base->cap || newcap < newlen) { 100 newcap = newlen; 101 } 102 newbuf = OPENSSL_realloc(base->buf, newcap); 103 if (newbuf == NULL) { 104 return 0; 105 } 106 107 base->buf = newbuf; 108 base->cap = newcap; 109 } 110 111 if (out) { 112 *out = base->buf + base->len; 113 } 114 base->len = newlen; 115 return 1; 116 } 117 118 static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, 119 size_t len_len) { 120 uint8_t *buf; 121 size_t i; 122 123 if (len_len == 0) { 124 return 1; 125 } 126 if (!cbb_buffer_add(base, &buf, len_len)) { 127 return 0; 128 } 129 130 for (i = len_len - 1; i < len_len; i--) { 131 buf[i] = v; 132 v >>= 8; 133 } 134 return 1; 135 } 136 137 int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { 138 if (!cbb->is_top_level) { 139 return 0; 140 } 141 142 if (!CBB_flush(cbb)) { 143 return 0; 144 } 145 146 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { 147 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */ 148 return 0; 149 } 150 151 if (out_data != NULL) { 152 *out_data = cbb->base->buf; 153 } 154 if (out_len != NULL) { 155 *out_len = cbb->base->len; 156 } 157 cbb->base->buf = NULL; 158 CBB_cleanup(cbb); 159 return 1; 160 } 161 162 /* CBB_flush recurses and then writes out any pending length prefix. The 163 * current length of the underlying base is taken to be the length of the 164 * length-prefixed data. */ 165 int CBB_flush(CBB *cbb) { 166 size_t child_start, i, len; 167 168 if (cbb->base == NULL) { 169 return 0; 170 } 171 172 if (cbb->child == NULL || cbb->pending_len_len == 0) { 173 return 1; 174 } 175 176 child_start = cbb->offset + cbb->pending_len_len; 177 178 if (!CBB_flush(cbb->child) || 179 child_start < cbb->offset || 180 cbb->base->len < child_start) { 181 return 0; 182 } 183 184 len = cbb->base->len - child_start; 185 186 if (cbb->pending_is_asn1) { 187 /* For ASN.1 we assume that we'll only need a single byte for the length. 188 * If that turned out to be incorrect, we have to move the contents along 189 * in order to make space. */ 190 size_t len_len; 191 uint8_t initial_length_byte; 192 193 assert (cbb->pending_len_len == 1); 194 195 if (len > 0xfffffffe) { 196 /* Too large. */ 197 return 0; 198 } else if (len > 0xffffff) { 199 len_len = 5; 200 initial_length_byte = 0x80 | 4; 201 } else if (len > 0xffff) { 202 len_len = 4; 203 initial_length_byte = 0x80 | 3; 204 } else if (len > 0xff) { 205 len_len = 3; 206 initial_length_byte = 0x80 | 2; 207 } else if (len > 0x7f) { 208 len_len = 2; 209 initial_length_byte = 0x80 | 1; 210 } else { 211 len_len = 1; 212 initial_length_byte = len; 213 len = 0; 214 } 215 216 if (len_len != 1) { 217 /* We need to move the contents along in order to make space. */ 218 size_t extra_bytes = len_len - 1; 219 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { 220 return 0; 221 } 222 memmove(cbb->base->buf + child_start + extra_bytes, 223 cbb->base->buf + child_start, len); 224 } 225 cbb->base->buf[cbb->offset++] = initial_length_byte; 226 cbb->pending_len_len = len_len - 1; 227 } 228 229 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { 230 cbb->base->buf[cbb->offset + i] = len; 231 len >>= 8; 232 } 233 if (len != 0) { 234 return 0; 235 } 236 237 cbb->child->base = NULL; 238 cbb->child = NULL; 239 cbb->pending_len_len = 0; 240 cbb->pending_is_asn1 = 0; 241 cbb->offset = 0; 242 243 return 1; 244 } 245 246 247 static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, 248 size_t len_len) { 249 uint8_t *prefix_bytes; 250 251 if (!CBB_flush(cbb)) { 252 return 0; 253 } 254 255 cbb->offset = cbb->base->len; 256 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { 257 return 0; 258 } 259 260 memset(prefix_bytes, 0, len_len); 261 memset(out_contents, 0, sizeof(CBB)); 262 out_contents->base = cbb->base; 263 cbb->child = out_contents; 264 cbb->pending_len_len = len_len; 265 cbb->pending_is_asn1 = 0; 266 267 return 1; 268 } 269 270 int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { 271 return cbb_add_length_prefixed(cbb, out_contents, 1); 272 } 273 274 int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { 275 return cbb_add_length_prefixed(cbb, out_contents, 2); 276 } 277 278 int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { 279 return cbb_add_length_prefixed(cbb, out_contents, 3); 280 } 281 282 int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) { 283 if ((tag & 0x1f) == 0x1f) { 284 /* Long form identifier octets are not supported. */ 285 return 0; 286 } 287 288 if (!CBB_flush(cbb) || 289 !CBB_add_u8(cbb, tag)) { 290 return 0; 291 } 292 293 cbb->offset = cbb->base->len; 294 if (!CBB_add_u8(cbb, 0)) { 295 return 0; 296 } 297 298 memset(out_contents, 0, sizeof(CBB)); 299 out_contents->base = cbb->base; 300 cbb->child = out_contents; 301 cbb->pending_len_len = 1; 302 cbb->pending_is_asn1 = 1; 303 304 return 1; 305 } 306 307 int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { 308 uint8_t *dest; 309 310 if (!CBB_flush(cbb) || 311 !cbb_buffer_add(cbb->base, &dest, len)) { 312 return 0; 313 } 314 memcpy(dest, data, len); 315 return 1; 316 } 317 318 int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { 319 if (!CBB_flush(cbb) || 320 !cbb_buffer_add(cbb->base, out_data, len)) { 321 return 0; 322 } 323 return 1; 324 } 325 326 int CBB_add_u8(CBB *cbb, uint8_t value) { 327 if (!CBB_flush(cbb)) { 328 return 0; 329 } 330 331 return cbb_buffer_add_u(cbb->base, value, 1); 332 } 333 334 int CBB_add_u16(CBB *cbb, uint16_t value) { 335 if (!CBB_flush(cbb)) { 336 return 0; 337 } 338 339 return cbb_buffer_add_u(cbb->base, value, 2); 340 } 341 342 int CBB_add_u24(CBB *cbb, uint32_t value) { 343 if (!CBB_flush(cbb)) { 344 return 0; 345 } 346 347 return cbb_buffer_add_u(cbb->base, value, 3); 348 } 349 350 int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { 351 CBB child; 352 size_t i; 353 int started = 0; 354 355 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { 356 return 0; 357 } 358 359 for (i = 0; i < 8; i++) { 360 uint8_t byte = (value >> 8*(7-i)) & 0xff; 361 if (!started) { 362 if (byte == 0) { 363 /* Don't encode leading zeros. */ 364 continue; 365 } 366 /* If the high bit is set, add a padding byte to make it 367 * unsigned. */ 368 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { 369 return 0; 370 } 371 started = 1; 372 } 373 if (!CBB_add_u8(&child, byte)) { 374 return 0; 375 } 376 } 377 378 /* 0 is encoded as a single 0, not the empty string. */ 379 if (!started && !CBB_add_u8(&child, 0)) { 380 return 0; 381 } 382 383 return CBB_flush(cbb); 384 } 385