1 /* $OpenBSD: bs_cbs.c,v 1.18 2019/01/23 22:20:40 beck 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 <stdlib.h> 18 #include <string.h> 19 20 #include <openssl/opensslconf.h> 21 #include <openssl/buffer.h> 22 #include <openssl/crypto.h> 23 24 #include "bytestring.h" 25 26 void 27 CBS_init(CBS *cbs, const uint8_t *data, size_t len) 28 { 29 cbs->data = data; 30 cbs->initial_len = len; 31 cbs->len = len; 32 } 33 34 void 35 CBS_dup(const CBS *cbs, CBS *out) 36 { 37 CBS_init(out, CBS_data(cbs), CBS_len(cbs)); 38 out->initial_len = cbs->initial_len; 39 } 40 41 static int 42 cbs_get(CBS *cbs, const uint8_t **p, size_t n) 43 { 44 if (cbs->len < n) 45 return 0; 46 47 *p = cbs->data; 48 cbs->data += n; 49 cbs->len -= n; 50 return 1; 51 } 52 53 size_t 54 CBS_offset(const CBS *cbs) 55 { 56 return cbs->initial_len - cbs->len; 57 } 58 59 int 60 CBS_skip(CBS *cbs, size_t len) 61 { 62 const uint8_t *dummy; 63 return cbs_get(cbs, &dummy, len); 64 } 65 66 const uint8_t * 67 CBS_data(const CBS *cbs) 68 { 69 return cbs->data; 70 } 71 72 size_t 73 CBS_len(const CBS *cbs) 74 { 75 return cbs->len; 76 } 77 78 int 79 CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) 80 { 81 free(*out_ptr); 82 *out_ptr = NULL; 83 *out_len = 0; 84 85 if (cbs->len == 0) 86 return 1; 87 88 if ((*out_ptr = malloc(cbs->len)) == NULL) 89 return 0; 90 91 memcpy(*out_ptr, cbs->data, cbs->len); 92 93 *out_len = cbs->len; 94 return 1; 95 } 96 97 int 98 CBS_strdup(const CBS *cbs, char **out_ptr) 99 { 100 free(*out_ptr); 101 *out_ptr = strndup((const char *)cbs->data, cbs->len); 102 return (*out_ptr != NULL); 103 } 104 105 int 106 CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied) 107 { 108 if (dst_len < cbs->len) 109 return 0; 110 111 memmove(dst, cbs->data, cbs->len); 112 113 if (copied != NULL) 114 *copied = cbs->len; 115 116 return 1; 117 } 118 119 int 120 CBS_contains_zero_byte(const CBS *cbs) 121 { 122 return memchr(cbs->data, 0, cbs->len) != NULL; 123 } 124 125 int 126 CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) 127 { 128 if (len != cbs->len) 129 return 0; 130 131 return timingsafe_memcmp(cbs->data, data, len) == 0; 132 } 133 134 static int 135 cbs_get_u(CBS *cbs, uint32_t *out, size_t len) 136 { 137 uint32_t result = 0; 138 size_t i; 139 const uint8_t *data; 140 141 if (len < 1 || len > 4) 142 return 0; 143 144 if (!cbs_get(cbs, &data, len)) 145 return 0; 146 147 for (i = 0; i < len; i++) { 148 result <<= 8; 149 result |= data[i]; 150 } 151 *out = result; 152 return 1; 153 } 154 155 int 156 CBS_get_u8(CBS *cbs, uint8_t *out) 157 { 158 const uint8_t *v; 159 160 if (!cbs_get(cbs, &v, 1)) 161 return 0; 162 163 *out = *v; 164 return 1; 165 } 166 167 int 168 CBS_get_u16(CBS *cbs, uint16_t *out) 169 { 170 uint32_t v; 171 172 if (!cbs_get_u(cbs, &v, 2)) 173 return 0; 174 175 *out = v; 176 return 1; 177 } 178 179 int 180 CBS_get_u24(CBS *cbs, uint32_t *out) 181 { 182 return cbs_get_u(cbs, out, 3); 183 } 184 185 int 186 CBS_get_u32(CBS *cbs, uint32_t *out) 187 { 188 return cbs_get_u(cbs, out, 4); 189 } 190 191 int 192 CBS_get_bytes(CBS *cbs, CBS *out, size_t len) 193 { 194 const uint8_t *v; 195 196 if (!cbs_get(cbs, &v, len)) 197 return 0; 198 199 CBS_init(out, v, len); 200 return 1; 201 } 202 203 static int 204 cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) 205 { 206 uint32_t len; 207 208 if (!cbs_get_u(cbs, &len, len_len)) 209 return 0; 210 211 return CBS_get_bytes(cbs, out, len); 212 } 213 214 int 215 CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) 216 { 217 return cbs_get_length_prefixed(cbs, out, 1); 218 } 219 220 int 221 CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) 222 { 223 return cbs_get_length_prefixed(cbs, out, 2); 224 } 225 226 int 227 CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) 228 { 229 return cbs_get_length_prefixed(cbs, out, 3); 230 } 231 232 int 233 CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, 234 size_t *out_header_len) 235 { 236 return cbs_get_any_asn1_element_internal(cbs, out, out_tag, 237 out_header_len, 1); 238 } 239 240 /* 241 * Review X.690 for details on ASN.1 DER encoding. 242 * 243 * If non-strict mode is enabled, then DER rules are relaxed 244 * for indefinite constructs (violates DER but a little closer to BER). 245 * Non-strict mode should only be used by bs_ber.c 246 * 247 * Sections 8, 10 and 11 for DER encoding 248 */ 249 int 250 cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, 251 size_t *out_header_len, int strict) 252 { 253 uint8_t tag, length_byte; 254 CBS header = *cbs; 255 CBS throwaway; 256 size_t len; 257 258 if (out == NULL) 259 out = &throwaway; 260 261 /* 262 * Get identifier octet and length octet. Only 1 octet for each 263 * is a CBS limitation. 264 */ 265 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) 266 return 0; 267 268 /* CBS limitation: long form tags are not supported. */ 269 if ((tag & 0x1f) == 0x1f) 270 return 0; 271 272 if (out_tag != NULL) 273 *out_tag = tag; 274 275 if ((length_byte & 0x80) == 0) { 276 /* Short form length. */ 277 len = ((size_t) length_byte) + 2; 278 if (out_header_len != NULL) 279 *out_header_len = 2; 280 281 } else { 282 /* Long form length. */ 283 const size_t num_bytes = length_byte & 0x7f; 284 uint32_t len32; 285 286 /* ASN.1 reserved value for future extensions */ 287 if (num_bytes == 0x7f) 288 return 0; 289 290 /* Handle indefinite form length */ 291 if (num_bytes == 0) { 292 /* DER encoding doesn't allow for indefinite form. */ 293 if (strict) 294 return 0; 295 296 /* Primitive cannot use indefinite in BER or DER. */ 297 if ((tag & CBS_ASN1_CONSTRUCTED) == 0) 298 return 0; 299 300 /* Constructed, indefinite length allowed in BER. */ 301 if (out_header_len != NULL) 302 *out_header_len = 2; 303 return CBS_get_bytes(cbs, out, 2); 304 } 305 306 /* CBS limitation. */ 307 if (num_bytes > 4) 308 return 0; 309 310 if (!cbs_get_u(&header, &len32, num_bytes)) 311 return 0; 312 313 /* DER has a minimum length octet requirement. */ 314 if (len32 < 128) 315 /* Should have used short form instead */ 316 return 0; 317 318 if ((len32 >> ((num_bytes - 1) * 8)) == 0) 319 /* Length should have been at least one byte shorter. */ 320 return 0; 321 322 len = len32; 323 if (len + 2 + num_bytes < len) 324 /* Overflow. */ 325 return 0; 326 327 len += 2 + num_bytes; 328 if (out_header_len != NULL) 329 *out_header_len = 2 + num_bytes; 330 } 331 332 return CBS_get_bytes(cbs, out, len); 333 } 334 335 static int 336 cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header) 337 { 338 size_t header_len; 339 unsigned int tag; 340 CBS throwaway; 341 342 if (out == NULL) 343 out = &throwaway; 344 345 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || 346 tag != tag_value) 347 return 0; 348 349 if (skip_header && !CBS_skip(out, header_len)) 350 return 0; 351 352 return 1; 353 } 354 355 int 356 CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value) 357 { 358 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); 359 } 360 361 int 362 CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value) 363 { 364 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); 365 } 366 367 int 368 CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value) 369 { 370 if (CBS_len(cbs) < 1) 371 return 0; 372 373 /* 374 * Tag number 31 indicates the start of a long form number. 375 * This is valid in ASN.1, but CBS only supports short form. 376 */ 377 if ((tag_value & 0x1f) == 0x1f) 378 return 0; 379 380 return CBS_data(cbs)[0] == tag_value; 381 } 382 383 /* Encoding details are in ASN.1: X.690 section 8.3 */ 384 int 385 CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) 386 { 387 CBS bytes; 388 const uint8_t *data; 389 size_t i, len; 390 391 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) 392 return 0; 393 394 *out = 0; 395 data = CBS_data(&bytes); 396 len = CBS_len(&bytes); 397 398 if (len == 0) 399 /* An INTEGER is encoded with at least one content octet. */ 400 return 0; 401 402 if ((data[0] & 0x80) != 0) 403 /* Negative number. */ 404 return 0; 405 406 if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) 407 /* Violates smallest encoding rule: excessive leading zeros. */ 408 return 0; 409 410 for (i = 0; i < len; i++) { 411 if ((*out >> 56) != 0) 412 /* Too large to represent as a uint64_t. */ 413 return 0; 414 415 *out <<= 8; 416 *out |= data[i]; 417 } 418 419 return 1; 420 } 421 422 int 423 CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag) 424 { 425 if (CBS_peek_asn1_tag(cbs, tag)) { 426 if (!CBS_get_asn1(cbs, out, tag)) 427 return 0; 428 429 *out_present = 1; 430 } else { 431 *out_present = 0; 432 } 433 return 1; 434 } 435 436 int 437 CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, 438 unsigned int tag) 439 { 440 CBS child; 441 int present; 442 443 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) 444 return 0; 445 446 if (present) { 447 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || 448 CBS_len(&child) != 0) 449 return 0; 450 } else { 451 CBS_init(out, NULL, 0); 452 } 453 if (out_present) 454 *out_present = present; 455 456 return 1; 457 } 458 459 int 460 CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, 461 uint64_t default_value) 462 { 463 CBS child; 464 int present; 465 466 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) 467 return 0; 468 469 if (present) { 470 if (!CBS_get_asn1_uint64(&child, out) || 471 CBS_len(&child) != 0) 472 return 0; 473 } else { 474 *out = default_value; 475 } 476 return 1; 477 } 478 479 int 480 CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, 481 int default_value) 482 { 483 CBS child, child2; 484 int present; 485 486 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) 487 return 0; 488 489 if (present) { 490 uint8_t boolean; 491 492 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || 493 CBS_len(&child2) != 1 || CBS_len(&child) != 0) 494 return 0; 495 496 boolean = CBS_data(&child2)[0]; 497 if (boolean == 0) 498 *out = 0; 499 else if (boolean == 0xff) 500 *out = 1; 501 else 502 return 0; 503 504 } else { 505 *out = default_value; 506 } 507 return 1; 508 } 509