diff options
author | tb <> | 2023-04-28 15:30:14 +0000 |
---|---|---|
committer | tb <> | 2023-04-28 15:30:14 +0000 |
commit | f68709d955967ac16bd0e68c0044a9c7935da680 (patch) | |
tree | 7298ec4e409970d1c8462275689e9343db7bec11 | |
parent | 66d5d7d5b34bf542137abdb15c68ec1be3f500d7 (diff) | |
download | openbsd-f68709d955967ac16bd0e68c0044a9c7935da680.tar.gz openbsd-f68709d955967ac16bd0e68c0044a9c7935da680.tar.bz2 openbsd-f68709d955967ac16bd0e68c0044a9c7935da680.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
-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)); |