/* $OpenBSD: ber_test_int_i.c,v 1.6 2019/10/24 12:39:26 tb Exp $ */ /* * Copyright (c) Rob Pierce * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #define SUCCEED 0 #define FAIL 1 struct test_vector { int fail; /* 1 means test is expected to fail */ char title[128]; size_t input_length; long long value; unsigned char input[1024]; size_t expect_length; unsigned char expect[1024]; }; struct test_vector test_vectors[] = { { SUCCEED, "integer (-9223372036854775807)", 10, -9223372036854775807, { 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 10, { 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, }, { SUCCEED, "integer (-9223372036854775806)", 10, -9223372036854775806, { 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, 10, { 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, }, { FAIL, "integer (-2147483650) (expected failure)", 10, -2147483650, { 0x02, 0x08, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfe }, 7, { 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe }, }, { SUCCEED, "integer (-2147483650)", 7, -2147483650, { 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe }, 7, { 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe }, }, { SUCCEED, "integer (-2147483649)", 7, -2147483649, { 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xff }, 7, { 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xff }, }, { FAIL, "integer (-2147483648) (expected failure)", 8, -2147483648, { 0x02, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-2147483648)", 6, -2147483648, { 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-1073741824)", 6, -1073741824, { 0x02, 0x04, 0xc0, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0xc0, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-536870912)", 6, -536870912, { 0x02, 0x04, 0xe0, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0xe0, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-268435456)", 6, -268435456, { 0x02, 0x04, 0xf0, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0xf0, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-1342177728)", 6, -1342177728, { 0x02, 0x04, 0xaf, 0xff, 0xfe, 0x40 }, 6, { 0x02, 0x04, 0xaf, 0xff, 0xfe, 0x40 }, }, { SUCCEED, "integer (-67108865)", 6, -67108865, { 0x02, 0x04, 0xfb, 0xff, 0xff, 0xff }, 6, { 0x02, 0x04, 0xfb, 0xff, 0xff, 0xff }, }, { SUCCEED, "integer (-67108864)", 6, -67108864, { 0x02, 0x04, 0xfc, 0x00, 0x00, 0x00 }, 6, { 0x02, 0x04, 0xfc, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (-67108863)", 6, -67108863, { 0x02, 0x04, 0xfc, 0x00, 0x00, 0x01 }, 6, { 0x02, 0x04, 0xfc, 0x00, 0x00, 0x01 }, }, { SUCCEED, "integer (-3554432)", 5, -3554432, { 0x02, 0x03, 0xc9, 0xc3, 0x80 }, 5, { 0x02, 0x03, 0xc9, 0xc3, 0x80 }, }, { SUCCEED, "integer (-65535)", 5, -65535, { 0x02, 0x03, 0xff, 0x00, 0x01, }, 5, { 0x02, 0x03, 0xff, 0x00, 0x01, }, }, { SUCCEED, "integer (-32769)", 5, -32769, { 0x02, 0x03, 0xff, 0x7f, 0xff }, 5, { 0x02, 0x03, 0xff, 0x7f, 0xff }, }, { SUCCEED, "integer (-32768)", 4, -32768, { 0x02, 0x02, 0x80, 0x00 }, 4, { 0x02, 0x02, 0x80, 0x00 }, }, { SUCCEED, "integer (-128)", 3, -128, { 0x02, 0x01, 0x80 }, 3, { 0x02, 0x01, 0x80 }, }, { SUCCEED, "integer (-1)", 3, -1, { 0x02, 0x01, 0xff }, 3, { 0x02, 0x01, 0xff }, }, { SUCCEED, "integer (0)", 3, 0, { 0x02, 0x01, 0x00 }, 3, { 0x02, 0x01, 0x00 }, }, { SUCCEED, "integer (127)", 3, 127, { 0x02, 0x01, 0x7f }, 3, { 0x02, 0x01, 0x7f }, }, { SUCCEED, "integer (128)", 4, 128, { 0x02, 0x02, 0x00, 0x80 }, 4, { 0x02, 0x02, 0x00, 0x80 }, }, { SUCCEED, "integer (32767)", 4, 32767, { 0x02, 0x02, 0x7f, 0xff }, 4, { 0x02, 0x02, 0x7f, 0xff }, }, { SUCCEED, "integer (32768)", 5, 32768, { 0x02, 0x03, 0x00, 0x80, 0x00 }, 5, { 0x02, 0x03, 0x00, 0x80, 0x00 }, }, { SUCCEED, "integer (65535)", 5, 65535, { 0x02, 0x03, 0x00, 0xff, 0xff }, 5, { 0x02, 0x03, 0x00, 0xff, 0xff }, }, { SUCCEED, "integer (65536)", 5, 65536, { 0x02, 0x03, 0x01, 0x00, 0x00 }, 5, { 0x02, 0x03, 0x01, 0x00, 0x00 }, }, { SUCCEED, "integer (2147483647)", 6, 2147483647, { 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff }, 6, { 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff }, }, { SUCCEED, "integer (2147483648)", 7, 2147483648, { 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00 }, 7, { 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (2147483649)", 7, 2147483649, { 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x01 }, 7, { 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x01 }, }, { SUCCEED, "integer (4294967295)", 7, 4294967295, { 0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff }, 7, { 0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff }, }, { SUCCEED, "integer (4294967296)", 7, 4294967296, { 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }, 7, { 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }, }, { SUCCEED, "integer (4294967297)", 7, 4294967297, { 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01 }, 7, { 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01 }, }, { SUCCEED, "integer (9223372036854775806)", 10, 9223372036854775806, { 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe }, 10, { 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe }, }, { SUCCEED, "integer (9223372036854775807)", 10, 9223372036854775807, { 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 10, { 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, }, }; static void hexdump(const unsigned char *buf, size_t len) { size_t i; for (i = 1; i < len; i++) fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "": "\n"); fprintf(stderr, " 0x%02hhx", buf[i - 1]); fprintf(stderr, "\n"); } static int test_read_elements(int i) { int pos, b; char *string; void *p = NULL; ssize_t len = 0; struct ber_element *elm = NULL, *ptr = NULL; struct ber ber; long long val; void *bstring = NULL; struct ber_oid oid; struct ber_octetstring ostring; bzero(&ber, sizeof(ber)); ober_set_readbuf(&ber, test_vectors[i].input, test_vectors[i].input_length); elm = ober_read_elements(&ber, elm); if (elm != NULL && test_vectors[i].fail == FAIL) { printf("unexpectedly passed ober_read_elements\n"); return 1; } else if (elm == NULL && test_vectors[i].fail != FAIL) { printf("unexpectedly failed ober_read_elements\n"); return 1; } else if (elm == NULL && test_vectors[i].fail == FAIL) return 0; pos = ober_getpos(elm); if (pos != 2) { printf("unexpected element position within " "byte stream (%d)\n", pos); return 1; } switch (elm->be_encoding) { case BER_TYPE_INTEGER: if (ober_get_integer(elm, &val) == -1) { printf("failed (int) encoding check\n"); return 1; } if (val != test_vectors[i].value) { printf("(ober_get_integer) got %lld, expected %lld\n", val, test_vectors[i].value); return 1; } if (ober_scanf_elements(elm, "i", &val) == -1) { printf("(ober_scanf_elements) failed (int)" " ober_scanf_elements (i)\n"); return 1; } if (val != test_vectors[i].value) { printf("got %lld, expected %lld\n", val, test_vectors[i].value); return 1; } break; default: printf("failed with unexpected encoding (%ud)\n", elm->be_encoding); return 1; } len = ober_calc_len(elm); if (len != test_vectors[i].expect_length) { printf("failed to calculate length\n"); printf("was %zd want %zu\n", len, test_vectors[i].expect_length); return 1; } ber.br_wbuf = NULL; len = ober_write_elements(&ber, elm); if (len != test_vectors[i].expect_length) { printf("failed length check (was %zd want " "%zd)\n", len, test_vectors[i].expect_length); return 1; } if (memcmp(ber.br_wbuf, test_vectors[i].expect, test_vectors[i].expect_length) != 0) { printf("failed byte stream compare\n"); printf("Got:\n"); hexdump(ber.br_wbuf, len); printf("Expected:\n"); hexdump(test_vectors[i].expect, test_vectors[i].expect_length); return 1; } ober_free(&ber); ober_free_elements(elm); return 0; } static int test_printf_elements(int i) { int pos, b; char *string; void *p = NULL; ssize_t len = 0; struct ber_element *elm = NULL, *ptr = NULL; struct ber ber; long long val; void *bstring = NULL; struct ber_oid oid; struct ber_octetstring ostring; bzero(&ber, sizeof(ber)); ober_set_readbuf(&ber, test_vectors[i].input, test_vectors[i].input_length); elm = ober_printf_elements(elm, "i", test_vectors[i].value); if (elm == NULL) { printf("unexpectedly failed ober_printf_elements\n"); return 1; } switch (elm->be_encoding) { case BER_TYPE_INTEGER: if (ober_get_integer(elm, &val) == -1) { printf("failed (int) encoding check\n"); return 1; } if (val != test_vectors[i].value) { printf("(ober_get_integer) got %lld, expected %lld\n", val, test_vectors[i].value); return 1; } if (ober_scanf_elements(elm, "i", &val) == -1) { printf("(ober_scanf_elements) failed (int)" " ober_scanf_elements (i)\n"); return 1; } if (val != test_vectors[i].value) { printf("got %lld, expected %lld\n", val, test_vectors[i].value); return 1; } break; default: printf("failed with unexpected encoding (%ud)\n", elm->be_encoding); return 1; } len = ober_calc_len(elm); if (len != test_vectors[i].expect_length) { printf("failed to calculate length\n"); printf("was %zd want %zu\n", len, test_vectors[i].expect_length); return 1; } ber.br_wbuf = NULL; len = ober_write_elements(&ber, elm); if (len != test_vectors[i].expect_length) { printf("failed length check (was %zd want " "%zd)\n", len, test_vectors[i].expect_length); return 1; } if (memcmp(ber.br_wbuf, test_vectors[i].expect, test_vectors[i].expect_length) != 0) { printf("failed byte stream compare\n"); printf("Got:\n"); hexdump(ber.br_wbuf, len); printf("Expected:\n"); hexdump(test_vectors[i].expect, test_vectors[i].expect_length); return 1; } ober_free(&ber); ober_free_elements(elm); return 0; } int main(void) { extern char *__progname; ssize_t len = 0; int i, ret = 0; /* * drive test vectors for ber byte stream input validation, etc. */ printf("= = = = = test_read_elements\n"); for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { if (test_read_elements(i) != 0) { printf("FAILED: %s\n", test_vectors[i].title); ret = 1; } else printf("SUCCESS: %s\n", test_vectors[i].title); } printf("= = = = = test_printf_elements\n"); for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { /* * skip test cases known to fail under ober_read_elements as * they are not applicable to ober_printf_elements */ if (test_vectors[i].fail) continue; if (test_printf_elements(i) != 0) { printf("FAILED: %s\n", test_vectors[i].title); ret = 1; } else printf("SUCCESS: %s\n", test_vectors[i].title); } if (ret != 0) { printf("FAILED: %s\n", __progname); return 1; } return 0; }