OLD | NEW |
1 /* pcy_tree.c */ | 1 /* pcy_tree.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 * project 2004. | 3 * project 2004. |
4 */ | 4 */ |
5 /* ==================================================================== | 5 /* ==================================================================== |
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. | 6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 * Hudson (tjh@cryptsoft.com). | 55 * Hudson (tjh@cryptsoft.com). |
56 * | 56 * |
57 */ | 57 */ |
58 | 58 |
59 #include "cryptlib.h" | 59 #include "cryptlib.h" |
60 #include <openssl/x509.h> | 60 #include <openssl/x509.h> |
61 #include <openssl/x509v3.h> | 61 #include <openssl/x509v3.h> |
62 | 62 |
63 #include "pcy_int.h" | 63 #include "pcy_int.h" |
64 | 64 |
| 65 /* Enable this to print out the complete policy tree at various point during |
| 66 * evaluation. |
| 67 */ |
| 68 |
| 69 /*#define OPENSSL_POLICY_DEBUG*/ |
| 70 |
| 71 #ifdef OPENSSL_POLICY_DEBUG |
| 72 |
| 73 static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, |
| 74 X509_POLICY_NODE *node, int indent) |
| 75 { |
| 76 if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP) |
| 77 || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) |
| 78 BIO_puts(err, " Not Mapped\n"); |
| 79 else |
| 80 { |
| 81 int i; |
| 82 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; |
| 83 ASN1_OBJECT *oid; |
| 84 BIO_puts(err, " Expected: "); |
| 85 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) |
| 86 { |
| 87 oid = sk_ASN1_OBJECT_value(pset, i); |
| 88 if (i) |
| 89 BIO_puts(err, ", "); |
| 90 i2a_ASN1_OBJECT(err, oid); |
| 91 } |
| 92 BIO_puts(err, "\n"); |
| 93 } |
| 94 } |
| 95 |
| 96 static void tree_print(char *str, X509_POLICY_TREE *tree, |
| 97 X509_POLICY_LEVEL *curr) |
| 98 { |
| 99 X509_POLICY_LEVEL *plev; |
| 100 X509_POLICY_NODE *node; |
| 101 int i; |
| 102 BIO *err; |
| 103 err = BIO_new_fp(stderr, BIO_NOCLOSE); |
| 104 if (!curr) |
| 105 curr = tree->levels + tree->nlevel; |
| 106 else |
| 107 curr++; |
| 108 BIO_printf(err, "Level print after %s\n", str); |
| 109 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); |
| 110 for (plev = tree->levels; plev != curr; plev++) |
| 111 { |
| 112 BIO_printf(err, "Level %ld, flags = %x\n", |
| 113 plev - tree->levels, plev->flags); |
| 114 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) |
| 115 { |
| 116 node = sk_X509_POLICY_NODE_value(plev->nodes, i); |
| 117 X509_POLICY_NODE_print(err, node, 2); |
| 118 expected_print(err, plev, node, 2); |
| 119 BIO_printf(err, " Flags: %x\n", node->data->flags); |
| 120 } |
| 121 if (plev->anyPolicy) |
| 122 X509_POLICY_NODE_print(err, plev->anyPolicy, 2); |
| 123 } |
| 124 |
| 125 BIO_free(err); |
| 126 |
| 127 } |
| 128 #else |
| 129 |
| 130 #define tree_print(a,b,c) /* */ |
| 131 |
| 132 #endif |
| 133 |
65 /* Initialize policy tree. Return values: | 134 /* Initialize policy tree. Return values: |
66 * 0 Some internal error occured. | 135 * 0 Some internal error occured. |
67 * -1 Inconsistent or invalid extensions in certificates. | 136 * -1 Inconsistent or invalid extensions in certificates. |
68 * 1 Tree initialized OK. | 137 * 1 Tree initialized OK. |
69 * 2 Policy tree is empty. | 138 * 2 Policy tree is empty. |
70 * 5 Tree OK and requireExplicitPolicy true. | 139 * 5 Tree OK and requireExplicitPolicy true. |
71 * 6 Tree empty and requireExplicitPolicy true. | 140 * 6 Tree empty and requireExplicitPolicy true. |
72 */ | 141 */ |
73 | 142 |
74 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, | 143 static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, |
75 unsigned int flags) | 144 unsigned int flags) |
76 { | 145 { |
77 X509_POLICY_TREE *tree; | 146 X509_POLICY_TREE *tree; |
78 X509_POLICY_LEVEL *level; | 147 X509_POLICY_LEVEL *level; |
79 const X509_POLICY_CACHE *cache; | 148 const X509_POLICY_CACHE *cache; |
80 X509_POLICY_DATA *data = NULL; | 149 X509_POLICY_DATA *data = NULL; |
81 X509 *x; | 150 X509 *x; |
82 int ret = 1; | 151 int ret = 1; |
83 int i, n; | 152 int i, n; |
84 int explicit_policy; | 153 int explicit_policy; |
85 int any_skip; | 154 int any_skip; |
86 int map_skip; | 155 int map_skip; |
87 *ptree = NULL; | 156 *ptree = NULL; |
88 n = sk_X509_num(certs); | 157 n = sk_X509_num(certs); |
89 | 158 |
| 159 #if 0 |
90 /* Disable policy mapping for now... */ | 160 /* Disable policy mapping for now... */ |
91 flags |= X509_V_FLAG_INHIBIT_MAP; | 161 flags |= X509_V_FLAG_INHIBIT_MAP; |
| 162 #endif |
92 | 163 |
93 if (flags & X509_V_FLAG_EXPLICIT_POLICY) | 164 if (flags & X509_V_FLAG_EXPLICIT_POLICY) |
94 explicit_policy = 0; | 165 explicit_policy = 0; |
95 else | 166 else |
96 explicit_policy = n + 1; | 167 explicit_policy = n + 1; |
97 | 168 |
98 if (flags & X509_V_FLAG_INHIBIT_ANY) | 169 if (flags & X509_V_FLAG_INHIBIT_ANY) |
99 any_skip = 0; | 170 any_skip = 0; |
100 else | 171 else |
101 any_skip = n + 1; | 172 any_skip = n + 1; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); | 248 data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); |
178 | 249 |
179 if (!data || !level_add_node(level, data, NULL, tree)) | 250 if (!data || !level_add_node(level, data, NULL, tree)) |
180 goto bad_tree; | 251 goto bad_tree; |
181 | 252 |
182 for (i = n - 2; i >= 0; i--) | 253 for (i = n - 2; i >= 0; i--) |
183 { | 254 { |
184 level++; | 255 level++; |
185 x = sk_X509_value(certs, i); | 256 x = sk_X509_value(certs, i); |
186 cache = policy_cache_set(x); | 257 cache = policy_cache_set(x); |
187 | |
188 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | 258 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
189 level->cert = x; | 259 level->cert = x; |
190 | 260 |
191 if (!cache->anyPolicy) | 261 if (!cache->anyPolicy) |
192 level->flags |= X509_V_FLAG_INHIBIT_ANY; | 262 level->flags |= X509_V_FLAG_INHIBIT_ANY; |
193 | 263 |
194 /* Determine inhibit any and inhibit map flags */ | 264 /* Determine inhibit any and inhibit map flags */ |
195 if (any_skip == 0) | 265 if (any_skip == 0) |
196 { | 266 { |
197 /* Any matching allowed if certificate is self | 267 /* Any matching allowed if certificate is self |
198 * issued and not the last in the chain. | 268 * issued and not the last in the chain. |
199 */ | 269 */ |
200 if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) | 270 if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) |
201 level->flags |= X509_V_FLAG_INHIBIT_ANY; | 271 level->flags |= X509_V_FLAG_INHIBIT_ANY; |
202 } | 272 } |
203 else | 273 else |
204 { | 274 { |
205 if (!(x->ex_flags & EXFLAG_SI)) | 275 if (!(x->ex_flags & EXFLAG_SI)) |
206 any_skip--; | 276 any_skip--; |
207 if ((cache->any_skip >= 0) | 277 if ((cache->any_skip >= 0) |
208 && (cache->any_skip < any_skip)) | 278 && (cache->any_skip < any_skip)) |
209 any_skip = cache->any_skip; | 279 any_skip = cache->any_skip; |
210 } | 280 } |
211 | 281 |
212 if (map_skip == 0) | 282 if (map_skip == 0) |
213 level->flags |= X509_V_FLAG_INHIBIT_MAP; | 283 level->flags |= X509_V_FLAG_INHIBIT_MAP; |
214 else | 284 else |
215 { | 285 { |
216 » » » map_skip--; | 286 » » » if (!(x->ex_flags & EXFLAG_SI)) |
| 287 » » » » map_skip--; |
217 if ((cache->map_skip >= 0) | 288 if ((cache->map_skip >= 0) |
218 && (cache->map_skip < map_skip)) | 289 && (cache->map_skip < map_skip)) |
219 map_skip = cache->map_skip; | 290 map_skip = cache->map_skip; |
220 } | 291 } |
221 | 292 |
222 | |
223 } | 293 } |
224 | 294 |
225 *ptree = tree; | 295 *ptree = tree; |
226 | 296 |
227 if (explicit_policy) | 297 if (explicit_policy) |
228 return 1; | 298 return 1; |
229 else | 299 else |
230 return 5; | 300 return 5; |
231 | 301 |
232 bad_tree: | 302 bad_tree: |
233 | 303 |
234 X509_policy_tree_free(tree); | 304 X509_policy_tree_free(tree); |
235 | 305 |
236 return 0; | 306 return 0; |
237 | 307 |
238 } | 308 } |
239 | 309 |
240 /* This corresponds to RFC3280 XXXX XXXXX: | 310 static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, |
| 311 » » » » const X509_POLICY_DATA *data) |
| 312 » { |
| 313 » X509_POLICY_LEVEL *last = curr - 1; |
| 314 » X509_POLICY_NODE *node; |
| 315 » int i, matched = 0; |
| 316 » /* Iterate through all in nodes linking matches */ |
| 317 » for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) |
| 318 » » { |
| 319 » » node = sk_X509_POLICY_NODE_value(last->nodes, i); |
| 320 » » if (policy_node_match(last, node, data->valid_policy)) |
| 321 » » » { |
| 322 » » » if (!level_add_node(curr, data, node, NULL)) |
| 323 » » » » return 0; |
| 324 » » » matched = 1; |
| 325 » » » } |
| 326 » » } |
| 327 » if (!matched && last->anyPolicy) |
| 328 » » { |
| 329 » » if (!level_add_node(curr, data, last->anyPolicy, NULL)) |
| 330 » » » return 0; |
| 331 » » } |
| 332 » return 1; |
| 333 » } |
| 334 |
| 335 /* This corresponds to RFC3280 6.1.3(d)(1): |
241 * link any data from CertificatePolicies onto matching parent | 336 * link any data from CertificatePolicies onto matching parent |
242 * or anyPolicy if no match. | 337 * or anyPolicy if no match. |
243 */ | 338 */ |
244 | 339 |
245 static int tree_link_nodes(X509_POLICY_LEVEL *curr, | 340 static int tree_link_nodes(X509_POLICY_LEVEL *curr, |
246 const X509_POLICY_CACHE *cache) | 341 const X509_POLICY_CACHE *cache) |
247 { | 342 { |
248 int i; | 343 int i; |
249 X509_POLICY_LEVEL *last; | |
250 X509_POLICY_DATA *data; | 344 X509_POLICY_DATA *data; |
251 » X509_POLICY_NODE *parent; | 345 |
252 » last = curr - 1; | |
253 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) | 346 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) |
254 { | 347 { |
255 data = sk_X509_POLICY_DATA_value(cache->data, i); | 348 data = sk_X509_POLICY_DATA_value(cache->data, i); |
256 /* If a node is mapped any it doesn't have a corresponding | 349 /* If a node is mapped any it doesn't have a corresponding |
257 * CertificatePolicies entry. | 350 * CertificatePolicies entry. |
258 * However such an identical node would be created | 351 * However such an identical node would be created |
259 * if anyPolicy matching is enabled because there would be | 352 * if anyPolicy matching is enabled because there would be |
260 * no match with the parent valid_policy_set. So we create | 353 * no match with the parent valid_policy_set. So we create |
261 * link because then it will have the mapping flags | 354 * link because then it will have the mapping flags |
262 * right and we can prune it later. | 355 * right and we can prune it later. |
263 */ | 356 */ |
| 357 #if 0 |
264 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) | 358 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) |
265 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) | 359 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) |
266 continue; | 360 continue; |
267 » » /* Look for matching node in parent */ | 361 #endif |
268 » » parent = level_find_node(last, data->valid_policy); | 362 » » /* Look for matching nodes in previous level */ |
269 » » /* If no match link to anyPolicy */ | 363 » » if (!tree_link_matching_nodes(curr, data)) |
270 » » if (!parent) | |
271 » » » parent = last->anyPolicy; | |
272 » » if (parent && !level_add_node(curr, data, parent, NULL)) | |
273 return 0; | 364 return 0; |
274 } | 365 } |
275 return 1; | 366 return 1; |
276 } | 367 } |
277 | 368 |
278 /* This corresponds to RFC3280 XXXX XXXXX: | 369 /* This corresponds to RFC3280 6.1.3(d)(2): |
279 * Create new data for any unmatched policies in the parent and link | 370 * Create new data for any unmatched policies in the parent and link |
280 * to anyPolicy. | 371 * to anyPolicy. |
281 */ | 372 */ |
282 | 373 |
| 374 static int tree_add_unmatched(X509_POLICY_LEVEL *curr, |
| 375 const X509_POLICY_CACHE *cache, |
| 376 const ASN1_OBJECT *id, |
| 377 X509_POLICY_NODE *node, |
| 378 X509_POLICY_TREE *tree) |
| 379 { |
| 380 X509_POLICY_DATA *data; |
| 381 if (id == NULL) |
| 382 id = node->data->valid_policy; |
| 383 /* Create a new node with qualifiers from anyPolicy and |
| 384 * id from unmatched node. |
| 385 */ |
| 386 data = policy_data_new(NULL, id, node_critical(node)); |
| 387 |
| 388 if (data == NULL) |
| 389 return 0; |
| 390 /* Curr may not have anyPolicy */ |
| 391 data->qualifier_set = cache->anyPolicy->qualifier_set; |
| 392 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; |
| 393 if (!level_add_node(curr, data, node, tree)) |
| 394 { |
| 395 policy_data_free(data); |
| 396 return 0; |
| 397 } |
| 398 |
| 399 return 1; |
| 400 } |
| 401 |
| 402 static int tree_link_unmatched(X509_POLICY_LEVEL *curr, |
| 403 const X509_POLICY_CACHE *cache, |
| 404 X509_POLICY_NODE *node, |
| 405 X509_POLICY_TREE *tree) |
| 406 { |
| 407 const X509_POLICY_LEVEL *last = curr - 1; |
| 408 int i; |
| 409 |
| 410 if ( (last->flags & X509_V_FLAG_INHIBIT_MAP) |
| 411 || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) |
| 412 { |
| 413 /* If no policy mapping: matched if one child present */ |
| 414 if (node->nchild) |
| 415 return 1; |
| 416 if (!tree_add_unmatched(curr, cache, NULL, node, tree)) |
| 417 return 0; |
| 418 /* Add it */ |
| 419 } |
| 420 else |
| 421 { |
| 422 /* If mapping: matched if one child per expected policy set */ |
| 423 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; |
| 424 if (node->nchild == sk_ASN1_OBJECT_num(expset)) |
| 425 return 1; |
| 426 /* Locate unmatched nodes */ |
| 427 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) |
| 428 { |
| 429 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); |
| 430 if (level_find_node(curr, node, oid)) |
| 431 continue; |
| 432 if (!tree_add_unmatched(curr, cache, oid, node, tree)) |
| 433 return 0; |
| 434 } |
| 435 |
| 436 } |
| 437 |
| 438 return 1; |
| 439 |
| 440 } |
| 441 |
283 static int tree_link_any(X509_POLICY_LEVEL *curr, | 442 static int tree_link_any(X509_POLICY_LEVEL *curr, |
284 const X509_POLICY_CACHE *cache, | 443 const X509_POLICY_CACHE *cache, |
285 X509_POLICY_TREE *tree) | 444 X509_POLICY_TREE *tree) |
286 { | 445 { |
287 int i; | 446 int i; |
288 » X509_POLICY_DATA *data; | 447 » /*X509_POLICY_DATA *data;*/ |
289 X509_POLICY_NODE *node; | 448 X509_POLICY_NODE *node; |
290 » X509_POLICY_LEVEL *last; | 449 » X509_POLICY_LEVEL *last = curr - 1; |
291 | |
292 » last = curr - 1; | |
293 | 450 |
294 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) | 451 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) |
295 { | 452 { |
296 node = sk_X509_POLICY_NODE_value(last->nodes, i); | 453 node = sk_X509_POLICY_NODE_value(last->nodes, i); |
297 | 454 |
| 455 if (!tree_link_unmatched(curr, cache, node, tree)) |
| 456 return 0; |
| 457 |
| 458 #if 0 |
| 459 |
298 /* Skip any node with any children: we only want unmathced | 460 /* Skip any node with any children: we only want unmathced |
299 * nodes. | 461 * nodes. |
300 * | 462 * |
301 * Note: need something better for policy mapping | 463 * Note: need something better for policy mapping |
302 * because each node may have multiple children | 464 * because each node may have multiple children |
303 */ | 465 */ |
304 if (node->nchild) | 466 if (node->nchild) |
305 continue; | 467 continue; |
| 468 |
306 /* Create a new node with qualifiers from anyPolicy and | 469 /* Create a new node with qualifiers from anyPolicy and |
307 * id from unmatched node. | 470 * id from unmatched node. |
308 */ | 471 */ |
309 data = policy_data_new(NULL, node->data->valid_policy, | 472 data = policy_data_new(NULL, node->data->valid_policy, |
310 node_critical(node)); | 473 node_critical(node)); |
311 | 474 |
312 if (data == NULL) | 475 if (data == NULL) |
313 return 0; | 476 return 0; |
314 /* Curr may not have anyPolicy */ | 477 /* Curr may not have anyPolicy */ |
315 data->qualifier_set = cache->anyPolicy->qualifier_set; | 478 data->qualifier_set = cache->anyPolicy->qualifier_set; |
316 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; | 479 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; |
317 if (!level_add_node(curr, data, node, tree)) | 480 if (!level_add_node(curr, data, node, tree)) |
318 { | 481 { |
319 policy_data_free(data); | 482 policy_data_free(data); |
320 return 0; | 483 return 0; |
321 } | 484 } |
| 485 |
| 486 #endif |
| 487 |
322 } | 488 } |
323 /* Finally add link to anyPolicy */ | 489 /* Finally add link to anyPolicy */ |
324 if (last->anyPolicy) | 490 if (last->anyPolicy) |
325 { | 491 { |
326 if (!level_add_node(curr, cache->anyPolicy, | 492 if (!level_add_node(curr, cache->anyPolicy, |
327 last->anyPolicy, NULL)) | 493 last->anyPolicy, NULL)) |
328 return 0; | 494 return 0; |
329 } | 495 } |
330 return 1; | 496 return 1; |
331 } | 497 } |
332 | 498 |
333 /* Prune the tree: delete any child mapped child data on the current level | 499 /* Prune the tree: delete any child mapped child data on the current level |
334 * then proceed up the tree deleting any data with no children. If we ever | 500 * then proceed up the tree deleting any data with no children. If we ever |
335 * have no data on a level we can halt because the tree will be empty. | 501 * have no data on a level we can halt because the tree will be empty. |
336 */ | 502 */ |
337 | 503 |
338 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) | 504 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) |
339 { | 505 { |
| 506 STACK_OF(X509_POLICY_NODE) *nodes; |
340 X509_POLICY_NODE *node; | 507 X509_POLICY_NODE *node; |
341 int i; | 508 int i; |
342 » for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) | 509 » nodes = curr->nodes; |
| 510 » if (curr->flags & X509_V_FLAG_INHIBIT_MAP) |
343 { | 511 { |
344 » » node = sk_X509_POLICY_NODE_value(curr->nodes, i); | 512 » » for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) |
345 » » /* Delete any mapped data: see RFC3280 XXXX */ | |
346 » » if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) | |
347 { | 513 { |
348 » » » node->parent->nchild--; | 514 » » » node = sk_X509_POLICY_NODE_value(nodes, i); |
349 » » » OPENSSL_free(node); | 515 » » » /* Delete any mapped data: see RFC3280 XXXX */ |
350 » » » (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); | 516 » » » if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) |
| 517 » » » » { |
| 518 » » » » node->parent->nchild--; |
| 519 » » » » OPENSSL_free(node); |
| 520 » » » » (void)sk_X509_POLICY_NODE_delete(nodes,i); |
| 521 » » » » } |
351 } | 522 } |
352 } | 523 } |
353 | 524 |
354 for(;;) { | 525 for(;;) { |
355 --curr; | 526 --curr; |
356 » » for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) | 527 » » nodes = curr->nodes; |
| 528 » » for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) |
357 { | 529 { |
358 » » » node = sk_X509_POLICY_NODE_value(curr->nodes, i); | 530 » » » node = sk_X509_POLICY_NODE_value(nodes, i); |
359 if (node->nchild == 0) | 531 if (node->nchild == 0) |
360 { | 532 { |
361 node->parent->nchild--; | 533 node->parent->nchild--; |
362 OPENSSL_free(node); | 534 OPENSSL_free(node); |
363 » » » » (void)sk_X509_POLICY_NODE_delete(curr->nodes, i)
; | 535 » » » » (void)sk_X509_POLICY_NODE_delete(nodes, i); |
364 } | 536 } |
365 } | 537 } |
366 if (curr->anyPolicy && !curr->anyPolicy->nchild) | 538 if (curr->anyPolicy && !curr->anyPolicy->nchild) |
367 { | 539 { |
368 if (curr->anyPolicy->parent) | 540 if (curr->anyPolicy->parent) |
369 curr->anyPolicy->parent->nchild--; | 541 curr->anyPolicy->parent->nchild--; |
370 OPENSSL_free(curr->anyPolicy); | 542 OPENSSL_free(curr->anyPolicy); |
371 curr->anyPolicy = NULL; | 543 curr->anyPolicy = NULL; |
372 } | 544 } |
373 if (curr == tree->levels) | 545 if (curr == tree->levels) |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 | 701 |
530 for(i = 1; i < tree->nlevel; i++, curr++) | 702 for(i = 1; i < tree->nlevel; i++, curr++) |
531 { | 703 { |
532 cache = policy_cache_set(curr->cert); | 704 cache = policy_cache_set(curr->cert); |
533 if (!tree_link_nodes(curr, cache)) | 705 if (!tree_link_nodes(curr, cache)) |
534 return 0; | 706 return 0; |
535 | 707 |
536 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) | 708 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) |
537 && !tree_link_any(curr, cache, tree)) | 709 && !tree_link_any(curr, cache, tree)) |
538 return 0; | 710 return 0; |
| 711 tree_print("before tree_prune()", tree, curr); |
539 ret = tree_prune(tree, curr); | 712 ret = tree_prune(tree, curr); |
540 if (ret != 1) | 713 if (ret != 1) |
541 return ret; | 714 return ret; |
542 } | 715 } |
543 | 716 |
544 return 1; | 717 return 1; |
545 | 718 |
546 } | 719 } |
547 | 720 |
548 static void exnode_free(X509_POLICY_NODE *node) | 721 static void exnode_free(X509_POLICY_NODE *node) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 unsigned int flags) | 770 unsigned int flags) |
598 { | 771 { |
599 int ret; | 772 int ret; |
600 X509_POLICY_TREE *tree = NULL; | 773 X509_POLICY_TREE *tree = NULL; |
601 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; | 774 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; |
602 *ptree = NULL; | 775 *ptree = NULL; |
603 | 776 |
604 *pexplicit_policy = 0; | 777 *pexplicit_policy = 0; |
605 ret = tree_init(&tree, certs, flags); | 778 ret = tree_init(&tree, certs, flags); |
606 | 779 |
607 | |
608 switch (ret) | 780 switch (ret) |
609 { | 781 { |
610 | 782 |
611 /* Tree empty requireExplicit False: OK */ | 783 /* Tree empty requireExplicit False: OK */ |
612 case 2: | 784 case 2: |
613 return 1; | 785 return 1; |
614 | 786 |
615 /* Some internal error */ | 787 /* Some internal error */ |
| 788 case -1: |
| 789 return -1; |
| 790 |
| 791 /* Some internal error */ |
616 case 0: | 792 case 0: |
617 return 0; | 793 return 0; |
618 | 794 |
619 /* Tree empty requireExplicit True: Error */ | 795 /* Tree empty requireExplicit True: Error */ |
620 | 796 |
621 case 6: | 797 case 6: |
622 *pexplicit_policy = 1; | 798 *pexplicit_policy = 1; |
623 return -2; | 799 return -2; |
624 | 800 |
625 /* Tree OK requireExplicit True: OK and continue */ | 801 /* Tree OK requireExplicit True: OK and continue */ |
(...skipping 13 matching lines...) Expand all Loading... |
639 * as an internal error which our caller | 815 * as an internal error which our caller |
640 * interprets as a malloc failure is wrong. | 816 * interprets as a malloc failure is wrong. |
641 */ | 817 */ |
642 return 1; | 818 return 1; |
643 break; | 819 break; |
644 } | 820 } |
645 | 821 |
646 if (!tree) goto error; | 822 if (!tree) goto error; |
647 ret = tree_evaluate(tree); | 823 ret = tree_evaluate(tree); |
648 | 824 |
| 825 tree_print("tree_evaluate()", tree, NULL); |
| 826 |
649 if (ret <= 0) | 827 if (ret <= 0) |
650 goto error; | 828 goto error; |
651 | 829 |
652 /* Return value 2 means tree empty */ | 830 /* Return value 2 means tree empty */ |
653 if (ret == 2) | 831 if (ret == 2) |
654 { | 832 { |
655 X509_policy_tree_free(tree); | 833 X509_policy_tree_free(tree); |
656 if (*pexplicit_policy) | 834 if (*pexplicit_policy) |
657 return -2; | 835 return -2; |
658 else | 836 else |
(...skipping 26 matching lines...) Expand all Loading... |
685 return 1; | 863 return 1; |
686 | 864 |
687 error: | 865 error: |
688 | 866 |
689 X509_policy_tree_free(tree); | 867 X509_policy_tree_free(tree); |
690 | 868 |
691 return 0; | 869 return 0; |
692 | 870 |
693 } | 871 } |
694 | 872 |
OLD | NEW |