pcy_tree.c 22 KB

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