2
0

pcy_tree.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. /* pcy_tree.c */
  2. /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  3. * project 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. #include "cryptlib.h"
  59. #include <openssl/x509.h>
  60. #include <openssl/x509v3.h>
  61. #include "pcy_int.h"
  62. /* Enable this to print out the complete policy tree at various point during
  63. * evaluation.
  64. */
  65. /*#define OPENSSL_POLICY_DEBUG*/
  66. #ifdef OPENSSL_POLICY_DEBUG
  67. static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
  68. X509_POLICY_NODE *node, int indent)
  69. {
  70. if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
  71. || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
  72. BIO_puts(err, " Not Mapped\n");
  73. else
  74. {
  75. int i;
  76. STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
  77. ASN1_OBJECT *oid;
  78. BIO_puts(err, " Expected: ");
  79. for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
  80. {
  81. oid = sk_ASN1_OBJECT_value(pset, i);
  82. if (i)
  83. BIO_puts(err, ", ");
  84. i2a_ASN1_OBJECT(err, oid);
  85. }
  86. BIO_puts(err, "\n");
  87. }
  88. }
  89. static void tree_print(char *str, X509_POLICY_TREE *tree,
  90. X509_POLICY_LEVEL *curr)
  91. {
  92. X509_POLICY_LEVEL *plev;
  93. X509_POLICY_NODE *node;
  94. int i;
  95. BIO *err;
  96. err = BIO_new_fp(stderr, BIO_NOCLOSE);
  97. if (!curr)
  98. curr = tree->levels + tree->nlevel;
  99. else
  100. curr++;
  101. BIO_printf(err, "Level print after %s\n", str);
  102. BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
  103. for (plev = tree->levels; plev != curr; plev++)
  104. {
  105. BIO_printf(err, "Level %ld, flags = %x\n",
  106. plev - tree->levels, plev->flags);
  107. for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
  108. {
  109. node = sk_X509_POLICY_NODE_value(plev->nodes, i);
  110. X509_POLICY_NODE_print(err, node, 2);
  111. expected_print(err, plev, node, 2);
  112. BIO_printf(err, " Flags: %x\n", node->data->flags);
  113. }
  114. if (plev->anyPolicy)
  115. X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
  116. }
  117. BIO_free(err);
  118. }
  119. #else
  120. #define tree_print(a,b,c) /* */
  121. #endif
  122. /* Initialize policy tree. Return values:
  123. * 0 Some internal error occured.
  124. * -1 Inconsistent or invalid extensions in certificates.
  125. * 1 Tree initialized OK.
  126. * 2 Policy tree is empty.
  127. * 5 Tree OK and requireExplicitPolicy true.
  128. * 6 Tree empty and requireExplicitPolicy true.
  129. */
  130. static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
  131. unsigned int flags)
  132. {
  133. X509_POLICY_TREE *tree;
  134. X509_POLICY_LEVEL *level;
  135. const X509_POLICY_CACHE *cache;
  136. X509_POLICY_DATA *data = NULL;
  137. X509 *x;
  138. int ret = 1;
  139. int i, n;
  140. int explicit_policy;
  141. int any_skip;
  142. int map_skip;
  143. *ptree = NULL;
  144. n = sk_X509_num(certs);
  145. #if 0
  146. /* Disable policy mapping for now... */
  147. flags |= X509_V_FLAG_INHIBIT_MAP;
  148. #endif
  149. if (flags & X509_V_FLAG_EXPLICIT_POLICY)
  150. explicit_policy = 0;
  151. else
  152. explicit_policy = n + 1;
  153. if (flags & X509_V_FLAG_INHIBIT_ANY)
  154. any_skip = 0;
  155. else
  156. any_skip = n + 1;
  157. if (flags & X509_V_FLAG_INHIBIT_MAP)
  158. map_skip = 0;
  159. else
  160. map_skip = n + 1;
  161. /* Can't do anything with just a trust anchor */
  162. if (n == 1)
  163. return 1;
  164. /* First setup policy cache in all certificates apart from the
  165. * trust anchor. Note any bad cache results on the way. Also can
  166. * calculate explicit_policy value at this point.
  167. */
  168. for (i = n - 2; i >= 0; i--)
  169. {
  170. x = sk_X509_value(certs, i);
  171. X509_check_purpose(x, -1, -1);
  172. cache = policy_cache_set(x);
  173. /* If cache NULL something bad happened: return immediately */
  174. if (cache == NULL)
  175. return 0;
  176. /* If inconsistent extensions keep a note of it but continue */
  177. if (x->ex_flags & EXFLAG_INVALID_POLICY)
  178. ret = -1;
  179. /* Otherwise if we have no data (hence no CertificatePolicies)
  180. * and haven't already set an inconsistent code note it.
  181. */
  182. else if ((ret == 1) && !cache->data)
  183. ret = 2;
  184. if (explicit_policy > 0)
  185. {
  186. if (!(x->ex_flags & EXFLAG_SI))
  187. explicit_policy--;
  188. if ((cache->explicit_skip != -1)
  189. && (cache->explicit_skip < explicit_policy))
  190. explicit_policy = cache->explicit_skip;
  191. }
  192. }
  193. if (ret != 1)
  194. {
  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(X509_POLICY_TREE));
  201. if (!tree)
  202. return 0;
  203. tree->flags = 0;
  204. tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * 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. {
  211. OPENSSL_free(tree);
  212. return 0;
  213. }
  214. memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
  215. tree->nlevel = n;
  216. level = tree->levels;
  217. /* Root data: initialize to anyPolicy */
  218. data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
  219. if (!data || !level_add_node(level, data, NULL, tree))
  220. goto bad_tree;
  221. for (i = n - 2; i >= 0; i--)
  222. {
  223. level++;
  224. x = sk_X509_value(certs, i);
  225. cache = policy_cache_set(x);
  226. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
  227. level->cert = x;
  228. if (!cache->anyPolicy)
  229. level->flags |= X509_V_FLAG_INHIBIT_ANY;
  230. /* Determine inhibit any and inhibit map flags */
  231. if (any_skip == 0)
  232. {
  233. /* Any matching allowed if certificate is self
  234. * issued and not the last in the chain.
  235. */
  236. if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
  237. level->flags |= X509_V_FLAG_INHIBIT_ANY;
  238. }
  239. else
  240. {
  241. if (!(x->ex_flags & EXFLAG_SI))
  242. any_skip--;
  243. if ((cache->any_skip >= 0)
  244. && (cache->any_skip < any_skip))
  245. any_skip = cache->any_skip;
  246. }
  247. if (map_skip == 0)
  248. level->flags |= X509_V_FLAG_INHIBIT_MAP;
  249. else
  250. {
  251. if (!(x->ex_flags & EXFLAG_SI))
  252. map_skip--;
  253. if ((cache->map_skip >= 0)
  254. && (cache->map_skip < map_skip))
  255. map_skip = cache->map_skip;
  256. }
  257. }
  258. *ptree = tree;
  259. if (explicit_policy)
  260. return 1;
  261. else
  262. return 5;
  263. bad_tree:
  264. X509_policy_tree_free(tree);
  265. return 0;
  266. }
  267. static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
  268. const X509_POLICY_DATA *data)
  269. {
  270. X509_POLICY_LEVEL *last = curr - 1;
  271. X509_POLICY_NODE *node;
  272. int i, matched = 0;
  273. /* Iterate through all in nodes linking matches */
  274. for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
  275. {
  276. node = sk_X509_POLICY_NODE_value(last->nodes, i);
  277. if (policy_node_match(last, node, data->valid_policy))
  278. {
  279. if (!level_add_node(curr, data, node, NULL))
  280. return 0;
  281. matched = 1;
  282. }
  283. }
  284. if (!matched && last->anyPolicy)
  285. {
  286. if (!level_add_node(curr, data, last->anyPolicy, NULL))
  287. return 0;
  288. }
  289. return 1;
  290. }
  291. /* This corresponds to RFC3280 6.1.3(d)(1):
  292. * link any data from CertificatePolicies onto matching parent
  293. * or anyPolicy if no match.
  294. */
  295. static int tree_link_nodes(X509_POLICY_LEVEL *curr,
  296. const X509_POLICY_CACHE *cache)
  297. {
  298. int i;
  299. X509_POLICY_DATA *data;
  300. for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
  301. {
  302. data = sk_X509_POLICY_DATA_value(cache->data, i);
  303. /* If a node is mapped any it doesn't have a corresponding
  304. * CertificatePolicies entry.
  305. * However such an identical node would be created
  306. * if anyPolicy matching is enabled because there would be
  307. * no match with the parent valid_policy_set. So we create
  308. * link because then it will have the mapping flags
  309. * right and we can prune it later.
  310. */
  311. #if 0
  312. if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
  313. && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
  314. continue;
  315. #endif
  316. /* Look for matching nodes in previous level */
  317. if (!tree_link_matching_nodes(curr, data))
  318. return 0;
  319. }
  320. return 1;
  321. }
  322. /* This corresponds to RFC3280 6.1.3(d)(2):
  323. * Create new data for any unmatched policies in the parent and link
  324. * to anyPolicy.
  325. */
  326. static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
  327. const X509_POLICY_CACHE *cache,
  328. const ASN1_OBJECT *id,
  329. X509_POLICY_NODE *node,
  330. X509_POLICY_TREE *tree)
  331. {
  332. X509_POLICY_DATA *data;
  333. if (id == NULL)
  334. id = node->data->valid_policy;
  335. /* Create a new node with qualifiers from anyPolicy and
  336. * id from unmatched node.
  337. */
  338. data = policy_data_new(NULL, id, node_critical(node));
  339. if (data == NULL)
  340. return 0;
  341. /* Curr may not have anyPolicy */
  342. data->qualifier_set = cache->anyPolicy->qualifier_set;
  343. data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
  344. if (!level_add_node(curr, data, node, tree))
  345. {
  346. policy_data_free(data);
  347. return 0;
  348. }
  349. return 1;
  350. }
  351. static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
  352. const X509_POLICY_CACHE *cache,
  353. X509_POLICY_NODE *node,
  354. X509_POLICY_TREE *tree)
  355. {
  356. const X509_POLICY_LEVEL *last = curr - 1;
  357. int i;
  358. if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
  359. || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
  360. {
  361. /* If no policy mapping: matched if one child present */
  362. if (node->nchild)
  363. return 1;
  364. if (!tree_add_unmatched(curr, cache, NULL, node, tree))
  365. return 0;
  366. /* Add it */
  367. }
  368. else
  369. {
  370. /* If mapping: matched if one child per expected policy set */
  371. STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
  372. if (node->nchild == sk_ASN1_OBJECT_num(expset))
  373. return 1;
  374. /* Locate unmatched nodes */
  375. for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
  376. {
  377. ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
  378. if (level_find_node(curr, node, oid))
  379. continue;
  380. if (!tree_add_unmatched(curr, cache, oid, node, tree))
  381. return 0;
  382. }
  383. }
  384. return 1;
  385. }
  386. static int tree_link_any(X509_POLICY_LEVEL *curr,
  387. const X509_POLICY_CACHE *cache,
  388. X509_POLICY_TREE *tree)
  389. {
  390. int i;
  391. /*X509_POLICY_DATA *data;*/
  392. X509_POLICY_NODE *node;
  393. X509_POLICY_LEVEL *last = curr - 1;
  394. for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
  395. {
  396. node = sk_X509_POLICY_NODE_value(last->nodes, i);
  397. if (!tree_link_unmatched(curr, cache, node, tree))
  398. return 0;
  399. #if 0
  400. /* Skip any node with any children: we only want unmathced
  401. * nodes.
  402. *
  403. * Note: need something better for policy mapping
  404. * because each node may have multiple children
  405. */
  406. if (node->nchild)
  407. continue;
  408. /* Create a new node with qualifiers from anyPolicy and
  409. * id from unmatched node.
  410. */
  411. data = policy_data_new(NULL, node->data->valid_policy,
  412. node_critical(node));
  413. if (data == NULL)
  414. return 0;
  415. /* Curr may not have anyPolicy */
  416. data->qualifier_set = cache->anyPolicy->qualifier_set;
  417. data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
  418. if (!level_add_node(curr, data, node, tree))
  419. {
  420. policy_data_free(data);
  421. return 0;
  422. }
  423. #endif
  424. }
  425. /* Finally add link to anyPolicy */
  426. if (last->anyPolicy)
  427. {
  428. if (!level_add_node(curr, cache->anyPolicy,
  429. last->anyPolicy, NULL))
  430. return 0;
  431. }
  432. return 1;
  433. }
  434. /* Prune the tree: delete any child mapped child data on the current level
  435. * then proceed up the tree deleting any data with no children. If we ever
  436. * have no data on a level we can halt because the tree will be empty.
  437. */
  438. static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
  439. {
  440. STACK_OF(X509_POLICY_NODE) *nodes;
  441. X509_POLICY_NODE *node;
  442. int i;
  443. nodes = curr->nodes;
  444. if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
  445. {
  446. for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
  447. {
  448. node = sk_X509_POLICY_NODE_value(nodes, i);
  449. /* Delete any mapped data: see RFC3280 XXXX */
  450. if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
  451. {
  452. node->parent->nchild--;
  453. OPENSSL_free(node);
  454. (void)sk_X509_POLICY_NODE_delete(nodes,i);
  455. }
  456. }
  457. }
  458. for(;;) {
  459. --curr;
  460. nodes = curr->nodes;
  461. for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
  462. {
  463. node = sk_X509_POLICY_NODE_value(nodes, i);
  464. if (node->nchild == 0)
  465. {
  466. node->parent->nchild--;
  467. OPENSSL_free(node);
  468. (void)sk_X509_POLICY_NODE_delete(nodes, i);
  469. }
  470. }
  471. if (curr->anyPolicy && !curr->anyPolicy->nchild)
  472. {
  473. if (curr->anyPolicy->parent)
  474. curr->anyPolicy->parent->nchild--;
  475. OPENSSL_free(curr->anyPolicy);
  476. curr->anyPolicy = NULL;
  477. }
  478. if (curr == tree->levels)
  479. {
  480. /* If we zapped anyPolicy at top then tree is empty */
  481. if (!curr->anyPolicy)
  482. return 2;
  483. return 1;
  484. }
  485. }
  486. return 1;
  487. }
  488. static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
  489. X509_POLICY_NODE *pcy)
  490. {
  491. if (!*pnodes)
  492. {
  493. *pnodes = policy_node_cmp_new();
  494. if (!*pnodes)
  495. return 0;
  496. }
  497. else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
  498. return 1;
  499. if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
  500. return 0;
  501. return 1;
  502. }
  503. /* Calculate the authority set based on policy tree.
  504. * The 'pnodes' parameter is used as a store for the set of policy nodes
  505. * used to calculate the user set. If the authority set is not anyPolicy
  506. * then pnodes will just point to the authority set. If however the authority
  507. * set is anyPolicy then the set of valid policies (other than anyPolicy)
  508. * is store in pnodes. The return value of '2' is used in this case to indicate
  509. * that pnodes should be freed.
  510. */
  511. static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
  512. STACK_OF(X509_POLICY_NODE) **pnodes)
  513. {
  514. X509_POLICY_LEVEL *curr;
  515. X509_POLICY_NODE *node, *anyptr;
  516. STACK_OF(X509_POLICY_NODE) **addnodes;
  517. int i, j;
  518. curr = tree->levels + tree->nlevel - 1;
  519. /* If last level contains anyPolicy set is anyPolicy */
  520. if (curr->anyPolicy)
  521. {
  522. if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
  523. return 0;
  524. addnodes = pnodes;
  525. }
  526. else
  527. /* Add policies to authority set */
  528. addnodes = &tree->auth_policies;
  529. curr = tree->levels;
  530. for (i = 1; i < tree->nlevel; i++)
  531. {
  532. /* If no anyPolicy node on this this level it can't
  533. * appear on lower levels so end search.
  534. */
  535. if (!(anyptr = curr->anyPolicy))
  536. break;
  537. curr++;
  538. for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
  539. {
  540. node = sk_X509_POLICY_NODE_value(curr->nodes, j);
  541. if ((node->parent == anyptr)
  542. && !tree_add_auth_node(addnodes, node))
  543. return 0;
  544. }
  545. }
  546. if (addnodes == pnodes)
  547. return 2;
  548. *pnodes = tree->auth_policies;
  549. return 1;
  550. }
  551. static int tree_calculate_user_set(X509_POLICY_TREE *tree,
  552. STACK_OF(ASN1_OBJECT) *policy_oids,
  553. STACK_OF(X509_POLICY_NODE) *auth_nodes)
  554. {
  555. int i;
  556. X509_POLICY_NODE *node;
  557. ASN1_OBJECT *oid;
  558. X509_POLICY_NODE *anyPolicy;
  559. X509_POLICY_DATA *extra;
  560. /* Check if anyPolicy present in authority constrained policy set:
  561. * this will happen if it is a leaf node.
  562. */
  563. if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
  564. return 1;
  565. anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
  566. for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
  567. {
  568. oid = sk_ASN1_OBJECT_value(policy_oids, i);
  569. if (OBJ_obj2nid(oid) == NID_any_policy)
  570. {
  571. tree->flags |= POLICY_FLAG_ANY_POLICY;
  572. return 1;
  573. }
  574. }
  575. for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
  576. {
  577. oid = sk_ASN1_OBJECT_value(policy_oids, i);
  578. node = tree_find_sk(auth_nodes, oid);
  579. if (!node)
  580. {
  581. if (!anyPolicy)
  582. continue;
  583. /* Create a new node with policy ID from user set
  584. * and qualifiers from anyPolicy.
  585. */
  586. extra = policy_data_new(NULL, oid,
  587. node_critical(anyPolicy));
  588. if (!extra)
  589. return 0;
  590. extra->qualifier_set = anyPolicy->data->qualifier_set;
  591. extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
  592. | POLICY_DATA_FLAG_EXTRA_NODE;
  593. node = level_add_node(NULL, extra, anyPolicy->parent,
  594. tree);
  595. }
  596. if (!tree->user_policies)
  597. {
  598. tree->user_policies = sk_X509_POLICY_NODE_new_null();
  599. if (!tree->user_policies)
  600. return 1;
  601. }
  602. if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
  603. return 0;
  604. }
  605. return 1;
  606. }
  607. static int tree_evaluate(X509_POLICY_TREE *tree)
  608. {
  609. int ret, i;
  610. X509_POLICY_LEVEL *curr = tree->levels + 1;
  611. const X509_POLICY_CACHE *cache;
  612. for(i = 1; i < tree->nlevel; i++, curr++)
  613. {
  614. cache = policy_cache_set(curr->cert);
  615. if (!tree_link_nodes(curr, cache))
  616. return 0;
  617. if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
  618. && !tree_link_any(curr, cache, tree))
  619. return 0;
  620. tree_print("before tree_prune()", tree, curr);
  621. ret = tree_prune(tree, curr);
  622. if (ret != 1)
  623. return ret;
  624. }
  625. return 1;
  626. }
  627. static void exnode_free(X509_POLICY_NODE *node)
  628. {
  629. if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
  630. OPENSSL_free(node);
  631. }
  632. void X509_policy_tree_free(X509_POLICY_TREE *tree)
  633. {
  634. X509_POLICY_LEVEL *curr;
  635. int i;
  636. if (!tree)
  637. return;
  638. sk_X509_POLICY_NODE_free(tree->auth_policies);
  639. sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
  640. for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
  641. {
  642. if (curr->cert)
  643. X509_free(curr->cert);
  644. if (curr->nodes)
  645. sk_X509_POLICY_NODE_pop_free(curr->nodes,
  646. policy_node_free);
  647. if (curr->anyPolicy)
  648. policy_node_free(curr->anyPolicy);
  649. }
  650. if (tree->extra_data)
  651. sk_X509_POLICY_DATA_pop_free(tree->extra_data,
  652. policy_data_free);
  653. OPENSSL_free(tree->levels);
  654. OPENSSL_free(tree);
  655. }
  656. /* Application policy checking function.
  657. * Return codes:
  658. * 0 Internal Error.
  659. * 1 Successful.
  660. * -1 One or more certificates contain invalid or inconsistent extensions
  661. * -2 User constrained policy set empty and requireExplicit true.
  662. */
  663. int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
  664. STACK_OF(X509) *certs,
  665. STACK_OF(ASN1_OBJECT) *policy_oids,
  666. unsigned int flags)
  667. {
  668. int ret;
  669. X509_POLICY_TREE *tree = NULL;
  670. STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
  671. *ptree = NULL;
  672. *pexplicit_policy = 0;
  673. ret = tree_init(&tree, certs, flags);
  674. switch (ret)
  675. {
  676. /* Tree empty requireExplicit False: OK */
  677. case 2:
  678. return 1;
  679. /* Some internal error */
  680. case -1:
  681. return -1;
  682. /* Some internal error */
  683. case 0:
  684. return 0;
  685. /* Tree empty requireExplicit True: Error */
  686. case 6:
  687. *pexplicit_policy = 1;
  688. return -2;
  689. /* Tree OK requireExplicit True: OK and continue */
  690. case 5:
  691. *pexplicit_policy = 1;
  692. break;
  693. /* Tree OK: continue */
  694. case 1:
  695. if (!tree)
  696. /*
  697. * tree_init() returns success and a null tree
  698. * if it's just looking at a trust anchor.
  699. * I'm not sure that returning success here is
  700. * correct, but I'm sure that reporting this
  701. * as an internal error which our caller
  702. * interprets as a malloc failure is wrong.
  703. */
  704. return 1;
  705. break;
  706. }
  707. if (!tree) goto error;
  708. ret = tree_evaluate(tree);
  709. tree_print("tree_evaluate()", tree, NULL);
  710. if (ret <= 0)
  711. goto error;
  712. /* Return value 2 means tree empty */
  713. if (ret == 2)
  714. {
  715. X509_policy_tree_free(tree);
  716. if (*pexplicit_policy)
  717. return -2;
  718. else
  719. return 1;
  720. }
  721. /* Tree is not empty: continue */
  722. ret = tree_calculate_authority_set(tree, &auth_nodes);
  723. if (!ret)
  724. goto error;
  725. if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
  726. goto error;
  727. if (ret == 2)
  728. sk_X509_POLICY_NODE_free(auth_nodes);
  729. if (tree)
  730. *ptree = tree;
  731. if (*pexplicit_policy)
  732. {
  733. nodes = X509_policy_tree_get0_user_policies(tree);
  734. if (sk_X509_POLICY_NODE_num(nodes) <= 0)
  735. return -2;
  736. }
  737. return 1;
  738. error:
  739. X509_policy_tree_free(tree);
  740. return 0;
  741. }