1 /* $OpenBSD: validate.c,v 1.62 2023/05/23 06:42:08 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 <arpa/inet.h> 19 #include <assert.h> 20 #include <ctype.h> 21 #include <err.h> 22 #include <fcntl.h> 23 #include <inttypes.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include "extern.h" 29 30 extern ASN1_OBJECT *certpol_oid; 31 32 /* 33 * Walk up the chain of certificates trying to match our AS number to 34 * one of the allocations in that chain. 35 * Returns 1 if covered or 0 if not. 36 */ 37 static int 38 valid_as(struct auth *a, uint32_t min, uint32_t max) 39 { 40 int c; 41 42 if (a == NULL) 43 return 0; 44 45 /* Does this certificate cover our AS number? */ 46 c = as_check_covered(min, max, a->cert->as, a->cert->asz); 47 if (c > 0) 48 return 1; 49 else if (c < 0) 50 return 0; 51 52 /* If it inherits, walk up the chain. */ 53 return valid_as(a->parent, min, max); 54 } 55 56 /* 57 * Walk up the chain of certificates (really just the last one, but in 58 * the case of inheritance, the ones before) making sure that our IP 59 * prefix is covered in the first non-inheriting specification. 60 * Returns 1 if covered or 0 if not. 61 */ 62 static int 63 valid_ip(struct auth *a, enum afi afi, 64 const unsigned char *min, const unsigned char *max) 65 { 66 int c; 67 68 if (a == NULL) 69 return 0; 70 71 /* Does this certificate cover our IP prefix? */ 72 c = ip_addr_check_covered(afi, min, max, a->cert->ips, a->cert->ipsz); 73 if (c > 0) 74 return 1; 75 else if (c < 0) 76 return 0; 77 78 /* If it inherits, walk up the chain. */ 79 return valid_ip(a->parent, afi, min, max); 80 } 81 82 /* 83 * Make sure the AKI is the same as the AKI listed on the Manifest, 84 * and that the SKI doesn't already exist. 85 * Return the parent by its AKI, or NULL on failure. 86 */ 87 struct auth * 88 valid_ski_aki(const char *fn, struct auth_tree *auths, 89 const char *ski, const char *aki, const char *mftaki) 90 { 91 struct auth *a; 92 93 if (mftaki != NULL) { 94 if (strcmp(aki, mftaki) != 0) { 95 warnx("%s: AKI doesn't match Manifest AKI", fn); 96 return NULL; 97 } 98 } 99 100 if (auth_find(auths, ski) != NULL) { 101 warnx("%s: RFC 6487: duplicate SKI", fn); 102 return NULL; 103 } 104 105 a = auth_find(auths, aki); 106 if (a == NULL) 107 warnx("%s: RFC 6487: unknown AKI", fn); 108 109 return a; 110 } 111 112 /* 113 * Validate a trust anchor by making sure that the SKI is unique. 114 * Returns 1 if valid, 0 otherwise. 115 */ 116 int 117 valid_ta(const char *fn, struct auth_tree *auths, const struct cert *cert) 118 { 119 /* SKI must not be a dupe. */ 120 if (auth_find(auths, cert->ski) != NULL) { 121 warnx("%s: RFC 6487: duplicate SKI", fn); 122 return 0; 123 } 124 125 return 1; 126 } 127 128 /* 129 * Validate a non-TA certificate: make sure its IP and AS resources are 130 * fully covered by those in the authority key (which must exist). 131 * Returns 1 if valid, 0 otherwise. 132 */ 133 int 134 valid_cert(const char *fn, struct auth *a, const struct cert *cert) 135 { 136 size_t i; 137 uint32_t min, max; 138 char buf1[64], buf2[64]; 139 140 for (i = 0; i < cert->asz; i++) { 141 if (cert->as[i].type == CERT_AS_INHERIT) 142 continue; 143 min = cert->as[i].type == CERT_AS_ID ? 144 cert->as[i].id : cert->as[i].range.min; 145 max = cert->as[i].type == CERT_AS_ID ? 146 cert->as[i].id : cert->as[i].range.max; 147 if (valid_as(a, min, max)) 148 continue; 149 warnx("%s: RFC 6487: uncovered AS: " 150 "%u--%u", fn, min, max); 151 return 0; 152 } 153 154 for (i = 0; i < cert->ipsz; i++) { 155 if (cert->ips[i].type == CERT_IP_INHERIT) 156 continue; 157 if (valid_ip(a, cert->ips[i].afi, cert->ips[i].min, 158 cert->ips[i].max)) 159 continue; 160 switch (cert->ips[i].type) { 161 case CERT_IP_RANGE: 162 ip_addr_print(&cert->ips[i].range.min, 163 cert->ips[i].afi, buf1, sizeof(buf1)); 164 ip_addr_print(&cert->ips[i].range.max, 165 cert->ips[i].afi, buf2, sizeof(buf2)); 166 warnx("%s: RFC 6487: uncovered IP: " 167 "%s--%s", fn, buf1, buf2); 168 break; 169 case CERT_IP_ADDR: 170 ip_addr_print(&cert->ips[i].ip, 171 cert->ips[i].afi, buf1, sizeof(buf1)); 172 warnx("%s: RFC 6487: uncovered IP: " 173 "%s", fn, buf1); 174 break; 175 case CERT_IP_INHERIT: 176 warnx("%s: RFC 6487: uncovered IP: " 177 "(inherit)", fn); 178 break; 179 } 180 return 0; 181 } 182 183 return 1; 184 } 185 186 /* 187 * Validate our ROA: check that the prefixes (ipAddrBlocks) are contained. 188 * Returns 1 if valid, 0 otherwise. 189 */ 190 int 191 valid_roa(const char *fn, struct cert *cert, struct roa *roa) 192 { 193 size_t i; 194 char buf[64]; 195 196 for (i = 0; i < roa->ipsz; i++) { 197 if (ip_addr_check_covered(roa->ips[i].afi, roa->ips[i].min, 198 roa->ips[i].max, cert->ips, cert->ipsz) > 0) 199 continue; 200 201 ip_addr_print(&roa->ips[i].addr, roa->ips[i].afi, buf, 202 sizeof(buf)); 203 warnx("%s: RFC 6482: uncovered IP: %s", fn, buf); 204 return 0; 205 } 206 207 return 1; 208 } 209 210 /* 211 * Validate a file by verifying the SHA256 hash of that file. 212 * The file to check is passed as a file descriptor. 213 * Returns 1 if hash matched, 0 otherwise. Closes fd when done. 214 */ 215 int 216 valid_filehash(int fd, const char *hash, size_t hlen) 217 { 218 SHA256_CTX ctx; 219 char filehash[SHA256_DIGEST_LENGTH]; 220 char buffer[8192]; 221 ssize_t nr; 222 223 if (hlen != sizeof(filehash)) 224 errx(1, "bad hash size"); 225 226 if (fd == -1) 227 return 0; 228 229 SHA256_Init(&ctx); 230 while ((nr = read(fd, buffer, sizeof(buffer))) > 0) 231 SHA256_Update(&ctx, buffer, nr); 232 close(fd); 233 SHA256_Final(filehash, &ctx); 234 235 if (memcmp(hash, filehash, sizeof(filehash)) != 0) 236 return 0; 237 return 1; 238 } 239 240 /* 241 * Same as above but with a buffer instead of a fd. 242 */ 243 int 244 valid_hash(unsigned char *buf, size_t len, const char *hash, size_t hlen) 245 { 246 char filehash[SHA256_DIGEST_LENGTH]; 247 248 if (hlen != sizeof(filehash)) 249 errx(1, "bad hash size"); 250 251 if (buf == NULL || len == 0) 252 return 0; 253 254 if (!EVP_Digest(buf, len, filehash, NULL, EVP_sha256(), NULL)) 255 errx(1, "EVP_Digest failed"); 256 257 if (memcmp(hash, filehash, sizeof(filehash)) != 0) 258 return 0; 259 return 1; 260 } 261 262 /* 263 * Validate that a filename only contains characters from the POSIX portable 264 * filename character set [A-Za-z0-9._-], see IEEE Std 1003.1-2013, 3.278. 265 */ 266 int 267 valid_filename(const char *fn, size_t len) 268 { 269 const unsigned char *c; 270 size_t i; 271 272 for (c = fn, i = 0; i < len; i++, c++) 273 if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.') 274 return 0; 275 return 1; 276 } 277 278 /* 279 * Validate a URI to make sure it is pure ASCII and does not point backwards 280 * or doing some other silly tricks. To enforce the protocol pass either 281 * https:// or rsync:// as proto, if NULL is passed no protocol is enforced. 282 * Returns 1 if valid, 0 otherwise. 283 */ 284 int 285 valid_uri(const char *uri, size_t usz, const char *proto) 286 { 287 size_t s; 288 289 if (usz > MAX_URI_LENGTH) 290 return 0; 291 292 for (s = 0; s < usz; s++) 293 if (!isalnum((unsigned char)uri[s]) && 294 !ispunct((unsigned char)uri[s])) 295 return 0; 296 297 if (proto != NULL) { 298 s = strlen(proto); 299 if (s >= usz) 300 return 0; 301 if (strncasecmp(uri, proto, s) != 0) 302 return 0; 303 } 304 305 /* do not allow files or directories to start with a '.' */ 306 if (strstr(uri, "/.") != NULL) 307 return 0; 308 309 return 1; 310 } 311 312 /* 313 * Validate that a URI has the same host as the URI passed in proto. 314 * Returns 1 if valid, 0 otherwise. 315 */ 316 int 317 valid_origin(const char *uri, const char *proto) 318 { 319 const char *to; 320 321 /* extract end of host from proto URI */ 322 to = strstr(proto, "://"); 323 if (to == NULL) 324 return 0; 325 to += strlen("://"); 326 if ((to = strchr(to, '/')) == NULL) 327 return 0; 328 329 /* compare hosts including the / for the start of the path section */ 330 if (strncasecmp(uri, proto, to - proto + 1) != 0) 331 return 0; 332 333 return 1; 334 } 335 336 /* 337 * Walk the tree of known valid CA certificates until we find a certificate that 338 * doesn't inherit. Build a chain of intermediates and use the non-inheriting 339 * certificate as a trusted root by virtue of X509_V_FLAG_PARTIAL_CHAIN. The 340 * RFC 3779 path validation needs a non-inheriting trust root to ensure that 341 * all delegated resources are covered. 342 */ 343 static void 344 build_chain(const struct auth *a, STACK_OF(X509) **intermediates, 345 STACK_OF(X509) **root) 346 { 347 *intermediates = NULL; 348 *root = NULL; 349 350 if (a == NULL) 351 return; 352 353 if ((*intermediates = sk_X509_new_null()) == NULL) 354 err(1, "sk_X509_new_null"); 355 if ((*root = sk_X509_new_null()) == NULL) 356 err(1, "sk_X509_new_null"); 357 for (; a != NULL; a = a->parent) { 358 assert(a->cert->x509 != NULL); 359 if (!a->any_inherits) { 360 if (!sk_X509_push(*root, a->cert->x509)) 361 errx(1, "sk_X509_push"); 362 break; 363 } 364 if (!sk_X509_push(*intermediates, a->cert->x509)) 365 errx(1, "sk_X509_push"); 366 } 367 assert(sk_X509_num(*root) == 1); 368 } 369 370 /* 371 * Add the CRL based on the certs SKI value. 372 * No need to insert any other CRL since those were already checked. 373 */ 374 static void 375 build_crls(const struct crl *crl, STACK_OF(X509_CRL) **crls) 376 { 377 *crls = NULL; 378 379 if (crl == NULL) 380 return; 381 if ((*crls = sk_X509_CRL_new_null()) == NULL) 382 errx(1, "sk_X509_CRL_new_null"); 383 if (!sk_X509_CRL_push(*crls, crl->x509_crl)) 384 err(1, "sk_X509_CRL_push"); 385 } 386 387 /* 388 * Validate the X509 certificate. Returns 1 for valid certificates, 389 * returns 0 if there is a verify error and sets *errstr to the error 390 * returned by X509_verify_cert_error_string(). 391 */ 392 int 393 valid_x509(char *file, X509_STORE_CTX *store_ctx, X509 *x509, struct auth *a, 394 struct crl *crl, const char **errstr) 395 { 396 X509_VERIFY_PARAM *params; 397 ASN1_OBJECT *cp_oid; 398 STACK_OF(X509) *intermediates, *root; 399 STACK_OF(X509_CRL) *crls = NULL; 400 unsigned long flags; 401 int error; 402 403 *errstr = NULL; 404 build_chain(a, &intermediates, &root); 405 build_crls(crl, &crls); 406 407 assert(store_ctx != NULL); 408 assert(x509 != NULL); 409 if (!X509_STORE_CTX_init(store_ctx, NULL, x509, NULL)) 410 cryptoerrx("X509_STORE_CTX_init"); 411 412 if ((params = X509_STORE_CTX_get0_param(store_ctx)) == NULL) 413 cryptoerrx("X509_STORE_CTX_get0_param"); 414 if ((cp_oid = OBJ_dup(certpol_oid)) == NULL) 415 cryptoerrx("OBJ_dup"); 416 if (!X509_VERIFY_PARAM_add0_policy(params, cp_oid)) 417 cryptoerrx("X509_VERIFY_PARAM_add0_policy"); 418 X509_VERIFY_PARAM_set_time(params, evaluation_time); 419 420 flags = X509_V_FLAG_CRL_CHECK; 421 flags |= X509_V_FLAG_PARTIAL_CHAIN; 422 flags |= X509_V_FLAG_POLICY_CHECK; 423 flags |= X509_V_FLAG_EXPLICIT_POLICY; 424 flags |= X509_V_FLAG_INHIBIT_MAP; 425 X509_STORE_CTX_set_flags(store_ctx, flags); 426 X509_STORE_CTX_set_depth(store_ctx, MAX_CERT_DEPTH); 427 /* 428 * See the comment above build_chain() for details on what's happening 429 * here. The nomenclature in this API is dubious and poorly documented. 430 */ 431 X509_STORE_CTX_set0_untrusted(store_ctx, intermediates); 432 X509_STORE_CTX_set0_trusted_stack(store_ctx, root); 433 X509_STORE_CTX_set0_crls(store_ctx, crls); 434 435 if (X509_verify_cert(store_ctx) <= 0) { 436 error = X509_STORE_CTX_get_error(store_ctx); 437 *errstr = X509_verify_cert_error_string(error); 438 X509_STORE_CTX_cleanup(store_ctx); 439 sk_X509_free(intermediates); 440 sk_X509_free(root); 441 sk_X509_CRL_free(crls); 442 return 0; 443 } 444 445 X509_STORE_CTX_cleanup(store_ctx); 446 sk_X509_free(intermediates); 447 sk_X509_free(root); 448 sk_X509_CRL_free(crls); 449 return 1; 450 } 451 452 /* 453 * Validate our RSC: check that all items in the ResourceBlock are contained. 454 * Returns 1 if valid, 0 otherwise. 455 */ 456 int 457 valid_rsc(const char *fn, struct cert *cert, struct rsc *rsc) 458 { 459 size_t i; 460 uint32_t min, max; 461 char buf1[64], buf2[64]; 462 463 for (i = 0; i < rsc->asz; i++) { 464 min = rsc->as[i].type == CERT_AS_RANGE ? rsc->as[i].range.min 465 : rsc->as[i].id; 466 max = rsc->as[i].type == CERT_AS_RANGE ? rsc->as[i].range.max 467 : rsc->as[i].id; 468 469 if (as_check_covered(min, max, cert->as, cert->asz) > 0) 470 continue; 471 472 switch (rsc->as[i].type) { 473 case CERT_AS_ID: 474 warnx("%s: RSC resourceBlock: uncovered AS Identifier: " 475 "%u", fn, rsc->as[i].id); 476 break; 477 case CERT_AS_RANGE: 478 warnx("%s: RSC resourceBlock: uncovered AS Range: " 479 "%u--%u", fn, min, max); 480 break; 481 default: 482 break; 483 } 484 return 0; 485 } 486 487 for (i = 0; i < rsc->ipsz; i++) { 488 if (ip_addr_check_covered(rsc->ips[i].afi, rsc->ips[i].min, 489 rsc->ips[i].max, cert->ips, cert->ipsz) > 0) 490 continue; 491 492 switch (rsc->ips[i].type) { 493 case CERT_IP_RANGE: 494 ip_addr_print(&rsc->ips[i].range.min, 495 rsc->ips[i].afi, buf1, sizeof(buf1)); 496 ip_addr_print(&rsc->ips[i].range.max, 497 rsc->ips[i].afi, buf2, sizeof(buf2)); 498 warnx("%s: RSC ResourceBlock: uncovered IP Range: " 499 "%s--%s", fn, buf1, buf2); 500 break; 501 case CERT_IP_ADDR: 502 ip_addr_print(&rsc->ips[i].ip, 503 rsc->ips[i].afi, buf1, sizeof(buf1)); 504 warnx("%s: RSC ResourceBlock: uncovered IP: " 505 "%s", fn, buf1); 506 break; 507 default: 508 break; 509 } 510 return 0; 511 } 512 513 return 1; 514 } 515 516 int 517 valid_econtent_version(const char *fn, const ASN1_INTEGER *aint) 518 { 519 uint64_t version; 520 521 if (aint == NULL) 522 return 1; 523 524 if (!ASN1_INTEGER_get_uint64(&version, aint)) { 525 warnx("%s: ASN1_INTEGER_get_uint64 failed", fn); 526 return 0; 527 } 528 529 switch (version) { 530 case 0: 531 warnx("%s: incorrect encoding for version 0", fn); 532 return 0; 533 default: 534 warnx("%s: version %llu not supported (yet)", fn, 535 (unsigned long long)version); 536 return 0; 537 } 538 } 539 540 /* 541 * Validate the ASPA: check that the customerASID is contained. 542 * Returns 1 if valid, 0 otherwise. 543 */ 544 int 545 valid_aspa(const char *fn, struct cert *cert, struct aspa *aspa) 546 { 547 548 if (as_check_covered(aspa->custasid, aspa->custasid, 549 cert->as, cert->asz) > 0) 550 return 1; 551 552 warnx("%s: ASPA: uncovered Customer ASID: %u", fn, aspa->custasid); 553 554 return 0; 555 } 556 557 /* 558 * Validate Geofeed prefixes: check that the prefixes are contained. 559 * Returns 1 if valid, 0 otherwise. 560 */ 561 int 562 valid_geofeed(const char *fn, struct cert *cert, struct geofeed *g) 563 { 564 size_t i; 565 char buf[64]; 566 567 for (i = 0; i < g->geoipsz; i++) { 568 if (ip_addr_check_covered(g->geoips[i].ip->afi, 569 g->geoips[i].ip->min, g->geoips[i].ip->max, cert->ips, 570 cert->ipsz) > 0) 571 continue; 572 573 ip_addr_print(&g->geoips[i].ip->ip, g->geoips[i].ip->afi, buf, 574 sizeof(buf)); 575 warnx("%s: Geofeed: uncovered IP: %s", fn, buf); 576 return 0; 577 } 578 579 return 1; 580 } 581 582 /* 583 * Validate whether a given string is a valid UUID. 584 * Returns 1 if valid, 0 otherwise. 585 */ 586 int 587 valid_uuid(const char *s) 588 { 589 int n = 0; 590 591 while (1) { 592 switch (n) { 593 case 8: 594 case 13: 595 case 18: 596 case 23: 597 if (s[n] != '-') 598 return 0; 599 break; 600 /* Check UUID is version 4 */ 601 case 14: 602 if (s[n] != '4') 603 return 0; 604 break; 605 /* Check UUID variant is 1 */ 606 case 19: 607 if (s[n] != '8' && s[n] != '9' && s[n] != 'a' && 608 s[n] != 'A' && s[n] != 'b' && s[n] != 'B') 609 return 0; 610 break; 611 case 36: 612 return s[n] == '\0'; 613 default: 614 if (!isxdigit((unsigned char)s[n])) 615 return 0; 616 break; 617 } 618 n++; 619 } 620 } 621 622 int 623 valid_ca_pkey(const char *fn, EVP_PKEY *pkey) 624 { 625 RSA *rsa; 626 const BIGNUM *rsa_e; 627 int key_bits; 628 629 if (pkey == NULL) { 630 warnx("%s: failure, pkey is NULL", fn); 631 return 0; 632 } 633 634 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { 635 warnx("%s: Expected EVP_PKEY_RSA, got %d", fn, 636 EVP_PKEY_base_id(pkey)); 637 return 0; 638 } 639 640 if ((key_bits = EVP_PKEY_bits(pkey)) != 2048) { 641 warnx("%s: RFC 7935: expected 2048-bit modulus, got %d bits", 642 fn, key_bits); 643 return 0; 644 } 645 646 if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { 647 warnx("%s: failed to extract RSA public key", fn); 648 return 0; 649 } 650 651 if ((rsa_e = RSA_get0_e(rsa)) == NULL) { 652 warnx("%s: failed to get RSA exponent", fn); 653 return 0; 654 } 655 656 if (!BN_is_word(rsa_e, 65537)) { 657 warnx("%s: incorrect exponent (e) in RSA public key", fn); 658 return 0; 659 } 660 661 return 1; 662 } 663