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