diff options
| author | tb <> | 2023-04-28 15:30:14 +0000 |
|---|---|---|
| committer | tb <> | 2023-04-28 15:30:14 +0000 |
| commit | 47f8ac7de208f199f32ebabd0f2f10b399059620 (patch) | |
| tree | 7298ec4e409970d1c8462275689e9343db7bec11 | |
| parent | 820a4d15a33384a359895de6c354c2a6c399de7c (diff) | |
| download | openbsd-47f8ac7de208f199f32ebabd0f2f10b399059620.tar.gz openbsd-47f8ac7de208f199f32ebabd0f2f10b399059620.tar.bz2 openbsd-47f8ac7de208f199f32ebabd0f2f10b399059620.zip | |
Deassert x509_policy_level_find()
Move the check that level->nodes is sorted to the call site and make sure
that the logic is preserved and erroring does the right thing.
with beck
ok jsing
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_policy.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/lib/libcrypto/x509/x509_policy.c b/src/lib/libcrypto/x509/x509_policy.c index c2ef47aa0f..368a3e42f4 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.19 2023/04/28 15:27:15 tb Exp $ */ | 1 | /* $OpenBSD: x509_policy.c,v 1.20 2023/04/28 15:30:14 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022, Google Inc. | 3 | * Copyright (c) 2022, Google Inc. |
| 4 | * | 4 | * |
| @@ -281,16 +281,16 @@ x509_policy_level_clear(X509_POLICY_LEVEL *level) | |||
| 281 | 281 | ||
| 282 | /* | 282 | /* |
| 283 | * x509_policy_level_find returns the node in |level| corresponding to |policy|, | 283 | * x509_policy_level_find returns the node in |level| corresponding to |policy|, |
| 284 | * or NULL if none exists. | 284 | * or NULL if none exists. Callers should ensure that level->nodes is sorted |
| 285 | * to avoid the cost of sorting it in sk_find(). | ||
| 285 | */ | 286 | */ |
| 286 | static X509_POLICY_NODE * | 287 | static X509_POLICY_NODE * |
| 287 | x509_policy_level_find(X509_POLICY_LEVEL *level, | 288 | x509_policy_level_find(X509_POLICY_LEVEL *level, const ASN1_OBJECT *policy) |
| 288 | const ASN1_OBJECT *policy) | ||
| 289 | { | 289 | { |
| 290 | assert(sk_X509_POLICY_NODE_is_sorted(level->nodes)); | ||
| 291 | X509_POLICY_NODE node; | 290 | X509_POLICY_NODE node; |
| 292 | node.policy = (ASN1_OBJECT *)policy; | 291 | node.policy = (ASN1_OBJECT *)policy; |
| 293 | int idx; | 292 | int idx; |
| 293 | |||
| 294 | if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) | 294 | if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) |
| 295 | return NULL; | 295 | return NULL; |
| 296 | return sk_X509_POLICY_NODE_value(level->nodes, idx); | 296 | return sk_X509_POLICY_NODE_value(level->nodes, idx); |
| @@ -435,15 +435,17 @@ process_certificate_policies(const X509 *x509, X509_POLICY_LEVEL *level, | |||
| 435 | * is in |level| if and only if it would have been a | 435 | * is in |level| if and only if it would have been a |
| 436 | * match in step (d.1.ii). | 436 | * match in step (d.1.ii). |
| 437 | */ | 437 | */ |
| 438 | if (!is_any_policy(policy->policyid) && | 438 | if (is_any_policy(policy->policyid)) |
| 439 | x509_policy_level_find(level, policy->policyid) == | 439 | continue; |
| 440 | NULL) { | 440 | if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) |
| 441 | node = x509_policy_node_new(policy->policyid); | 441 | goto err; |
| 442 | if (node == NULL || | 442 | if (x509_policy_level_find(level, policy->policyid) != NULL) |
| 443 | !sk_X509_POLICY_NODE_push(new_nodes, node)) { | 443 | continue; |
| 444 | x509_policy_node_free(node); | 444 | node = x509_policy_node_new(policy->policyid); |
| 445 | goto err; | 445 | if (node == NULL || |
| 446 | } | 446 | !sk_X509_POLICY_NODE_push(new_nodes, node)) { |
| 447 | x509_policy_node_free(node); | ||
| 448 | goto err; | ||
| 447 | } | 449 | } |
| 448 | } | 450 | } |
| 449 | if (!x509_policy_level_add_nodes(level, new_nodes)) | 451 | if (!x509_policy_level_add_nodes(level, new_nodes)) |
| @@ -569,6 +571,8 @@ process_policy_mappings(const X509 *cert, | |||
| 569 | continue; | 571 | continue; |
| 570 | last_policy = mapping->issuerDomainPolicy; | 572 | last_policy = mapping->issuerDomainPolicy; |
| 571 | 573 | ||
| 574 | if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) | ||
| 575 | goto err; | ||
| 572 | node = x509_policy_level_find(level, | 576 | node = x509_policy_level_find(level, |
| 573 | mapping->issuerDomainPolicy); | 577 | mapping->issuerDomainPolicy); |
| 574 | if (node == NULL) { | 578 | if (node == NULL) { |
| @@ -643,10 +647,13 @@ process_policy_mappings(const X509 *cert, | |||
| 643 | * Skip mappings where |issuerDomainPolicy| does not appear in | 647 | * Skip mappings where |issuerDomainPolicy| does not appear in |
| 644 | * the graph. | 648 | * the graph. |
| 645 | */ | 649 | */ |
| 646 | if (!level->has_any_policy && | 650 | if (!level->has_any_policy) { |
| 647 | x509_policy_level_find(level, | 651 | if (!sk_X509_POLICY_NODE_is_sorted(level->nodes)) |
| 648 | mapping->issuerDomainPolicy) == NULL) | 652 | goto err; |
| 649 | continue; | 653 | if (x509_policy_level_find(level, |
| 654 | mapping->issuerDomainPolicy) == NULL) | ||
| 655 | continue; | ||
| 656 | } | ||
| 650 | 657 | ||
| 651 | if (last_node == NULL || | 658 | if (last_node == NULL || |
| 652 | OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != | 659 | OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != |
| @@ -841,6 +848,8 @@ has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, | |||
| 841 | */ | 848 | */ |
| 842 | prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); | 849 | prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); |
| 843 | for (k = 0; k < num_parent_policies; k++) { | 850 | for (k = 0; k < num_parent_policies; k++) { |
| 851 | if (!sk_X509_POLICY_NODE_is_sorted(prev->nodes)) | ||
| 852 | return 0; | ||
| 844 | parent = x509_policy_level_find(prev, | 853 | parent = x509_policy_level_find(prev, |
| 845 | sk_ASN1_OBJECT_value(node->parent_policies, | 854 | sk_ASN1_OBJECT_value(node->parent_policies, |
| 846 | k)); | 855 | k)); |
