diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_policy.c | 133 |
1 files changed, 49 insertions, 84 deletions
diff --git a/src/lib/libcrypto/x509/x509_policy.c b/src/lib/libcrypto/x509/x509_policy.c index 85286080f1..3a3a7555ca 100644 --- a/src/lib/libcrypto/x509/x509_policy.c +++ b/src/lib/libcrypto/x509/x509_policy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_policy.c,v 1.13 2023/04/27 08:04:40 tb Exp $ */ | 1 | /* $OpenBSD: x509_policy.c,v 1.14 2023/04/27 08:07:26 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022, Google Inc. | 3 | * Copyright (c) 2022, Google Inc. |
| 4 | * | 4 | * |
| @@ -246,7 +246,7 @@ x509_policy_level_new(void) | |||
| 246 | if ((level = calloc(1, sizeof(*level))) == NULL) | 246 | if ((level = calloc(1, sizeof(*level))) == NULL) |
| 247 | goto err; | 247 | goto err; |
| 248 | level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); | 248 | level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); |
| 249 | if (level->nodes== NULL) | 249 | if (level->nodes == NULL) |
| 250 | goto err; | 250 | goto err; |
| 251 | 251 | ||
| 252 | return level; | 252 | return level; |
| @@ -288,9 +288,8 @@ x509_policy_level_find(X509_POLICY_LEVEL *level, | |||
| 288 | X509_POLICY_NODE node; | 288 | X509_POLICY_NODE node; |
| 289 | node.policy = (ASN1_OBJECT *)policy; | 289 | node.policy = (ASN1_OBJECT *)policy; |
| 290 | int idx; | 290 | int idx; |
| 291 | if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) { | 291 | if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) |
| 292 | return NULL; | 292 | return NULL; |
| 293 | } | ||
| 294 | return sk_X509_POLICY_NODE_value(level->nodes, idx); | 293 | return sk_X509_POLICY_NODE_value(level->nodes, idx); |
| 295 | } | 294 | } |
| 296 | 295 | ||
| @@ -311,9 +310,8 @@ x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, | |||
| 311 | 310 | ||
| 312 | for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { | 311 | for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { |
| 313 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); | 312 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); |
| 314 | if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { | 313 | if (!sk_X509_POLICY_NODE_push(level->nodes, node)) |
| 315 | return 0; | 314 | return 0; |
| 316 | } | ||
| 317 | sk_X509_POLICY_NODE_set(nodes, i, NULL); | 315 | sk_X509_POLICY_NODE_set(nodes, i, NULL); |
| 318 | } | 316 | } |
| 319 | sk_X509_POLICY_NODE_sort(level->nodes); | 317 | sk_X509_POLICY_NODE_sort(level->nodes); |
| @@ -344,9 +342,8 @@ delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) | |||
| 344 | assert(sk_POLICYINFO_is_sorted(policies)); | 342 | assert(sk_POLICYINFO_is_sorted(policies)); |
| 345 | POLICYINFO info; | 343 | POLICYINFO info; |
| 346 | info.policyid = node->policy; | 344 | info.policyid = node->policy; |
| 347 | if (sk_POLICYINFO_find(policies, &info) >= 0) { | 345 | if (sk_POLICYINFO_find(policies, &info) >= 0) |
| 348 | return 0; | 346 | return 0; |
| 349 | } | ||
| 350 | x509_policy_node_free(node); | 347 | x509_policy_node_free(node); |
| 351 | return 1; | 348 | return 1; |
| 352 | } | 349 | } |
| @@ -373,9 +370,8 @@ process_certificate_policies(const X509 *x509, | |||
| 373 | CERTIFICATEPOLICIES *policies = | 370 | CERTIFICATEPOLICIES *policies = |
| 374 | X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL); | 371 | X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL); |
| 375 | if (policies == NULL) { | 372 | if (policies == NULL) { |
| 376 | if (critical != -1) { | 373 | if (critical != -1) |
| 377 | return 0; /* Syntax error in the extension. */ | 374 | return 0; /* Syntax error in the extension. */ |
| 378 | } | ||
| 379 | 375 | ||
| 380 | /* RFC 5280, section 6.1.3, step (e). */ | 376 | /* RFC 5280, section 6.1.3, step (e). */ |
| 381 | x509_policy_level_clear(level); | 377 | x509_policy_level_clear(level); |
| @@ -396,9 +392,8 @@ process_certificate_policies(const X509 *x509, | |||
| 396 | int cert_has_any_policy = 0; | 392 | int cert_has_any_policy = 0; |
| 397 | for (i = 0; i < sk_POLICYINFO_num(policies); i++) { | 393 | for (i = 0; i < sk_POLICYINFO_num(policies); i++) { |
| 398 | const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); | 394 | const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); |
| 399 | if (is_any_policy(policy->policyid)) { | 395 | if (is_any_policy(policy->policyid)) |
| 400 | cert_has_any_policy = 1; | 396 | cert_has_any_policy = 1; |
| 401 | } | ||
| 402 | if (i > 0 && | 397 | if (i > 0 && |
| 403 | OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, | 398 | OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, |
| 404 | policy->policyid) == 0) { | 399 | policy->policyid) == 0) { |
| @@ -436,9 +431,8 @@ process_certificate_policies(const X509 *x509, | |||
| 436 | */ | 431 | */ |
| 437 | if (previous_level_has_any_policy) { | 432 | if (previous_level_has_any_policy) { |
| 438 | new_nodes = sk_X509_POLICY_NODE_new_null(); | 433 | new_nodes = sk_X509_POLICY_NODE_new_null(); |
| 439 | if (new_nodes == NULL) { | 434 | if (new_nodes == NULL) |
| 440 | goto err; | 435 | goto err; |
| 441 | } | ||
| 442 | for (i = 0; i < sk_POLICYINFO_num(policies); i++) { | 436 | for (i = 0; i < sk_POLICYINFO_num(policies); i++) { |
| 443 | const POLICYINFO *policy = sk_POLICYINFO_value(policies, | 437 | const POLICYINFO *policy = sk_POLICYINFO_value(policies, |
| 444 | i); | 438 | i); |
| @@ -460,9 +454,8 @@ process_certificate_policies(const X509 *x509, | |||
| 460 | } | 454 | } |
| 461 | } | 455 | } |
| 462 | } | 456 | } |
| 463 | if (!x509_policy_level_add_nodes(level, new_nodes)) { | 457 | if (!x509_policy_level_add_nodes(level, new_nodes)) |
| 464 | goto err; | 458 | goto err; |
| 465 | } | ||
| 466 | } | 459 | } |
| 467 | 460 | ||
| 468 | ret = 1; | 461 | ret = 1; |
| @@ -495,9 +488,8 @@ delete_if_mapped(X509_POLICY_NODE *node, void *data) | |||
| 495 | assert(sk_POLICY_MAPPING_is_sorted(mappings)); | 488 | assert(sk_POLICY_MAPPING_is_sorted(mappings)); |
| 496 | POLICY_MAPPING mapping; | 489 | POLICY_MAPPING mapping; |
| 497 | mapping.issuerDomainPolicy = node->policy; | 490 | mapping.issuerDomainPolicy = node->policy; |
| 498 | if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) { | 491 | if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) |
| 499 | return 0; | 492 | return 0; |
| 500 | } | ||
| 501 | x509_policy_node_free(node); | 493 | x509_policy_node_free(node); |
| 502 | return 1; | 494 | return 1; |
| 503 | } | 495 | } |
| @@ -527,9 +519,9 @@ process_policy_mappings(const X509 *cert, | |||
| 527 | { | 519 | { |
| 528 | size_t i; | 520 | size_t i; |
| 529 | int ok = 0; | 521 | int ok = 0; |
| 522 | int critical; | ||
| 530 | STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; | 523 | STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; |
| 531 | X509_POLICY_LEVEL *next = NULL; | 524 | X509_POLICY_LEVEL *next = NULL; |
| 532 | int critical; | ||
| 533 | POLICY_MAPPINGS *mappings = | 525 | POLICY_MAPPINGS *mappings = |
| 534 | X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); | 526 | X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); |
| 535 | if (mappings == NULL && critical != -1) { | 527 | if (mappings == NULL && critical != -1) { |
| @@ -550,11 +542,11 @@ process_policy_mappings(const X509 *cert, | |||
| 550 | 542 | ||
| 551 | /* RFC 5280, section 6.1.4, step (a). */ | 543 | /* RFC 5280, section 6.1.4, step (a). */ |
| 552 | for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { | 544 | for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { |
| 553 | POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); | 545 | POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, |
| 546 | i); | ||
| 554 | if (is_any_policy(mapping->issuerDomainPolicy) || | 547 | if (is_any_policy(mapping->issuerDomainPolicy) || |
| 555 | is_any_policy(mapping->subjectDomainPolicy)) { | 548 | is_any_policy(mapping->subjectDomainPolicy)) |
| 556 | goto err; | 549 | goto err; |
| 557 | } | ||
| 558 | } | 550 | } |
| 559 | 551 | ||
| 560 | /* Sort to group by issuerDomainPolicy. */ | 552 | /* Sort to group by issuerDomainPolicy. */ |
| @@ -568,9 +560,8 @@ process_policy_mappings(const X509 *cert, | |||
| 568 | * section 6.1.4, step (b.1). | 560 | * section 6.1.4, step (b.1). |
| 569 | */ | 561 | */ |
| 570 | new_nodes = sk_X509_POLICY_NODE_new_null(); | 562 | new_nodes = sk_X509_POLICY_NODE_new_null(); |
| 571 | if (new_nodes == NULL) { | 563 | if (new_nodes == NULL) |
| 572 | goto err; | 564 | goto err; |
| 573 | } | ||
| 574 | const ASN1_OBJECT *last_policy = NULL; | 565 | const ASN1_OBJECT *last_policy = NULL; |
| 575 | for (i = 0; i < sk_POLICY_MAPPING_num(mappings); | 566 | for (i = 0; i < sk_POLICY_MAPPING_num(mappings); |
| 576 | i++) { | 567 | i++) { |
| @@ -582,18 +573,16 @@ process_policy_mappings(const X509 *cert, | |||
| 582 | */ | 573 | */ |
| 583 | if (last_policy != NULL && | 574 | if (last_policy != NULL && |
| 584 | OBJ_cmp(mapping->issuerDomainPolicy, | 575 | OBJ_cmp(mapping->issuerDomainPolicy, |
| 585 | last_policy) == 0) { | 576 | last_policy) == 0) |
| 586 | continue; | 577 | continue; |
| 587 | } | ||
| 588 | last_policy = mapping->issuerDomainPolicy; | 578 | last_policy = mapping->issuerDomainPolicy; |
| 589 | 579 | ||
| 590 | X509_POLICY_NODE *node = | 580 | X509_POLICY_NODE *node = |
| 591 | x509_policy_level_find(level, | 581 | x509_policy_level_find(level, |
| 592 | mapping->issuerDomainPolicy); | 582 | mapping->issuerDomainPolicy); |
| 593 | if (node == NULL) { | 583 | if (node == NULL) { |
| 594 | if (!level->has_any_policy) { | 584 | if (!level->has_any_policy) |
| 595 | continue; | 585 | continue; |
| 596 | } | ||
| 597 | node = x509_policy_node_new( | 586 | node = x509_policy_node_new( |
| 598 | mapping->issuerDomainPolicy); | 587 | mapping->issuerDomainPolicy); |
| 599 | if (node == NULL || | 588 | if (node == NULL || |
| @@ -605,9 +594,8 @@ process_policy_mappings(const X509 *cert, | |||
| 605 | } | 594 | } |
| 606 | node->mapped = 1; | 595 | node->mapped = 1; |
| 607 | } | 596 | } |
| 608 | if (!x509_policy_level_add_nodes(level, new_nodes)) { | 597 | if (!x509_policy_level_add_nodes(level, new_nodes)) |
| 609 | goto err; | 598 | goto err; |
| 610 | } | ||
| 611 | } else { | 599 | } else { |
| 612 | /* | 600 | /* |
| 613 | * RFC 5280, section 6.1.4, step (b.2). If mapping is | 601 | * RFC 5280, section 6.1.4, step (b.2). If mapping is |
| @@ -627,18 +615,16 @@ process_policy_mappings(const X509 *cert, | |||
| 627 | */ | 615 | */ |
| 628 | if (mappings == NULL) { | 616 | if (mappings == NULL) { |
| 629 | mappings = sk_POLICY_MAPPING_new_null(); | 617 | mappings = sk_POLICY_MAPPING_new_null(); |
| 630 | if (mappings == NULL) { | 618 | if (mappings == NULL) |
| 631 | goto err; | 619 | goto err; |
| 632 | } | ||
| 633 | } | 620 | } |
| 634 | for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { | 621 | for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { |
| 635 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, | 622 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, |
| 636 | i); | 623 | i); |
| 637 | if (!node->mapped) { | 624 | if (!node->mapped) { |
| 638 | POLICY_MAPPING *mapping = POLICY_MAPPING_new(); | 625 | POLICY_MAPPING *mapping = POLICY_MAPPING_new(); |
| 639 | if (mapping == NULL) { | 626 | if (mapping == NULL) |
| 640 | goto err; | 627 | goto err; |
| 641 | } | ||
| 642 | mapping->issuerDomainPolicy = OBJ_dup(node->policy); | 628 | mapping->issuerDomainPolicy = OBJ_dup(node->policy); |
| 643 | mapping->subjectDomainPolicy = OBJ_dup(node->policy); | 629 | mapping->subjectDomainPolicy = OBJ_dup(node->policy); |
| 644 | if (mapping->issuerDomainPolicy == NULL || | 630 | if (mapping->issuerDomainPolicy == NULL || |
| @@ -656,9 +642,8 @@ process_policy_mappings(const X509 *cert, | |||
| 656 | 642 | ||
| 657 | /* Convert |mappings| to our "expected_policy_set" representation. */ | 643 | /* Convert |mappings| to our "expected_policy_set" representation. */ |
| 658 | next = x509_policy_level_new(); | 644 | next = x509_policy_level_new(); |
| 659 | if (next == NULL) { | 645 | if (next == NULL) |
| 660 | goto err; | 646 | goto err; |
| 661 | } | ||
| 662 | next->has_any_policy = level->has_any_policy; | 647 | next->has_any_policy = level->has_any_policy; |
| 663 | 648 | ||
| 664 | X509_POLICY_NODE *last_node = NULL; | 649 | X509_POLICY_NODE *last_node = NULL; |
| @@ -670,9 +655,8 @@ process_policy_mappings(const X509 *cert, | |||
| 670 | */ | 655 | */ |
| 671 | if (!level->has_any_policy && | 656 | if (!level->has_any_policy && |
| 672 | x509_policy_level_find(level, | 657 | x509_policy_level_find(level, |
| 673 | mapping->issuerDomainPolicy) == NULL) { | 658 | mapping->issuerDomainPolicy) == NULL) |
| 674 | continue; | 659 | continue; |
| 675 | } | ||
| 676 | 660 | ||
| 677 | if (last_node == NULL || | 661 | if (last_node == NULL || |
| 678 | OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != | 662 | OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != |
| @@ -687,9 +671,8 @@ process_policy_mappings(const X509 *cert, | |||
| 687 | } | 671 | } |
| 688 | 672 | ||
| 689 | if (!sk_ASN1_OBJECT_push(last_node->parent_policies, | 673 | if (!sk_ASN1_OBJECT_push(last_node->parent_policies, |
| 690 | mapping->issuerDomainPolicy)) { | 674 | mapping->issuerDomainPolicy)) |
| 691 | goto err; | 675 | goto err; |
| 692 | } | ||
| 693 | mapping->issuerDomainPolicy = NULL; | 676 | mapping->issuerDomainPolicy = NULL; |
| 694 | } | 677 | } |
| 695 | 678 | ||
| @@ -715,9 +698,8 @@ err: | |||
| 715 | static int | 698 | static int |
| 716 | apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) | 699 | apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) |
| 717 | { | 700 | { |
| 718 | if (skip_certs == NULL) { | 701 | if (skip_certs == NULL) |
| 719 | return 1; | 702 | return 1; |
| 720 | } | ||
| 721 | 703 | ||
| 722 | /* TODO(https://crbug.com/boringssl/443): Move this check into the parser. */ | 704 | /* TODO(https://crbug.com/boringssl/443): Move this check into the parser. */ |
| 723 | if (skip_certs->type & V_ASN1_NEG) { | 705 | if (skip_certs->type & V_ASN1_NEG) { |
| @@ -727,9 +709,8 @@ apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) | |||
| 727 | 709 | ||
| 728 | /* If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. */ | 710 | /* If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. */ |
| 729 | uint64_t u64; | 711 | uint64_t u64; |
| 730 | if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) { | 712 | if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) |
| 731 | *value = (size_t)u64; | 713 | *value = (size_t)u64; |
| 732 | } | ||
| 733 | ERR_clear_error(); | 714 | ERR_clear_error(); |
| 734 | return 1; | 715 | return 1; |
| 735 | } | 716 | } |
| @@ -748,9 +729,8 @@ process_policy_constraints(const X509 *x509, size_t *explicit_policy, | |||
| 748 | int critical; | 729 | int critical; |
| 749 | POLICY_CONSTRAINTS *constraints = | 730 | POLICY_CONSTRAINTS *constraints = |
| 750 | X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL); | 731 | X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL); |
| 751 | if (constraints == NULL && critical != -1) { | 732 | if (constraints == NULL && critical != -1) |
| 752 | return 0; | 733 | return 0; |
| 753 | } | ||
| 754 | if (constraints != NULL) { | 734 | if (constraints != NULL) { |
| 755 | if (constraints->requireExplicitPolicy == NULL && | 735 | if (constraints->requireExplicitPolicy == NULL && |
| 756 | constraints->inhibitPolicyMapping == NULL) { | 736 | constraints->inhibitPolicyMapping == NULL) { |
| @@ -768,16 +748,14 @@ process_policy_constraints(const X509 *x509, size_t *explicit_policy, | |||
| 768 | apply_skip_certs(constraints->inhibitPolicyMapping, | 748 | apply_skip_certs(constraints->inhibitPolicyMapping, |
| 769 | policy_mapping); | 749 | policy_mapping); |
| 770 | POLICY_CONSTRAINTS_free(constraints); | 750 | POLICY_CONSTRAINTS_free(constraints); |
| 771 | if (!ok) { | 751 | if (!ok) |
| 772 | return 0; | 752 | return 0; |
| 773 | } | ||
| 774 | } | 753 | } |
| 775 | 754 | ||
| 776 | ASN1_INTEGER *inhibit_any_policy_ext = | 755 | ASN1_INTEGER *inhibit_any_policy_ext = |
| 777 | X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL); | 756 | X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL); |
| 778 | if (inhibit_any_policy_ext == NULL && critical != -1) { | 757 | if (inhibit_any_policy_ext == NULL && critical != -1) |
| 779 | return 0; | 758 | return 0; |
| 780 | } | ||
| 781 | int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); | 759 | int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); |
| 782 | ASN1_INTEGER_free(inhibit_any_policy_ext); | 760 | ASN1_INTEGER_free(inhibit_any_policy_ext); |
| 783 | return ok; | 761 | return ok; |
| @@ -803,9 +781,8 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 803 | size_t num_levels = sk_X509_POLICY_LEVEL_num(levels); | 781 | size_t num_levels = sk_X509_POLICY_LEVEL_num(levels); |
| 804 | X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, | 782 | X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, |
| 805 | num_levels - 1); | 783 | num_levels - 1); |
| 806 | if (x509_policy_level_is_empty(level)) { | 784 | if (x509_policy_level_is_empty(level)) |
| 807 | return 0; | 785 | return 0; |
| 808 | } | ||
| 809 | 786 | ||
| 810 | /* | 787 | /* |
| 811 | * If |user_policies| is empty, we interpret it as having a single | 788 | * If |user_policies| is empty, we interpret it as having a single |
| @@ -824,9 +801,8 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 824 | * Step (g.ii). If the policy graph is not empty and the user set | 801 | * Step (g.ii). If the policy graph is not empty and the user set |
| 825 | * contains anyPolicy, the intersection is the entire (non-empty) graph. | 802 | * contains anyPolicy, the intersection is the entire (non-empty) graph. |
| 826 | */ | 803 | */ |
| 827 | if (user_has_any_policy) { | 804 | if (user_has_any_policy) |
| 828 | return 1; | 805 | return 1; |
| 829 | } | ||
| 830 | 806 | ||
| 831 | /* | 807 | /* |
| 832 | * Step (g.iii) does not delete anyPolicy nodes, so if the graph has | 808 | * Step (g.iii) does not delete anyPolicy nodes, so if the graph has |
| @@ -834,18 +810,16 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 834 | * may synthesize some nodes in step (g.iii.3), but we do not return the | 810 | * may synthesize some nodes in step (g.iii.3), but we do not return the |
| 835 | * policy list itself, so we skip actually computing this. | 811 | * policy list itself, so we skip actually computing this. |
| 836 | */ | 812 | */ |
| 837 | if (level->has_any_policy) { | 813 | if (level->has_any_policy) |
| 838 | return 1; | 814 | return 1; |
| 839 | } | ||
| 840 | 815 | ||
| 841 | /* | 816 | /* |
| 842 | * We defer pruning the tree, so as we look for nodes with parent | 817 | * We defer pruning the tree, so as we look for nodes with parent |
| 843 | * anyPolicy, step (g.iii.1), we must limit to nodes reachable from the | 818 | * anyPolicy, step (g.iii.1), we must limit to nodes reachable from the |
| 844 | * bottommost level. Start by marking each of those nodes as reachable. | 819 | * bottommost level. Start by marking each of those nodes as reachable. |
| 845 | */ | 820 | */ |
| 846 | for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { | 821 | for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) |
| 847 | sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; | 822 | sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; |
| 848 | } | ||
| 849 | 823 | ||
| 850 | for (i = num_levels - 1; i < num_levels; i--) { | 824 | for (i = num_levels - 1; i < num_levels; i--) { |
| 851 | level = sk_X509_POLICY_LEVEL_value(levels, i); | 825 | level = sk_X509_POLICY_LEVEL_value(levels, i); |
| @@ -853,9 +827,8 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 853 | j++) { | 827 | j++) { |
| 854 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, | 828 | X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, |
| 855 | j); | 829 | j); |
| 856 | if (!node->reachable) { | 830 | if (!node->reachable) |
| 857 | continue; | 831 | continue; |
| 858 | } | ||
| 859 | if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { | 832 | if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { |
| 860 | /* | 833 | /* |
| 861 | * |node|'s parent is anyPolicy and is part of | 834 | * |node|'s parent is anyPolicy and is part of |
| @@ -864,9 +837,8 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 864 | * non-empty and we * can return immediately. | 837 | * non-empty and we * can return immediately. |
| 865 | */ | 838 | */ |
| 866 | if (sk_ASN1_OBJECT_find(user_policies, | 839 | if (sk_ASN1_OBJECT_find(user_policies, |
| 867 | node->policy) >= 0) { | 840 | node->policy) >= 0) |
| 868 | return 1; | 841 | return 1; |
| 869 | } | ||
| 870 | } else if (i > 0) { | 842 | } else if (i > 0) { |
| 871 | /* |node|'s parents are concrete policies. Mark | 843 | /* |node|'s parents are concrete policies. Mark |
| 872 | * the parents reachable, to be inspected by the | 844 | * the parents reachable, to be inspected by the |
| @@ -874,15 +846,17 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 874 | */ | 846 | */ |
| 875 | X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, | 847 | X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, |
| 876 | i - 1); | 848 | i - 1); |
| 877 | for (k = 0; k < sk_ASN1_OBJECT_num(node->parent_policies); | 849 | for (k = 0; |
| 850 | k < | ||
| 851 | sk_ASN1_OBJECT_num(node->parent_policies); | ||
| 878 | k++) { | 852 | k++) { |
| 879 | X509_POLICY_NODE *parent = x509_policy_level_find( | 853 | X509_POLICY_NODE *parent = x509_policy_level_find( |
| 880 | prev, | 854 | prev, |
| 881 | 855 | ||
| 882 | sk_ASN1_OBJECT_value(node->parent_policies, k)); | 856 | sk_ASN1_OBJECT_value(node->parent_policies, |
| 883 | if (parent != NULL) { | 857 | k)); |
| 858 | if (parent != NULL) | ||
| 884 | parent->reachable = 1; | 859 | parent->reachable = 1; |
| 885 | } | ||
| 886 | } | 860 | } |
| 887 | } | 861 | } |
| 888 | } | 862 | } |
| @@ -912,9 +886,8 @@ X509_policy_check(const STACK_OF(X509) *certs, | |||
| 912 | size_t i; | 886 | size_t i; |
| 913 | 887 | ||
| 914 | /* Skip policy checking if the chain is just the trust anchor. */ | 888 | /* Skip policy checking if the chain is just the trust anchor. */ |
| 915 | if (num_certs <= 1) { | 889 | if (num_certs <= 1) |
| 916 | return X509_V_OK; | 890 | return X509_V_OK; |
| 917 | } | ||
| 918 | 891 | ||
| 919 | /* See RFC 5280, section 6.1.2, steps (d) through (f). */ | 892 | /* See RFC 5280, section 6.1.2, steps (d) through (f). */ |
| 920 | size_t explicit_policy = | 893 | size_t explicit_policy = |
| @@ -925,23 +898,20 @@ X509_policy_check(const STACK_OF(X509) *certs, | |||
| 925 | (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; | 898 | (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; |
| 926 | 899 | ||
| 927 | levels = sk_X509_POLICY_LEVEL_new_null(); | 900 | levels = sk_X509_POLICY_LEVEL_new_null(); |
| 928 | if (levels == NULL) { | 901 | if (levels == NULL) |
| 929 | goto err; | 902 | goto err; |
| 930 | } | ||
| 931 | 903 | ||
| 932 | for (i = num_certs - 2; i < num_certs; i--) { | 904 | for (i = num_certs - 2; i < num_certs; i--) { |
| 933 | X509 *cert = sk_X509_value(certs, i); | 905 | X509 *cert = sk_X509_value(certs, i); |
| 934 | if (!x509v3_cache_extensions(cert)) { | 906 | if (!x509v3_cache_extensions(cert)) |
| 935 | goto err; | 907 | goto err; |
| 936 | } | ||
| 937 | const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; | 908 | const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; |
| 938 | 909 | ||
| 939 | if (level == NULL) { | 910 | if (level == NULL) { |
| 940 | assert(i == num_certs - 2); | 911 | assert(i == num_certs - 2); |
| 941 | level = x509_policy_level_new(); | 912 | level = x509_policy_level_new(); |
| 942 | if (level == NULL) { | 913 | if (level == NULL) |
| 943 | goto err; | 914 | goto err; |
| 944 | } | ||
| 945 | level->has_any_policy = 1; | 915 | level->has_any_policy = 1; |
| 946 | } | 916 | } |
| 947 | 917 | ||
| @@ -965,9 +935,8 @@ X509_policy_check(const STACK_OF(X509) *certs, | |||
| 965 | } | 935 | } |
| 966 | 936 | ||
| 967 | /* Insert into the list. */ | 937 | /* Insert into the list. */ |
| 968 | if (!sk_X509_POLICY_LEVEL_push(levels, level)) { | 938 | if (!sk_X509_POLICY_LEVEL_push(levels, level)) |
| 969 | goto err; | 939 | goto err; |
| 970 | } | ||
| 971 | X509_POLICY_LEVEL *current_level = level; | 940 | X509_POLICY_LEVEL *current_level = level; |
| 972 | level = NULL; | 941 | level = NULL; |
| 973 | 942 | ||
| @@ -994,15 +963,12 @@ X509_policy_check(const STACK_OF(X509) *certs, | |||
| 994 | * longer read at this point, so we use the same process. | 963 | * longer read at this point, so we use the same process. |
| 995 | */ | 964 | */ |
| 996 | if (i == 0 || !is_self_issued) { | 965 | if (i == 0 || !is_self_issued) { |
| 997 | if (explicit_policy > 0) { | 966 | if (explicit_policy > 0) |
| 998 | explicit_policy--; | 967 | explicit_policy--; |
| 999 | } | 968 | if (policy_mapping > 0) |
| 1000 | if (policy_mapping > 0) { | ||
| 1001 | policy_mapping--; | 969 | policy_mapping--; |
| 1002 | } | 970 | if (inhibit_any_policy > 0) |
| 1003 | if (inhibit_any_policy > 0) { | ||
| 1004 | inhibit_any_policy--; | 971 | inhibit_any_policy--; |
| 1005 | } | ||
| 1006 | } | 972 | } |
| 1007 | if (!process_policy_constraints(cert, &explicit_policy, | 973 | if (!process_policy_constraints(cert, &explicit_policy, |
| 1008 | &policy_mapping, &inhibit_any_policy)) { | 974 | &policy_mapping, &inhibit_any_policy)) { |
| @@ -1025,9 +991,8 @@ X509_policy_check(const STACK_OF(X509) *certs, | |||
| 1025 | if (user_policies != NULL) { | 991 | if (user_policies != NULL) { |
| 1026 | user_policies_sorted = sk_ASN1_OBJECT_dup( | 992 | user_policies_sorted = sk_ASN1_OBJECT_dup( |
| 1027 | user_policies); | 993 | user_policies); |
| 1028 | if (user_policies_sorted == NULL) { | 994 | if (user_policies_sorted == NULL) |
| 1029 | goto err; | 995 | goto err; |
| 1030 | } | ||
| 1031 | sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, | 996 | sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, |
| 1032 | asn1_object_cmp); | 997 | asn1_object_cmp); |
| 1033 | sk_ASN1_OBJECT_sort(user_policies_sorted); | 998 | sk_ASN1_OBJECT_sort(user_policies_sorted); |
