xref: /openbsd/usr.sbin/rpki-client/ip.c (revision 9eb589bc)
1 /*	$OpenBSD: ip.c,v 1.23 2022/05/13 06:18:21 tb Exp $ */
2 /*
3  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
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 <sys/socket.h>
19 #include <arpa/inet.h>
20 
21 #include <assert.h>
22 #include <err.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "extern.h"
29 
30 #define   PREFIX_SIZE(x)  (((x) + 7) / 8)
31 
32 /*
33  * Parse an IP address family.
34  * This is defined in different places in the ROA/X509 standards, but
35  * it's the same thing.
36  * We prohibit all but IPv4 and IPv6, without SAFI.
37  * Return zero on failure, non-zero on success.
38  */
39 int
40 ip_addr_afi_parse(const char *fn, const ASN1_OCTET_STRING *p, enum afi *afi)
41 {
42 	uint16_t v;
43 
44 	if (p->length == 0 || p->length > 3) {
45 		warnx("%s: invalid field length, want 1--3, have %d",
46 		    fn, p->length);
47 		return 0;
48 	}
49 
50 	memcpy(&v, p->data, sizeof(v));
51 	v = ntohs(v);
52 
53 	/* Only accept IPv4 and IPv6 AFIs. */
54 
55 	if (v != AFI_IPV4 && v != AFI_IPV6) {
56 		warnx("%s: only AFI for IPV4 (1) and IPV6 (2) allowed: "
57 		    "have %hd", fn, v);
58 		return 0;
59 	}
60 
61 	/* Disallow the optional SAFI. */
62 
63 	if (p->length == 3) {
64 		warnx("%s: SAFI not allowed", fn);
65 		return 0;
66 	}
67 
68 	*afi = v;
69 	return 1;
70 }
71 
72 /*
73  * See if a given IP prefix is covered by the IP prefixes or ranges
74  * specified in the "ips" array.
75  * This means that the IP prefix must be strictly within the ranges or
76  * singletons given in the array.
77  * Return 0 if we're inheriting from the parent, >0 if we're covered,
78  * or <0 if we're not covered.
79  */
80 int
81 ip_addr_check_covered(enum afi afi,
82     const unsigned char *min, const unsigned char *max,
83     const struct cert_ip *ips, size_t ipsz)
84 {
85 	size_t	 i, sz = AFI_IPV4 == afi ? 4 : 16;
86 
87 	for (i = 0; i < ipsz; i++) {
88 		if (ips[i].afi != afi)
89 			continue;
90 		if (ips[i].type == CERT_IP_INHERIT)
91 			return 0;
92 		if (memcmp(ips[i].min, min, sz) <= 0 &&
93 		    memcmp(ips[i].max, max, sz) >= 0)
94 			return 1;
95 	}
96 
97 	return -1;
98 }
99 
100 /*
101  * Given a newly-parsed IP address or range "ip", make sure that "ip"
102  * does not overlap with any addresses or ranges in the "ips" array.
103  * This is defined by RFC 3779 section 2.2.3.6.
104  * Returns zero on failure, non-zero on success.
105  */
106 int
107 ip_addr_check_overlap(const struct cert_ip *ip, const char *fn,
108     const struct cert_ip *ips, size_t ipsz)
109 {
110 	size_t	 i, sz = ip->afi == AFI_IPV4 ? 4 : 16;
111 	int	 inherit_v4 = 0, inherit_v6 = 0;
112 	int	 has_v4 = 0, has_v6 = 0, socktype;
113 
114 	/*
115 	 * FIXME: cache this by having a flag on the cert_ip, else we're
116 	 * going to need to do a lot of scanning for big allocations.
117 	 */
118 
119 	for (i = 0; i < ipsz; i++)
120 		if (ips[i].type == CERT_IP_INHERIT) {
121 			if (ips[i].afi == AFI_IPV4)
122 				inherit_v4 = 1;
123 			else
124 				inherit_v6 = 1;
125 		} else {
126 			if (ips[i].afi == AFI_IPV4)
127 				has_v4 = 1;
128 			else
129 				has_v6 = 1;
130 		}
131 
132 	/* Disallow multiple inheritance per type. */
133 
134 	if ((inherit_v4 && ip->afi == AFI_IPV4) ||
135 	    (inherit_v6 && ip->afi == AFI_IPV6) ||
136 	    (has_v4 && ip->afi == AFI_IPV4 &&
137 	     ip->type == CERT_IP_INHERIT) ||
138 	    (has_v6 && ip->afi == AFI_IPV6 &&
139 	     ip->type == CERT_IP_INHERIT)) {
140 		warnx("%s: RFC 3779 section 2.2.3.5: "
141 		    "cannot have multiple inheritance or inheritance and "
142 		    "addresses of the same class", fn);
143 		return 0;
144 	}
145 
146 	/* Check our ranges. */
147 
148 	for (i = 0; i < ipsz; i++) {
149 		char	 buf[64];
150 
151 		if (ips[i].afi != ip->afi)
152 			continue;
153 		if (memcmp(ips[i].max, ip->min, sz) <= 0 ||
154 		    memcmp(ips[i].min, ip->max, sz) >= 0)
155 			continue;
156 		socktype = (ips[i].afi == AFI_IPV4) ? AF_INET : AF_INET6,
157 		warnx("%s: RFC 3779 section 2.2.3.5: "
158 		    "cannot have overlapping IP addresses", fn);
159 		ip_addr_print(&ip->ip, ip->afi, buf, sizeof(buf));
160 		warnx("%s: certificate IP: %s", fn, buf);
161 		if (inet_ntop(socktype, ip->min, buf, sizeof(buf)) == NULL)
162 			err(1, "inet_ntop");
163 		warnx("%s: certificate IP minimum: %s", fn, buf);
164 		if (inet_ntop(socktype, ip->max, buf, sizeof(buf)) == NULL)
165 			err(1, "inet_ntop");
166 		warnx("%s: certificate IP maximum: %s", fn, buf);
167 		if (inet_ntop(socktype, ips[i].min, buf, sizeof(buf)) == NULL)
168 			err(1, "inet_ntop");
169 		warnx("%s: offending IP minimum: %s", fn, buf);
170 		if (inet_ntop(socktype, ips[i].max, buf, sizeof(buf)) == NULL)
171 			err(1, "inet_ntop");
172 		warnx("%s: offending IP maximum: %s", fn, buf);
173 		return 0;
174 	}
175 
176 	return 1;
177 }
178 
179 /*
180  * Parse an IP address, RFC 3779, 2.2.3.8.
181  * Return zero on failure, non-zero on success.
182  */
183 int
184 ip_addr_parse(const ASN1_BIT_STRING *p,
185     enum afi afi, const char *fn, struct ip_addr *addr)
186 {
187 	long	 unused = 0;
188 
189 	/* Weird OpenSSL-ism to get unused bit count. */
190 
191 	if ((p->flags & ASN1_STRING_FLAG_BITS_LEFT))
192 		unused = p->flags & 0x07;
193 
194 	if (p->length == 0 && unused != 0) {
195 		warnx("%s: RFC 3779 section 2.2.3.8: "
196 		    "unused bit count must be zero if length is zero", fn);
197 		return 0;
198 	}
199 
200 	/*
201 	 * Check that the unused bits are set to zero.
202 	 * If we don't do this, stray bits will corrupt our composition
203 	 * of the [minimum] address ranges.
204 	 */
205 
206 	if (p->length != 0 &&
207 	    (p->data[p->length - 1] & ((1 << unused) - 1))) {
208 		warnx("%s: RFC 3779 section 2.2.3.8: "
209 		    "unused bits must be set to zero", fn);
210 		return 0;
211 	}
212 
213 	/* Limit possible sizes of addresses. */
214 
215 	if ((afi == AFI_IPV4 && p->length > 4) ||
216 	    (afi == AFI_IPV6 && p->length > 16)) {
217 		warnx("%s: RFC 3779 section 2.2.3.8: "
218 		    "IP address too long", fn);
219 		return 0;
220 	}
221 
222 	memset(addr, 0, sizeof(struct ip_addr));
223 	addr->prefixlen = p->length * 8 - unused;
224 	memcpy(addr->addr, p->data, p->length);
225 	return 1;
226 }
227 
228 /*
229  * Convert a ip_addr into a NUL-terminated CIDR notation string
230  * conforming to RFC 4632 or 4291.
231  * The size of the buffer must be at least 64 (inclusive).
232  */
233 void
234 ip_addr_print(const struct ip_addr *addr,
235     enum afi afi, char *buf, size_t bufsz)
236 {
237 	char ipbuf[INET6_ADDRSTRLEN];
238 	int ret, af;
239 
240 	switch (afi) {
241 	case AFI_IPV4:
242 		af = AF_INET;
243 		break;
244 	case AFI_IPV6:
245 		af = AF_INET6;
246 		break;
247 	default:
248 		errx(1, "unsupported address family identifier");
249 	}
250 
251 	if (inet_ntop(af, addr->addr, ipbuf, sizeof(ipbuf)) == NULL)
252 		err(1, "inet_ntop");
253 	ret = snprintf(buf, bufsz, "%s/%hhu", ipbuf, addr->prefixlen);
254 	if (ret < 0 || (size_t)ret >= bufsz)
255 		err(1, "malformed IP address");
256 }
257 
258 /*
259  * Given the addresses (range or IP) in cert_ip, fill in the "min" and
260  * "max" fields with the minimum and maximum possible IP addresses given
261  * those ranges (or singleton prefixed range).
262  * This does nothing if CERT_IP_INHERIT.
263  * Returns zero on failure (misordered ranges), non-zero on success.
264  */
265 int
266 ip_cert_compose_ranges(struct cert_ip *p)
267 {
268 	size_t sz;
269 
270 	switch (p->type) {
271 	case CERT_IP_ADDR:
272 		sz = PREFIX_SIZE(p->ip.prefixlen);
273 		memset(p->min, 0x0, sizeof(p->min));
274 		memcpy(p->min, p->ip.addr, sz);
275 		memset(p->max, 0xff, sizeof(p->max));
276 		memcpy(p->max, p->ip.addr, sz);
277 		if (sz > 0 && p->ip.prefixlen % 8 != 0)
278 			p->max[sz - 1] |= (1 << (8 - p->ip.prefixlen % 8)) - 1;
279 		break;
280 	case CERT_IP_RANGE:
281 		memset(p->min, 0x0, sizeof(p->min));
282 		sz = PREFIX_SIZE(p->range.min.prefixlen);
283 		memcpy(p->min, p->range.min.addr, sz);
284 		memset(p->max, 0xff, sizeof(p->max));
285 		sz = PREFIX_SIZE(p->range.max.prefixlen);
286 		memcpy(p->max, p->range.max.addr, sz);
287 		if (sz > 0 && p->range.max.prefixlen % 8 != 0)
288 			p->max[sz - 1] |=
289 			    (1 << (8 - p->range.max.prefixlen % 8)) - 1;
290 		break;
291 	default:
292 		return 1;
293 	}
294 
295 	sz = AFI_IPV4 == p->afi ? 4 : 16;
296 	return memcmp(p->min, p->max, sz) <= 0;
297 }
298 
299 /*
300  * Given the ROA's acceptable prefix, compute the minimum and maximum
301  * address accepted by the prefix.
302  */
303 void
304 ip_roa_compose_ranges(struct roa_ip *p)
305 {
306 	size_t sz = PREFIX_SIZE(p->addr.prefixlen);
307 
308 	memset(p->min, 0x0, sizeof(p->min));
309 	memcpy(p->min, p->addr.addr, sz);
310 	memset(p->max, 0xff, sizeof(p->max));
311 	memcpy(p->max, p->addr.addr, sz);
312 	if (sz > 0 && p->addr.prefixlen % 8 != 0)
313 		p->max[sz - 1] |= (1 << (8 - p->addr.prefixlen % 8)) - 1;
314 }
315