1 /* $OpenBSD: rfc3779.c,v 1.10 2023/12/13 07:19:37 tb Exp $ */
2 /*
3 * Copyright (c) 2021 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 <stdio.h>
19 #include <string.h>
20
21 #include <openssl/asn1.h>
22 #include <openssl/asn1t.h>
23 #include <openssl/x509v3.h>
24
25 #define RAW_ADDRESS_SIZE 16
26
27 static void
hexdump(const unsigned char * buf,size_t len)28 hexdump(const unsigned char *buf, size_t len)
29 {
30 size_t i;
31
32 for (i = 1; i <= len; i++)
33 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
34
35 if (len % 8)
36 fprintf(stderr, "\n");
37 }
38
39 static void
report_hexdump(const char * func,const char * description,const char * msg,const unsigned char * want,size_t want_len,const unsigned char * got,size_t got_len)40 report_hexdump(const char *func, const char *description, const char *msg,
41 const unsigned char *want, size_t want_len,
42 const unsigned char *got, size_t got_len)
43 {
44 fprintf(stderr, "%s: \"%s\" %s\nwant:\n", func, description, msg);
45 hexdump(want, want_len);
46 fprintf(stderr, "got:\n");
47 hexdump(got, got_len);
48 }
49
50 static int
afi_size(int afi)51 afi_size(int afi)
52 {
53 switch (afi) {
54 case IANA_AFI_IPV4:
55 return 4;
56 case IANA_AFI_IPV6:
57 return 16;
58 }
59 return 0;
60 }
61
62 struct IPAddressOrRange_test {
63 const char *description;
64 const uint8_t der[32];
65 size_t der_len;
66 unsigned afi;
67 const uint8_t min[RAW_ADDRESS_SIZE];
68 const uint8_t max[RAW_ADDRESS_SIZE];
69 };
70
71 const struct IPAddressOrRange_test IPAddressOrRange_test_data[] = {
72 /* Examples from RFC 3779, section 2.1.1 */
73 {
74 .description = "address 10.5.0.4",
75 .der = {
76 0x03, 0x05, 0x00, 0x0a, 0x05, 0x00, 0x04,
77 },
78 .der_len = 7,
79 .afi = IANA_AFI_IPV4,
80 .min = {
81 0x0a, 0x05, 0x00, 0x04,
82 },
83 .max = {
84 0x0a, 0x05, 0x00, 0x04,
85 }
86 },
87 {
88 .description = "prefix 10.5.0/23",
89 .der = {
90 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00,
91 },
92 .der_len = 6,
93 .afi = IANA_AFI_IPV4,
94 .min = {
95 0x0a, 0x05, 0x00, 0x00,
96 },
97 .max = {
98 0x0a, 0x05, 0x01, 0xff,
99 }
100 },
101 {
102 .description = "address 2001:0:200:3::1",
103 .der = {
104 0x03, 0x11, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02,
105 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x01,
107 },
108 .der_len = 19,
109 .afi = IANA_AFI_IPV6,
110 .min = {
111 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
113 },
114 .max = {
115 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
117 },
118 },
119 {
120 .description = "prefix 2001:0:200/39",
121 .der = {
122 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02,
123 },
124 .der_len = 8,
125 .afi = IANA_AFI_IPV6,
126 .min = {
127 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 },
130 .max = {
131 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
133 },
134 },
135
136 /* Examples from RFC 3779, Section 2.1.2 */
137 {
138 .description = "prefix 10.5.0/23 as a range",
139 .der = {
140 /* Sequence */
141 0x30, 0x0b,
142 /* 10.5.0.0 */
143 0x03, 0x03, 0x00, 0x0a, 0x05,
144 /* 10.5.1.255 */
145 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00,
146 },
147 .der_len = 13,
148 .afi = IANA_AFI_IPV4,
149 .min = {
150 0x0a, 0x05, 0x00, 0x00,
151 },
152 .max = {
153 0x0a, 0x05, 0x01, 0xff,
154 }
155 },
156 {
157 .description = "prefix 2001:0:200/39 as a range",
158 .der = {
159 /* Sequence */
160 0x30, 0x10,
161 /* 2001:0:200:: */
162 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02,
163 /* 2001:0:3ff:ffff:ffff:ffff:ffff:ffff */
164 0x03, 0x06, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00,
165 },
166 .der_len = 18,
167 .afi = IANA_AFI_IPV6,
168 .min = {
169 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 },
172 .max = {
173 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
174 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
175 }
176 },
177 {
178 .description = "prefix 0/0",
179 .der = {
180 0x03, 0x01, 0x00,
181 },
182 .der_len = 3,
183 .afi = IANA_AFI_IPV4,
184 .min = {
185 0x00, 0x00, 0x00, 0x00,
186 },
187 .max = {
188 0xff, 0xff, 0xff, 0xff,
189 }
190 },
191 {
192 .description = "prefix 10.64/12",
193 .der = {
194 0x03, 0x03, 0x04, 0x0a, 0x40,
195 },
196 .der_len = 5,
197 .afi = IANA_AFI_IPV4,
198 .min = {
199 0x0a, 0x40, 0x00, 0x00,
200 },
201 .max = {
202 0x0a, 0x4f, 0xff, 0xff,
203 },
204 },
205 {
206 .description = "prefix 10.64/20",
207 .der = {
208 0x03, 0x04, 0x04, 0x0a, 0x40, 0x00,
209 },
210 .der_len = 6,
211 .afi = IANA_AFI_IPV4,
212 .min = {
213 0x0a, 0x40, 0x00, 0x00,
214 },
215 .max = {
216 0x0a, 0x40, 0x0f, 0xff,
217 },
218 },
219 };
220
221 const size_t N_IPADDRESSORRANGE_TESTS =
222 sizeof(IPAddressOrRange_test_data) / sizeof(IPAddressOrRange_test_data[0]);
223
224 static int
test_IPAddressOrRange(const struct IPAddressOrRange_test * test)225 test_IPAddressOrRange(const struct IPAddressOrRange_test *test)
226 {
227 IPAddressOrRange *aor;
228 const unsigned char *p;
229 unsigned char min[RAW_ADDRESS_SIZE] = {0}, max[RAW_ADDRESS_SIZE] = {0};
230 unsigned char *out = NULL;
231 int out_len;
232 int afi_len;
233 int memcmp_failed = 0;
234 int failed = 1;
235
236 /*
237 * First, decode DER from the test case.
238 */
239
240 p = &test->der[0];
241 if ((aor = d2i_IPAddressOrRange(NULL, &p, test->der_len)) == NULL) {
242 fprintf(stderr, "%s: \"%s\" d2i_IPAddressOrRange failed\n",
243 __func__, test->description);
244 goto err;
245 }
246
247 /*
248 * Now extract minimum and maximum from the parsed range.
249 */
250
251 afi_len = afi_size(test->afi);
252
253 if (X509v3_addr_get_range(aor, test->afi, min, max, sizeof min) !=
254 afi_len) {
255 fprintf(stderr, "%s: \"%s\" X509v3_addr_get_range failed\n",
256 __func__, test->description);
257 goto err;
258 }
259
260 /*
261 * Check that min and max match expectations.
262 */
263
264 if (memcmp(min, test->min, afi_len) != 0) {
265 memcmp_failed |= 1;
266 report_hexdump(__func__, test->description, "memcmp min failed",
267 test->min, afi_len, min, afi_len);
268 }
269 if (memcmp(max, test->max, afi_len) != 0) {
270 memcmp_failed |= 1;
271 report_hexdump(__func__, test->description, "memcmp max failed",
272 test->max, afi_len, max, afi_len);
273 }
274 if (memcmp_failed)
275 goto err;
276
277 /*
278 * Now turn the parsed IPAddressOrRange back into DER and check that
279 * it matches the DER in the test case.
280 */
281
282 out = NULL;
283 if ((out_len = i2d_IPAddressOrRange(aor, &out)) <= 0) {
284 fprintf(stderr, "%s: \"%s\" i2d_IPAddressOrRange failed\n",
285 __func__, test->description);
286 goto err;
287 }
288
289 memcmp_failed = (size_t)out_len != test->der_len;
290 if (!memcmp_failed)
291 memcmp_failed = memcmp(test->der, out, out_len);
292
293 if (memcmp_failed) {
294 report_hexdump(__func__, test->description, "memcmp DER failed",
295 test->der, test->der_len, out, out_len);
296 goto err;
297 }
298
299 failed = 0;
300 err:
301 IPAddressOrRange_free(aor);
302 free(out);
303
304 return failed;
305 }
306
307 static int
run_IPAddressOrRange_tests(void)308 run_IPAddressOrRange_tests(void)
309 {
310 size_t i;
311 int failed = 0;
312
313 for (i = 0; i < N_IPADDRESSORRANGE_TESTS; i++)
314 failed |=
315 test_IPAddressOrRange(&IPAddressOrRange_test_data[i]);
316
317 return failed;
318 }
319
320 /*
321 * XXX: These should really be part of the public API...
322 */
323 static IPAddrBlocks *IPAddrBlocks_new(void);
324 static void IPAddrBlocks_free(IPAddrBlocks *addr);
325 static IPAddrBlocks *d2i_IPAddrBlocks(IPAddrBlocks **addrs,
326 const unsigned char **in, long len);
327 static int i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out);
328
329 static IPAddrBlocks *
IPAddrBlocks_new(void)330 IPAddrBlocks_new(void)
331 {
332 IPAddrBlocks *addrs;
333
334 /*
335 * XXX The comparison function IPAddressFamily_cmp() isn't public.
336 * Start with the default and exploit a side effect of the lovely API
337 * which helpfully sets the correct function in a few places. Let's
338 * use the cheapest and easiest to reach one.
339 */
340 if ((addrs = sk_IPAddressFamily_new_null()) == NULL)
341 return NULL;
342 if (!X509v3_addr_canonize(addrs)) {
343 IPAddrBlocks_free(addrs);
344 return NULL;
345 }
346
347 return addrs;
348 }
349
350 static void
IPAddrBlocks_free(IPAddrBlocks * addr)351 IPAddrBlocks_free(IPAddrBlocks *addr)
352 {
353 sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
354 }
355
356 /*
357 * We want {d2i,i2d}_IPAddrBlocks() to play with the DER of the extension.
358 * These don't exist, so we have to implement them ourselves. IPAddrBlocks_it
359 * isn't public, so we need to fetch it from the library. We cache it in a
360 * static variable to avoid the cost of a binary search through all supported
361 * extensions on each call.
362 */
363
364 static ASN1_ITEM_EXP *
get_IPAddrBlocks_it(void)365 get_IPAddrBlocks_it(void)
366 {
367 static ASN1_ITEM_EXP *my_IPAddrBlocks_it;
368 const X509V3_EXT_METHOD *v3_addr;
369
370 if (my_IPAddrBlocks_it != NULL)
371 return my_IPAddrBlocks_it;
372
373 if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) {
374 fprintf(stderr, "could not get v3_addr\n");
375 return NULL;
376 }
377
378 my_IPAddrBlocks_it = v3_addr->it;
379
380 return my_IPAddrBlocks_it;
381 }
382
383 static IPAddrBlocks *
d2i_IPAddrBlocks(IPAddrBlocks ** addrs,const unsigned char ** in,long len)384 d2i_IPAddrBlocks(IPAddrBlocks **addrs, const unsigned char **in, long len)
385 {
386 ASN1_ITEM_EXP *my_IPAddrBlocks_it;
387
388 if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL)
389 return NULL;
390
391 return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrs, in, len,
392 my_IPAddrBlocks_it);
393 }
394
395 static int
i2d_IPAddrBlocks(IPAddrBlocks * addrs,unsigned char ** out)396 i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out)
397 {
398 ASN1_ITEM_EXP *my_IPAddrBlocks_it;
399
400 if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL)
401 return -1;
402
403 return ASN1_item_i2d((ASN1_VALUE *)addrs, out, my_IPAddrBlocks_it);
404 }
405
406 struct ipv4_prefix {
407 unsigned char addr[4];
408 size_t addr_len;
409 size_t prefix_len;
410 };
411
412 struct ipv4_range {
413 unsigned char min[4];
414 unsigned char max[4];
415 };
416
417 union ipv4_choice {
418 struct ipv4_prefix prefix;
419 struct ipv4_range range;
420 };
421
422 struct ipv6_prefix {
423 unsigned char addr[16];
424 size_t addr_len;
425 size_t prefix_len;
426 };
427
428 struct ipv6_range {
429 unsigned char min[16];
430 unsigned char max[16];
431 };
432
433 union ipv6_choice {
434 struct ipv6_prefix prefix;
435 struct ipv6_range range;
436 };
437
438 enum choice_type {
439 choice_prefix,
440 choice_range,
441 choice_inherit,
442 choice_last,
443 };
444
445 union ip {
446 union ipv4_choice ipv4;
447 union ipv6_choice ipv6;
448 };
449
450 enum safi {
451 safi_none,
452 safi_unicast,
453 safi_multicast,
454 };
455
456 struct ip_addr_block {
457 unsigned int afi;
458 enum safi safi;
459 enum choice_type type;
460 union ip addr;
461 };
462
463 struct build_addr_block_test_data {
464 char *description;
465 struct ip_addr_block addrs[16];
466 char der[128];
467 size_t der_len;
468 int is_canonical;
469 int inherits;
470 unsigned int afis[4];
471 int afi_len;
472 };
473
474 const struct build_addr_block_test_data build_addr_block_tests[] = {
475 {
476 .description = "RFC 3779, Appendix B, example 1",
477 .addrs = {
478 {
479 .afi = IANA_AFI_IPV4,
480 .safi = safi_unicast,
481 .type = choice_prefix,
482 .addr.ipv4.prefix = {
483 .addr = {
484 10, 0, 32,
485 },
486 .addr_len = 3,
487 .prefix_len = 20,
488 },
489 },
490 {
491 .afi = IANA_AFI_IPV4,
492 .safi = safi_unicast,
493 .type = choice_prefix,
494 .addr.ipv4.prefix = {
495 .addr = {
496 10, 0, 64,
497 },
498 .addr_len = 3,
499 .prefix_len = 24,
500 },
501 },
502 {
503 .afi = IANA_AFI_IPV4,
504 .safi = safi_unicast,
505 .type = choice_prefix,
506 .addr.ipv4.prefix = {
507 .addr = {
508 10, 1,
509 },
510 .addr_len = 2,
511 .prefix_len = 16,
512 },
513 },
514 {
515 .afi = IANA_AFI_IPV4,
516 .safi = safi_unicast,
517 .type = choice_prefix,
518 .addr.ipv4.prefix = {
519 .addr = {
520 10, 2, 48,
521 },
522 .addr_len = 3,
523 .prefix_len = 20,
524 },
525 },
526 {
527 .afi = IANA_AFI_IPV4,
528 .safi = safi_unicast,
529 .type = choice_prefix,
530 .addr.ipv4.prefix = {
531 .addr = {
532 10, 2, 64,
533 },
534 .addr_len = 3,
535 .prefix_len = 24,
536 },
537 },
538 {
539 .afi = IANA_AFI_IPV4,
540 .safi = safi_unicast,
541 .type = choice_prefix,
542 .addr.ipv4.prefix = {
543 .addr = {
544 10, 3,
545 },
546 .addr_len = 2,
547 .prefix_len = 16,
548 },
549 },
550 {
551 .afi = IANA_AFI_IPV6,
552 .safi = safi_none,
553 .type = choice_inherit,
554 },
555 {
556 .type = choice_last,
557 },
558 },
559 .der = {
560 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01,
561 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00,
562 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03,
563 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04,
564 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a,
565 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30,
566 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00,
567 },
568 .der_len = 55,
569 .is_canonical = 0,
570 .inherits = 1,
571 .afis = {
572 IANA_AFI_IPV4, IANA_AFI_IPV6,
573 },
574 .afi_len = 2,
575 },
576 {
577 .description = "RFC 3779, Appendix B, example 1 canonical",
578 .addrs = {
579 {
580 .afi = IANA_AFI_IPV4,
581 .safi = safi_unicast,
582 .type = choice_prefix,
583 .addr.ipv4.prefix = {
584 .addr = {
585 10, 0, 32,
586 },
587 .addr_len = 3,
588 .prefix_len = 20,
589 },
590 },
591 {
592 .afi = IANA_AFI_IPV4,
593 .safi = safi_unicast,
594 .type = choice_prefix,
595 .addr.ipv4.prefix = {
596 .addr = {
597 10, 0, 64,
598 },
599 .addr_len = 3,
600 .prefix_len = 24,
601 },
602 },
603 {
604 .afi = IANA_AFI_IPV4,
605 .safi = safi_unicast,
606 .type = choice_prefix,
607 .addr.ipv4.prefix = {
608 .addr = {
609 10, 1,
610 },
611 .addr_len = 2,
612 .prefix_len = 16,
613 },
614 },
615 {
616 .afi = IANA_AFI_IPV4,
617 .safi = safi_unicast,
618 .type = choice_range,
619 .addr.ipv4.range = {
620 .min = {
621 10, 2, 48, 00,
622 },
623 .max = {
624 10, 2, 64, 255,
625 },
626 },
627 },
628 {
629 .afi = IANA_AFI_IPV4,
630 .safi = safi_unicast,
631 .type = choice_prefix,
632 .addr.ipv4.prefix = {
633 .addr = {
634 10, 3,
635 },
636 .addr_len = 2,
637 .prefix_len = 16,
638 },
639 },
640 {
641 .afi = IANA_AFI_IPV6,
642 .safi = safi_none,
643 .type = choice_inherit,
644 },
645 {
646 .type = choice_last,
647 },
648 },
649 .der = {
650 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01,
651 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00,
652 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03,
653 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04,
654 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a,
655 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30,
656 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00,
657 },
658 .der_len = 55,
659 .is_canonical = 1,
660 .inherits = 1,
661 .afis = {
662 IANA_AFI_IPV4, IANA_AFI_IPV6,
663 },
664 .afi_len = 2,
665 },
666 {
667 .description = "RFC 3779, Appendix B, example 2",
668 .addrs = {
669 {
670 .afi = IANA_AFI_IPV6,
671 .safi = safi_none,
672 .type = choice_prefix,
673 .addr.ipv6.prefix = {
674 .addr = {
675 0x20, 0x01, 0x00, 0x00,
676 0x00, 0x02,
677 },
678 .addr_len = 6,
679 .prefix_len = 48,
680 },
681 },
682 {
683 .afi = IANA_AFI_IPV4,
684 .safi = safi_unicast,
685 .type = choice_prefix,
686 .addr.ipv4.prefix = {
687 .addr = {
688 10,
689 },
690 .addr_len = 1,
691 .prefix_len = 8,
692 },
693 },
694 {
695 .afi = IANA_AFI_IPV4,
696 .safi = safi_unicast,
697 .type = choice_prefix,
698 .addr.ipv4.prefix = {
699 .addr = {
700 172, 16,
701 },
702 .addr_len = 2,
703 .prefix_len = 12,
704 },
705 },
706 {
707 .afi = IANA_AFI_IPV4,
708 .safi = safi_multicast,
709 .type = choice_inherit,
710 },
711 {
712 .type = choice_last,
713 },
714 },
715 .der = {
716 0x30, 0x2c, 0x30, 0x10, 0x04, 0x03, 0x00, 0x01,
717 0x01, 0x30, 0x09, 0x03, 0x02, 0x00, 0x0a, 0x03,
718 0x03, 0x04, 0xac, 0x10, 0x30, 0x07, 0x04, 0x03,
719 0x00, 0x01, 0x02, 0x05, 0x00, 0x30, 0x0f, 0x04,
720 0x02, 0x00, 0x02, 0x30, 0x09, 0x03, 0x07, 0x00,
721 0x20, 0x01, 0x00, 0x00, 0x00, 0x02,
722 },
723 .der_len = 46,
724 .is_canonical = 0,
725 .inherits = 1,
726 .afis = {
727 IANA_AFI_IPV4, IANA_AFI_IPV4,
728 },
729 .afi_len = 2,
730 },
731 {
732 .description = "Range should be prefix 127/8",
733 .addrs = {
734 {
735 .afi = IANA_AFI_IPV4,
736 .safi = safi_none,
737 .type = choice_range,
738 .addr.ipv4.range = {
739 .min = {
740 127, 0, 0, 0,
741 },
742 .max = {
743 127, 255, 255, 255,
744 },
745 },
746 },
747 {
748 .type = choice_last,
749 },
750 },
751 .der = {
752 0x30, 0x0c, 0x30, 0x0a, 0x04, 0x02, 0x00, 0x01,
753 0x30, 0x04, 0x03, 0x02, 0x00, 0x7f,
754 },
755 .der_len = 14,
756 .is_canonical = 1,
757 .inherits = 0,
758 .afis = {
759 IANA_AFI_IPV4,
760 },
761 .afi_len = 1,
762 },
763 };
764
765 const size_t N_BUILD_ADDR_BLOCK_TESTS =
766 sizeof(build_addr_block_tests) / sizeof(build_addr_block_tests[0]);
767
768 static unsigned int *
addr_block_get_safi(const struct ip_addr_block * addr)769 addr_block_get_safi(const struct ip_addr_block *addr)
770 {
771 static unsigned int safi;
772
773 switch (addr->safi) {
774 case safi_none:
775 return NULL;
776 case safi_unicast:
777 safi = 1;
778 break;
779 case safi_multicast:
780 safi = 2;
781 break;
782 }
783
784 return &safi;
785 }
786
787 static int
addr_block_add_ipv4_addr(IPAddrBlocks * block,enum choice_type type,const union ipv4_choice * ipv4,unsigned int * safi)788 addr_block_add_ipv4_addr(IPAddrBlocks *block, enum choice_type type,
789 const union ipv4_choice *ipv4, unsigned int *safi)
790 {
791 unsigned char addr[RAW_ADDRESS_SIZE] = {0};
792 unsigned char min[RAW_ADDRESS_SIZE];
793 unsigned char max[RAW_ADDRESS_SIZE];
794
795 switch (type) {
796 case choice_prefix:
797 memcpy(addr, ipv4->prefix.addr, ipv4->prefix.addr_len);
798 return X509v3_addr_add_prefix(block, IANA_AFI_IPV4, safi,
799 addr, ipv4->prefix.prefix_len);
800 case choice_range:
801 memcpy(min, ipv4->range.min, sizeof(ipv4->range.min));
802 memcpy(max, ipv4->range.max, sizeof(ipv4->range.max));
803 return X509v3_addr_add_range(block, IANA_AFI_IPV4, safi,
804 min, max);
805 case choice_inherit:
806 return X509v3_addr_add_inherit(block, IANA_AFI_IPV4, safi);
807 case choice_last:
808 default:
809 return 0;
810 }
811 }
812
813 static int
addr_block_add_ipv6_addr(IPAddrBlocks * block,enum choice_type type,const union ipv6_choice * ipv6,unsigned int * safi)814 addr_block_add_ipv6_addr(IPAddrBlocks *block, enum choice_type type,
815 const union ipv6_choice *ipv6, unsigned int *safi)
816 {
817 unsigned char addr[RAW_ADDRESS_SIZE] = {0};
818 unsigned char min[RAW_ADDRESS_SIZE];
819 unsigned char max[RAW_ADDRESS_SIZE];
820
821 switch (type) {
822 case choice_prefix:
823 memcpy(addr, ipv6->prefix.addr, ipv6->prefix.addr_len);
824 return X509v3_addr_add_prefix(block, IANA_AFI_IPV6, safi,
825 addr, ipv6->prefix.prefix_len);
826 case choice_range:
827 memcpy(min, ipv6->range.min, sizeof(ipv6->range.min));
828 memcpy(max, ipv6->range.max, sizeof(ipv6->range.max));
829 return X509v3_addr_add_range(block, IANA_AFI_IPV6, safi,
830 min, max);
831 case choice_inherit:
832 return X509v3_addr_add_inherit(block, IANA_AFI_IPV6, safi);
833 case choice_last:
834 default:
835 return 0;
836 }
837 }
838
839 static int
addr_block_add_addrs(IPAddrBlocks * block,const struct ip_addr_block addrs[])840 addr_block_add_addrs(IPAddrBlocks *block, const struct ip_addr_block addrs[])
841 {
842 const struct ip_addr_block *addr;
843 unsigned int *safi;
844
845 for (addr = &addrs[0]; addr->type != choice_last; addr++) {
846 safi = addr_block_get_safi(addr);
847 switch (addr->afi) {
848 case IANA_AFI_IPV4:
849 if (!addr_block_add_ipv4_addr(block, addr->type,
850 &addr->addr.ipv4, safi))
851 return 0;
852 break;
853 case IANA_AFI_IPV6:
854 if (!addr_block_add_ipv6_addr(block, addr->type,
855 &addr->addr.ipv6, safi))
856 return 0;
857 break;
858 default:
859 fprintf(stderr, "%s: corrupt test data", __func__);
860 exit(1);
861 }
862 }
863
864 return 1;
865 }
866
867 static int
build_addr_block_test(const struct build_addr_block_test_data * test)868 build_addr_block_test(const struct build_addr_block_test_data *test)
869 {
870 IPAddrBlocks *addrs = NULL, *parsed = NULL;
871 const unsigned char *p;
872 unsigned char *out = NULL;
873 int out_len;
874 int i;
875 int memcmp_failed = 1;
876 int failed = 1;
877
878 if ((addrs = IPAddrBlocks_new()) == NULL)
879 goto err;
880
881 if (!addr_block_add_addrs(addrs, test->addrs))
882 goto err;
883
884 if (X509v3_addr_is_canonical(addrs) != test->is_canonical) {
885 fprintf(stderr, "%s: \"%s\" X509v3_addr_is_canonical not %d\n",
886 __func__, test->description, test->is_canonical);
887 goto err;
888 }
889
890 if (!X509v3_addr_canonize(addrs)) {
891 fprintf(stderr, "%s: \"%s\" failed to canonize\n",
892 __func__, test->description);
893 goto err;
894 }
895
896 if (!X509v3_addr_is_canonical(addrs)) {
897 fprintf(stderr, "%s: \"%s\" canonization wasn't canonical\n",
898 __func__, test->description);
899 goto err;
900 }
901
902 if ((out_len = i2d_IPAddrBlocks(addrs, &out)) <= 0) {
903 fprintf(stderr, "%s: \"%s\" i2d_IPAddrBlocks failed\n",
904 __func__, test->description);
905 goto err;
906 }
907
908 memcmp_failed = (size_t)out_len != test->der_len;
909 if (!memcmp_failed)
910 memcmp_failed = memcmp(out, test->der, test->der_len);
911 if (memcmp_failed) {
912 report_hexdump(__func__, test->description, "memcmp DER failed",
913 test->der, test->der_len, out, out_len);
914 goto err;
915 }
916
917 if (X509v3_addr_inherits(addrs) != test->inherits) {
918 fprintf(stderr, "%s: \"%s\" X509v3_addr_inherits not %d\n",
919 __func__, test->description, test->inherits);
920 goto err;
921 }
922
923 for (i = 0; i < sk_IPAddressFamily_num(addrs) && i < test->afi_len; i++) {
924 IPAddressFamily *family;
925 unsigned int afi;
926
927 family = sk_IPAddressFamily_value(addrs, i);
928
929 if ((afi = X509v3_addr_get_afi(family)) == 0) {
930 fprintf(stderr, "%s: \"%s\" X509v3_addr_get_afi"
931 " failed\n", __func__, test->description);
932 goto err;
933 }
934 if (test->afis[i] != afi){
935 fprintf(stderr, "%s: \"%s\" afi[%d] mismatch. "
936 "want: %u, got: %u\n", __func__,
937 test->description, i, test->afis[i], afi);
938 goto err;
939 }
940 }
941 if (i != test->afi_len) {
942 fprintf(stderr, "%s: \"%s\" checked %d afis, expected %d\n",
943 __func__, test->description, i, test->afi_len);
944 goto err;
945 }
946
947 p = test->der;
948 if ((parsed = d2i_IPAddrBlocks(NULL, &p, test->der_len)) == NULL) {
949 fprintf(stderr, "%s: \"%s\" d2i_IPAddrBlocks failed\n",
950 __func__, test->description);
951 goto err;
952 }
953 if (!X509v3_addr_is_canonical(parsed)) {
954 fprintf(stderr, "%s: \"%s\" parsed AddrBlocks isn't canonical\n",
955 __func__, test->description);
956 goto err;
957 }
958 /* Can't compare IPAddrBlocks with inheritance. */
959 if (!X509v3_addr_inherits(addrs) && !X509v3_addr_inherits(parsed)) {
960 if (!X509v3_addr_subset(addrs, parsed)) {
961 fprintf(stderr, "%s: \"%s\" addrs not subset of parsed\n",
962 __func__, test->description);
963 }
964 if (!X509v3_addr_subset(parsed, addrs)) {
965 fprintf(stderr, "%s: \"%s\" parsed not subset of addrs\n",
966 __func__, test->description);
967 }
968 }
969
970 failed = 0;
971
972 err:
973 IPAddrBlocks_free(addrs);
974 IPAddrBlocks_free(parsed);
975 free(out);
976
977 return failed;
978 }
979
980 static int
run_IPAddrBlock_tests(void)981 run_IPAddrBlock_tests(void)
982 {
983 size_t i;
984 int failed = 0;
985
986 for (i = 0; i < N_BUILD_ADDR_BLOCK_TESTS; i++)
987 failed |= build_addr_block_test(&build_addr_block_tests[i]);
988
989 return failed;
990 }
991
992 struct asid_or_range {
993 int type;
994 int inherit;
995 const unsigned char *min;
996 const unsigned char *max;
997 };
998
999 struct ASIdentifiers_build_test {
1000 const char *description;
1001 int should_build;
1002 int inherits;
1003 int canonical;
1004 int should_canonize;
1005 struct asid_or_range delegations[8];
1006 const unsigned char der[128];
1007 size_t der_len;
1008 };
1009
1010 /* Sentinel value used for marking the end of the delegations table. */
1011 #define V3_ASID_END -1
1012
1013 const struct ASIdentifiers_build_test ASIdentifiers_build_data[] = {
1014 {
1015 .description = "RFC 3779, Appendix C",
1016 .should_build = 1,
1017 .inherits = 1,
1018 .canonical = 1,
1019 .delegations = {
1020 {
1021 .type = V3_ASID_ASNUM,
1022 .inherit = 0,
1023 .min = "135",
1024 .max = NULL,
1025 },
1026 {
1027 .type = V3_ASID_ASNUM,
1028 .inherit = 0,
1029 .min = "3000",
1030 .max = "3999",
1031 },
1032 {
1033 .type = V3_ASID_ASNUM,
1034 .inherit = 0,
1035 .min = "5001",
1036 .max = NULL,
1037 },
1038 {
1039 .type = V3_ASID_RDI,
1040 .inherit = 1,
1041 .min = NULL,
1042 .max = NULL,
1043 },
1044 {
1045 .type = V3_ASID_END,
1046 },
1047 },
1048 .der = {
1049 0x30, 0x1a, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
1050 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
1051 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
1052 0xa1, 0x02, 0x05, 0x00,
1053 },
1054 .der_len = 28,
1055 },
1056 {
1057 .description = "RFC 3779, Appendix C without rdi",
1058 .should_build = 1,
1059 .inherits = 0,
1060 .canonical = 1,
1061 .delegations = {
1062 {
1063 .type = V3_ASID_ASNUM,
1064 .inherit = 0,
1065 .min = "135",
1066 .max = NULL,
1067 },
1068 {
1069 .type = V3_ASID_ASNUM,
1070 .inherit = 0,
1071 .min = "3000",
1072 .max = "3999",
1073 },
1074 {
1075 .type = V3_ASID_ASNUM,
1076 .inherit = 0,
1077 .min = "5001",
1078 .max = NULL,
1079 },
1080 {
1081 .type = V3_ASID_END,
1082 },
1083 },
1084 .der = {
1085 0x30, 0x16, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
1086 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
1087 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
1088 },
1089 .der_len = 24,
1090 },
1091 {
1092 .description = "RFC 3779, Appendix C variant",
1093 .should_build = 1,
1094 .inherits = 0,
1095 .canonical = 1,
1096 .delegations = {
1097 {
1098 .type = V3_ASID_ASNUM,
1099 .inherit = 0,
1100 .min = "135",
1101 .max = NULL,
1102 },
1103 {
1104 .type = V3_ASID_ASNUM,
1105 .inherit = 0,
1106 .min = "3000",
1107 .max = "3999",
1108 },
1109 {
1110 .type = V3_ASID_ASNUM,
1111 .inherit = 0,
1112 .min = "5001",
1113 .max = NULL,
1114 },
1115 {
1116 .type = V3_ASID_RDI,
1117 .inherit = 0,
1118 .min = "135",
1119 .max = NULL,
1120 },
1121 {
1122 .type = V3_ASID_RDI,
1123 .inherit = 0,
1124 .min = "3000",
1125 .max = "3999",
1126 },
1127 {
1128 .type = V3_ASID_RDI,
1129 .inherit = 0,
1130 .min = "5001",
1131 .max = NULL,
1132 },
1133 {
1134 .type = V3_ASID_END,
1135 },
1136 },
1137 .der = {
1138 0x30, 0x2c, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
1139 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
1140 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
1141 0xa1, 0x14, 0x30, 0x12, 0x02, 0x02, 0x00, 0x87,
1142 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 0x02, 0x02,
1143 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
1144 },
1145 .der_len = 46,
1146 },
1147 {
1148 .description = "inherit only",
1149 .should_build = 1,
1150 .inherits = 1,
1151 .canonical = 1,
1152 .delegations = {
1153 {
1154 .type = V3_ASID_ASNUM,
1155 .inherit = 1,
1156 },
1157 {
1158 .type = V3_ASID_RDI,
1159 .inherit = 1,
1160 },
1161 {
1162 .type = V3_ASID_END,
1163 },
1164 },
1165 .der = {
1166 0x30, 0x08, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x02,
1167 0x05, 0x00,
1168 },
1169 .der_len = 10,
1170 },
1171 {
1172 .description = "adjacent unsorted ranges are merged",
1173 .should_build = 1,
1174 .inherits = 0,
1175 .canonical = 0,
1176 .should_canonize = 1,
1177 .delegations = {
1178 {
1179 .type = V3_ASID_RDI,
1180 .inherit = 0,
1181 .min = "27",
1182 .max = NULL,
1183 },
1184 {
1185 .type = V3_ASID_RDI,
1186 .inherit = 0,
1187 .min = "28",
1188 .max = "57",
1189 },
1190 {
1191 .type = V3_ASID_RDI,
1192 .inherit = 0,
1193 .min = "66",
1194 .max = "68",
1195 },
1196 {
1197 .type = V3_ASID_RDI,
1198 .inherit = 0,
1199 .min = "58",
1200 .max = "63",
1201 },
1202 {
1203 .type = V3_ASID_RDI,
1204 .inherit = 0,
1205 .min = "64",
1206 .max = NULL,
1207 },
1208 {
1209 .type = V3_ASID_END,
1210 },
1211 },
1212 .der = {
1213 0x30, 0x14, 0xa1, 0x12, 0x30, 0x10, 0x30, 0x06,
1214 0x02, 0x01, 0x1b, 0x02, 0x01, 0x40, 0x30, 0x06,
1215 0x02, 0x01, 0x42, 0x02, 0x01, 0x44,
1216 },
1217 .der_len = 22,
1218 },
1219 {
1220 .description = "range of length 0",
1221 .should_build = 1,
1222 .inherits = 1,
1223 .canonical = 1,
1224 .should_canonize = 1,
1225 .delegations = {
1226 {
1227 .type = V3_ASID_RDI,
1228 .inherit = 0,
1229 .min = "27",
1230 .max = "27",
1231 },
1232 {
1233 .type = V3_ASID_ASNUM,
1234 .inherit = 1,
1235 },
1236 {
1237 .type = V3_ASID_END,
1238 },
1239 },
1240 .der = {
1241 0x30, 0x10, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x0a,
1242 0x30, 0x08, 0x30, 0x06, 0x02, 0x01, 0x1b, 0x02,
1243 0x01, 0x1b,
1244 },
1245 .der_len = 18,
1246 },
1247 {
1248 .description = "reversed range doesn't canonize",
1249 .should_build = 1,
1250 .inherits = 0,
1251 .canonical = 0,
1252 .should_canonize = 0,
1253 .delegations = {
1254 {
1255 .type = V3_ASID_ASNUM,
1256 .inherit = 0,
1257 .min = "57",
1258 .max = "42",
1259 },
1260 {
1261 .type = V3_ASID_END,
1262 },
1263 },
1264 },
1265 {
1266 .description = "overlapping ranges don't canonize",
1267 .should_build = 1,
1268 .inherits = 0,
1269 .canonical = 0,
1270 .should_canonize = 0,
1271 .delegations = {
1272 {
1273 .type = V3_ASID_ASNUM,
1274 .inherit = 0,
1275 .min = "42",
1276 .max = "57",
1277 },
1278 {
1279 .type = V3_ASID_ASNUM,
1280 .inherit = 0,
1281 .min = "57",
1282 .max = "60",
1283 },
1284 {
1285 .type = V3_ASID_END,
1286 },
1287 },
1288 },
1289 {
1290 .description = "reversed interior range doesn't canonize",
1291 .should_build = 1,
1292 .inherits = 0,
1293 .canonical = 0,
1294 .should_canonize = 0,
1295 .delegations = {
1296 {
1297 .type = V3_ASID_ASNUM,
1298 .inherit = 0,
1299 .min = "1",
1300 .max = "2",
1301 },
1302 {
1303 .type = V3_ASID_ASNUM,
1304 .inherit = 0,
1305 .min = "57",
1306 .max = "42",
1307 },
1308 {
1309 .type = V3_ASID_ASNUM,
1310 .inherit = 0,
1311 .min = "65523",
1312 .max = "65535",
1313 },
1314 {
1315 .type = V3_ASID_END,
1316 },
1317 },
1318 },
1319 {
1320 .description = "can't inherit and add AS ids",
1321 .should_build = 0,
1322 .inherits = 0,
1323 .canonical = 0,
1324 .should_canonize = 0,
1325 .delegations = {
1326 {
1327 .type = V3_ASID_ASNUM,
1328 .inherit = 0,
1329 .min = "1",
1330 .max = "2",
1331 },
1332 {
1333 .type = V3_ASID_ASNUM,
1334 .inherit = 1,
1335 },
1336 {
1337 .type = V3_ASID_END,
1338 },
1339 },
1340 },
1341 {
1342 .description = "can't inherit and add rdis",
1343 .should_build = 0,
1344 .inherits = 0,
1345 .canonical = 0,
1346 .should_canonize = 0,
1347 .delegations = {
1348 {
1349 .type = V3_ASID_RDI,
1350 .inherit = 0,
1351 .min = "1",
1352 .max = "2",
1353 },
1354 {
1355 .type = V3_ASID_RDI,
1356 .inherit = 1,
1357 },
1358 {
1359 .type = V3_ASID_END,
1360 },
1361 },
1362 },
1363 };
1364
1365 const size_t N_ASIDENTIFIERS_BUILD_TESTS =
1366 sizeof(ASIdentifiers_build_data) / sizeof(ASIdentifiers_build_data[0]);
1367
1368 static int
add_as_delegation(ASIdentifiers * asid,const struct asid_or_range * delegation)1369 add_as_delegation(ASIdentifiers *asid, const struct asid_or_range *delegation)
1370 {
1371 ASN1_INTEGER *min = NULL, *max = NULL;
1372 int ret = 0;
1373
1374 if (delegation->inherit)
1375 return X509v3_asid_add_inherit(asid, delegation->type);
1376
1377 if ((min = s2i_ASN1_INTEGER(NULL, delegation->min)) == NULL)
1378 goto err;
1379
1380 if (delegation->max != NULL) {
1381 if ((max = s2i_ASN1_INTEGER(NULL, delegation->max)) == NULL)
1382 goto err;
1383 }
1384
1385 if (!X509v3_asid_add_id_or_range(asid, delegation->type, min, max))
1386 goto err;
1387 min = NULL;
1388 max = NULL;
1389
1390 ret = 1;
1391
1392 err:
1393 ASN1_INTEGER_free(min);
1394 ASN1_INTEGER_free(max);
1395
1396 return ret;
1397 }
1398
1399 static ASIdentifiers *
build_asid(const struct asid_or_range delegations[])1400 build_asid(const struct asid_or_range delegations[])
1401 {
1402 ASIdentifiers *asid = NULL;
1403 const struct asid_or_range *delegation;
1404
1405 if ((asid = ASIdentifiers_new()) == NULL)
1406 goto err;
1407
1408 for (delegation = &delegations[0]; delegation->type != V3_ASID_END;
1409 delegation++) {
1410 if (!add_as_delegation(asid, delegation))
1411 goto err;
1412 }
1413
1414 return asid;
1415
1416 err:
1417 ASIdentifiers_free(asid);
1418 return NULL;
1419 }
1420
1421 static int
build_asid_test(const struct ASIdentifiers_build_test * test)1422 build_asid_test(const struct ASIdentifiers_build_test *test)
1423 {
1424 ASIdentifiers *asid = NULL;
1425 unsigned char *out = NULL;
1426 int out_len;
1427 int memcmp_failed = 1;
1428 int failed = 1;
1429
1430 if ((asid = build_asid(test->delegations)) == NULL) {
1431 if (!test->should_build) {
1432 failed = 0;
1433 return failed;
1434 }
1435 fprintf(stderr, "%s: \"%s\" failed to build\n", __func__,
1436 test->description);
1437 return failed;
1438 }
1439
1440 if (!test->canonical) {
1441 if (X509v3_asid_is_canonical(asid)) {
1442 fprintf(stderr, "%s: \"%s\" shouldn't be canonical\n",
1443 __func__, test->description);
1444 goto err;
1445 }
1446 if (X509v3_asid_canonize(asid) != test->should_canonize) {
1447 fprintf(stderr, "%s: \"%s\" failed to canonize\n",
1448 __func__, test->description);
1449 goto err;
1450 }
1451 if (!test->should_canonize) {
1452 failed = 0;
1453 goto err;
1454 }
1455 }
1456
1457 /*
1458 * Verify that asid is in canonical form before converting it to DER.
1459 */
1460 if (!X509v3_asid_is_canonical(asid)) {
1461 fprintf(stderr, "%s: asid is not canonical\n", __func__);
1462 goto err;
1463 }
1464
1465 /*
1466 * Convert asid to DER and check that it matches expectations
1467 */
1468 out = NULL;
1469 if ((out_len = i2d_ASIdentifiers(asid, &out)) <= 0) {
1470 fprintf(stderr, "%s: \"%s\" i2d_ASIdentifiers failed\n",
1471 __func__, test->description);
1472 goto err;
1473 }
1474
1475
1476 memcmp_failed = (size_t)out_len != test->der_len;
1477 if (!memcmp_failed)
1478 memcmp_failed = memcmp(out, test->der, test->der_len);
1479 if (memcmp_failed) {
1480 report_hexdump(__func__, test->description, "memcmp DER failed",
1481 test->der, test->der_len, out, out_len);
1482 goto err;
1483 }
1484
1485 /*
1486 * Verify that asid inherits as expected
1487 */
1488 if (X509v3_asid_inherits(asid) != test->inherits) {
1489 fprintf(stderr, "%s: \"%s\" unexpected asid inherit %d\n",
1490 __func__, test->description, test->inherits);
1491 goto err;
1492 }
1493
1494 failed = 0;
1495
1496 err:
1497 free(out);
1498 ASIdentifiers_free(asid);
1499
1500 return failed;
1501 }
1502
1503 static int
run_ASIdentifiers_build_test(void)1504 run_ASIdentifiers_build_test(void)
1505 {
1506 size_t i;
1507 int failed = 0;
1508
1509 for (i = 0; i < N_ASIDENTIFIERS_BUILD_TESTS; i++)
1510 failed |= build_asid_test(&ASIdentifiers_build_data[i]);
1511
1512 return failed;
1513 }
1514
1515 struct ASIdentifiers_subset_test {
1516 const char *description;
1517 struct asid_or_range delegationsA[8];
1518 struct asid_or_range delegationsB[8];
1519 int is_subset;
1520 int is_subset_if_canonized;
1521 };
1522
1523 const struct ASIdentifiers_subset_test ASIdentifiers_subset_data[] = {
1524 {
1525 .description = "simple subset relation",
1526 .delegationsA = {
1527 {
1528 .type = V3_ASID_ASNUM,
1529 .inherit = 0,
1530 .min = "2",
1531 .max = "4",
1532 },
1533 {
1534 .type = V3_ASID_RDI,
1535 .inherit = 0,
1536 .min = "2",
1537 .max = NULL,
1538 },
1539 {
1540 .type = V3_ASID_END,
1541 },
1542 },
1543 .delegationsB = {
1544 {
1545 .type = V3_ASID_ASNUM,
1546 .inherit = 0,
1547 .min = "1",
1548 .max = "5",
1549 },
1550 {
1551 .type = V3_ASID_RDI,
1552 .inherit = 0,
1553 .min = "1",
1554 .max = "5",
1555 },
1556 {
1557 .type = V3_ASID_END,
1558 },
1559 },
1560 .is_subset = 1,
1561 .is_subset_if_canonized = 1,
1562 },
1563 {
1564 .description = "only asnums",
1565 .delegationsA = {
1566 {
1567 .type = V3_ASID_ASNUM,
1568 .inherit = 0,
1569 .min = "2",
1570 .max = "4",
1571 },
1572 {
1573 .type = V3_ASID_END,
1574 },
1575 },
1576 .delegationsB = {
1577 {
1578 .type = V3_ASID_ASNUM,
1579 .inherit = 0,
1580 .min = "1",
1581 .max = "5",
1582 },
1583 {
1584 .type = V3_ASID_END,
1585 },
1586 },
1587 .is_subset = 1,
1588 .is_subset_if_canonized = 1,
1589 },
1590 {
1591 .description = "only rdis",
1592 .delegationsA = {
1593 {
1594 .type = V3_ASID_RDI,
1595 .inherit = 0,
1596 .min = "2",
1597 .max = NULL,
1598 },
1599 {
1600 .type = V3_ASID_END,
1601 },
1602 },
1603 .delegationsB = {
1604 {
1605 .type = V3_ASID_RDI,
1606 .inherit = 0,
1607 .min = "1",
1608 .max = "5",
1609 },
1610 {
1611 .type = V3_ASID_END,
1612 },
1613 },
1614 .is_subset = 1,
1615 .is_subset_if_canonized = 1,
1616 },
1617 {
1618 .description = "child only has asnums, parent only has rdis",
1619 .delegationsA = {
1620 {
1621 .type = V3_ASID_ASNUM,
1622 .inherit = 0,
1623 .min = "2",
1624 .max = "4",
1625 },
1626 {
1627 .type = V3_ASID_END,
1628 },
1629 },
1630 .delegationsB = {
1631 {
1632 .type = V3_ASID_RDI,
1633 .inherit = 0,
1634 .min = "1",
1635 .max = "5",
1636 },
1637 {
1638 .type = V3_ASID_END,
1639 },
1640 },
1641 .is_subset = 0,
1642 .is_subset_if_canonized = 0,
1643 },
1644 {
1645 .description = "child only has rdis, parent only has asnums",
1646 .delegationsA = {
1647 {
1648 .type = V3_ASID_RDI,
1649 .inherit = 0,
1650 .min = "2",
1651 .max = "4",
1652 },
1653 {
1654 .type = V3_ASID_END,
1655 },
1656 },
1657 .delegationsB = {
1658 {
1659 .type = V3_ASID_ASNUM,
1660 .inherit = 0,
1661 .min = "1",
1662 .max = "5",
1663 },
1664 {
1665 .type = V3_ASID_END,
1666 },
1667 },
1668 .is_subset = 0,
1669 .is_subset_if_canonized = 0,
1670 },
1671 {
1672 .description = "child only has rdis, parent has both",
1673 .delegationsA = {
1674 {
1675 .type = V3_ASID_RDI,
1676 .inherit = 0,
1677 .min = "2",
1678 .max = "4",
1679 },
1680 {
1681 .type = V3_ASID_END,
1682 },
1683 },
1684 .delegationsB = {
1685 {
1686 .type = V3_ASID_ASNUM,
1687 .inherit = 0,
1688 .min = "1",
1689 .max = "5",
1690 },
1691 {
1692 .type = V3_ASID_RDI,
1693 .inherit = 0,
1694 .min = "1",
1695 .max = "5",
1696 },
1697 {
1698 .type = V3_ASID_END,
1699 },
1700 },
1701 .is_subset = 1,
1702 .is_subset_if_canonized = 1,
1703 },
1704 {
1705 .description = "subset relation only after canonization",
1706 .delegationsA = {
1707 {
1708 .type = V3_ASID_ASNUM,
1709 .inherit = 0,
1710 .min = "2",
1711 .max = NULL,
1712 },
1713 {
1714 .type = V3_ASID_ASNUM,
1715 .inherit = 0,
1716 .min = "3",
1717 .max = "4",
1718 },
1719 {
1720 .type = V3_ASID_RDI,
1721 .inherit = 0,
1722 .min = "2",
1723 .max = NULL,
1724 },
1725 {
1726 .type = V3_ASID_END,
1727 },
1728 },
1729 .delegationsB = {
1730 {
1731 .type = V3_ASID_ASNUM,
1732 .inherit = 0,
1733 .min = "1",
1734 .max = "3",
1735 },
1736 {
1737 .type = V3_ASID_ASNUM,
1738 .inherit = 0,
1739 .min = "4",
1740 .max = "5",
1741 },
1742 {
1743 .type = V3_ASID_RDI,
1744 .inherit = 0,
1745 .min = "1",
1746 .max = "5",
1747 },
1748 {
1749 .type = V3_ASID_END,
1750 },
1751 },
1752 .is_subset = 0,
1753 .is_subset_if_canonized = 1,
1754 },
1755 {
1756 .description = "no subset if A inherits",
1757 .delegationsA = {
1758 {
1759 .type = V3_ASID_ASNUM,
1760 .inherit = 0,
1761 .min = "2",
1762 .max = NULL,
1763 },
1764 {
1765 .type = V3_ASID_ASNUM,
1766 .inherit = 0,
1767 .min = "3",
1768 .max = "4",
1769 },
1770 {
1771 .type = V3_ASID_RDI,
1772 .inherit = 1,
1773 },
1774 {
1775 .type = V3_ASID_END,
1776 },
1777 },
1778 .delegationsB = {
1779 {
1780 .type = V3_ASID_ASNUM,
1781 .inherit = 0,
1782 .min = "1",
1783 .max = "3",
1784 },
1785 {
1786 .type = V3_ASID_ASNUM,
1787 .inherit = 0,
1788 .min = "4",
1789 .max = "5",
1790 },
1791 {
1792 .type = V3_ASID_RDI,
1793 .inherit = 0,
1794 .min = "1",
1795 .max = "5",
1796 },
1797 {
1798 .type = V3_ASID_END,
1799 },
1800 },
1801 .is_subset = 0,
1802 .is_subset_if_canonized = 0,
1803 },
1804 {
1805 .description = "no subset if B inherits",
1806 .delegationsA = {
1807 {
1808 .type = V3_ASID_ASNUM,
1809 .inherit = 0,
1810 .min = "2",
1811 .max = NULL,
1812 },
1813 {
1814 .type = V3_ASID_ASNUM,
1815 .inherit = 0,
1816 .min = "3",
1817 .max = "4",
1818 },
1819 {
1820 .type = V3_ASID_RDI,
1821 .inherit = 0,
1822 .min = "5",
1823 .max = NULL,
1824 },
1825 {
1826 .type = V3_ASID_END,
1827 },
1828 },
1829 .delegationsB = {
1830 {
1831 .type = V3_ASID_ASNUM,
1832 .inherit = 0,
1833 .min = "1",
1834 .max = "3",
1835 },
1836 {
1837 .type = V3_ASID_ASNUM,
1838 .inherit = 0,
1839 .min = "4",
1840 .max = "5",
1841 },
1842 {
1843 .type = V3_ASID_RDI,
1844 .inherit = 1,
1845 },
1846 {
1847 .type = V3_ASID_END,
1848 },
1849 },
1850 .is_subset = 0,
1851 .is_subset_if_canonized = 0,
1852 },
1853 {
1854 .description = "no subset if both inherit",
1855 .delegationsA = {
1856 {
1857 .type = V3_ASID_ASNUM,
1858 .inherit = 0,
1859 .min = "2",
1860 .max = NULL,
1861 },
1862 {
1863 .type = V3_ASID_ASNUM,
1864 .inherit = 0,
1865 .min = "3",
1866 .max = "4",
1867 },
1868 {
1869 .type = V3_ASID_RDI,
1870 .inherit = 1,
1871 },
1872 {
1873 .type = V3_ASID_END,
1874 },
1875 },
1876 .delegationsB = {
1877 {
1878 .type = V3_ASID_ASNUM,
1879 .inherit = 0,
1880 .min = "1",
1881 .max = "3",
1882 },
1883 {
1884 .type = V3_ASID_ASNUM,
1885 .inherit = 0,
1886 .min = "4",
1887 .max = "5",
1888 },
1889 {
1890 .type = V3_ASID_RDI,
1891 .inherit = 1,
1892 },
1893 {
1894 .type = V3_ASID_END,
1895 },
1896 },
1897 .is_subset = 0,
1898 .is_subset_if_canonized = 0,
1899 },
1900 };
1901
1902 const size_t N_ASIDENTIFIERS_SUBSET_TESTS =
1903 sizeof(ASIdentifiers_subset_data) / sizeof(ASIdentifiers_subset_data[0]);
1904
1905 static int
asid_subset_test(const struct ASIdentifiers_subset_test * test)1906 asid_subset_test(const struct ASIdentifiers_subset_test *test)
1907 {
1908 ASIdentifiers *asidA = NULL, *asidB = NULL;
1909 int failed = 0;
1910
1911 if ((asidA = build_asid(test->delegationsA)) == NULL)
1912 goto err;
1913 if ((asidB = build_asid(test->delegationsB)) == NULL)
1914 goto err;
1915
1916 if (X509v3_asid_subset(asidA, asidB) != test->is_subset) {
1917 fprintf(stderr, "%s: \"%s\" X509v3_asid_subset failed\n",
1918 __func__, test->description);
1919 failed = 1;
1920 }
1921
1922 if (!test->is_subset) {
1923 if (!X509v3_asid_canonize(asidA))
1924 goto err;
1925 if (!X509v3_asid_canonize(asidB))
1926 goto err;
1927 if (X509v3_asid_subset(asidA, asidB) !=
1928 test->is_subset_if_canonized) {
1929 fprintf(stderr, "%s: \"%s\" canonized subset failed\n",
1930 __func__, test->description);
1931 failed = 1;
1932 }
1933 }
1934
1935 err:
1936 ASIdentifiers_free(asidA);
1937 ASIdentifiers_free(asidB);
1938
1939 return failed;
1940 }
1941
1942 static int
run_ASIdentifiers_subset_test(void)1943 run_ASIdentifiers_subset_test(void)
1944 {
1945 size_t i;
1946 int failed = 0;
1947
1948 for (i = 0; i < N_ASIDENTIFIERS_SUBSET_TESTS; i++)
1949 failed |= asid_subset_test(&ASIdentifiers_subset_data[i]);
1950
1951 return failed;
1952 }
1953
1954 int
main(void)1955 main(void)
1956 {
1957 int failed = 0;
1958
1959 failed |= run_IPAddressOrRange_tests();
1960 failed |= run_IPAddrBlock_tests();
1961 failed |= run_ASIdentifiers_build_test();
1962 failed |= run_ASIdentifiers_subset_test();
1963
1964 return failed;
1965 }
1966