Initial support for name constraints certificate extension.
[openssl.git] / crypto / x509v3 / pcy_tree.c
index 8871ab88b6a3c539ad73c2306953deab44418fd6..b1ce77b9afc7ad9d5ebb11177ae2a6a8d7625768 100644 (file)
@@ -130,9 +130,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                        ret = 2;
                if (explicit_policy > 0)
                        {
-                       explicit_policy--;
-                       if (!(x->ex_flags & EXFLAG_SS)
-                               && (cache->explicit_skip != -1)
+                       if (!(x->ex_flags & EXFLAG_SI))
+                               explicit_policy--;
+                       if ((cache->explicit_skip != -1)
                                && (cache->explicit_skip < explicit_policy))
                                explicit_policy = cache->explicit_skip;
                        }
@@ -197,13 +197,14 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                        /* Any matching allowed if certificate is self
                         * issued and not the last in the chain.
                         */
-                       if (!(x->ex_flags && EXFLAG_SS) || (i == 0))
+                       if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
                                level->flags |= X509_V_FLAG_INHIBIT_ANY;
                        }
                else
                        {
-                       any_skip--;
-                       if ((cache->any_skip > 0)
+                       if (!(x->ex_flags & EXFLAG_SI))
+                               any_skip--;
+                       if ((cache->any_skip >= 0)
                                && (cache->any_skip < any_skip))
                                any_skip = cache->any_skip;
                        }
@@ -213,7 +214,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                else
                        {
                        map_skip--;
-                       if ((cache->map_skip > 0)
+                       if ((cache->map_skip >= 0)
                                && (cache->map_skip < map_skip))
                                map_skip = cache->map_skip;
                        }
@@ -310,7 +311,8 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
 
                if (data == NULL)
                        return 0;
-               data->qualifier_set = curr->anyPolicy->data->qualifier_set;
+               /* Curr may not have anyPolicy */
+               data->qualifier_set = cache->anyPolicy->qualifier_set;
                data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
                if (!level_add_node(curr, data, node, tree))
                        {
@@ -345,7 +347,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
                        {
                        node->parent->nchild--;
                        OPENSSL_free(node);
-                       sk_X509_POLICY_NODE_delete(curr->nodes, i);
+                       (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
                        }
                }
 
@@ -358,7 +360,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
                                {
                                node->parent->nchild--;
                                OPENSSL_free(node);
-                               sk_X509_POLICY_NODE_delete(curr->nodes, i);
+                               (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
                                }
                        }
                if (curr->anyPolicy && !curr->anyPolicy->nchild)
@@ -410,11 +412,11 @@ static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
  */
 
 static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
-                                       STACK_OF(X509_POLICY_NODES) **pnodes)
+                                       STACK_OF(X509_POLICY_NODE) **pnodes)
        {
        X509_POLICY_LEVEL *curr;
        X509_POLICY_NODE *node, *anyptr;
-       STACK_OF(X509_POLICY_NODES) **addnodes;
+       STACK_OF(X509_POLICY_NODE) **addnodes;
        int i, j;
        curr = tree->levels + tree->nlevel - 1;
 
@@ -589,17 +591,17 @@ void X509_policy_tree_free(X509_POLICY_TREE *tree)
  * -2  User constrained policy set empty and requireExplicit true.
  */
 
-int X509_policy_check(X509_POLICY_TREE **ptree, int *explicit,
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
                        STACK_OF(X509) *certs,
                        STACK_OF(ASN1_OBJECT) *policy_oids,
                        unsigned int flags)
        {
        int ret;
        X509_POLICY_TREE *tree = NULL;
-       STACK_OF(X509_NODE) *nodes, *auth_nodes = NULL;
+       STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
        *ptree = NULL;
 
-       *explicit = 0;
+       *pexplicit_policy = 0;
        ret = tree_init(&tree, certs, flags);
 
 
@@ -617,20 +619,31 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *explicit,
                /* Tree empty requireExplicit True: Error */
 
                case 6:
-               *explicit = 1;
+               *pexplicit_policy = 1;
                return -2;
 
                /* Tree OK requireExplicit True: OK and continue */
                case 5:
-               *explicit = 1;
+               *pexplicit_policy = 1;
                break;
 
                /* Tree OK: continue */
 
                case 1:
+               if (!tree)
+                       /*
+                        * tree_init() returns success and a null tree
+                        * if it's just looking at a trust anchor.
+                        * I'm not sure that returning success here is
+                        * correct, but I'm sure that reporting this
+                        * as an internal error which our caller
+                        * interprets as a malloc failure is wrong.
+                        */
+                       return 1;
                break;
                }
 
+       if (!tree) goto error;
        ret = tree_evaluate(tree);
 
        if (ret <= 0)
@@ -640,7 +653,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *explicit,
        if (ret == 2)
                {
                X509_policy_tree_free(tree);
-               if (*explicit)
+               if (*pexplicit_policy)
                        return -2;
                else
                        return 1;
@@ -662,7 +675,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *explicit,
        if (tree)
                *ptree = tree;
 
-       if (*explicit)
+       if (*pexplicit_policy)
                {
                nodes = X509_policy_tree_get0_user_policies(tree);
                if (sk_X509_POLICY_NODE_num(nodes) <= 0)