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