pcy_tree.c
Go to the documentation of this file.
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 2004.
4  */
5 /* ====================================================================
6  * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
28  * licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com). This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <string.h>
60 
61 #include <openssl/mem.h>
62 #include <openssl/obj.h>
63 #include <openssl/stack.h>
64 #include <openssl/thread.h>
65 #include <openssl/x509.h>
66 #include <openssl/x509v3.h>
67 
68 #include "../internal.h"
69 #include "../x509/internal.h"
70 #include "internal.h"
71 
72 /*
73  * Enable this to print out the complete policy tree at various point during
74  * evaluation.
75  */
76 
77 /*
78  * #define OPENSSL_POLICY_DEBUG
79  */
80 
81 #ifdef OPENSSL_POLICY_DEBUG
82 
83 static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
84  X509_POLICY_NODE *node, int indent)
85 {
86  if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)
87  || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
88  BIO_puts(err, " Not Mapped\n");
89  else {
90  int i;
91  STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
93  BIO_puts(err, " Expected: ");
94  for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
95  oid = sk_ASN1_OBJECT_value(pset, i);
96  if (i)
97  BIO_puts(err, ", ");
99  }
100  BIO_puts(err, "\n");
101  }
102 }
103 
104 static void tree_print(char *str, X509_POLICY_TREE *tree,
105  X509_POLICY_LEVEL *curr)
106 {
107  X509_POLICY_LEVEL *plev;
108  X509_POLICY_NODE *node;
109  int i;
110  BIO *err;
112  if (!curr)
113  curr = tree->levels + tree->nlevel;
114  else
115  curr++;
116  BIO_printf(err, "Level print after %s\n", str);
117  BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
118  for (plev = tree->levels; plev != curr; plev++) {
119  BIO_printf(err, "Level %ld, flags = %x\n",
120  plev - tree->levels, plev->flags);
121  for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
122  node = sk_X509_POLICY_NODE_value(plev->nodes, i);
123  X509_POLICY_NODE_print(err, node, 2);
124  expected_print(err, plev, node, 2);
125  BIO_printf(err, " Flags: %x\n", node->data->flags);
126  }
127  if (plev->anyPolicy)
129  }
130 
131  BIO_free(err);
132 
133 }
134 #else
135 
136 # define tree_print(a,b,c) /* */
137 
138 #endif
139 
140 /*-
141  * Initialize policy tree. Return values:
142  * 0 Some internal error occurred.
143  * -1 Inconsistent or invalid extensions in certificates.
144  * 1 Tree initialized OK.
145  * 2 Policy tree is empty.
146  * 5 Tree OK and requireExplicitPolicy true.
147  * 6 Tree empty and requireExplicitPolicy true.
148  */
149 
150 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
151  unsigned int flags)
152 {
153  X509_POLICY_TREE *tree;
155  const X509_POLICY_CACHE *cache;
156  X509_POLICY_DATA *data = NULL;
157  X509 *x;
158  int ret = 1;
159  int i, n;
160  int explicit_policy;
161  int any_skip;
162  int map_skip;
163  *ptree = NULL;
164  n = sk_X509_num(certs);
165 
166 #if 0
167  /* Disable policy mapping for now... */
169 #endif
170 
172  explicit_policy = 0;
173  else
174  explicit_policy = n + 1;
175 
177  any_skip = 0;
178  else
179  any_skip = n + 1;
180 
182  map_skip = 0;
183  else
184  map_skip = n + 1;
185 
186  /* Can't do anything with just a trust anchor */
187  if (n == 1)
188  return 1;
189  /*
190  * First setup policy cache in all certificates apart from the trust
191  * anchor. Note any bad cache results on the way. Also can calculate
192  * explicit_policy value at this point.
193  */
194  for (i = n - 2; i >= 0; i--) {
195  x = sk_X509_value(certs, i);
196  X509_check_purpose(x, -1, -1);
197  cache = policy_cache_set(x);
198  /* If cache NULL something bad happened: return immediately */
199  if (cache == NULL)
200  return 0;
201  /*
202  * If inconsistent extensions keep a note of it but continue
203  */
204  if (x->ex_flags & EXFLAG_INVALID_POLICY)
205  ret = -1;
206  /*
207  * Otherwise if we have no data (hence no CertificatePolicies) and
208  * haven't already set an inconsistent code note it.
209  */
210  else if ((ret == 1) && !cache->data)
211  ret = 2;
212  if (explicit_policy > 0) {
213  if (!(x->ex_flags & EXFLAG_SI))
214  explicit_policy--;
215  if ((cache->explicit_skip != -1)
216  && (cache->explicit_skip < explicit_policy))
217  explicit_policy = cache->explicit_skip;
218  }
219  }
220 
221  if (ret != 1) {
222  if (ret == 2 && !explicit_policy)
223  return 6;
224  return ret;
225  }
226 
227  /* If we get this far initialize the tree */
228 
229  tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
230 
231  if (!tree)
232  return 0;
233 
234  tree->flags = 0;
235  tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
236  tree->nlevel = 0;
237  tree->extra_data = NULL;
238  tree->auth_policies = NULL;
239  tree->user_policies = NULL;
240 
241  if (!tree->levels) {
242  OPENSSL_free(tree);
243  return 0;
244  }
245 
246  OPENSSL_memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
247 
248  tree->nlevel = n;
249 
250  level = tree->levels;
251 
252  /* Root data: initialize to anyPolicy */
253 
255 
256  if (!data || !level_add_node(level, data, NULL, tree))
257  goto bad_tree;
258 
259  for (i = n - 2; i >= 0; i--) {
260  level++;
261  x = sk_X509_value(certs, i);
262  cache = policy_cache_set(x);
263  X509_up_ref(x);
264  level->cert = x;
265 
266  if (!cache->anyPolicy)
267  level->flags |= X509_V_FLAG_INHIBIT_ANY;
268 
269  /* Determine inhibit any and inhibit map flags */
270  if (any_skip == 0) {
271  /*
272  * Any matching allowed if certificate is self issued and not the
273  * last in the chain.
274  */
275  if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
276  level->flags |= X509_V_FLAG_INHIBIT_ANY;
277  } else {
278  if (!(x->ex_flags & EXFLAG_SI))
279  any_skip--;
280  if ((cache->any_skip >= 0)
281  && (cache->any_skip < any_skip))
282  any_skip = cache->any_skip;
283  }
284 
285  if (map_skip == 0)
286  level->flags |= X509_V_FLAG_INHIBIT_MAP;
287  else {
288  if (!(x->ex_flags & EXFLAG_SI))
289  map_skip--;
290  if ((cache->map_skip >= 0)
291  && (cache->map_skip < map_skip))
292  map_skip = cache->map_skip;
293  }
294 
295  }
296 
297  *ptree = tree;
298 
299  if (explicit_policy)
300  return 1;
301  else
302  return 5;
303 
304  bad_tree:
305 
306  X509_policy_tree_free(tree);
307 
308  return 0;
309 
310 }
311 
314 {
315  X509_POLICY_LEVEL *last = curr - 1;
316  X509_POLICY_NODE *node;
317  int matched = 0;
318  size_t i;
319  /* Iterate through all in nodes linking matches */
320  for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
321  node = sk_X509_POLICY_NODE_value(last->nodes, i);
322  if (policy_node_match(last, node, data->valid_policy)) {
323  if (!level_add_node(curr, data, node, NULL))
324  return 0;
325  matched = 1;
326  }
327  }
328  if (!matched && last->anyPolicy) {
329  if (!level_add_node(curr, data, last->anyPolicy, NULL))
330  return 0;
331  }
332  return 1;
333 }
334 
335 /*
336  * This corresponds to RFC 3280 6.1.3(d)(1): link any data from
337  * CertificatePolicies onto matching parent or anyPolicy if no match.
338  */
339 
341  const X509_POLICY_CACHE *cache)
342 {
343  size_t i;
345 
346  for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
347  data = sk_X509_POLICY_DATA_value(cache->data, i);
348  /*
349  * If a node is mapped any it doesn't have a corresponding
350  * CertificatePolicies entry. However such an identical node would
351  * be created if anyPolicy matching is enabled because there would be
352  * no match with the parent valid_policy_set. So we create link
353  * because then it will have the mapping flags right and we can prune
354  * it later.
355  */
356 #if 0
357  if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
358  && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
359  continue;
360 #endif
361  /* Look for matching nodes in previous level */
362  if (!tree_link_matching_nodes(curr, data))
363  return 0;
364  }
365  return 1;
366 }
367 
368 /*
369  * This corresponds to RFC 3280 6.1.3(d)(2): Create new data for any unmatched
370  * policies in the parent and link to anyPolicy.
371  */
372 
374  const X509_POLICY_CACHE *cache,
375  const ASN1_OBJECT *id,
376  X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
377 {
379  if (id == NULL)
380  id = node->data->valid_policy;
381  /*
382  * Create a new node with qualifiers from anyPolicy and id from unmatched
383  * node.
384  */
385  data = policy_data_new(NULL, id, node_critical(node));
386 
387  if (data == NULL)
388  return 0;
389  /* Curr may not have anyPolicy */
390  data->qualifier_set = cache->anyPolicy->qualifier_set;
392  if (!level_add_node(curr, data, node, tree)) {
394  return 0;
395  }
396 
397  return 1;
398 }
399 
401  const X509_POLICY_CACHE *cache,
402  X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
403 {
404  const X509_POLICY_LEVEL *last = curr - 1;
405  size_t i;
406 
407  if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
408  || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
409  /* If no policy mapping: matched if one child present */
410  if (node->nchild)
411  return 1;
412  if (!tree_add_unmatched(curr, cache, NULL, node, tree))
413  return 0;
414  /* Add it */
415  } else {
416  /* If mapping: matched if one child per expected policy set */
417  STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
418  if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset))
419  return 1;
420  /* Locate unmatched nodes */
421  for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
422  ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
423  if (level_find_node(curr, node, oid))
424  continue;
425  if (!tree_add_unmatched(curr, cache, oid, node, tree))
426  return 0;
427  }
428 
429  }
430 
431  return 1;
432 
433 }
434 
436  const X509_POLICY_CACHE *cache,
437  X509_POLICY_TREE *tree)
438 {
439  size_t i;
440  /*
441  * X509_POLICY_DATA *data;
442  */
443  X509_POLICY_NODE *node;
444  X509_POLICY_LEVEL *last = curr - 1;
445 
446  for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
447  node = sk_X509_POLICY_NODE_value(last->nodes, i);
448 
449  if (!tree_link_unmatched(curr, cache, node, tree))
450  return 0;
451 
452 #if 0
453 
454  /*
455  * Skip any node with any children: we only want unmathced nodes.
456  * Note: need something better for policy mapping because each node
457  * may have multiple children
458  */
459  if (node->nchild)
460  continue;
461 
462  /*
463  * Create a new node with qualifiers from anyPolicy and id from
464  * unmatched node.
465  */
466  data = policy_data_new(NULL, node->data->valid_policy,
467  node_critical(node));
468 
469  if (data == NULL)
470  return 0;
471  /* Curr may not have anyPolicy */
472  data->qualifier_set = cache->anyPolicy->qualifier_set;
474  if (!level_add_node(curr, data, node, tree)) {
476  return 0;
477  }
478 #endif
479 
480  }
481  /* Finally add link to anyPolicy */
482  if (last->anyPolicy) {
483  if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL))
484  return 0;
485  }
486  return 1;
487 }
488 
489 /*
490  * Prune the tree: delete any child mapped child data on the current level
491  * then proceed up the tree deleting any data with no children. If we ever
492  * have no data on a level we can halt because the tree will be empty.
493  */
494 
496 {
497  STACK_OF(X509_POLICY_NODE) *nodes;
498  X509_POLICY_NODE *node;
499  int i;
500  nodes = curr->nodes;
501  if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
502  for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
503  node = sk_X509_POLICY_NODE_value(nodes, i);
504  /* Delete any mapped data: see RFC 3280 XXXX */
505  if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
506  node->parent->nchild--;
507  OPENSSL_free(node);
508  (void)sk_X509_POLICY_NODE_delete(nodes, i);
509  }
510  }
511  }
512 
513  for (;;) {
514  --curr;
515  nodes = curr->nodes;
516  for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
517  node = sk_X509_POLICY_NODE_value(nodes, i);
518  if (node->nchild == 0) {
519  node->parent->nchild--;
520  OPENSSL_free(node);
521  (void)sk_X509_POLICY_NODE_delete(nodes, i);
522  }
523  }
524  if (curr->anyPolicy && !curr->anyPolicy->nchild) {
525  if (curr->anyPolicy->parent)
526  curr->anyPolicy->parent->nchild--;
527  OPENSSL_free(curr->anyPolicy);
528  curr->anyPolicy = NULL;
529  }
530  if (curr == tree->levels) {
531  /* If we zapped anyPolicy at top then tree is empty */
532  if (!curr->anyPolicy)
533  return 2;
534  return 1;
535  }
536  }
537 
538 }
539 
541  X509_POLICY_NODE *pcy)
542 {
543  if (!*pnodes) {
544  *pnodes = policy_node_cmp_new();
545  if (!*pnodes)
546  return 0;
547  } else {
548  sk_X509_POLICY_NODE_sort(*pnodes);
549  if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
550  return 1;
551  }
552  if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
553  return 0;
554 
555  return 1;
556 
557 }
558 
559 /*
560  * Calculate the authority set based on policy tree. The 'pnodes' parameter
561  * is used as a store for the set of policy nodes used to calculate the user
562  * set. If the authority set is not anyPolicy then pnodes will just point to
563  * the authority set. If however the authority set is anyPolicy then the set
564  * of valid policies (other than anyPolicy) is store in pnodes. The return
565  * value of '2' is used in this case to indicate that pnodes should be freed.
566  */
567 
569  STACK_OF(X509_POLICY_NODE) **pnodes)
570 {
571  X509_POLICY_LEVEL *curr;
572  X509_POLICY_NODE *node, *anyptr;
573  STACK_OF(X509_POLICY_NODE) **addnodes;
574  int i;
575  size_t j;
576  curr = tree->levels + tree->nlevel - 1;
577 
578  /* If last level contains anyPolicy set is anyPolicy */
579  if (curr->anyPolicy) {
580  if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
581  return 0;
582  addnodes = pnodes;
583  } else
584  /* Add policies to authority set */
585  addnodes = &tree->auth_policies;
586 
587  curr = tree->levels;
588  for (i = 1; i < tree->nlevel; i++) {
589  /*
590  * If no anyPolicy node on this this level it can't appear on lower
591  * levels so end search.
592  */
593  if (!(anyptr = curr->anyPolicy))
594  break;
595  curr++;
596  for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
597  node = sk_X509_POLICY_NODE_value(curr->nodes, j);
598  if ((node->parent == anyptr)
599  && !tree_add_auth_node(addnodes, node))
600  return 0;
601  }
602  }
603 
604  if (addnodes == pnodes)
605  return 2;
606 
607  *pnodes = tree->auth_policies;
608 
609  return 1;
610 }
611 
613  STACK_OF(ASN1_OBJECT) *policy_oids,
614  STACK_OF(X509_POLICY_NODE) *auth_nodes)
615 {
616  size_t i;
617  X509_POLICY_NODE *node;
618  ASN1_OBJECT *oid;
619 
620  X509_POLICY_NODE *anyPolicy;
621  X509_POLICY_DATA *extra;
622 
623  /*
624  * Check if anyPolicy present in authority constrained policy set: this
625  * will happen if it is a leaf node.
626  */
627 
628  if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
629  return 1;
630 
631  anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
632 
633  for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
634  oid = sk_ASN1_OBJECT_value(policy_oids, i);
635  if (OBJ_obj2nid(oid) == NID_any_policy) {
636  tree->flags |= POLICY_FLAG_ANY_POLICY;
637  return 1;
638  }
639  }
640 
641  for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
642  oid = sk_ASN1_OBJECT_value(policy_oids, i);
643  node = tree_find_sk(auth_nodes, oid);
644  if (!node) {
645  if (!anyPolicy)
646  continue;
647  /*
648  * Create a new node with policy ID from user set and qualifiers
649  * from anyPolicy.
650  */
651  extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
652  if (!extra)
653  return 0;
654  extra->qualifier_set = anyPolicy->data->qualifier_set;
657  node = level_add_node(NULL, extra, anyPolicy->parent, tree);
658  }
659  if (!tree->user_policies) {
660  tree->user_policies = sk_X509_POLICY_NODE_new_null();
661  if (!tree->user_policies)
662  return 1;
663  }
664  if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
665  return 0;
666  }
667  return 1;
668 
669 }
670 
672 {
673  int ret, i;
674  X509_POLICY_LEVEL *curr = tree->levels + 1;
675  const X509_POLICY_CACHE *cache;
676 
677  for (i = 1; i < tree->nlevel; i++, curr++) {
678  cache = policy_cache_set(curr->cert);
679  if (!tree_link_nodes(curr, cache))
680  return 0;
681 
682  if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
683  && !tree_link_any(curr, cache, tree))
684  return 0;
685  tree_print("before tree_prune()", tree, curr);
686  ret = tree_prune(tree, curr);
687  if (ret != 1)
688  return ret;
689  }
690 
691  return 1;
692 
693 }
694 
695 static void exnode_free(X509_POLICY_NODE *node)
696 {
697  if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
698  OPENSSL_free(node);
699 }
700 
702 {
703  X509_POLICY_LEVEL *curr;
704  int i;
705 
706  if (!tree)
707  return;
708 
709  sk_X509_POLICY_NODE_free(tree->auth_policies);
710  sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
711 
712  for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
713  if (curr->cert)
714  X509_free(curr->cert);
715  if (curr->nodes)
716  sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
717  if (curr->anyPolicy)
719  }
720 
721  if (tree->extra_data)
722  sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
723 
724  OPENSSL_free(tree->levels);
725  OPENSSL_free(tree);
726 
727 }
728 
729 /*-
730  * Application policy checking function.
731  * Return codes:
732  * 0 Internal Error.
733  * 1 Successful.
734  * -1 One or more certificates contain invalid or inconsistent extensions
735  * -2 User constrained policy set empty and requireExplicit true.
736  */
737 
738 int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
739  STACK_OF(X509) *certs,
740  STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
741 {
742  int ret;
743  int calc_ret;
744  X509_POLICY_TREE *tree = NULL;
745  STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
746  *ptree = NULL;
747 
748  *pexplicit_policy = 0;
749  ret = tree_init(&tree, certs, flags);
750 
751  switch (ret) {
752 
753  /* Tree empty requireExplicit False: OK */
754  case 2:
755  return 1;
756 
757  /* Some internal error */
758  case -1:
759  return -1;
760 
761  /* Some internal error */
762  case 0:
763  return 0;
764 
765  /* Tree empty requireExplicit True: Error */
766 
767  case 6:
768  *pexplicit_policy = 1;
769  return -2;
770 
771  /* Tree OK requireExplicit True: OK and continue */
772  case 5:
773  *pexplicit_policy = 1;
774  break;
775 
776  /* Tree OK: continue */
777 
778  case 1:
779  if (!tree)
780  /*
781  * tree_init() returns success and a null tree
782  * if it's just looking at a trust anchor.
783  * I'm not sure that returning success here is
784  * correct, but I'm sure that reporting this
785  * as an internal error which our caller
786  * interprets as a malloc failure is wrong.
787  */
788  return 1;
789  break;
790  }
791 
792  if (!tree)
793  goto error;
794  ret = tree_evaluate(tree);
795 
796  tree_print("tree_evaluate()", tree, NULL);
797 
798  if (ret <= 0)
799  goto error;
800 
801  /* Return value 2 means tree empty */
802  if (ret == 2) {
803  X509_policy_tree_free(tree);
804  if (*pexplicit_policy)
805  return -2;
806  else
807  return 1;
808  }
809 
810  /* Tree is not empty: continue */
811 
812  calc_ret = tree_calculate_authority_set(tree, &auth_nodes);
813 
814  if (!calc_ret)
815  goto error;
816 
817  ret = tree_calculate_user_set(tree, policy_oids, auth_nodes);
818 
819  if (calc_ret == 2)
820  sk_X509_POLICY_NODE_free(auth_nodes);
821 
822  if (!ret)
823  goto error;
824 
825 
826  if (tree)
827  *ptree = tree;
828 
829  if (*pexplicit_policy) {
831  if (sk_X509_POLICY_NODE_num(nodes) <= 0)
832  return -2;
833  }
834 
835  return 1;
836 
837  error:
838 
839  X509_policy_tree_free(tree);
840 
841  return 0;
842 
843 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
tree_link_any
static int tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, X509_POLICY_TREE *tree)
Definition: pcy_tree.c:435
BIO_new_fp
#define BIO_new_fp
Definition: boringssl_prefix_symbols.h:819
tree_link_nodes
static int tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache)
Definition: pcy_tree.c:340
X509_POLICY_LEVEL_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:214
X509_POLICY_TREE_st::levels
X509_POLICY_LEVEL * levels
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:230
POLICY_DATA_FLAG_MAPPED
#define POLICY_DATA_FLAG_MAPPED
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:153
policy_data_free
#define policy_data_free
Definition: boringssl_prefix_symbols.h:3349
tree_link_unmatched
static int tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
Definition: pcy_tree.c:400
tree_find_sk
#define tree_find_sk
Definition: boringssl_prefix_symbols.h:3395
X509_POLICY_CACHE_st::any_skip
long any_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:186
exnode_free
static void exnode_free(X509_POLICY_NODE *node)
Definition: pcy_tree.c:695
bio_st
Definition: bio.h:822
internal.h
X509_POLICY_CACHE_st::anyPolicy
X509_POLICY_DATA * anyPolicy
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:182
X509_POLICY_LEVEL_st::flags
unsigned int flags
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:225
string.h
sk_X509_num
#define sk_X509_num
Definition: boringssl_prefix_symbols.h:587
X509_POLICY_NODE_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:205
X509_policy_tree_get0_user_policies
#define X509_policy_tree_get0_user_policies
Definition: boringssl_prefix_symbols.h:2699
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
x509v3.h
tree_add_unmatched
static int tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
Definition: pcy_tree.c:373
python_utils.upload_rbe_results.indent
indent
Definition: upload_rbe_results.py:183
X509_POLICY_NODE_print
OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
X509_POLICY_DATA_st::flags
unsigned int flags
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:139
BIO_printf
#define BIO_printf
Definition: boringssl_prefix_symbols.h:827
tree_init
static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags)
Definition: pcy_tree.c:150
asn1_object_st
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:102
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
POLICY_DATA_FLAG_MAPPED_ANY
#define POLICY_DATA_FLAG_MAPPED_ANY
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:160
X509_free
#define X509_free
Definition: boringssl_prefix_symbols.h:2632
OBJ_nid2obj
#define OBJ_nid2obj
Definition: boringssl_prefix_symbols.h:1855
OPENSSL_malloc
#define OPENSSL_malloc
Definition: boringssl_prefix_symbols.h:1885
X509_V_FLAG_EXPLICIT_POLICY
#define X509_V_FLAG_EXPLICIT_POLICY
Definition: x509.h:2019
level_find_node
#define level_find_node
Definition: boringssl_prefix_symbols.h:3319
X509_POLICY_TREE_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:228
EXFLAG_SI
#define EXFLAG_SI
Definition: x509v3.h:394
X509_V_FLAG_INHIBIT_MAP
#define X509_V_FLAG_INHIBIT_MAP
Definition: x509.h:2023
X509_POLICY_NODE_st::data
const X509_POLICY_DATA * data
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:207
OBJ_obj2nid
#define OBJ_obj2nid
Definition: boringssl_prefix_symbols.h:1857
X509_POLICY_NODE_st::parent
X509_POLICY_NODE * parent
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:209
oid
uint8_t oid[9]
Definition: digest_extra.c:124
tree_link_matching_nodes
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, X509_POLICY_DATA *data)
Definition: pcy_tree.c:312
STACK_OF
#define STACK_OF(type)
Definition: stack.h:125
POLICY_DATA_FLAG_EXTRA_NODE
#define POLICY_DATA_FLAG_EXTRA_NODE
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:172
tree_evaluate
static int tree_evaluate(X509_POLICY_TREE *tree)
Definition: pcy_tree.c:671
X509_policy_check
int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
Definition: pcy_tree.c:738
X509_POLICY_CACHE_st::explicit_skip
long explicit_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:191
EXFLAG_INVALID_POLICY
#define EXFLAG_INVALID_POLICY
Definition: x509v3.h:401
NID_any_policy
#define NID_any_policy
Definition: nid.h:3293
X509_up_ref
OPENSSL_EXPORT int X509_up_ref(X509 *x509)
tree_calculate_authority_set
static int tree_calculate_authority_set(X509_POLICY_TREE *tree, STACK_OF(X509_POLICY_NODE) **pnodes)
Definition: pcy_tree.c:568
policy_cache_set
#define policy_cache_set
Definition: boringssl_prefix_symbols.h:3347
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
X509_POLICY_LEVEL_st::anyPolicy
X509_POLICY_NODE * anyPolicy
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:220
X509_POLICY_LEVEL_st::cert
X509 * cert
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:216
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
tree_prune
static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
Definition: pcy_tree.c:495
X509_POLICY_TREE_st::flags
unsigned int flags
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:240
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
policy_node_match
#define policy_node_match
Definition: boringssl_prefix_symbols.h:3353
X509_POLICY_DATA_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:138
BIO_free
#define BIO_free
Definition: boringssl_prefix_symbols.h:787
X509_POLICY_DATA_st::valid_policy
ASN1_OBJECT * valid_policy
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:141
policy_node_cmp_new
#define policy_node_cmp_new
Definition: boringssl_prefix_symbols.h:3351
POLICY_DATA_FLAG_MAP_MASK
#define POLICY_DATA_FLAG_MAP_MASK
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:164
i2a_ASN1_OBJECT
#define i2a_ASN1_OBJECT
Definition: boringssl_prefix_symbols.h:3172
x509_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:139
tree_calculate_user_set
static int tree_calculate_user_set(X509_POLICY_TREE *tree, STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes)
Definition: pcy_tree.c:612
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
X509_POLICY_NODE_st::nchild
int nchild
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:211
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
sk_X509_value
#define sk_X509_value
Definition: boringssl_prefix_symbols.h:590
BIO_puts
#define BIO_puts
Definition: boringssl_prefix_symbols.h:830
policy_node_free
#define policy_node_free
Definition: boringssl_prefix_symbols.h:3352
X509_POLICY_CACHE_st::map_skip
long map_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:196
node_critical
#define node_critical(node)
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:249
X509_V_FLAG_INHIBIT_ANY
#define X509_V_FLAG_INHIBIT_ANY
Definition: x509.h:2021
tree_add_auth_node
static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy)
Definition: pcy_tree.c:540
obj.h
BIO_NOCLOSE
#define BIO_NOCLOSE
Definition: bio.h:373
tree_print
#define tree_print(a, b, c)
Definition: pcy_tree.c:136
policy_data_new
#define policy_data_new
Definition: boringssl_prefix_symbols.h:3350
mem.h
client.level
level
Definition: examples/python/async_streaming/client.py:118
X509_POLICY_CACHE_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:180
POLICY_FLAG_ANY_POLICY
#define POLICY_FLAG_ANY_POLICY
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:244
thread.h
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
POLICY_DATA_FLAG_SHARED_QUALIFIERS
#define POLICY_DATA_FLAG_SHARED_QUALIFIERS
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:168
level_add_node
#define level_add_node
Definition: boringssl_prefix_symbols.h:3318
X509_POLICY_TREE_st::nlevel
int nlevel
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:231
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
X509_policy_tree_free
void X509_policy_tree_free(X509_POLICY_TREE *tree)
Definition: pcy_tree.c:701
stack.h
X509_check_purpose
#define X509_check_purpose
Definition: boringssl_prefix_symbols.h:2621
x509.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:41