-/* $OpenBSD: x509_policy.c,v 1.19 2023/04/28 15:27:15 tb Exp $ */
+/* $OpenBSD: x509_policy.c,v 1.20 2023/04/28 15:30:14 tb Exp $ */
/*
* Copyright (c) 2022, Google Inc.
*
/*
* x509_policy_level_find returns the node in |level| corresponding to |policy|,
- * or NULL if none exists.
+ * or NULL if none exists. Callers should ensure that level->nodes is sorted
+ * to avoid the cost of sorting it in sk_find().
*/
static X509_POLICY_NODE *
-x509_policy_level_find(X509_POLICY_LEVEL *level,
- const ASN1_OBJECT *policy)
+x509_policy_level_find(X509_POLICY_LEVEL *level, const ASN1_OBJECT *policy)
{
- assert(sk_X509_POLICY_NODE_is_sorted(level->nodes));
X509_POLICY_NODE node;
node.policy = (ASN1_OBJECT *)policy;
int idx;
+
if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0)
return NULL;
return sk_X509_POLICY_NODE_value(level->nodes, idx);
* is in |level| if and only if it would have been a
* match in step (d.1.ii).
*/
- if (!is_any_policy(policy->policyid) &&
- x509_policy_level_find(level, policy->policyid) ==
- NULL) {
- node = x509_policy_node_new(policy->policyid);
- if (node == NULL ||
- !sk_X509_POLICY_NODE_push(new_nodes, node)) {
- x509_policy_node_free(node);
- goto err;
- }
+ if (is_any_policy(policy->policyid))
+ continue;
+ if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
+ goto err;
+ if (x509_policy_level_find(level, policy->policyid) != NULL)
+ continue;
+ node = x509_policy_node_new(policy->policyid);
+ if (node == NULL ||
+ !sk_X509_POLICY_NODE_push(new_nodes, node)) {
+ x509_policy_node_free(node);
+ goto err;
}
}
if (!x509_policy_level_add_nodes(level, new_nodes))
continue;
last_policy = mapping->issuerDomainPolicy;
+ if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
+ goto err;
node = x509_policy_level_find(level,
mapping->issuerDomainPolicy);
if (node == NULL) {
* Skip mappings where |issuerDomainPolicy| does not appear in
* the graph.
*/
- if (!level->has_any_policy &&
- x509_policy_level_find(level,
- mapping->issuerDomainPolicy) == NULL)
- continue;
+ if (!level->has_any_policy) {
+ if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
+ goto err;
+ if (x509_policy_level_find(level,
+ mapping->issuerDomainPolicy) == NULL)
+ continue;
+ }
if (last_node == NULL ||
OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) !=
*/
prev = sk_X509_POLICY_LEVEL_value(levels, i - 1);
for (k = 0; k < num_parent_policies; k++) {
+ if (!sk_X509_POLICY_NODE_is_sorted(prev->nodes))
+ return 0;
parent = x509_policy_level_find(prev,
sk_ASN1_OBJECT_value(node->parent_policies,
k));