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
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
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
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
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
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 *
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
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 *
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 *
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
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 *
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
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
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
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
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
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
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 *
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
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
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
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
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
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