1 /* $OpenBSD: roa.c,v 1.13 2021/02/04 08:58:19 claudio 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 <assert.h> 19 #include <err.h> 20 #include <stdarg.h> 21 #include <stdint.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #include <openssl/asn1.h> 27 #include <openssl/x509.h> 28 29 #include "extern.h" 30 31 /* 32 * Parse results and data of the manifest file. 33 */ 34 struct parse { 35 const char *fn; /* manifest file name */ 36 struct roa *res; /* results */ 37 }; 38 39 /* 40 * Parse IP address (ROAIPAddress), RFC 6482, section 3.3. 41 * Returns zero on failure, non-zero on success. 42 */ 43 static int 44 roa_parse_addr(const ASN1_OCTET_STRING *os, enum afi afi, struct parse *p) 45 { 46 ASN1_SEQUENCE_ANY *seq; 47 const unsigned char *d = os->data; 48 size_t dsz = os->length; 49 int rc = 0; 50 const ASN1_TYPE *t; 51 const ASN1_INTEGER *maxlength = NULL; 52 struct ip_addr addr; 53 struct roa_ip *res; 54 55 if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) { 56 cryptowarnx("%s: RFC 6482 section 3.3: address: " 57 "failed ASN.1 sequence parse", p->fn); 58 goto out; 59 } 60 61 /* ROAIPAddress has the address and optional maxlength. */ 62 63 if (sk_ASN1_TYPE_num(seq) != 1 && 64 sk_ASN1_TYPE_num(seq) != 2) { 65 warnx("%s: RFC 6482 section 3.3: adddress: " 66 "want 1 or 2 elements, have %d", 67 p->fn, sk_ASN1_TYPE_num(seq)); 68 goto out; 69 } 70 71 t = sk_ASN1_TYPE_value(seq, 0); 72 if (t->type != V_ASN1_BIT_STRING) { 73 warnx("%s: RFC 6482 section 3.3: address: " 74 "want ASN.1 bit string, have %s (NID %d)", 75 p->fn, ASN1_tag2str(t->type), t->type); 76 goto out; 77 } 78 if (!ip_addr_parse(t->value.bit_string, afi, p->fn, &addr)) { 79 warnx("%s: RFC 6482 section 3.3: address: " 80 "invalid IP address", p->fn); 81 goto out; 82 } 83 84 /* 85 * RFC 6482, section 3.3 doesn't ever actually state that the 86 * maximum length can't be negative, but it needs to be >=0. 87 */ 88 89 if (sk_ASN1_TYPE_num(seq) == 2) { 90 t = sk_ASN1_TYPE_value(seq, 1); 91 if (t->type != V_ASN1_INTEGER) { 92 warnx("%s: RFC 6482 section 3.1: maxLength: " 93 "want ASN.1 integer, have %s (NID %d)", 94 p->fn, ASN1_tag2str(t->type), t->type); 95 goto out; 96 } 97 maxlength = t->value.integer; 98 99 /* 100 * It's safe to use ASN1_INTEGER_get() here 101 * because we're not going to have more than signed 32 102 * bit maximum of length. 103 */ 104 105 if (ASN1_INTEGER_get(maxlength) < 0) { 106 warnx("%s: RFC 6482 section 3.2: maxLength: " 107 "want positive integer, have %ld", 108 p->fn, ASN1_INTEGER_get(maxlength)); 109 goto out; 110 } 111 /* FIXME: maximum check. */ 112 } 113 114 p->res->ips = reallocarray(p->res->ips, 115 p->res->ipsz + 1, sizeof(struct roa_ip)); 116 if (p->res->ips == NULL) 117 err(1, NULL); 118 res = &p->res->ips[p->res->ipsz++]; 119 memset(res, 0, sizeof(struct roa_ip)); 120 121 res->addr = addr; 122 res->afi = afi; 123 res->maxlength = (maxlength == NULL) ? addr.prefixlen : 124 ASN1_INTEGER_get(maxlength); 125 ip_roa_compose_ranges(res); 126 127 rc = 1; 128 out: 129 sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free); 130 return rc; 131 } 132 133 /* 134 * Parse IP address family, RFC 6482, section 3.3. 135 * Returns zero on failure, non-zero on success. 136 */ 137 static int 138 roa_parse_ipfam(const ASN1_OCTET_STRING *os, struct parse *p) 139 { 140 ASN1_SEQUENCE_ANY *seq, *sseq = NULL; 141 const unsigned char *d = os->data; 142 size_t dsz = os->length; 143 int i, rc = 0; 144 const ASN1_TYPE *t; 145 enum afi afi; 146 147 if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) { 148 cryptowarnx("%s: RFC 6482 section 3.3: ROAIPAddressFamily: " 149 "failed ASN.1 sequence parse", p->fn); 150 goto out; 151 } else if (sk_ASN1_TYPE_num(seq) != 2) { 152 warnx("%s: RFC 6482 section 3.3: ROAIPAddressFamily: " 153 "want 2 elements, have %d", 154 p->fn, sk_ASN1_TYPE_num(seq)); 155 goto out; 156 } 157 158 t = sk_ASN1_TYPE_value(seq, 0); 159 if (t->type != V_ASN1_OCTET_STRING) { 160 warnx("%s: RFC 6482 section 3.3: addressFamily: " 161 "want ASN.1 octet string, have %s (NID %d)", 162 p->fn, ASN1_tag2str(t->type), t->type); 163 goto out; 164 } 165 if (!ip_addr_afi_parse(p->fn, t->value.octet_string, &afi)) { 166 warnx("%s: RFC 6482 section 3.3: addressFamily: " 167 "invalid", p->fn); 168 goto out; 169 } 170 171 t = sk_ASN1_TYPE_value(seq, 1); 172 if (t->type != V_ASN1_SEQUENCE) { 173 warnx("%s: RFC 6482 section 3.3: addresses: " 174 "want ASN.1 sequence, have %s (NID %d)", 175 p->fn, ASN1_tag2str(t->type), t->type); 176 goto out; 177 } 178 179 d = t->value.octet_string->data; 180 dsz = t->value.octet_string->length; 181 182 if ((sseq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) { 183 cryptowarnx("%s: RFC 6482 section 3.3: addresses: " 184 "failed ASN.1 sequence parse", p->fn); 185 goto out; 186 } 187 188 for (i = 0; i < sk_ASN1_TYPE_num(sseq); i++) { 189 t = sk_ASN1_TYPE_value(sseq, i); 190 if (t->type != V_ASN1_SEQUENCE) { 191 warnx("%s: RFC 6482 section 3.3: ROAIPAddress: " 192 "want ASN.1 sequence, have %s (NID %d)", 193 p->fn, ASN1_tag2str(t->type), t->type); 194 goto out; 195 } 196 if (!roa_parse_addr(t->value.octet_string, afi, p)) 197 goto out; 198 } 199 200 rc = 1; 201 out: 202 sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free); 203 sk_ASN1_TYPE_pop_free(sseq, ASN1_TYPE_free); 204 return rc; 205 } 206 207 /* 208 * Parse IP blocks, RFC 6482, section 3.3. 209 * Returns zero on failure, non-zero on success. 210 */ 211 static int 212 roa_parse_ipblocks(const ASN1_OCTET_STRING *os, struct parse *p) 213 { 214 ASN1_SEQUENCE_ANY *seq; 215 const unsigned char *d = os->data; 216 size_t dsz = os->length; 217 int i, rc = 0; 218 const ASN1_TYPE *t; 219 220 if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) { 221 cryptowarnx("%s: RFC 6482 section 3.3: ipAddrBlocks: " 222 "failed ASN.1 sequence parse", p->fn); 223 goto out; 224 } 225 226 for (i = 0; i < sk_ASN1_TYPE_num(seq); i++) { 227 t = sk_ASN1_TYPE_value(seq, i); 228 if (t->type != V_ASN1_SEQUENCE) { 229 warnx("%s: RFC 6482 section 3.3: ROAIPAddressFamily: " 230 "want ASN.1 sequence, have %s (NID %d)", 231 p->fn, ASN1_tag2str(t->type), t->type); 232 goto out; 233 } else if (!roa_parse_ipfam(t->value.octet_string, p)) 234 goto out; 235 } 236 237 rc = 1; 238 out: 239 sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free); 240 return rc; 241 } 242 243 /* 244 * Parses the eContent section of an ROA file, RFC 6482, section 3. 245 * Returns zero on failure, non-zero on success. 246 */ 247 static int 248 roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p) 249 { 250 ASN1_SEQUENCE_ANY *seq; 251 int i = 0, rc = 0, sz; 252 const ASN1_TYPE *t; 253 254 /* RFC 6482, section 3. */ 255 256 if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) { 257 cryptowarnx("%s: RFC 6482 section 3: RouteOriginAttestation: " 258 "failed ASN.1 sequence parse", p->fn); 259 goto out; 260 } 261 262 if ((sz = sk_ASN1_TYPE_num(seq)) != 2 && sz != 3) { 263 warnx("%s: RFC 6482 section 3: RouteOriginAttestation: " 264 "want 2 or 3 elements, have %d", 265 p->fn, sk_ASN1_TYPE_num(seq)); 266 goto out; 267 } 268 269 /* RFC 6482, section 3.1. */ 270 271 if (sz == 3) { 272 t = sk_ASN1_TYPE_value(seq, i++); 273 274 /* 275 * This check with ASN1_INTEGER_get() is fine since 276 * we're looking for a value of zero anyway, so any 277 * overflowing number will be definition be wrong. 278 */ 279 280 if (t->type != V_ASN1_INTEGER) { 281 warnx("%s: RFC 6482 section 3.1: version: " 282 "want ASN.1 integer, have %s (NID %d)", 283 p->fn, ASN1_tag2str(t->type), t->type); 284 goto out; 285 } else if (ASN1_INTEGER_get(t->value.integer) != 0) { 286 warnx("%s: RFC 6482 section 3.1: version: " 287 "want version 0, have %ld", 288 p->fn, ASN1_INTEGER_get(t->value.integer)); 289 goto out; 290 } 291 } 292 293 /* 294 * RFC 6482, section 3.2. 295 * It doesn't ever actually state that AS numbers can't be 296 * negative, but...? 297 */ 298 299 t = sk_ASN1_TYPE_value(seq, i++); 300 if (t->type != V_ASN1_INTEGER) { 301 warnx("%s: RFC 6482 section 3.2: asID: " 302 "want ASN.1 integer, have %s (NID %d)", 303 p->fn, ASN1_tag2str(t->type), t->type); 304 goto out; 305 } else if (!as_id_parse(t->value.integer, &p->res->asid)) { 306 warnx("%s: RFC 6482 section 3.2: asID: " 307 "malformed AS identifier", p->fn); 308 goto out; 309 } 310 311 /* RFC 6482, section 3.3. */ 312 313 t = sk_ASN1_TYPE_value(seq, i++); 314 if (t->type != V_ASN1_SEQUENCE) { 315 warnx("%s: RFC 6482 section 3.3: ipAddrBlocks: " 316 "want ASN.1 sequence, have %s (NID %d)", 317 p->fn, ASN1_tag2str(t->type), t->type); 318 goto out; 319 } else if (!roa_parse_ipblocks(t->value.octet_string, p)) 320 goto out; 321 322 rc = 1; 323 out: 324 sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free); 325 return rc; 326 } 327 328 /* 329 * Parse a full RFC 6482 file. 330 * Returns the ROA or NULL if the document was malformed. 331 */ 332 struct roa * 333 roa_parse(X509 **x509, const char *fn) 334 { 335 struct parse p; 336 size_t cmsz; 337 unsigned char *cms; 338 int rc = 0; 339 340 memset(&p, 0, sizeof(struct parse)); 341 p.fn = fn; 342 343 /* OID from section 2, RFC 6482. */ 344 345 cms = cms_parse_validate(x509, fn, 346 "1.2.840.113549.1.9.16.1.24", &cmsz); 347 if (cms == NULL) 348 return NULL; 349 350 if ((p.res = calloc(1, sizeof(struct roa))) == NULL) 351 err(1, NULL); 352 if (!x509_get_ski_aki(*x509, fn, &p.res->ski, &p.res->aki)) 353 goto out; 354 if (!roa_parse_econtent(cms, cmsz, &p)) 355 goto out; 356 357 rc = 1; 358 out: 359 if (rc == 0) { 360 roa_free(p.res); 361 p.res = NULL; 362 X509_free(*x509); 363 *x509 = NULL; 364 } 365 free(cms); 366 return p.res; 367 368 } 369 370 /* 371 * Free an ROA pointer. 372 * Safe to call with NULL. 373 */ 374 void 375 roa_free(struct roa *p) 376 { 377 378 if (p == NULL) 379 return; 380 free(p->aki); 381 free(p->ski); 382 free(p->ips); 383 free(p->tal); 384 free(p); 385 } 386 387 /* 388 * Serialise parsed ROA content. 389 * See roa_read() for reader. 390 */ 391 void 392 roa_buffer(struct ibuf *b, const struct roa *p) 393 { 394 size_t i; 395 396 io_simple_buffer(b, &p->valid, sizeof(int)); 397 io_simple_buffer(b, &p->asid, sizeof(uint32_t)); 398 io_simple_buffer(b, &p->ipsz, sizeof(size_t)); 399 400 for (i = 0; i < p->ipsz; i++) { 401 io_simple_buffer(b, &p->ips[i].afi, sizeof(enum afi)); 402 io_simple_buffer(b, &p->ips[i].maxlength, sizeof(size_t)); 403 io_simple_buffer(b, p->ips[i].min, sizeof(p->ips[i].min)); 404 io_simple_buffer(b, p->ips[i].max, sizeof(p->ips[i].max)); 405 ip_addr_buffer(b, &p->ips[i].addr); 406 } 407 408 io_str_buffer(b, p->aki); 409 io_str_buffer(b, p->ski); 410 io_str_buffer(b, p->tal); 411 } 412 413 /* 414 * Read parsed ROA content from descriptor. 415 * See roa_buffer() for writer. 416 * Result must be passed to roa_free(). 417 */ 418 struct roa * 419 roa_read(int fd) 420 { 421 struct roa *p; 422 size_t i; 423 424 if ((p = calloc(1, sizeof(struct roa))) == NULL) 425 err(1, NULL); 426 427 io_simple_read(fd, &p->valid, sizeof(int)); 428 io_simple_read(fd, &p->asid, sizeof(uint32_t)); 429 io_simple_read(fd, &p->ipsz, sizeof(size_t)); 430 431 if ((p->ips = calloc(p->ipsz, sizeof(struct roa_ip))) == NULL) 432 err(1, NULL); 433 434 for (i = 0; i < p->ipsz; i++) { 435 io_simple_read(fd, &p->ips[i].afi, sizeof(enum afi)); 436 io_simple_read(fd, &p->ips[i].maxlength, sizeof(size_t)); 437 io_simple_read(fd, &p->ips[i].min, sizeof(p->ips[i].min)); 438 io_simple_read(fd, &p->ips[i].max, sizeof(p->ips[i].max)); 439 ip_addr_read(fd, &p->ips[i].addr); 440 } 441 442 io_str_read(fd, &p->aki); 443 io_str_read(fd, &p->ski); 444 io_str_read(fd, &p->tal); 445 assert(p->aki && p->ski && p->tal); 446 447 return p; 448 } 449 450 /* 451 * Add each IP address in the ROA into the VRP tree. 452 * Updates "vrps" to be the number of VRPs and "uniqs" to be the unique 453 * number of addresses. 454 */ 455 void 456 roa_insert_vrps(struct vrp_tree *tree, struct roa *roa, size_t *vrps, 457 size_t *uniqs) 458 { 459 struct vrp *v; 460 size_t i; 461 462 for (i = 0; i < roa->ipsz; i++) { 463 if ((v = malloc(sizeof(*v))) == NULL) 464 err(1, NULL); 465 v->afi = roa->ips[i].afi; 466 v->addr = roa->ips[i].addr; 467 v->maxlength = roa->ips[i].maxlength; 468 v->asid = roa->asid; 469 if ((v->tal = strdup(roa->tal)) == NULL) 470 err(1, NULL); 471 if (RB_INSERT(vrp_tree, tree, v) == NULL) 472 (*uniqs)++; 473 else /* already exists */ 474 free(v); 475 (*vrps)++; 476 } 477 } 478 479 static inline int 480 vrpcmp(struct vrp *a, struct vrp *b) 481 { 482 int rv; 483 484 if (a->afi > b->afi) 485 return 1; 486 if (a->afi < b->afi) 487 return -1; 488 switch (a->afi) { 489 case AFI_IPV4: 490 rv = memcmp(&a->addr.addr, &b->addr.addr, 4); 491 if (rv) 492 return rv; 493 break; 494 case AFI_IPV6: 495 rv = memcmp(&a->addr.addr, &b->addr.addr, 16); 496 if (rv) 497 return rv; 498 break; 499 } 500 /* a smaller prefixlen is considered bigger, e.g. /8 vs /10 */ 501 if (a->addr.prefixlen < b->addr.prefixlen) 502 return 1; 503 if (a->addr.prefixlen > b->addr.prefixlen) 504 return -1; 505 if (a->maxlength < b->maxlength) 506 return 1; 507 if (a->maxlength > b->maxlength) 508 return -1; 509 510 if (a->asid > b->asid) 511 return 1; 512 if (a->asid < b->asid) 513 return -1; 514 515 return 0; 516 } 517 518 RB_GENERATE(vrp_tree, vrp, entry, vrpcmp); 519