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 44int 45der_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(unsigned) + 1 && p[0] == 0) 52 ; 53 else if (len > sizeof(unsigned)) 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 63int 64der_get_integer (const unsigned char *p, size_t len, 65 int *ret, size_t *size) 66{ 67 int val = 0; 68 size_t oldlen = len; 69 70 if (len > sizeof(int)) 71 return ASN1_OVERRUN; 72 73 if (len > 0) { 74 val = (signed char)*p++; 75 while (--len) 76 val = val * 256 + *p++; 77 } 78 *ret = val; 79 if(size) *size = oldlen; 80 return 0; 81} 82 83int 84der_get_length (const unsigned char *p, size_t len, 85 size_t *val, size_t *size) 86{ 87 size_t v; 88 89 if (len <= 0) 90 return ASN1_OVERRUN; 91 --len; 92 v = *p++; 93 if (v < 128) { 94 *val = v; 95 if(size) *size = 1; 96 } else { 97 int e; 98 size_t l; 99 unsigned tmp; 100 101 if(v == 0x80){ 102 *val = ASN1_INDEFINITE; 103 if(size) *size = 1; 104 return 0; 105 } 106 v &= 0x7F; 107 if (len < v) 108 return ASN1_OVERRUN; 109 e = der_get_unsigned (p, v, &tmp, &l); 110 if(e) return e; 111 *val = tmp; 112 if(size) *size = l + 1; 113 } 114 return 0; 115} 116 117int 118der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size) 119{ 120 if(len < 1) 121 return ASN1_OVERRUN; 122 if(*p != 0) 123 *data = 1; 124 else 125 *data = 0; 126 *size = 1; 127 return 0; 128} 129 130int 131der_get_general_string (const unsigned char *p, size_t len, 132 heim_general_string *str, size_t *size) 133{ 134 const unsigned char *p1; 135 char *s; 136 137 p1 = memchr(p, 0, len); 138 if (p1 != NULL) { 139 /* 140 * Allow trailing NULs. We allow this since MIT Kerberos sends 141 * an strings in the NEED_PREAUTH case that includes a 142 * trailing NUL. 143 */ 144 while ((size_t)(p1 - p) < len && *p1 == '\0') 145 p1++; 146 if ((size_t)(p1 - p) != len) { 147 *str = NULL; 148 return ASN1_BAD_CHARACTER; 149 } 150 } 151 if (len > len + 1) { 152 *str = NULL; 153 return ASN1_BAD_LENGTH; 154 } 155 156 *str = s = malloc (len + 1); 157 if (s == NULL) 158 return ENOMEM; 159 memcpy (s, p, len); 160 s[len] = '\0'; 161 162 if(size) *size = len; 163 return 0; 164} 165 166int 167der_get_utf8string (const unsigned char *p, size_t len, 168 heim_utf8_string *str, size_t *size) 169{ 170 return der_get_general_string(p, len, str, size); 171} 172 173#define gen_data_zero(_data) \ 174 do { (_data)->length = 0; (_data)->data = NULL; } while(0) 175 176int 177der_get_printable_string(const unsigned char *p, size_t len, 178 heim_printable_string *str, size_t *size) 179{ 180 if (len > len + 1) { 181 gen_data_zero(str); 182 return ASN1_BAD_LENGTH; 183 } 184 str->length = len; 185 str->data = malloc(len + 1); 186 if (str->data == NULL) { 187 gen_data_zero(str); 188 return ENOMEM; 189 } 190 memcpy(str->data, p, len); 191 ((char *)str->data)[len] = '\0'; 192 if(size) *size = len; 193 return 0; 194} 195 196int 197der_get_ia5_string(const unsigned char *p, size_t len, 198 heim_ia5_string *str, size_t *size) 199{ 200 return der_get_printable_string(p, len, str, size); 201} 202 203int 204der_get_bmp_string (const unsigned char *p, size_t len, 205 heim_bmp_string *data, size_t *size) 206{ 207 size_t i; 208 209 if (len & 1) { 210 gen_data_zero(data); 211 return ASN1_BAD_FORMAT; 212 } 213 data->length = len / 2; 214 if (data->length > UINT_MAX/sizeof(data->data[0])) { 215 gen_data_zero(data); 216 return ERANGE; 217 } 218 data->data = malloc(data->length * sizeof(data->data[0])); 219 if (data->data == NULL && data->length != 0) { 220 gen_data_zero(data); 221 return ENOMEM; 222 } 223 224 for (i = 0; i < data->length; i++) { 225 data->data[i] = (p[0] << 8) | p[1]; 226 p += 2; 227 /* check for NUL in the middle of the string */ 228 if (data->data[i] == 0 && i != (data->length - 1)) { 229 free(data->data); 230 gen_data_zero(data); 231 return ASN1_BAD_CHARACTER; 232 } 233 } 234 if (size) *size = len; 235 236 return 0; 237} 238 239int 240der_get_universal_string (const unsigned char *p, size_t len, 241 heim_universal_string *data, size_t *size) 242{ 243 size_t i; 244 245 if (len & 3) { 246 gen_data_zero(data); 247 return ASN1_BAD_FORMAT; 248 } 249 data->length = len / 4; 250 if (data->length > UINT_MAX/sizeof(data->data[0])) { 251 gen_data_zero(data); 252 return ERANGE; 253 } 254 data->data = malloc(data->length * sizeof(data->data[0])); 255 if (data->data == NULL && data->length != 0) { 256 gen_data_zero(data); 257 return ENOMEM; 258 } 259 260 for (i = 0; i < data->length; i++) { 261 data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 262 p += 4; 263 /* check for NUL in the middle of the string */ 264 if (data->data[i] == 0 && i != (data->length - 1)) { 265 free(data->data); 266 gen_data_zero(data); 267 return ASN1_BAD_CHARACTER; 268 } 269 } 270 if (size) *size = len; 271 return 0; 272} 273 274int 275der_get_visible_string (const unsigned char *p, size_t len, 276 heim_visible_string *str, size_t *size) 277{ 278 return der_get_general_string(p, len, str, size); 279} 280 281int 282der_get_octet_string (const unsigned char *p, size_t len, 283 heim_octet_string *data, size_t *size) 284{ 285 data->length = len; 286 data->data = malloc(len); 287 if (data->data == NULL && data->length != 0) 288 return ENOMEM; 289 memcpy (data->data, p, len); 290 if(size) *size = len; 291 return 0; 292} 293 294int 295der_get_octet_string_ber (const unsigned char *p, size_t len, 296 heim_octet_string *data, size_t *size) 297{ 298 int e; 299 Der_type type; 300 Der_class class; 301 unsigned int tag, depth = 0; 302 size_t l, datalen, oldlen = len; 303 304 data->length = 0; 305 data->data = NULL; 306 307 while (len) { 308 e = der_get_tag (p, len, &class, &type, &tag, &l); 309 if (e) goto out; 310 if (class != ASN1_C_UNIV) { 311 e = ASN1_BAD_ID; 312 goto out; 313 } 314 if (type == PRIM && tag == UT_EndOfContent) { 315 if (depth == 0) 316 break; 317 depth--; 318 } 319 if (tag != UT_OctetString) { 320 e = ASN1_BAD_ID; 321 goto out; 322 } 323 324 p += l; 325 len -= l; 326 e = der_get_length (p, len, &datalen, &l); 327 if (e) goto out; 328 p += l; 329 len -= l; 330 331 if (datalen > len) 332 return ASN1_OVERRUN; 333 334 if (type == PRIM) { 335 void *ptr; 336 337 ptr = realloc(data->data, data->length + datalen); 338 if (ptr == NULL) { 339 e = ENOMEM; 340 goto out; 341 } 342 data->data = ptr; 343 memcpy(((unsigned char *)data->data) + data->length, p, datalen); 344 data->length += datalen; 345 } else 346 depth++; 347 348 p += datalen; 349 len -= datalen; 350 } 351 if (depth != 0) 352 return ASN1_INDEF_OVERRUN; 353 if(size) *size = oldlen - len; 354 return 0; 355 out: 356 free(data->data); 357 data->data = NULL; 358 data->length = 0; 359 return e; 360} 361 362 363int 364der_get_heim_integer (const unsigned char *p, size_t len, 365 heim_integer *data, size_t *size) 366{ 367 data->length = 0; 368 data->negative = 0; 369 data->data = NULL; 370 371 if (len == 0) { 372 if (size) 373 *size = 0; 374 return 0; 375 } 376 if (p[0] & 0x80) { 377 unsigned char *q; 378 int carry = 1; 379 data->negative = 1; 380 381 data->length = len; 382 383 if (p[0] == 0xff) { 384 p++; 385 data->length--; 386 } 387 data->data = malloc(data->length); 388 if (data->data == NULL) { 389 data->length = 0; 390 if (size) 391 *size = 0; 392 return ENOMEM; 393 } 394 q = &((unsigned char*)data->data)[data->length - 1]; 395 p += data->length - 1; 396 while (q >= (unsigned char*)data->data) { 397 *q = *p ^ 0xff; 398 if (carry) 399 carry = !++*q; 400 p--; 401 q--; 402 } 403 } else { 404 data->negative = 0; 405 data->length = len; 406 407 if (p[0] == 0) { 408 p++; 409 data->length--; 410 } 411 data->data = malloc(data->length); 412 if (data->data == NULL && data->length != 0) { 413 data->length = 0; 414 if (size) 415 *size = 0; 416 return ENOMEM; 417 } 418 memcpy(data->data, p, data->length); 419 } 420 if (size) 421 *size = len; 422 return 0; 423} 424 425static int 426generalizedtime2time (const char *s, time_t *t) 427{ 428 struct tm tm; 429 430 memset(&tm, 0, sizeof(tm)); 431 if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ", 432 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 433 &tm.tm_min, &tm.tm_sec) != 6) { 434 if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ", 435 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 436 &tm.tm_min, &tm.tm_sec) != 6) 437 return ASN1_BAD_TIMEFORMAT; 438 if (tm.tm_year < 50) 439 tm.tm_year += 2000; 440 else 441 tm.tm_year += 1900; 442 } 443 tm.tm_year -= 1900; 444 tm.tm_mon -= 1; 445 *t = _der_timegm (&tm); 446 return 0; 447} 448 449static int 450der_get_time (const unsigned char *p, size_t len, 451 time_t *data, size_t *size) 452{ 453 char *times; 454 int e; 455 456 if (len > len + 1 || len == 0) 457 return ASN1_BAD_LENGTH; 458 459 times = malloc(len + 1); 460 if (times == NULL) 461 return ENOMEM; 462 memcpy(times, p, len); 463 times[len] = '\0'; 464 e = generalizedtime2time(times, data); 465 free (times); 466 if(size) *size = len; 467 return e; 468} 469 470int 471der_get_generalized_time (const unsigned char *p, size_t len, 472 time_t *data, size_t *size) 473{ 474 return der_get_time(p, len, data, size); 475} 476 477int 478der_get_utctime (const unsigned char *p, size_t len, 479 time_t *data, size_t *size) 480{ 481 return der_get_time(p, len, data, size); 482} 483 484int 485der_get_oid (const unsigned char *p, size_t len, 486 heim_oid *data, size_t *size) 487{ 488 size_t n; 489 size_t oldlen = len; 490 491 if (len < 1) 492 return ASN1_OVERRUN; 493 494 if (len > len + 1) 495 return ASN1_BAD_LENGTH; 496 497 if (len + 1 > UINT_MAX/sizeof(data->components[0])) 498 return ERANGE; 499 500 data->components = malloc((len + 1) * sizeof(data->components[0])); 501 if (data->components == NULL) 502 return ENOMEM; 503 data->components[0] = (*p) / 40; 504 data->components[1] = (*p) % 40; 505 --len; 506 ++p; 507 for (n = 2; len > 0; ++n) { 508 unsigned u = 0, u1; 509 510 do { 511 --len; 512 u1 = u * 128 + (*p++ % 128); 513 /* check that we don't overflow the element */ 514 if (u1 < u) { 515 der_free_oid(data); 516 return ASN1_OVERRUN; 517 } 518 u = u1; 519 } while (len > 0 && p[-1] & 0x80); 520 data->components[n] = u; 521 } 522 if (n > 2 && p[-1] & 0x80) { 523 der_free_oid (data); 524 return ASN1_OVERRUN; 525 } 526 data->length = n; 527 if (size) 528 *size = oldlen; 529 return 0; 530} 531 532int 533der_get_tag (const unsigned char *p, size_t len, 534 Der_class *class, Der_type *type, 535 unsigned int *tag, size_t *size) 536{ 537 size_t ret = 0; 538 if (len < 1) 539 return ASN1_OVERRUN; 540 *class = (Der_class)(((*p) >> 6) & 0x03); 541 *type = (Der_type)(((*p) >> 5) & 0x01); 542 *tag = (*p) & 0x1f; 543 p++; len--; ret++; 544 if(*tag == 0x1f) { 545 unsigned int continuation; 546 unsigned int tag1; 547 *tag = 0; 548 do { 549 if(len < 1) 550 return ASN1_OVERRUN; 551 continuation = *p & 128; 552 tag1 = *tag * 128 + (*p % 128); 553 /* check that we don't overflow the tag */ 554 if (tag1 < *tag) 555 return ASN1_OVERFLOW; 556 *tag = tag1; 557 p++; len--; ret++; 558 } while(continuation); 559 } 560 if(size) *size = ret; 561 return 0; 562} 563 564int 565der_match_tag (const unsigned char *p, size_t len, 566 Der_class class, Der_type type, 567 unsigned int tag, size_t *size) 568{ 569 Der_type thistype; 570 int e; 571 572 e = der_match_tag2(p, len, class, &thistype, tag, size); 573 if (e) return e; 574 if (thistype != type) return ASN1_BAD_ID; 575 return 0; 576} 577 578int 579der_match_tag2 (const unsigned char *p, size_t len, 580 Der_class class, Der_type *type, 581 unsigned int tag, size_t *size) 582{ 583 size_t l; 584 Der_class thisclass; 585 unsigned int thistag; 586 int e; 587 588 e = der_get_tag (p, len, &thisclass, type, &thistag, &l); 589 if (e) return e; 590 if (class != thisclass) 591 return ASN1_BAD_ID; 592 if(tag > thistag) 593 return ASN1_MISPLACED_FIELD; 594 if(tag < thistag) 595 return ASN1_MISSING_FIELD; 596 if(size) *size = l; 597 return 0; 598} 599 600int 601der_match_tag_and_length (const unsigned char *p, size_t len, 602 Der_class class, Der_type *type, unsigned int tag, 603 size_t *length_ret, size_t *size) 604{ 605 size_t l, ret = 0; 606 int e; 607 608 e = der_match_tag2 (p, len, class, type, tag, &l); 609 if (e) return e; 610 p += l; 611 len -= l; 612 ret += l; 613 e = der_get_length (p, len, length_ret, &l); 614 if (e) return e; 615 if(size) *size = ret + l; 616 return 0; 617} 618 619 620 621/* 622 * Old versions of DCE was based on a very early beta of the MIT code, 623 * which used MAVROS for ASN.1 encoding. MAVROS had the interesting 624 * feature that it encoded data in the forward direction, which has 625 * it's problems, since you have no idea how long the data will be 626 * until after you're done. MAVROS solved this by reserving one byte 627 * for length, and later, if the actual length was longer, it reverted 628 * to indefinite, BER style, lengths. The version of MAVROS used by 629 * the DCE people could apparently generate correct X.509 DER encodings, and 630 * did this by making space for the length after encoding, but 631 * unfortunately this feature wasn't used with Kerberos. 632 */ 633 634int 635_heim_fix_dce(size_t reallen, size_t *len) 636{ 637 if(reallen == ASN1_INDEFINITE) 638 return 1; 639 if(*len < reallen) 640 return -1; 641 *len = reallen; 642 return 0; 643} 644 645int 646der_get_bit_string (const unsigned char *p, size_t len, 647 heim_bit_string *data, size_t *size) 648{ 649 if (len < 1) 650 return ASN1_OVERRUN; 651 if (p[0] > 7) 652 return ASN1_BAD_FORMAT; 653 if (len - 1 == 0 && p[0] != 0) 654 return ASN1_BAD_FORMAT; 655 /* check if any of the three upper bits are set 656 * any of them will cause a interger overrun */ 657 if ((len - 1) >> (sizeof(len) * 8 - 3)) 658 return ASN1_OVERRUN; 659 /* 660 * If there is data to copy, do that now. 661 */ 662 if (len - 1 > 0) { 663 data->length = (len - 1) * 8; 664 data->data = malloc(len - 1); 665 if (data->data == NULL) 666 return ENOMEM; 667 memcpy (data->data, p + 1, len - 1); 668 data->length -= p[0]; 669 } else { 670 data->data = NULL; 671 data->length = 0; 672 } 673 if(size) *size = len; 674 return 0; 675} 676