1 /* $OpenBSD: asn1basic.c,v 1.16 2024/02/04 13:07:02 tb Exp $ */
2 /*
3 * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <openssl/asn1.h>
20 #include <openssl/err.h>
21
22 #include <err.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "asn1_local.h"
27
28 static void
hexdump(const unsigned char * buf,size_t len)29 hexdump(const unsigned char *buf, size_t len)
30 {
31 size_t i;
32
33 for (i = 1; i <= len; i++)
34 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
35
36 fprintf(stderr, "\n");
37 }
38
39 static int
asn1_compare_bytes(const char * label,const unsigned char * d1,int len1,const unsigned char * d2,int len2)40 asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
41 const unsigned char *d2, int len2)
42 {
43 if (len1 != len2) {
44 fprintf(stderr, "FAIL: %s - byte lengths differ "
45 "(%d != %d)\n", label, len1, len2);
46 fprintf(stderr, "Got:\n");
47 hexdump(d1, len1);
48 fprintf(stderr, "Want:\n");
49 hexdump(d2, len2);
50 return 0;
51 }
52 if (memcmp(d1, d2, len1) != 0) {
53 fprintf(stderr, "FAIL: %s - bytes differ\n", label);
54 fprintf(stderr, "Got:\n");
55 hexdump(d1, len1);
56 fprintf(stderr, "Want:\n");
57 hexdump(d2, len2);
58 return 0;
59 }
60 return 1;
61 }
62
63 const uint8_t asn1_bit_string_primitive[] = {
64 0x03, 0x07,
65 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0,
66 };
67
68 static int
asn1_bit_string_test(void)69 asn1_bit_string_test(void)
70 {
71 uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0};
72 ASN1_BIT_STRING *abs;
73 uint8_t *p = NULL, *pp;
74 const uint8_t *q;
75 int bit, i, len;
76 int failed = 1;
77
78 if ((abs = ASN1_BIT_STRING_new()) == NULL) {
79 fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n");
80 goto failed;
81 }
82 if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) {
83 fprintf(stderr, "FAIL: failed to set bit string\n");
84 goto failed;
85 }
86
87 if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) {
88 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n");
89 goto failed;
90 }
91 if ((p = malloc(len)) == NULL)
92 errx(1, "malloc");
93 memset(p, 0xbd, len);
94 pp = p;
95 if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
96 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
97 goto failed;
98 }
99 if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive,
100 sizeof(asn1_bit_string_primitive)))
101 goto failed;
102 if (pp != p + len) {
103 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING pp = %p, want %p\n",
104 pp, p + len);
105 goto failed;
106 }
107
108 /* Test primitive decoding. */
109 q = p;
110 if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) {
111 fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n");
112 goto failed;
113 }
114 if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length,
115 bs, sizeof(bs)))
116 goto failed;
117 if (q != p + len) {
118 fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING q = %p, want %p\n",
119 q, p + len);
120 goto failed;
121 }
122
123 /* Test ASN1_BIT_STRING_get_bit(). */
124 for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
125 bit = (bs[i / 8] >> (7 - i % 8)) & 1;
126
127 if (ASN1_BIT_STRING_get_bit(abs, i) != bit) {
128 fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) "
129 "= %d, want %d\n", i,
130 ASN1_BIT_STRING_get_bit(abs, i), bit);
131 goto failed;
132 }
133 }
134
135 /* Test ASN1_BIT_STRING_set_bit(). */
136 for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
137 if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) {
138 fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n");
139 goto failed;
140 }
141 }
142 for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) {
143 bit = (bs[i / 8] >> (7 - i % 8)) & 1;
144 if (bit == 1)
145 continue;
146 if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) {
147 fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n");
148 goto failed;
149 }
150 }
151
152 if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) {
153 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
154 goto failed;
155 }
156
157 memset(p, 0xbd, len);
158 pp = p;
159 if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
160 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
161 goto failed;
162 }
163
164 if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive,
165 sizeof(asn1_bit_string_primitive)))
166 goto failed;
167
168 failed = 0;
169
170 failed:
171 ASN1_BIT_STRING_free(abs);
172 free(p);
173
174 return failed;
175 }
176
177 const uint8_t asn1_boolean_false[] = {
178 0x01, 0x01, 0x00,
179 };
180 const uint8_t asn1_boolean_true[] = {
181 0x01, 0x01, 0x01,
182 };
183
184 static int
asn1_boolean_test(void)185 asn1_boolean_test(void)
186 {
187 uint8_t *p = NULL, *pp;
188 const uint8_t *q;
189 int len;
190 int failed = 1;
191
192 if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) {
193 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n");
194 goto failed;
195 }
196 if ((p = malloc(len)) == NULL)
197 errx(1, "calloc");
198 memset(p, 0xbd, len);
199 pp = p;
200 if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) {
201 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n");
202 goto failed;
203 }
204 if (pp != p + len) {
205 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
206 pp, p + len);
207 goto failed;
208 }
209
210 if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false,
211 sizeof(asn1_boolean_false)))
212 goto failed;
213
214 q = p;
215 if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) {
216 fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n");
217 goto failed;
218 }
219 if (q != p + len) {
220 fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
221 q, p + len);
222 goto failed;
223 }
224
225 free(p);
226 p = NULL;
227
228 if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) {
229 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n");
230 goto failed;
231 }
232 if ((p = calloc(1, len)) == NULL)
233 errx(1, "calloc");
234 pp = p;
235 if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) {
236 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n");
237 goto failed;
238 }
239 if (pp != p + len) {
240 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
241 pp, p + len);
242 goto failed;
243 }
244
245 if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true,
246 sizeof(asn1_boolean_true)))
247 goto failed;
248
249 q = p;
250 if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) {
251 fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n");
252 goto failed;
253 }
254 if (q != p + len) {
255 fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
256 q, p + len);
257 goto failed;
258 }
259
260 failed = 0;
261
262 failed:
263 free(p);
264
265 return failed;
266 }
267
268 struct asn1_integer_test {
269 long value;
270 uint8_t content[64];
271 size_t content_len;
272 int content_neg;
273 uint8_t der[64];
274 size_t der_len;
275 int want_error;
276 };
277
278 struct asn1_integer_test asn1_integer_tests[] = {
279 {
280 .value = 0,
281 .content = {0x00},
282 .content_len = 1,
283 .der = {0x02, 0x01, 0x00},
284 .der_len = 3,
285 },
286 {
287 .value = 1,
288 .content = {0x01},
289 .content_len = 1,
290 .der = {0x02, 0x01, 0x01},
291 .der_len = 3,
292 },
293 {
294 .value = -1,
295 .content = {0x01},
296 .content_len = 1,
297 .content_neg = 1,
298 .der = {0x02, 0x01, 0xff},
299 .der_len = 3,
300 },
301 {
302 .value = 127,
303 .content = {0x7f},
304 .content_len = 1,
305 .der = {0x02, 0x01, 0x7f},
306 .der_len = 3,
307 },
308 {
309 .value = -127,
310 .content = {0x7f},
311 .content_len = 1,
312 .content_neg = 1,
313 .der = {0x02, 0x01, 0x81},
314 .der_len = 3,
315 },
316 {
317 .value = 128,
318 .content = {0x80},
319 .content_len = 1,
320 .der = {0x02, 0x02, 0x00, 0x80},
321 .der_len = 4,
322 },
323 {
324 .value = -128,
325 .content = {0x80},
326 .content_len = 1,
327 .content_neg = 1,
328 .der = {0x02, 0x01, 0x80},
329 .der_len = 3,
330 },
331 {
332 /* 2^64 */
333 .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
334 .content_len = 9,
335 .der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
336 .der_len = 11,
337 },
338 {
339 /* -2^64 */
340 .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
341 .content_len = 9,
342 .content_neg = 1,
343 .der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
344 .der_len = 11,
345 },
346 {
347 /* Invalid length. */
348 .der = {0x02, 0x00},
349 .der_len = 2,
350 .want_error = 1,
351 },
352 {
353 /* Invalid padding. */
354 .der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
355 .der_len = 11,
356 .want_error = 1,
357 },
358 {
359 /* Invalid padding. */
360 .der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
361 .der_len = 11,
362 .want_error = 1,
363 },
364 {
365 /* Invalid encoding (constructed with definite length). */
366 .der = {0x22, 0x03, 0x02, 0x01, 0x01},
367 .der_len = 5,
368 .want_error = 1,
369 },
370 {
371 /* Invalid encoding (constructed with indefinite length). */
372 .der = {0x22, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00},
373 .der_len = 7,
374 .want_error = 1,
375 },
376 };
377
378 #define N_ASN1_INTEGER_TESTS \
379 (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests))
380
381 static int
asn1_integer_set_test(struct asn1_integer_test * ait)382 asn1_integer_set_test(struct asn1_integer_test *ait)
383 {
384 ASN1_INTEGER *aint = NULL;
385 uint8_t *p = NULL, *pp;
386 int len;
387 int failed = 1;
388
389 if ((aint = ASN1_INTEGER_new()) == NULL) {
390 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
391 goto failed;
392 }
393 if (!ASN1_INTEGER_set(aint, ait->value)) {
394 fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n",
395 ait->value);
396 goto failed;
397 }
398 if (ait->value != 0 &&
399 !asn1_compare_bytes("INTEGER set", aint->data, aint->length,
400 ait->content, ait->content_len))
401 goto failed;
402 if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) {
403 fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n");
404 goto failed;
405 }
406 if (ASN1_INTEGER_get(aint) != ait->value) {
407 fprintf(stderr, "FAIL: ASN1_INTEGER_get() = %ld, want %ld\n",
408 ASN1_INTEGER_get(aint), ait->value);
409 goto failed;
410 }
411 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
412 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
413 goto failed;
414 }
415 if ((p = malloc(len)) == NULL)
416 errx(1, "malloc");
417 memset(p, 0xbd, len);
418 pp = p;
419 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
420 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
421 goto failed;
422 }
423 if (!asn1_compare_bytes("INTEGER set", p, len, ait->der,
424 ait->der_len))
425 goto failed;
426
427 failed = 0;
428
429 failed:
430 ASN1_INTEGER_free(aint);
431 free(p);
432
433 return failed;
434 }
435
436 static int
asn1_integer_content_test(struct asn1_integer_test * ait)437 asn1_integer_content_test(struct asn1_integer_test *ait)
438 {
439 ASN1_INTEGER *aint = NULL;
440 uint8_t *p = NULL, *pp;
441 int len;
442 int failed = 1;
443
444 if ((aint = ASN1_INTEGER_new()) == NULL) {
445 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
446 goto failed;
447 }
448 if ((aint->data = malloc(ait->content_len)) == NULL)
449 errx(1, "malloc");
450 memcpy(aint->data, ait->content, ait->content_len);
451 aint->length = ait->content_len;
452 if (ait->content_neg)
453 aint->type = V_ASN1_NEG_INTEGER;
454
455 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
456 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
457 goto failed;
458 }
459 if ((p = malloc(len)) == NULL)
460 errx(1, "malloc");
461 memset(p, 0xbd, len);
462 pp = p;
463 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
464 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
465 goto failed;
466 }
467 if (!asn1_compare_bytes("INTEGER content", p, len, ait->der,
468 ait->der_len))
469 goto failed;
470 if (pp != p + len) {
471 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER pp = %p, want %p\n",
472 pp, p + len);
473 goto failed;
474 }
475
476 failed = 0;
477
478 failed:
479 ASN1_INTEGER_free(aint);
480 free(p);
481
482 return failed;
483 }
484
485 static int
asn1_integer_decode_test(struct asn1_integer_test * ait)486 asn1_integer_decode_test(struct asn1_integer_test *ait)
487 {
488 ASN1_INTEGER *aint = NULL;
489 const uint8_t *q;
490 int failed = 1;
491
492 q = ait->der;
493 if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) {
494 if (ait->want_error != 0) {
495 fprintf(stderr, "FAIL: INTEGER decoded when it should "
496 "have failed\n");
497 goto failed;
498 }
499 if (!asn1_compare_bytes("INTEGER content", aint->data,
500 aint->length, ait->content, ait->content_len))
501 goto failed;
502 if (q != ait->der + ait->der_len) {
503 fprintf(stderr, "FAIL: d2i_ASN1_INTEGER q = %p, want %p\n",
504 q, ait->der + ait->der_len);
505 goto failed;
506 }
507 } else if (ait->want_error == 0) {
508 fprintf(stderr, "FAIL: INTEGER failed to decode\n");
509 ERR_print_errors_fp(stderr);
510 goto failed;
511 }
512
513 failed = 0;
514
515 failed:
516 ASN1_INTEGER_free(aint);
517
518 return failed;
519 }
520
521 static int
asn1_integer_set_val_test(void)522 asn1_integer_set_val_test(void)
523 {
524 ASN1_INTEGER *aint = NULL;
525 uint64_t uval;
526 int64_t val;
527 int failed = 1;
528
529 if ((aint = ASN1_INTEGER_new()) == NULL) {
530 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
531 goto failed;
532 }
533
534 if (!ASN1_INTEGER_set_uint64(aint, 0)) {
535 fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
536 "0\n");
537 goto failed;
538 }
539 if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
540 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
541 "0\n");
542 goto failed;
543 }
544 if (uval != 0) {
545 fprintf(stderr, "FAIL: uval != 0\n");
546 goto failed;
547 }
548
549 if (!ASN1_INTEGER_set_uint64(aint, UINT64_MAX)) {
550 fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
551 "UINT64_MAX\n");
552 goto failed;
553 }
554 if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
555 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
556 "UINT64_MAX\n");
557 goto failed;
558 }
559 if (uval != UINT64_MAX) {
560 fprintf(stderr, "FAIL: uval != UINT64_MAX\n");
561 goto failed;
562 }
563 if (ASN1_INTEGER_get_int64(&val, aint)) {
564 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() succeeded "
565 "with UINT64_MAX\n");
566 goto failed;
567 }
568
569 if (!ASN1_INTEGER_set_int64(aint, INT64_MIN)) {
570 fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
571 "INT64_MIN\n");
572 goto failed;
573 }
574 if (!ASN1_INTEGER_get_int64(&val, aint)) {
575 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
576 "INT64_MIN\n");
577 goto failed;
578 }
579 if (val != INT64_MIN) {
580 fprintf(stderr, "FAIL: val != INT64_MIN\n");
581 goto failed;
582 }
583 if (ASN1_INTEGER_get_uint64(&uval, aint)) {
584 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() succeeded "
585 "with INT64_MIN\n");
586 goto failed;
587 }
588
589 if (!ASN1_INTEGER_set_int64(aint, INT64_MAX)) {
590 fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
591 "INT64_MAX\n");
592 goto failed;
593 }
594 if (!ASN1_INTEGER_get_int64(&val, aint)) {
595 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
596 "INT64_MAX\n");
597 goto failed;
598 }
599 if (val != INT64_MAX) {
600 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
601 "INT64_MAX\n");
602 goto failed;
603 }
604 if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
605 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
606 "INT64_MAX\n");
607 goto failed;
608 }
609 if (uval != INT64_MAX) {
610 fprintf(stderr, "FAIL: uval != INT64_MAX\n");
611 goto failed;
612 }
613
614 failed = 0;
615
616 failed:
617 ASN1_INTEGER_free(aint);
618
619 return failed;
620 }
621
622 static int
asn1_integer_cmp_test(void)623 asn1_integer_cmp_test(void)
624 {
625 ASN1_INTEGER *a = NULL, *b = NULL;
626 int failed = 1;
627
628 if ((a = ASN1_INTEGER_new()) == NULL)
629 goto failed;
630 if ((b = ASN1_INTEGER_new()) == NULL)
631 goto failed;
632
633 if (ASN1_INTEGER_cmp(a, b) != 0) {
634 fprintf(stderr, "FAIL: INTEGER 0 == 0");
635 goto failed;
636 }
637
638 if (!ASN1_INTEGER_set(b, 1)) {
639 fprintf(stderr, "FAIL: failed to set INTEGER");
640 goto failed;
641 }
642 if (ASN1_INTEGER_cmp(a, b) >= 0) {
643 fprintf(stderr, "FAIL: INTEGER 0 < 1");
644 goto failed;
645 }
646 if (ASN1_INTEGER_cmp(b, a) <= 0) {
647 fprintf(stderr, "FAIL: INTEGER 1 > 0");
648 goto failed;
649 }
650
651 if (!ASN1_INTEGER_set(b, -1)) {
652 fprintf(stderr, "FAIL: failed to set INTEGER");
653 goto failed;
654 }
655 if (ASN1_INTEGER_cmp(a, b) <= 0) {
656 fprintf(stderr, "FAIL: INTEGER 0 > -1");
657 goto failed;
658 }
659 if (ASN1_INTEGER_cmp(b, a) >= 0) {
660 fprintf(stderr, "FAIL: INTEGER -1 < 0");
661 goto failed;
662 }
663
664 if (!ASN1_INTEGER_set(a, 1)) {
665 fprintf(stderr, "FAIL: failed to set INTEGER");
666 goto failed;
667 }
668 if (ASN1_INTEGER_cmp(a, b) <= 0) {
669 fprintf(stderr, "FAIL: INTEGER 1 > -1");
670 goto failed;
671 }
672 if (ASN1_INTEGER_cmp(b, a) >= 0) {
673 fprintf(stderr, "FAIL: INTEGER -1 < 1");
674 goto failed;
675 }
676
677 if (!ASN1_INTEGER_set(b, 1)) {
678 fprintf(stderr, "FAIL: failed to set INTEGER");
679 goto failed;
680 }
681 if (ASN1_INTEGER_cmp(a, b) != 0) {
682 fprintf(stderr, "FAIL: INTEGER 1 == 1");
683 goto failed;
684 }
685
686 failed = 0;
687
688 failed:
689 ASN1_INTEGER_free(a);
690 ASN1_INTEGER_free(b);
691
692 return failed;
693 }
694
695 static int
asn1_integer_null_data_test(void)696 asn1_integer_null_data_test(void)
697 {
698 const uint8_t der[] = {0x02, 0x01, 0x00};
699 ASN1_INTEGER *aint = NULL;
700 uint8_t *p = NULL, *pp;
701 int len;
702 int failed = 1;
703
704 if ((aint = ASN1_INTEGER_new()) == NULL) {
705 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
706 goto failed;
707 }
708 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
709 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
710 goto failed;
711 }
712 if ((p = calloc(1, len)) == NULL)
713 errx(1, "calloc");
714 pp = p;
715 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
716 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
717 goto failed;
718 }
719 if (!asn1_compare_bytes("INTEGER NULL data", p, len, der, sizeof(der)))
720 goto failed;
721
722 failed = 0;
723
724 failed:
725 ASN1_INTEGER_free(aint);
726 free(p);
727
728 return failed;
729 }
730
731 static int
asn1_integer_test(void)732 asn1_integer_test(void)
733 {
734 struct asn1_integer_test *ait;
735 int failed = 0;
736 size_t i;
737
738 for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) {
739 ait = &asn1_integer_tests[i];
740 if (ait->content_len > 0 && ait->content_len <= 4)
741 failed |= asn1_integer_set_test(ait);
742 if (ait->content_len > 0)
743 failed |= asn1_integer_content_test(ait);
744 failed |= asn1_integer_decode_test(ait);
745 }
746
747 failed |= asn1_integer_cmp_test();
748 failed |= asn1_integer_null_data_test();
749 failed |= asn1_integer_set_val_test();
750
751 return failed;
752 }
753
754 static const struct asn1_string_new_test {
755 const char *name;
756 ASN1_STRING *(*new)(void);
757 void (*free)(ASN1_STRING *);
758 int type;
759 long flags;
760 } asn1_string_new_tests[] = {
761 {
762 .name = "ASN1_STRING",
763 .new = ASN1_STRING_new,
764 .free = ASN1_STRING_free,
765 .type = V_ASN1_OCTET_STRING,
766 },
767 {
768 .name = "ASN1_OCTET_STRING",
769 .new = ASN1_OCTET_STRING_new,
770 .free = ASN1_OCTET_STRING_free,
771 .type = V_ASN1_OCTET_STRING,
772 },
773 {
774 .name = "ASN1_BIT_STRING",
775 .new = ASN1_BIT_STRING_new,
776 .free = ASN1_BIT_STRING_free,
777 .type = V_ASN1_BIT_STRING,
778 },
779 {
780 .name = "ASN1_INTEGER",
781 .new = ASN1_INTEGER_new,
782 .free = ASN1_INTEGER_free,
783 .type = V_ASN1_INTEGER,
784 },
785 {
786 .name = "ASN1_ENUMERATED",
787 .new = ASN1_ENUMERATED_new,
788 .free = ASN1_ENUMERATED_free,
789 .type = V_ASN1_ENUMERATED,
790 },
791 {
792 .name = "ASN1_UTF8STRING",
793 .new = ASN1_UTF8STRING_new,
794 .free = ASN1_UTF8STRING_free,
795 .type = V_ASN1_UTF8STRING,
796 },
797 {
798 .name = "ASN1_IA5STRING",
799 .new = ASN1_IA5STRING_new,
800 .free = ASN1_IA5STRING_free,
801 .type = V_ASN1_IA5STRING,
802 },
803 {
804 .name = "ASN1_UNIVERSALSTRING",
805 .new = ASN1_UNIVERSALSTRING_new,
806 .free = ASN1_UNIVERSALSTRING_free,
807 .type = V_ASN1_UNIVERSALSTRING,
808 },
809 {
810 .name = "ASN1_BMPSTRING",
811 .new = ASN1_BMPSTRING_new,
812 .free = ASN1_BMPSTRING_free,
813 .type = V_ASN1_BMPSTRING,
814 },
815 {
816 .name = "ASN1_GENERALSTRING",
817 .new = ASN1_GENERALSTRING_new,
818 .free = ASN1_GENERALSTRING_free,
819 .type = V_ASN1_GENERALSTRING,
820 },
821 {
822 .name = "ASN1_T61STRING",
823 .new = ASN1_T61STRING_new,
824 .free = ASN1_T61STRING_free,
825 .type = V_ASN1_T61STRING,
826 },
827 {
828 .name = "ASN1_VISIBLESTRING",
829 .new = ASN1_VISIBLESTRING_new,
830 .free = ASN1_VISIBLESTRING_free,
831 .type = V_ASN1_VISIBLESTRING,
832 },
833 {
834 .name = "ASN1_PRINTABLESTRING",
835 .new = ASN1_PRINTABLESTRING_new,
836 .free = ASN1_PRINTABLESTRING_free,
837 .type = V_ASN1_PRINTABLESTRING,
838 },
839 {
840 .name = "ASN1_PRINTABLE",
841 .new = ASN1_PRINTABLE_new,
842 .free = ASN1_PRINTABLE_free,
843 .type = V_ASN1_UNDEF,
844 .flags = ASN1_STRING_FLAG_MSTRING,
845 },
846 {
847 .name = "DIRECTORYSTRING",
848 .new = DIRECTORYSTRING_new,
849 .free = DIRECTORYSTRING_free,
850 .type = V_ASN1_UNDEF,
851 .flags = ASN1_STRING_FLAG_MSTRING,
852 },
853 {
854 .name = "DISPLAYTEXT",
855 .new = DISPLAYTEXT_new,
856 .free = DISPLAYTEXT_free,
857 .type = V_ASN1_UNDEF,
858 .flags = ASN1_STRING_FLAG_MSTRING,
859 },
860 {
861 .name = "ASN1_GENERALIZEDTIME",
862 .new = ASN1_GENERALIZEDTIME_new,
863 .free = ASN1_GENERALIZEDTIME_free,
864 .type = V_ASN1_GENERALIZEDTIME,
865 },
866 {
867 .name = "ASN1_UTCTIME",
868 .new = ASN1_UTCTIME_new,
869 .free = ASN1_UTCTIME_free,
870 .type = V_ASN1_UTCTIME,
871 },
872 {
873 .name = "ASN1_TIME",
874 .new = ASN1_TIME_new,
875 .free = ASN1_TIME_free,
876 .type = V_ASN1_UNDEF,
877 .flags = ASN1_STRING_FLAG_MSTRING,
878 },
879 };
880
881 #define N_ASN1_STRING_NEW_TESTS \
882 (sizeof(asn1_string_new_tests) / sizeof(asn1_string_new_tests[0]))
883
884 static int
asn1_string_new_test(void)885 asn1_string_new_test(void)
886 {
887 size_t i;
888 ASN1_STRING *astr = NULL;
889 int failed = 1;
890
891 for (i = 0; i < N_ASN1_STRING_NEW_TESTS; i++) {
892 const struct asn1_string_new_test *asnt = &asn1_string_new_tests[i];
893
894 if ((astr = asnt->new()) == NULL) {
895 fprintf(stderr, "%s_new() failed\n", asnt->name);
896 goto err;
897 }
898 if (ASN1_STRING_type(astr) != asnt->type) {
899 fprintf(stderr, "%s type: want %d, got %d\n",
900 asnt->name, asnt->type, ASN1_STRING_type(astr));
901 goto err;
902 }
903 if (ASN1_STRING_data(astr) != NULL) {
904 fprintf(stderr, "%s data != NULL\n", asnt->name);
905 goto err;
906 }
907 if (ASN1_STRING_get0_data(astr) != NULL) {
908 fprintf(stderr, "%s data != NULL\n", asnt->name);
909 goto err;
910 }
911 if (ASN1_STRING_length(astr) != 0) {
912 fprintf(stderr, "%s length %d != 0\n", asnt->name,
913 ASN1_STRING_length(astr));
914 goto err;
915 }
916 ASN1_STRING_length_set(astr, 20);
917 if (ASN1_STRING_length(astr) != 20) {
918 fprintf(stderr, "%s length %d != 20\n", asnt->name,
919 ASN1_STRING_length(astr));
920 goto err;
921 }
922 astr->flags |= ASN1_STRING_FLAG_NDEF;
923 if (astr->flags != (asnt->flags | ASN1_STRING_FLAG_NDEF)) {
924 fprintf(stderr, "%s flags: %lx\n", asnt->name,
925 astr->flags);
926 goto err;
927 }
928 /* ASN1_STRING_set0() clears ASN1_STRING_FLAG_NDEF. */
929 ASN1_STRING_set0(astr, NULL, 0);
930 if (astr->flags != asnt->flags) {
931 fprintf(stderr, "%s flags: %lx != %lx\n", asnt->name,
932 astr->flags, asnt->flags);
933 goto err;
934 }
935 asnt->free(astr);
936 astr = NULL;
937
938 if ((astr = ASN1_STRING_type_new(asnt->type)) == NULL) {
939 fprintf(stderr, "ASN1_STRING_type_new(%s) failed\n",
940 asnt->name);
941 goto err;
942 }
943 if (ASN1_STRING_type(astr) != asnt->type) {
944 fprintf(stderr, "%s type: want %d, got %d\n",
945 asnt->name, asnt->type, ASN1_STRING_type(astr));
946 goto err;
947 }
948 if (ASN1_STRING_data(astr) != NULL) {
949 fprintf(stderr, "%s data != NULL\n", asnt->name);
950 goto err;
951 }
952 /* ASN1_STRING_type_new() does not set flags. */
953 if (astr->flags != 0) {
954 fprintf(stderr, "%s flags %lx\n", asnt->name,
955 astr->flags);
956 goto err;
957 }
958 asnt->free(astr);
959 astr = NULL;
960
961 }
962
963 failed = 0;
964
965 err:
966 ASN1_STRING_free(astr);
967
968 return failed;
969 }
970
971 static char *comparison_str = "mystring";
972
973 static int
asn1_string_cmp_test(void)974 asn1_string_cmp_test(void)
975 {
976 ASN1_STRING *a = NULL, *b = NULL;
977 int got, want;
978 int failed = 1;
979
980 if ((got = ASN1_STRING_cmp(NULL, NULL)) != -1) {
981 fprintf(stderr, "ASN1_STRING_cmp(NULL, NULL): %d != -1\n", got);
982 goto err;
983 }
984
985 if ((a = ASN1_STRING_new()) == NULL) {
986 fprintf(stderr, "a = ASN1_STRING_new() failed\n");
987 goto err;
988 }
989 if ((b = ASN1_STRING_type_new(V_ASN1_UTF8STRING)) == NULL) {
990 fprintf(stderr, "b = ASN1_STRING_type_new() failed\n");
991 goto err;
992 }
993
994 if ((got = ASN1_STRING_cmp(a, NULL)) != -1) {
995 fprintf(stderr, "ASN1_STRING_cmp(a, NULL): %d != -1\n", got);
996 goto err;
997 }
998 if ((got = ASN1_STRING_cmp(NULL, a)) != -1) {
999 fprintf(stderr, "ASN1_STRING_cmp(NULL, a): %d != -1\n", got);
1000 goto err;
1001 }
1002
1003 if (ASN1_STRING_cmp(a, b) >= 0) {
1004 fprintf(stderr, "V_ASN1_OCTET_STRING >= V_ASN1_UTF8STRING\n");
1005 goto err;
1006 }
1007 want = V_ASN1_UTF8STRING - V_ASN1_OCTET_STRING;
1008 if ((got = ASN1_STRING_cmp(b, a)) != want) {
1009 fprintf(stderr, "comparison of octet with utf8 string:"
1010 "want %d, got %d\n", want, got);
1011 goto err;
1012 }
1013
1014 ASN1_STRING_set0(a, comparison_str, strlen(comparison_str));
1015 ASN1_STRING_set0(b, comparison_str, strlen(comparison_str));
1016
1017 /* Ensure any data set on a or b isn't freed/zeroed. */
1018 a->flags |= ASN1_STRING_FLAG_NDEF;
1019 b->flags |= ASN1_STRING_FLAG_NDEF;
1020
1021 if ((got = ASN1_STRING_cmp(b, a)) != want) {
1022 fprintf(stderr, "comparison of octet with utf8 string:"
1023 "want %d, got %d\n", want, got);
1024 goto err;
1025 }
1026
1027 b->type = V_ASN1_OCTET_STRING;
1028
1029 if ((got = ASN1_STRING_cmp(a, b)) != 0) {
1030 fprintf(stderr, "same string on both. want 0, got %d\n", got);
1031 goto err;
1032 }
1033
1034 if (!ASN1_STRING_set(b, "myString", -1)) {
1035 fprintf(stderr, "ASN1_STRING_set(b) failed\n");
1036 goto err;
1037 }
1038
1039 if ((got = ASN1_STRING_cmp(a, b)) <= 0) {
1040 fprintf(stderr, "capitalized letter compares larger: got %d\n",
1041 got);
1042 goto err;
1043 }
1044 if ((got = ASN1_STRING_cmp(b, a)) >= 0) {
1045 fprintf(stderr, "capitalized letter is larger 2: %d\n", got);
1046 goto err;
1047 }
1048
1049 ASN1_STRING_length_set(b, 2);
1050
1051 want = strlen(comparison_str) - 2;
1052
1053 if ((got = ASN1_STRING_cmp(a, b)) != want) {
1054 fprintf(stderr, "comparison of a with truncated b: "
1055 "want %d, got %d\n", want, got);
1056 goto err;
1057 }
1058
1059 want = -want;
1060
1061 if ((got = ASN1_STRING_cmp(b, a)) != want) {
1062 fprintf(stderr, "comparison of truncated b with a: "
1063 "want %d, got %d\n", want, got);
1064 goto err;
1065 }
1066
1067 ASN1_STRING_length_set(a, 2);
1068
1069 if ((got = ASN1_STRING_cmp(a, b)) != 0) {
1070 fprintf(stderr, "both truncated compared to %d\n", got);
1071 goto err;
1072 }
1073
1074 ASN1_STRING_length_set(a, strlen(comparison_str));
1075
1076 ASN1_STRING_set0(b, NULL, 0);
1077
1078 want = strlen(comparison_str);
1079 if ((got = ASN1_STRING_cmp(a, b)) != want) {
1080 fprintf(stderr, "comparison of a with zeroed b: "
1081 "want %d, got %d\n", want, got);
1082 goto err;
1083 }
1084
1085 ASN1_STRING_set0(b, "", 0);
1086 b->flags |= ASN1_STRING_FLAG_NDEF;
1087
1088 if ((got = ASN1_STRING_cmp(a, b)) != want) {
1089 fprintf(stderr, "comparison of a with zero-length b: "
1090 "want %d, got %d\n", want, got);
1091 goto err;
1092 }
1093
1094 ASN1_STRING_set0(a, NULL, 0);
1095 if ((got = ASN1_STRING_cmp(a, b)) != 0) {
1096 fprintf(stderr, "comparison of zeroed a with zero-length b: "
1097 "want 0, got %d\n", got);
1098 goto err;
1099 }
1100 if ((got = ASN1_STRING_cmp(b, a)) != 0) {
1101 fprintf(stderr, "comparison of zero-length b with zeroed a: "
1102 "want 0, got %d\n", got);
1103 goto err;
1104 }
1105
1106 failed = 0;
1107
1108 err:
1109 ASN1_STRING_free(a);
1110 ASN1_STRING_free(b);
1111
1112 return failed;
1113 }
1114
1115 static int
asn1_string_test(void)1116 asn1_string_test(void)
1117 {
1118 int failed = 0;
1119
1120 failed |= asn1_string_new_test();
1121 failed |= asn1_string_cmp_test();
1122
1123 return failed;
1124 }
1125
1126 int
main(int argc,char ** argv)1127 main(int argc, char **argv)
1128 {
1129 int failed = 0;
1130
1131 failed |= asn1_bit_string_test();
1132 failed |= asn1_boolean_test();
1133 failed |= asn1_integer_test();
1134 failed |= asn1_string_test();
1135
1136 return (failed);
1137 }
1138