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