1*696b5899Stb /* $OpenBSD: ber_test.c,v 1.20 2019/10/24 12:39:26 tb Exp $
26a0724fcSrob */
36a0724fcSrob /*
46a0724fcSrob * Copyright (c) Rob Pierce <rob@openbsd.org>
56a0724fcSrob *
66a0724fcSrob * Permission to use, copy, modify, and distribute this software for any
76a0724fcSrob * purpose with or without fee is hereby granted, provided that the above
86a0724fcSrob * copyright notice and this permission notice appear in all copies.
96a0724fcSrob *
106a0724fcSrob * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
116a0724fcSrob * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
126a0724fcSrob * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
136a0724fcSrob * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
146a0724fcSrob * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
156a0724fcSrob * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
166a0724fcSrob * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
176a0724fcSrob */
186a0724fcSrob
196a0724fcSrob #include <sys/types.h>
206a0724fcSrob
216a0724fcSrob #include <ber.h>
226a0724fcSrob #include <errno.h>
236a0724fcSrob #include <stdio.h>
246a0724fcSrob #include <string.h>
256a0724fcSrob
266a0724fcSrob #define SUCCEED 0
276a0724fcSrob #define FAIL 1
286a0724fcSrob
296a0724fcSrob struct test_vector {
3036a71bf8Srob int fail; /* 1 means test is expected to fail */
3136a71bf8Srob int memcheck; /* 1 when short forms used */
326a0724fcSrob char title[128];
336a0724fcSrob size_t length;
346a0724fcSrob unsigned char input[1024];
356a0724fcSrob };
366a0724fcSrob
376a0724fcSrob struct test_vector test_vectors[] = {
386a0724fcSrob {
396a0724fcSrob SUCCEED,
4036a71bf8Srob 1,
416a0724fcSrob "boolean",
426a0724fcSrob 3,
436a0724fcSrob {
446a0724fcSrob 0x01, 0x01, 0xff
456a0724fcSrob },
466a0724fcSrob },
476a0724fcSrob {
4890377c34Srob FAIL,
4990377c34Srob 0,
5090377c34Srob "boolean (constructed - expected failure)",
5190377c34Srob 3,
5290377c34Srob {
5390377c34Srob 0x21, 0x01, 0xff
5490377c34Srob },
5590377c34Srob },
5690377c34Srob {
5790377c34Srob FAIL,
5890377c34Srob 0,
5990377c34Srob "boolean (more than 1 content octet - expected failure)",
6090377c34Srob 4,
6190377c34Srob {
6290377c34Srob 0x01, 0x02, 0x00, 0xff
6390377c34Srob },
6490377c34Srob },
6590377c34Srob {
666a0724fcSrob SUCCEED,
6736a71bf8Srob 1,
68ce5d4185Srob "enum",
69ce5d4185Srob 3,
70ce5d4185Srob {
71ce5d4185Srob 0x0a, 0x01, 0x00
72ce5d4185Srob },
73ce5d4185Srob },
74ce5d4185Srob {
75ce5d4185Srob FAIL,
76ce5d4185Srob 0,
77ce5d4185Srob "enum (constructed - expected failure)",
78ce5d4185Srob 3,
79ce5d4185Srob {
80ce5d4185Srob 0x2a, 0x01, 0x00
81ce5d4185Srob },
82ce5d4185Srob },
83ce5d4185Srob {
84ba9a685bSrob FAIL,
85ba9a685bSrob 0,
86ba9a685bSrob "enum minimal contents octets (expected failure)",
87ba9a685bSrob 4,
88ba9a685bSrob {
89ba9a685bSrob 0x0a, 0x02, 0x00, 0x01
90ba9a685bSrob },
91ba9a685bSrob },
92ba9a685bSrob {
93ce5d4185Srob SUCCEED,
94ce5d4185Srob 1,
956a0724fcSrob "integer (zero)",
966a0724fcSrob 3,
976a0724fcSrob {
986a0724fcSrob 0x02, 0x01, 0x00
996a0724fcSrob },
1006a0724fcSrob },
1016a0724fcSrob {
102ce5d4185Srob FAIL,
103ce5d4185Srob 0,
104ce5d4185Srob "integer (constructed - expected failure)",
105ce5d4185Srob 3,
106ce5d4185Srob {
107ce5d4185Srob 0x22, 0x01, 0x01
108ce5d4185Srob },
109ce5d4185Srob },
110ce5d4185Srob {
1116a0724fcSrob SUCCEED,
11236a71bf8Srob 1,
1136a0724fcSrob "positive integer",
1146a0724fcSrob 3,
1156a0724fcSrob {
1166a0724fcSrob 0x02, 0x01, 0x63
1176a0724fcSrob },
1186a0724fcSrob },
1196a0724fcSrob {
1206a0724fcSrob SUCCEED,
12136a71bf8Srob 1,
1226a0724fcSrob "large positive integer",
1236a0724fcSrob 5,
1246a0724fcSrob {
1256a0724fcSrob 0x02, 0x03, 0x01, 0x00, 0x00
1266a0724fcSrob },
1276a0724fcSrob },
1286a0724fcSrob {
1296a0724fcSrob SUCCEED,
13036a71bf8Srob 1,
1316a0724fcSrob "negative integer",
1326a0724fcSrob 4,
1336a0724fcSrob {
1346a0724fcSrob 0x02, 0x02, 0xff, 0x7f
1356a0724fcSrob },
1366a0724fcSrob },
1376a0724fcSrob {
1385175af87Srob FAIL,
1395175af87Srob 0,
140ba9a685bSrob "integer minimal contents octets (expected failure)",
1415175af87Srob 4,
1425175af87Srob {
1435175af87Srob 0x02, 0x02, 0x00, 0x01
1445175af87Srob },
1455175af87Srob },
1465175af87Srob {
1476a0724fcSrob SUCCEED,
14836a71bf8Srob 1,
1496a0724fcSrob "bit string",
1506a0724fcSrob 6,
1516a0724fcSrob {
1526a0724fcSrob 0x03, 0x04, 0xde, 0xad, 0xbe, 0xef
1536a0724fcSrob },
1546a0724fcSrob },
1556a0724fcSrob {
1566a0724fcSrob SUCCEED,
15736a71bf8Srob 1,
1586a0724fcSrob "octet string",
1596a0724fcSrob 10,
1606a0724fcSrob {
1616a0724fcSrob 0x04, 0x08, 0x01, 0x23, 0x45,
1626a0724fcSrob 0x67, 0x89, 0xab, 0xcd, 0xef
1636a0724fcSrob },
1646a0724fcSrob },
1656a0724fcSrob {
1666a0724fcSrob SUCCEED,
16736a71bf8Srob 1,
1686a0724fcSrob "null",
1696a0724fcSrob 2,
1706a0724fcSrob {
1716a0724fcSrob 0x05, 0x00
1726a0724fcSrob },
1736a0724fcSrob },
1746a0724fcSrob {
175ce5d4185Srob FAIL,
176ce5d4185Srob 0,
177ce5d4185Srob "null (constructed - expected failure)",
178ce5d4185Srob 2,
179ce5d4185Srob {
180ce5d4185Srob 0x25, 0x00
181ce5d4185Srob },
182ce5d4185Srob },
183ce5d4185Srob {
1846a0724fcSrob SUCCEED,
18536a71bf8Srob 1,
1866a0724fcSrob "object identifier",
1876a0724fcSrob 8,
1886a0724fcSrob {
1896a0724fcSrob 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d
1906a0724fcSrob }
1916a0724fcSrob },
1926a0724fcSrob {
1936a0724fcSrob SUCCEED,
19436a71bf8Srob 1,
1956a0724fcSrob "sequence", /* ldap */
1966a0724fcSrob 14,
1976a0724fcSrob {
198cc5c2ffaSrob 0x30, 0x0c, 0x02, 0x01, 0x01, 0x60, 0x07, 0x02,
199cc5c2ffaSrob 0x01, 0x03, 0x04, 0x00, 0x80, 0x00
200cc5c2ffaSrob }
201cc5c2ffaSrob },
202cc5c2ffaSrob {
203cc5c2ffaSrob SUCCEED,
204cc5c2ffaSrob 1,
205cc5c2ffaSrob "ldap bind",
206cc5c2ffaSrob 30,
207cc5c2ffaSrob {
208cc5c2ffaSrob 0x30, 0x1c, 0x02, 0x01, 0x01, 0x60, 0x17, 0x02,
209cc5c2ffaSrob 0x01, 0x03, 0x04, 0x08, 0x63, 0x6e, 0x3d, 0x61,
210cc5c2ffaSrob 0x64, 0x6d, 0x69, 0x6e, 0x80, 0x08, 0x70, 0x61,
211cc5c2ffaSrob 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64
212cc5c2ffaSrob }
213cc5c2ffaSrob },
214cc5c2ffaSrob {
215cc5c2ffaSrob SUCCEED,
216cc5c2ffaSrob 1,
217cc5c2ffaSrob "ldap search",
218cc5c2ffaSrob 37,
219cc5c2ffaSrob {
220cc5c2ffaSrob 0x30, 0x23, 0x02, 0x01, 0x01, 0x60, 0x1e, 0x04,
221cc5c2ffaSrob 0x09, 0x6f, 0x75, 0x3d, 0x70, 0x65, 0x6f, 0x70,
222cc5c2ffaSrob 0x6c, 0x65, 0x0a, 0x01, 0x00, 0x0a, 0x01, 0x00,
223cc5c2ffaSrob 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
224cc5c2ffaSrob 0x00, 0x04, 0x02, 0x63, 0x6e
2256a0724fcSrob }
2266a0724fcSrob },
2276a0724fcSrob {
2286a0724fcSrob SUCCEED,
22936a71bf8Srob 1,
2304947a39fSrob "snmpd encode",
2314947a39fSrob 15,
2324947a39fSrob {
2334947a39fSrob 0x30, 0x0d, 0x02, 0x01, 0x01, 0x02, 0x02, 0x20,
2344947a39fSrob 0x00, 0x04, 0x01, 0x01, 0x02, 0x01, 0x03
2354947a39fSrob }
2364947a39fSrob },
2374947a39fSrob {
2384947a39fSrob SUCCEED,
2394947a39fSrob 1,
2406a0724fcSrob "set with integer and boolean",
2416a0724fcSrob 8,
2426a0724fcSrob {
2436a0724fcSrob 0x31, 0x06, 0x02, 0x01, 0x04, 0x01, 0x01, 0xff
2446a0724fcSrob }
2456a0724fcSrob },
2466a0724fcSrob {
2476a0724fcSrob FAIL,
24836a71bf8Srob 0,
24936a71bf8Srob "indefinite encoding (expected failure)",
2506a0724fcSrob 4,
2516a0724fcSrob {
2526a0724fcSrob 0x30, 0x80, 0x00, 0x00
2536a0724fcSrob }
2546a0724fcSrob },
2556a0724fcSrob {
25690377c34Srob FAIL,
25736a71bf8Srob 0,
25890377c34Srob "reserved for future use (expected failure)",
25990377c34Srob 4,
2606a0724fcSrob {
26190377c34Srob 0x30, 0xff, 0x01, 0x01
26290377c34Srob }
2636a0724fcSrob },
2646a0724fcSrob {
2656a0724fcSrob FAIL,
26636a71bf8Srob 0,
26790377c34Srob "long form tagging prohibited (expected failure)",
26890377c34Srob 5,
2696a0724fcSrob {
27090377c34Srob 0x1f, 0x80, 0x02, 0x01, 0x01
2716a0724fcSrob },
2726a0724fcSrob },
2736a0724fcSrob {
27436a71bf8Srob SUCCEED,
27536a71bf8Srob 0,
2767ffe596eSrob "max long form length octets (i.e. 4 bytes)",
2777ffe596eSrob 7,
27836a71bf8Srob {
2797ffe596eSrob 0x02, 0x84, 0x00, 0x00, 0x00, 0x01, 0x01
28036a71bf8Srob },
28136a71bf8Srob },
28236a71bf8Srob {
2836a0724fcSrob FAIL,
28436a71bf8Srob 0,
28536a71bf8Srob "overflow long form length octets (expected failure)",
2867ffe596eSrob 8,
28736a71bf8Srob {
2887ffe596eSrob 0x02, 0x85, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01
28936a71bf8Srob },
29036a71bf8Srob },
29136a71bf8Srob {
29236a71bf8Srob FAIL,
29336a71bf8Srob 0,
29468cc6c26Srob "incorrect length - not enough data (expected failure)",
29568cc6c26Srob 3,
2966a0724fcSrob {
29768cc6c26Srob 0x02, 0x02, 0x01
2986a0724fcSrob }
2996a0724fcSrob }
3006a0724fcSrob };
3016a0724fcSrob
3026a0724fcSrob static void
hexdump(const unsigned char * buf,size_t len)3036a0724fcSrob hexdump(const unsigned char *buf, size_t len)
3046a0724fcSrob {
3056a0724fcSrob size_t i;
3066a0724fcSrob
3076a0724fcSrob for (i = 1; i < len; i++)
3086a0724fcSrob fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "": "\n");
3096a0724fcSrob
3106a0724fcSrob fprintf(stderr, " 0x%02hhx", buf[i - 1]);
3116a0724fcSrob fprintf(stderr, "\n");
3126a0724fcSrob }
3136a0724fcSrob
314cc5c2ffaSrob unsigned int
ldap_application(struct ber_element * elm)315cc5c2ffaSrob ldap_application(struct ber_element *elm)
316cc5c2ffaSrob {
317cc5c2ffaSrob return BER_TYPE_OCTETSTRING;
318cc5c2ffaSrob }
319cc5c2ffaSrob
3206a0724fcSrob static int
test(int i)3216a0724fcSrob test(int i)
3226a0724fcSrob {
3236a0724fcSrob int pos, b;
3246a0724fcSrob char *string;
3256a0724fcSrob void *p = NULL;
3266a0724fcSrob ssize_t len = 0;
3276a0724fcSrob struct ber_element *elm = NULL, *ptr = NULL;
3286a0724fcSrob struct ber ber;
3296a0724fcSrob long long val;
3306a0724fcSrob void *bstring = NULL;
3316a0724fcSrob struct ber_oid oid;
3326a0724fcSrob struct ber_octetstring ostring;
3336a0724fcSrob
3346a0724fcSrob bzero(&ber, sizeof(ber));
335*696b5899Stb ober_set_readbuf(&ber, test_vectors[i].input, test_vectors[i].length);
336*696b5899Stb ober_set_application(&ber, ldap_application);
3376a0724fcSrob
338*696b5899Stb elm = ober_read_elements(&ber, elm);
33950795871Srob if (elm == NULL && test_vectors[i].fail &&
34050795871Srob (errno == EINVAL || errno == ERANGE || errno == ECANCELED))
3416a0724fcSrob return 0;
3426a0724fcSrob else if (elm != NULL && test_vectors[i].fail) {
343*696b5899Stb printf("expected failure of ober_read_elements did not occur\n");
3446a0724fcSrob return 1;
3456a0724fcSrob } else if (elm == NULL) {
346*696b5899Stb printf("unexpectedly failed ober_read_elements\n");
3476a0724fcSrob return 1;
3486a0724fcSrob }
3496a0724fcSrob
3506a0724fcSrob /*
3516a0724fcSrob * short form tagged elements start at the 3rd octet (i.e. position 2).
3526a0724fcSrob */
35336a71bf8Srob if (test_vectors[i].memcheck) {
354*696b5899Stb pos = ober_getpos(elm);
3556a0724fcSrob if (pos != 2) {
3566a0724fcSrob printf("unexpected element position within "
35717b9f730Srob "byte stream\n");
3586a0724fcSrob return 1;
3596a0724fcSrob }
3606a0724fcSrob }
3616a0724fcSrob
3626a0724fcSrob switch (elm->be_encoding) {
3636a0724fcSrob case BER_TYPE_EOC:
364*696b5899Stb if (ober_get_eoc(elm) == -1) {
3656a0724fcSrob printf("failed (eoc) encoding check\n");
3666a0724fcSrob return 1;
3676a0724fcSrob }
368*696b5899Stb if (ober_scanf_elements(elm, ".", &val) == -1) {
369*696b5899Stb printf("failed (eoc) ober_scanf_elements\n");
3706a0724fcSrob return 1;
3716a0724fcSrob }
3726a0724fcSrob break;
3736a0724fcSrob case BER_TYPE_BOOLEAN:
374*696b5899Stb if (ober_get_boolean(elm, &b) == -1) {
3756a0724fcSrob printf("failed (boolean) encoding check\n");
3766a0724fcSrob return 1;
3776a0724fcSrob }
378*696b5899Stb if (ober_scanf_elements(elm, "b", &b) == -1) {
379*696b5899Stb printf("failed (boolean) ober_scanf_elements\n");
3806a0724fcSrob return 1;
3816a0724fcSrob }
3826a0724fcSrob break;
3836a0724fcSrob case BER_TYPE_INTEGER:
384*696b5899Stb if (ober_get_integer(elm, &val) == -1) {
3856a0724fcSrob printf("failed (int) encoding check\n");
3866a0724fcSrob return 1;
3876a0724fcSrob }
388*696b5899Stb if (ober_scanf_elements(elm, "i", &val) == -1) {
389*696b5899Stb printf("failed (int) ober_scanf_elements (i)\n");
3906a0724fcSrob return 1;
3916a0724fcSrob }
392*696b5899Stb if (ober_scanf_elements(elm, "d", &val) == -1) {
393*696b5899Stb printf("failed (int) ober_scanf_elements (d)\n");
3946a0724fcSrob return 1;
3956a0724fcSrob }
3966a0724fcSrob break;
397ce5d4185Srob case BER_TYPE_ENUMERATED:
398*696b5899Stb if (ober_get_enumerated(elm, &val) == -1) {
399ce5d4185Srob printf("failed (enum) encoding check\n");
400ce5d4185Srob return 1;
401ce5d4185Srob }
402*696b5899Stb if (ober_scanf_elements(elm, "E", &val) == -1) {
403*696b5899Stb printf("failed (enum) ober_scanf_elements (E)\n");
404ce5d4185Srob return 1;
405ce5d4185Srob }
406ce5d4185Srob break;
4076a0724fcSrob case BER_TYPE_BITSTRING:
408*696b5899Stb if (ober_get_bitstring(elm, &bstring, &len) == -1) {
4096a0724fcSrob printf("failed (bit string) encoding check\n");
4106a0724fcSrob return 1;
4116a0724fcSrob }
4126a0724fcSrob break;
4136a0724fcSrob case BER_TYPE_OCTETSTRING:
414*696b5899Stb if (ober_get_ostring(elm, &ostring) == -1) {
4156a0724fcSrob printf("failed (octet string) encoding check\n");
4166a0724fcSrob return 1;
4176a0724fcSrob }
418*696b5899Stb if (ober_scanf_elements(elm, "s", &string) == -1) {
419*696b5899Stb printf("failed (octet string) ober_scanf_elements\n");
4206a0724fcSrob return 1;
4216a0724fcSrob }
4226a0724fcSrob break;
4236a0724fcSrob case BER_TYPE_NULL:
424*696b5899Stb if (ober_get_null(elm) == -1) {
4256a0724fcSrob printf("failed (null) encoding check\n");
4266a0724fcSrob return 1;
4276a0724fcSrob }
428*696b5899Stb if (ober_scanf_elements(elm, "0", &val) == -1) {
429*696b5899Stb printf("failed (null) ober_scanf_elements\n");
4306a0724fcSrob return 1;
4316a0724fcSrob }
4326a0724fcSrob break;
4336a0724fcSrob case BER_TYPE_OBJECT: /* OID */
434*696b5899Stb if (ober_get_oid(elm, &oid) == -1) {
435c95a2219Srob printf("failed (oid) encoding check\n");
4366a0724fcSrob return 1;
4376a0724fcSrob }
438*696b5899Stb if (ober_scanf_elements(elm, "o", &oid) == -1) {
439*696b5899Stb printf("failed (oid) ober_scanf_elements\n");
4406a0724fcSrob return 1;
4416a0724fcSrob }
4426a0724fcSrob break;
4436a0724fcSrob case BER_TYPE_SET:
4446a0724fcSrob case BER_TYPE_SEQUENCE:
4456a0724fcSrob if (elm->be_sub != NULL) {
4466a0724fcSrob ptr = elm->be_sub;
447*696b5899Stb if (ober_getpos(ptr) <= pos) {
4486a0724fcSrob printf("unexpected element position within "
4496a0724fcSrob "byte stream\n");
4506a0724fcSrob return 1;
4516a0724fcSrob }
4526a0724fcSrob } else {
4536a0724fcSrob printf("expected sub element was not present\n");
4546a0724fcSrob return 1;
4556a0724fcSrob }
4566a0724fcSrob break;
4576a0724fcSrob default:
4586a0724fcSrob printf("failed with unknown encoding (%ud)\n",
4596a0724fcSrob elm->be_encoding);
4606a0724fcSrob return 1;
4616a0724fcSrob }
4626a0724fcSrob
4636a0724fcSrob /*
46417b9f730Srob * additional testing on short form encoding
4656a0724fcSrob */
46636a71bf8Srob if (test_vectors[i].memcheck) {
467*696b5899Stb len = ober_calc_len(elm);
4686a0724fcSrob if (len != test_vectors[i].length) {
4696a0724fcSrob printf("failed to calculate length\n");
4706a0724fcSrob return 1;
4716a0724fcSrob }
4726a0724fcSrob
4736a0724fcSrob ber.br_wbuf = NULL;
474*696b5899Stb len = ober_write_elements(&ber, elm);
4756a0724fcSrob if (len != test_vectors[i].length) {
4766a0724fcSrob printf("failed length check (was %zd want "
4776a0724fcSrob "%zd)\n", len, test_vectors[i].length);
4786a0724fcSrob return 1;
4796a0724fcSrob }
4806a0724fcSrob
4816a0724fcSrob if (memcmp(ber.br_wbuf, test_vectors[i].input,
482cc5c2ffaSrob test_vectors[i].length) != 0) {
483cc5c2ffaSrob printf("failed byte stream compare\n");
484cc5c2ffaSrob printf("Got:\n");
485cc5c2ffaSrob hexdump(ber.br_wbuf, len);
486cc5c2ffaSrob printf("Expected:\n");
487cc5c2ffaSrob hexdump(test_vectors[i].input, test_vectors[i].length);
4886a0724fcSrob return 1;
489cc5c2ffaSrob }
490*696b5899Stb ober_free(&ber);
4916a0724fcSrob
4926a0724fcSrob }
493*696b5899Stb ober_free_elements(elm);
4946a0724fcSrob
4956a0724fcSrob return 0;
4966a0724fcSrob }
4976a0724fcSrob
4986a0724fcSrob int
test_ber_printf_elements_integer(void)4996a0724fcSrob test_ber_printf_elements_integer(void) {
5006a0724fcSrob int val = 1, len = 0;
5016a0724fcSrob struct ber_element *elm = NULL;
5026a0724fcSrob struct ber ber;
5036a0724fcSrob
5046a0724fcSrob unsigned char exp[3] = { 0x02, 0x01, 0x01 };
5056a0724fcSrob
506*696b5899Stb elm = ober_printf_elements(elm, "d", val);
5076a0724fcSrob if (elm == NULL) {
508*696b5899Stb printf("failed ober_printf_elements\n");
5096a0724fcSrob return 1;
5106a0724fcSrob }
5116a0724fcSrob
5126a0724fcSrob bzero(&ber, sizeof(ber));
5136a0724fcSrob ber.br_wbuf = NULL;
514*696b5899Stb len = ober_write_elements(&ber, elm);
5156a0724fcSrob if (len != sizeof(exp)) {
5166a0724fcSrob printf("failed length check (was %d want %zd)\n", len,
5176a0724fcSrob sizeof(exp));
5186a0724fcSrob return 1;
5196a0724fcSrob }
5206a0724fcSrob
5216a0724fcSrob if (memcmp(ber.br_wbuf, exp, len) != 0) {
5226a0724fcSrob printf("failed (int) byte stream compare\n");
5236a0724fcSrob return 1;
5246a0724fcSrob }
5256a0724fcSrob
526*696b5899Stb ober_free_elements(elm);
527*696b5899Stb ober_free(&ber);
5286a0724fcSrob return 0;
5296a0724fcSrob }
5306a0724fcSrob
5316a0724fcSrob #define LDAP_REQ_BIND 0
5326a0724fcSrob #define LDAP_REQ_SEARCH 0
5336a0724fcSrob #define VERSION 3
5346a0724fcSrob #define LDAP_AUTH_SIMPLE 0
5356a0724fcSrob
5366a0724fcSrob int
test_ber_printf_elements_ldap_bind(void)5376a0724fcSrob test_ber_printf_elements_ldap_bind(void) {
5386a0724fcSrob int len = 0, msgid = 1;
5396a0724fcSrob char *binddn = "cn=admin";
5406a0724fcSrob char *bindcred = "password";
5416a0724fcSrob struct ber_element *root = NULL, *elm = NULL;
5426a0724fcSrob struct ber ber;
5436a0724fcSrob
5446a0724fcSrob unsigned char exp[] = {
5456a0724fcSrob 0x30, 0x1c,
5466a0724fcSrob 0x02, 0x01, 0x01,
5476a0724fcSrob 0x60, 0x17,
5486a0724fcSrob 0x02, 0x01, 0x03,
5496a0724fcSrob 0x04, 0x08, 0x63, 0x6e, 0x3d, 0x61, 0x64, 0x6d, 0x69, 0x6e,
5506a0724fcSrob 0x80, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64
5516a0724fcSrob };
5526a0724fcSrob
553*696b5899Stb if ((root = ober_add_sequence(NULL)) == NULL)
5546a0724fcSrob return 1;
5556a0724fcSrob
556*696b5899Stb elm = ober_printf_elements(root, "d{tdsst", msgid,
5576a0724fcSrob BER_CLASS_APP, LDAP_REQ_BIND,
5586a0724fcSrob VERSION,
5596a0724fcSrob binddn, bindcred,
5606a0724fcSrob BER_CLASS_CONTEXT, LDAP_AUTH_SIMPLE);
5616a0724fcSrob
5626a0724fcSrob if (elm == NULL) {
563*696b5899Stb printf("failed ober_printf_elements\n");
5646a0724fcSrob return 1;
5656a0724fcSrob }
5666a0724fcSrob
5676a0724fcSrob bzero(&ber, sizeof(ber));
5686a0724fcSrob ber.br_wbuf = NULL;
569*696b5899Stb ober_set_application(&ber, ldap_application);
570*696b5899Stb len = ober_write_elements(&ber, root);
5716a0724fcSrob if (len != sizeof(exp)) {
5726a0724fcSrob printf("failed length check (was %d want %zd)\n", len,
5736a0724fcSrob sizeof(exp));
5746a0724fcSrob return 1;
5756a0724fcSrob }
5766a0724fcSrob
5776a0724fcSrob if (memcmp(ber.br_wbuf, exp, len) != 0) {
5786a0724fcSrob printf("failed (ldap bind) byte stream compare\n");
5796a0724fcSrob hexdump(ber.br_wbuf, len);
5806a0724fcSrob return 1;
5816a0724fcSrob }
5826a0724fcSrob
583*696b5899Stb ober_free_elements(elm);
584*696b5899Stb ober_free(&ber);
5856a0724fcSrob return 0;
5866a0724fcSrob }
5876a0724fcSrob
5886a0724fcSrob int
test_ber_printf_elements_ldap_search(void)5896a0724fcSrob test_ber_printf_elements_ldap_search(void) {
5906a0724fcSrob int len = 0, msgid = 1;
5916a0724fcSrob int sizelimit = 0, timelimit = 0;
5926a0724fcSrob int typesonly = 0;
5936a0724fcSrob long long scope = 0, deref = 0;
5946a0724fcSrob char *basedn = "ou=people";
5956a0724fcSrob char *filter = "cn";
596c95a2219Srob struct ber_element *root = NULL, *elm = NULL, *felm = NULL;
5976a0724fcSrob struct ber ber;
5986a0724fcSrob
5996a0724fcSrob unsigned char exp[] = {
600cc5c2ffaSrob 0x30, 0x23, 0x02, 0x01, 0x01, 0x60, 0x1e, 0x04,
601cc5c2ffaSrob 0x09, 0x6f, 0x75, 0x3d, 0x70, 0x65, 0x6f, 0x70,
602cc5c2ffaSrob 0x6c, 0x65, 0x0a, 0x01, 0x00, 0x0a, 0x01, 0x00,
603cc5c2ffaSrob 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
604cc5c2ffaSrob 0x00, 0x04, 0x02, 0x63, 0x6e
6056a0724fcSrob };
6066a0724fcSrob
607*696b5899Stb if ((root = ober_add_sequence(NULL)) == NULL)
6086a0724fcSrob return 1;
6096a0724fcSrob
610*696b5899Stb elm = ober_printf_elements(root, "d{tsEEddbs",
611cc5c2ffaSrob msgid, BER_CLASS_APP, LDAP_REQ_SEARCH,
612cc5c2ffaSrob basedn, scope, deref, sizelimit, timelimit, typesonly, filter);
6136a0724fcSrob if (elm == NULL) {
614*696b5899Stb printf("failed ober_printf_elements\n");
6156a0724fcSrob return 1;
6166a0724fcSrob }
6176a0724fcSrob
6186a0724fcSrob bzero(&ber, sizeof(ber));
6196a0724fcSrob ber.br_wbuf = NULL;
620*696b5899Stb ober_set_application(&ber, ldap_application);
621*696b5899Stb len = ober_write_elements(&ber, root);
6226a0724fcSrob if (len != sizeof(exp)) {
6236a0724fcSrob printf("failed length check (was %d want %zd)\n", len,
6246a0724fcSrob sizeof(exp));
6256a0724fcSrob return 1;
6266a0724fcSrob }
6276a0724fcSrob
6286a0724fcSrob if (memcmp(ber.br_wbuf, exp, len) != 0) {
6296a0724fcSrob printf("failed (ldap search) byte stream compare\n");
6306a0724fcSrob hexdump(ber.br_wbuf, len);
6316a0724fcSrob return 1;
6326a0724fcSrob }
6336a0724fcSrob
634*696b5899Stb ober_free_elements(elm);
635*696b5899Stb ober_free(&ber);
6366a0724fcSrob return 0;
6376a0724fcSrob }
6386a0724fcSrob
6396a0724fcSrob int
test_ber_printf_elements_snmp_v3_encode(void)6406a0724fcSrob test_ber_printf_elements_snmp_v3_encode(void) {
6416a0724fcSrob int len = 0;
6426a0724fcSrob u_int8_t f = 0x01; /* verbose */
6436a0724fcSrob long long secmodel = 3; /* USM */
6446a0724fcSrob long long msgid = 1, max_msg_size = 8192;
6456a0724fcSrob struct ber_element *elm = NULL;
6466a0724fcSrob struct ber ber;
6476a0724fcSrob
6486a0724fcSrob unsigned char exp[] = {
6494947a39fSrob 0x30, 0x0d, 0x02, 0x01, 0x01, 0x02, 0x02, 0x20,
6504947a39fSrob 0x00, 0x04, 0x01, 0x01, 0x02, 0x01, 0x03
6516a0724fcSrob };
6526a0724fcSrob
653*696b5899Stb elm = ober_printf_elements(elm, "{iixi}", msgid, max_msg_size,
6546a0724fcSrob &f, sizeof(f), secmodel);
6556a0724fcSrob if (elm == NULL) {
656*696b5899Stb printf("failed ober_printf_elements\n");
6576a0724fcSrob return 1;
6586a0724fcSrob }
6596a0724fcSrob
6606a0724fcSrob bzero(&ber, sizeof(ber));
6616a0724fcSrob ber.br_wbuf = NULL;
662*696b5899Stb len = ober_write_elements(&ber, elm);
6636a0724fcSrob if (len != sizeof(exp)) {
6646a0724fcSrob printf("failed length check (was %d want %zd)\n", len,
6656a0724fcSrob sizeof(exp));
6666a0724fcSrob return 1;
6676a0724fcSrob }
6686a0724fcSrob
6696a0724fcSrob if (memcmp(ber.br_wbuf, exp, len) != 0) {
6706a0724fcSrob printf("failed (snmp_v3_encode) byte stream compare\n");
6716a0724fcSrob hexdump(ber.br_wbuf, len);
6726a0724fcSrob return 1;
6736a0724fcSrob }
6746a0724fcSrob
675*696b5899Stb ober_free_elements(elm);
676*696b5899Stb ober_free(&ber);
6776a0724fcSrob return 0;
6786a0724fcSrob }
6796a0724fcSrob
6806a0724fcSrob int
test_ber_null(void)681376546ccSrob test_ber_null(void)
682376546ccSrob {
683376546ccSrob long long val;
684376546ccSrob struct ber_element *elm = NULL;
685376546ccSrob
686376546ccSrob /* scanning into a null ber_element should fail */
687*696b5899Stb if (ober_scanf_elements(elm, "0", &val) != -1) {
688*696b5899Stb printf("failed (null ber_element) ober_scanf_elements empty\n");
689376546ccSrob goto fail;
690376546ccSrob }
691376546ccSrob
692*696b5899Stb if ((elm = ober_printf_elements(elm, "{d}", 1)) == NULL) {
693*696b5899Stb printf("failed (null ber_element) ober_printf_elements\n");
694376546ccSrob }
695376546ccSrob
696376546ccSrob /*
6977ccbcfe6Srob * Scanning after the last valid element should be able to descend back
698376546ccSrob * into the parent level.
699376546ccSrob */
700*696b5899Stb if (ober_scanf_elements(elm, "{i}", &val) != 0) {
701*696b5899Stb printf("failed (null ber_element) ober_scanf_elements valid\n");
702376546ccSrob goto fail;
703376546ccSrob }
704376546ccSrob /*
705376546ccSrob * Scanning for a non-existent element should fail, even if it's just a
706376546ccSrob * skip.
707376546ccSrob */
708*696b5899Stb if (ober_scanf_elements(elm, "{lS}", &val) != -1) {
709*696b5899Stb printf("failed (null ber_element) ober_scanf_elements invalid\n");
710376546ccSrob goto fail;
711376546ccSrob }
712376546ccSrob
713*696b5899Stb ober_free_elements(elm);
714376546ccSrob return 0;
715376546ccSrob
716376546ccSrob fail:
717*696b5899Stb ober_free_elements(elm);
718376546ccSrob return 1;
719376546ccSrob }
720376546ccSrob
721376546ccSrob int
main(void)7226a0724fcSrob main(void)
7236a0724fcSrob {
7246a0724fcSrob extern char *__progname;
7256a0724fcSrob
7266a0724fcSrob ssize_t len = 0;
7276a0724fcSrob int i, ret = 0;
7286a0724fcSrob
7296a0724fcSrob /*
7306a0724fcSrob * drive test vectors for ber byte stream input validation, etc.
7316a0724fcSrob */
7326a0724fcSrob for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
7336a0724fcSrob if (test(i) != 0) {
7346a0724fcSrob printf("FAILED: %s\n", test_vectors[i].title);
7356a0724fcSrob ret = 1;
7366a0724fcSrob } else
7376a0724fcSrob printf("SUCCESS: %s\n", test_vectors[i].title);
7386a0724fcSrob }
7396a0724fcSrob
7406a0724fcSrob /*
7416a0724fcSrob * run standalone functions for ber byte stream creation, etc.
7426a0724fcSrob * (e.g. ldap, snmpd)
7436a0724fcSrob */
744cca1463aSrob if (test_ber_printf_elements_integer() != 0) {
745cca1463aSrob printf("FAILED: test_ber_printf_elements_integer\n");
7466a0724fcSrob ret = 1;
747cca1463aSrob } else
7486a0724fcSrob printf("SUCCESS: test_ber_printf_elements_integer\n");
7496a0724fcSrob
750cca1463aSrob if (test_ber_printf_elements_ldap_bind() != 0) {
751cca1463aSrob printf("FAILED: test_ber_printf_elements_ldap_bind\n");
7526a0724fcSrob ret = 1;
753cca1463aSrob } else
7546a0724fcSrob printf("SUCCESS: test_ber_printf_elements_ldap_bind\n");
7556a0724fcSrob
756cca1463aSrob if (test_ber_printf_elements_ldap_search() != 0) {
757cca1463aSrob printf("FAILED: test_ber_printf_elements_ldap_search\n");
7586a0724fcSrob ret = 1;
759cca1463aSrob } else
7606a0724fcSrob printf("SUCCESS: test_ber_printf_elements_ldap_search\n");
7616a0724fcSrob
762cca1463aSrob if (test_ber_printf_elements_snmp_v3_encode() != 0) {
763cca1463aSrob printf("FAILED: test_ber_printf_elements_snmpd_v3_encode\n");
7646a0724fcSrob ret = 1;
765cca1463aSrob } else
7666a0724fcSrob printf("SUCCESS: test_ber_printf_elements_snmpd_v3_encode\n");
767cca1463aSrob
768376546ccSrob if (test_ber_null() != 0) {
769376546ccSrob printf("FAILED: test_ber_null\n");
770376546ccSrob ret = 1;
771376546ccSrob } else
772376546ccSrob printf("SUCCESS: test_ber_null\n");
773376546ccSrob
7746a0724fcSrob if (ret != 0) {
7756a0724fcSrob printf("FAILED: %s\n", __progname);
7766a0724fcSrob return 1;
7776a0724fcSrob }
7786a0724fcSrob
7796a0724fcSrob return 0;
7806a0724fcSrob }
781