summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3/pcy_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509v3/pcy_tree.c')
-rw-r--r--src/lib/libcrypto/x509v3/pcy_tree.c235
1 files changed, 28 insertions, 207 deletions
diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c
index 92f6b24556..6c87a7f506 100644
--- a/src/lib/libcrypto/x509v3/pcy_tree.c
+++ b/src/lib/libcrypto/x509v3/pcy_tree.c
@@ -62,75 +62,6 @@
62 62
63#include "pcy_int.h" 63#include "pcy_int.h"
64 64
65/* Enable this to print out the complete policy tree at various point during
66 * evaluation.
67 */
68
69/*#define OPENSSL_POLICY_DEBUG*/
70
71#ifdef OPENSSL_POLICY_DEBUG
72
73static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
74 X509_POLICY_NODE *node, int indent)
75 {
76 if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
77 || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
78 BIO_puts(err, " Not Mapped\n");
79 else
80 {
81 int i;
82 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
83 ASN1_OBJECT *oid;
84 BIO_puts(err, " Expected: ");
85 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
86 {
87 oid = sk_ASN1_OBJECT_value(pset, i);
88 if (i)
89 BIO_puts(err, ", ");
90 i2a_ASN1_OBJECT(err, oid);
91 }
92 BIO_puts(err, "\n");
93 }
94 }
95
96static void tree_print(char *str, X509_POLICY_TREE *tree,
97 X509_POLICY_LEVEL *curr)
98 {
99 X509_POLICY_LEVEL *plev;
100 X509_POLICY_NODE *node;
101 int i;
102 BIO *err;
103 err = BIO_new_fp(stderr, BIO_NOCLOSE);
104 if (!curr)
105 curr = tree->levels + tree->nlevel;
106 else
107 curr++;
108 BIO_printf(err, "Level print after %s\n", str);
109 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
110 for (plev = tree->levels; plev != curr; plev++)
111 {
112 BIO_printf(err, "Level %ld, flags = %x\n",
113 plev - tree->levels, plev->flags);
114 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
115 {
116 node = sk_X509_POLICY_NODE_value(plev->nodes, i);
117 X509_POLICY_NODE_print(err, node, 2);
118 expected_print(err, plev, node, 2);
119 BIO_printf(err, " Flags: %x\n", node->data->flags);
120 }
121 if (plev->anyPolicy)
122 X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
123 }
124
125 BIO_free(err);
126
127 }
128#else
129
130#define tree_print(a,b,c) /* */
131
132#endif
133
134/* Initialize policy tree. Return values: 65/* Initialize policy tree. Return values:
135 * 0 Some internal error occured. 66 * 0 Some internal error occured.
136 * -1 Inconsistent or invalid extensions in certificates. 67 * -1 Inconsistent or invalid extensions in certificates.
@@ -156,10 +87,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
156 *ptree = NULL; 87 *ptree = NULL;
157 n = sk_X509_num(certs); 88 n = sk_X509_num(certs);
158 89
159#if 0
160 /* Disable policy mapping for now... */ 90 /* Disable policy mapping for now... */
161 flags |= X509_V_FLAG_INHIBIT_MAP; 91 flags |= X509_V_FLAG_INHIBIT_MAP;
162#endif
163 92
164 if (flags & X509_V_FLAG_EXPLICIT_POLICY) 93 if (flags & X509_V_FLAG_EXPLICIT_POLICY)
165 explicit_policy = 0; 94 explicit_policy = 0;
@@ -231,7 +160,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
231 tree->auth_policies = NULL; 160 tree->auth_policies = NULL;
232 tree->user_policies = NULL; 161 tree->user_policies = NULL;
233 162
234 if (!tree->levels) 163 if (!tree)
235 { 164 {
236 OPENSSL_free(tree); 165 OPENSSL_free(tree);
237 return 0; 166 return 0;
@@ -255,6 +184,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
255 level++; 184 level++;
256 x = sk_X509_value(certs, i); 185 x = sk_X509_value(certs, i);
257 cache = policy_cache_set(x); 186 cache = policy_cache_set(x);
187
258 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 188 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
259 level->cert = x; 189 level->cert = x;
260 190
@@ -283,13 +213,13 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
283 level->flags |= X509_V_FLAG_INHIBIT_MAP; 213 level->flags |= X509_V_FLAG_INHIBIT_MAP;
284 else 214 else
285 { 215 {
286 if (!(x->ex_flags & EXFLAG_SI)) 216 map_skip--;
287 map_skip--;
288 if ((cache->map_skip >= 0) 217 if ((cache->map_skip >= 0)
289 && (cache->map_skip < map_skip)) 218 && (cache->map_skip < map_skip))
290 map_skip = cache->map_skip; 219 map_skip = cache->map_skip;
291 } 220 }
292 221
222
293 } 223 }
294 224
295 *ptree = tree; 225 *ptree = tree;
@@ -307,32 +237,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
307 237
308 } 238 }
309 239
310static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, 240/* This corresponds to RFC3280 XXXX XXXXX:
311 const X509_POLICY_DATA *data)
312 {
313 X509_POLICY_LEVEL *last = curr - 1;
314 X509_POLICY_NODE *node;
315 int i, matched = 0;
316 /* Iterate through all in nodes linking matches */
317 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
318 {
319 node = sk_X509_POLICY_NODE_value(last->nodes, i);
320 if (policy_node_match(last, node, data->valid_policy))
321 {
322 if (!level_add_node(curr, data, node, NULL))
323 return 0;
324 matched = 1;
325 }
326 }
327 if (!matched && last->anyPolicy)
328 {
329 if (!level_add_node(curr, data, last->anyPolicy, NULL))
330 return 0;
331 }
332 return 1;
333 }
334
335/* This corresponds to RFC3280 6.1.3(d)(1):
336 * link any data from CertificatePolicies onto matching parent 241 * link any data from CertificatePolicies onto matching parent
337 * or anyPolicy if no match. 242 * or anyPolicy if no match.
338 */ 243 */
@@ -343,6 +248,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
343 int i; 248 int i;
344 X509_POLICY_LEVEL *last; 249 X509_POLICY_LEVEL *last;
345 X509_POLICY_DATA *data; 250 X509_POLICY_DATA *data;
251 X509_POLICY_NODE *parent;
346 last = curr - 1; 252 last = curr - 1;
347 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) 253 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
348 { 254 {
@@ -355,109 +261,40 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
355 * link because then it will have the mapping flags 261 * link because then it will have the mapping flags
356 * right and we can prune it later. 262 * right and we can prune it later.
357 */ 263 */
358#if 0
359 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) 264 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
360 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) 265 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
361 continue; 266 continue;
362#endif 267 /* Look for matching node in parent */
363 /* Look for matching nodes in previous level */ 268 parent = level_find_node(last, data->valid_policy);
364 if (!tree_link_matching_nodes(curr, data)) 269 /* If no match link to anyPolicy */
270 if (!parent)
271 parent = last->anyPolicy;
272 if (parent && !level_add_node(curr, data, parent, NULL))
365 return 0; 273 return 0;
366 } 274 }
367 return 1; 275 return 1;
368 } 276 }
369 277
370/* This corresponds to RFC3280 6.1.3(d)(2): 278/* This corresponds to RFC3280 XXXX XXXXX:
371 * Create new data for any unmatched policies in the parent and link 279 * Create new data for any unmatched policies in the parent and link
372 * to anyPolicy. 280 * to anyPolicy.
373 */ 281 */
374 282
375static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
376 const X509_POLICY_CACHE *cache,
377 const ASN1_OBJECT *id,
378 X509_POLICY_NODE *node,
379 X509_POLICY_TREE *tree)
380 {
381 X509_POLICY_DATA *data;
382 if (id == NULL)
383 id = node->data->valid_policy;
384 /* Create a new node with qualifiers from anyPolicy and
385 * id from unmatched node.
386 */
387 data = policy_data_new(NULL, id, node_critical(node));
388
389 if (data == NULL)
390 return 0;
391 /* Curr may not have anyPolicy */
392 data->qualifier_set = cache->anyPolicy->qualifier_set;
393 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
394 if (!level_add_node(curr, data, node, tree))
395 {
396 policy_data_free(data);
397 return 0;
398 }
399
400 return 1;
401 }
402
403static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
404 const X509_POLICY_CACHE *cache,
405 X509_POLICY_NODE *node,
406 X509_POLICY_TREE *tree)
407 {
408 const X509_POLICY_LEVEL *last = curr - 1;
409 int i;
410
411 if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
412 || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
413 {
414 /* If no policy mapping: matched if one child present */
415 if (node->nchild)
416 return 1;
417 if (!tree_add_unmatched(curr, cache, NULL, node, tree))
418 return 0;
419 /* Add it */
420 }
421 else
422 {
423 /* If mapping: matched if one child per expected policy set */
424 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
425 if (node->nchild == sk_ASN1_OBJECT_num(expset))
426 return 1;
427 /* Locate unmatched nodes */
428 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
429 {
430 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
431 if (level_find_node(curr, node, oid))
432 continue;
433 if (!tree_add_unmatched(curr, cache, oid, node, tree))
434 return 0;
435 }
436
437 }
438
439 return 1;
440
441 }
442
443static int tree_link_any(X509_POLICY_LEVEL *curr, 283static int tree_link_any(X509_POLICY_LEVEL *curr,
444 const X509_POLICY_CACHE *cache, 284 const X509_POLICY_CACHE *cache,
445 X509_POLICY_TREE *tree) 285 X509_POLICY_TREE *tree)
446 { 286 {
447 int i; 287 int i;
448 /*X509_POLICY_DATA *data;*/ 288 X509_POLICY_DATA *data;
449 X509_POLICY_NODE *node; 289 X509_POLICY_NODE *node;
450 X509_POLICY_LEVEL *last = curr - 1; 290 X509_POLICY_LEVEL *last;
291
292 last = curr - 1;
451 293
452 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 294 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
453 { 295 {
454 node = sk_X509_POLICY_NODE_value(last->nodes, i); 296 node = sk_X509_POLICY_NODE_value(last->nodes, i);
455 297
456 if (!tree_link_unmatched(curr, cache, node, tree))
457 return 0;
458
459#if 0
460
461 /* Skip any node with any children: we only want unmathced 298 /* Skip any node with any children: we only want unmathced
462 * nodes. 299 * nodes.
463 * 300 *
@@ -466,7 +303,6 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
466 */ 303 */
467 if (node->nchild) 304 if (node->nchild)
468 continue; 305 continue;
469
470 /* Create a new node with qualifiers from anyPolicy and 306 /* Create a new node with qualifiers from anyPolicy and
471 * id from unmatched node. 307 * id from unmatched node.
472 */ 308 */
@@ -483,9 +319,6 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
483 policy_data_free(data); 319 policy_data_free(data);
484 return 0; 320 return 0;
485 } 321 }
486
487#endif
488
489 } 322 }
490 /* Finally add link to anyPolicy */ 323 /* Finally add link to anyPolicy */
491 if (last->anyPolicy) 324 if (last->anyPolicy)
@@ -504,36 +337,30 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
504 337
505static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) 338static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
506 { 339 {
507 STACK_OF(X509_POLICY_NODE) *nodes;
508 X509_POLICY_NODE *node; 340 X509_POLICY_NODE *node;
509 int i; 341 int i;
510 nodes = curr->nodes; 342 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
511 if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
512 { 343 {
513 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 344 node = sk_X509_POLICY_NODE_value(curr->nodes, i);
345 /* Delete any mapped data: see RFC3280 XXXX */
346 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
514 { 347 {
515 node = sk_X509_POLICY_NODE_value(nodes, i); 348 node->parent->nchild--;
516 /* Delete any mapped data: see RFC3280 XXXX */ 349 OPENSSL_free(node);
517 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) 350 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
518 {
519 node->parent->nchild--;
520 OPENSSL_free(node);
521 (void)sk_X509_POLICY_NODE_delete(nodes,i);
522 }
523 } 351 }
524 } 352 }
525 353
526 for(;;) { 354 for(;;) {
527 --curr; 355 --curr;
528 nodes = curr->nodes; 356 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
529 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
530 { 357 {
531 node = sk_X509_POLICY_NODE_value(nodes, i); 358 node = sk_X509_POLICY_NODE_value(curr->nodes, i);
532 if (node->nchild == 0) 359 if (node->nchild == 0)
533 { 360 {
534 node->parent->nchild--; 361 node->parent->nchild--;
535 OPENSSL_free(node); 362 OPENSSL_free(node);
536 (void)sk_X509_POLICY_NODE_delete(nodes, i); 363 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
537 } 364 }
538 } 365 }
539 if (curr->anyPolicy && !curr->anyPolicy->nchild) 366 if (curr->anyPolicy && !curr->anyPolicy->nchild)
@@ -709,7 +536,6 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
709 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) 536 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
710 && !tree_link_any(curr, cache, tree)) 537 && !tree_link_any(curr, cache, tree))
711 return 0; 538 return 0;
712 tree_print("before tree_prune()", tree, curr);
713 ret = tree_prune(tree, curr); 539 ret = tree_prune(tree, curr);
714 if (ret != 1) 540 if (ret != 1)
715 return ret; 541 return ret;
@@ -778,6 +604,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
778 *pexplicit_policy = 0; 604 *pexplicit_policy = 0;
779 ret = tree_init(&tree, certs, flags); 605 ret = tree_init(&tree, certs, flags);
780 606
607
781 switch (ret) 608 switch (ret)
782 { 609 {
783 610
@@ -786,10 +613,6 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
786 return 1; 613 return 1;
787 614
788 /* Some internal error */ 615 /* Some internal error */
789 case -1:
790 return -1;
791
792 /* Some internal error */
793 case 0: 616 case 0:
794 return 0; 617 return 0;
795 618
@@ -823,8 +646,6 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
823 if (!tree) goto error; 646 if (!tree) goto error;
824 ret = tree_evaluate(tree); 647 ret = tree_evaluate(tree);
825 648
826 tree_print("tree_evaluate()", tree, NULL);
827
828 if (ret <= 0) 649 if (ret <= 0)
829 goto error; 650 goto error;
830 651