1 /* $NetBSD: der_get.c,v 1.2 2017/01/28 21:31:45 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "der_locl.h" 37 38 /* 39 * All decoding functions take a pointer `p' to first position in 40 * which to read, from the left, `len' which means the maximum number 41 * of characters we are able to read, `ret' were the value will be 42 * returned and `size' where the number of used bytes is stored. 43 * Either 0 or an error code is returned. 44 */ 45 46 int 47 der_get_unsigned (const unsigned char *p, size_t len, 48 unsigned *ret, size_t *size) 49 { 50 unsigned val = 0; 51 size_t oldlen = len; 52 53 if (len == sizeof(val) + 1 && p[0] == 0) 54 ; 55 else if (len > sizeof(val)) 56 return ASN1_OVERRUN; 57 58 while (len--) 59 val = val * 256 + *p++; 60 *ret = val; 61 if(size) *size = oldlen; 62 return 0; 63 } 64 65 int 66 der_get_unsigned64 (const unsigned char *p, size_t len, 67 uint64_t *ret, size_t *size) 68 { 69 uint64_t val = 0; 70 size_t oldlen = len; 71 72 if (len == sizeof(val) + 1 && p[0] == 0) 73 ; 74 else if (len > sizeof(val)) 75 return ASN1_OVERRUN; 76 77 while (len--) 78 val = val * 256 + *p++; 79 *ret = val; 80 if(size) *size = oldlen; 81 return 0; 82 } 83 84 int 85 der_get_integer (const unsigned char *p, size_t len, 86 int *ret, size_t *size) 87 { 88 int val = 0; 89 size_t oldlen = len; 90 91 if (len > sizeof(val)) 92 return ASN1_OVERRUN; 93 94 if (len > 0) { 95 val = (signed char)*p++; 96 while (--len) 97 val = val * 256 + *p++; 98 } 99 *ret = val; 100 if(size) *size = oldlen; 101 return 0; 102 } 103 104 int 105 der_get_integer64 (const unsigned char *p, size_t len, 106 int64_t *ret, size_t *size) 107 { 108 int64_t val = 0; 109 size_t oldlen = len; 110 111 if (len > sizeof(val)) 112 return ASN1_OVERRUN; 113 114 if (len > 0) { 115 val = (signed char)*p++; 116 while (--len) 117 val = val * 256 + *p++; 118 } 119 *ret = val; 120 if(size) *size = oldlen; 121 return 0; 122 } 123 124 125 int 126 der_get_length (const unsigned char *p, size_t len, 127 size_t *val, size_t *size) 128 { 129 size_t v; 130 131 if (len <= 0) 132 return ASN1_OVERRUN; 133 --len; 134 v = *p++; 135 if (v < 128) { 136 *val = v; 137 if(size) *size = 1; 138 } else { 139 int e; 140 size_t l; 141 unsigned tmp; 142 143 if(v == 0x80){ 144 *val = ASN1_INDEFINITE; 145 if(size) *size = 1; 146 return 0; 147 } 148 v &= 0x7F; 149 if (len < v) 150 return ASN1_OVERRUN; 151 e = der_get_unsigned (p, v, &tmp, &l); 152 if(e) return e; 153 *val = tmp; 154 if(size) *size = l + 1; 155 } 156 return 0; 157 } 158 159 int 160 der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size) 161 { 162 if(len < 1) 163 return ASN1_OVERRUN; 164 if(*p != 0) 165 *data = 1; 166 else 167 *data = 0; 168 *size = 1; 169 return 0; 170 } 171 172 int 173 der_get_general_string (const unsigned char *p, size_t len, 174 heim_general_string *str, size_t *size) 175 { 176 const unsigned char *p1; 177 char *s; 178 179 p1 = memchr(p, 0, len); 180 if (p1 != NULL) { 181 /* 182 * Allow trailing NULs. We allow this since MIT Kerberos sends 183 * an strings in the NEED_PREAUTH case that includes a 184 * trailing NUL. 185 */ 186 while ((size_t)(p1 - p) < len && *p1 == '\0') 187 p1++; 188 if ((size_t)(p1 - p) != len) { 189 *str = NULL; 190 return ASN1_BAD_CHARACTER; 191 } 192 } 193 if (len == SIZE_MAX) { 194 *str = NULL; 195 return ASN1_BAD_LENGTH; 196 } 197 198 *str = s = malloc (len + 1); 199 if (s == NULL) 200 return ENOMEM; 201 memcpy (s, p, len); 202 s[len] = '\0'; 203 204 if(size) *size = len; 205 return 0; 206 } 207 208 int 209 der_get_utf8string (const unsigned char *p, size_t len, 210 heim_utf8_string *str, size_t *size) 211 { 212 return der_get_general_string(p, len, str, size); 213 } 214 215 #define gen_data_zero(_data) \ 216 do { (_data)->length = 0; (_data)->data = NULL; } while(0) 217 218 int 219 der_get_printable_string(const unsigned char *p, size_t len, 220 heim_printable_string *str, size_t *size) 221 { 222 if (len == SIZE_MAX) { 223 gen_data_zero(str); 224 return ASN1_BAD_LENGTH; 225 } 226 str->length = len; 227 str->data = malloc(len + 1); 228 if (str->data == NULL) { 229 gen_data_zero(str); 230 return ENOMEM; 231 } 232 memcpy(str->data, p, len); 233 ((char *)str->data)[len] = '\0'; 234 if(size) *size = len; 235 return 0; 236 } 237 238 int 239 der_get_ia5_string(const unsigned char *p, size_t len, 240 heim_ia5_string *str, size_t *size) 241 { 242 return der_get_printable_string(p, len, str, size); 243 } 244 245 int 246 der_get_bmp_string (const unsigned char *p, size_t len, 247 heim_bmp_string *data, size_t *size) 248 { 249 size_t i; 250 251 if (len & 1) { 252 gen_data_zero(data); 253 return ASN1_BAD_FORMAT; 254 } 255 data->length = len / 2; 256 if (data->length > UINT_MAX/sizeof(data->data[0])) { 257 gen_data_zero(data); 258 return ERANGE; 259 } 260 data->data = malloc(data->length * sizeof(data->data[0])); 261 if (data->data == NULL && data->length != 0) { 262 gen_data_zero(data); 263 return ENOMEM; 264 } 265 266 for (i = 0; i < data->length; i++) { 267 data->data[i] = (p[0] << 8) | p[1]; 268 p += 2; 269 /* check for NUL in the middle of the string */ 270 if (data->data[i] == 0 && i != (data->length - 1)) { 271 free(data->data); 272 gen_data_zero(data); 273 return ASN1_BAD_CHARACTER; 274 } 275 } 276 if (size) *size = len; 277 278 return 0; 279 } 280 281 int 282 der_get_universal_string (const unsigned char *p, size_t len, 283 heim_universal_string *data, size_t *size) 284 { 285 size_t i; 286 287 if (len & 3) { 288 gen_data_zero(data); 289 return ASN1_BAD_FORMAT; 290 } 291 data->length = len / 4; 292 if (data->length > UINT_MAX/sizeof(data->data[0])) { 293 gen_data_zero(data); 294 return ERANGE; 295 } 296 data->data = malloc(data->length * sizeof(data->data[0])); 297 if (data->data == NULL && data->length != 0) { 298 gen_data_zero(data); 299 return ENOMEM; 300 } 301 302 for (i = 0; i < data->length; i++) { 303 data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 304 p += 4; 305 /* check for NUL in the middle of the string */ 306 if (data->data[i] == 0 && i != (data->length - 1)) { 307 free(data->data); 308 gen_data_zero(data); 309 return ASN1_BAD_CHARACTER; 310 } 311 } 312 if (size) *size = len; 313 return 0; 314 } 315 316 int 317 der_get_visible_string (const unsigned char *p, size_t len, 318 heim_visible_string *str, size_t *size) 319 { 320 return der_get_general_string(p, len, str, size); 321 } 322 323 int 324 der_get_octet_string (const unsigned char *p, size_t len, 325 heim_octet_string *data, size_t *size) 326 { 327 data->length = len; 328 data->data = malloc(len); 329 if (data->data == NULL && data->length != 0) 330 return ENOMEM; 331 memcpy (data->data, p, len); 332 if(size) *size = len; 333 return 0; 334 } 335 336 int 337 der_get_octet_string_ber (const unsigned char *p, size_t len, 338 heim_octet_string *data, size_t *size) 339 { 340 int e; 341 Der_type type; 342 Der_class cls; 343 unsigned int tag, depth = 0; 344 size_t l, datalen, oldlen = len; 345 346 data->length = 0; 347 data->data = NULL; 348 349 while (len) { 350 e = der_get_tag (p, len, &cls, &type, &tag, &l); 351 if (e) goto out; 352 if (cls != ASN1_C_UNIV) { 353 e = ASN1_BAD_ID; 354 goto out; 355 } 356 if (type == PRIM && tag == UT_EndOfContent) { 357 if (depth == 0) 358 break; 359 depth--; 360 } 361 if (tag != UT_OctetString) { 362 e = ASN1_BAD_ID; 363 goto out; 364 } 365 366 p += l; 367 len -= l; 368 e = der_get_length (p, len, &datalen, &l); 369 if (e) goto out; 370 p += l; 371 len -= l; 372 373 if (datalen > len) 374 return ASN1_OVERRUN; 375 376 if (type == PRIM) { 377 void *ptr; 378 379 ptr = realloc(data->data, data->length + datalen); 380 if (ptr == NULL) { 381 e = ENOMEM; 382 goto out; 383 } 384 data->data = ptr; 385 memcpy(((unsigned char *)data->data) + data->length, p, datalen); 386 data->length += datalen; 387 } else 388 depth++; 389 390 p += datalen; 391 len -= datalen; 392 } 393 if (depth != 0) 394 return ASN1_INDEF_OVERRUN; 395 if(size) *size = oldlen - len; 396 return 0; 397 out: 398 free(data->data); 399 data->data = NULL; 400 data->length = 0; 401 return e; 402 } 403 404 405 int 406 der_get_heim_integer (const unsigned char *p, size_t len, 407 heim_integer *data, size_t *size) 408 { 409 data->length = 0; 410 data->negative = 0; 411 data->data = NULL; 412 413 if (len == 0) { 414 if (size) 415 *size = 0; 416 return 0; 417 } 418 if (p[0] & 0x80) { 419 unsigned char *q; 420 int carry = 1; 421 data->negative = 1; 422 423 data->length = len; 424 425 if (p[0] == 0xff) { 426 p++; 427 data->length--; 428 } 429 data->data = malloc(data->length); 430 if (data->data == NULL) { 431 data->length = 0; 432 if (size) 433 *size = 0; 434 return ENOMEM; 435 } 436 q = &((unsigned char*)data->data)[data->length - 1]; 437 p += data->length - 1; 438 while (q >= (unsigned char*)data->data) { 439 *q = *p ^ 0xff; 440 if (carry) 441 carry = !++*q; 442 p--; 443 q--; 444 } 445 } else { 446 data->negative = 0; 447 data->length = len; 448 449 if (p[0] == 0) { 450 p++; 451 data->length--; 452 } 453 data->data = malloc(data->length); 454 if (data->data == NULL && data->length != 0) { 455 data->length = 0; 456 if (size) 457 *size = 0; 458 return ENOMEM; 459 } 460 memcpy(data->data, p, data->length); 461 } 462 if (size) 463 *size = len; 464 return 0; 465 } 466 467 static int 468 generalizedtime2time (const char *s, time_t *t) 469 { 470 struct tm tm; 471 472 memset(&tm, 0, sizeof(tm)); 473 if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ", 474 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 475 &tm.tm_min, &tm.tm_sec) != 6) { 476 if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ", 477 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 478 &tm.tm_min, &tm.tm_sec) != 6) 479 return ASN1_BAD_TIMEFORMAT; 480 if (tm.tm_year < 50) 481 tm.tm_year += 2000; 482 else 483 tm.tm_year += 1900; 484 } 485 tm.tm_year -= 1900; 486 tm.tm_mon -= 1; 487 *t = _der_timegm (&tm); 488 return 0; 489 } 490 491 static int 492 der_get_time (const unsigned char *p, size_t len, 493 time_t *data, size_t *size) 494 { 495 char *times; 496 int e; 497 498 if (len == SIZE_MAX || len == 0) 499 return ASN1_BAD_LENGTH; 500 501 times = malloc(len + 1); 502 if (times == NULL) 503 return ENOMEM; 504 memcpy(times, p, len); 505 times[len] = '\0'; 506 e = generalizedtime2time(times, data); 507 free (times); 508 if(size) *size = len; 509 return e; 510 } 511 512 int 513 der_get_generalized_time (const unsigned char *p, size_t len, 514 time_t *data, size_t *size) 515 { 516 return der_get_time(p, len, data, size); 517 } 518 519 int 520 der_get_utctime (const unsigned char *p, size_t len, 521 time_t *data, size_t *size) 522 { 523 return der_get_time(p, len, data, size); 524 } 525 526 int 527 der_get_oid (const unsigned char *p, size_t len, 528 heim_oid *data, size_t *size) 529 { 530 size_t n; 531 size_t oldlen = len; 532 533 if (len < 1) 534 return ASN1_OVERRUN; 535 536 if (len == SIZE_MAX) 537 return ASN1_BAD_LENGTH; 538 539 if (len + 1 > UINT_MAX/sizeof(data->components[0])) 540 return ERANGE; 541 542 data->components = malloc((len + 1) * sizeof(data->components[0])); 543 if (data->components == NULL) 544 return ENOMEM; 545 data->components[0] = (*p) / 40; 546 data->components[1] = (*p) % 40; 547 --len; 548 ++p; 549 for (n = 2; len > 0; ++n) { 550 unsigned u = 0, u1; 551 552 do { 553 --len; 554 u1 = u * 128 + (*p++ % 128); 555 /* check that we don't overflow the element */ 556 if (u1 < u) { 557 der_free_oid(data); 558 return ASN1_OVERRUN; 559 } 560 u = u1; 561 } while (len > 0 && p[-1] & 0x80); 562 data->components[n] = u; 563 } 564 if (n > 2 && p[-1] & 0x80) { 565 der_free_oid (data); 566 return ASN1_OVERRUN; 567 } 568 data->length = n; 569 if (size) 570 *size = oldlen; 571 return 0; 572 } 573 574 int 575 der_get_tag (const unsigned char *p, size_t len, 576 Der_class *cls, Der_type *type, 577 unsigned int *tag, size_t *size) 578 { 579 size_t ret = 0; 580 if (len < 1) 581 return ASN1_OVERRUN; 582 *cls = (Der_class)(((*p) >> 6) & 0x03); 583 *type = (Der_type)(((*p) >> 5) & 0x01); 584 *tag = (*p) & 0x1f; 585 p++; len--; ret++; 586 if(*tag == 0x1f) { 587 unsigned int continuation; 588 unsigned int tag1; 589 *tag = 0; 590 do { 591 if(len < 1) 592 return ASN1_OVERRUN; 593 continuation = *p & 128; 594 tag1 = *tag * 128 + (*p % 128); 595 /* check that we don't overflow the tag */ 596 if (tag1 < *tag) 597 return ASN1_OVERFLOW; 598 *tag = tag1; 599 p++; len--; ret++; 600 } while(continuation); 601 } 602 if(size) *size = ret; 603 return 0; 604 } 605 606 int 607 der_match_tag (const unsigned char *p, size_t len, 608 Der_class cls, Der_type type, 609 unsigned int tag, size_t *size) 610 { 611 Der_type thistype; 612 int e; 613 614 e = der_match_tag2(p, len, cls, &thistype, tag, size); 615 if (e) return e; 616 if (thistype != type) return ASN1_BAD_ID; 617 return 0; 618 } 619 620 int 621 der_match_tag2 (const unsigned char *p, size_t len, 622 Der_class cls, Der_type *type, 623 unsigned int tag, size_t *size) 624 { 625 size_t l; 626 Der_class thisclass; 627 unsigned int thistag; 628 int e; 629 630 e = der_get_tag (p, len, &thisclass, type, &thistag, &l); 631 if (e) return e; 632 if (cls != thisclass) 633 return ASN1_BAD_ID; 634 if(tag > thistag) 635 return ASN1_MISPLACED_FIELD; 636 if(tag < thistag) 637 return ASN1_MISSING_FIELD; 638 if(size) *size = l; 639 return 0; 640 } 641 642 int 643 der_match_tag_and_length (const unsigned char *p, size_t len, 644 Der_class cls, Der_type *type, unsigned int tag, 645 size_t *length_ret, size_t *size) 646 { 647 size_t l, ret = 0; 648 int e; 649 650 e = der_match_tag2 (p, len, cls, type, tag, &l); 651 if (e) return e; 652 p += l; 653 len -= l; 654 ret += l; 655 e = der_get_length (p, len, length_ret, &l); 656 if (e) return e; 657 if(size) *size = ret + l; 658 return 0; 659 } 660 661 662 663 /* 664 * Old versions of DCE was based on a very early beta of the MIT code, 665 * which used MAVROS for ASN.1 encoding. MAVROS had the interesting 666 * feature that it encoded data in the forward direction, which has 667 * it's problems, since you have no idea how long the data will be 668 * until after you're done. MAVROS solved this by reserving one byte 669 * for length, and later, if the actual length was longer, it reverted 670 * to indefinite, BER style, lengths. The version of MAVROS used by 671 * the DCE people could apparently generate correct X.509 DER encodings, and 672 * did this by making space for the length after encoding, but 673 * unfortunately this feature wasn't used with Kerberos. 674 */ 675 676 int 677 _heim_fix_dce(size_t reallen, size_t *len) 678 { 679 if(reallen == ASN1_INDEFINITE) 680 return 1; 681 if(*len < reallen) 682 return -1; 683 *len = reallen; 684 return 0; 685 } 686 687 int 688 der_get_bit_string (const unsigned char *p, size_t len, 689 heim_bit_string *data, size_t *size) 690 { 691 if (len < 1) 692 return ASN1_OVERRUN; 693 if (p[0] > 7) 694 return ASN1_BAD_FORMAT; 695 if (len - 1 == 0 && p[0] != 0) 696 return ASN1_BAD_FORMAT; 697 /* check if any of the three upper bits are set 698 * any of them will cause a interger overrun */ 699 if ((len - 1) >> (sizeof(len) * 8 - 3)) 700 return ASN1_OVERRUN; 701 /* 702 * If there is data to copy, do that now. 703 */ 704 if (len - 1 > 0) { 705 data->length = (len - 1) * 8; 706 data->data = malloc(len - 1); 707 if (data->data == NULL) 708 return ENOMEM; 709 memcpy (data->data, p + 1, len - 1); 710 data->length -= p[0]; 711 } else { 712 data->data = NULL; 713 data->length = 0; 714 } 715 if(size) *size = len; 716 return 0; 717 } 718