ip.c revision 1.22
1/*	$OpenBSD: ip.c,v 1.22 2022/05/11 18:48:35 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 */
39int
40ip_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 */
80int
81ip_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 */
106int
107ip_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 */
183int
184ip_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 & ~ASN1_STRING_FLAG_BITS_LEFT;
193
194	if (unused < 0) {
195		warnx("%s: RFC 3779 section 2.2.3.8: "
196		    "unused bit count must be non-negative", fn);
197		return 0;
198	} else if (unused >= 8) {
199		warnx("%s: RFC 3779 section 2.2.3.8: "
200		    "unused bit count must mask an unsigned char", fn);
201		return 0;
202	} else if (p->length == 0 && unused != 0) {
203		warnx("%s: RFC 3779 section 2.2.3.8: "
204		    "unused bit count must be zero if length is zero", fn);
205		return 0;
206	}
207
208	/*
209	 * Check that the unused bits are set to zero.
210	 * If we don't do this, stray bits will corrupt our composition
211	 * of the [minimum] address ranges.
212	 */
213
214	if (p->length != 0 &&
215	    (p->data[p->length - 1] & ((1 << unused) - 1))) {
216		warnx("%s: RFC 3779 section 2.2.3.8: "
217		    "unused bits must be set to zero", fn);
218		return 0;
219	}
220
221	/* Limit possible sizes of addresses. */
222
223	if ((afi == AFI_IPV4 && p->length > 4) ||
224	    (afi == AFI_IPV6 && p->length > 16)) {
225		warnx("%s: RFC 3779 section 2.2.3.8: "
226		    "IP address too long", fn);
227		return 0;
228	}
229
230	memset(addr, 0, sizeof(struct ip_addr));
231	addr->prefixlen = p->length * 8 - unused;
232	memcpy(addr->addr, p->data, p->length);
233	return 1;
234}
235
236/*
237 * Convert a ip_addr into a NUL-terminated CIDR notation string
238 * conforming to RFC 4632 or 4291.
239 * The size of the buffer must be at least 64 (inclusive).
240 */
241void
242ip_addr_print(const struct ip_addr *addr,
243    enum afi afi, char *buf, size_t bufsz)
244{
245	char ipbuf[INET6_ADDRSTRLEN];
246	int ret, af;
247
248	switch (afi) {
249	case AFI_IPV4:
250		af = AF_INET;
251		break;
252	case AFI_IPV6:
253		af = AF_INET6;
254		break;
255	default:
256		errx(1, "unsupported address family identifier");
257	}
258
259	if (inet_ntop(af, addr->addr, ipbuf, sizeof(ipbuf)) == NULL)
260		err(1, "inet_ntop");
261	ret = snprintf(buf, bufsz, "%s/%hhu", ipbuf, addr->prefixlen);
262	if (ret < 0 || (size_t)ret >= bufsz)
263		err(1, "malformed IP address");
264}
265
266/*
267 * Given the addresses (range or IP) in cert_ip, fill in the "min" and
268 * "max" fields with the minimum and maximum possible IP addresses given
269 * those ranges (or singleton prefixed range).
270 * This does nothing if CERT_IP_INHERIT.
271 * Returns zero on failure (misordered ranges), non-zero on success.
272 */
273int
274ip_cert_compose_ranges(struct cert_ip *p)
275{
276	size_t sz;
277
278	switch (p->type) {
279	case CERT_IP_ADDR:
280		sz = PREFIX_SIZE(p->ip.prefixlen);
281		memset(p->min, 0x0, sizeof(p->min));
282		memcpy(p->min, p->ip.addr, sz);
283		memset(p->max, 0xff, sizeof(p->max));
284		memcpy(p->max, p->ip.addr, sz);
285		if (sz > 0 && p->ip.prefixlen % 8 != 0)
286			p->max[sz - 1] |= (1 << (8 - p->ip.prefixlen % 8)) - 1;
287		break;
288	case CERT_IP_RANGE:
289		memset(p->min, 0x0, sizeof(p->min));
290		sz = PREFIX_SIZE(p->range.min.prefixlen);
291		memcpy(p->min, p->range.min.addr, sz);
292		memset(p->max, 0xff, sizeof(p->max));
293		sz = PREFIX_SIZE(p->range.max.prefixlen);
294		memcpy(p->max, p->range.max.addr, sz);
295		if (sz > 0 && p->range.max.prefixlen % 8 != 0)
296			p->max[sz - 1] |=
297			    (1 << (8 - p->range.max.prefixlen % 8)) - 1;
298		break;
299	default:
300		return 1;
301	}
302
303	sz = AFI_IPV4 == p->afi ? 4 : 16;
304	return memcmp(p->min, p->max, sz) <= 0;
305}
306
307/*
308 * Given the ROA's acceptable prefix, compute the minimum and maximum
309 * address accepted by the prefix.
310 */
311void
312ip_roa_compose_ranges(struct roa_ip *p)
313{
314	size_t sz = PREFIX_SIZE(p->addr.prefixlen);
315
316	memset(p->min, 0x0, sizeof(p->min));
317	memcpy(p->min, p->addr.addr, sz);
318	memset(p->max, 0xff, sizeof(p->max));
319	memcpy(p->max, p->addr.addr, sz);
320	if (sz > 0 && p->addr.prefixlen % 8 != 0)
321		p->max[sz - 1] |= (1 << (8 - p->addr.prefixlen % 8)) - 1;
322}
323