1*d3ce54f2Stb /* $OpenBSD: rfc3779.c,v 1.10 2023/12/13 07:19:37 tb Exp $ */
24defbdf5Stb /*
34defbdf5Stb * Copyright (c) 2021 Theo Buehler <tb@openbsd.org>
44defbdf5Stb *
54defbdf5Stb * Permission to use, copy, modify, and distribute this software for any
64defbdf5Stb * purpose with or without fee is hereby granted, provided that the above
74defbdf5Stb * copyright notice and this permission notice appear in all copies.
84defbdf5Stb *
94defbdf5Stb * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
104defbdf5Stb * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
114defbdf5Stb * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
124defbdf5Stb * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
134defbdf5Stb * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
144defbdf5Stb * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
154defbdf5Stb * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
164defbdf5Stb */
174defbdf5Stb
184defbdf5Stb #include <stdio.h>
194defbdf5Stb #include <string.h>
204defbdf5Stb
214defbdf5Stb #include <openssl/asn1.h>
224defbdf5Stb #include <openssl/asn1t.h>
234defbdf5Stb #include <openssl/x509v3.h>
244defbdf5Stb
254defbdf5Stb #define RAW_ADDRESS_SIZE 16
264defbdf5Stb
274defbdf5Stb static void
hexdump(const unsigned char * buf,size_t len)284defbdf5Stb hexdump(const unsigned char *buf, size_t len)
294defbdf5Stb {
304defbdf5Stb size_t i;
314defbdf5Stb
324defbdf5Stb for (i = 1; i <= len; i++)
334defbdf5Stb fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
344defbdf5Stb
354defbdf5Stb if (len % 8)
364defbdf5Stb fprintf(stderr, "\n");
374defbdf5Stb }
384defbdf5Stb
394defbdf5Stb 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)404defbdf5Stb report_hexdump(const char *func, const char *description, const char *msg,
414defbdf5Stb const unsigned char *want, size_t want_len,
424defbdf5Stb const unsigned char *got, size_t got_len)
434defbdf5Stb {
444defbdf5Stb fprintf(stderr, "%s: \"%s\" %s\nwant:\n", func, description, msg);
454defbdf5Stb hexdump(want, want_len);
464defbdf5Stb fprintf(stderr, "got:\n");
474defbdf5Stb hexdump(got, got_len);
484defbdf5Stb }
494defbdf5Stb
504defbdf5Stb static int
afi_size(int afi)514defbdf5Stb afi_size(int afi)
524defbdf5Stb {
534defbdf5Stb switch (afi) {
544defbdf5Stb case IANA_AFI_IPV4:
554defbdf5Stb return 4;
564defbdf5Stb case IANA_AFI_IPV6:
574defbdf5Stb return 16;
584defbdf5Stb }
594defbdf5Stb return 0;
604defbdf5Stb }
614defbdf5Stb
624defbdf5Stb struct IPAddressOrRange_test {
634defbdf5Stb const char *description;
644defbdf5Stb const uint8_t der[32];
654defbdf5Stb size_t der_len;
664defbdf5Stb unsigned afi;
674defbdf5Stb const uint8_t min[RAW_ADDRESS_SIZE];
684defbdf5Stb const uint8_t max[RAW_ADDRESS_SIZE];
694defbdf5Stb };
704defbdf5Stb
714defbdf5Stb const struct IPAddressOrRange_test IPAddressOrRange_test_data[] = {
724defbdf5Stb /* Examples from RFC 3779, section 2.1.1 */
734defbdf5Stb {
744defbdf5Stb .description = "address 10.5.0.4",
754defbdf5Stb .der = {
764defbdf5Stb 0x03, 0x05, 0x00, 0x0a, 0x05, 0x00, 0x04,
774defbdf5Stb },
784defbdf5Stb .der_len = 7,
794defbdf5Stb .afi = IANA_AFI_IPV4,
804defbdf5Stb .min = {
814defbdf5Stb 0x0a, 0x05, 0x00, 0x04,
824defbdf5Stb },
834defbdf5Stb .max = {
844defbdf5Stb 0x0a, 0x05, 0x00, 0x04,
854defbdf5Stb }
864defbdf5Stb },
874defbdf5Stb {
884defbdf5Stb .description = "prefix 10.5.0/23",
894defbdf5Stb .der = {
904defbdf5Stb 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00,
914defbdf5Stb },
924defbdf5Stb .der_len = 6,
934defbdf5Stb .afi = IANA_AFI_IPV4,
944defbdf5Stb .min = {
954defbdf5Stb 0x0a, 0x05, 0x00, 0x00,
964defbdf5Stb },
974defbdf5Stb .max = {
984defbdf5Stb 0x0a, 0x05, 0x01, 0xff,
994defbdf5Stb }
1004defbdf5Stb },
1014defbdf5Stb {
1024defbdf5Stb .description = "address 2001:0:200:3::1",
1034defbdf5Stb .der = {
1044defbdf5Stb 0x03, 0x11, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02,
1054defbdf5Stb 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
1064defbdf5Stb 0x00, 0x00, 0x01,
1074defbdf5Stb },
1084defbdf5Stb .der_len = 19,
1094defbdf5Stb .afi = IANA_AFI_IPV6,
1104defbdf5Stb .min = {
1114defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03,
1124defbdf5Stb 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1134defbdf5Stb },
1144defbdf5Stb .max = {
1154defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03,
1164defbdf5Stb 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1174defbdf5Stb },
1184defbdf5Stb },
1194defbdf5Stb {
1204defbdf5Stb .description = "prefix 2001:0:200/39",
1214defbdf5Stb .der = {
1224defbdf5Stb 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02,
1234defbdf5Stb },
1244defbdf5Stb .der_len = 8,
1254defbdf5Stb .afi = IANA_AFI_IPV6,
1264defbdf5Stb .min = {
1274defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1284defbdf5Stb 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294defbdf5Stb },
1304defbdf5Stb .max = {
1314defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
1324defbdf5Stb 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1334defbdf5Stb },
1344defbdf5Stb },
1354defbdf5Stb
1364defbdf5Stb /* Examples from RFC 3779, Section 2.1.2 */
1374defbdf5Stb {
1384defbdf5Stb .description = "prefix 10.5.0/23 as a range",
1394defbdf5Stb .der = {
1404defbdf5Stb /* Sequence */
1414defbdf5Stb 0x30, 0x0b,
1424defbdf5Stb /* 10.5.0.0 */
1434defbdf5Stb 0x03, 0x03, 0x00, 0x0a, 0x05,
1444defbdf5Stb /* 10.5.1.255 */
1454defbdf5Stb 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00,
1464defbdf5Stb },
1474defbdf5Stb .der_len = 13,
1484defbdf5Stb .afi = IANA_AFI_IPV4,
1494defbdf5Stb .min = {
1504defbdf5Stb 0x0a, 0x05, 0x00, 0x00,
1514defbdf5Stb },
1524defbdf5Stb .max = {
1534defbdf5Stb 0x0a, 0x05, 0x01, 0xff,
1544defbdf5Stb }
1554defbdf5Stb },
1564defbdf5Stb {
1574defbdf5Stb .description = "prefix 2001:0:200/39 as a range",
1584defbdf5Stb .der = {
1594defbdf5Stb /* Sequence */
1604defbdf5Stb 0x30, 0x10,
1614defbdf5Stb /* 2001:0:200:: */
1624defbdf5Stb 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02,
1634defbdf5Stb /* 2001:0:3ff:ffff:ffff:ffff:ffff:ffff */
1644defbdf5Stb 0x03, 0x06, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00,
1654defbdf5Stb },
1664defbdf5Stb .der_len = 18,
1674defbdf5Stb .afi = IANA_AFI_IPV6,
1684defbdf5Stb .min = {
1694defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1704defbdf5Stb 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1714defbdf5Stb },
1724defbdf5Stb .max = {
1734defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
1744defbdf5Stb 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1754defbdf5Stb }
1764defbdf5Stb },
1774defbdf5Stb {
1784defbdf5Stb .description = "prefix 0/0",
1794defbdf5Stb .der = {
1804defbdf5Stb 0x03, 0x01, 0x00,
1814defbdf5Stb },
1824defbdf5Stb .der_len = 3,
1834defbdf5Stb .afi = IANA_AFI_IPV4,
1844defbdf5Stb .min = {
1854defbdf5Stb 0x00, 0x00, 0x00, 0x00,
1864defbdf5Stb },
1874defbdf5Stb .max = {
1884defbdf5Stb 0xff, 0xff, 0xff, 0xff,
1894defbdf5Stb }
1904defbdf5Stb },
1914defbdf5Stb {
1924defbdf5Stb .description = "prefix 10.64/12",
1934defbdf5Stb .der = {
1944defbdf5Stb 0x03, 0x03, 0x04, 0x0a, 0x40,
1954defbdf5Stb },
1964defbdf5Stb .der_len = 5,
1974defbdf5Stb .afi = IANA_AFI_IPV4,
1984defbdf5Stb .min = {
1994defbdf5Stb 0x0a, 0x40, 0x00, 0x00,
2004defbdf5Stb },
2014defbdf5Stb .max = {
2024defbdf5Stb 0x0a, 0x4f, 0xff, 0xff,
2034defbdf5Stb },
2044defbdf5Stb },
2054defbdf5Stb {
2064defbdf5Stb .description = "prefix 10.64/20",
2074defbdf5Stb .der = {
2084defbdf5Stb 0x03, 0x04, 0x04, 0x0a, 0x40, 0x00,
2094defbdf5Stb },
2104defbdf5Stb .der_len = 6,
2114defbdf5Stb .afi = IANA_AFI_IPV4,
2124defbdf5Stb .min = {
2134defbdf5Stb 0x0a, 0x40, 0x00, 0x00,
2144defbdf5Stb },
2154defbdf5Stb .max = {
2164defbdf5Stb 0x0a, 0x40, 0x0f, 0xff,
2174defbdf5Stb },
2184defbdf5Stb },
2194defbdf5Stb };
2204defbdf5Stb
2214defbdf5Stb const size_t N_IPADDRESSORRANGE_TESTS =
2224defbdf5Stb sizeof(IPAddressOrRange_test_data) / sizeof(IPAddressOrRange_test_data[0]);
2234defbdf5Stb
2244defbdf5Stb static int
test_IPAddressOrRange(const struct IPAddressOrRange_test * test)2254defbdf5Stb test_IPAddressOrRange(const struct IPAddressOrRange_test *test)
2264defbdf5Stb {
2274defbdf5Stb IPAddressOrRange *aor;
2284defbdf5Stb const unsigned char *p;
2294defbdf5Stb unsigned char min[RAW_ADDRESS_SIZE] = {0}, max[RAW_ADDRESS_SIZE] = {0};
2304defbdf5Stb unsigned char *out = NULL;
2314defbdf5Stb int out_len;
2324defbdf5Stb int afi_len;
2334defbdf5Stb int memcmp_failed = 0;
2344defbdf5Stb int failed = 1;
2354defbdf5Stb
2364defbdf5Stb /*
2374defbdf5Stb * First, decode DER from the test case.
2384defbdf5Stb */
2394defbdf5Stb
2404defbdf5Stb p = &test->der[0];
2414defbdf5Stb if ((aor = d2i_IPAddressOrRange(NULL, &p, test->der_len)) == NULL) {
2424defbdf5Stb fprintf(stderr, "%s: \"%s\" d2i_IPAddressOrRange failed\n",
2434defbdf5Stb __func__, test->description);
2444defbdf5Stb goto err;
2454defbdf5Stb }
2464defbdf5Stb
2474defbdf5Stb /*
2484defbdf5Stb * Now extract minimum and maximum from the parsed range.
2494defbdf5Stb */
2504defbdf5Stb
2514defbdf5Stb afi_len = afi_size(test->afi);
2524defbdf5Stb
2534defbdf5Stb if (X509v3_addr_get_range(aor, test->afi, min, max, sizeof min) !=
2544defbdf5Stb afi_len) {
2554defbdf5Stb fprintf(stderr, "%s: \"%s\" X509v3_addr_get_range failed\n",
2564defbdf5Stb __func__, test->description);
2574defbdf5Stb goto err;
2584defbdf5Stb }
2594defbdf5Stb
2604defbdf5Stb /*
2614defbdf5Stb * Check that min and max match expectations.
2624defbdf5Stb */
2634defbdf5Stb
2644defbdf5Stb if (memcmp(min, test->min, afi_len) != 0) {
2654defbdf5Stb memcmp_failed |= 1;
2664defbdf5Stb report_hexdump(__func__, test->description, "memcmp min failed",
2674defbdf5Stb test->min, afi_len, min, afi_len);
2684defbdf5Stb }
2694defbdf5Stb if (memcmp(max, test->max, afi_len) != 0) {
2704defbdf5Stb memcmp_failed |= 1;
2714defbdf5Stb report_hexdump(__func__, test->description, "memcmp max failed",
2724defbdf5Stb test->max, afi_len, max, afi_len);
2734defbdf5Stb }
2744defbdf5Stb if (memcmp_failed)
2754defbdf5Stb goto err;
2764defbdf5Stb
2774defbdf5Stb /*
2784defbdf5Stb * Now turn the parsed IPAddressOrRange back into DER and check that
2794defbdf5Stb * it matches the DER in the test case.
2804defbdf5Stb */
2814defbdf5Stb
2824defbdf5Stb out = NULL;
2834defbdf5Stb if ((out_len = i2d_IPAddressOrRange(aor, &out)) <= 0) {
2844defbdf5Stb fprintf(stderr, "%s: \"%s\" i2d_IPAddressOrRange failed\n",
2854defbdf5Stb __func__, test->description);
2864defbdf5Stb goto err;
2874defbdf5Stb }
2884defbdf5Stb
2894defbdf5Stb memcmp_failed = (size_t)out_len != test->der_len;
2904defbdf5Stb if (!memcmp_failed)
2914defbdf5Stb memcmp_failed = memcmp(test->der, out, out_len);
2924defbdf5Stb
2934defbdf5Stb if (memcmp_failed) {
2944defbdf5Stb report_hexdump(__func__, test->description, "memcmp DER failed",
2954defbdf5Stb test->der, test->der_len, out, out_len);
2964defbdf5Stb goto err;
2974defbdf5Stb }
2984defbdf5Stb
2994defbdf5Stb failed = 0;
3004defbdf5Stb err:
3014defbdf5Stb IPAddressOrRange_free(aor);
3024defbdf5Stb free(out);
3034defbdf5Stb
3044defbdf5Stb return failed;
3054defbdf5Stb }
3064defbdf5Stb
3074defbdf5Stb static int
run_IPAddressOrRange_tests(void)3084defbdf5Stb run_IPAddressOrRange_tests(void)
3094defbdf5Stb {
3104defbdf5Stb size_t i;
3114defbdf5Stb int failed = 0;
3124defbdf5Stb
3134defbdf5Stb for (i = 0; i < N_IPADDRESSORRANGE_TESTS; i++)
3144defbdf5Stb failed |=
3154defbdf5Stb test_IPAddressOrRange(&IPAddressOrRange_test_data[i]);
3164defbdf5Stb
3174defbdf5Stb return failed;
3184defbdf5Stb }
3194defbdf5Stb
3204defbdf5Stb /*
3214defbdf5Stb * XXX: These should really be part of the public API...
3224defbdf5Stb */
3234defbdf5Stb static IPAddrBlocks *IPAddrBlocks_new(void);
3244defbdf5Stb static void IPAddrBlocks_free(IPAddrBlocks *addr);
325f911aa70Stb static IPAddrBlocks *d2i_IPAddrBlocks(IPAddrBlocks **addrs,
3264defbdf5Stb const unsigned char **in, long len);
3274defbdf5Stb static int i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out);
3284defbdf5Stb
3294defbdf5Stb static IPAddrBlocks *
IPAddrBlocks_new(void)3304defbdf5Stb IPAddrBlocks_new(void)
3314defbdf5Stb {
3324defbdf5Stb IPAddrBlocks *addrs;
3334defbdf5Stb
3344defbdf5Stb /*
3354defbdf5Stb * XXX The comparison function IPAddressFamily_cmp() isn't public.
3364defbdf5Stb * Start with the default and exploit a side effect of the lovely API
3374defbdf5Stb * which helpfully sets the correct function in a few places. Let's
3384defbdf5Stb * use the cheapest and easiest to reach one.
3394defbdf5Stb */
3404defbdf5Stb if ((addrs = sk_IPAddressFamily_new_null()) == NULL)
3414defbdf5Stb return NULL;
3424defbdf5Stb if (!X509v3_addr_canonize(addrs)) {
3434defbdf5Stb IPAddrBlocks_free(addrs);
3444defbdf5Stb return NULL;
3454defbdf5Stb }
3464defbdf5Stb
3474defbdf5Stb return addrs;
3484defbdf5Stb }
3494defbdf5Stb
3504defbdf5Stb static void
IPAddrBlocks_free(IPAddrBlocks * addr)3514defbdf5Stb IPAddrBlocks_free(IPAddrBlocks *addr)
3524defbdf5Stb {
3534defbdf5Stb sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
3544defbdf5Stb }
3554defbdf5Stb
3564defbdf5Stb /*
3574defbdf5Stb * We want {d2i,i2d}_IPAddrBlocks() to play with the DER of the extension.
3584defbdf5Stb * These don't exist, so we have to implement them ourselves. IPAddrBlocks_it
3594defbdf5Stb * isn't public, so we need to fetch it from the library. We cache it in a
3604defbdf5Stb * static variable to avoid the cost of a binary search through all supported
3614defbdf5Stb * extensions on each call.
3624defbdf5Stb */
3634defbdf5Stb
364*d3ce54f2Stb static ASN1_ITEM_EXP *
get_IPAddrBlocks_it(void)3654defbdf5Stb get_IPAddrBlocks_it(void)
3664defbdf5Stb {
367*d3ce54f2Stb static ASN1_ITEM_EXP *my_IPAddrBlocks_it;
3684defbdf5Stb const X509V3_EXT_METHOD *v3_addr;
3694defbdf5Stb
3704defbdf5Stb if (my_IPAddrBlocks_it != NULL)
3714defbdf5Stb return my_IPAddrBlocks_it;
3724defbdf5Stb
3734defbdf5Stb if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) {
3744defbdf5Stb fprintf(stderr, "could not get v3_addr\n");
3754defbdf5Stb return NULL;
3764defbdf5Stb }
3774defbdf5Stb
3784defbdf5Stb my_IPAddrBlocks_it = v3_addr->it;
3794defbdf5Stb
3804defbdf5Stb return my_IPAddrBlocks_it;
3814defbdf5Stb }
3824defbdf5Stb
383f911aa70Stb static IPAddrBlocks *
d2i_IPAddrBlocks(IPAddrBlocks ** addrs,const unsigned char ** in,long len)3844defbdf5Stb d2i_IPAddrBlocks(IPAddrBlocks **addrs, const unsigned char **in, long len)
3854defbdf5Stb {
386*d3ce54f2Stb ASN1_ITEM_EXP *my_IPAddrBlocks_it;
3874defbdf5Stb
388bd5381c8Stb if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL)
3894defbdf5Stb return NULL;
3904defbdf5Stb
3914defbdf5Stb return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrs, in, len,
3924defbdf5Stb my_IPAddrBlocks_it);
3934defbdf5Stb }
3944defbdf5Stb
3954defbdf5Stb static int
i2d_IPAddrBlocks(IPAddrBlocks * addrs,unsigned char ** out)3964defbdf5Stb i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out)
3974defbdf5Stb {
398*d3ce54f2Stb ASN1_ITEM_EXP *my_IPAddrBlocks_it;
3994defbdf5Stb
400bd5381c8Stb if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL)
4014defbdf5Stb return -1;
4024defbdf5Stb
4034defbdf5Stb return ASN1_item_i2d((ASN1_VALUE *)addrs, out, my_IPAddrBlocks_it);
4044defbdf5Stb }
4054defbdf5Stb
4064defbdf5Stb struct ipv4_prefix {
4074defbdf5Stb unsigned char addr[4];
4084defbdf5Stb size_t addr_len;
4094defbdf5Stb size_t prefix_len;
4104defbdf5Stb };
4114defbdf5Stb
4124defbdf5Stb struct ipv4_range {
4134defbdf5Stb unsigned char min[4];
4144defbdf5Stb unsigned char max[4];
4154defbdf5Stb };
4164defbdf5Stb
4174defbdf5Stb union ipv4_choice {
4184defbdf5Stb struct ipv4_prefix prefix;
4194defbdf5Stb struct ipv4_range range;
4204defbdf5Stb };
4214defbdf5Stb
4224defbdf5Stb struct ipv6_prefix {
4234defbdf5Stb unsigned char addr[16];
4244defbdf5Stb size_t addr_len;
4254defbdf5Stb size_t prefix_len;
4264defbdf5Stb };
4274defbdf5Stb
4284defbdf5Stb struct ipv6_range {
4294defbdf5Stb unsigned char min[16];
4304defbdf5Stb unsigned char max[16];
4314defbdf5Stb };
4324defbdf5Stb
4334defbdf5Stb union ipv6_choice {
4344defbdf5Stb struct ipv6_prefix prefix;
4354defbdf5Stb struct ipv6_range range;
4364defbdf5Stb };
4374defbdf5Stb
4384defbdf5Stb enum choice_type {
4394defbdf5Stb choice_prefix,
4404defbdf5Stb choice_range,
4414defbdf5Stb choice_inherit,
4424defbdf5Stb choice_last,
4434defbdf5Stb };
4444defbdf5Stb
4454defbdf5Stb union ip {
4464defbdf5Stb union ipv4_choice ipv4;
4474defbdf5Stb union ipv6_choice ipv6;
4484defbdf5Stb };
4494defbdf5Stb
4504defbdf5Stb enum safi {
4514defbdf5Stb safi_none,
4524defbdf5Stb safi_unicast,
4534defbdf5Stb safi_multicast,
4544defbdf5Stb };
4554defbdf5Stb
4564defbdf5Stb struct ip_addr_block {
4574defbdf5Stb unsigned int afi;
4584defbdf5Stb enum safi safi;
4594defbdf5Stb enum choice_type type;
4604defbdf5Stb union ip addr;
4614defbdf5Stb };
4624defbdf5Stb
4634defbdf5Stb struct build_addr_block_test_data {
4644defbdf5Stb char *description;
4654defbdf5Stb struct ip_addr_block addrs[16];
4664defbdf5Stb char der[128];
4674defbdf5Stb size_t der_len;
4684defbdf5Stb int is_canonical;
4694defbdf5Stb int inherits;
4704defbdf5Stb unsigned int afis[4];
4714defbdf5Stb int afi_len;
4724defbdf5Stb };
4734defbdf5Stb
4749dd2bbd1Stb const struct build_addr_block_test_data build_addr_block_tests[] = {
4754defbdf5Stb {
4764defbdf5Stb .description = "RFC 3779, Appendix B, example 1",
4774defbdf5Stb .addrs = {
4784defbdf5Stb {
4794defbdf5Stb .afi = IANA_AFI_IPV4,
4804defbdf5Stb .safi = safi_unicast,
4814defbdf5Stb .type = choice_prefix,
4824defbdf5Stb .addr.ipv4.prefix = {
4834defbdf5Stb .addr = {
4844defbdf5Stb 10, 0, 32,
4854defbdf5Stb },
4864defbdf5Stb .addr_len = 3,
4874defbdf5Stb .prefix_len = 20,
4884defbdf5Stb },
4894defbdf5Stb },
4904defbdf5Stb {
4914defbdf5Stb .afi = IANA_AFI_IPV4,
4924defbdf5Stb .safi = safi_unicast,
4934defbdf5Stb .type = choice_prefix,
4944defbdf5Stb .addr.ipv4.prefix = {
4954defbdf5Stb .addr = {
4964defbdf5Stb 10, 0, 64,
4974defbdf5Stb },
4984defbdf5Stb .addr_len = 3,
4994defbdf5Stb .prefix_len = 24,
5004defbdf5Stb },
5014defbdf5Stb },
5024defbdf5Stb {
5034defbdf5Stb .afi = IANA_AFI_IPV4,
5044defbdf5Stb .safi = safi_unicast,
5054defbdf5Stb .type = choice_prefix,
5064defbdf5Stb .addr.ipv4.prefix = {
5074defbdf5Stb .addr = {
5084defbdf5Stb 10, 1,
5094defbdf5Stb },
5104defbdf5Stb .addr_len = 2,
5114defbdf5Stb .prefix_len = 16,
5124defbdf5Stb },
5134defbdf5Stb },
5144defbdf5Stb {
5154defbdf5Stb .afi = IANA_AFI_IPV4,
5164defbdf5Stb .safi = safi_unicast,
5174defbdf5Stb .type = choice_prefix,
5184defbdf5Stb .addr.ipv4.prefix = {
5194defbdf5Stb .addr = {
5204defbdf5Stb 10, 2, 48,
5214defbdf5Stb },
5224defbdf5Stb .addr_len = 3,
5234defbdf5Stb .prefix_len = 20,
5244defbdf5Stb },
5254defbdf5Stb },
5264defbdf5Stb {
5274defbdf5Stb .afi = IANA_AFI_IPV4,
5284defbdf5Stb .safi = safi_unicast,
5294defbdf5Stb .type = choice_prefix,
5304defbdf5Stb .addr.ipv4.prefix = {
5314defbdf5Stb .addr = {
5324defbdf5Stb 10, 2, 64,
5334defbdf5Stb },
5344defbdf5Stb .addr_len = 3,
5354defbdf5Stb .prefix_len = 24,
5364defbdf5Stb },
5374defbdf5Stb },
5384defbdf5Stb {
5394defbdf5Stb .afi = IANA_AFI_IPV4,
5404defbdf5Stb .safi = safi_unicast,
5414defbdf5Stb .type = choice_prefix,
5424defbdf5Stb .addr.ipv4.prefix = {
5434defbdf5Stb .addr = {
5444defbdf5Stb 10, 3,
5454defbdf5Stb },
5464defbdf5Stb .addr_len = 2,
5474defbdf5Stb .prefix_len = 16,
5484defbdf5Stb },
5494defbdf5Stb },
5504defbdf5Stb {
5514defbdf5Stb .afi = IANA_AFI_IPV6,
5524defbdf5Stb .safi = safi_none,
5534defbdf5Stb .type = choice_inherit,
5544defbdf5Stb },
5554defbdf5Stb {
5564defbdf5Stb .type = choice_last,
5574defbdf5Stb },
5584defbdf5Stb },
5594defbdf5Stb .der = {
5604defbdf5Stb 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01,
5614defbdf5Stb 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00,
5624defbdf5Stb 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03,
5634defbdf5Stb 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04,
5644defbdf5Stb 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a,
5654defbdf5Stb 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30,
5664defbdf5Stb 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00,
5674defbdf5Stb },
5684defbdf5Stb .der_len = 55,
5694defbdf5Stb .is_canonical = 0,
5704defbdf5Stb .inherits = 1,
5714defbdf5Stb .afis = {
5724defbdf5Stb IANA_AFI_IPV4, IANA_AFI_IPV6,
5734defbdf5Stb },
5744defbdf5Stb .afi_len = 2,
5754defbdf5Stb },
5764defbdf5Stb {
5774defbdf5Stb .description = "RFC 3779, Appendix B, example 1 canonical",
5784defbdf5Stb .addrs = {
5794defbdf5Stb {
5804defbdf5Stb .afi = IANA_AFI_IPV4,
5814defbdf5Stb .safi = safi_unicast,
5824defbdf5Stb .type = choice_prefix,
5834defbdf5Stb .addr.ipv4.prefix = {
5844defbdf5Stb .addr = {
5854defbdf5Stb 10, 0, 32,
5864defbdf5Stb },
5874defbdf5Stb .addr_len = 3,
5884defbdf5Stb .prefix_len = 20,
5894defbdf5Stb },
5904defbdf5Stb },
5914defbdf5Stb {
5924defbdf5Stb .afi = IANA_AFI_IPV4,
5934defbdf5Stb .safi = safi_unicast,
5944defbdf5Stb .type = choice_prefix,
5954defbdf5Stb .addr.ipv4.prefix = {
5964defbdf5Stb .addr = {
5974defbdf5Stb 10, 0, 64,
5984defbdf5Stb },
5994defbdf5Stb .addr_len = 3,
6004defbdf5Stb .prefix_len = 24,
6014defbdf5Stb },
6024defbdf5Stb },
6034defbdf5Stb {
6044defbdf5Stb .afi = IANA_AFI_IPV4,
6054defbdf5Stb .safi = safi_unicast,
6064defbdf5Stb .type = choice_prefix,
6074defbdf5Stb .addr.ipv4.prefix = {
6084defbdf5Stb .addr = {
6094defbdf5Stb 10, 1,
6104defbdf5Stb },
6114defbdf5Stb .addr_len = 2,
6124defbdf5Stb .prefix_len = 16,
6134defbdf5Stb },
6144defbdf5Stb },
6154defbdf5Stb {
6164defbdf5Stb .afi = IANA_AFI_IPV4,
6174defbdf5Stb .safi = safi_unicast,
6184defbdf5Stb .type = choice_range,
6194defbdf5Stb .addr.ipv4.range = {
6204defbdf5Stb .min = {
6214defbdf5Stb 10, 2, 48, 00,
6224defbdf5Stb },
6234defbdf5Stb .max = {
6244defbdf5Stb 10, 2, 64, 255,
6254defbdf5Stb },
6264defbdf5Stb },
6274defbdf5Stb },
6284defbdf5Stb {
6294defbdf5Stb .afi = IANA_AFI_IPV4,
6304defbdf5Stb .safi = safi_unicast,
6314defbdf5Stb .type = choice_prefix,
6324defbdf5Stb .addr.ipv4.prefix = {
6334defbdf5Stb .addr = {
6344defbdf5Stb 10, 3,
6354defbdf5Stb },
6364defbdf5Stb .addr_len = 2,
6374defbdf5Stb .prefix_len = 16,
6384defbdf5Stb },
6394defbdf5Stb },
6404defbdf5Stb {
6414defbdf5Stb .afi = IANA_AFI_IPV6,
6424defbdf5Stb .safi = safi_none,
6434defbdf5Stb .type = choice_inherit,
6444defbdf5Stb },
6454defbdf5Stb {
6464defbdf5Stb .type = choice_last,
6474defbdf5Stb },
6484defbdf5Stb },
6494defbdf5Stb .der = {
6504defbdf5Stb 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01,
6514defbdf5Stb 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00,
6524defbdf5Stb 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03,
6534defbdf5Stb 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04,
6544defbdf5Stb 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a,
6554defbdf5Stb 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30,
6564defbdf5Stb 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00,
6574defbdf5Stb },
6584defbdf5Stb .der_len = 55,
6594defbdf5Stb .is_canonical = 1,
6604defbdf5Stb .inherits = 1,
6614defbdf5Stb .afis = {
6624defbdf5Stb IANA_AFI_IPV4, IANA_AFI_IPV6,
6634defbdf5Stb },
6644defbdf5Stb .afi_len = 2,
6654defbdf5Stb },
6664defbdf5Stb {
6674defbdf5Stb .description = "RFC 3779, Appendix B, example 2",
6684defbdf5Stb .addrs = {
6694defbdf5Stb {
6704defbdf5Stb .afi = IANA_AFI_IPV6,
6714defbdf5Stb .safi = safi_none,
6724defbdf5Stb .type = choice_prefix,
6734defbdf5Stb .addr.ipv6.prefix = {
6744defbdf5Stb .addr = {
6754defbdf5Stb 0x20, 0x01, 0x00, 0x00,
6764defbdf5Stb 0x00, 0x02,
6774defbdf5Stb },
6784defbdf5Stb .addr_len = 6,
6794defbdf5Stb .prefix_len = 48,
6804defbdf5Stb },
6814defbdf5Stb },
6824defbdf5Stb {
6834defbdf5Stb .afi = IANA_AFI_IPV4,
6844defbdf5Stb .safi = safi_unicast,
6854defbdf5Stb .type = choice_prefix,
6864defbdf5Stb .addr.ipv4.prefix = {
6874defbdf5Stb .addr = {
6884defbdf5Stb 10,
6894defbdf5Stb },
6904defbdf5Stb .addr_len = 1,
6914defbdf5Stb .prefix_len = 8,
6924defbdf5Stb },
6934defbdf5Stb },
6944defbdf5Stb {
6954defbdf5Stb .afi = IANA_AFI_IPV4,
6964defbdf5Stb .safi = safi_unicast,
6974defbdf5Stb .type = choice_prefix,
6984defbdf5Stb .addr.ipv4.prefix = {
6994defbdf5Stb .addr = {
7004defbdf5Stb 172, 16,
7014defbdf5Stb },
7024defbdf5Stb .addr_len = 2,
7034defbdf5Stb .prefix_len = 12,
7044defbdf5Stb },
7054defbdf5Stb },
7064defbdf5Stb {
7074defbdf5Stb .afi = IANA_AFI_IPV4,
7084defbdf5Stb .safi = safi_multicast,
7094defbdf5Stb .type = choice_inherit,
7104defbdf5Stb },
7114defbdf5Stb {
7124defbdf5Stb .type = choice_last,
7134defbdf5Stb },
7144defbdf5Stb },
7154defbdf5Stb .der = {
7164defbdf5Stb 0x30, 0x2c, 0x30, 0x10, 0x04, 0x03, 0x00, 0x01,
7174defbdf5Stb 0x01, 0x30, 0x09, 0x03, 0x02, 0x00, 0x0a, 0x03,
7184defbdf5Stb 0x03, 0x04, 0xac, 0x10, 0x30, 0x07, 0x04, 0x03,
7194defbdf5Stb 0x00, 0x01, 0x02, 0x05, 0x00, 0x30, 0x0f, 0x04,
7204defbdf5Stb 0x02, 0x00, 0x02, 0x30, 0x09, 0x03, 0x07, 0x00,
7214defbdf5Stb 0x20, 0x01, 0x00, 0x00, 0x00, 0x02,
7224defbdf5Stb },
7234defbdf5Stb .der_len = 46,
7244defbdf5Stb .is_canonical = 0,
7254defbdf5Stb .inherits = 1,
7264defbdf5Stb .afis = {
7274defbdf5Stb IANA_AFI_IPV4, IANA_AFI_IPV4,
7284defbdf5Stb },
7294defbdf5Stb .afi_len = 2,
7304defbdf5Stb },
7314defbdf5Stb {
7324defbdf5Stb .description = "Range should be prefix 127/8",
7334defbdf5Stb .addrs = {
7344defbdf5Stb {
7354defbdf5Stb .afi = IANA_AFI_IPV4,
7364defbdf5Stb .safi = safi_none,
7374defbdf5Stb .type = choice_range,
7384defbdf5Stb .addr.ipv4.range = {
7394defbdf5Stb .min = {
7404defbdf5Stb 127, 0, 0, 0,
7414defbdf5Stb },
7424defbdf5Stb .max = {
7434defbdf5Stb 127, 255, 255, 255,
7444defbdf5Stb },
7454defbdf5Stb },
7464defbdf5Stb },
7474defbdf5Stb {
7484defbdf5Stb .type = choice_last,
7494defbdf5Stb },
7504defbdf5Stb },
7514defbdf5Stb .der = {
7524defbdf5Stb 0x30, 0x0c, 0x30, 0x0a, 0x04, 0x02, 0x00, 0x01,
7534defbdf5Stb 0x30, 0x04, 0x03, 0x02, 0x00, 0x7f,
7544defbdf5Stb },
7554defbdf5Stb .der_len = 14,
7564defbdf5Stb .is_canonical = 1,
7574defbdf5Stb .inherits = 0,
7584defbdf5Stb .afis = {
7594defbdf5Stb IANA_AFI_IPV4,
7604defbdf5Stb },
7614defbdf5Stb .afi_len = 1,
7624defbdf5Stb },
7634defbdf5Stb };
7644defbdf5Stb
7654defbdf5Stb const size_t N_BUILD_ADDR_BLOCK_TESTS =
7664defbdf5Stb sizeof(build_addr_block_tests) / sizeof(build_addr_block_tests[0]);
7674defbdf5Stb
7684defbdf5Stb static unsigned int *
addr_block_get_safi(const struct ip_addr_block * addr)7694defbdf5Stb addr_block_get_safi(const struct ip_addr_block *addr)
7704defbdf5Stb {
7714defbdf5Stb static unsigned int safi;
7724defbdf5Stb
7734defbdf5Stb switch (addr->safi) {
7744defbdf5Stb case safi_none:
7754defbdf5Stb return NULL;
7764defbdf5Stb case safi_unicast:
7774defbdf5Stb safi = 1;
7784defbdf5Stb break;
7794defbdf5Stb case safi_multicast:
7804defbdf5Stb safi = 2;
7814defbdf5Stb break;
7824defbdf5Stb }
7834defbdf5Stb
7844defbdf5Stb return &safi;
7854defbdf5Stb }
7864defbdf5Stb
7874defbdf5Stb static int
addr_block_add_ipv4_addr(IPAddrBlocks * block,enum choice_type type,const union ipv4_choice * ipv4,unsigned int * safi)7884defbdf5Stb addr_block_add_ipv4_addr(IPAddrBlocks *block, enum choice_type type,
7899dd2bbd1Stb const union ipv4_choice *ipv4, unsigned int *safi)
7904defbdf5Stb {
7919dd2bbd1Stb unsigned char addr[RAW_ADDRESS_SIZE] = {0};
7929dd2bbd1Stb unsigned char min[RAW_ADDRESS_SIZE];
7939dd2bbd1Stb unsigned char max[RAW_ADDRESS_SIZE];
7949dd2bbd1Stb
7954defbdf5Stb switch (type) {
7964defbdf5Stb case choice_prefix:
7979dd2bbd1Stb memcpy(addr, ipv4->prefix.addr, ipv4->prefix.addr_len);
7984defbdf5Stb return X509v3_addr_add_prefix(block, IANA_AFI_IPV4, safi,
7999dd2bbd1Stb addr, ipv4->prefix.prefix_len);
8004defbdf5Stb case choice_range:
8019dd2bbd1Stb memcpy(min, ipv4->range.min, sizeof(ipv4->range.min));
8029dd2bbd1Stb memcpy(max, ipv4->range.max, sizeof(ipv4->range.max));
8034defbdf5Stb return X509v3_addr_add_range(block, IANA_AFI_IPV4, safi,
8049dd2bbd1Stb min, max);
8054defbdf5Stb case choice_inherit:
8064defbdf5Stb return X509v3_addr_add_inherit(block, IANA_AFI_IPV4, safi);
8074defbdf5Stb case choice_last:
8084defbdf5Stb default:
8094defbdf5Stb return 0;
8104defbdf5Stb }
8114defbdf5Stb }
8124defbdf5Stb
8134defbdf5Stb static int
addr_block_add_ipv6_addr(IPAddrBlocks * block,enum choice_type type,const union ipv6_choice * ipv6,unsigned int * safi)8144defbdf5Stb addr_block_add_ipv6_addr(IPAddrBlocks *block, enum choice_type type,
8159dd2bbd1Stb const union ipv6_choice *ipv6, unsigned int *safi)
8164defbdf5Stb {
8179dd2bbd1Stb unsigned char addr[RAW_ADDRESS_SIZE] = {0};
8189dd2bbd1Stb unsigned char min[RAW_ADDRESS_SIZE];
8199dd2bbd1Stb unsigned char max[RAW_ADDRESS_SIZE];
8209dd2bbd1Stb
8214defbdf5Stb switch (type) {
8224defbdf5Stb case choice_prefix:
8239dd2bbd1Stb memcpy(addr, ipv6->prefix.addr, ipv6->prefix.addr_len);
8244defbdf5Stb return X509v3_addr_add_prefix(block, IANA_AFI_IPV6, safi,
8259dd2bbd1Stb addr, ipv6->prefix.prefix_len);
8264defbdf5Stb case choice_range:
8279dd2bbd1Stb memcpy(min, ipv6->range.min, sizeof(ipv6->range.min));
8289dd2bbd1Stb memcpy(max, ipv6->range.max, sizeof(ipv6->range.max));
8294defbdf5Stb return X509v3_addr_add_range(block, IANA_AFI_IPV6, safi,
8309dd2bbd1Stb min, max);
8314defbdf5Stb case choice_inherit:
8324defbdf5Stb return X509v3_addr_add_inherit(block, IANA_AFI_IPV6, safi);
8334defbdf5Stb case choice_last:
8344defbdf5Stb default:
8354defbdf5Stb return 0;
8364defbdf5Stb }
8374defbdf5Stb }
8384defbdf5Stb
8394defbdf5Stb static int
addr_block_add_addrs(IPAddrBlocks * block,const struct ip_addr_block addrs[])8409dd2bbd1Stb addr_block_add_addrs(IPAddrBlocks *block, const struct ip_addr_block addrs[])
8414defbdf5Stb {
8429dd2bbd1Stb const struct ip_addr_block *addr;
8434defbdf5Stb unsigned int *safi;
8444defbdf5Stb
8454defbdf5Stb for (addr = &addrs[0]; addr->type != choice_last; addr++) {
8464defbdf5Stb safi = addr_block_get_safi(addr);
8474defbdf5Stb switch (addr->afi) {
8484defbdf5Stb case IANA_AFI_IPV4:
8494defbdf5Stb if (!addr_block_add_ipv4_addr(block, addr->type,
8504defbdf5Stb &addr->addr.ipv4, safi))
8514defbdf5Stb return 0;
8524defbdf5Stb break;
8534defbdf5Stb case IANA_AFI_IPV6:
8544defbdf5Stb if (!addr_block_add_ipv6_addr(block, addr->type,
8554defbdf5Stb &addr->addr.ipv6, safi))
8564defbdf5Stb return 0;
8574defbdf5Stb break;
8584defbdf5Stb default:
8594defbdf5Stb fprintf(stderr, "%s: corrupt test data", __func__);
8604defbdf5Stb exit(1);
8614defbdf5Stb }
8624defbdf5Stb }
8634defbdf5Stb
8644defbdf5Stb return 1;
8654defbdf5Stb }
8664defbdf5Stb
8674defbdf5Stb static int
build_addr_block_test(const struct build_addr_block_test_data * test)8689dd2bbd1Stb build_addr_block_test(const struct build_addr_block_test_data *test)
8694defbdf5Stb {
870f911aa70Stb IPAddrBlocks *addrs = NULL, *parsed = NULL;
871f911aa70Stb const unsigned char *p;
8724defbdf5Stb unsigned char *out = NULL;
8734defbdf5Stb int out_len;
8744defbdf5Stb int i;
8754defbdf5Stb int memcmp_failed = 1;
8764defbdf5Stb int failed = 1;
8774defbdf5Stb
8784defbdf5Stb if ((addrs = IPAddrBlocks_new()) == NULL)
8794defbdf5Stb goto err;
8804defbdf5Stb
8814defbdf5Stb if (!addr_block_add_addrs(addrs, test->addrs))
8824defbdf5Stb goto err;
8834defbdf5Stb
8844defbdf5Stb if (X509v3_addr_is_canonical(addrs) != test->is_canonical) {
8854defbdf5Stb fprintf(stderr, "%s: \"%s\" X509v3_addr_is_canonical not %d\n",
8864defbdf5Stb __func__, test->description, test->is_canonical);
8874defbdf5Stb goto err;
8884defbdf5Stb }
8894defbdf5Stb
8904defbdf5Stb if (!X509v3_addr_canonize(addrs)) {
8914defbdf5Stb fprintf(stderr, "%s: \"%s\" failed to canonize\n",
8924defbdf5Stb __func__, test->description);
8934defbdf5Stb goto err;
8944defbdf5Stb }
8954defbdf5Stb
8964defbdf5Stb if (!X509v3_addr_is_canonical(addrs)) {
8974defbdf5Stb fprintf(stderr, "%s: \"%s\" canonization wasn't canonical\n",
8984defbdf5Stb __func__, test->description);
8994defbdf5Stb goto err;
9004defbdf5Stb }
9014defbdf5Stb
9024defbdf5Stb if ((out_len = i2d_IPAddrBlocks(addrs, &out)) <= 0) {
9034defbdf5Stb fprintf(stderr, "%s: \"%s\" i2d_IPAddrBlocks failed\n",
9044defbdf5Stb __func__, test->description);
9054defbdf5Stb goto err;
9064defbdf5Stb }
9074defbdf5Stb
9084defbdf5Stb memcmp_failed = (size_t)out_len != test->der_len;
9094defbdf5Stb if (!memcmp_failed)
9104defbdf5Stb memcmp_failed = memcmp(out, test->der, test->der_len);
9114defbdf5Stb if (memcmp_failed) {
9124defbdf5Stb report_hexdump(__func__, test->description, "memcmp DER failed",
9134defbdf5Stb test->der, test->der_len, out, out_len);
9144defbdf5Stb goto err;
9154defbdf5Stb }
9164defbdf5Stb
9174defbdf5Stb if (X509v3_addr_inherits(addrs) != test->inherits) {
9184defbdf5Stb fprintf(stderr, "%s: \"%s\" X509v3_addr_inherits not %d\n",
9194defbdf5Stb __func__, test->description, test->inherits);
9204defbdf5Stb goto err;
9214defbdf5Stb }
9224defbdf5Stb
9234defbdf5Stb for (i = 0; i < sk_IPAddressFamily_num(addrs) && i < test->afi_len; i++) {
9244defbdf5Stb IPAddressFamily *family;
9254defbdf5Stb unsigned int afi;
9264defbdf5Stb
9274defbdf5Stb family = sk_IPAddressFamily_value(addrs, i);
9284defbdf5Stb
9294defbdf5Stb if ((afi = X509v3_addr_get_afi(family)) == 0) {
9304defbdf5Stb fprintf(stderr, "%s: \"%s\" X509v3_addr_get_afi"
9314defbdf5Stb " failed\n", __func__, test->description);
9324defbdf5Stb goto err;
9334defbdf5Stb }
9344defbdf5Stb if (test->afis[i] != afi){
9354defbdf5Stb fprintf(stderr, "%s: \"%s\" afi[%d] mismatch. "
9364defbdf5Stb "want: %u, got: %u\n", __func__,
9374defbdf5Stb test->description, i, test->afis[i], afi);
9384defbdf5Stb goto err;
9394defbdf5Stb }
9404defbdf5Stb }
9414defbdf5Stb if (i != test->afi_len) {
9424defbdf5Stb fprintf(stderr, "%s: \"%s\" checked %d afis, expected %d\n",
9434defbdf5Stb __func__, test->description, i, test->afi_len);
9444defbdf5Stb goto err;
9454defbdf5Stb }
9464defbdf5Stb
947f911aa70Stb p = test->der;
948f911aa70Stb if ((parsed = d2i_IPAddrBlocks(NULL, &p, test->der_len)) == NULL) {
949f911aa70Stb fprintf(stderr, "%s: \"%s\" d2i_IPAddrBlocks failed\n",
950f911aa70Stb __func__, test->description);
951f911aa70Stb goto err;
952f911aa70Stb }
953f911aa70Stb if (!X509v3_addr_is_canonical(parsed)) {
954f911aa70Stb fprintf(stderr, "%s: \"%s\" parsed AddrBlocks isn't canonical\n",
955f911aa70Stb __func__, test->description);
956f911aa70Stb goto err;
957f911aa70Stb }
958f911aa70Stb /* Can't compare IPAddrBlocks with inheritance. */
959f911aa70Stb if (!X509v3_addr_inherits(addrs) && !X509v3_addr_inherits(parsed)) {
960f911aa70Stb if (!X509v3_addr_subset(addrs, parsed)) {
961f911aa70Stb fprintf(stderr, "%s: \"%s\" addrs not subset of parsed\n",
962f911aa70Stb __func__, test->description);
963f911aa70Stb }
964f911aa70Stb if (!X509v3_addr_subset(parsed, addrs)) {
965f911aa70Stb fprintf(stderr, "%s: \"%s\" parsed not subset of addrs\n",
966f911aa70Stb __func__, test->description);
967f911aa70Stb }
968f911aa70Stb }
969f911aa70Stb
9704defbdf5Stb failed = 0;
9714defbdf5Stb
9724defbdf5Stb err:
9734defbdf5Stb IPAddrBlocks_free(addrs);
974f911aa70Stb IPAddrBlocks_free(parsed);
9754defbdf5Stb free(out);
9764defbdf5Stb
9774defbdf5Stb return failed;
9784defbdf5Stb }
9794defbdf5Stb
9804defbdf5Stb static int
run_IPAddrBlock_tests(void)9814defbdf5Stb run_IPAddrBlock_tests(void)
9824defbdf5Stb {
9834defbdf5Stb size_t i;
9844defbdf5Stb int failed = 0;
9854defbdf5Stb
9864defbdf5Stb for (i = 0; i < N_BUILD_ADDR_BLOCK_TESTS; i++)
9874defbdf5Stb failed |= build_addr_block_test(&build_addr_block_tests[i]);
9884defbdf5Stb
9894defbdf5Stb return failed;
9904defbdf5Stb }
9914defbdf5Stb
9924defbdf5Stb struct asid_or_range {
9934defbdf5Stb int type;
9944defbdf5Stb int inherit;
9954defbdf5Stb const unsigned char *min;
9964defbdf5Stb const unsigned char *max;
9974defbdf5Stb };
9984defbdf5Stb
9994defbdf5Stb struct ASIdentifiers_build_test {
10004defbdf5Stb const char *description;
10014defbdf5Stb int should_build;
10024defbdf5Stb int inherits;
10034defbdf5Stb int canonical;
10044defbdf5Stb int should_canonize;
10054defbdf5Stb struct asid_or_range delegations[8];
10064defbdf5Stb const unsigned char der[128];
10074defbdf5Stb size_t der_len;
10084defbdf5Stb };
10094defbdf5Stb
10104defbdf5Stb /* Sentinel value used for marking the end of the delegations table. */
10114defbdf5Stb #define V3_ASID_END -1
10124defbdf5Stb
10134defbdf5Stb const struct ASIdentifiers_build_test ASIdentifiers_build_data[] = {
10144defbdf5Stb {
10154defbdf5Stb .description = "RFC 3779, Appendix C",
10164defbdf5Stb .should_build = 1,
10174defbdf5Stb .inherits = 1,
10184defbdf5Stb .canonical = 1,
10194defbdf5Stb .delegations = {
10204defbdf5Stb {
10214defbdf5Stb .type = V3_ASID_ASNUM,
10224defbdf5Stb .inherit = 0,
10234defbdf5Stb .min = "135",
10244defbdf5Stb .max = NULL,
10254defbdf5Stb },
10264defbdf5Stb {
10274defbdf5Stb .type = V3_ASID_ASNUM,
10284defbdf5Stb .inherit = 0,
10294defbdf5Stb .min = "3000",
10304defbdf5Stb .max = "3999",
10314defbdf5Stb },
10324defbdf5Stb {
10334defbdf5Stb .type = V3_ASID_ASNUM,
10344defbdf5Stb .inherit = 0,
10354defbdf5Stb .min = "5001",
10364defbdf5Stb .max = NULL,
10374defbdf5Stb },
10384defbdf5Stb {
10394defbdf5Stb .type = V3_ASID_RDI,
10404defbdf5Stb .inherit = 1,
10414defbdf5Stb .min = NULL,
10424defbdf5Stb .max = NULL,
10434defbdf5Stb },
10444defbdf5Stb {
10454defbdf5Stb .type = V3_ASID_END,
10464defbdf5Stb },
10474defbdf5Stb },
10484defbdf5Stb .der = {
10494defbdf5Stb 0x30, 0x1a, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
10504defbdf5Stb 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
10514defbdf5Stb 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
10524defbdf5Stb 0xa1, 0x02, 0x05, 0x00,
10534defbdf5Stb },
10544defbdf5Stb .der_len = 28,
10554defbdf5Stb },
10564defbdf5Stb {
10574defbdf5Stb .description = "RFC 3779, Appendix C without rdi",
10584defbdf5Stb .should_build = 1,
10594defbdf5Stb .inherits = 0,
10604defbdf5Stb .canonical = 1,
10614defbdf5Stb .delegations = {
10624defbdf5Stb {
10634defbdf5Stb .type = V3_ASID_ASNUM,
10644defbdf5Stb .inherit = 0,
10654defbdf5Stb .min = "135",
10664defbdf5Stb .max = NULL,
10674defbdf5Stb },
10684defbdf5Stb {
10694defbdf5Stb .type = V3_ASID_ASNUM,
10704defbdf5Stb .inherit = 0,
10714defbdf5Stb .min = "3000",
10724defbdf5Stb .max = "3999",
10734defbdf5Stb },
10744defbdf5Stb {
10754defbdf5Stb .type = V3_ASID_ASNUM,
10764defbdf5Stb .inherit = 0,
10774defbdf5Stb .min = "5001",
10784defbdf5Stb .max = NULL,
10794defbdf5Stb },
10804defbdf5Stb {
10814defbdf5Stb .type = V3_ASID_END,
10824defbdf5Stb },
10834defbdf5Stb },
10844defbdf5Stb .der = {
10854defbdf5Stb 0x30, 0x16, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
10864defbdf5Stb 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
10874defbdf5Stb 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
10884defbdf5Stb },
10894defbdf5Stb .der_len = 24,
10904defbdf5Stb },
10914defbdf5Stb {
10924defbdf5Stb .description = "RFC 3779, Appendix C variant",
10934defbdf5Stb .should_build = 1,
10944defbdf5Stb .inherits = 0,
10954defbdf5Stb .canonical = 1,
10964defbdf5Stb .delegations = {
10974defbdf5Stb {
10984defbdf5Stb .type = V3_ASID_ASNUM,
10994defbdf5Stb .inherit = 0,
11004defbdf5Stb .min = "135",
11014defbdf5Stb .max = NULL,
11024defbdf5Stb },
11034defbdf5Stb {
11044defbdf5Stb .type = V3_ASID_ASNUM,
11054defbdf5Stb .inherit = 0,
11064defbdf5Stb .min = "3000",
11074defbdf5Stb .max = "3999",
11084defbdf5Stb },
11094defbdf5Stb {
11104defbdf5Stb .type = V3_ASID_ASNUM,
11114defbdf5Stb .inherit = 0,
11124defbdf5Stb .min = "5001",
11134defbdf5Stb .max = NULL,
11144defbdf5Stb },
11154defbdf5Stb {
11164defbdf5Stb .type = V3_ASID_RDI,
11174defbdf5Stb .inherit = 0,
11184defbdf5Stb .min = "135",
11194defbdf5Stb .max = NULL,
11204defbdf5Stb },
11214defbdf5Stb {
11224defbdf5Stb .type = V3_ASID_RDI,
11234defbdf5Stb .inherit = 0,
11244defbdf5Stb .min = "3000",
11254defbdf5Stb .max = "3999",
11264defbdf5Stb },
11274defbdf5Stb {
11284defbdf5Stb .type = V3_ASID_RDI,
11294defbdf5Stb .inherit = 0,
11304defbdf5Stb .min = "5001",
11314defbdf5Stb .max = NULL,
11324defbdf5Stb },
11334defbdf5Stb {
11344defbdf5Stb .type = V3_ASID_END,
11354defbdf5Stb },
11364defbdf5Stb },
11374defbdf5Stb .der = {
11384defbdf5Stb 0x30, 0x2c, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02,
11394defbdf5Stb 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8,
11404defbdf5Stb 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
11414defbdf5Stb 0xa1, 0x14, 0x30, 0x12, 0x02, 0x02, 0x00, 0x87,
11424defbdf5Stb 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 0x02, 0x02,
11434defbdf5Stb 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89,
11444defbdf5Stb },
11454defbdf5Stb .der_len = 46,
11464defbdf5Stb },
11474defbdf5Stb {
11484defbdf5Stb .description = "inherit only",
11494defbdf5Stb .should_build = 1,
11504defbdf5Stb .inherits = 1,
11514defbdf5Stb .canonical = 1,
11524defbdf5Stb .delegations = {
11534defbdf5Stb {
11544defbdf5Stb .type = V3_ASID_ASNUM,
11554defbdf5Stb .inherit = 1,
11564defbdf5Stb },
11574defbdf5Stb {
11584defbdf5Stb .type = V3_ASID_RDI,
11594defbdf5Stb .inherit = 1,
11604defbdf5Stb },
11614defbdf5Stb {
11624defbdf5Stb .type = V3_ASID_END,
11634defbdf5Stb },
11644defbdf5Stb },
11654defbdf5Stb .der = {
11664defbdf5Stb 0x30, 0x08, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x02,
11674defbdf5Stb 0x05, 0x00,
11684defbdf5Stb },
11694defbdf5Stb .der_len = 10,
11704defbdf5Stb },
11714defbdf5Stb {
11724defbdf5Stb .description = "adjacent unsorted ranges are merged",
11734defbdf5Stb .should_build = 1,
11744defbdf5Stb .inherits = 0,
11754defbdf5Stb .canonical = 0,
11764defbdf5Stb .should_canonize = 1,
11774defbdf5Stb .delegations = {
11784defbdf5Stb {
11794defbdf5Stb .type = V3_ASID_RDI,
11804defbdf5Stb .inherit = 0,
11814defbdf5Stb .min = "27",
11824defbdf5Stb .max = NULL,
11834defbdf5Stb },
11844defbdf5Stb {
11854defbdf5Stb .type = V3_ASID_RDI,
11864defbdf5Stb .inherit = 0,
11874defbdf5Stb .min = "28",
11884defbdf5Stb .max = "57",
11894defbdf5Stb },
11904defbdf5Stb {
11914defbdf5Stb .type = V3_ASID_RDI,
11924defbdf5Stb .inherit = 0,
11934defbdf5Stb .min = "66",
11944defbdf5Stb .max = "68",
11954defbdf5Stb },
11964defbdf5Stb {
11974defbdf5Stb .type = V3_ASID_RDI,
11984defbdf5Stb .inherit = 0,
11994defbdf5Stb .min = "58",
12004defbdf5Stb .max = "63",
12014defbdf5Stb },
12024defbdf5Stb {
12034defbdf5Stb .type = V3_ASID_RDI,
12044defbdf5Stb .inherit = 0,
12054defbdf5Stb .min = "64",
12064defbdf5Stb .max = NULL,
12074defbdf5Stb },
12084defbdf5Stb {
12094defbdf5Stb .type = V3_ASID_END,
12104defbdf5Stb },
12114defbdf5Stb },
12124defbdf5Stb .der = {
12134defbdf5Stb 0x30, 0x14, 0xa1, 0x12, 0x30, 0x10, 0x30, 0x06,
12144defbdf5Stb 0x02, 0x01, 0x1b, 0x02, 0x01, 0x40, 0x30, 0x06,
12154defbdf5Stb 0x02, 0x01, 0x42, 0x02, 0x01, 0x44,
12164defbdf5Stb },
12174defbdf5Stb .der_len = 22,
12184defbdf5Stb },
12194defbdf5Stb {
12204defbdf5Stb .description = "range of length 0",
12214defbdf5Stb .should_build = 1,
12224defbdf5Stb .inherits = 1,
12234defbdf5Stb .canonical = 1,
12244defbdf5Stb .should_canonize = 1,
12254defbdf5Stb .delegations = {
12264defbdf5Stb {
12274defbdf5Stb .type = V3_ASID_RDI,
12284defbdf5Stb .inherit = 0,
12294defbdf5Stb .min = "27",
12304defbdf5Stb .max = "27",
12314defbdf5Stb },
12324defbdf5Stb {
12334defbdf5Stb .type = V3_ASID_ASNUM,
12344defbdf5Stb .inherit = 1,
12354defbdf5Stb },
12364defbdf5Stb {
12374defbdf5Stb .type = V3_ASID_END,
12384defbdf5Stb },
12394defbdf5Stb },
12404defbdf5Stb .der = {
12414defbdf5Stb 0x30, 0x10, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x0a,
12424defbdf5Stb 0x30, 0x08, 0x30, 0x06, 0x02, 0x01, 0x1b, 0x02,
12434defbdf5Stb 0x01, 0x1b,
12444defbdf5Stb },
12454defbdf5Stb .der_len = 18,
12464defbdf5Stb },
12474defbdf5Stb {
12484defbdf5Stb .description = "reversed range doesn't canonize",
12494defbdf5Stb .should_build = 1,
12504defbdf5Stb .inherits = 0,
12514defbdf5Stb .canonical = 0,
12524defbdf5Stb .should_canonize = 0,
12534defbdf5Stb .delegations = {
12544defbdf5Stb {
12554defbdf5Stb .type = V3_ASID_ASNUM,
12564defbdf5Stb .inherit = 0,
12574defbdf5Stb .min = "57",
12584defbdf5Stb .max = "42",
12594defbdf5Stb },
12604defbdf5Stb {
12614defbdf5Stb .type = V3_ASID_END,
12624defbdf5Stb },
12634defbdf5Stb },
12644defbdf5Stb },
12654defbdf5Stb {
12664defbdf5Stb .description = "overlapping ranges don't canonize",
12674defbdf5Stb .should_build = 1,
12684defbdf5Stb .inherits = 0,
12694defbdf5Stb .canonical = 0,
12704defbdf5Stb .should_canonize = 0,
12714defbdf5Stb .delegations = {
12724defbdf5Stb {
12734defbdf5Stb .type = V3_ASID_ASNUM,
12744defbdf5Stb .inherit = 0,
12754defbdf5Stb .min = "42",
12764defbdf5Stb .max = "57",
12774defbdf5Stb },
12784defbdf5Stb {
12794defbdf5Stb .type = V3_ASID_ASNUM,
12804defbdf5Stb .inherit = 0,
12814defbdf5Stb .min = "57",
12824defbdf5Stb .max = "60",
12834defbdf5Stb },
12844defbdf5Stb {
12854defbdf5Stb .type = V3_ASID_END,
12864defbdf5Stb },
12874defbdf5Stb },
12884defbdf5Stb },
12894defbdf5Stb {
12904defbdf5Stb .description = "reversed interior range doesn't canonize",
12914defbdf5Stb .should_build = 1,
12924defbdf5Stb .inherits = 0,
12934defbdf5Stb .canonical = 0,
12944defbdf5Stb .should_canonize = 0,
12954defbdf5Stb .delegations = {
12964defbdf5Stb {
12974defbdf5Stb .type = V3_ASID_ASNUM,
12984defbdf5Stb .inherit = 0,
12994defbdf5Stb .min = "1",
13004defbdf5Stb .max = "2",
13014defbdf5Stb },
13024defbdf5Stb {
13034defbdf5Stb .type = V3_ASID_ASNUM,
13044defbdf5Stb .inherit = 0,
13054defbdf5Stb .min = "57",
13064defbdf5Stb .max = "42",
13074defbdf5Stb },
13084defbdf5Stb {
13094defbdf5Stb .type = V3_ASID_ASNUM,
13104defbdf5Stb .inherit = 0,
13114defbdf5Stb .min = "65523",
13124defbdf5Stb .max = "65535",
13134defbdf5Stb },
13144defbdf5Stb {
13154defbdf5Stb .type = V3_ASID_END,
13164defbdf5Stb },
13174defbdf5Stb },
13184defbdf5Stb },
13194defbdf5Stb {
13204defbdf5Stb .description = "can't inherit and add AS ids",
13214defbdf5Stb .should_build = 0,
13224defbdf5Stb .inherits = 0,
13234defbdf5Stb .canonical = 0,
13244defbdf5Stb .should_canonize = 0,
13254defbdf5Stb .delegations = {
13264defbdf5Stb {
13274defbdf5Stb .type = V3_ASID_ASNUM,
13284defbdf5Stb .inherit = 0,
13294defbdf5Stb .min = "1",
13304defbdf5Stb .max = "2",
13314defbdf5Stb },
13324defbdf5Stb {
13334defbdf5Stb .type = V3_ASID_ASNUM,
13344defbdf5Stb .inherit = 1,
13354defbdf5Stb },
13364defbdf5Stb {
13374defbdf5Stb .type = V3_ASID_END,
13384defbdf5Stb },
13394defbdf5Stb },
13404defbdf5Stb },
13414defbdf5Stb {
13424defbdf5Stb .description = "can't inherit and add rdis",
13434defbdf5Stb .should_build = 0,
13444defbdf5Stb .inherits = 0,
13454defbdf5Stb .canonical = 0,
13464defbdf5Stb .should_canonize = 0,
13474defbdf5Stb .delegations = {
13484defbdf5Stb {
13494defbdf5Stb .type = V3_ASID_RDI,
13504defbdf5Stb .inherit = 0,
13514defbdf5Stb .min = "1",
13524defbdf5Stb .max = "2",
13534defbdf5Stb },
13544defbdf5Stb {
13554defbdf5Stb .type = V3_ASID_RDI,
13564defbdf5Stb .inherit = 1,
13574defbdf5Stb },
13584defbdf5Stb {
13594defbdf5Stb .type = V3_ASID_END,
13604defbdf5Stb },
13614defbdf5Stb },
13624defbdf5Stb },
13634defbdf5Stb };
13644defbdf5Stb
13654defbdf5Stb const size_t N_ASIDENTIFIERS_BUILD_TESTS =
13664defbdf5Stb sizeof(ASIdentifiers_build_data) / sizeof(ASIdentifiers_build_data[0]);
13674defbdf5Stb
13684defbdf5Stb static int
add_as_delegation(ASIdentifiers * asid,const struct asid_or_range * delegation)13694defbdf5Stb add_as_delegation(ASIdentifiers *asid, const struct asid_or_range *delegation)
13704defbdf5Stb {
13714defbdf5Stb ASN1_INTEGER *min = NULL, *max = NULL;
13724defbdf5Stb int ret = 0;
13734defbdf5Stb
13744defbdf5Stb if (delegation->inherit)
13754defbdf5Stb return X509v3_asid_add_inherit(asid, delegation->type);
13764defbdf5Stb
13774defbdf5Stb if ((min = s2i_ASN1_INTEGER(NULL, delegation->min)) == NULL)
13784defbdf5Stb goto err;
13794defbdf5Stb
13804defbdf5Stb if (delegation->max != NULL) {
13814defbdf5Stb if ((max = s2i_ASN1_INTEGER(NULL, delegation->max)) == NULL)
13824defbdf5Stb goto err;
13834defbdf5Stb }
13844defbdf5Stb
13854defbdf5Stb if (!X509v3_asid_add_id_or_range(asid, delegation->type, min, max))
13864defbdf5Stb goto err;
13874defbdf5Stb min = NULL;
13884defbdf5Stb max = NULL;
13894defbdf5Stb
13904defbdf5Stb ret = 1;
13914defbdf5Stb
13924defbdf5Stb err:
13934defbdf5Stb ASN1_INTEGER_free(min);
13944defbdf5Stb ASN1_INTEGER_free(max);
13954defbdf5Stb
13964defbdf5Stb return ret;
13974defbdf5Stb }
13984defbdf5Stb
13994defbdf5Stb static ASIdentifiers *
build_asid(const struct asid_or_range delegations[])14004defbdf5Stb build_asid(const struct asid_or_range delegations[])
14014defbdf5Stb {
14024defbdf5Stb ASIdentifiers *asid = NULL;
14034defbdf5Stb const struct asid_or_range *delegation;
14044defbdf5Stb
14054defbdf5Stb if ((asid = ASIdentifiers_new()) == NULL)
14064defbdf5Stb goto err;
14074defbdf5Stb
14084defbdf5Stb for (delegation = &delegations[0]; delegation->type != V3_ASID_END;
14094defbdf5Stb delegation++) {
14104defbdf5Stb if (!add_as_delegation(asid, delegation))
14114defbdf5Stb goto err;
14124defbdf5Stb }
14134defbdf5Stb
14144defbdf5Stb return asid;
14154defbdf5Stb
14164defbdf5Stb err:
14174defbdf5Stb ASIdentifiers_free(asid);
14184defbdf5Stb return NULL;
14194defbdf5Stb }
14204defbdf5Stb
14214defbdf5Stb static int
build_asid_test(const struct ASIdentifiers_build_test * test)14224defbdf5Stb build_asid_test(const struct ASIdentifiers_build_test *test)
14234defbdf5Stb {
14244defbdf5Stb ASIdentifiers *asid = NULL;
14254defbdf5Stb unsigned char *out = NULL;
14264defbdf5Stb int out_len;
14274defbdf5Stb int memcmp_failed = 1;
14284defbdf5Stb int failed = 1;
14294defbdf5Stb
14304defbdf5Stb if ((asid = build_asid(test->delegations)) == NULL) {
14314defbdf5Stb if (!test->should_build) {
14324defbdf5Stb failed = 0;
14334defbdf5Stb return failed;
14344defbdf5Stb }
14354defbdf5Stb fprintf(stderr, "%s: \"%s\" failed to build\n", __func__,
14364defbdf5Stb test->description);
14374defbdf5Stb return failed;
14384defbdf5Stb }
14394defbdf5Stb
14404defbdf5Stb if (!test->canonical) {
14414defbdf5Stb if (X509v3_asid_is_canonical(asid)) {
14424defbdf5Stb fprintf(stderr, "%s: \"%s\" shouldn't be canonical\n",
14434defbdf5Stb __func__, test->description);
14444defbdf5Stb goto err;
14454defbdf5Stb }
14464defbdf5Stb if (X509v3_asid_canonize(asid) != test->should_canonize) {
14474defbdf5Stb fprintf(stderr, "%s: \"%s\" failed to canonize\n",
14484defbdf5Stb __func__, test->description);
14494defbdf5Stb goto err;
14504defbdf5Stb }
14514defbdf5Stb if (!test->should_canonize) {
14524defbdf5Stb failed = 0;
14534defbdf5Stb goto err;
14544defbdf5Stb }
14554defbdf5Stb }
14564defbdf5Stb
14574defbdf5Stb /*
14584defbdf5Stb * Verify that asid is in canonical form before converting it to DER.
14594defbdf5Stb */
14604defbdf5Stb if (!X509v3_asid_is_canonical(asid)) {
14614defbdf5Stb fprintf(stderr, "%s: asid is not canonical\n", __func__);
14624defbdf5Stb goto err;
14634defbdf5Stb }
14644defbdf5Stb
14654defbdf5Stb /*
14664defbdf5Stb * Convert asid to DER and check that it matches expectations
14674defbdf5Stb */
14684defbdf5Stb out = NULL;
14694defbdf5Stb if ((out_len = i2d_ASIdentifiers(asid, &out)) <= 0) {
14704defbdf5Stb fprintf(stderr, "%s: \"%s\" i2d_ASIdentifiers failed\n",
14714defbdf5Stb __func__, test->description);
14724defbdf5Stb goto err;
14734defbdf5Stb }
14744defbdf5Stb
14754defbdf5Stb
14764defbdf5Stb memcmp_failed = (size_t)out_len != test->der_len;
14774defbdf5Stb if (!memcmp_failed)
14784defbdf5Stb memcmp_failed = memcmp(out, test->der, test->der_len);
14794defbdf5Stb if (memcmp_failed) {
14804defbdf5Stb report_hexdump(__func__, test->description, "memcmp DER failed",
14814defbdf5Stb test->der, test->der_len, out, out_len);
14824defbdf5Stb goto err;
14834defbdf5Stb }
14844defbdf5Stb
14854defbdf5Stb /*
14864defbdf5Stb * Verify that asid inherits as expected
14874defbdf5Stb */
14884defbdf5Stb if (X509v3_asid_inherits(asid) != test->inherits) {
14894defbdf5Stb fprintf(stderr, "%s: \"%s\" unexpected asid inherit %d\n",
14904defbdf5Stb __func__, test->description, test->inherits);
14914defbdf5Stb goto err;
14924defbdf5Stb }
14934defbdf5Stb
14944defbdf5Stb failed = 0;
14954defbdf5Stb
14964defbdf5Stb err:
14974defbdf5Stb free(out);
14984defbdf5Stb ASIdentifiers_free(asid);
14994defbdf5Stb
15004defbdf5Stb return failed;
15014defbdf5Stb }
15024defbdf5Stb
15034defbdf5Stb static int
run_ASIdentifiers_build_test(void)15044defbdf5Stb run_ASIdentifiers_build_test(void)
15054defbdf5Stb {
15064defbdf5Stb size_t i;
15074defbdf5Stb int failed = 0;
15084defbdf5Stb
15094defbdf5Stb for (i = 0; i < N_ASIDENTIFIERS_BUILD_TESTS; i++)
15104defbdf5Stb failed |= build_asid_test(&ASIdentifiers_build_data[i]);
15114defbdf5Stb
15124defbdf5Stb return failed;
15134defbdf5Stb }
15144defbdf5Stb
15154defbdf5Stb struct ASIdentifiers_subset_test {
15164defbdf5Stb const char *description;
15174defbdf5Stb struct asid_or_range delegationsA[8];
15184defbdf5Stb struct asid_or_range delegationsB[8];
15194defbdf5Stb int is_subset;
15204defbdf5Stb int is_subset_if_canonized;
15214defbdf5Stb };
15224defbdf5Stb
15234defbdf5Stb const struct ASIdentifiers_subset_test ASIdentifiers_subset_data[] = {
15244defbdf5Stb {
15254defbdf5Stb .description = "simple subset relation",
15264defbdf5Stb .delegationsA = {
15274defbdf5Stb {
15284defbdf5Stb .type = V3_ASID_ASNUM,
15294defbdf5Stb .inherit = 0,
15304defbdf5Stb .min = "2",
15314defbdf5Stb .max = "4",
15324defbdf5Stb },
15334defbdf5Stb {
15344defbdf5Stb .type = V3_ASID_RDI,
15354defbdf5Stb .inherit = 0,
15364defbdf5Stb .min = "2",
15374defbdf5Stb .max = NULL,
15384defbdf5Stb },
15394defbdf5Stb {
15404defbdf5Stb .type = V3_ASID_END,
15414defbdf5Stb },
15424defbdf5Stb },
15434defbdf5Stb .delegationsB = {
15444defbdf5Stb {
15454defbdf5Stb .type = V3_ASID_ASNUM,
15464defbdf5Stb .inherit = 0,
15474defbdf5Stb .min = "1",
15484defbdf5Stb .max = "5",
15494defbdf5Stb },
15504defbdf5Stb {
15514defbdf5Stb .type = V3_ASID_RDI,
15524defbdf5Stb .inherit = 0,
15534defbdf5Stb .min = "1",
15544defbdf5Stb .max = "5",
15554defbdf5Stb },
15564defbdf5Stb {
15574defbdf5Stb .type = V3_ASID_END,
15584defbdf5Stb },
15594defbdf5Stb },
15604defbdf5Stb .is_subset = 1,
15614defbdf5Stb .is_subset_if_canonized = 1,
15624defbdf5Stb },
15631a2187c2Stb {
15641a2187c2Stb .description = "only asnums",
15651a2187c2Stb .delegationsA = {
15661a2187c2Stb {
15671a2187c2Stb .type = V3_ASID_ASNUM,
15681a2187c2Stb .inherit = 0,
15691a2187c2Stb .min = "2",
15701a2187c2Stb .max = "4",
15711a2187c2Stb },
15721a2187c2Stb {
15731a2187c2Stb .type = V3_ASID_END,
15741a2187c2Stb },
15751a2187c2Stb },
15761a2187c2Stb .delegationsB = {
15771a2187c2Stb {
15781a2187c2Stb .type = V3_ASID_ASNUM,
15791a2187c2Stb .inherit = 0,
15801a2187c2Stb .min = "1",
15811a2187c2Stb .max = "5",
15821a2187c2Stb },
15831a2187c2Stb {
15841a2187c2Stb .type = V3_ASID_END,
15851a2187c2Stb },
15861a2187c2Stb },
15871a2187c2Stb .is_subset = 1,
15881a2187c2Stb .is_subset_if_canonized = 1,
15891a2187c2Stb },
15901a2187c2Stb {
15911a2187c2Stb .description = "only rdis",
15921a2187c2Stb .delegationsA = {
15931a2187c2Stb {
15941a2187c2Stb .type = V3_ASID_RDI,
15951a2187c2Stb .inherit = 0,
15961a2187c2Stb .min = "2",
15971a2187c2Stb .max = NULL,
15981a2187c2Stb },
15991a2187c2Stb {
16001a2187c2Stb .type = V3_ASID_END,
16011a2187c2Stb },
16021a2187c2Stb },
16031a2187c2Stb .delegationsB = {
16041a2187c2Stb {
16051a2187c2Stb .type = V3_ASID_RDI,
16061a2187c2Stb .inherit = 0,
16071a2187c2Stb .min = "1",
16081a2187c2Stb .max = "5",
16091a2187c2Stb },
16101a2187c2Stb {
16111a2187c2Stb .type = V3_ASID_END,
16121a2187c2Stb },
16131a2187c2Stb },
16141a2187c2Stb .is_subset = 1,
16151a2187c2Stb .is_subset_if_canonized = 1,
16161a2187c2Stb },
16171a2187c2Stb {
16181a2187c2Stb .description = "child only has asnums, parent only has rdis",
16191a2187c2Stb .delegationsA = {
16201a2187c2Stb {
16211a2187c2Stb .type = V3_ASID_ASNUM,
16221a2187c2Stb .inherit = 0,
16231a2187c2Stb .min = "2",
16241a2187c2Stb .max = "4",
16251a2187c2Stb },
16261a2187c2Stb {
16271a2187c2Stb .type = V3_ASID_END,
16281a2187c2Stb },
16291a2187c2Stb },
16301a2187c2Stb .delegationsB = {
16311a2187c2Stb {
16321a2187c2Stb .type = V3_ASID_RDI,
16331a2187c2Stb .inherit = 0,
16341a2187c2Stb .min = "1",
16351a2187c2Stb .max = "5",
16361a2187c2Stb },
16371a2187c2Stb {
16381a2187c2Stb .type = V3_ASID_END,
16391a2187c2Stb },
16401a2187c2Stb },
16411a2187c2Stb .is_subset = 0,
16421a2187c2Stb .is_subset_if_canonized = 0,
16431a2187c2Stb },
16441a2187c2Stb {
16451a2187c2Stb .description = "child only has rdis, parent only has asnums",
16461a2187c2Stb .delegationsA = {
16471a2187c2Stb {
16481a2187c2Stb .type = V3_ASID_RDI,
16491a2187c2Stb .inherit = 0,
16501a2187c2Stb .min = "2",
16511a2187c2Stb .max = "4",
16521a2187c2Stb },
16531a2187c2Stb {
16541a2187c2Stb .type = V3_ASID_END,
16551a2187c2Stb },
16561a2187c2Stb },
16571a2187c2Stb .delegationsB = {
16581a2187c2Stb {
16591a2187c2Stb .type = V3_ASID_ASNUM,
16601a2187c2Stb .inherit = 0,
16611a2187c2Stb .min = "1",
16621a2187c2Stb .max = "5",
16631a2187c2Stb },
16641a2187c2Stb {
16651a2187c2Stb .type = V3_ASID_END,
16661a2187c2Stb },
16671a2187c2Stb },
16681a2187c2Stb .is_subset = 0,
16691a2187c2Stb .is_subset_if_canonized = 0,
16701a2187c2Stb },
16711a2187c2Stb {
16721a2187c2Stb .description = "child only has rdis, parent has both",
16731a2187c2Stb .delegationsA = {
16741a2187c2Stb {
16751a2187c2Stb .type = V3_ASID_RDI,
16761a2187c2Stb .inherit = 0,
16771a2187c2Stb .min = "2",
16781a2187c2Stb .max = "4",
16791a2187c2Stb },
16801a2187c2Stb {
16811a2187c2Stb .type = V3_ASID_END,
16821a2187c2Stb },
16831a2187c2Stb },
16841a2187c2Stb .delegationsB = {
16851a2187c2Stb {
16861a2187c2Stb .type = V3_ASID_ASNUM,
16871a2187c2Stb .inherit = 0,
16881a2187c2Stb .min = "1",
16891a2187c2Stb .max = "5",
16901a2187c2Stb },
16911a2187c2Stb {
16921a2187c2Stb .type = V3_ASID_RDI,
16931a2187c2Stb .inherit = 0,
16941a2187c2Stb .min = "1",
16951a2187c2Stb .max = "5",
16961a2187c2Stb },
16971a2187c2Stb {
16981a2187c2Stb .type = V3_ASID_END,
16991a2187c2Stb },
17001a2187c2Stb },
17011a2187c2Stb .is_subset = 1,
17021a2187c2Stb .is_subset_if_canonized = 1,
17031a2187c2Stb },
17044defbdf5Stb {
17054defbdf5Stb .description = "subset relation only after canonization",
17064defbdf5Stb .delegationsA = {
17074defbdf5Stb {
17084defbdf5Stb .type = V3_ASID_ASNUM,
17094defbdf5Stb .inherit = 0,
17104defbdf5Stb .min = "2",
17114defbdf5Stb .max = NULL,
17124defbdf5Stb },
17134defbdf5Stb {
17144defbdf5Stb .type = V3_ASID_ASNUM,
17154defbdf5Stb .inherit = 0,
17164defbdf5Stb .min = "3",
17174defbdf5Stb .max = "4",
17184defbdf5Stb },
17194defbdf5Stb {
17204defbdf5Stb .type = V3_ASID_RDI,
17214defbdf5Stb .inherit = 0,
17224defbdf5Stb .min = "2",
17234defbdf5Stb .max = NULL,
17244defbdf5Stb },
17254defbdf5Stb {
17264defbdf5Stb .type = V3_ASID_END,
17274defbdf5Stb },
17284defbdf5Stb },
17294defbdf5Stb .delegationsB = {
17304defbdf5Stb {
17314defbdf5Stb .type = V3_ASID_ASNUM,
17324defbdf5Stb .inherit = 0,
17334defbdf5Stb .min = "1",
17344defbdf5Stb .max = "3",
17354defbdf5Stb },
17364defbdf5Stb {
17374defbdf5Stb .type = V3_ASID_ASNUM,
17384defbdf5Stb .inherit = 0,
17394defbdf5Stb .min = "4",
17404defbdf5Stb .max = "5",
17414defbdf5Stb },
17424defbdf5Stb {
17434defbdf5Stb .type = V3_ASID_RDI,
17444defbdf5Stb .inherit = 0,
17454defbdf5Stb .min = "1",
17464defbdf5Stb .max = "5",
17474defbdf5Stb },
17484defbdf5Stb {
17494defbdf5Stb .type = V3_ASID_END,
17504defbdf5Stb },
17514defbdf5Stb },
17524defbdf5Stb .is_subset = 0,
17534defbdf5Stb .is_subset_if_canonized = 1,
17544defbdf5Stb },
17554defbdf5Stb {
17564defbdf5Stb .description = "no subset if A inherits",
17574defbdf5Stb .delegationsA = {
17584defbdf5Stb {
17594defbdf5Stb .type = V3_ASID_ASNUM,
17604defbdf5Stb .inherit = 0,
17614defbdf5Stb .min = "2",
17624defbdf5Stb .max = NULL,
17634defbdf5Stb },
17644defbdf5Stb {
17654defbdf5Stb .type = V3_ASID_ASNUM,
17664defbdf5Stb .inherit = 0,
17674defbdf5Stb .min = "3",
17684defbdf5Stb .max = "4",
17694defbdf5Stb },
17704defbdf5Stb {
17714defbdf5Stb .type = V3_ASID_RDI,
17724defbdf5Stb .inherit = 1,
17734defbdf5Stb },
17744defbdf5Stb {
17754defbdf5Stb .type = V3_ASID_END,
17764defbdf5Stb },
17774defbdf5Stb },
17784defbdf5Stb .delegationsB = {
17794defbdf5Stb {
17804defbdf5Stb .type = V3_ASID_ASNUM,
17814defbdf5Stb .inherit = 0,
17824defbdf5Stb .min = "1",
17834defbdf5Stb .max = "3",
17844defbdf5Stb },
17854defbdf5Stb {
17864defbdf5Stb .type = V3_ASID_ASNUM,
17874defbdf5Stb .inherit = 0,
17884defbdf5Stb .min = "4",
17894defbdf5Stb .max = "5",
17904defbdf5Stb },
17914defbdf5Stb {
17924defbdf5Stb .type = V3_ASID_RDI,
17934defbdf5Stb .inherit = 0,
17944defbdf5Stb .min = "1",
17954defbdf5Stb .max = "5",
17964defbdf5Stb },
17974defbdf5Stb {
17984defbdf5Stb .type = V3_ASID_END,
17994defbdf5Stb },
18004defbdf5Stb },
18014defbdf5Stb .is_subset = 0,
18024defbdf5Stb .is_subset_if_canonized = 0,
18034defbdf5Stb },
18044defbdf5Stb {
18054defbdf5Stb .description = "no subset if B inherits",
18064defbdf5Stb .delegationsA = {
18074defbdf5Stb {
18084defbdf5Stb .type = V3_ASID_ASNUM,
18094defbdf5Stb .inherit = 0,
18104defbdf5Stb .min = "2",
18114defbdf5Stb .max = NULL,
18124defbdf5Stb },
18134defbdf5Stb {
18144defbdf5Stb .type = V3_ASID_ASNUM,
18154defbdf5Stb .inherit = 0,
18164defbdf5Stb .min = "3",
18174defbdf5Stb .max = "4",
18184defbdf5Stb },
18194defbdf5Stb {
18204defbdf5Stb .type = V3_ASID_RDI,
18214defbdf5Stb .inherit = 0,
18224defbdf5Stb .min = "5",
18234defbdf5Stb .max = NULL,
18244defbdf5Stb },
18254defbdf5Stb {
18264defbdf5Stb .type = V3_ASID_END,
18274defbdf5Stb },
18284defbdf5Stb },
18294defbdf5Stb .delegationsB = {
18304defbdf5Stb {
18314defbdf5Stb .type = V3_ASID_ASNUM,
18324defbdf5Stb .inherit = 0,
18334defbdf5Stb .min = "1",
18344defbdf5Stb .max = "3",
18354defbdf5Stb },
18364defbdf5Stb {
18374defbdf5Stb .type = V3_ASID_ASNUM,
18384defbdf5Stb .inherit = 0,
18394defbdf5Stb .min = "4",
18404defbdf5Stb .max = "5",
18414defbdf5Stb },
18424defbdf5Stb {
18434defbdf5Stb .type = V3_ASID_RDI,
18444defbdf5Stb .inherit = 1,
18454defbdf5Stb },
18464defbdf5Stb {
18474defbdf5Stb .type = V3_ASID_END,
18484defbdf5Stb },
18494defbdf5Stb },
18504defbdf5Stb .is_subset = 0,
18514defbdf5Stb .is_subset_if_canonized = 0,
18524defbdf5Stb },
18534defbdf5Stb {
18544defbdf5Stb .description = "no subset if both inherit",
18554defbdf5Stb .delegationsA = {
18564defbdf5Stb {
18574defbdf5Stb .type = V3_ASID_ASNUM,
18584defbdf5Stb .inherit = 0,
18594defbdf5Stb .min = "2",
18604defbdf5Stb .max = NULL,
18614defbdf5Stb },
18624defbdf5Stb {
18634defbdf5Stb .type = V3_ASID_ASNUM,
18644defbdf5Stb .inherit = 0,
18654defbdf5Stb .min = "3",
18664defbdf5Stb .max = "4",
18674defbdf5Stb },
18684defbdf5Stb {
18694defbdf5Stb .type = V3_ASID_RDI,
18704defbdf5Stb .inherit = 1,
18714defbdf5Stb },
18724defbdf5Stb {
18734defbdf5Stb .type = V3_ASID_END,
18744defbdf5Stb },
18754defbdf5Stb },
18764defbdf5Stb .delegationsB = {
18774defbdf5Stb {
18784defbdf5Stb .type = V3_ASID_ASNUM,
18794defbdf5Stb .inherit = 0,
18804defbdf5Stb .min = "1",
18814defbdf5Stb .max = "3",
18824defbdf5Stb },
18834defbdf5Stb {
18844defbdf5Stb .type = V3_ASID_ASNUM,
18854defbdf5Stb .inherit = 0,
18864defbdf5Stb .min = "4",
18874defbdf5Stb .max = "5",
18884defbdf5Stb },
18894defbdf5Stb {
18904defbdf5Stb .type = V3_ASID_RDI,
18914defbdf5Stb .inherit = 1,
18924defbdf5Stb },
18934defbdf5Stb {
18944defbdf5Stb .type = V3_ASID_END,
18954defbdf5Stb },
18964defbdf5Stb },
18974defbdf5Stb .is_subset = 0,
18984defbdf5Stb .is_subset_if_canonized = 0,
18994defbdf5Stb },
19004defbdf5Stb };
19014defbdf5Stb
19024defbdf5Stb const size_t N_ASIDENTIFIERS_SUBSET_TESTS =
1903e84a01fbStb sizeof(ASIdentifiers_subset_data) / sizeof(ASIdentifiers_subset_data[0]);
19044defbdf5Stb
19054defbdf5Stb static int
asid_subset_test(const struct ASIdentifiers_subset_test * test)19064defbdf5Stb asid_subset_test(const struct ASIdentifiers_subset_test *test)
19074defbdf5Stb {
19084defbdf5Stb ASIdentifiers *asidA = NULL, *asidB = NULL;
19094defbdf5Stb int failed = 0;
19104defbdf5Stb
19114defbdf5Stb if ((asidA = build_asid(test->delegationsA)) == NULL)
19124defbdf5Stb goto err;
19134defbdf5Stb if ((asidB = build_asid(test->delegationsB)) == NULL)
19144defbdf5Stb goto err;
19154defbdf5Stb
19164defbdf5Stb if (X509v3_asid_subset(asidA, asidB) != test->is_subset) {
19174defbdf5Stb fprintf(stderr, "%s: \"%s\" X509v3_asid_subset failed\n",
19184defbdf5Stb __func__, test->description);
19194defbdf5Stb failed = 1;
19204defbdf5Stb }
19214defbdf5Stb
19224defbdf5Stb if (!test->is_subset) {
19234defbdf5Stb if (!X509v3_asid_canonize(asidA))
19244defbdf5Stb goto err;
19254defbdf5Stb if (!X509v3_asid_canonize(asidB))
19264defbdf5Stb goto err;
19274defbdf5Stb if (X509v3_asid_subset(asidA, asidB) !=
19284defbdf5Stb test->is_subset_if_canonized) {
19294defbdf5Stb fprintf(stderr, "%s: \"%s\" canonized subset failed\n",
19304defbdf5Stb __func__, test->description);
19314defbdf5Stb failed = 1;
19324defbdf5Stb }
19334defbdf5Stb }
19344defbdf5Stb
19354defbdf5Stb err:
19364defbdf5Stb ASIdentifiers_free(asidA);
19374defbdf5Stb ASIdentifiers_free(asidB);
19384defbdf5Stb
19394defbdf5Stb return failed;
19404defbdf5Stb }
19414defbdf5Stb
19424defbdf5Stb static int
run_ASIdentifiers_subset_test(void)19434defbdf5Stb run_ASIdentifiers_subset_test(void)
19444defbdf5Stb {
19454defbdf5Stb size_t i;
19464defbdf5Stb int failed = 0;
19474defbdf5Stb
19484defbdf5Stb for (i = 0; i < N_ASIDENTIFIERS_SUBSET_TESTS; i++)
19494defbdf5Stb failed |= asid_subset_test(&ASIdentifiers_subset_data[i]);
19504defbdf5Stb
19514defbdf5Stb return failed;
19524defbdf5Stb }
19534defbdf5Stb
19544defbdf5Stb int
main(void)19554defbdf5Stb main(void)
19564defbdf5Stb {
19574defbdf5Stb int failed = 0;
19584defbdf5Stb
19594defbdf5Stb failed |= run_IPAddressOrRange_tests();
19604defbdf5Stb failed |= run_IPAddrBlock_tests();
19614defbdf5Stb failed |= run_ASIdentifiers_build_test();
19624defbdf5Stb failed |= run_ASIdentifiers_subset_test();
19634defbdf5Stb
19644defbdf5Stb return failed;
19654defbdf5Stb }
1966