1 /*	$OpenBSD: bn_to_string.c,v 1.5 2023/04/10 21:00:16 tb Exp $ */
2 /*
3  * Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <err.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include <openssl/x509v3.h>
24 
25 struct bn_to_string_tests {
26 	const char	*input;
27 	const char	*want;
28 } testcases[] = {
29 	{
30 		.input = "0x0",
31 		.want = "0",
32 	},
33 	{
34 		.input = "-0x0",
35 		.want = "0",
36 	},
37 	{
38 		.input = "0x7",
39 		.want = "7",
40 	},
41 	{
42 		.input = "-0x7",
43 		.want = "-7",
44 	},
45 	{
46 		.input = "0x8",
47 		.want = "8",
48 	},
49 	{
50 		.input = "-0x8",
51 		.want = "-8",
52 	},
53 	{
54 		.input = "0xF",
55 		.want = "15",
56 	},
57 	{
58 		.input = "-0xF",
59 		.want = "-15",
60 	},
61 	{
62 		.input = "0x10",
63 		.want = "16",
64 	},
65 	{
66 		.input = "-0x10",
67 		.want = "-16",
68 	},
69 	{
70 		.input = "0x7F",
71 		.want = "127",
72 	},
73 	{
74 		.input = "-0x7F",
75 		.want = "-127",
76 	},
77 	{
78 		.input = "0x80",
79 		.want = "128",
80 	},
81 	{
82 		.input = "-0x80",
83 		.want = "-128",
84 	},
85 	{
86 		.input = "0xFF",
87 		.want = "255",
88 	},
89 	{
90 		.input = "-0xFF",
91 		.want = "-255",
92 	},
93 	{
94 		.input = "0x100",
95 		.want = "256",
96 	},
97 	{
98 		.input = "0x7FFF",
99 		.want = "32767",
100 	},
101 	{
102 		.input = "-0x7FFF",
103 		.want = "-32767",
104 	},
105 	{
106 		.input = "0x8000",
107 		.want = "32768",
108 	},
109 	{
110 		.input = "-0x8000",
111 		.want = "-32768",
112 	},
113 	{
114 		.input = "0xFFFF",
115 		.want = "65535",
116 	},
117 	{
118 		.input = "-0xFFFF",
119 		.want = "-65535",
120 	},
121 	{
122 		.input = "0x10000",
123 		.want = "65536",
124 	},
125 	{
126 		.input = "-0x10000",
127 		.want = "-65536",
128 	},
129 	{
130 		.input = "0x7FFFFFFF",
131 		.want = "2147483647",
132 	},
133 	{
134 		.input = "-0x7FFFFFFF",
135 		.want = "-2147483647",
136 	},
137 	{
138 		.input = "0x80000000",
139 		.want = "2147483648",
140 	},
141 	{
142 		.input = "-0x80000000",
143 		.want = "-2147483648",
144 	},
145 	{
146 		.input = "0xFFFFFFFF",
147 		.want = "4294967295",
148 	},
149 	{
150 		.input = "-0xFFFFFFFF",
151 		.want = "-4294967295",
152 	},
153 	{
154 		.input = "0x100000000",
155 		.want = "4294967296",
156 	},
157 	{
158 		.input = "-0x100000000",
159 		.want = "-4294967296",
160 	},
161 	{
162 		.input = "0x7FFFFFFFFFFFFFFF",
163 		.want = "9223372036854775807",
164 	},
165 	{
166 		.input = "-0x7FFFFFFFFFFFFFFF",
167 		.want = "-9223372036854775807",
168 	},
169 	{
170 		.input = "0x8000000000000000",
171 		.want = "9223372036854775808",
172 	},
173 	{
174 		.input = "-0x8000000000000000",
175 		.want = "-9223372036854775808",
176 	},
177 	{
178 		.input = "0xFFFFFFFFFFFFFFFF",
179 		.want = "18446744073709551615",
180 	},
181 	{
182 		.input = "-0xFFFFFFFFFFFFFFFF",
183 		.want = "-18446744073709551615",
184 	},
185 	{
186 		.input = "0x10000000000000000",
187 		.want = "18446744073709551616",
188 	},
189 	{
190 		.input = "-0x10000000000000000",
191 		.want = "-18446744073709551616",
192 	},
193 	{
194 		.input = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
195 		.want = "170141183460469231731687303715884105727",
196 	},
197 	{
198 		.input = "-0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
199 		.want = "-170141183460469231731687303715884105727",
200 	},
201 	{
202 		.input = "0x80000000000000000000000000000000",
203 		.want = "0x80000000000000000000000000000000",
204 	},
205 	{
206 		.input = "-0x80000000000000000000000000000000",
207 		.want = "-0x80000000000000000000000000000000",
208 	},
209 	{
210 		.input = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
211 		.want = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
212 	},
213 	{
214 		.input = "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
215 		.want = "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
216 	},
217 	{
218 		.input = "0x100000000000000000000000000000000",
219 		.want = "0x0100000000000000000000000000000000",
220 	},
221 	{
222 		.input = "-0x100000000000000000000000000000000",
223 		.want = "-0x0100000000000000000000000000000000",
224 	},
225 	{
226 		.input = NULL,
227 	},
228 };
229 
230 int
231 main(void)
232 {
233 	struct bn_to_string_tests *test;
234 	ASN1_INTEGER *aint;
235 	char *got;
236 	int failed = 0;
237 
238 	for (test = testcases; test->input != NULL; test++) {
239 		if ((aint = s2i_ASN1_INTEGER(NULL, test->input)) == NULL)
240 			errx(1, "s2i_ASN1_INTEGER(%s)", test->input);
241 		if ((got = i2s_ASN1_INTEGER(NULL, aint)) == NULL)
242 			errx(1, "i2s_ASN1_INTEGER(%s)", test->input);
243 		if (strcmp(got, test->want) != 0) {
244 			warnx("want: %s, got: %s", test->want, got);
245 			failed |= 1;
246 		}
247 		ASN1_INTEGER_free(aint);
248 		free(got);
249 	}
250 
251 	return failed;
252 }
253