summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3/pcy_tree.c
diff options
context:
space:
mode:
authorjsing <>2014-04-21 08:41:26 +0000
committerjsing <>2014-04-21 08:41:26 +0000
commitaf50ddfc8cd7409b6577826223496779c69cd1e0 (patch)
treef2f8e8a8d38afa820e7b749c66023be793b9ca3c /src/lib/libcrypto/x509v3/pcy_tree.c
parentf46c697a11680ae5d3ab06393f0bfe2ed1841168 (diff)
downloadopenbsd-af50ddfc8cd7409b6577826223496779c69cd1e0.tar.gz
openbsd-af50ddfc8cd7409b6577826223496779c69cd1e0.tar.bz2
openbsd-af50ddfc8cd7409b6577826223496779c69cd1e0.zip
KNF.
Diffstat (limited to 'src/lib/libcrypto/x509v3/pcy_tree.c')
-rw-r--r--src/lib/libcrypto/x509v3/pcy_tree.c457
1 files changed, 202 insertions, 255 deletions
diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c
index c4239b1fd9..ebc4809371 100644
--- a/src/lib/libcrypto/x509v3/pcy_tree.c
+++ b/src/lib/libcrypto/x509v3/pcy_tree.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -70,36 +70,36 @@
70 70
71#ifdef OPENSSL_POLICY_DEBUG 71#ifdef OPENSSL_POLICY_DEBUG
72 72
73static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, 73static void
74 X509_POLICY_NODE *node, int indent) 74expected_print(BIO *err, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node,
75 { 75 int indent)
76 if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP) 76{
77 || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) 77 if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) ||
78 !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
78 BIO_puts(err, " Not Mapped\n"); 79 BIO_puts(err, " Not Mapped\n");
79 else 80 else {
80 {
81 int i; 81 int i;
82 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; 82 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
83 ASN1_OBJECT *oid; 83 ASN1_OBJECT *oid;
84 BIO_puts(err, " Expected: "); 84 BIO_puts(err, " Expected: ");
85 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) 85 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
86 {
87 oid = sk_ASN1_OBJECT_value(pset, i); 86 oid = sk_ASN1_OBJECT_value(pset, i);
88 if (i) 87 if (i)
89 BIO_puts(err, ", "); 88 BIO_puts(err, ", ");
90 i2a_ASN1_OBJECT(err, oid); 89 i2a_ASN1_OBJECT(err, oid);
91 }
92 BIO_puts(err, "\n");
93 } 90 }
91 BIO_puts(err, "\n");
94 } 92 }
93}
95 94
96static void tree_print(char *str, X509_POLICY_TREE *tree, 95static void
97 X509_POLICY_LEVEL *curr) 96tree_print(char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
98 { 97{
99 X509_POLICY_LEVEL *plev; 98 X509_POLICY_LEVEL *plev;
100 X509_POLICY_NODE *node; 99 X509_POLICY_NODE *node;
101 int i; 100 int i;
102 BIO *err; 101 BIO *err;
102
103 err = BIO_new_fp(stderr, BIO_NOCLOSE); 103 err = BIO_new_fp(stderr, BIO_NOCLOSE);
104 if (!curr) 104 if (!curr)
105 curr = tree->levels + tree->nlevel; 105 curr = tree->levels + tree->nlevel;
@@ -107,24 +107,21 @@ static void tree_print(char *str, X509_POLICY_TREE *tree,
107 curr++; 107 curr++;
108 BIO_printf(err, "Level print after %s\n", str); 108 BIO_printf(err, "Level print after %s\n", str);
109 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); 109 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
110 for (plev = tree->levels; plev != curr; plev++) 110 for (plev = tree->levels; plev != curr; plev++) {
111 {
112 BIO_printf(err, "Level %ld, flags = %x\n", 111 BIO_printf(err, "Level %ld, flags = %x\n",
113 plev - tree->levels, plev->flags); 112 plev - tree->levels, plev->flags);
114 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) 113 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
115 {
116 node = sk_X509_POLICY_NODE_value(plev->nodes, i); 114 node = sk_X509_POLICY_NODE_value(plev->nodes, i);
117 X509_POLICY_NODE_print(err, node, 2); 115 X509_POLICY_NODE_print(err, node, 2);
118 expected_print(err, plev, node, 2); 116 expected_print(err, plev, node, 2);
119 BIO_printf(err, " Flags: %x\n", node->data->flags); 117 BIO_printf(err, " Flags: %x\n", node->data->flags);
120 } 118 }
121 if (plev->anyPolicy) 119 if (plev->anyPolicy)
122 X509_POLICY_NODE_print(err, plev->anyPolicy, 2); 120 X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
123 } 121 }
124 122
125 BIO_free(err); 123 BIO_free(err);
126 124}
127 }
128#else 125#else
129 126
130#define tree_print(a,b,c) /* */ 127#define tree_print(a,b,c) /* */
@@ -140,9 +137,9 @@ static void tree_print(char *str, X509_POLICY_TREE *tree,
140 * 6 Tree empty and requireExplicitPolicy true. 137 * 6 Tree empty and requireExplicitPolicy true.
141 */ 138 */
142 139
143static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, 140static int
144 unsigned int flags) 141tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags)
145 { 142{
146 X509_POLICY_TREE *tree; 143 X509_POLICY_TREE *tree;
147 X509_POLICY_LEVEL *level; 144 X509_POLICY_LEVEL *level;
148 const X509_POLICY_CACHE *cache; 145 const X509_POLICY_CACHE *cache;
@@ -153,6 +150,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
153 int explicit_policy; 150 int explicit_policy;
154 int any_skip; 151 int any_skip;
155 int map_skip; 152 int map_skip;
153
156 *ptree = NULL; 154 *ptree = NULL;
157 n = sk_X509_num(certs); 155 n = sk_X509_num(certs);
158 156
@@ -183,8 +181,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
183 * trust anchor. Note any bad cache results on the way. Also can 181 * trust anchor. Note any bad cache results on the way. Also can
184 * calculate explicit_policy value at this point. 182 * calculate explicit_policy value at this point.
185 */ 183 */
186 for (i = n - 2; i >= 0; i--) 184 for (i = n - 2; i >= 0; i--) {
187 {
188 x = sk_X509_value(certs, i); 185 x = sk_X509_value(certs, i);
189 X509_check_purpose(x, -1, -1); 186 X509_check_purpose(x, -1, -1);
190 cache = policy_cache_set(x); 187 cache = policy_cache_set(x);
@@ -199,22 +196,20 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
199 */ 196 */
200 else if ((ret == 1) && !cache->data) 197 else if ((ret == 1) && !cache->data)
201 ret = 2; 198 ret = 2;
202 if (explicit_policy > 0) 199 if (explicit_policy > 0) {
203 {
204 if (!(x->ex_flags & EXFLAG_SI)) 200 if (!(x->ex_flags & EXFLAG_SI))
205 explicit_policy--; 201 explicit_policy--;
206 if ((cache->explicit_skip != -1) 202 if ((cache->explicit_skip != -1) &&
207 && (cache->explicit_skip < explicit_policy)) 203 (cache->explicit_skip < explicit_policy))
208 explicit_policy = cache->explicit_skip; 204 explicit_policy = cache->explicit_skip;
209 }
210 } 205 }
206 }
211 207
212 if (ret != 1) 208 if (ret != 1) {
213 {
214 if (ret == 2 && !explicit_policy) 209 if (ret == 2 && !explicit_policy)
215 return 6; 210 return 6;
216 return ret; 211 return ret;
217 } 212 }
218 213
219 214
220 /* If we get this far initialize the tree */ 215 /* If we get this far initialize the tree */
@@ -231,11 +226,10 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
231 tree->auth_policies = NULL; 226 tree->auth_policies = NULL;
232 tree->user_policies = NULL; 227 tree->user_policies = NULL;
233 228
234 if (!tree->levels) 229 if (!tree->levels) {
235 {
236 free(tree); 230 free(tree);
237 return 0; 231 return 0;
238 } 232 }
239 233
240 memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); 234 memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
241 235
@@ -250,8 +244,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
250 if (!data || !level_add_node(level, data, NULL, tree)) 244 if (!data || !level_add_node(level, data, NULL, tree))
251 goto bad_tree; 245 goto bad_tree;
252 246
253 for (i = n - 2; i >= 0; i--) 247 for (i = n - 2; i >= 0; i--) {
254 {
255 level++; 248 level++;
256 x = sk_X509_value(certs, i); 249 x = sk_X509_value(certs, i);
257 cache = policy_cache_set(x); 250 cache = policy_cache_set(x);
@@ -259,39 +252,35 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
259 level->cert = x; 252 level->cert = x;
260 253
261 if (!cache->anyPolicy) 254 if (!cache->anyPolicy)
262 level->flags |= X509_V_FLAG_INHIBIT_ANY; 255 level->flags |= X509_V_FLAG_INHIBIT_ANY;
263 256
264 /* Determine inhibit any and inhibit map flags */ 257 /* Determine inhibit any and inhibit map flags */
265 if (any_skip == 0) 258 if (any_skip == 0) {
266 {
267 /* Any matching allowed if certificate is self 259 /* Any matching allowed if certificate is self
268 * issued and not the last in the chain. 260 * issued and not the last in the chain.
269 */ 261 */
270 if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) 262 if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
271 level->flags |= X509_V_FLAG_INHIBIT_ANY; 263 level->flags |= X509_V_FLAG_INHIBIT_ANY;
272 } 264 } else {
273 else
274 {
275 if (!(x->ex_flags & EXFLAG_SI)) 265 if (!(x->ex_flags & EXFLAG_SI))
276 any_skip--; 266 any_skip--;
277 if ((cache->any_skip >= 0) 267 if ((cache->any_skip >= 0) &&
278 && (cache->any_skip < any_skip)) 268 (cache->any_skip < any_skip))
279 any_skip = cache->any_skip; 269 any_skip = cache->any_skip;
280 } 270 }
281 271
282 if (map_skip == 0) 272 if (map_skip == 0)
283 level->flags |= X509_V_FLAG_INHIBIT_MAP; 273 level->flags |= X509_V_FLAG_INHIBIT_MAP;
284 else 274 else {
285 {
286 if (!(x->ex_flags & EXFLAG_SI)) 275 if (!(x->ex_flags & EXFLAG_SI))
287 map_skip--; 276 map_skip--;
288 if ((cache->map_skip >= 0) 277 if ((cache->map_skip >= 0) &&
289 && (cache->map_skip < map_skip)) 278 (cache->map_skip < map_skip))
290 map_skip = cache->map_skip; 279 map_skip = cache->map_skip;
291 }
292
293 } 280 }
294 281
282 }
283
295 *ptree = tree; 284 *ptree = tree;
296 285
297 if (explicit_policy) 286 if (explicit_policy)
@@ -299,55 +288,50 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
299 else 288 else
300 return 5; 289 return 5;
301 290
302 bad_tree: 291bad_tree:
303
304 X509_policy_tree_free(tree); 292 X509_policy_tree_free(tree);
305 293
306 return 0; 294 return 0;
295}
307 296
308 } 297static int
309 298tree_link_matching_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_DATA *data)
310static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, 299{
311 const X509_POLICY_DATA *data)
312 {
313 X509_POLICY_LEVEL *last = curr - 1; 300 X509_POLICY_LEVEL *last = curr - 1;
314 X509_POLICY_NODE *node; 301 X509_POLICY_NODE *node;
315 int i, matched = 0; 302 int i, matched = 0;
303
316 /* Iterate through all in nodes linking matches */ 304 /* Iterate through all in nodes linking matches */
317 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 305 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
318 {
319 node = sk_X509_POLICY_NODE_value(last->nodes, i); 306 node = sk_X509_POLICY_NODE_value(last->nodes, i);
320 if (policy_node_match(last, node, data->valid_policy)) 307 if (policy_node_match(last, node, data->valid_policy)) {
321 {
322 if (!level_add_node(curr, data, node, NULL)) 308 if (!level_add_node(curr, data, node, NULL))
323 return 0; 309 return 0;
324 matched = 1; 310 matched = 1;
325 }
326 } 311 }
327 if (!matched && last->anyPolicy) 312 }
328 { 313 if (!matched && last->anyPolicy) {
329 if (!level_add_node(curr, data, last->anyPolicy, NULL)) 314 if (!level_add_node(curr, data, last->anyPolicy, NULL))
330 return 0; 315 return 0;
331 }
332 return 1;
333 } 316 }
317 return 1;
318}
334 319
335/* This corresponds to RFC3280 6.1.3(d)(1): 320/* This corresponds to RFC3280 6.1.3(d)(1):
336 * link any data from CertificatePolicies onto matching parent 321 * link any data from CertificatePolicies onto matching parent
337 * or anyPolicy if no match. 322 * or anyPolicy if no match.
338 */ 323 */
339 324
340static int tree_link_nodes(X509_POLICY_LEVEL *curr, 325static int
341 const X509_POLICY_CACHE *cache) 326tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache)
342 { 327{
343 int i; 328 int i;
344 X509_POLICY_DATA *data; 329 X509_POLICY_DATA *data;
345 330
346 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) 331 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
347 {
348 data = sk_X509_POLICY_DATA_value(cache->data, i); 332 data = sk_X509_POLICY_DATA_value(cache->data, i);
349 /* If a node is mapped any it doesn't have a corresponding 333 /* If a node is mapped any it doesn't have a corresponding
350 * CertificatePolicies entry. 334 * CertificatePolicies entry.
351 * However such an identical node would be created 335 * However such an identical node would be created
352 * if anyPolicy matching is enabled because there would be 336 * if anyPolicy matching is enabled because there would be
353 * no match with the parent valid_policy_set. So we create 337 * no match with the parent valid_policy_set. So we create
@@ -355,29 +339,28 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
355 * right and we can prune it later. 339 * right and we can prune it later.
356 */ 340 */
357#if 0 341#if 0
358 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) 342 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) &&
359 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) 343 !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
360 continue; 344 continue;
361#endif 345#endif
362 /* Look for matching nodes in previous level */ 346 /* Look for matching nodes in previous level */
363 if (!tree_link_matching_nodes(curr, data)) 347 if (!tree_link_matching_nodes(curr, data))
364 return 0; 348 return 0;
365 }
366 return 1;
367 } 349 }
350 return 1;
351}
368 352
369/* This corresponds to RFC3280 6.1.3(d)(2): 353/* This corresponds to RFC3280 6.1.3(d)(2):
370 * Create new data for any unmatched policies in the parent and link 354 * Create new data for any unmatched policies in the parent and link
371 * to anyPolicy. 355 * to anyPolicy.
372 */ 356 */
373 357
374static int tree_add_unmatched(X509_POLICY_LEVEL *curr, 358static int
375 const X509_POLICY_CACHE *cache, 359tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
376 const ASN1_OBJECT *id, 360 const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
377 X509_POLICY_NODE *node, 361{
378 X509_POLICY_TREE *tree)
379 {
380 X509_POLICY_DATA *data; 362 X509_POLICY_DATA *data;
363
381 if (id == NULL) 364 if (id == NULL)
382 id = node->data->valid_policy; 365 id = node->data->valid_policy;
383 /* Create a new node with qualifiers from anyPolicy and 366 /* Create a new node with qualifiers from anyPolicy and
@@ -390,66 +373,57 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
390 /* Curr may not have anyPolicy */ 373 /* Curr may not have anyPolicy */
391 data->qualifier_set = cache->anyPolicy->qualifier_set; 374 data->qualifier_set = cache->anyPolicy->qualifier_set;
392 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 375 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
393 if (!level_add_node(curr, data, node, tree)) 376 if (!level_add_node(curr, data, node, tree)) {
394 {
395 policy_data_free(data); 377 policy_data_free(data);
396 return 0; 378 return 0;
397 } 379 }
398 380
399 return 1; 381 return 1;
400 } 382}
401 383
402static int tree_link_unmatched(X509_POLICY_LEVEL *curr, 384static int
403 const X509_POLICY_CACHE *cache, 385tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
404 X509_POLICY_NODE *node, 386 X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
405 X509_POLICY_TREE *tree) 387{
406 {
407 const X509_POLICY_LEVEL *last = curr - 1; 388 const X509_POLICY_LEVEL *last = curr - 1;
408 int i; 389 int i;
409 390
410 if ( (last->flags & X509_V_FLAG_INHIBIT_MAP) 391 if ((last->flags & X509_V_FLAG_INHIBIT_MAP) ||
411 || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) 392 !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
412 {
413 /* If no policy mapping: matched if one child present */ 393 /* If no policy mapping: matched if one child present */
414 if (node->nchild) 394 if (node->nchild)
415 return 1; 395 return 1;
416 if (!tree_add_unmatched(curr, cache, NULL, node, tree)) 396 if (!tree_add_unmatched(curr, cache, NULL, node, tree))
417 return 0; 397 return 0;
418 /* Add it */ 398 /* Add it */
419 } 399 } else {
420 else
421 {
422 /* If mapping: matched if one child per expected policy set */ 400 /* If mapping: matched if one child per expected policy set */
423 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; 401 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
424 if (node->nchild == sk_ASN1_OBJECT_num(expset)) 402 if (node->nchild == sk_ASN1_OBJECT_num(expset))
425 return 1; 403 return 1;
426 /* Locate unmatched nodes */ 404 /* Locate unmatched nodes */
427 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) 405 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
428 {
429 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); 406 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
430 if (level_find_node(curr, node, oid)) 407 if (level_find_node(curr, node, oid))
431 continue; 408 continue;
432 if (!tree_add_unmatched(curr, cache, oid, node, tree)) 409 if (!tree_add_unmatched(curr, cache, oid, node, tree))
433 return 0; 410 return 0;
434 }
435
436 } 411 }
412 }
437 413
438 return 1; 414 return 1;
415}
439 416
440 } 417static int
441 418tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
442static int tree_link_any(X509_POLICY_LEVEL *curr, 419 X509_POLICY_TREE *tree)
443 const X509_POLICY_CACHE *cache, 420{
444 X509_POLICY_TREE *tree)
445 {
446 int i; 421 int i;
447 /*X509_POLICY_DATA *data;*/ 422 /*X509_POLICY_DATA *data;*/
448 X509_POLICY_NODE *node; 423 X509_POLICY_NODE *node;
449 X509_POLICY_LEVEL *last = curr - 1; 424 X509_POLICY_LEVEL *last = curr - 1;
450 425
451 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 426 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
452 {
453 node = sk_X509_POLICY_NODE_value(last->nodes, i); 427 node = sk_X509_POLICY_NODE_value(last->nodes, i);
454 428
455 if (!tree_link_unmatched(curr, cache, node, tree)) 429 if (!tree_link_unmatched(curr, cache, node, tree))
@@ -461,7 +435,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
461 * nodes. 435 * nodes.
462 * 436 *
463 * Note: need something better for policy mapping 437 * Note: need something better for policy mapping
464 * because each node may have multiple children 438 * because each node may have multiple children
465 */ 439 */
466 if (node->nchild) 440 if (node->nchild)
467 continue; 441 continue;
@@ -469,110 +443,99 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
469 /* Create a new node with qualifiers from anyPolicy and 443 /* Create a new node with qualifiers from anyPolicy and
470 * id from unmatched node. 444 * id from unmatched node.
471 */ 445 */
472 data = policy_data_new(NULL, node->data->valid_policy, 446 data = policy_data_new(NULL, node->data->valid_policy,
473 node_critical(node)); 447 node_critical(node));
474 448
475 if (data == NULL) 449 if (data == NULL)
476 return 0; 450 return 0;
477 /* Curr may not have anyPolicy */ 451 /* Curr may not have anyPolicy */
478 data->qualifier_set = cache->anyPolicy->qualifier_set; 452 data->qualifier_set = cache->anyPolicy->qualifier_set;
479 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 453 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
480 if (!level_add_node(curr, data, node, tree)) 454 if (!level_add_node(curr, data, node, tree)) {
481 {
482 policy_data_free(data); 455 policy_data_free(data);
483 return 0; 456 return 0;
484 } 457 }
485 458
486#endif 459#endif
487 460
488 } 461 }
489 /* Finally add link to anyPolicy */ 462 /* Finally add link to anyPolicy */
490 if (last->anyPolicy) 463 if (last->anyPolicy) {
491 {
492 if (!level_add_node(curr, cache->anyPolicy, 464 if (!level_add_node(curr, cache->anyPolicy,
493 last->anyPolicy, NULL)) 465 last->anyPolicy, NULL))
494 return 0; 466 return 0;
495 }
496 return 1;
497 } 467 }
468 return 1;
469}
498 470
499/* Prune the tree: delete any child mapped child data on the current level 471/* Prune the tree: delete any child mapped child data on the current level
500 * then proceed up the tree deleting any data with no children. If we ever 472 * then proceed up the tree deleting any data with no children. If we ever
501 * have no data on a level we can halt because the tree will be empty. 473 * have no data on a level we can halt because the tree will be empty.
502 */ 474 */
503 475
504static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) 476static int
505 { 477tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
478{
506 STACK_OF(X509_POLICY_NODE) *nodes; 479 STACK_OF(X509_POLICY_NODE) *nodes;
507 X509_POLICY_NODE *node; 480 X509_POLICY_NODE *node;
508 int i; 481 int i;
482
509 nodes = curr->nodes; 483 nodes = curr->nodes;
510 if (curr->flags & X509_V_FLAG_INHIBIT_MAP) 484 if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
511 { 485 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
512 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
513 {
514 node = sk_X509_POLICY_NODE_value(nodes, i); 486 node = sk_X509_POLICY_NODE_value(nodes, i);
515 /* Delete any mapped data: see RFC3280 XXXX */ 487 /* Delete any mapped data: see RFC3280 XXXX */
516 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) 488 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
517 {
518 node->parent->nchild--; 489 node->parent->nchild--;
519 free(node); 490 free(node);
520 (void)sk_X509_POLICY_NODE_delete(nodes,i); 491 (void)sk_X509_POLICY_NODE_delete(nodes, i);
521 }
522 } 492 }
523 } 493 }
494 }
524 495
525 for(;;) { 496 for (;;) {
526 --curr; 497 --curr;
527 nodes = curr->nodes; 498 nodes = curr->nodes;
528 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) 499 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
529 {
530 node = sk_X509_POLICY_NODE_value(nodes, i); 500 node = sk_X509_POLICY_NODE_value(nodes, i);
531 if (node->nchild == 0) 501 if (node->nchild == 0) {
532 {
533 node->parent->nchild--; 502 node->parent->nchild--;
534 free(node); 503 free(node);
535 (void)sk_X509_POLICY_NODE_delete(nodes, i); 504 (void)sk_X509_POLICY_NODE_delete(nodes, i);
536 }
537 } 505 }
538 if (curr->anyPolicy && !curr->anyPolicy->nchild) 506 }
539 { 507 if (curr->anyPolicy && !curr->anyPolicy->nchild) {
540 if (curr->anyPolicy->parent) 508 if (curr->anyPolicy->parent)
541 curr->anyPolicy->parent->nchild--; 509 curr->anyPolicy->parent->nchild--;
542 free(curr->anyPolicy); 510 free(curr->anyPolicy);
543 curr->anyPolicy = NULL; 511 curr->anyPolicy = NULL;
544 } 512 }
545 if (curr == tree->levels) 513 if (curr == tree->levels) {
546 {
547 /* If we zapped anyPolicy at top then tree is empty */ 514 /* If we zapped anyPolicy at top then tree is empty */
548 if (!curr->anyPolicy) 515 if (!curr->anyPolicy)
549 return 2; 516 return 2;
550 return 1; 517 return 1;
551 }
552 } 518 }
519 }
553 520
554 return 1; 521 return 1;
522}
555 523
556 } 524static int
557 525tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy)
558static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, 526{
559 X509_POLICY_NODE *pcy) 527 if (!*pnodes) {
560 {
561 if (!*pnodes)
562 {
563 *pnodes = policy_node_cmp_new(); 528 *pnodes = policy_node_cmp_new();
564 if (!*pnodes) 529 if (!*pnodes)
565 return 0; 530 return 0;
566 } 531 } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
567 else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
568 return 1; 532 return 1;
569 533
570 if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) 534 if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
571 return 0; 535 return 0;
572 536
573 return 1; 537 return 1;
574 538}
575 }
576 539
577/* Calculate the authority set based on policy tree. 540/* Calculate the authority set based on policy tree.
578 * The 'pnodes' parameter is used as a store for the set of policy nodes 541 * The 'pnodes' parameter is used as a store for the set of policy nodes
@@ -583,43 +546,41 @@ static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
583 * that pnodes should be freed. 546 * that pnodes should be freed.
584 */ 547 */
585 548
586static int tree_calculate_authority_set(X509_POLICY_TREE *tree, 549static int
587 STACK_OF(X509_POLICY_NODE) **pnodes) 550tree_calculate_authority_set(X509_POLICY_TREE *tree,
588 { 551 STACK_OF(X509_POLICY_NODE) **pnodes)
552{
589 X509_POLICY_LEVEL *curr; 553 X509_POLICY_LEVEL *curr;
590 X509_POLICY_NODE *node, *anyptr; 554 X509_POLICY_NODE *node, *anyptr;
591 STACK_OF(X509_POLICY_NODE) **addnodes; 555 STACK_OF(X509_POLICY_NODE) **addnodes;
592 int i, j; 556 int i, j;
557
593 curr = tree->levels + tree->nlevel - 1; 558 curr = tree->levels + tree->nlevel - 1;
594 559
595 /* If last level contains anyPolicy set is anyPolicy */ 560 /* If last level contains anyPolicy set is anyPolicy */
596 if (curr->anyPolicy) 561 if (curr->anyPolicy) {
597 {
598 if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) 562 if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
599 return 0; 563 return 0;
600 addnodes = pnodes; 564 addnodes = pnodes;
601 } 565 } else
602 else
603 /* Add policies to authority set */ 566 /* Add policies to authority set */
604 addnodes = &tree->auth_policies; 567 addnodes = &tree->auth_policies;
605 568
606 curr = tree->levels; 569 curr = tree->levels;
607 for (i = 1; i < tree->nlevel; i++) 570 for (i = 1; i < tree->nlevel; i++) {
608 {
609 /* If no anyPolicy node on this this level it can't 571 /* If no anyPolicy node on this this level it can't
610 * appear on lower levels so end search. 572 * appear on lower levels so end search.
611 */ 573 */
612 if (!(anyptr = curr->anyPolicy)) 574 if (!(anyptr = curr->anyPolicy))
613 break; 575 break;
614 curr++; 576 curr++;
615 for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) 577 for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
616 {
617 node = sk_X509_POLICY_NODE_value(curr->nodes, j); 578 node = sk_X509_POLICY_NODE_value(curr->nodes, j);
618 if ((node->parent == anyptr) 579 if ((node->parent == anyptr) &&
619 && !tree_add_auth_node(addnodes, node)) 580 !tree_add_auth_node(addnodes, node))
620 return 0; 581 return 0;
621 }
622 } 582 }
583 }
623 584
624 if (addnodes == pnodes) 585 if (addnodes == pnodes)
625 return 2; 586 return 2;
@@ -627,16 +588,15 @@ static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
627 *pnodes = tree->auth_policies; 588 *pnodes = tree->auth_policies;
628 589
629 return 1; 590 return 1;
630 } 591}
631 592
632static int tree_calculate_user_set(X509_POLICY_TREE *tree, 593static int
633 STACK_OF(ASN1_OBJECT) *policy_oids, 594tree_calculate_user_set(X509_POLICY_TREE *tree,
634 STACK_OF(X509_POLICY_NODE) *auth_nodes) 595 STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes)
635 { 596{
636 int i; 597 int i;
637 X509_POLICY_NODE *node; 598 X509_POLICY_NODE *node;
638 ASN1_OBJECT *oid; 599 ASN1_OBJECT *oid;
639
640 X509_POLICY_NODE *anyPolicy; 600 X509_POLICY_NODE *anyPolicy;
641 X509_POLICY_DATA *extra; 601 X509_POLICY_DATA *extra;
642 602
@@ -649,84 +609,78 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree,
649 609
650 anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; 610 anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
651 611
652 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 612 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
653 {
654 oid = sk_ASN1_OBJECT_value(policy_oids, i); 613 oid = sk_ASN1_OBJECT_value(policy_oids, i);
655 if (OBJ_obj2nid(oid) == NID_any_policy) 614 if (OBJ_obj2nid(oid) == NID_any_policy) {
656 {
657 tree->flags |= POLICY_FLAG_ANY_POLICY; 615 tree->flags |= POLICY_FLAG_ANY_POLICY;
658 return 1; 616 return 1;
659 }
660 } 617 }
618 }
661 619
662 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) 620 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
663 {
664 oid = sk_ASN1_OBJECT_value(policy_oids, i); 621 oid = sk_ASN1_OBJECT_value(policy_oids, i);
665 node = tree_find_sk(auth_nodes, oid); 622 node = tree_find_sk(auth_nodes, oid);
666 if (!node) 623 if (!node) {
667 {
668 if (!anyPolicy) 624 if (!anyPolicy)
669 continue; 625 continue;
670 /* Create a new node with policy ID from user set 626 /* Create a new node with policy ID from user set
671 * and qualifiers from anyPolicy. 627 * and qualifiers from anyPolicy.
672 */ 628 */
673 extra = policy_data_new(NULL, oid, 629 extra = policy_data_new(NULL, oid,
674 node_critical(anyPolicy)); 630 node_critical(anyPolicy));
675 if (!extra) 631 if (!extra)
676 return 0; 632 return 0;
677 extra->qualifier_set = anyPolicy->data->qualifier_set; 633 extra->qualifier_set = anyPolicy->data->qualifier_set;
678 extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS 634 extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS |
679 | POLICY_DATA_FLAG_EXTRA_NODE; 635 POLICY_DATA_FLAG_EXTRA_NODE;
680 node = level_add_node(NULL, extra, anyPolicy->parent, 636 node = level_add_node(NULL, extra, anyPolicy->parent,
681 tree); 637 tree);
682 } 638 }
683 if (!tree->user_policies) 639 if (!tree->user_policies) {
684 {
685 tree->user_policies = sk_X509_POLICY_NODE_new_null(); 640 tree->user_policies = sk_X509_POLICY_NODE_new_null();
686 if (!tree->user_policies) 641 if (!tree->user_policies)
687 return 1; 642 return 1;
688 } 643 }
689 if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) 644 if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
690 return 0; 645 return 0;
691 }
692 return 1;
693
694 } 646 }
647 return 1;
648}
695 649
696static int tree_evaluate(X509_POLICY_TREE *tree) 650static int
697 { 651tree_evaluate(X509_POLICY_TREE *tree)
652{
698 int ret, i; 653 int ret, i;
699 X509_POLICY_LEVEL *curr = tree->levels + 1; 654 X509_POLICY_LEVEL *curr = tree->levels + 1;
700 const X509_POLICY_CACHE *cache; 655 const X509_POLICY_CACHE *cache;
701 656
702 for(i = 1; i < tree->nlevel; i++, curr++) 657 for (i = 1; i < tree->nlevel; i++, curr++) {
703 {
704 cache = policy_cache_set(curr->cert); 658 cache = policy_cache_set(curr->cert);
705 if (!tree_link_nodes(curr, cache)) 659 if (!tree_link_nodes(curr, cache))
706 return 0; 660 return 0;
707 661
708 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) 662 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) &&
709 && !tree_link_any(curr, cache, tree)) 663 !tree_link_any(curr, cache, tree))
710 return 0; 664 return 0;
711 tree_print("before tree_prune()", tree, curr); 665 tree_print("before tree_prune()", tree, curr);
712 ret = tree_prune(tree, curr); 666 ret = tree_prune(tree, curr);
713 if (ret != 1) 667 if (ret != 1)
714 return ret; 668 return ret;
715 } 669 }
716 670
717 return 1; 671 return 1;
672}
718 673
719 } 674static void
720 675exnode_free(X509_POLICY_NODE *node)
721static void exnode_free(X509_POLICY_NODE *node) 676{
722 {
723 if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) 677 if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
724 free(node); 678 free(node);
725 } 679}
726 680
727 681void
728void X509_policy_tree_free(X509_POLICY_TREE *tree) 682X509_policy_tree_free(X509_POLICY_TREE *tree)
729 { 683{
730 X509_POLICY_LEVEL *curr; 684 X509_POLICY_LEVEL *curr;
731 int i; 685 int i;
732 686
@@ -736,25 +690,23 @@ void X509_policy_tree_free(X509_POLICY_TREE *tree)
736 sk_X509_POLICY_NODE_free(tree->auth_policies); 690 sk_X509_POLICY_NODE_free(tree->auth_policies);
737 sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); 691 sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
738 692
739 for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) 693 for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
740 {
741 if (curr->cert) 694 if (curr->cert)
742 X509_free(curr->cert); 695 X509_free(curr->cert);
743 if (curr->nodes) 696 if (curr->nodes)
744 sk_X509_POLICY_NODE_pop_free(curr->nodes, 697 sk_X509_POLICY_NODE_pop_free(curr->nodes,
745 policy_node_free); 698 policy_node_free);
746 if (curr->anyPolicy) 699 if (curr->anyPolicy)
747 policy_node_free(curr->anyPolicy); 700 policy_node_free(curr->anyPolicy);
748 } 701 }
749 702
750 if (tree->extra_data) 703 if (tree->extra_data)
751 sk_X509_POLICY_DATA_pop_free(tree->extra_data, 704 sk_X509_POLICY_DATA_pop_free(tree->extra_data,
752 policy_data_free); 705 policy_data_free);
753 706
754 free(tree->levels); 707 free(tree->levels);
755 free(tree); 708 free(tree);
756 709}
757 }
758 710
759/* Application policy checking function. 711/* Application policy checking function.
760 * Return codes: 712 * Return codes:
@@ -764,48 +716,47 @@ void X509_policy_tree_free(X509_POLICY_TREE *tree)
764 * -2 User constrained policy set empty and requireExplicit true. 716 * -2 User constrained policy set empty and requireExplicit true.
765 */ 717 */
766 718
767int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, 719int
768 STACK_OF(X509) *certs, 720X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
769 STACK_OF(ASN1_OBJECT) *policy_oids, 721 STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids,
770 unsigned int flags) 722 unsigned int flags)
771 { 723{
772 int ret; 724 int ret;
773 X509_POLICY_TREE *tree = NULL; 725 X509_POLICY_TREE *tree = NULL;
774 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; 726 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
775 *ptree = NULL;
776 727
728 *ptree = NULL;
777 *pexplicit_policy = 0; 729 *pexplicit_policy = 0;
778 ret = tree_init(&tree, certs, flags); 730 ret = tree_init(&tree, certs, flags);
779 731
780 switch (ret) 732 switch (ret) {
781 {
782 733
783 /* Tree empty requireExplicit False: OK */ 734 /* Tree empty requireExplicit False: OK */
784 case 2: 735 case 2:
785 return 1; 736 return 1;
786 737
787 /* Some internal error */ 738 /* Some internal error */
788 case -1: 739 case -1:
789 return -1; 740 return -1;
790 741
791 /* Some internal error */ 742 /* Some internal error */
792 case 0: 743 case 0:
793 return 0; 744 return 0;
794 745
795 /* Tree empty requireExplicit True: Error */ 746 /* Tree empty requireExplicit True: Error */
796 747
797 case 6: 748 case 6:
798 *pexplicit_policy = 1; 749 *pexplicit_policy = 1;
799 return -2; 750 return -2;
800 751
801 /* Tree OK requireExplicit True: OK and continue */ 752 /* Tree OK requireExplicit True: OK and continue */
802 case 5: 753 case 5:
803 *pexplicit_policy = 1; 754 *pexplicit_policy = 1;
804 break; 755 break;
805 756
806 /* Tree OK: continue */ 757 /* Tree OK: continue */
807 758
808 case 1: 759 case 1:
809 if (!tree) 760 if (!tree)
810 /* 761 /*
811 * tree_init() returns success and a null tree 762 * tree_init() returns success and a null tree
@@ -817,9 +768,10 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
817 */ 768 */
818 return 1; 769 return 1;
819 break; 770 break;
820 } 771 }
821 772
822 if (!tree) goto error; 773 if (!tree)
774 goto error;
823 ret = tree_evaluate(tree); 775 ret = tree_evaluate(tree);
824 776
825 tree_print("tree_evaluate()", tree, NULL); 777 tree_print("tree_evaluate()", tree, NULL);
@@ -828,14 +780,13 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
828 goto error; 780 goto error;
829 781
830 /* Return value 2 means tree empty */ 782 /* Return value 2 means tree empty */
831 if (ret == 2) 783 if (ret == 2) {
832 {
833 X509_policy_tree_free(tree); 784 X509_policy_tree_free(tree);
834 if (*pexplicit_policy) 785 if (*pexplicit_policy)
835 return -2; 786 return -2;
836 else 787 else
837 return 1; 788 return 1;
838 } 789 }
839 790
840 /* Tree is not empty: continue */ 791 /* Tree is not empty: continue */
841 792
@@ -846,27 +797,23 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
846 797
847 if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) 798 if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
848 goto error; 799 goto error;
849 800
850 if (ret == 2) 801 if (ret == 2)
851 sk_X509_POLICY_NODE_free(auth_nodes); 802 sk_X509_POLICY_NODE_free(auth_nodes);
852 803
853 if (tree) 804 if (tree)
854 *ptree = tree; 805 *ptree = tree;
855 806
856 if (*pexplicit_policy) 807 if (*pexplicit_policy) {
857 {
858 nodes = X509_policy_tree_get0_user_policies(tree); 808 nodes = X509_policy_tree_get0_user_policies(tree);
859 if (sk_X509_POLICY_NODE_num(nodes) <= 0) 809 if (sk_X509_POLICY_NODE_num(nodes) <= 0)
860 return -2; 810 return -2;
861 } 811 }
862 812
863 return 1; 813 return 1;
864 814
865 error: 815error:
866
867 X509_policy_tree_free(tree); 816 X509_policy_tree_free(tree);
868 817
869 return 0; 818 return 0;
870 819}
871 }
872