summaryrefslogtreecommitdiff
path: root/src/regress/lib
diff options
context:
space:
mode:
authorjsing <>2021-12-14 17:10:02 +0000
committerjsing <>2021-12-14 17:10:02 +0000
commitbb673fb853e10ee12848841c7d2608a5018a7e5c (patch)
tree30d331f6d53c153c12aa41a88aa83dd15954c8e7 /src/regress/lib
parent1d9510b0e4ff14df346622c4b2cdb7e461b208a6 (diff)
downloadopenbsd-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.c263
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
124struct 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
135const 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
316static int
317asn1_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
124int 384int
125main(int argc, char **argv) 385main(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}