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