OpenCoverage

pcy_tree.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/x509v3/pcy_tree.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.-
3 *-
4 * Licensed under the OpenSSL license (the "License"). You may not use-
5 * this file except in compliance with the License. You can obtain a copy-
6 * in the file LICENSE in the source distribution or at-
7 * https://www.openssl.org/source/license.html-
8 */-
9-
10#include "internal/cryptlib.h"-
11#include <openssl/x509.h>-
12#include <openssl/x509v3.h>-
13-
14#include "pcy_int.h"-
15-
16/*-
17 * Enable this to print out the complete policy tree at various point during-
18 * evaluation.-
19 */-
20-
21/*-
22 * #define OPENSSL_POLICY_DEBUG-
23 */-
24-
25#ifdef OPENSSL_POLICY_DEBUG-
26-
27static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,-
28 X509_POLICY_NODE *node, int indent)-
29{-
30 if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)-
31 || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))-
32 BIO_puts(err, " Not Mapped\n");-
33 else {-
34 int i;-
35 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;-
36 ASN1_OBJECT *oid;-
37 BIO_puts(err, " Expected: ");-
38 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {-
39 oid = sk_ASN1_OBJECT_value(pset, i);-
40 if (i)-
41 BIO_puts(err, ", ");-
42 i2a_ASN1_OBJECT(err, oid);-
43 }-
44 BIO_puts(err, "\n");-
45 }-
46}-
47-
48static void tree_print(char *str, X509_POLICY_TREE *tree,-
49 X509_POLICY_LEVEL *curr)-
50{-
51 BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE);-
52 X509_POLICY_LEVEL *plev;-
53-
54 if (err == NULL)-
55 return;-
56 if (!curr)-
57 curr = tree->levels + tree->nlevel;-
58 else-
59 curr++;-
60-
61 BIO_printf(err, "Level print after %s\n", str);-
62 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);-
63 for (plev = tree->levels; plev != curr; plev++) {-
64 int i;-
65-
66 BIO_printf(err, "Level %ld, flags = %x\n",-
67 (long)(plev - tree->levels), plev->flags);-
68 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {-
69 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(plev->nodes, i);-
70-
71 X509_POLICY_NODE_print(err, node, 2);-
72 expected_print(err, plev, node, 2);-
73 BIO_printf(err, " Flags: %x\n", node->data->flags);-
74 }-
75 if (plev->anyPolicy)-
76 X509_POLICY_NODE_print(err, plev->anyPolicy, 2);-
77 }-
78 BIO_free(err);-
79}-
80#endif-
81-
82/*--
83 * Return value: <= 0 on error, or positive bit mask:-
84 *-
85 * X509_PCY_TREE_VALID: valid tree-
86 * X509_PCY_TREE_EMPTY: empty tree (including bare TA case)-
87 * X509_PCY_TREE_EXPLICIT: explicit policy required-
88 */-
89static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,-
90 unsigned int flags)-
91{-
92 X509_POLICY_TREE *tree;-
93 X509_POLICY_LEVEL *level;-
94 const X509_POLICY_CACHE *cache;-
95 X509_POLICY_DATA *data = NULL;-
96 int ret = X509_PCY_TREE_VALID;-
97 int n = sk_X509_num(certs) - 1; /* RFC5280 paths omit the TA */-
98 int explicit_policy = (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : n+1;
(flags & 0x100)Description
TRUEnever evaluated
FALSEnever evaluated
0
99 int any_skip = (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : n+1;
(flags & 0x200)Description
TRUEnever evaluated
FALSEnever evaluated
0
100 int map_skip = (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : n+1;
(flags & 0x400)Description
TRUEnever evaluated
FALSEnever evaluated
0
101 int i;-
102-
103 *ptree = NULL;-
104-
105 /* Can't do anything with just a trust anchor */-
106 if (n == 0)
n == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
107 return X509_PCY_TREE_EMPTY;
never executed: return 2;
0
108-
109 /*-
110 * First setup the policy cache in all n non-TA certificates, this will be-
111 * used in X509_verify_cert() which will invoke the verify callback for all-
112 * certificates with invalid policy extensions.-
113 */-
114 for (i = n - 1; i >= 0; i--) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
115 X509 *x = sk_X509_value(certs, i);-
116-
117 /* Call for side-effect of computing hash and caching extensions */-
118 X509_check_purpose(x, -1, 0);-
119-
120 /* If cache is NULL, likely ENOMEM: return immediately */-
121 if (policy_cache_set(x) == NULL)
policy_cache_s...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
122 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
123 }
never executed: end of block
0
124-
125 /*-
126 * At this point check for invalid policies and required explicit policy.-
127 * Note that the explicit_policy counter is a count-down to zero, with the-
128 * requirement kicking in if and once it does that. The counter is-
129 * decremented for every non-self-issued certificate in the path, but may-
130 * be further reduced by policy constraints in a non-leaf certificate.-
131 *-
132 * The ultimate policy set is the intersection of all the policies along-
133 * the path, if we hit a certificate with an empty policy set, and explicit-
134 * policy is required we're done.-
135 */-
136 for (i = n - 1;-
137 i >= 0 && (explicit_policy > 0 || (ret & X509_PCY_TREE_EMPTY) == 0);
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
explicit_policy > 0Description
TRUEnever evaluated
FALSEnever evaluated
(ret & 2) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
138 i--) {-
139 X509 *x = sk_X509_value(certs, i);-
140 uint32_t ex_flags = X509_get_extension_flags(x);-
141-
142 /* All the policies are already cached, we can return early */-
143 if (ex_flags & EXFLAG_INVALID_POLICY)
ex_flags & 0x800Description
TRUEnever evaluated
FALSEnever evaluated
0
144 return X509_PCY_TREE_INVALID;
never executed: return -1;
0
145-
146 /* Access the cache which we now know exists */-
147 cache = policy_cache_set(x);-
148-
149 if ((ret & X509_PCY_TREE_VALID) && cache->data == NULL)
(ret & 1)Description
TRUEnever evaluated
FALSEnever evaluated
cache->data == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
150 ret = X509_PCY_TREE_EMPTY;
never executed: ret = 2;
0
151 if (explicit_policy > 0) {
explicit_policy > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
152 if (!(ex_flags & EXFLAG_SI))
!(ex_flags & 0x20)Description
TRUEnever evaluated
FALSEnever evaluated
0
153 explicit_policy--;
never executed: explicit_policy--;
0
154 if ((cache->explicit_skip >= 0)
(cache->explicit_skip >= 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
155 && (cache->explicit_skip < explicit_policy))
(cache->explic...plicit_policy)Description
TRUEnever evaluated
FALSEnever evaluated
0
156 explicit_policy = cache->explicit_skip;
never executed: explicit_policy = cache->explicit_skip;
0
157 }
never executed: end of block
0
158 }
never executed: end of block
0
159-
160 if (explicit_policy == 0)
explicit_policy == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
161 ret |= X509_PCY_TREE_EXPLICIT;
never executed: ret |= 4;
0
162 if ((ret & X509_PCY_TREE_VALID) == 0)
(ret & 1) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
163 return ret;
never executed: return ret;
0
164-
165 /* If we get this far initialize the tree */-
166 if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL) {
(tree = CRYPTO...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
167 X509V3err(X509V3_F_TREE_INIT, ERR_R_MALLOC_FAILURE);-
168 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
169 }-
170-
171 /*-
172 * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.-
173 *-
174 * The top level is implicitly for the trust anchor with valid expected-
175 * policies of anyPolicy. (RFC 5280 has the TA at depth 0 and the leaf at-
176 * depth n, we have the leaf at depth 0 and the TA at depth n).-
177 */-
178 if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) {
(tree->levels ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
179 OPENSSL_free(tree);-
180 X509V3err(X509V3_F_TREE_INIT, ERR_R_MALLOC_FAILURE);-
181 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
182 }-
183 tree->nlevel = n+1;-
184 level = tree->levels;-
185 if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
(data = policy...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
186 goto bad_tree;
never executed: goto bad_tree;
0
187 if (level_add_node(level, data, NULL, tree) == NULL) {
level_add_node...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
188 policy_data_free(data);-
189 goto bad_tree;
never executed: goto bad_tree;
0
190 }-
191-
192 /*-
193 * In this pass initialize all the tree levels and whether anyPolicy and-
194 * policy mapping are inhibited at each level.-
195 */-
196 for (i = n - 1; i >= 0; i--) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
197 X509 *x = sk_X509_value(certs, i);-
198 uint32_t ex_flags = X509_get_extension_flags(x);-
199-
200 /* Access the cache which we now know exists */-
201 cache = policy_cache_set(x);-
202-
203 X509_up_ref(x);-
204 (++level)->cert = x;-
205-
206 if (!cache->anyPolicy)
!cache->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
207 level->flags |= X509_V_FLAG_INHIBIT_ANY;
never executed: level->flags |= 0x200;
0
208-
209 /* Determine inhibit any and inhibit map flags */-
210 if (any_skip == 0) {
any_skip == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
211 /*-
212 * Any matching allowed only if certificate is self issued and not-
213 * the last in the chain.-
214 */-
215 if (!(ex_flags & EXFLAG_SI) || (i == 0))
!(ex_flags & 0x20)Description
TRUEnever evaluated
FALSEnever evaluated
(i == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
216 level->flags |= X509_V_FLAG_INHIBIT_ANY;
never executed: level->flags |= 0x200;
0
217 } else {
never executed: end of block
0
218 if (!(ex_flags & EXFLAG_SI))
!(ex_flags & 0x20)Description
TRUEnever evaluated
FALSEnever evaluated
0
219 any_skip--;
never executed: any_skip--;
0
220 if ((cache->any_skip >= 0) && (cache->any_skip < any_skip))
(cache->any_skip >= 0)Description
TRUEnever evaluated
FALSEnever evaluated
(cache->any_skip < any_skip)Description
TRUEnever evaluated
FALSEnever evaluated
0
221 any_skip = cache->any_skip;
never executed: any_skip = cache->any_skip;
0
222 }
never executed: end of block
0
223-
224 if (map_skip == 0)
map_skip == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
225 level->flags |= X509_V_FLAG_INHIBIT_MAP;
never executed: level->flags |= 0x400;
0
226 else {-
227 if (!(ex_flags & EXFLAG_SI))
!(ex_flags & 0x20)Description
TRUEnever evaluated
FALSEnever evaluated
0
228 map_skip--;
never executed: map_skip--;
0
229 if ((cache->map_skip >= 0) && (cache->map_skip < map_skip))
(cache->map_skip >= 0)Description
TRUEnever evaluated
FALSEnever evaluated
(cache->map_skip < map_skip)Description
TRUEnever evaluated
FALSEnever evaluated
0
230 map_skip = cache->map_skip;
never executed: map_skip = cache->map_skip;
0
231 }
never executed: end of block
0
232 }-
233-
234 *ptree = tree;-
235 return ret;
never executed: return ret;
0
236-
237 bad_tree:-
238 X509_policy_tree_free(tree);-
239 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
240}-
241-
242/*-
243 * Return value: 1 on success, 0 otherwise-
244 */-
245static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,-
246 X509_POLICY_DATA *data)-
247{-
248 X509_POLICY_LEVEL *last = curr - 1;-
249 int i, matched = 0;-
250-
251 /* Iterate through all in nodes linking matches */-
252 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
i < sk_X509_PO...m(last->nodes)Description
TRUEnever evaluated
FALSEnever evaluated
0
253 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);-
254-
255 if (policy_node_match(last, node, data->valid_policy)) {
policy_node_ma...>valid_policy)Description
TRUEnever evaluated
FALSEnever evaluated
0
256 if (level_add_node(curr, data, node, NULL) == NULL)
level_add_node...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
257 return 0;
never executed: return 0;
0
258 matched = 1;-
259 }
never executed: end of block
0
260 }
never executed: end of block
0
261 if (!matched && last->anyPolicy) {
!matchedDescription
TRUEnever evaluated
FALSEnever evaluated
last->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
262 if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
level_add_node...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
263 return 0;
never executed: return 0;
0
264 }
never executed: end of block
0
265 return 1;
never executed: return 1;
0
266}-
267-
268/*-
269 * This corresponds to RFC3280 6.1.3(d)(1): link any data from-
270 * CertificatePolicies onto matching parent or anyPolicy if no match.-
271 *-
272 * Return value: 1 on success, 0 otherwise.-
273 */-
274static int tree_link_nodes(X509_POLICY_LEVEL *curr,-
275 const X509_POLICY_CACHE *cache)-
276{-
277 int i;-
278-
279 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
i < sk_X509_PO...m(cache->data)Description
TRUEnever evaluated
FALSEnever evaluated
0
280 X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);-
281-
282 /* Look for matching nodes in previous level */-
283 if (!tree_link_matching_nodes(curr, data))
!tree_link_mat...es(curr, data)Description
TRUEnever evaluated
FALSEnever evaluated
0
284 return 0;
never executed: return 0;
0
285 }
never executed: end of block
0
286 return 1;
never executed: return 1;
0
287}-
288-
289/*-
290 * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched-
291 * policies in the parent and link to anyPolicy.-
292 *-
293 * Return value: 1 on success, 0 otherwise.-
294 */-
295static int tree_add_unmatched(X509_POLICY_LEVEL *curr,-
296 const X509_POLICY_CACHE *cache,-
297 const ASN1_OBJECT *id,-
298 X509_POLICY_NODE *node, X509_POLICY_TREE *tree)-
299{-
300 X509_POLICY_DATA *data;-
301-
302 if (id == NULL)
id == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
303 id = node->data->valid_policy;
never executed: id = node->data->valid_policy;
0
304 /*-
305 * Create a new node with qualifiers from anyPolicy and id from unmatched-
306 * node.-
307 */-
308 if ((data = policy_data_new(NULL, id, node_critical(node))) == NULL)
(data = policy...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
309 return 0;
never executed: return 0;
0
310-
311 /* Curr may not have anyPolicy */-
312 data->qualifier_set = cache->anyPolicy->qualifier_set;-
313 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;-
314 if (level_add_node(curr, data, node, tree) == NULL) {
level_add_node...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
315 policy_data_free(data);-
316 return 0;
never executed: return 0;
0
317 }-
318 return 1;
never executed: return 1;
0
319}-
320-
321/*-
322 * Return value: 1 on success, 0 otherwise.-
323 */-
324static int tree_link_unmatched(X509_POLICY_LEVEL *curr,-
325 const X509_POLICY_CACHE *cache,-
326 X509_POLICY_NODE *node, X509_POLICY_TREE *tree)-
327{-
328 const X509_POLICY_LEVEL *last = curr - 1;-
329 int i;-
330-
331 if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
(last->flags & 0x400)Description
TRUEnever evaluated
FALSEnever evaluated
0
332 || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
!(node->data->flags & 0x1)Description
TRUEnever evaluated
FALSEnever evaluated
0
333 /* If no policy mapping: matched if one child present */-
334 if (node->nchild)
node->nchildDescription
TRUEnever evaluated
FALSEnever evaluated
0
335 return 1;
never executed: return 1;
0
336 if (!tree_add_unmatched(curr, cache, NULL, node, tree))
!tree_add_unma... , node, tree)Description
TRUEnever evaluated
FALSEnever evaluated
0
337 return 0;
never executed: return 0;
0
338 /* Add it */-
339 } else {
never executed: end of block
0
340 /* If mapping: matched if one child per expected policy set */-
341 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;-
342 if (node->nchild == sk_ASN1_OBJECT_num(expset))
node->nchild =...CT_num(expset)Description
TRUEnever evaluated
FALSEnever evaluated
0
343 return 1;
never executed: return 1;
0
344 /* Locate unmatched nodes */-
345 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
i < sk_ASN1_OBJECT_num(expset)Description
TRUEnever evaluated
FALSEnever evaluated
0
346 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);-
347 if (level_find_node(curr, node, oid))
level_find_nod...rr, node, oid)Description
TRUEnever evaluated
FALSEnever evaluated
0
348 continue;
never executed: continue;
0
349 if (!tree_add_unmatched(curr, cache, oid, node, tree))
!tree_add_unma...d, node, tree)Description
TRUEnever evaluated
FALSEnever evaluated
0
350 return 0;
never executed: return 0;
0
351 }
never executed: end of block
0
352-
353 }
never executed: end of block
0
354 return 1;
never executed: return 1;
0
355}-
356-
357/*-
358 * Return value: 1 on success, 0 otherwise-
359 */-
360static int tree_link_any(X509_POLICY_LEVEL *curr,-
361 const X509_POLICY_CACHE *cache,-
362 X509_POLICY_TREE *tree)-
363{-
364 int i;-
365 X509_POLICY_NODE *node;-
366 X509_POLICY_LEVEL *last = curr - 1;-
367-
368 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
i < sk_X509_PO...m(last->nodes)Description
TRUEnever evaluated
FALSEnever evaluated
0
369 node = sk_X509_POLICY_NODE_value(last->nodes, i);-
370-
371 if (!tree_link_unmatched(curr, cache, node, tree))
!tree_link_unm...e, node, tree)Description
TRUEnever evaluated
FALSEnever evaluated
0
372 return 0;
never executed: return 0;
0
373 }
never executed: end of block
0
374 /* Finally add link to anyPolicy */-
375 if (last->anyPolicy &&
last->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
376 level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL)
level_add_node...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
377 return 0;
never executed: return 0;
0
378 return 1;
never executed: return 1;
0
379}-
380-
381/*--
382 * Prune the tree: delete any child mapped child data on the current level then-
383 * proceed up the tree deleting any data with no children. If we ever have no-
384 * data on a level we can halt because the tree will be empty.-
385 *-
386 * Return value: <= 0 error, otherwise one of:-
387 *-
388 * X509_PCY_TREE_VALID: valid tree-
389 * X509_PCY_TREE_EMPTY: empty tree-
390 */-
391static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)-
392{-
393 STACK_OF(X509_POLICY_NODE) *nodes;-
394 X509_POLICY_NODE *node;-
395 int i;-
396 nodes = curr->nodes;-
397 if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
curr->flags & 0x400Description
TRUEnever evaluated
FALSEnever evaluated
0
398 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
399 node = sk_X509_POLICY_NODE_value(nodes, i);-
400 /* Delete any mapped data: see RFC3280 XXXX */-
401 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
node->data->flags & 0x3Description
TRUEnever evaluated
FALSEnever evaluated
0
402 node->parent->nchild--;-
403 OPENSSL_free(node);-
404 (void)sk_X509_POLICY_NODE_delete(nodes, i);-
405 }
never executed: end of block
0
406 }
never executed: end of block
0
407 }
never executed: end of block
0
408-
409 for (;;) {-
410 --curr;-
411 nodes = curr->nodes;-
412 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
413 node = sk_X509_POLICY_NODE_value(nodes, i);-
414 if (node->nchild == 0) {
node->nchild == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
415 node->parent->nchild--;-
416 OPENSSL_free(node);-
417 (void)sk_X509_POLICY_NODE_delete(nodes, i);-
418 }
never executed: end of block
0
419 }
never executed: end of block
0
420 if (curr->anyPolicy && !curr->anyPolicy->nchild) {
curr->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
!curr->anyPolicy->nchildDescription
TRUEnever evaluated
FALSEnever evaluated
0
421 if (curr->anyPolicy->parent)
curr->anyPolicy->parentDescription
TRUEnever evaluated
FALSEnever evaluated
0
422 curr->anyPolicy->parent->nchild--;
never executed: curr->anyPolicy->parent->nchild--;
0
423 OPENSSL_free(curr->anyPolicy);-
424 curr->anyPolicy = NULL;-
425 }
never executed: end of block
0
426 if (curr == tree->levels) {
curr == tree->levelsDescription
TRUEnever evaluated
FALSEnever evaluated
0
427 /* If we zapped anyPolicy at top then tree is empty */-
428 if (!curr->anyPolicy)
!curr->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
429 return X509_PCY_TREE_EMPTY;
never executed: return 2;
0
430 break;
never executed: break;
0
431 }-
432 }
never executed: end of block
0
433 return X509_PCY_TREE_VALID;
never executed: return 1;
0
434}-
435-
436/*-
437 * Return value: 1 on success, 0 otherwise.-
438 */-
439static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,-
440 X509_POLICY_NODE *pcy)-
441{-
442 if (*pnodes == NULL &&
*pnodes == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
443 (*pnodes = policy_node_cmp_new()) == NULL)
(*pnodes = pol...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
444 return 0;
never executed: return 0;
0
445 if (sk_X509_POLICY_NODE_find(*pnodes, pcy) >= 0)
sk_X509_POLICY...des, pcy) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
446 return 1;
never executed: return 1;
0
447 return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0;
never executed: return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0;
0
448}-
449-
450#define TREE_CALC_FAILURE 0-
451#define TREE_CALC_OK_NOFREE 1-
452#define TREE_CALC_OK_DOFREE 2-
453-
454/*--
455 * Calculate the authority set based on policy tree. The 'pnodes' parameter is-
456 * used as a store for the set of policy nodes used to calculate the user set.-
457 * If the authority set is not anyPolicy then pnodes will just point to the-
458 * authority set. If however the authority set is anyPolicy then the set of-
459 * valid policies (other than anyPolicy) is store in pnodes.-
460 *-
461 * Return value:-
462 * TREE_CALC_FAILURE on failure,-
463 * TREE_CALC_OK_NOFREE on success and pnodes need not be freed,-
464 * TREE_CALC_OK_DOFREE on success and pnodes needs to be freed-
465 */-
466static int tree_calculate_authority_set(X509_POLICY_TREE *tree,-
467 STACK_OF(X509_POLICY_NODE) **pnodes)-
468{-
469 X509_POLICY_LEVEL *curr;-
470 X509_POLICY_NODE *node, *anyptr;-
471 STACK_OF(X509_POLICY_NODE) **addnodes;-
472 int i, j;-
473 curr = tree->levels + tree->nlevel - 1;-
474-
475 /* If last level contains anyPolicy set is anyPolicy */-
476 if (curr->anyPolicy) {
curr->anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
477 if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
!tree_add_auth...rr->anyPolicy)Description
TRUEnever evaluated
FALSEnever evaluated
0
478 return TREE_CALC_FAILURE;
never executed: return 0;
0
479 addnodes = pnodes;-
480 } else
never executed: end of block
0
481 /* Add policies to authority set */-
482 addnodes = &tree->auth_policies;
never executed: addnodes = &tree->auth_policies;
0
483-
484 curr = tree->levels;-
485 for (i = 1; i < tree->nlevel; i++) {
i < tree->nlevelDescription
TRUEnever evaluated
FALSEnever evaluated
0
486 /*-
487 * If no anyPolicy node on this this level it can't appear on lower-
488 * levels so end search.-
489 */-
490 if ((anyptr = curr->anyPolicy) == NULL)
(anyptr = curr...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
491 break;
never executed: break;
0
492 curr++;-
493 for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
j < sk_X509_PO...m(curr->nodes)Description
TRUEnever evaluated
FALSEnever evaluated
0
494 node = sk_X509_POLICY_NODE_value(curr->nodes, j);-
495 if ((node->parent == anyptr)
(node->parent == anyptr)Description
TRUEnever evaluated
FALSEnever evaluated
0
496 && !tree_add_auth_node(addnodes, node)) {
!tree_add_auth...ddnodes, node)Description
TRUEnever evaluated
FALSEnever evaluated
0
497 if (addnodes == pnodes) {
addnodes == pnodesDescription
TRUEnever evaluated
FALSEnever evaluated
0
498 sk_X509_POLICY_NODE_free(*pnodes);-
499 *pnodes = NULL;-
500 }
never executed: end of block
0
501 return TREE_CALC_FAILURE;
never executed: return 0;
0
502 }-
503 }
never executed: end of block
0
504 }
never executed: end of block
0
505 if (addnodes == pnodes)
addnodes == pnodesDescription
TRUEnever evaluated
FALSEnever evaluated
0
506 return TREE_CALC_OK_DOFREE;
never executed: return 2;
0
507-
508 *pnodes = tree->auth_policies;-
509 return TREE_CALC_OK_NOFREE;
never executed: return 1;
0
510}-
511-
512/*-
513 * Return value: 1 on success, 0 otherwise.-
514 */-
515static int tree_calculate_user_set(X509_POLICY_TREE *tree,-
516 STACK_OF(ASN1_OBJECT) *policy_oids,-
517 STACK_OF(X509_POLICY_NODE) *auth_nodes)-
518{-
519 int i;-
520 X509_POLICY_NODE *node;-
521 ASN1_OBJECT *oid;-
522 X509_POLICY_NODE *anyPolicy;-
523 X509_POLICY_DATA *extra;-
524-
525 /*-
526 * Check if anyPolicy present in authority constrained policy set: this-
527 * will happen if it is a leaf node.-
528 */-
529 if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
sk_ASN1_OBJECT...icy_oids) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
530 return 1;
never executed: return 1;
0
531-
532 anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;-
533-
534 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
i < sk_ASN1_OB...m(policy_oids)Description
TRUEnever evaluated
FALSEnever evaluated
0
535 oid = sk_ASN1_OBJECT_value(policy_oids, i);-
536 if (OBJ_obj2nid(oid) == NID_any_policy) {
OBJ_obj2nid(oid) == 746Description
TRUEnever evaluated
FALSEnever evaluated
0
537 tree->flags |= POLICY_FLAG_ANY_POLICY;-
538 return 1;
never executed: return 1;
0
539 }-
540 }
never executed: end of block
0
541-
542 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
i < sk_ASN1_OB...m(policy_oids)Description
TRUEnever evaluated
FALSEnever evaluated
0
543 oid = sk_ASN1_OBJECT_value(policy_oids, i);-
544 node = tree_find_sk(auth_nodes, oid);-
545 if (!node) {
!nodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
546 if (!anyPolicy)
!anyPolicyDescription
TRUEnever evaluated
FALSEnever evaluated
0
547 continue;
never executed: continue;
0
548 /*-
549 * Create a new node with policy ID from user set and qualifiers-
550 * from anyPolicy.-
551 */-
552 extra = policy_data_new(NULL, oid, node_critical(anyPolicy));-
553 if (extra == NULL)
extra == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
554 return 0;
never executed: return 0;
0
555 extra->qualifier_set = anyPolicy->data->qualifier_set;-
556 extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS-
557 | POLICY_DATA_FLAG_EXTRA_NODE;-
558 node = level_add_node(NULL, extra, anyPolicy->parent, tree);-
559 }
never executed: end of block
0
560 if (!tree->user_policies) {
!tree->user_policiesDescription
TRUEnever evaluated
FALSEnever evaluated
0
561 tree->user_policies = sk_X509_POLICY_NODE_new_null();-
562 if (!tree->user_policies)
!tree->user_policiesDescription
TRUEnever evaluated
FALSEnever evaluated
0
563 return 1;
never executed: return 1;
0
564 }
never executed: end of block
0
565 if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
!sk_X509_POLIC...olicies, node)Description
TRUEnever evaluated
FALSEnever evaluated
0
566 return 0;
never executed: return 0;
0
567 }
never executed: end of block
0
568 return 1;
never executed: return 1;
0
569}-
570-
571/*--
572 * Return value: <= 0 error, otherwise one of:-
573 * X509_PCY_TREE_VALID: valid tree-
574 * X509_PCY_TREE_EMPTY: empty tree-
575 * (see tree_prune()).-
576 */-
577static int tree_evaluate(X509_POLICY_TREE *tree)-
578{-
579 int ret, i;-
580 X509_POLICY_LEVEL *curr = tree->levels + 1;-
581 const X509_POLICY_CACHE *cache;-
582-
583 for (i = 1; i < tree->nlevel; i++, curr++) {
i < tree->nlevelDescription
TRUEnever evaluated
FALSEnever evaluated
0
584 cache = policy_cache_set(curr->cert);-
585 if (!tree_link_nodes(curr, cache))
!tree_link_nodes(curr, cache)Description
TRUEnever evaluated
FALSEnever evaluated
0
586 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
587-
588 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
!(curr->flags & 0x200)Description
TRUEnever evaluated
FALSEnever evaluated
0
589 && !tree_link_any(curr, cache, tree))
!tree_link_any..., cache, tree)Description
TRUEnever evaluated
FALSEnever evaluated
0
590 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
591#ifdef OPENSSL_POLICY_DEBUG-
592 tree_print("before tree_prune()", tree, curr);-
593#endif-
594 ret = tree_prune(tree, curr);-
595 if (ret != X509_PCY_TREE_VALID)
ret != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
596 return ret;
never executed: return ret;
0
597 }
never executed: end of block
0
598 return X509_PCY_TREE_VALID;
never executed: return 1;
0
599}-
600-
601static void exnode_free(X509_POLICY_NODE *node)-
602{-
603 if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
node->dataDescription
TRUEnever evaluated
FALSEnever evaluated
(node->data->flags & 0x8)Description
TRUEnever evaluated
FALSEnever evaluated
0
604 OPENSSL_free(node);
never executed: CRYPTO_free(node, __FILE__, 604);
0
605}
never executed: end of block
0
606-
607void X509_policy_tree_free(X509_POLICY_TREE *tree)-
608{-
609 X509_POLICY_LEVEL *curr;-
610 int i;-
611-
612 if (!tree)
!treeDescription
TRUEevaluated 5111 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-5111
613 return;
executed 5111 times by 1 test: return;
Executed by:
  • libcrypto.so.1.1
5111
614-
615 sk_X509_POLICY_NODE_free(tree->auth_policies);-
616 sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);-
617-
618 for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
i < tree->nlevelDescription
TRUEnever evaluated
FALSEnever evaluated
0
619 X509_free(curr->cert);-
620 sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);-
621 policy_node_free(curr->anyPolicy);-
622 }
never executed: end of block
0
623-
624 sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);-
625 OPENSSL_free(tree->levels);-
626 OPENSSL_free(tree);-
627-
628}
never executed: end of block
0
629-
630/*--
631 * Application policy checking function.-
632 * Return codes:-
633 * X509_PCY_TREE_FAILURE: Failure to satisfy explicit policy-
634 * X509_PCY_TREE_INVALID: Inconsistent or invalid extensions-
635 * X509_PCY_TREE_INTERNAL: Internal error, most likely malloc-
636 * X509_PCY_TREE_VALID: Success (null tree if empty or bare TA)-
637 */-
638int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,-
639 STACK_OF(X509) *certs,-
640 STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)-
641{-
642 int init_ret;-
643 int ret;-
644 int calc_ret;-
645 X509_POLICY_TREE *tree = NULL;-
646 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;-
647-
648 *ptree = NULL;-
649 *pexplicit_policy = 0;-
650 init_ret = tree_init(&tree, certs, flags);-
651-
652 if (init_ret <= 0)
init_ret <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
653 return init_ret;
never executed: return init_ret;
0
654-
655 if ((init_ret & X509_PCY_TREE_EXPLICIT) == 0) {
(init_ret & 4) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
656 if (init_ret & X509_PCY_TREE_EMPTY) {
init_ret & 2Description
TRUEnever evaluated
FALSEnever evaluated
0
657 X509_policy_tree_free(tree);-
658 return X509_PCY_TREE_VALID;
never executed: return 1;
0
659 }-
660 } else {
never executed: end of block
0
661 *pexplicit_policy = 1;-
662 /* Tree empty and requireExplicit True: Error */-
663 if (init_ret & X509_PCY_TREE_EMPTY)
init_ret & 2Description
TRUEnever evaluated
FALSEnever evaluated
0
664 return X509_PCY_TREE_FAILURE;
never executed: return -2;
0
665 }
never executed: end of block
0
666-
667 ret = tree_evaluate(tree);-
668#ifdef OPENSSL_POLICY_DEBUG-
669 tree_print("tree_evaluate()", tree, NULL);-
670#endif-
671 if (ret <= 0)
ret <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
672 goto error;
never executed: goto error;
0
673-
674 if (ret == X509_PCY_TREE_EMPTY) {
ret == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
675 X509_policy_tree_free(tree);-
676 if (init_ret & X509_PCY_TREE_EXPLICIT)
init_ret & 4Description
TRUEnever evaluated
FALSEnever evaluated
0
677 return X509_PCY_TREE_FAILURE;
never executed: return -2;
0
678 return X509_PCY_TREE_VALID;
never executed: return 1;
0
679 }-
680-
681 /* Tree is not empty: continue */-
682-
683 if ((calc_ret = tree_calculate_authority_set(tree, &auth_nodes)) == 0)
(calc_ret = tr...h_nodes)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
684 goto error;
never executed: goto error;
0
685 ret = tree_calculate_user_set(tree, policy_oids, auth_nodes);-
686 if (calc_ret == TREE_CALC_OK_DOFREE)
calc_ret == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
687 sk_X509_POLICY_NODE_free(auth_nodes);
never executed: sk_X509_POLICY_NODE_free(auth_nodes);
0
688 if (!ret)
!retDescription
TRUEnever evaluated
FALSEnever evaluated
0
689 goto error;
never executed: goto error;
0
690-
691 *ptree = tree;-
692-
693 if (init_ret & X509_PCY_TREE_EXPLICIT) {
init_ret & 4Description
TRUEnever evaluated
FALSEnever evaluated
0
694 nodes = X509_policy_tree_get0_user_policies(tree);-
695 if (sk_X509_POLICY_NODE_num(nodes) <= 0)
sk_X509_POLICY...um(nodes) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
696 return X509_PCY_TREE_FAILURE;
never executed: return -2;
0
697 }
never executed: end of block
0
698 return X509_PCY_TREE_VALID;
never executed: return 1;
0
699-
700 error:-
701 X509_policy_tree_free(tree);-
702 return X509_PCY_TREE_INTERNAL;
never executed: return 0;
0
703}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2