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 "pcy_int.h"
69 #include "../internal.h"
70 #include "../x509/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
expected_print(BIO * err,X509_POLICY_LEVEL * lev,X509_POLICY_NODE * node,int indent)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;
92 ASN1_OBJECT *oid;
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, ", ");
98 i2a_ASN1_OBJECT(err, oid);
99 }
100 BIO_puts(err, "\n");
101 }
102 }
103
tree_print(char * str,X509_POLICY_TREE * tree,X509_POLICY_LEVEL * curr)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;
111 err = BIO_new_fp(stderr, BIO_NOCLOSE);
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)
128 X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
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
tree_init(X509_POLICY_TREE ** ptree,STACK_OF (X509)* certs,unsigned int flags)150 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
151 unsigned int flags)
152 {
153 X509_POLICY_TREE *tree;
154 X509_POLICY_LEVEL *level;
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... */
168 flags |= X509_V_FLAG_INHIBIT_MAP;
169 #endif
170
171 if (flags & X509_V_FLAG_EXPLICIT_POLICY)
172 explicit_policy = 0;
173 else
174 explicit_policy = n + 1;
175
176 if (flags & X509_V_FLAG_INHIBIT_ANY)
177 any_skip = 0;
178 else
179 any_skip = n + 1;
180
181 if (flags & X509_V_FLAG_INHIBIT_MAP)
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
254 data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
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
tree_link_matching_nodes(X509_POLICY_LEVEL * curr,X509_POLICY_DATA * data)312 static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
313 X509_POLICY_DATA *data)
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
tree_link_nodes(X509_POLICY_LEVEL * curr,const X509_POLICY_CACHE * cache)340 static int tree_link_nodes(X509_POLICY_LEVEL *curr,
341 const X509_POLICY_CACHE *cache)
342 {
343 size_t i;
344 X509_POLICY_DATA *data;
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
tree_add_unmatched(X509_POLICY_LEVEL * curr,const X509_POLICY_CACHE * cache,const ASN1_OBJECT * id,X509_POLICY_NODE * node,X509_POLICY_TREE * tree)373 static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
374 const X509_POLICY_CACHE *cache,
375 const ASN1_OBJECT *id,
376 X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
377 {
378 X509_POLICY_DATA *data;
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;
391 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
392 if (!level_add_node(curr, data, node, tree)) {
393 policy_data_free(data);
394 return 0;
395 }
396
397 return 1;
398 }
399
tree_link_unmatched(X509_POLICY_LEVEL * curr,const X509_POLICY_CACHE * cache,X509_POLICY_NODE * node,X509_POLICY_TREE * tree)400 static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
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
tree_link_any(X509_POLICY_LEVEL * curr,const X509_POLICY_CACHE * cache,X509_POLICY_TREE * tree)435 static int tree_link_any(X509_POLICY_LEVEL *curr,
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;
473 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
474 if (!level_add_node(curr, data, node, tree)) {
475 policy_data_free(data);
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
tree_prune(X509_POLICY_TREE * tree,X509_POLICY_LEVEL * curr)495 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
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
tree_add_auth_node(STACK_OF (X509_POLICY_NODE)** pnodes,X509_POLICY_NODE * pcy)540 static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
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
tree_calculate_authority_set(X509_POLICY_TREE * tree,STACK_OF (X509_POLICY_NODE)** pnodes)568 static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
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
tree_calculate_user_set(X509_POLICY_TREE * tree,STACK_OF (ASN1_OBJECT)* policy_oids,STACK_OF (X509_POLICY_NODE)* auth_nodes)612 static int tree_calculate_user_set(X509_POLICY_TREE *tree,
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;
655 extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
656 | POLICY_DATA_FLAG_EXTRA_NODE;
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
tree_evaluate(X509_POLICY_TREE * tree)671 static int tree_evaluate(X509_POLICY_TREE *tree)
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
exnode_free(X509_POLICY_NODE * node)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
X509_policy_tree_free(X509_POLICY_TREE * tree)701 void X509_policy_tree_free(X509_POLICY_TREE *tree)
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)
718 policy_node_free(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
X509_policy_check(X509_POLICY_TREE ** ptree,int * pexplicit_policy,STACK_OF (X509)* certs,STACK_OF (ASN1_OBJECT)* policy_oids,unsigned int flags)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) {
830 nodes = X509_policy_tree_get0_user_policies(tree);
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 }
844