xref: /openbsd-src/regress/lib/libcrypto/asn1/asn1_string_to_utf8.c (revision a201dd641c0ccb400edef7e81e23c453d6779580)
1*a201dd64Stb /*	$OpenBSD: asn1_string_to_utf8.c,v 1.2 2022/11/23 08:51:05 tb Exp $ */
2eabc5796Stb /*
3eabc5796Stb  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
4eabc5796Stb  *
5eabc5796Stb  * Permission to use, copy, modify, and distribute this software for any
6eabc5796Stb  * purpose with or without fee is hereby granted, provided that the above
7eabc5796Stb  * copyright notice and this permission notice appear in all copies.
8eabc5796Stb  *
9eabc5796Stb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10eabc5796Stb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11eabc5796Stb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12eabc5796Stb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13eabc5796Stb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14eabc5796Stb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15eabc5796Stb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16eabc5796Stb  */
17eabc5796Stb 
18eabc5796Stb #include <err.h>
19eabc5796Stb #include <string.h>
20eabc5796Stb 
21eabc5796Stb #include <openssl/asn1.h>
22eabc5796Stb 
23eabc5796Stb struct asn1_string_to_utf8_test_case {
24eabc5796Stb 	const char *description;
25eabc5796Stb 	const ASN1_ITEM *item;
26eabc5796Stb 	const uint8_t der[32];
27eabc5796Stb 	size_t der_len;
28eabc5796Stb 	const uint8_t want[32];
29eabc5796Stb 	int want_len;
30eabc5796Stb };
31eabc5796Stb 
32eabc5796Stb static const struct asn1_string_to_utf8_test_case tests[] = {
33eabc5796Stb 	{
34eabc5796Stb 		.description = "hello",
35eabc5796Stb 		.item = &ASN1_PRINTABLESTRING_it,
36eabc5796Stb 		.der = {
37eabc5796Stb 			0x13, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
38eabc5796Stb 		},
39eabc5796Stb 		.der_len = 7,
40eabc5796Stb 		.want = {
41eabc5796Stb 			0x68, 0x65, 0x6c, 0x6c, 0x6f,
42eabc5796Stb 		},
43eabc5796Stb 		.want_len = 5,
44eabc5796Stb 	},
45eabc5796Stb 	{
46eabc5796Stb 		.description = "face with tears of joy",
47eabc5796Stb 		.item = &ASN1_UTF8STRING_it,
48eabc5796Stb 		.der = {
49eabc5796Stb 			0x0c, 0x04, 0xF0, 0x9F, 0x98, 0x82,
50eabc5796Stb 		},
51eabc5796Stb 		.der_len = 6,
52eabc5796Stb 		.want = {
53eabc5796Stb 			0xF0, 0x9F, 0x98, 0x82,
54eabc5796Stb 		},
55eabc5796Stb 		.want_len = 4,
56eabc5796Stb 	},
57eabc5796Stb 	{
58eabc5796Stb 		.description = "hi",
59eabc5796Stb 		.item = &ASN1_IA5STRING_it,
60eabc5796Stb 		.der = {
61eabc5796Stb 			0x16, 0x02, 0x68, 0x69,
62eabc5796Stb 		},
63eabc5796Stb 		.der_len = 4,
64eabc5796Stb 		.want = {
65eabc5796Stb 			0x68, 0x69,
66eabc5796Stb 		},
67eabc5796Stb 		.want_len = 2,
68eabc5796Stb 	},
69eabc5796Stb };
70eabc5796Stb 
71eabc5796Stb const size_t N_TESTS = sizeof(tests) / sizeof(tests[0]);
72eabc5796Stb 
73eabc5796Stb static int
asn1_string_to_utf8_test(const struct asn1_string_to_utf8_test_case * test)74eabc5796Stb asn1_string_to_utf8_test(const struct asn1_string_to_utf8_test_case *test)
75eabc5796Stb {
76eabc5796Stb 	ASN1_STRING *str = NULL;
77eabc5796Stb 	const unsigned char *der;
78eabc5796Stb 	unsigned char *out = NULL;
79eabc5796Stb 	int ret;
80eabc5796Stb 	int failed = 1;
81eabc5796Stb 
82eabc5796Stb 	der = test->der;
83eabc5796Stb 	if ((str = (ASN1_STRING *)ASN1_item_d2i(NULL, &der, test->der_len,
84eabc5796Stb 	    test->item)) == NULL) {
85eabc5796Stb 		warnx("ASN1_item_d2i failed");
86eabc5796Stb 		goto err;
87eabc5796Stb 	}
88eabc5796Stb 
89*a201dd64Stb 	if ((ret = ASN1_STRING_to_UTF8(&out, str)) < 0) {
90eabc5796Stb 		warnx("ASN1_STRING_to_UTF8 failed: got %d, want %d", ret,
91eabc5796Stb 		    test->want_len);
92eabc5796Stb 		goto err;
93eabc5796Stb 	}
94eabc5796Stb 
95*a201dd64Stb 	if (ret != test->want_len) {
96*a201dd64Stb 		warnx("ASN1_STRING_to_UTF8: got %d, want %d", ret,
97*a201dd64Stb 		    test->want_len);
98*a201dd64Stb 		goto err;
99*a201dd64Stb 	}
100*a201dd64Stb 
101eabc5796Stb 	if (memcmp(out, test->want, test->want_len) != 0) {
102eabc5796Stb 		warnx("memcmp failed");
103eabc5796Stb 		goto err;
104eabc5796Stb 	}
105eabc5796Stb 
106eabc5796Stb 	failed = 0;
107eabc5796Stb  err:
108eabc5796Stb 	ASN1_STRING_free(str);
109eabc5796Stb 	free(out);
110eabc5796Stb 
111eabc5796Stb 	return failed;
112eabc5796Stb }
113eabc5796Stb 
114eabc5796Stb static int
asn1_string_to_utf8_tests(void)115eabc5796Stb asn1_string_to_utf8_tests(void)
116eabc5796Stb {
117eabc5796Stb 	size_t i;
118eabc5796Stb 	int failed = 0;
119eabc5796Stb 
120eabc5796Stb 	for (i = 0; i < N_TESTS; i++)
121eabc5796Stb 		failed |= asn1_string_to_utf8_test(&tests[i]);
122eabc5796Stb 
123eabc5796Stb 	return failed;
124eabc5796Stb }
125eabc5796Stb 
126eabc5796Stb int
main(void)127eabc5796Stb main(void)
128eabc5796Stb {
129eabc5796Stb 	int failed = 0;
130eabc5796Stb 
131eabc5796Stb 	failed |= asn1_string_to_utf8_tests();
132eabc5796Stb 
133eabc5796Stb 	return failed;
134eabc5796Stb }
135