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