diff options
author | jsing <> | 2021-12-14 17:10:02 +0000 |
---|---|---|
committer | jsing <> | 2021-12-14 17:10:02 +0000 |
commit | bb673fb853e10ee12848841c7d2608a5018a7e5c (patch) | |
tree | 30d331f6d53c153c12aa41a88aa83dd15954c8e7 /src/regress/lib | |
parent | 1d9510b0e4ff14df346622c4b2cdb7e461b208a6 (diff) | |
download | openbsd-bb673fb853e10ee12848841c7d2608a5018a7e5c.tar.gz openbsd-bb673fb853e10ee12848841c7d2608a5018a7e5c.tar.bz2 openbsd-bb673fb853e10ee12848841c7d2608a5018a7e5c.zip |
Add regress coverage for ASN1_get_object()
Diffstat (limited to 'src/regress/lib')
-rw-r--r-- | src/regress/lib/libcrypto/asn1/asn1api.c | 263 |
1 files changed, 262 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/asn1/asn1api.c b/src/regress/lib/libcrypto/asn1/asn1api.c index 05b7353d4d..4825dd65f2 100644 --- a/src/regress/lib/libcrypto/asn1/asn1api.c +++ b/src/regress/lib/libcrypto/asn1/asn1api.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: asn1api.c,v 1.1 2021/12/14 17:07:57 jsing Exp $ */ | 1 | /* $OpenBSD: asn1api.c,v 1.2 2021/12/14 17:10:02 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -121,6 +121,266 @@ asn1_tag2str(void) | |||
121 | return failed; | 121 | return failed; |
122 | } | 122 | } |
123 | 123 | ||
124 | struct asn1_get_object_test { | ||
125 | const uint8_t asn1[64]; | ||
126 | size_t asn1_len; | ||
127 | size_t asn1_hdr_len; | ||
128 | int want_ret; | ||
129 | long want_length; | ||
130 | int want_tag; | ||
131 | int want_class; | ||
132 | int want_error; | ||
133 | }; | ||
134 | |||
135 | const struct asn1_get_object_test asn1_get_object_tests[] = { | ||
136 | { | ||
137 | /* Zero tag and zero length (EOC). */ | ||
138 | .asn1 = {0x00, 0x00}, | ||
139 | .asn1_len = 2, | ||
140 | .asn1_hdr_len = 2, | ||
141 | .want_ret = 0x00, | ||
142 | .want_length = 0, | ||
143 | .want_tag = 0, | ||
144 | .want_class = 0, | ||
145 | }, | ||
146 | { | ||
147 | /* Boolean with short form length. */ | ||
148 | .asn1 = {0x01, 0x01}, | ||
149 | .asn1_len = 3, | ||
150 | .asn1_hdr_len = 2, | ||
151 | .want_ret = 0x00, | ||
152 | .want_length = 1, | ||
153 | .want_tag = 1, | ||
154 | .want_class = 0, | ||
155 | }, | ||
156 | { | ||
157 | /* Long form tag. */ | ||
158 | .asn1 = {0x1f, 0x7f, 0x01}, | ||
159 | .asn1_len = 3 + 128, | ||
160 | .asn1_hdr_len = 3, | ||
161 | .want_ret = 0x00, | ||
162 | .want_length = 1, | ||
163 | .want_tag = 127, | ||
164 | .want_class = 0, | ||
165 | }, | ||
166 | { | ||
167 | /* Long form tag with class application. */ | ||
168 | .asn1 = {0x5f, 0x7f, 0x01}, | ||
169 | .asn1_len = 3 + 128, | ||
170 | .asn1_hdr_len = 3, | ||
171 | .want_ret = 0x00, | ||
172 | .want_length = 1, | ||
173 | .want_tag = 127, | ||
174 | .want_class = 1 << 6, | ||
175 | }, | ||
176 | { | ||
177 | /* Long form tag with class context-specific. */ | ||
178 | .asn1 = {0x9f, 0x7f, 0x01}, | ||
179 | .asn1_len = 3 + 128, | ||
180 | .asn1_hdr_len = 3, | ||
181 | .want_ret = 0x00, | ||
182 | .want_length = 1, | ||
183 | .want_tag = 127, | ||
184 | .want_class = 2 << 6, | ||
185 | }, | ||
186 | { | ||
187 | /* Long form tag with class private. */ | ||
188 | .asn1 = {0xdf, 0x7f, 0x01}, | ||
189 | .asn1_len = 3 + 128, | ||
190 | .asn1_hdr_len = 3, | ||
191 | .want_ret = 0x00, | ||
192 | .want_length = 1, | ||
193 | .want_tag = 127, | ||
194 | .want_class = 3 << 6, | ||
195 | }, | ||
196 | { | ||
197 | /* Long form tag (maximum). */ | ||
198 | .asn1 = {0x1f, 0x87, 0xff, 0xff, 0xff, 0x7f, 0x01}, | ||
199 | .asn1_len = 8, | ||
200 | .asn1_hdr_len = 7, | ||
201 | .want_ret = 0x00, | ||
202 | .want_length = 1, | ||
203 | .want_tag = 0x7fffffff, | ||
204 | .want_class = 0, | ||
205 | }, | ||
206 | { | ||
207 | /* Long form tag (maximum + 1). */ | ||
208 | .asn1 = {0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x01}, | ||
209 | .asn1_len = 8, | ||
210 | .asn1_hdr_len = 7, | ||
211 | .want_ret = 0x80, | ||
212 | .want_error = ASN1_R_HEADER_TOO_LONG, | ||
213 | }, | ||
214 | { | ||
215 | /* OctetString with long form length. */ | ||
216 | .asn1 = {0x04, 0x81, 0x80}, | ||
217 | .asn1_len = 3 + 128, | ||
218 | .asn1_hdr_len = 3, | ||
219 | .want_ret = 0x00, | ||
220 | .want_length = 128, | ||
221 | .want_tag = 4, | ||
222 | .want_class = 0, | ||
223 | }, | ||
224 | { | ||
225 | /* OctetString with long form length. */ | ||
226 | .asn1 = {0x04, 0x84, 0x7f, 0xff, 0xff, 0xf9}, | ||
227 | .asn1_len = 0x7fffffff, | ||
228 | .asn1_hdr_len = 6, | ||
229 | .want_ret = 0x00, | ||
230 | .want_length = 0x7ffffff9, | ||
231 | .want_tag = 4, | ||
232 | .want_class = 0, | ||
233 | }, | ||
234 | { | ||
235 | /* Long form tag and long form length. */ | ||
236 | .asn1 = {0x1f, 0x87, 0xff, 0xff, 0xff, 0x7f, 0x84, 0x7f, 0xff, 0xff, 0xf4}, | ||
237 | .asn1_len = 0x7fffffff, | ||
238 | .asn1_hdr_len = 11, | ||
239 | .want_ret = 0x00, | ||
240 | .want_length = 0x7ffffff4, | ||
241 | .want_tag = 0x7fffffff, | ||
242 | .want_class = 0, | ||
243 | }, | ||
244 | { | ||
245 | /* Constructed OctetString with definite length. */ | ||
246 | .asn1 = {0x24, 0x03}, | ||
247 | .asn1_len = 5, | ||
248 | .asn1_hdr_len = 2, | ||
249 | .want_ret = 0x20, | ||
250 | .want_length = 3, | ||
251 | .want_tag = 4, | ||
252 | .want_class = 0, | ||
253 | }, | ||
254 | { | ||
255 | /* Constructed OctetString with indefinite length. */ | ||
256 | .asn1 = {0x24, 0x80}, | ||
257 | .asn1_len = 5, | ||
258 | .asn1_hdr_len = 2, | ||
259 | .want_ret = 0x21, | ||
260 | .want_length = 0, | ||
261 | .want_tag = 4, | ||
262 | .want_class = 0, | ||
263 | }, | ||
264 | { | ||
265 | /* Boolean with indefinite length (invalid). */ | ||
266 | .asn1 = {0x01, 0x80}, | ||
267 | .asn1_len = 3, | ||
268 | .want_ret = 0x80, | ||
269 | .want_error = ASN1_R_HEADER_TOO_LONG, | ||
270 | }, | ||
271 | { | ||
272 | /* OctetString with insufficient data (only tag). */ | ||
273 | .asn1 = {0x04, 0x04}, | ||
274 | .asn1_len = 1, | ||
275 | .want_ret = 0x80, | ||
276 | .want_error = ASN1_R_HEADER_TOO_LONG, | ||
277 | }, | ||
278 | { | ||
279 | /* OctetString with insufficient data (missing content). */ | ||
280 | .asn1 = {0x04, 0x04}, | ||
281 | .asn1_len = 2, | ||
282 | .asn1_hdr_len = 2, | ||
283 | .want_ret = 0x80, | ||
284 | .want_length = 4, | ||
285 | .want_tag = 4, | ||
286 | .want_class = 0, | ||
287 | .want_error = ASN1_R_TOO_LONG, | ||
288 | }, | ||
289 | { | ||
290 | /* OctetString with insufficient data (partial content). */ | ||
291 | .asn1 = {0x04, 0x04}, | ||
292 | .asn1_len = 5, | ||
293 | .asn1_hdr_len = 2, | ||
294 | .want_ret = 0x80, | ||
295 | .want_length = 4, | ||
296 | .want_tag = 4, | ||
297 | .want_class = 0, | ||
298 | .want_error = ASN1_R_TOO_LONG, | ||
299 | }, | ||
300 | { | ||
301 | /* Constructed OctetString with insufficient data (only tag/len). */ | ||
302 | .asn1 = {0x24, 0x04}, | ||
303 | .asn1_len = 2, | ||
304 | .asn1_hdr_len = 2, | ||
305 | .want_ret = 0xa0, | ||
306 | .want_length = 4, | ||
307 | .want_tag = 4, | ||
308 | .want_class = 0, | ||
309 | .want_error = ASN1_R_TOO_LONG, | ||
310 | }, | ||
311 | }; | ||
312 | |||
313 | #define N_ASN1_GET_OBJECT_TESTS \ | ||
314 | (sizeof(asn1_get_object_tests) / sizeof(*asn1_get_object_tests)) | ||
315 | |||
316 | static int | ||
317 | asn1_get_object(void) | ||
318 | { | ||
319 | const struct asn1_get_object_test *agot; | ||
320 | const uint8_t *p; | ||
321 | int ret, tag, tag_class; | ||
322 | long err, length; | ||
323 | size_t i; | ||
324 | int failed = 1; | ||
325 | |||
326 | for (i = 0; i < N_ASN1_GET_OBJECT_TESTS; i++) { | ||
327 | agot = &asn1_get_object_tests[i]; | ||
328 | |||
329 | ERR_clear_error(); | ||
330 | |||
331 | p = agot->asn1; | ||
332 | ret = ASN1_get_object(&p, &length, &tag, &tag_class, agot->asn1_len); | ||
333 | |||
334 | if (ret != agot->want_ret) { | ||
335 | fprintf(stderr, "FAIL: %zu - got return value %x, want %x\n", | ||
336 | i, ret, agot->want_ret); | ||
337 | goto failed; | ||
338 | } | ||
339 | if (ret & 0x80) { | ||
340 | err = ERR_peek_error(); | ||
341 | if (ERR_GET_REASON(err) != agot->want_error) { | ||
342 | fprintf(stderr, "FAIL: %zu - got error reason %d, " | ||
343 | "want %d\n", i, ERR_GET_REASON(err), | ||
344 | agot->want_error); | ||
345 | goto failed; | ||
346 | } | ||
347 | if (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG) { | ||
348 | if (p != agot->asn1) { | ||
349 | fprintf(stderr, "FAIL: %zu - got ber_in %p, " | ||
350 | "want %p\n", i, p, agot->asn1); | ||
351 | goto failed; | ||
352 | } | ||
353 | continue; | ||
354 | } | ||
355 | } | ||
356 | if (length != agot->want_length) { | ||
357 | fprintf(stderr, "FAIL: %zu - got length %ld, want %ld\n", | ||
358 | i, length, agot->want_length); | ||
359 | goto failed; | ||
360 | } | ||
361 | if (tag != agot->want_tag) { | ||
362 | fprintf(stderr, "FAIL: %zu - got tag %d, want %d\n", | ||
363 | i, tag, agot->want_tag); | ||
364 | goto failed; | ||
365 | } | ||
366 | if (tag_class != agot->want_class) { | ||
367 | fprintf(stderr, "FAIL: %zu - got class %d, want %d\n", | ||
368 | i, tag_class, agot->want_class); | ||
369 | goto failed; | ||
370 | } | ||
371 | if (p != agot->asn1 + agot->asn1_hdr_len) { | ||
372 | fprintf(stderr, "FAIL: %zu - got ber_in %p, want %p\n", | ||
373 | i, p, agot->asn1 + agot->asn1_len); | ||
374 | goto failed; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | failed = 0; | ||
379 | |||
380 | failed: | ||
381 | return failed; | ||
382 | } | ||
383 | |||
124 | int | 384 | int |
125 | main(int argc, char **argv) | 385 | main(int argc, char **argv) |
126 | { | 386 | { |
@@ -128,6 +388,7 @@ main(int argc, char **argv) | |||
128 | 388 | ||
129 | failed |= asn1_tag2bit(); | 389 | failed |= asn1_tag2bit(); |
130 | failed |= asn1_tag2str(); | 390 | failed |= asn1_tag2str(); |
391 | failed |= asn1_get_object(); | ||
131 | 392 | ||
132 | return (failed); | 393 | return (failed); |
133 | } | 394 | } |