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