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