xref: /openbsd-src/regress/lib/libcrypto/asn1/asn1oct.c (revision 9b0855c6d8c640364c58be7328e1294d6594b791)
1*9b0855c6Stb /*	$OpenBSD: asn1oct.c,v 1.4 2023/05/13 07:17:32 tb Exp $ */
251de66fbStb 
351de66fbStb /*
451de66fbStb  * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
551de66fbStb  *
651de66fbStb  * Permission to use, copy, modify, and distribute this software for any
751de66fbStb  * purpose with or without fee is hereby granted, provided that the above
851de66fbStb  * copyright notice and this permission notice appear in all copies.
951de66fbStb  *
1051de66fbStb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1151de66fbStb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1251de66fbStb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1351de66fbStb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1451de66fbStb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1551de66fbStb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1651de66fbStb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1751de66fbStb  */
1851de66fbStb 
19*9b0855c6Stb #include <assert.h>
2051de66fbStb #include <err.h>
2151de66fbStb #include <string.h>
2251de66fbStb 
2351de66fbStb #include <openssl/asn1.h>
2451de66fbStb #include <openssl/x509v3.h>
2551de66fbStb 
2651de66fbStb #define TESTBUFFER_SIZE		20
2751de66fbStb 
2851de66fbStb static const struct i2s_asn1_octet_string_test {
2951de66fbStb 	const char *desc;
3051de66fbStb 	const uint8_t buf[TESTBUFFER_SIZE];
3151de66fbStb 	long len;
3251de66fbStb 	const char *want;
3351de66fbStb } i2s_test[] = {
3451de66fbStb 	{
3551de66fbStb 		.desc = "Empty buffer gives empty string",
3651de66fbStb 		.buf = { 0x00, },
3751de66fbStb 		.len = 0,
3851de66fbStb 		.want = "",
3951de66fbStb 	},
4051de66fbStb 	{
4151de66fbStb 		.desc = "all hex digits",
4251de66fbStb 		.buf = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, },
4351de66fbStb 		.len = 8,
4451de66fbStb 		.want = "01:23:45:67:89:AB:CD:EF",
4551de66fbStb 	},
4651de66fbStb 	{
4751de66fbStb 		.desc = "all hex digits, scrambled",
4851de66fbStb 		.buf = { 0x98, 0x24, 0xbf, 0x3a, 0xc7, 0xd6, 0x01, 0x5e, },
4951de66fbStb 		.len = 8,
5051de66fbStb 		.want = "98:24:BF:3A:C7:D6:01:5E",
5151de66fbStb 	},
5251de66fbStb 	{
5351de66fbStb 		.desc = "Embedded 0 byte",
5451de66fbStb 		.buf = { 0x7a, 0x00, 0xbb, },
5551de66fbStb 		.len = 3,
5651de66fbStb 		.want = "7A:00:BB",
5751de66fbStb 	},
5851de66fbStb 	{
5951de66fbStb 		.desc = "All zeroes",
6051de66fbStb 		.buf = { 0x00, 0x00, 0x00, 0x00, 0x00, },
6151de66fbStb 		.len = 4,
6251de66fbStb 		.want = "00:00:00:00",
6351de66fbStb 	},
6451de66fbStb 	{
6551de66fbStb 		.desc = "All bits set",
6651de66fbStb 		.buf = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
6751de66fbStb 		.len = 8,
6851de66fbStb 		.want = "FF:FF:FF:FF:FF:FF:FF:FF",
6951de66fbStb 	},
7051de66fbStb 	{
7151de66fbStb 		.desc = "negative length",
7251de66fbStb 		.buf = { 0x00, },
7351de66fbStb 		.len = -1,
7451de66fbStb 	},
7551de66fbStb };
7651de66fbStb 
7751de66fbStb #define N_I2S_TESTS (sizeof(i2s_test) / sizeof(i2s_test[0]))
7851de66fbStb 
7951de66fbStb static int
test_i2s_ASN1_OCTET_STRING(const struct i2s_asn1_octet_string_test * test)8051de66fbStb test_i2s_ASN1_OCTET_STRING(const struct i2s_asn1_octet_string_test *test)
8151de66fbStb {
8251de66fbStb 	ASN1_OCTET_STRING *aos = NULL;
8351de66fbStb 	int should_fail = test->want == NULL;
8451de66fbStb 	char *got = NULL;
8551de66fbStb 	int failed = 0;
8651de66fbStb 
8751de66fbStb 	if ((aos = ASN1_OCTET_STRING_new()) == NULL)
8851de66fbStb 		errx(1, "ASN1_OCTET_STRING_new");
8951de66fbStb 
9051de66fbStb 	if (!ASN1_STRING_set(aos, (void *)test->buf, test->len))
9151de66fbStb 		errx(1, "ASN1_STRING_set");
9251de66fbStb 
9351de66fbStb 	if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL) {
9451de66fbStb 		if (!should_fail)
9551de66fbStb 			errx(1, "i2s_ASN1_OCTET_STRING");
9651de66fbStb 	}
9751de66fbStb 
9851de66fbStb 	if (!should_fail && strcmp(test->want, got) != 0) {
9951de66fbStb 		fprintf(stderr, "%s: \"%s\" failed: want \"%s\", got \"%s\"\n",
10051de66fbStb 		    __func__, test->desc, test->want, got);
10151de66fbStb 		failed |= 1;
10251de66fbStb 	}
10351de66fbStb 
10451de66fbStb 	ASN1_OCTET_STRING_free(aos);
10551de66fbStb 	free(got);
10651de66fbStb 
10751de66fbStb 	return failed;
10851de66fbStb }
10951de66fbStb 
11051de66fbStb static int
test_new_ASN1_OCTET_STRING(void)11151de66fbStb test_new_ASN1_OCTET_STRING(void)
11251de66fbStb {
11351de66fbStb 	ASN1_OCTET_STRING *aos = NULL;
11451de66fbStb 	char *got;
11551de66fbStb 	int failed = 0;
11651de66fbStb 
11751de66fbStb 	if ((aos = ASN1_OCTET_STRING_new()) == NULL)
11852bf25b2Stb 		errx(1, "%s: ASN1_OCTET_STRING_new", __func__);
11951de66fbStb 	if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL)
12052bf25b2Stb 		errx(1, "%s: i2s_ASN1_OCTET_STRING", __func__);
12151de66fbStb 
12251de66fbStb 	if (strcmp("", got) != 0) {
12351de66fbStb 		fprintf(stderr, "%s failed: want \"\", got \"%s\"\n",
12451de66fbStb 		    __func__, got);
12551de66fbStb 		failed |= 1;
12651de66fbStb 	}
12751de66fbStb 
12851de66fbStb 	ASN1_OCTET_STRING_free(aos);
12951de66fbStb 	free(got);
13051de66fbStb 
13151de66fbStb 	return failed;
13251de66fbStb }
13351de66fbStb 
13451de66fbStb static int
run_i2s_ASN1_OCTET_STRING_tests(void)13551de66fbStb run_i2s_ASN1_OCTET_STRING_tests(void)
13651de66fbStb {
13751de66fbStb 	size_t i;
13851de66fbStb 	int failed = 0;
13951de66fbStb 
14051de66fbStb 	failed |= test_new_ASN1_OCTET_STRING();
14151de66fbStb 
14251de66fbStb 	for (i = 0; i < N_I2S_TESTS; i++)
14351de66fbStb 		failed |= test_i2s_ASN1_OCTET_STRING(&i2s_test[i]);
14451de66fbStb 
14551de66fbStb 	return failed;
14651de66fbStb }
14751de66fbStb 
14851de66fbStb static const struct s2i_asn1_octet_string_test {
14951de66fbStb 	const char *desc;
15051de66fbStb 	const char *in;
15151de66fbStb 	const char *want;
15251de66fbStb } s2i_test[] = {
15351de66fbStb 	/* Tests that should succeed. */
15451de66fbStb 	{
15551de66fbStb 		.desc = "empty string",
15651de66fbStb 		.in = "",
15751de66fbStb 		.want = "",
15851de66fbStb 	},
15951de66fbStb 	{
160193c6483Stb 		.desc = "only colons",
161193c6483Stb 		.in = ":::::::",
162193c6483Stb 		.want = "",
163193c6483Stb 	},
164193c6483Stb 	{
16551de66fbStb 		.desc = "a 0 octet",
16651de66fbStb 		.in = "00",
16751de66fbStb 		.want = "00",
16851de66fbStb 	},
16951de66fbStb 	{
17051de66fbStb 		.desc = "a 0 octet with stupid colons",
17151de66fbStb 		.in = ":::00:::::",
17251de66fbStb 		.want = "00",
17351de66fbStb 	},
17451de66fbStb 	{
17551de66fbStb 		.desc = "more stupid colons",
17651de66fbStb 		.in = ":::C0fF::Ee:::::",
17751de66fbStb 		.want = "C0:FF:EE",
17851de66fbStb 	},
17951de66fbStb 	{
18051de66fbStb 		.desc = "all hex digits",
18151de66fbStb 		.in = "0123456789abcdef",
18251de66fbStb 		.want = "01:23:45:67:89:AB:CD:EF",
18351de66fbStb 	},
18451de66fbStb 
18551de66fbStb 	/* Tests that should fail. */
18651de66fbStb 	{
18751de66fbStb 		.desc = "colons between hex digits",
18851de66fbStb 		.in = "A:F",
18951de66fbStb 	},
19051de66fbStb 	{
19151de66fbStb 		.desc = "more colons between hex digits",
19251de66fbStb 		.in = "5:7",
19351de66fbStb 	},
19451de66fbStb 	{
19551de66fbStb 		.desc = "one hex digit",
19651de66fbStb 		.in = "1",
19751de66fbStb 	},
19851de66fbStb 	{
19951de66fbStb 		.desc = "three hex digits",
20051de66fbStb 		.in = "bad",
20151de66fbStb 	},
20251de66fbStb 	{
20351de66fbStb 		.desc = "three hex digits, colon after first digit",
20451de66fbStb 		.in = "b:ad",
20551de66fbStb 	},
20651de66fbStb 	{
20751de66fbStb 		.desc = "three hex digits, colon after second digit",
20851de66fbStb 		.in = "ba:d",
20951de66fbStb 	},
21051de66fbStb 	{
21151de66fbStb 		.desc = "non-hex digit",
21251de66fbStb 		.in = "g00d",
21351de66fbStb 	},
21451de66fbStb 	{
215193c6483Stb 		.desc = "non-hex digits",
216193c6483Stb 		.in = "d0gged",
217193c6483Stb 	},
218193c6483Stb 	{
21951de66fbStb 		.desc = "trailing non-hex digit",
22051de66fbStb 		.in = "d00der",
22151de66fbStb 	},
22251de66fbStb };
22351de66fbStb 
22451de66fbStb #define N_S2I_TESTS (sizeof(s2i_test) / sizeof(s2i_test[0]))
22551de66fbStb 
22651de66fbStb static int
test_s2i_ASN1_OCTET_STRING(const struct s2i_asn1_octet_string_test * test)22751de66fbStb test_s2i_ASN1_OCTET_STRING(const struct s2i_asn1_octet_string_test *test)
22851de66fbStb {
22951de66fbStb 	ASN1_OCTET_STRING *aos = NULL;
23051de66fbStb 	char *got = NULL;
23151de66fbStb 	int should_fail = test->want == NULL;
23251de66fbStb 	int failed = 0;
23351de66fbStb 
23451de66fbStb 	if ((aos = s2i_ASN1_OCTET_STRING(NULL, NULL, test->in)) == NULL) {
23551de66fbStb 		if (!should_fail)
23651de66fbStb 			errx(1, "%s: s2i_ASN1_OCTET_STRING", test->desc);
23751de66fbStb 		goto done;
23851de66fbStb 	}
23951de66fbStb 
24051de66fbStb 	if ((got = i2s_ASN1_OCTET_STRING(NULL, aos)) == NULL)
24151de66fbStb 		errx(1, "%s: i2s_ASN1_OCTET_STRING", test->desc);
24251de66fbStb 
243*9b0855c6Stb 	assert(test->want != NULL);
24451de66fbStb 	if (strcmp(test->want, got) != 0) {
24551de66fbStb 		fprintf(stderr, "%s: \"%s\" failed: want \"%s\", got \"%s\"\n",
24651de66fbStb 		    __func__, test->desc, test->want, got);
24751de66fbStb 		failed |= 1;
24851de66fbStb 	}
24951de66fbStb 
25051de66fbStb  done:
25151de66fbStb 	ASN1_OCTET_STRING_free(aos);
25251de66fbStb 	free(got);
25351de66fbStb 
25451de66fbStb 	return failed;
25551de66fbStb }
25651de66fbStb 
25751de66fbStb static int
run_s2i_ASN1_OCTET_STRING_tests(void)25851de66fbStb run_s2i_ASN1_OCTET_STRING_tests(void)
25951de66fbStb {
26051de66fbStb 	size_t i;
26151de66fbStb 	int failed = 0;
26251de66fbStb 
26351de66fbStb 	failed |= test_new_ASN1_OCTET_STRING();
26451de66fbStb 
26551de66fbStb 	for (i = 0; i < N_S2I_TESTS; i++)
26651de66fbStb 		failed |= test_s2i_ASN1_OCTET_STRING(&s2i_test[i]);
26751de66fbStb 
26851de66fbStb 	return failed;
26951de66fbStb }
27051de66fbStb 
27151de66fbStb int
main(void)27251de66fbStb main(void)
27351de66fbStb {
27451de66fbStb 	int failed = 0;
27551de66fbStb 
27651de66fbStb 	failed |= run_i2s_ASN1_OCTET_STRING_tests();
27751de66fbStb 	failed |= run_s2i_ASN1_OCTET_STRING_tests();
27851de66fbStb 
27951de66fbStb 	return failed;
28051de66fbStb }
281