Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1363 lines
28 KiB

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