1 /* $OpenBSD: ber.c,v 1.26 2023/11/10 12:12:02 martijn Exp $ */ 2 3 /* 4 * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2006, 2007 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/types.h> 22 23 #include <errno.h> 24 #include <limits.h> 25 #include <stdlib.h> 26 #include <err.h> /* XXX for debug output */ 27 #include <stdio.h> /* XXX for debug output */ 28 #include <string.h> 29 #include <unistd.h> 30 #include <stdarg.h> 31 32 #include "ber.h" 33 34 #define BER_TYPE_CONSTRUCTED 0x20 /* otherwise primitive */ 35 #define BER_TYPE_SINGLE_MAX 30 36 #define BER_TAG_MASK 0x1f 37 #define BER_TAG_MORE 0x80 /* more subsequent octets */ 38 #define BER_TAG_TYPE_MASK 0x7f 39 #define BER_CLASS_SHIFT 6 40 41 static int ober_dump_element(struct ber *ber, struct ber_element *root); 42 static void ober_dump_header(struct ber *ber, struct ber_element *root); 43 static void ober_putc(struct ber *ber, u_char c); 44 static void ober_write(struct ber *ber, void *buf, size_t len); 45 static ssize_t get_id(struct ber *b, unsigned int *tag, int *class, 46 int *cstruct); 47 static ssize_t get_len(struct ber *b, ssize_t *len); 48 static ssize_t ober_read_element(struct ber *ber, struct ber_element *elm); 49 static ssize_t ober_getc(struct ber *b, u_char *c); 50 static ssize_t ober_read(struct ber *ber, void *buf, size_t len); 51 52 #ifdef DEBUG 53 #define DPRINTF(...) printf(__VA_ARGS__) 54 #else 55 #define DPRINTF(...) do { } while (0) 56 #endif 57 58 struct ber_element * 59 ober_get_element(unsigned int encoding) 60 { 61 struct ber_element *elm; 62 63 if ((elm = calloc(1, sizeof(*elm))) == NULL) 64 return NULL; 65 66 elm->be_encoding = encoding; 67 ober_set_header(elm, BER_CLASS_UNIVERSAL, BER_TYPE_DEFAULT); 68 69 return elm; 70 } 71 72 void 73 ober_set_header(struct ber_element *elm, int class, unsigned int type) 74 { 75 elm->be_class = class & BER_CLASS_MASK; 76 if (type == BER_TYPE_DEFAULT) 77 type = elm->be_encoding; 78 elm->be_type = type; 79 } 80 81 void 82 ober_link_elements(struct ber_element *prev, struct ber_element *elm) 83 { 84 if (prev != NULL) { 85 if ((prev->be_encoding == BER_TYPE_SEQUENCE || 86 prev->be_encoding == BER_TYPE_SET) && 87 prev->be_sub == NULL) 88 prev->be_sub = elm; 89 else 90 prev->be_next = elm; 91 } 92 } 93 94 struct ber_element * 95 ober_unlink_elements(struct ber_element *prev) 96 { 97 struct ber_element *elm; 98 99 if ((prev->be_encoding == BER_TYPE_SEQUENCE || 100 prev->be_encoding == BER_TYPE_SET) && 101 prev->be_sub != NULL) { 102 elm = prev->be_sub; 103 prev->be_sub = NULL; 104 } else { 105 elm = prev->be_next; 106 prev->be_next = NULL; 107 } 108 109 return (elm); 110 } 111 112 void 113 ober_replace_elements(struct ber_element *prev, struct ber_element *new) 114 { 115 struct ber_element *ber, *next; 116 117 ber = ober_unlink_elements(prev); 118 next = ober_unlink_elements(ber); 119 ober_link_elements(new, next); 120 ober_link_elements(prev, new); 121 122 /* cleanup old element */ 123 ober_free_elements(ber); 124 } 125 126 struct ber_element * 127 ober_add_sequence(struct ber_element *prev) 128 { 129 struct ber_element *elm; 130 131 if ((elm = ober_get_element(BER_TYPE_SEQUENCE)) == NULL) 132 return NULL; 133 134 ober_link_elements(prev, elm); 135 136 return elm; 137 } 138 139 struct ber_element * 140 ober_add_set(struct ber_element *prev) 141 { 142 struct ber_element *elm; 143 144 if ((elm = ober_get_element(BER_TYPE_SET)) == NULL) 145 return NULL; 146 147 ober_link_elements(prev, elm); 148 149 return elm; 150 } 151 152 struct ber_element * 153 ober_add_enumerated(struct ber_element *prev, long long val) 154 { 155 struct ber_element *elm; 156 u_int i, len = 0; 157 u_char cur, last = 0; 158 159 if ((elm = ober_get_element(BER_TYPE_ENUMERATED)) == NULL) 160 return NULL; 161 162 elm->be_numeric = val; 163 164 for (i = 0; i < sizeof(long long); i++) { 165 cur = val & 0xff; 166 if (cur != 0 && cur != 0xff) 167 len = i; 168 if ((cur == 0 && last & 0x80) || 169 (cur == 0xff && (last & 0x80) == 0)) 170 len = i; 171 val >>= 8; 172 last = cur; 173 } 174 elm->be_len = len + 1; 175 176 ober_link_elements(prev, elm); 177 178 return elm; 179 } 180 181 struct ber_element * 182 ober_add_integer(struct ber_element *prev, long long val) 183 { 184 struct ber_element *elm; 185 u_int i, len = 0; 186 u_char cur, last = 0; 187 188 if ((elm = ober_get_element(BER_TYPE_INTEGER)) == NULL) 189 return NULL; 190 191 elm->be_numeric = val; 192 193 for (i = 0; i < sizeof(long long); i++) { 194 cur = val & 0xff; 195 if (cur != 0 && cur != 0xff) 196 len = i; 197 if ((cur == 0 && last & 0x80) || 198 (cur == 0xff && (last & 0x80) == 0)) 199 len = i; 200 val >>= 8; 201 last = cur; 202 } 203 elm->be_len = len + 1; 204 205 ober_link_elements(prev, elm); 206 207 return elm; 208 } 209 210 int 211 ober_get_integer(struct ber_element *elm, long long *n) 212 { 213 if (elm->be_encoding != BER_TYPE_INTEGER) 214 return -1; 215 216 if (n != NULL) 217 *n = elm->be_numeric; 218 return 0; 219 } 220 221 int 222 ober_get_enumerated(struct ber_element *elm, long long *n) 223 { 224 if (elm->be_encoding != BER_TYPE_ENUMERATED) 225 return -1; 226 227 if (n != NULL) 228 *n = elm->be_numeric; 229 return 0; 230 } 231 232 struct ber_element * 233 ober_add_boolean(struct ber_element *prev, int bool) 234 { 235 struct ber_element *elm; 236 237 if ((elm = ober_get_element(BER_TYPE_BOOLEAN)) == NULL) 238 return NULL; 239 240 elm->be_numeric = bool ? 0xff : 0; 241 elm->be_len = 1; 242 243 ober_link_elements(prev, elm); 244 245 return elm; 246 } 247 248 int 249 ober_get_boolean(struct ber_element *elm, int *b) 250 { 251 if (elm->be_encoding != BER_TYPE_BOOLEAN) 252 return -1; 253 254 if (b != NULL) 255 *b = !(elm->be_numeric == 0); 256 return 0; 257 } 258 259 struct ber_element * 260 ober_add_string(struct ber_element *prev, const char *string) 261 { 262 return ober_add_nstring(prev, string, strlen(string)); 263 } 264 265 struct ber_element * 266 ober_add_nstring(struct ber_element *prev, const char *string0, size_t len) 267 { 268 struct ber_element *elm; 269 char *string; 270 271 if ((string = calloc(1, len + 1)) == NULL) 272 return NULL; 273 if ((elm = ober_get_element(BER_TYPE_OCTETSTRING)) == NULL) { 274 free(string); 275 return NULL; 276 } 277 278 bcopy(string0, string, len); 279 elm->be_val = string; 280 elm->be_len = len; 281 elm->be_free = 1; /* free string on cleanup */ 282 283 ober_link_elements(prev, elm); 284 285 return elm; 286 } 287 288 struct ber_element * 289 ober_add_ostring(struct ber_element *prev, struct ber_octetstring *s) 290 { 291 return ober_add_nstring(prev, s->ostr_val, s->ostr_len); 292 } 293 294 int 295 ober_get_string(struct ber_element *elm, char **s) 296 { 297 if (elm->be_encoding != BER_TYPE_OCTETSTRING) 298 return -1; 299 /* XXX some components use getstring on binary data containing \0 */ 300 #if 0 301 if (memchr(elm->be_val, '\0', elm->be_len) != NULL) 302 return -1; 303 #endif 304 305 if (s != NULL) 306 *s = elm->be_val; 307 return 0; 308 } 309 310 int 311 ober_get_nstring(struct ber_element *elm, void **p, size_t *len) 312 { 313 if (elm->be_encoding != BER_TYPE_OCTETSTRING) 314 return -1; 315 316 if (len != NULL) 317 *len = elm->be_len; 318 if (p != NULL) { 319 if (len != NULL) 320 *p = elm->be_val; 321 else 322 *p = NULL; 323 } 324 return 0; 325 } 326 327 int 328 ober_get_ostring(struct ber_element *elm, struct ber_octetstring *s) 329 { 330 if (elm->be_encoding != BER_TYPE_OCTETSTRING) 331 return -1; 332 333 if (s != NULL) { 334 s->ostr_val = elm->be_val; 335 s->ostr_len = elm->be_len; 336 } 337 return 0; 338 } 339 340 struct ber_element * 341 ober_add_bitstring(struct ber_element *prev, const void *v0, size_t len) 342 { 343 struct ber_element *elm; 344 void *v; 345 346 if ((v = calloc(1, len)) == NULL) 347 return NULL; 348 if ((elm = ober_get_element(BER_TYPE_BITSTRING)) == NULL) { 349 free(v); 350 return NULL; 351 } 352 353 bcopy(v0, v, len); 354 elm->be_val = v; 355 elm->be_len = len; 356 elm->be_free = 1; /* free string on cleanup */ 357 358 ober_link_elements(prev, elm); 359 360 return elm; 361 } 362 363 int 364 ober_get_bitstring(struct ber_element *elm, void **v, size_t *len) 365 { 366 if (elm->be_encoding != BER_TYPE_BITSTRING) 367 return -1; 368 369 if (len != NULL) 370 *len = elm->be_len; 371 if (v != NULL) { 372 if (len != NULL) 373 *v = elm->be_val; 374 else 375 *v = NULL; 376 } 377 return 0; 378 } 379 380 struct ber_element * 381 ober_add_null(struct ber_element *prev) 382 { 383 struct ber_element *elm; 384 385 if ((elm = ober_get_element(BER_TYPE_NULL)) == NULL) 386 return NULL; 387 388 ober_link_elements(prev, elm); 389 390 return elm; 391 } 392 393 int 394 ober_get_null(struct ber_element *elm) 395 { 396 if (elm->be_encoding != BER_TYPE_NULL) 397 return -1; 398 399 return 0; 400 } 401 402 struct ber_element * 403 ober_add_eoc(struct ber_element *prev) 404 { 405 struct ber_element *elm; 406 407 if ((elm = ober_get_element(BER_TYPE_EOC)) == NULL) 408 return NULL; 409 410 ober_link_elements(prev, elm); 411 412 return elm; 413 } 414 415 int 416 ober_get_eoc(struct ber_element *elm) 417 { 418 if (elm->be_encoding != BER_TYPE_EOC) 419 return -1; 420 421 return 0; 422 } 423 424 size_t 425 ober_oid2ber(struct ber_oid *o, u_int8_t *buf, size_t len) 426 { 427 u_int32_t v; 428 u_int i, j = 0, k; 429 430 if (o->bo_n < BER_MIN_OID_LEN || o->bo_n > BER_MAX_OID_LEN || 431 o->bo_id[0] > 2 || o->bo_id[1] > 40) 432 return (0); 433 434 v = (o->bo_id[0] * 40) + o->bo_id[1]; 435 for (i = 2, j = 0; i <= o->bo_n; v = o->bo_id[i], i++) { 436 for (k = 28; k >= 7; k -= 7) { 437 if (v >= (u_int)(1 << k)) { 438 if (len) 439 buf[j] = v >> k | BER_TAG_MORE; 440 j++; 441 } 442 } 443 if (len) 444 buf[j] = v & BER_TAG_TYPE_MASK; 445 j++; 446 } 447 448 return (j); 449 } 450 451 int 452 ober_string2oid(const char *oidstr, struct ber_oid *o) 453 { 454 char *sp, *p, str[BUFSIZ]; 455 const char *errstr; 456 457 if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str)) 458 return (-1); 459 memset(o, 0, sizeof(*o)); 460 461 /* Parse OID strings in the common forms n.n.n, n_n_n_n, or n-n-n */ 462 for (p = sp = str; p != NULL; sp = p) { 463 if ((p = strpbrk(p, "._-")) != NULL) 464 *p++ = '\0'; 465 o->bo_id[o->bo_n++] = strtonum(sp, 0, UINT_MAX, &errstr); 466 if (errstr || o->bo_n > BER_MAX_OID_LEN) 467 return (-1); 468 } 469 470 return (0); 471 } 472 473 int 474 ober_oid_cmp(struct ber_oid *a, struct ber_oid *b) 475 { 476 size_t i, min; 477 478 min = a->bo_n < b->bo_n ? a->bo_n : b->bo_n; 479 for (i = 0; i < min; i++) { 480 if (a->bo_id[i] < b->bo_id[i]) 481 return (-1); 482 if (a->bo_id[i] > b->bo_id[i]) 483 return (1); 484 } 485 /* a is parent of b */ 486 if (a->bo_n < b->bo_n) 487 return (-2); 488 /* a is child of b */ 489 if (a->bo_n > b->bo_n) 490 return 2; 491 return (0); 492 } 493 494 struct ber_element * 495 ober_add_oid(struct ber_element *prev, struct ber_oid *o) 496 { 497 struct ber_element *elm; 498 u_int8_t *buf; 499 size_t len; 500 501 if ((elm = ober_get_element(BER_TYPE_OBJECT)) == NULL) 502 return (NULL); 503 504 if ((len = ober_oid2ber(o, NULL, 0)) == 0) 505 goto fail; 506 507 if ((buf = calloc(1, len)) == NULL) 508 goto fail; 509 510 elm->be_val = buf; 511 elm->be_len = len; 512 elm->be_free = 1; 513 514 if (ober_oid2ber(o, buf, len) != len) 515 goto fail; 516 517 ober_link_elements(prev, elm); 518 519 return (elm); 520 521 fail: 522 ober_free_elements(elm); 523 return (NULL); 524 } 525 526 struct ber_element * 527 ober_add_noid(struct ber_element *prev, struct ber_oid *o, int n) 528 { 529 struct ber_oid no; 530 531 if (n > BER_MAX_OID_LEN) 532 return (NULL); 533 no.bo_n = n; 534 bcopy(&o->bo_id, &no.bo_id, sizeof(no.bo_id)); 535 536 return (ober_add_oid(prev, &no)); 537 } 538 539 struct ber_element * 540 ober_add_oidstring(struct ber_element *prev, const char *oidstr) 541 { 542 struct ber_oid o; 543 544 if (ober_string2oid(oidstr, &o) == -1) 545 return (NULL); 546 547 return (ober_add_oid(prev, &o)); 548 } 549 550 int 551 ober_get_oid(struct ber_element *elm, struct ber_oid *o) 552 { 553 u_int8_t *buf; 554 size_t len, i = 0, j = 0; 555 556 if (elm->be_encoding != BER_TYPE_OBJECT) 557 return (-1); 558 559 if (o == NULL) 560 return 0; 561 562 buf = elm->be_val; 563 len = elm->be_len; 564 565 memset(o, 0, sizeof(*o)); 566 o->bo_id[j++] = buf[i] / 40; 567 o->bo_id[j++] = buf[i++] % 40; 568 for (; i < len && j < BER_MAX_OID_LEN; i++) { 569 o->bo_id[j] = (o->bo_id[j] << 7) + (buf[i] & ~0x80); 570 if (buf[i] & 0x80) 571 continue; 572 j++; 573 } 574 o->bo_n = j; 575 576 return (0); 577 } 578 579 #define _MAX_SEQ 128 580 struct ber_element * 581 ober_printf_elements(struct ber_element *ber, char *fmt, ...) 582 { 583 va_list ap; 584 int d, class, level = 0; 585 size_t len; 586 unsigned int type; 587 long long i; 588 char *s; 589 void *p; 590 struct ber_oid *o; 591 struct ber_element *parent[_MAX_SEQ], *e; 592 struct ber_element *origber = ber, *firstber = NULL; 593 594 memset(parent, 0, sizeof(struct ber_element *) * _MAX_SEQ); 595 596 va_start(ap, fmt); 597 598 while (*fmt) { 599 switch (*fmt++) { 600 case 'B': 601 p = va_arg(ap, void *); 602 len = va_arg(ap, size_t); 603 if ((ber = ober_add_bitstring(ber, p, len)) == NULL) 604 goto fail; 605 break; 606 case 'b': 607 d = va_arg(ap, int); 608 if ((ber = ober_add_boolean(ber, d)) == NULL) 609 goto fail; 610 break; 611 case 'd': 612 d = va_arg(ap, int); 613 if ((ber = ober_add_integer(ber, d)) == NULL) 614 goto fail; 615 break; 616 case 'e': 617 e = va_arg(ap, struct ber_element *); 618 ober_link_elements(ber, e); 619 break; 620 case 'E': 621 i = va_arg(ap, long long); 622 if ((ber = ober_add_enumerated(ber, i)) == NULL) 623 goto fail; 624 break; 625 case 'i': 626 i = va_arg(ap, long long); 627 if ((ber = ober_add_integer(ber, i)) == NULL) 628 goto fail; 629 break; 630 case 'O': 631 o = va_arg(ap, struct ber_oid *); 632 if ((ber = ober_add_oid(ber, o)) == NULL) 633 goto fail; 634 break; 635 case 'o': 636 s = va_arg(ap, char *); 637 if ((ber = ober_add_oidstring(ber, s)) == NULL) 638 goto fail; 639 break; 640 case 's': 641 s = va_arg(ap, char *); 642 if ((ber = ober_add_string(ber, s)) == NULL) 643 goto fail; 644 break; 645 case 't': 646 class = va_arg(ap, int); 647 type = va_arg(ap, unsigned int); 648 ober_set_header(ber, class, type); 649 break; 650 case 'x': 651 s = va_arg(ap, char *); 652 len = va_arg(ap, size_t); 653 if ((ber = ober_add_nstring(ber, s, len)) == NULL) 654 goto fail; 655 break; 656 case '0': 657 if ((ber = ober_add_null(ber)) == NULL) 658 goto fail; 659 break; 660 case '{': 661 if (level >= _MAX_SEQ-1) 662 goto fail; 663 if ((ber= ober_add_sequence(ber)) == NULL) 664 goto fail; 665 parent[level++] = ber; 666 break; 667 case '(': 668 if (level >= _MAX_SEQ-1) 669 goto fail; 670 if ((ber = ober_add_set(ber)) == NULL) 671 goto fail; 672 parent[level++] = ber; 673 break; 674 case '}': 675 case ')': 676 if (level <= 0 || parent[level - 1] == NULL) 677 goto fail; 678 ber = parent[--level]; 679 break; 680 case '.': 681 if ((e = ober_add_eoc(ber)) == NULL) 682 goto fail; 683 ber = e; 684 break; 685 default: 686 break; 687 } 688 if (firstber == NULL) 689 firstber = ber; 690 } 691 va_end(ap); 692 693 return (ber); 694 fail: 695 if (origber != NULL) 696 ober_unlink_elements(origber); 697 ober_free_elements(firstber); 698 return (NULL); 699 } 700 701 int 702 ober_scanf_elements(struct ber_element *ber, char *fmt, ...) 703 { 704 va_list ap; 705 int *d, level = -1; 706 unsigned int *t; 707 long long *i, l; 708 void **ptr; 709 size_t *len, ret = 0, n = strlen(fmt); 710 char **s; 711 off_t *pos; 712 struct ber_oid *o; 713 struct ber_element *parent[_MAX_SEQ], **e; 714 715 memset(parent, 0, sizeof(struct ber_element *) * _MAX_SEQ); 716 717 va_start(ap, fmt); 718 while (*fmt) { 719 if (ber == NULL && *fmt != '$' && *fmt != '}' && *fmt != ')') 720 goto fail; 721 switch (*fmt++) { 722 case '$': 723 if (ber != NULL) 724 goto fail; 725 ret++; 726 continue; 727 case 'B': 728 ptr = va_arg(ap, void **); 729 len = va_arg(ap, size_t *); 730 if (ober_get_bitstring(ber, ptr, len) == -1) 731 goto fail; 732 ret++; 733 break; 734 case 'b': 735 d = va_arg(ap, int *); 736 if (ober_get_boolean(ber, d) == -1) 737 goto fail; 738 ret++; 739 break; 740 case 'd': 741 d = va_arg(ap, int *); 742 if (ober_get_integer(ber, &l) == -1) 743 goto fail; 744 if (d != NULL) 745 *d = l; 746 ret++; 747 break; 748 case 'e': 749 e = va_arg(ap, struct ber_element **); 750 *e = ber; 751 ret++; 752 continue; 753 case 'E': 754 i = va_arg(ap, long long *); 755 if (ober_get_enumerated(ber, i) == -1) 756 goto fail; 757 ret++; 758 break; 759 case 'i': 760 i = va_arg(ap, long long *); 761 if (ober_get_integer(ber, i) == -1) 762 goto fail; 763 ret++; 764 break; 765 case 'o': 766 o = va_arg(ap, struct ber_oid *); 767 if (ober_get_oid(ber, o) == -1) 768 goto fail; 769 ret++; 770 break; 771 case 'S': 772 ret++; 773 break; 774 case 's': 775 s = va_arg(ap, char **); 776 if (ober_get_string(ber, s) == -1) 777 goto fail; 778 ret++; 779 break; 780 case 't': 781 d = va_arg(ap, int *); 782 t = va_arg(ap, unsigned int *); 783 if (d != NULL) 784 *d = ber->be_class; 785 if (t != NULL) 786 *t = ber->be_type; 787 ret++; 788 continue; 789 case 'x': 790 ptr = va_arg(ap, void **); 791 len = va_arg(ap, size_t *); 792 if (ober_get_nstring(ber, ptr, len) == -1) 793 goto fail; 794 ret++; 795 break; 796 case '0': 797 if (ber->be_encoding != BER_TYPE_NULL) 798 goto fail; 799 ret++; 800 break; 801 case '.': 802 if (ber->be_encoding != BER_TYPE_EOC) 803 goto fail; 804 ret++; 805 break; 806 case 'p': 807 pos = va_arg(ap, off_t *); 808 *pos = ober_getpos(ber); 809 ret++; 810 continue; 811 case '{': 812 case '(': 813 if (ber->be_encoding != BER_TYPE_SEQUENCE && 814 ber->be_encoding != BER_TYPE_SET) 815 goto fail; 816 if (level >= _MAX_SEQ-1) 817 goto fail; 818 parent[++level] = ber; 819 ber = ber->be_sub; 820 ret++; 821 continue; 822 case '}': 823 case ')': 824 if (level < 0 || parent[level] == NULL) 825 goto fail; 826 ber = parent[level--]; 827 ret++; 828 break; 829 default: 830 goto fail; 831 } 832 833 ber = ber->be_next; 834 } 835 va_end(ap); 836 return (ret == n ? 0 : -1); 837 838 fail: 839 va_end(ap); 840 return (-1); 841 842 } 843 844 ssize_t 845 ober_get_writebuf(struct ber *b, void **buf) 846 { 847 if (b->br_wbuf == NULL) 848 return -1; 849 *buf = b->br_wbuf; 850 return (b->br_wend - b->br_wbuf); 851 } 852 853 /* 854 * write ber elements to the write buffer 855 * 856 * params: 857 * ber holds the destination write buffer byte stream 858 * root fully populated element tree 859 * 860 * returns: 861 * >=0 number of bytes written 862 * -1 on failure and sets errno 863 */ 864 ssize_t 865 ober_write_elements(struct ber *ber, struct ber_element *root) 866 { 867 size_t len; 868 869 /* calculate length because only the definite form is required */ 870 len = ober_calc_len(root); 871 DPRINTF("write ber element of %zd bytes length\n", len); 872 873 if (ber->br_wbuf != NULL && ber->br_wbuf + len > ber->br_wend) { 874 free(ber->br_wbuf); 875 ber->br_wbuf = NULL; 876 } 877 if (ber->br_wbuf == NULL) { 878 if ((ber->br_wbuf = malloc(len)) == NULL) 879 return -1; 880 ber->br_wend = ber->br_wbuf + len; 881 } 882 883 /* reset write pointer */ 884 ber->br_wptr = ber->br_wbuf; 885 886 if (ober_dump_element(ber, root) == -1) 887 return -1; 888 889 return (len); 890 } 891 892 void 893 ober_set_readbuf(struct ber *b, void *buf, size_t len) 894 { 895 b->br_rbuf = b->br_rptr = buf; 896 b->br_rend = (u_int8_t *)buf + len; 897 } 898 899 /* 900 * read ber elements from the read buffer 901 * 902 * params: 903 * ber holds a fully populated read buffer byte stream 904 * root if NULL, build up an element tree from what we receive on 905 * the wire. If not null, use the specified encoding for the 906 * elements received. 907 * 908 * returns: 909 * !=NULL, elements read and store in the ber_element tree 910 * NULL, type mismatch or read error 911 */ 912 struct ber_element * 913 ober_read_elements(struct ber *ber, struct ber_element *elm) 914 { 915 struct ber_element *root = elm; 916 917 if (root == NULL) { 918 if ((root = ober_get_element(0)) == NULL) 919 return NULL; 920 } 921 922 DPRINTF("read ber elements, root %p\n", root); 923 924 if (ober_read_element(ber, root) == -1) { 925 /* Cleanup if root was allocated by us */ 926 if (elm == NULL) 927 ober_free_elements(root); 928 return NULL; 929 } 930 931 return root; 932 } 933 934 off_t 935 ober_getpos(struct ber_element *elm) 936 { 937 return elm->be_offs; 938 } 939 940 struct ber_element * 941 ober_dup(struct ber_element *orig) 942 { 943 struct ber_element *new; 944 945 if ((new = malloc(sizeof(*new))) == NULL) 946 return NULL; 947 memcpy(new, orig, sizeof(*new)); 948 new->be_next = NULL; 949 new->be_sub = NULL; 950 951 if (orig->be_next != NULL) { 952 if ((new->be_next = ober_dup(orig->be_next)) == NULL) 953 goto fail; 954 } 955 if (orig->be_encoding == BER_TYPE_SEQUENCE || 956 orig->be_encoding == BER_TYPE_SET) { 957 if (orig->be_sub != NULL) { 958 if ((new->be_sub = ober_dup(orig->be_sub)) == NULL) 959 goto fail; 960 } 961 } else if (orig->be_encoding == BER_TYPE_OCTETSTRING || 962 orig->be_encoding == BER_TYPE_BITSTRING || 963 orig->be_encoding == BER_TYPE_OBJECT) { 964 if (orig->be_val != NULL) { 965 if ((new->be_val = malloc(orig->be_len)) == NULL) 966 goto fail; 967 memcpy(new->be_val, orig->be_val, orig->be_len); 968 } 969 } else 970 new->be_numeric = orig->be_numeric; 971 return new; 972 fail: 973 ober_free_elements(new); 974 return NULL; 975 } 976 977 void 978 ober_free_element(struct ber_element *root) 979 { 980 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 981 root->be_encoding == BER_TYPE_SET)) 982 ober_free_elements(root->be_sub); 983 if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || 984 root->be_encoding == BER_TYPE_BITSTRING || 985 root->be_encoding == BER_TYPE_OBJECT)) 986 free(root->be_val); 987 free(root); 988 } 989 990 void 991 ober_free_elements(struct ber_element *root) 992 { 993 if (root == NULL) 994 return; 995 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 996 root->be_encoding == BER_TYPE_SET)) 997 ober_free_elements(root->be_sub); 998 if (root->be_next) 999 ober_free_elements(root->be_next); 1000 if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || 1001 root->be_encoding == BER_TYPE_BITSTRING || 1002 root->be_encoding == BER_TYPE_OBJECT)) 1003 free(root->be_val); 1004 free(root); 1005 } 1006 1007 size_t 1008 ober_calc_len(struct ber_element *root) 1009 { 1010 unsigned int t; 1011 size_t s; 1012 size_t size = 2; /* minimum 1 byte head and 1 byte size */ 1013 1014 /* calculate the real length of a sequence or set */ 1015 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 1016 root->be_encoding == BER_TYPE_SET)) 1017 root->be_len = ober_calc_len(root->be_sub); 1018 1019 /* fix header length for extended types */ 1020 if (root->be_type > BER_TYPE_SINGLE_MAX) 1021 for (t = root->be_type; t > 0; t >>= 7) 1022 size++; 1023 if (root->be_len >= BER_TAG_MORE) 1024 for (s = root->be_len; s > 0; s >>= 8) 1025 size++; 1026 1027 /* calculate the length of the following elements */ 1028 if (root->be_next) 1029 size += ober_calc_len(root->be_next); 1030 1031 /* This is an empty element, do not use a minimal size */ 1032 if (root->be_class == BER_CLASS_UNIVERSAL && 1033 root->be_type == BER_TYPE_EOC && root->be_len == 0) 1034 return (0); 1035 1036 return (root->be_len + size); 1037 } 1038 1039 void 1040 ober_set_application(struct ber *b, unsigned int (*cb)(struct ber_element *)) 1041 { 1042 b->br_application = cb; 1043 } 1044 1045 void 1046 ober_set_writecallback(struct ber_element *elm, void (*cb)(void *, size_t), 1047 void *arg) 1048 { 1049 elm->be_cb = cb; 1050 elm->be_cbarg = arg; 1051 } 1052 1053 void 1054 ober_free(struct ber *b) 1055 { 1056 free(b->br_wbuf); 1057 } 1058 1059 /* 1060 * internal functions 1061 */ 1062 1063 static int 1064 ober_dump_element(struct ber *ber, struct ber_element *root) 1065 { 1066 unsigned long long l; 1067 int i; 1068 uint8_t u; 1069 1070 ober_dump_header(ber, root); 1071 if (root->be_cb) 1072 root->be_cb(root->be_cbarg, ber->br_wptr - ber->br_wbuf); 1073 1074 switch (root->be_encoding) { 1075 case BER_TYPE_BOOLEAN: 1076 case BER_TYPE_INTEGER: 1077 case BER_TYPE_ENUMERATED: 1078 l = (unsigned long long)root->be_numeric; 1079 for (i = root->be_len; i > 0; i--) { 1080 u = (l >> ((i - 1) * 8)) & 0xff; 1081 ober_putc(ber, u); 1082 } 1083 break; 1084 case BER_TYPE_BITSTRING: 1085 case BER_TYPE_OCTETSTRING: 1086 case BER_TYPE_OBJECT: 1087 ober_write(ber, root->be_val, root->be_len); 1088 break; 1089 case BER_TYPE_NULL: /* no payload */ 1090 case BER_TYPE_EOC: 1091 break; 1092 case BER_TYPE_SEQUENCE: 1093 case BER_TYPE_SET: 1094 if (root->be_sub && ober_dump_element(ber, root->be_sub) == -1) 1095 return -1; 1096 break; 1097 } 1098 1099 if (root->be_next == NULL) 1100 return 0; 1101 return ober_dump_element(ber, root->be_next); 1102 } 1103 1104 static void 1105 ober_dump_header(struct ber *ber, struct ber_element *root) 1106 { 1107 u_char id = 0, t, buf[5]; 1108 unsigned int type; 1109 size_t size; 1110 1111 /* class universal, type encoding depending on type value */ 1112 /* length encoding */ 1113 if (root->be_type <= BER_TYPE_SINGLE_MAX) { 1114 id = root->be_type | (root->be_class << BER_CLASS_SHIFT); 1115 if (root->be_encoding == BER_TYPE_SEQUENCE || 1116 root->be_encoding == BER_TYPE_SET) 1117 id |= BER_TYPE_CONSTRUCTED; 1118 1119 ober_putc(ber, id); 1120 } else { 1121 id = BER_TAG_MASK | (root->be_class << BER_CLASS_SHIFT); 1122 if (root->be_encoding == BER_TYPE_SEQUENCE || 1123 root->be_encoding == BER_TYPE_SET) 1124 id |= BER_TYPE_CONSTRUCTED; 1125 1126 ober_putc(ber, id); 1127 1128 for (t = 0, type = root->be_type; type > 0; type >>= 7) 1129 buf[t++] = type & ~BER_TAG_MORE; 1130 1131 while (t-- > 0) { 1132 if (t > 0) 1133 buf[t] |= BER_TAG_MORE; 1134 ober_putc(ber, buf[t]); 1135 } 1136 } 1137 1138 if (root->be_len < BER_TAG_MORE) { 1139 /* short form */ 1140 ober_putc(ber, root->be_len); 1141 } else { 1142 for (t = 0, size = root->be_len; size > 0; size >>= 8) 1143 buf[t++] = size & 0xff; 1144 1145 ober_putc(ber, t | BER_TAG_MORE); 1146 1147 while (t > 0) 1148 ober_putc(ber, buf[--t]); 1149 } 1150 } 1151 1152 static void 1153 ober_putc(struct ber *ber, u_char c) 1154 { 1155 if (ber->br_wptr + 1 <= ber->br_wend) 1156 *ber->br_wptr = c; 1157 ber->br_wptr++; 1158 } 1159 1160 static void 1161 ober_write(struct ber *ber, void *buf, size_t len) 1162 { 1163 if (ber->br_wptr + len <= ber->br_wend) 1164 bcopy(buf, ber->br_wptr, len); 1165 ber->br_wptr += len; 1166 } 1167 1168 /* 1169 * extract a BER encoded tag. There are two types, a short and long form. 1170 */ 1171 static ssize_t 1172 get_id(struct ber *b, unsigned int *tag, int *class, int *cstruct) 1173 { 1174 u_char u; 1175 size_t i = 0; 1176 unsigned int t = 0; 1177 1178 if (ober_getc(b, &u) == -1) 1179 return -1; 1180 1181 *class = (u >> BER_CLASS_SHIFT) & BER_CLASS_MASK; 1182 *cstruct = (u & BER_TYPE_CONSTRUCTED) == BER_TYPE_CONSTRUCTED; 1183 1184 if ((u & BER_TAG_MASK) != BER_TAG_MASK) { 1185 *tag = u & BER_TAG_MASK; 1186 return 1; 1187 } 1188 1189 do { 1190 if (ober_getc(b, &u) == -1) 1191 return -1; 1192 1193 /* enforce minimal number of octets for tag > 30 */ 1194 if (i == 0 && (u & ~BER_TAG_MORE) == 0) { 1195 errno = EINVAL; 1196 return -1; 1197 } 1198 1199 t = (t << 7) | (u & ~BER_TAG_MORE); 1200 i++; 1201 if (i > sizeof(unsigned int)) { 1202 errno = ERANGE; 1203 return -1; 1204 } 1205 } while (u & BER_TAG_MORE); 1206 1207 *tag = t; 1208 return i + 1; 1209 } 1210 1211 /* 1212 * extract length of a ber object -- if length is unknown an error is returned. 1213 */ 1214 static ssize_t 1215 get_len(struct ber *b, ssize_t *len) 1216 { 1217 u_char u, n; 1218 ssize_t s, r; 1219 1220 if (ober_getc(b, &u) == -1) 1221 return -1; 1222 if ((u & BER_TAG_MORE) == 0) { 1223 /* short form */ 1224 *len = u; 1225 return 1; 1226 } 1227 1228 if (u == 0x80) { 1229 /* Indefinite length not supported. */ 1230 errno = EINVAL; 1231 return -1; 1232 } 1233 1234 if (u == 0xff) { 1235 /* Reserved for future use. */ 1236 errno = EINVAL; 1237 return -1; 1238 } 1239 1240 n = u & ~BER_TAG_MORE; 1241 /* 1242 * Limit to a decent size that works on all of our architectures. 1243 */ 1244 if (sizeof(int32_t) < n) { 1245 errno = ERANGE; 1246 return -1; 1247 } 1248 r = n + 1; 1249 1250 for (s = 0; n > 0; n--) { 1251 if (ober_getc(b, &u) == -1) 1252 return -1; 1253 s = (s << 8) | u; 1254 } 1255 1256 if (s < 0) { 1257 /* overflow */ 1258 errno = ERANGE; 1259 return -1; 1260 } 1261 1262 *len = s; 1263 return r; 1264 } 1265 1266 static ssize_t 1267 ober_read_element(struct ber *ber, struct ber_element *elm) 1268 { 1269 long long val = 0; 1270 struct ber_element *next; 1271 unsigned int type; 1272 int i, class, cstruct, elements = 0; 1273 ssize_t len, r, totlen = 0; 1274 u_char c, last = 0; 1275 1276 if ((r = get_id(ber, &type, &class, &cstruct)) == -1) 1277 return -1; 1278 DPRINTF("ber read got class %d type %u, %s\n", 1279 class, type, cstruct ? "constructed" : "primitive"); 1280 totlen += r; 1281 if ((r = get_len(ber, &len)) == -1) 1282 return -1; 1283 DPRINTF("ber read element size %zd\n", len); 1284 totlen += r + len; 1285 1286 /* The encoding of boolean, integer, enumerated, and null values 1287 * must be primitive. */ 1288 if (class == BER_CLASS_UNIVERSAL) 1289 if (type == BER_TYPE_BOOLEAN || 1290 type == BER_TYPE_INTEGER || 1291 type == BER_TYPE_ENUMERATED || 1292 type == BER_TYPE_NULL) 1293 if (cstruct) { 1294 errno = EINVAL; 1295 return -1; 1296 } 1297 1298 /* If the total size of the element is larger than the buffer 1299 * don't bother to continue. */ 1300 if (len > ber->br_rend - ber->br_rptr) { 1301 errno = ECANCELED; 1302 return -1; 1303 } 1304 1305 elm->be_type = type; 1306 elm->be_len = len; 1307 elm->be_offs = ber->br_offs; /* element position within stream */ 1308 elm->be_class = class; 1309 1310 if (elm->be_encoding == 0) { 1311 /* try to figure out the encoding via class, type and cstruct */ 1312 if (cstruct) 1313 elm->be_encoding = BER_TYPE_SEQUENCE; 1314 else if (class == BER_CLASS_UNIVERSAL) 1315 elm->be_encoding = type; 1316 else if (ber->br_application != NULL) { 1317 /* 1318 * Ask the application to map the encoding to a 1319 * universal type. For example, a SMI IpAddress 1320 * type is defined as 4 byte OCTET STRING. 1321 */ 1322 elm->be_encoding = (*ber->br_application)(elm); 1323 } else 1324 /* last resort option */ 1325 elm->be_encoding = BER_TYPE_NULL; 1326 } 1327 1328 switch (elm->be_encoding) { 1329 case BER_TYPE_EOC: /* End-Of-Content */ 1330 break; 1331 case BER_TYPE_BOOLEAN: 1332 if (len != 1) { 1333 errno = EINVAL; 1334 return -1; 1335 } 1336 case BER_TYPE_INTEGER: 1337 case BER_TYPE_ENUMERATED: 1338 if (len < 1) { 1339 errno = EINVAL; 1340 return -1; 1341 } 1342 if (len > (ssize_t)sizeof(long long)) { 1343 errno = ERANGE; 1344 return -1; 1345 } 1346 for (i = 0; i < len; i++) { 1347 if (ober_getc(ber, &c) != 1) 1348 return -1; 1349 1350 /* smallest number of contents octets only */ 1351 if ((i == 1 && last == 0 && (c & 0x80) == 0) || 1352 (i == 1 && last == 0xff && (c & 0x80) != 0)) { 1353 errno = EINVAL; 1354 return -1; 1355 } 1356 1357 val <<= 8; 1358 val |= c; 1359 last = c; 1360 } 1361 1362 /* sign extend if MSB is set */ 1363 if (len < (ssize_t)sizeof(long long) && 1364 (val >> ((len - 1) * 8) & 0x80)) 1365 val |= ULLONG_MAX << (len * 8); 1366 elm->be_numeric = val; 1367 break; 1368 case BER_TYPE_BITSTRING: 1369 elm->be_val = malloc(len); 1370 if (elm->be_val == NULL) 1371 return -1; 1372 elm->be_free = 1; 1373 elm->be_len = len; 1374 ober_read(ber, elm->be_val, len); 1375 break; 1376 case BER_TYPE_OCTETSTRING: 1377 case BER_TYPE_OBJECT: 1378 elm->be_val = malloc(len + 1); 1379 if (elm->be_val == NULL) 1380 return -1; 1381 elm->be_free = 1; 1382 elm->be_len = len; 1383 ober_read(ber, elm->be_val, len); 1384 ((u_char *)elm->be_val)[len] = '\0'; 1385 break; 1386 case BER_TYPE_NULL: /* no payload */ 1387 if (len != 0) { 1388 errno = EINVAL; 1389 return -1; 1390 } 1391 break; 1392 case BER_TYPE_SEQUENCE: 1393 case BER_TYPE_SET: 1394 if (len > 0 && elm->be_sub == NULL) { 1395 if ((elm->be_sub = ober_get_element(0)) == NULL) 1396 return -1; 1397 } 1398 next = elm->be_sub; 1399 while (len > 0) { 1400 /* 1401 * Prevent stack overflow from excessive recursion 1402 * depth in ober_free_elements(). 1403 */ 1404 if (elements >= BER_MAX_SEQ_ELEMENTS) { 1405 errno = ERANGE; 1406 return -1; 1407 } 1408 r = ober_read_element(ber, next); 1409 if (r == -1) { 1410 /* sub-element overflows sequence/set */ 1411 if (errno == ECANCELED) 1412 errno = EINVAL; 1413 return -1; 1414 } 1415 if (r > len) { 1416 errno = EINVAL; 1417 return -1; 1418 } 1419 elements++; 1420 len -= r; 1421 if (len > 0 && next->be_next == NULL) { 1422 next->be_next = ober_get_element(0); 1423 if (next->be_next == NULL) 1424 return -1; 1425 } 1426 next = next->be_next; 1427 } 1428 break; 1429 } 1430 return totlen; 1431 } 1432 1433 static ssize_t 1434 ober_getc(struct ber *b, u_char *c) 1435 { 1436 return ober_read(b, c, 1); 1437 } 1438 1439 static ssize_t 1440 ober_read(struct ber *ber, void *buf, size_t len) 1441 { 1442 size_t sz; 1443 1444 if (ber->br_rbuf == NULL) { 1445 errno = ENOBUFS; 1446 return -1; 1447 } 1448 1449 sz = ber->br_rend - ber->br_rptr; 1450 if (len > sz) { 1451 errno = ECANCELED; 1452 return -1; /* parser wants more data than available */ 1453 } 1454 1455 bcopy(ber->br_rptr, buf, len); 1456 ber->br_rptr += len; 1457 ber->br_offs += len; 1458 1459 return len; 1460 } 1461