diff options
Diffstat (limited to 'src/lib/libcrypto')
| -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)); | 
