1 /* $OpenBSD: ber.c,v 1.22 2021/08/29 13:27:11 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; 477 for (i = 0; i < a->bo_n && i < b->bo_n; i++) { 478 if (a->bo_id[i] == b->bo_id[i]) 479 continue; 480 else if (a->bo_id[i] < b->bo_id[i]) { 481 /* b is a successor of a */ 482 return (1); 483 } else { 484 /* b is a predecessor of a */ 485 return (-1); 486 } 487 } 488 /* b is larger, but a child of a */ 489 if (a->bo_n < b->bo_n) 490 return (2); 491 /* b is a predecessor of a */ 492 if (a->bo_n > b->bo_n) 493 return -1; 494 495 /* b and a are identical */ 496 return (0); 497 } 498 499 struct ber_element * 500 ober_add_oid(struct ber_element *prev, struct ber_oid *o) 501 { 502 struct ber_element *elm; 503 u_int8_t *buf; 504 size_t len; 505 506 if ((elm = ober_get_element(BER_TYPE_OBJECT)) == NULL) 507 return (NULL); 508 509 if ((len = ober_oid2ber(o, NULL, 0)) == 0) 510 goto fail; 511 512 if ((buf = calloc(1, len)) == NULL) 513 goto fail; 514 515 elm->be_val = buf; 516 elm->be_len = len; 517 elm->be_free = 1; 518 519 if (ober_oid2ber(o, buf, len) != len) 520 goto fail; 521 522 ober_link_elements(prev, elm); 523 524 return (elm); 525 526 fail: 527 ober_free_elements(elm); 528 return (NULL); 529 } 530 531 struct ber_element * 532 ober_add_noid(struct ber_element *prev, struct ber_oid *o, int n) 533 { 534 struct ber_oid no; 535 536 if (n > BER_MAX_OID_LEN) 537 return (NULL); 538 no.bo_n = n; 539 bcopy(&o->bo_id, &no.bo_id, sizeof(no.bo_id)); 540 541 return (ober_add_oid(prev, &no)); 542 } 543 544 struct ber_element * 545 ober_add_oidstring(struct ber_element *prev, const char *oidstr) 546 { 547 struct ber_oid o; 548 549 if (ober_string2oid(oidstr, &o) == -1) 550 return (NULL); 551 552 return (ober_add_oid(prev, &o)); 553 } 554 555 int 556 ober_get_oid(struct ber_element *elm, struct ber_oid *o) 557 { 558 u_int8_t *buf; 559 size_t len, i = 0, j = 0; 560 561 if (elm->be_encoding != BER_TYPE_OBJECT) 562 return (-1); 563 564 if (o == NULL) 565 return 0; 566 567 buf = elm->be_val; 568 len = elm->be_len; 569 570 memset(o, 0, sizeof(*o)); 571 o->bo_id[j++] = buf[i] / 40; 572 o->bo_id[j++] = buf[i++] % 40; 573 for (; i < len && j < BER_MAX_OID_LEN; i++) { 574 o->bo_id[j] = (o->bo_id[j] << 7) + (buf[i] & ~0x80); 575 if (buf[i] & 0x80) 576 continue; 577 j++; 578 } 579 o->bo_n = j; 580 581 return (0); 582 } 583 584 struct ber_element * 585 ober_printf_elements(struct ber_element *ber, char *fmt, ...) 586 { 587 va_list ap; 588 int d, class; 589 size_t len; 590 unsigned int type; 591 long long i; 592 char *s; 593 void *p; 594 struct ber_oid *o; 595 struct ber_element *sub = ber, *e; 596 597 va_start(ap, fmt); 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 ((ber = sub = ober_add_sequence(ber)) == NULL) 662 goto fail; 663 break; 664 case '(': 665 if ((ber = sub = ober_add_set(ber)) == NULL) 666 goto fail; 667 break; 668 case '}': 669 case ')': 670 ber = sub; 671 break; 672 case '.': 673 if ((e = ober_add_eoc(ber)) == NULL) 674 goto fail; 675 ber = e; 676 break; 677 default: 678 break; 679 } 680 } 681 va_end(ap); 682 683 return (ber); 684 fail: 685 ober_free_elements(ber); 686 return (NULL); 687 } 688 689 int 690 ober_scanf_elements(struct ber_element *ber, char *fmt, ...) 691 { 692 #define _MAX_SEQ 128 693 va_list ap; 694 int *d, level = -1; 695 unsigned int *t; 696 long long *i, l; 697 void **ptr; 698 size_t *len, ret = 0, n = strlen(fmt); 699 char **s; 700 off_t *pos; 701 struct ber_oid *o; 702 struct ber_element *parent[_MAX_SEQ], **e; 703 704 memset(parent, 0, sizeof(struct ber_element *) * _MAX_SEQ); 705 706 va_start(ap, fmt); 707 while (*fmt) { 708 if (ber == NULL && *fmt != '$' && *fmt != '}' && *fmt != ')') 709 goto fail; 710 switch (*fmt++) { 711 case '$': 712 if (ber != NULL) 713 goto fail; 714 ret++; 715 continue; 716 case 'B': 717 ptr = va_arg(ap, void **); 718 len = va_arg(ap, size_t *); 719 if (ober_get_bitstring(ber, ptr, len) == -1) 720 goto fail; 721 ret++; 722 break; 723 case 'b': 724 d = va_arg(ap, int *); 725 if (ober_get_boolean(ber, d) == -1) 726 goto fail; 727 ret++; 728 break; 729 case 'd': 730 d = va_arg(ap, int *); 731 if (ober_get_integer(ber, &l) == -1) 732 goto fail; 733 if (d != NULL) 734 *d = l; 735 ret++; 736 break; 737 case 'e': 738 e = va_arg(ap, struct ber_element **); 739 *e = ber; 740 ret++; 741 continue; 742 case 'E': 743 i = va_arg(ap, long long *); 744 if (ober_get_enumerated(ber, i) == -1) 745 goto fail; 746 ret++; 747 break; 748 case 'i': 749 i = va_arg(ap, long long *); 750 if (ober_get_integer(ber, i) == -1) 751 goto fail; 752 ret++; 753 break; 754 case 'o': 755 o = va_arg(ap, struct ber_oid *); 756 if (ober_get_oid(ber, o) == -1) 757 goto fail; 758 ret++; 759 break; 760 case 'S': 761 ret++; 762 break; 763 case 's': 764 s = va_arg(ap, char **); 765 if (ober_get_string(ber, s) == -1) 766 goto fail; 767 ret++; 768 break; 769 case 't': 770 d = va_arg(ap, int *); 771 t = va_arg(ap, unsigned int *); 772 if (d != NULL) 773 *d = ber->be_class; 774 if (t != NULL) 775 *t = ber->be_type; 776 ret++; 777 continue; 778 case 'x': 779 ptr = va_arg(ap, void **); 780 len = va_arg(ap, size_t *); 781 if (ober_get_nstring(ber, ptr, len) == -1) 782 goto fail; 783 ret++; 784 break; 785 case '0': 786 if (ber->be_encoding != BER_TYPE_NULL) 787 goto fail; 788 ret++; 789 break; 790 case '.': 791 if (ber->be_encoding != BER_TYPE_EOC) 792 goto fail; 793 ret++; 794 break; 795 case 'p': 796 pos = va_arg(ap, off_t *); 797 *pos = ober_getpos(ber); 798 ret++; 799 continue; 800 case '{': 801 case '(': 802 if (ber->be_encoding != BER_TYPE_SEQUENCE && 803 ber->be_encoding != BER_TYPE_SET) 804 goto fail; 805 if (ber->be_sub == NULL || level >= _MAX_SEQ-1) 806 goto fail; 807 parent[++level] = ber; 808 ber = ber->be_sub; 809 ret++; 810 continue; 811 case '}': 812 case ')': 813 if (level < 0 || parent[level] == NULL) 814 goto fail; 815 ber = parent[level--]; 816 ret++; 817 break; 818 default: 819 goto fail; 820 } 821 822 ber = ber->be_next; 823 } 824 va_end(ap); 825 return (ret == n ? 0 : -1); 826 827 fail: 828 va_end(ap); 829 return (-1); 830 831 } 832 833 ssize_t 834 ober_get_writebuf(struct ber *b, void **buf) 835 { 836 if (b->br_wbuf == NULL) 837 return -1; 838 *buf = b->br_wbuf; 839 return (b->br_wend - b->br_wbuf); 840 } 841 842 /* 843 * write ber elements to the write buffer 844 * 845 * params: 846 * ber holds the destination write buffer byte stream 847 * root fully populated element tree 848 * 849 * returns: 850 * >=0 number of bytes written 851 * -1 on failure and sets errno 852 */ 853 ssize_t 854 ober_write_elements(struct ber *ber, struct ber_element *root) 855 { 856 size_t len; 857 858 /* calculate length because only the definite form is required */ 859 len = ober_calc_len(root); 860 DPRINTF("write ber element of %zd bytes length\n", len); 861 862 if (ber->br_wbuf != NULL && ber->br_wbuf + len > ber->br_wend) { 863 free(ber->br_wbuf); 864 ber->br_wbuf = NULL; 865 } 866 if (ber->br_wbuf == NULL) { 867 if ((ber->br_wbuf = malloc(len)) == NULL) 868 return -1; 869 ber->br_wend = ber->br_wbuf + len; 870 } 871 872 /* reset write pointer */ 873 ber->br_wptr = ber->br_wbuf; 874 875 if (ober_dump_element(ber, root) == -1) 876 return -1; 877 878 return (len); 879 } 880 881 void 882 ober_set_readbuf(struct ber *b, void *buf, size_t len) 883 { 884 b->br_rbuf = b->br_rptr = buf; 885 b->br_rend = (u_int8_t *)buf + len; 886 } 887 888 /* 889 * read ber elements from the read buffer 890 * 891 * params: 892 * ber holds a fully populated read buffer byte stream 893 * root if NULL, build up an element tree from what we receive on 894 * the wire. If not null, use the specified encoding for the 895 * elements received. 896 * 897 * returns: 898 * !=NULL, elements read and store in the ber_element tree 899 * NULL, type mismatch or read error 900 */ 901 struct ber_element * 902 ober_read_elements(struct ber *ber, struct ber_element *elm) 903 { 904 struct ber_element *root = elm; 905 906 if (root == NULL) { 907 if ((root = ober_get_element(0)) == NULL) 908 return NULL; 909 } 910 911 DPRINTF("read ber elements, root %p\n", root); 912 913 if (ober_read_element(ber, root) == -1) { 914 /* Cleanup if root was allocated by us */ 915 if (elm == NULL) 916 ober_free_elements(root); 917 return NULL; 918 } 919 920 return root; 921 } 922 923 off_t 924 ober_getpos(struct ber_element *elm) 925 { 926 return elm->be_offs; 927 } 928 929 struct ber_element * 930 ober_dup(struct ber_element *orig) 931 { 932 struct ber_element *new; 933 934 if ((new = malloc(sizeof(*new))) == NULL) 935 return NULL; 936 memcpy(new, orig, sizeof(*new)); 937 new->be_next = NULL; 938 new->be_sub = NULL; 939 940 if (orig->be_next != NULL) { 941 if ((new->be_next = ober_dup(orig->be_next)) == NULL) 942 goto fail; 943 } 944 if (orig->be_encoding == BER_TYPE_SEQUENCE || 945 orig->be_encoding == BER_TYPE_SET) { 946 if (orig->be_sub != NULL) { 947 if ((new->be_sub = ober_dup(orig->be_sub)) == NULL) 948 goto fail; 949 } 950 } else if (orig->be_encoding == BER_TYPE_OCTETSTRING || 951 orig->be_encoding == BER_TYPE_BITSTRING || 952 orig->be_encoding == BER_TYPE_OBJECT) { 953 if (orig->be_val != NULL) { 954 if ((new->be_val = malloc(orig->be_len)) == NULL) 955 goto fail; 956 memcpy(new->be_val, orig->be_val, orig->be_len); 957 } 958 } else 959 new->be_numeric = orig->be_numeric; 960 return new; 961 fail: 962 ober_free_elements(new); 963 return NULL; 964 } 965 966 void 967 ober_free_element(struct ber_element *root) 968 { 969 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 970 root->be_encoding == BER_TYPE_SET)) 971 ober_free_elements(root->be_sub); 972 if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || 973 root->be_encoding == BER_TYPE_BITSTRING || 974 root->be_encoding == BER_TYPE_OBJECT)) 975 free(root->be_val); 976 free(root); 977 } 978 979 void 980 ober_free_elements(struct ber_element *root) 981 { 982 if (root == NULL) 983 return; 984 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 985 root->be_encoding == BER_TYPE_SET)) 986 ober_free_elements(root->be_sub); 987 if (root->be_next) 988 ober_free_elements(root->be_next); 989 if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING || 990 root->be_encoding == BER_TYPE_BITSTRING || 991 root->be_encoding == BER_TYPE_OBJECT)) 992 free(root->be_val); 993 free(root); 994 } 995 996 size_t 997 ober_calc_len(struct ber_element *root) 998 { 999 unsigned int t; 1000 size_t s; 1001 size_t size = 2; /* minimum 1 byte head and 1 byte size */ 1002 1003 /* calculate the real length of a sequence or set */ 1004 if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE || 1005 root->be_encoding == BER_TYPE_SET)) 1006 root->be_len = ober_calc_len(root->be_sub); 1007 1008 /* fix header length for extended types */ 1009 if (root->be_type > BER_TYPE_SINGLE_MAX) 1010 for (t = root->be_type; t > 0; t >>= 7) 1011 size++; 1012 if (root->be_len >= BER_TAG_MORE) 1013 for (s = root->be_len; s > 0; s >>= 8) 1014 size++; 1015 1016 /* calculate the length of the following elements */ 1017 if (root->be_next) 1018 size += ober_calc_len(root->be_next); 1019 1020 /* This is an empty element, do not use a minimal size */ 1021 if (root->be_class == BER_CLASS_UNIVERSAL && 1022 root->be_type == BER_TYPE_EOC && root->be_len == 0) 1023 return (0); 1024 1025 return (root->be_len + size); 1026 } 1027 1028 void 1029 ober_set_application(struct ber *b, unsigned int (*cb)(struct ber_element *)) 1030 { 1031 b->br_application = cb; 1032 } 1033 1034 void 1035 ober_set_writecallback(struct ber_element *elm, void (*cb)(void *, size_t), 1036 void *arg) 1037 { 1038 elm->be_cb = cb; 1039 elm->be_cbarg = arg; 1040 } 1041 1042 void 1043 ober_free(struct ber *b) 1044 { 1045 free(b->br_wbuf); 1046 } 1047 1048 /* 1049 * internal functions 1050 */ 1051 1052 static int 1053 ober_dump_element(struct ber *ber, struct ber_element *root) 1054 { 1055 unsigned long long l; 1056 int i; 1057 uint8_t u; 1058 1059 ober_dump_header(ber, root); 1060 if (root->be_cb) 1061 root->be_cb(root->be_cbarg, ber->br_wptr - ber->br_wbuf); 1062 1063 switch (root->be_encoding) { 1064 case BER_TYPE_BOOLEAN: 1065 case BER_TYPE_INTEGER: 1066 case BER_TYPE_ENUMERATED: 1067 l = (unsigned long long)root->be_numeric; 1068 for (i = root->be_len; i > 0; i--) { 1069 u = (l >> ((i - 1) * 8)) & 0xff; 1070 ober_putc(ber, u); 1071 } 1072 break; 1073 case BER_TYPE_BITSTRING: 1074 case BER_TYPE_OCTETSTRING: 1075 case BER_TYPE_OBJECT: 1076 ober_write(ber, root->be_val, root->be_len); 1077 break; 1078 case BER_TYPE_NULL: /* no payload */ 1079 case BER_TYPE_EOC: 1080 break; 1081 case BER_TYPE_SEQUENCE: 1082 case BER_TYPE_SET: 1083 if (root->be_sub && ober_dump_element(ber, root->be_sub) == -1) 1084 return -1; 1085 break; 1086 } 1087 1088 if (root->be_next == NULL) 1089 return 0; 1090 return ober_dump_element(ber, root->be_next); 1091 } 1092 1093 static void 1094 ober_dump_header(struct ber *ber, struct ber_element *root) 1095 { 1096 u_char id = 0, t, buf[5]; 1097 unsigned int type; 1098 size_t size; 1099 1100 /* class universal, type encoding depending on type value */ 1101 /* length encoding */ 1102 if (root->be_type <= BER_TYPE_SINGLE_MAX) { 1103 id = root->be_type | (root->be_class << BER_CLASS_SHIFT); 1104 if (root->be_encoding == BER_TYPE_SEQUENCE || 1105 root->be_encoding == BER_TYPE_SET) 1106 id |= BER_TYPE_CONSTRUCTED; 1107 1108 ober_putc(ber, id); 1109 } else { 1110 id = BER_TAG_MASK | (root->be_class << BER_CLASS_SHIFT); 1111 if (root->be_encoding == BER_TYPE_SEQUENCE || 1112 root->be_encoding == BER_TYPE_SET) 1113 id |= BER_TYPE_CONSTRUCTED; 1114 1115 ober_putc(ber, id); 1116 1117 for (t = 0, type = root->be_type; type > 0; type >>= 7) 1118 buf[t++] = type & ~BER_TAG_MORE; 1119 1120 while (t-- > 0) { 1121 if (t > 0) 1122 buf[t] |= BER_TAG_MORE; 1123 ober_putc(ber, buf[t]); 1124 } 1125 } 1126 1127 if (root->be_len < BER_TAG_MORE) { 1128 /* short form */ 1129 ober_putc(ber, root->be_len); 1130 } else { 1131 for (t = 0, size = root->be_len; size > 0; size >>= 8) 1132 buf[t++] = size & 0xff; 1133 1134 ober_putc(ber, t | BER_TAG_MORE); 1135 1136 while (t > 0) 1137 ober_putc(ber, buf[--t]); 1138 } 1139 } 1140 1141 static void 1142 ober_putc(struct ber *ber, u_char c) 1143 { 1144 if (ber->br_wptr + 1 <= ber->br_wend) 1145 *ber->br_wptr = c; 1146 ber->br_wptr++; 1147 } 1148 1149 static void 1150 ober_write(struct ber *ber, void *buf, size_t len) 1151 { 1152 if (ber->br_wptr + len <= ber->br_wend) 1153 bcopy(buf, ber->br_wptr, len); 1154 ber->br_wptr += len; 1155 } 1156 1157 /* 1158 * extract a BER encoded tag. There are two types, a short and long form. 1159 */ 1160 static ssize_t 1161 get_id(struct ber *b, unsigned int *tag, int *class, int *cstruct) 1162 { 1163 u_char u; 1164 size_t i = 0; 1165 unsigned int t = 0; 1166 1167 if (ober_getc(b, &u) == -1) 1168 return -1; 1169 1170 *class = (u >> BER_CLASS_SHIFT) & BER_CLASS_MASK; 1171 *cstruct = (u & BER_TYPE_CONSTRUCTED) == BER_TYPE_CONSTRUCTED; 1172 1173 if ((u & BER_TAG_MASK) != BER_TAG_MASK) { 1174 *tag = u & BER_TAG_MASK; 1175 return 1; 1176 } 1177 1178 do { 1179 if (ober_getc(b, &u) == -1) 1180 return -1; 1181 1182 /* enforce minimal number of octets for tag > 30 */ 1183 if (i == 0 && (u & ~BER_TAG_MORE) == 0) { 1184 errno = EINVAL; 1185 return -1; 1186 } 1187 1188 t = (t << 7) | (u & ~BER_TAG_MORE); 1189 i++; 1190 if (i > sizeof(unsigned int)) { 1191 errno = ERANGE; 1192 return -1; 1193 } 1194 } while (u & BER_TAG_MORE); 1195 1196 *tag = t; 1197 return i + 1; 1198 } 1199 1200 /* 1201 * extract length of a ber object -- if length is unknown an error is returned. 1202 */ 1203 static ssize_t 1204 get_len(struct ber *b, ssize_t *len) 1205 { 1206 u_char u, n; 1207 ssize_t s, r; 1208 1209 if (ober_getc(b, &u) == -1) 1210 return -1; 1211 if ((u & BER_TAG_MORE) == 0) { 1212 /* short form */ 1213 *len = u; 1214 return 1; 1215 } 1216 1217 if (u == 0x80) { 1218 /* Indefinite length not supported. */ 1219 errno = EINVAL; 1220 return -1; 1221 } 1222 1223 if (u == 0xff) { 1224 /* Reserved for future use. */ 1225 errno = EINVAL; 1226 return -1; 1227 } 1228 1229 n = u & ~BER_TAG_MORE; 1230 /* 1231 * Limit to a decent size that works on all of our architectures. 1232 */ 1233 if (sizeof(int32_t) < n) { 1234 errno = ERANGE; 1235 return -1; 1236 } 1237 r = n + 1; 1238 1239 for (s = 0; n > 0; n--) { 1240 if (ober_getc(b, &u) == -1) 1241 return -1; 1242 s = (s << 8) | u; 1243 } 1244 1245 if (s < 0) { 1246 /* overflow */ 1247 errno = ERANGE; 1248 return -1; 1249 } 1250 1251 *len = s; 1252 return r; 1253 } 1254 1255 static ssize_t 1256 ober_read_element(struct ber *ber, struct ber_element *elm) 1257 { 1258 long long val = 0; 1259 struct ber_element *next; 1260 unsigned int type; 1261 int i, class, cstruct, elements = 0; 1262 ssize_t len, r, totlen = 0; 1263 u_char c, last = 0; 1264 1265 if ((r = get_id(ber, &type, &class, &cstruct)) == -1) 1266 return -1; 1267 DPRINTF("ber read got class %d type %u, %s\n", 1268 class, type, cstruct ? "constructed" : "primitive"); 1269 totlen += r; 1270 if ((r = get_len(ber, &len)) == -1) 1271 return -1; 1272 DPRINTF("ber read element size %zd\n", len); 1273 totlen += r + len; 1274 1275 /* The encoding of boolean, integer, enumerated, and null values 1276 * must be primitive. */ 1277 if (class == BER_CLASS_UNIVERSAL) 1278 if (type == BER_TYPE_BOOLEAN || 1279 type == BER_TYPE_INTEGER || 1280 type == BER_TYPE_ENUMERATED || 1281 type == BER_TYPE_NULL) 1282 if (cstruct) { 1283 errno = EINVAL; 1284 return -1; 1285 } 1286 1287 /* If the total size of the element is larger than the buffer 1288 * don't bother to continue. */ 1289 if (len > ber->br_rend - ber->br_rptr) { 1290 errno = ECANCELED; 1291 return -1; 1292 } 1293 1294 elm->be_type = type; 1295 elm->be_len = len; 1296 elm->be_offs = ber->br_offs; /* element position within stream */ 1297 elm->be_class = class; 1298 1299 if (elm->be_encoding == 0) { 1300 /* try to figure out the encoding via class, type and cstruct */ 1301 if (cstruct) 1302 elm->be_encoding = BER_TYPE_SEQUENCE; 1303 else if (class == BER_CLASS_UNIVERSAL) 1304 elm->be_encoding = type; 1305 else if (ber->br_application != NULL) { 1306 /* 1307 * Ask the application to map the encoding to a 1308 * universal type. For example, a SMI IpAddress 1309 * type is defined as 4 byte OCTET STRING. 1310 */ 1311 elm->be_encoding = (*ber->br_application)(elm); 1312 } else 1313 /* last resort option */ 1314 elm->be_encoding = BER_TYPE_NULL; 1315 } 1316 1317 switch (elm->be_encoding) { 1318 case BER_TYPE_EOC: /* End-Of-Content */ 1319 break; 1320 case BER_TYPE_BOOLEAN: 1321 if (len != 1) { 1322 errno = EINVAL; 1323 return -1; 1324 } 1325 case BER_TYPE_INTEGER: 1326 case BER_TYPE_ENUMERATED: 1327 if (len < 1) { 1328 errno = EINVAL; 1329 return -1; 1330 } 1331 if (len > (ssize_t)sizeof(long long)) { 1332 errno = ERANGE; 1333 return -1; 1334 } 1335 for (i = 0; i < len; i++) { 1336 if (ober_getc(ber, &c) != 1) 1337 return -1; 1338 1339 /* smallest number of contents octets only */ 1340 if ((i == 1 && last == 0 && (c & 0x80) == 0) || 1341 (i == 1 && last == 0xff && (c & 0x80) != 0)) { 1342 errno = EINVAL; 1343 return -1; 1344 } 1345 1346 val <<= 8; 1347 val |= c; 1348 last = c; 1349 } 1350 1351 /* sign extend if MSB is set */ 1352 if (len < (ssize_t)sizeof(long long) && 1353 (val >> ((len - 1) * 8) & 0x80)) 1354 val |= ULLONG_MAX << (len * 8); 1355 elm->be_numeric = val; 1356 break; 1357 case BER_TYPE_BITSTRING: 1358 elm->be_val = malloc(len); 1359 if (elm->be_val == NULL) 1360 return -1; 1361 elm->be_free = 1; 1362 elm->be_len = len; 1363 ober_read(ber, elm->be_val, len); 1364 break; 1365 case BER_TYPE_OCTETSTRING: 1366 case BER_TYPE_OBJECT: 1367 elm->be_val = malloc(len + 1); 1368 if (elm->be_val == NULL) 1369 return -1; 1370 elm->be_free = 1; 1371 elm->be_len = len; 1372 ober_read(ber, elm->be_val, len); 1373 ((u_char *)elm->be_val)[len] = '\0'; 1374 break; 1375 case BER_TYPE_NULL: /* no payload */ 1376 if (len != 0) { 1377 errno = EINVAL; 1378 return -1; 1379 } 1380 break; 1381 case BER_TYPE_SEQUENCE: 1382 case BER_TYPE_SET: 1383 if (elm->be_sub == NULL) { 1384 if ((elm->be_sub = ober_get_element(0)) == NULL) 1385 return -1; 1386 } 1387 next = elm->be_sub; 1388 while (len > 0) { 1389 /* 1390 * Prevent stack overflow from excessive recursion 1391 * depth in ober_free_elements(). 1392 */ 1393 if (elements >= BER_MAX_SEQ_ELEMENTS) { 1394 errno = ERANGE; 1395 return -1; 1396 } 1397 r = ober_read_element(ber, next); 1398 if (r == -1) 1399 return -1; 1400 elements++; 1401 len -= r; 1402 if (len > 0 && next->be_next == NULL) { 1403 if ((next->be_next = ober_get_element(0)) == 1404 NULL) 1405 return -1; 1406 } 1407 next = next->be_next; 1408 } 1409 break; 1410 } 1411 return totlen; 1412 } 1413 1414 static ssize_t 1415 ober_getc(struct ber *b, u_char *c) 1416 { 1417 return ober_read(b, c, 1); 1418 } 1419 1420 static ssize_t 1421 ober_read(struct ber *ber, void *buf, size_t len) 1422 { 1423 size_t sz; 1424 1425 if (ber->br_rbuf == NULL) { 1426 errno = ENOBUFS; 1427 return -1; 1428 } 1429 1430 sz = ber->br_rend - ber->br_rptr; 1431 if (len > sz) { 1432 errno = ECANCELED; 1433 return -1; /* parser wants more data than available */ 1434 } 1435 1436 bcopy(ber->br_rptr, buf, len); 1437 ber->br_rptr += len; 1438 ber->br_offs += len; 1439 1440 return len; 1441 } 1442