summaryrefslogtreecommitdiffstats
path: root/lib/util/tests/asn1_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util/tests/asn1_tests.c')
-rw-r--r--lib/util/tests/asn1_tests.c383
1 files changed, 383 insertions, 0 deletions
diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c
new file mode 100644
index 0000000..f2bd163
--- /dev/null
+++ b/lib/util/tests/asn1_tests.c
@@ -0,0 +1,383 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util_asn1 testing
+
+ Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
+ Copyright (C) Volker Lendecke 2004
+ Copyright (C) Andrew Bartlett 2011
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "../asn1.h"
+
+struct oid_data {
+ const char *oid; /* String OID */
+ const char *bin_oid; /* Binary OID represented as string */
+};
+
+/* Data for successful OIDs conversions */
+static const struct oid_data oid_data_ok[] = {
+ {
+ .oid = "2.5.4.0",
+ .bin_oid = "550400"
+ },
+ {
+ .oid = "2.5.4.1",
+ .bin_oid = "550401"
+ },
+ {
+ .oid = "2.5.4.130",
+ .bin_oid = "55048102"
+ },
+ {
+ .oid = "2.5.130.4",
+ .bin_oid = "55810204"
+ },
+ {
+ .oid = "2.5.4.16387",
+ .bin_oid = "5504818003"
+ },
+ {
+ .oid = "2.5.16387.4",
+ .bin_oid = "5581800304"
+ },
+ {
+ .oid = "2.5.2097155.4",
+ .bin_oid = "558180800304"
+ },
+ {
+ .oid = "2.5.4.130.16387.2097155.268435459",
+ .bin_oid = "55048102818003818080038180808003"
+ },
+};
+
+/* Data for successful OIDs conversions */
+static const char *oid_data_err[] = {
+ "", /* empty OID */
+ ".2.5.4.130", /* first sub-identifier is empty */
+ "2.5.4.130.", /* last sub-identifier is empty */
+ "2..5.4.130", /* second sub-identifier is empty */
+ "2.5..4.130", /* third sub-identifier is empty */
+ "2.abc.4.130", /* invalid sub-identifier */
+ "2.5abc.4.130", /* invalid sub-identifier (alphanumeric)*/
+};
+
+/* Data for successful Partial OIDs conversions */
+static const struct oid_data partial_oid_data_ok[] = {
+ {
+ .oid = "2.5.4.130:0x81",
+ .bin_oid = "5504810281"
+ },
+ {
+ .oid = "2.5.4.16387:0x8180",
+ .bin_oid = "55048180038180"
+ },
+ {
+ .oid = "2.5.4.16387:0x81",
+ .bin_oid = "550481800381"
+ },
+ {
+ .oid = "2.5.2097155.4:0x818080",
+ .bin_oid = "558180800304818080"
+ },
+ {
+ .oid = "2.5.2097155.4:0x8180",
+ .bin_oid = "5581808003048180"
+ },
+ {
+ .oid = "2.5.2097155.4:0x81",
+ .bin_oid = "55818080030481"
+ },
+};
+
+static const struct {
+ DATA_BLOB blob;
+ int value;
+} integer_tests[] = {
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x00"), 3},
+ .value = 0
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x7f"), 3},
+ .value = 127
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x00\x80"), 4},
+ .value = 128
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x01\x00"), 4},
+ .value = 256
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x80"), 3},
+ .value = -128
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x7f"), 4},
+ .value = -129
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\xff"), 3},
+ .value = -1
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x01"), 4},
+ .value = -255
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x00\xff"), 4},
+ .value = 255
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x04\x80\x00\x00\x00"), 6},
+ .value = 0x80000000
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x04\x7f\xff\xff\xff"), 6},
+ .value = 0x7fffffff
+ }
+};
+
+/* Testing ber_write_OID_String() function */
+static bool test_ber_write_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *hex_str;
+ DATA_BLOB blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* check for valid OIDs */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* check for invalid OIDs */
+ for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
+ torture_assert(tctx,
+ !ber_write_OID_String(mem_ctx, &blob, oid_data_err[i]),
+ talloc_asprintf(mem_ctx,
+ "Should fail for [%s] -> %s",
+ oid_data_err[i],
+ hex_encode_talloc(mem_ctx, blob.data, blob.length)));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_read_OID_String() function */
+static bool test_ber_read_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *oid;
+ DATA_BLOB oid_blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_write_partial_OID_String() function */
+static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *hex_str;
+ DATA_BLOB blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* ber_write_partial_OID_String() should work with not partial OIDs also */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_partial_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* ber_write_partial_OID_String() test with partial OIDs */
+ data = partial_oid_data_ok;
+ for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_partial_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_read_partial_OID_String() function */
+static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *oid;
+ DATA_BLOB oid_blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* ber_read_partial_OID_String() should work with not partial OIDs also */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_partial_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* ber_read_partial_OID_String() test with partial OIDs */
+ data = partial_oid_data_ok;
+ for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_partial_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/*
+ * Testing asn1_read_Integer and asn1_write_Integer functions,
+ * inspired by Love Hornquist Astrand
+ */
+
+static bool test_asn1_Integer(struct torture_context *tctx)
+{
+ int i;
+ TALLOC_CTX *mem_ctx;
+ bool ret = false;
+
+ mem_ctx = talloc_new(tctx);
+
+ for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
+ ASN1_DATA *data;
+ DATA_BLOB blob;
+ int val;
+
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
+ if (!data) {
+ goto err;
+ }
+
+ if (!asn1_write_Integer(data, integer_tests[i].value)) goto err;
+
+ if (!asn1_blob(data, &blob)) {
+ goto err;
+ }
+
+ torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
+
+ if (!asn1_load(data, blob)) goto err;
+ torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
+
+ torture_assert_int_equal(tctx, val, integer_tests[i].value,
+ "readback of asn1_write_Integer output by asn1_read_Integer() failed");
+ }
+
+ ret = true;
+
+ err:
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+
+/* LOCAL-ASN1 test suite creation */
+struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
+
+ torture_suite_add_simple_test(suite, "ber_write_OID_String",
+ test_ber_write_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_read_OID_String",
+ test_ber_read_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
+ test_ber_write_partial_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
+ test_ber_read_partial_OID_String);
+
+ torture_suite_add_simple_test(suite, "asn1_Integer",
+ test_asn1_Integer);
+
+ return suite;
+}