summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-04-26 21:07:32 +0000
committertb <>2023-04-26 21:07:32 +0000
commitb79485b52cb70e59a1009a4160ff34017797ef40 (patch)
treedf0b6fbe00685fbb214e40e97c128f449afa11e3 /src
parent102ccf204a2664e54c596fdc47602e28b493842c (diff)
downloadopenbsd-b79485b52cb70e59a1009a4160ff34017797ef40.tar.gz
openbsd-b79485b52cb70e59a1009a4160ff34017797ef40.tar.bz2
openbsd-b79485b52cb70e59a1009a4160ff34017797ef40.zip
KNF according to knfmt(1)
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/x509/x509_policy.c1115
1 files changed, 600 insertions, 515 deletions
diff --git a/src/lib/libcrypto/x509/x509_policy.c b/src/lib/libcrypto/x509/x509_policy.c
index 8d182ef45a..6005acd4fb 100644
--- a/src/lib/libcrypto/x509/x509_policy.c
+++ b/src/lib/libcrypto/x509/x509_policy.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_policy.c,v 1.9 2023/04/26 20:52:11 tb Exp $ */ 1/* $OpenBSD: x509_policy.c,v 1.10 2023/04/26 21:07:32 tb Exp $ */
2/* Copyright (c) 2022, Google Inc. 2/* Copyright (c) 2022, Google Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
@@ -55,7 +55,7 @@
55// from RFC 5280, section 6.1.2, step (a), but we store some fields differently. 55// from RFC 5280, section 6.1.2, step (a), but we store some fields differently.
56typedef struct x509_policy_node_st { 56typedef struct x509_policy_node_st {
57 // policy is the "valid_policy" field from RFC 5280. 57 // policy is the "valid_policy" field from RFC 5280.
58 ASN1_OBJECT *policy; 58 ASN1_OBJECT *policy;
59 59
60 // parent_policies, if non-empty, is the list of "valid_policy" values for all 60 // parent_policies, if non-empty, is the list of "valid_policy" values for all
61 // nodes which are a parent of this node. In this case, no entry in this list 61 // nodes which are a parent of this node. In this case, no entry in this list
@@ -70,15 +70,15 @@ typedef struct x509_policy_node_st {
70 // concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs if 70 // concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs if
71 // there was no match in step (d.1.i). We do not need to represent a parent 71 // there was no match in step (d.1.i). We do not need to represent a parent
72 // list of, say, {anyPolicy, OID1, OID2}. 72 // list of, say, {anyPolicy, OID1, OID2}.
73 STACK_OF(ASN1_OBJECT) *parent_policies; 73 STACK_OF(ASN1_OBJECT) *parent_policies;
74 74
75 // mapped is one if this node matches a policy mapping in the certificate and 75 // mapped is one if this node matches a policy mapping in the certificate and
76 // zero otherwise. 76 // zero otherwise.
77 int mapped; 77 int mapped;
78 78
79 // reachable is one if this node is reachable from some valid policy in the 79 // reachable is one if this node is reachable from some valid policy in the
80 // end-entity certificate. It is computed during |has_explicit_policy|. 80 // end-entity certificate. It is computed during |has_explicit_policy|.
81 int reachable; 81 int reachable;
82} X509_POLICY_NODE; 82} X509_POLICY_NODE;
83 83
84DECLARE_STACK_OF(X509_POLICY_NODE) 84DECLARE_STACK_OF(X509_POLICY_NODE)
@@ -111,11 +111,11 @@ DECLARE_STACK_OF(X509_POLICY_NODE)
111typedef struct x509_policy_level_st { 111typedef struct x509_policy_level_st {
112 // nodes is the list of nodes at this depth, except for the anyPolicy node, if 112 // nodes is the list of nodes at this depth, except for the anyPolicy node, if
113 // any. This list is sorted by policy OID for efficient lookup. 113 // any. This list is sorted by policy OID for efficient lookup.
114 STACK_OF(X509_POLICY_NODE) *nodes; 114 STACK_OF(X509_POLICY_NODE) *nodes;
115 115
116 // has_any_policy is one if there is an anyPolicy node at this depth, and zero 116 // has_any_policy is one if there is an anyPolicy node at this depth, and zero
117 // otherwise. 117 // otherwise.
118 int has_any_policy; 118 int has_any_policy;
119} X509_POLICY_LEVEL; 119} X509_POLICY_LEVEL;
120 120
121DECLARE_STACK_OF(X509_POLICY_LEVEL) 121DECLARE_STACK_OF(X509_POLICY_LEVEL)
@@ -165,84 +165,106 @@ sk_X509_POLICY_NODE_delete_if(STACK_OF(X509_POLICY_NODE) *nodes,
165 sk->num = new_num; 165 sk->num = new_num;
166} 166}
167 167
168static int is_any_policy(const ASN1_OBJECT *obj) { 168static int
169 return OBJ_obj2nid(obj) == NID_any_policy; 169is_any_policy(const ASN1_OBJECT *obj)
170{
171 return OBJ_obj2nid(obj) == NID_any_policy;
170} 172}
171 173
172static void x509_policy_node_free(X509_POLICY_NODE *node) { 174static void
173 if (node != NULL) { 175x509_policy_node_free(X509_POLICY_NODE *node)
174 ASN1_OBJECT_free(node->policy); 176{
175 sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free); 177 if (node != NULL) {
176 free(node); 178 ASN1_OBJECT_free(node->policy);
177 } 179 sk_ASN1_OBJECT_pop_free(node->parent_policies,
180 ASN1_OBJECT_free);
181 free(node);
182 }
178} 183}
179 184
180static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) { 185static X509_POLICY_NODE *
181 assert(!is_any_policy(policy)); 186x509_policy_node_new(const ASN1_OBJECT *policy)
182 X509_POLICY_NODE *node = malloc(sizeof(X509_POLICY_NODE)); 187{
183 if (node == NULL) { 188 assert(!is_any_policy(policy));
184 return NULL; 189 X509_POLICY_NODE *node = malloc(sizeof(X509_POLICY_NODE));
185 } 190 if (node == NULL) {
186 memset(node, 0, sizeof(X509_POLICY_NODE)); 191 return NULL;
187 node->policy = OBJ_dup(policy); 192 }
188 node->parent_policies = sk_ASN1_OBJECT_new_null(); 193 memset(node, 0, sizeof(X509_POLICY_NODE));
189 if (node->policy == NULL || node->parent_policies == NULL) { 194 node->policy = OBJ_dup(policy);
190 x509_policy_node_free(node); 195 node->parent_policies = sk_ASN1_OBJECT_new_null();
191 return NULL; 196 if (node->policy == NULL || node->parent_policies == NULL) {
192 } 197 x509_policy_node_free(node);
193 return node; 198 return NULL;
199 }
200 return node;
194} 201}
195 202
196static int x509_policy_node_cmp(const X509_POLICY_NODE *const *a, 203static int
197 const X509_POLICY_NODE *const *b) { 204x509_policy_node_cmp(const X509_POLICY_NODE *const *a,
198 return OBJ_cmp((*a)->policy, (*b)->policy); 205 const X509_POLICY_NODE *const *b)
206{
207 return OBJ_cmp((*a)->policy, (*b)->policy);
199} 208}
200 209
201static void x509_policy_level_free(X509_POLICY_LEVEL *level) { 210static void
202 if (level != NULL) { 211x509_policy_level_free(X509_POLICY_LEVEL *level)
203 sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free); 212{
204 free(level); 213 if (level != NULL) {
205 } 214 sk_X509_POLICY_NODE_pop_free(level->nodes,
215 x509_policy_node_free);
216 free(level);
217 }
206} 218}
207 219
208static X509_POLICY_LEVEL *x509_policy_level_new(void) { 220static X509_POLICY_LEVEL *
209 X509_POLICY_LEVEL *level = malloc(sizeof(X509_POLICY_LEVEL)); 221x509_policy_level_new(void)
210 if (level == NULL) { 222{
211 return NULL; 223 X509_POLICY_LEVEL *level = malloc(sizeof(X509_POLICY_LEVEL));
212 } 224 if (level == NULL) {
213 memset(level, 0, sizeof(X509_POLICY_LEVEL)); 225 return NULL;
214 level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); 226 }
215 if (level->nodes == NULL) { 227 memset(level, 0, sizeof(X509_POLICY_LEVEL));
216 x509_policy_level_free(level); 228 level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp);
217 return NULL; 229 if (level->nodes == NULL) {
218 } 230 x509_policy_level_free(level);
219 return level; 231 return NULL;
232 }
233 return level;
220} 234}
221 235
222static int x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) { 236static int
223 return !level->has_any_policy && sk_X509_POLICY_NODE_num(level->nodes) == 0; 237x509_policy_level_is_empty(const X509_POLICY_LEVEL *level)
238{
239 return !level->has_any_policy &&
240 sk_X509_POLICY_NODE_num(level->nodes) == 0;
224} 241}
225 242
226static void x509_policy_level_clear(X509_POLICY_LEVEL *level) { 243static void
227 level->has_any_policy = 0; 244x509_policy_level_clear(X509_POLICY_LEVEL *level)
228 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { 245{
229 x509_policy_node_free(sk_X509_POLICY_NODE_value(level->nodes, i)); 246 level->has_any_policy = 0;
230 } 247 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
231 sk_X509_POLICY_NODE_zero(level->nodes); 248 x509_policy_node_free(
249 sk_X509_POLICY_NODE_value(level->nodes, i));
250 }
251 sk_X509_POLICY_NODE_zero(level->nodes);
232} 252}
233 253
234// x509_policy_level_find returns the node in |level| corresponding to |policy|, 254// x509_policy_level_find returns the node in |level| corresponding to |policy|,
235// or NULL if none exists. 255// or NULL if none exists.
236static X509_POLICY_NODE *x509_policy_level_find(X509_POLICY_LEVEL *level, 256static X509_POLICY_NODE *
237 const ASN1_OBJECT *policy) { 257x509_policy_level_find(X509_POLICY_LEVEL *level,
238 assert(sk_X509_POLICY_NODE_is_sorted(level->nodes)); 258 const ASN1_OBJECT *policy)
239 X509_POLICY_NODE node; 259{
240 node.policy = (ASN1_OBJECT *)policy; 260 assert(sk_X509_POLICY_NODE_is_sorted(level->nodes));
241 int idx; 261 X509_POLICY_NODE node;
242 if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) { 262 node.policy = (ASN1_OBJECT *)policy;
243 return NULL; 263 int idx;
244 } 264 if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0) {
245 return sk_X509_POLICY_NODE_value(level->nodes, idx); 265 return NULL;
266 }
267 return sk_X509_POLICY_NODE_value(level->nodes, idx);
246} 268}
247 269
248// x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns 270// x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns
@@ -252,42 +274,50 @@ static X509_POLICY_NODE *x509_policy_level_find(X509_POLICY_LEVEL *level,
252// 274//
253// This function is used to add nodes to |level| in bulk, and avoid resorting 275// This function is used to add nodes to |level| in bulk, and avoid resorting
254// |level| after each addition. 276// |level| after each addition.
255static int x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, 277static int
256 STACK_OF(X509_POLICY_NODE) *nodes) { 278x509_policy_level_add_nodes(X509_POLICY_LEVEL *level,
257 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { 279 STACK_OF(X509_POLICY_NODE) *nodes)
258 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); 280{
259 if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { 281 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
260 return 0; 282 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i);
261 } 283 if (!sk_X509_POLICY_NODE_push(level->nodes, node)) {
262 sk_X509_POLICY_NODE_set(nodes, i, NULL); 284 return 0;
263 } 285 }
264 sk_X509_POLICY_NODE_sort(level->nodes); 286 sk_X509_POLICY_NODE_set(nodes, i, NULL);
287 }
288 sk_X509_POLICY_NODE_sort(level->nodes);
265 289
266#if !defined(NDEBUG) 290#if !defined(NDEBUG)
267 // There should be no duplicate nodes. 291 // There should be no duplicate nodes.
268 for (size_t i = 1; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { 292 for (size_t i = 1; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
269 assert(OBJ_cmp(sk_X509_POLICY_NODE_value(level->nodes, i - 1)->policy, 293 assert(
270 sk_X509_POLICY_NODE_value(level->nodes, i)->policy) != 0); 294 OBJ_cmp(
271 } 295 sk_X509_POLICY_NODE_value(level->nodes, i - 1)->policy,
296 sk_X509_POLICY_NODE_value(level->nodes, i)->policy) != 0);
297 }
272#endif 298#endif
273 return 1; 299 return 1;
274} 300}
275 301
276static int policyinfo_cmp(const POLICYINFO *const *a, 302static int
277 const POLICYINFO *const *b) { 303policyinfo_cmp(const POLICYINFO *const *a,
278 return OBJ_cmp((*a)->policyid, (*b)->policyid); 304 const POLICYINFO *const *b)
305{
306 return OBJ_cmp((*a)->policyid, (*b)->policyid);
279} 307}
280 308
281static int delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) { 309static int
282 const CERTIFICATEPOLICIES *policies = data; 310delete_if_not_in_policies(X509_POLICY_NODE *node, void *data)
283 assert(sk_POLICYINFO_is_sorted(policies)); 311{
284 POLICYINFO info; 312 const CERTIFICATEPOLICIES *policies = data;
285 info.policyid = node->policy; 313 assert(sk_POLICYINFO_is_sorted(policies));
286 if (sk_POLICYINFO_find(policies, &info) >= 0) { 314 POLICYINFO info;
287 return 0; 315 info.policyid = node->policy;
288 } 316 if (sk_POLICYINFO_find(policies, &info) >= 0) {
289 x509_policy_node_free(node); 317 return 0;
290 return 1; 318 }
319 x509_policy_node_free(node);
320 return 1;
291} 321}
292 322
293// process_certificate_policies updates |level| to incorporate |x509|'s 323// process_certificate_policies updates |level| to incorporate |x509|'s
@@ -297,115 +327,128 @@ static int delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) {
297// the output of |process_policy_mappings|. |any_policy_allowed| specifies 327// the output of |process_policy_mappings|. |any_policy_allowed| specifies
298// whether anyPolicy is allowed or inhibited, taking into account the exception 328// whether anyPolicy is allowed or inhibited, taking into account the exception
299// for self-issued certificates. 329// for self-issued certificates.
300static int process_certificate_policies(const X509 *x509, 330static int
301 X509_POLICY_LEVEL *level, 331process_certificate_policies(const X509 *x509,
302 int any_policy_allowed) { 332 X509_POLICY_LEVEL *level,
303 int ret = 0; 333 int any_policy_allowed)
304 int critical; 334{
305 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; 335 int ret = 0;
306 CERTIFICATEPOLICIES *policies = 336 int critical;
307 X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL); 337 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
308 if (policies == NULL) { 338 CERTIFICATEPOLICIES *policies =
309 if (critical != -1) { 339 X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL);
310 return 0; // Syntax error in the extension. 340 if (policies == NULL) {
311 } 341 if (critical != -1) {
342 return 0; // Syntax error in the extension.
343 }
312 344
313 // RFC 5280, section 6.1.3, step (e). 345 // RFC 5280, section 6.1.3, step (e).
314 x509_policy_level_clear(level); 346 x509_policy_level_clear(level);
315 return 1; 347 return 1;
316 } 348 }
317 349
318 // certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4. 350 // certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4.
319 // TODO(https://crbug.com/boringssl/443): Move this check into the parser. 351 // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
320 if (sk_POLICYINFO_num(policies) == 0) { 352 if (sk_POLICYINFO_num(policies) == 0) {
321 X509error(X509_R_INVALID_POLICY_EXTENSION); 353 X509error(X509_R_INVALID_POLICY_EXTENSION);
322 goto err; 354 goto err;
323 } 355 }
324 356
325 sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp); 357 sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp);
326 sk_POLICYINFO_sort(policies); 358 sk_POLICYINFO_sort(policies);
327 int cert_has_any_policy = 0; 359 int cert_has_any_policy = 0;
328 for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { 360 for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) {
329 const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); 361 const POLICYINFO *policy = sk_POLICYINFO_value(policies, i);
330 if (is_any_policy(policy->policyid)) { 362 if (is_any_policy(policy->policyid)) {
331 cert_has_any_policy = 1; 363 cert_has_any_policy = 1;
332 } 364 }
333 if (i > 0 && OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, 365 if (i > 0 &&
334 policy->policyid) == 0) { 366 OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid,
367 policy->policyid) == 0) {
335 // Per RFC 5280, section 4.2.1.4, |policies| may not have duplicates. 368 // Per RFC 5280, section 4.2.1.4, |policies| may not have duplicates.
336 X509error(X509_R_INVALID_POLICY_EXTENSION); 369 X509error(X509_R_INVALID_POLICY_EXTENSION);
337 goto err; 370 goto err;
338 } 371 }
339 } 372 }
340 373
341 // This does the same thing as RFC 5280, section 6.1.3, step (d), though in 374 // This does the same thing as RFC 5280, section 6.1.3, step (d), though in
342 // a slighty different order. |level| currently contains "expected_policy_set" 375 // a slighty different order. |level| currently contains "expected_policy_set"
343 // values of the previous level. See |process_policy_mappings| for details. 376 // values of the previous level. See |process_policy_mappings| for details.
344 const int previous_level_has_any_policy = level->has_any_policy; 377 const int previous_level_has_any_policy = level->has_any_policy;
345 378
346 // First, we handle steps (d.1.i) and (d.2). The net effect of these two steps 379 // First, we handle steps (d.1.i) and (d.2). The net effect of these two steps
347 // is to intersect |level| with |policies|, ignoring anyPolicy if it is 380 // is to intersect |level| with |policies|, ignoring anyPolicy if it is
348 // inhibited. 381 // inhibited.
349 if (!cert_has_any_policy || !any_policy_allowed) { 382 if (!cert_has_any_policy || !any_policy_allowed) {
350 sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_not_in_policies, 383 sk_X509_POLICY_NODE_delete_if(level->nodes,
351 policies); 384 delete_if_not_in_policies, policies);
352 level->has_any_policy = 0; 385 level->has_any_policy = 0;
353 } 386 }
354 387
355 // Step (d.1.ii) may attach new nodes to the previous level's anyPolicy node. 388 // Step (d.1.ii) may attach new nodes to the previous level's anyPolicy node.
356 if (previous_level_has_any_policy) { 389 if (previous_level_has_any_policy) {
357 new_nodes = sk_X509_POLICY_NODE_new_null(); 390 new_nodes = sk_X509_POLICY_NODE_new_null();
358 if (new_nodes == NULL) { 391 if (new_nodes == NULL) {
359 goto err; 392 goto err;
360 } 393 }
361 for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { 394 for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) {
362 const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); 395 const POLICYINFO *policy = sk_POLICYINFO_value(policies,
396 i);
363 // Though we've reordered the steps slightly, |policy| is in |level| if 397 // Though we've reordered the steps slightly, |policy| is in |level| if
364 // and only if it would have been a match in step (d.1.ii). 398 // and only if it would have been a match in step (d.1.ii).
365 if (!is_any_policy(policy->policyid) && 399 if (!is_any_policy(policy->policyid) &&
366 x509_policy_level_find(level, policy->policyid) == NULL) { 400 x509_policy_level_find(level, policy->policyid) ==
367 X509_POLICY_NODE *node = x509_policy_node_new(policy->policyid); 401 NULL) {
368 if (node == NULL || // 402 X509_POLICY_NODE *node = x509_policy_node_new(
369 !sk_X509_POLICY_NODE_push(new_nodes, node)) { 403 policy->policyid);
370 x509_policy_node_free(node); 404 if (node == NULL || //
371 goto err; 405 !sk_X509_POLICY_NODE_push(new_nodes,
372 } 406 node)) {
373 } 407 x509_policy_node_free(node);
374 } 408 goto err;
375 if (!x509_policy_level_add_nodes(level, new_nodes)) { 409 }
376 goto err; 410 }
377 } 411 }
378 } 412 if (!x509_policy_level_add_nodes(level, new_nodes)) {
379 413 goto err;
380 ret = 1; 414 }
415 }
416
417 ret = 1;
381 418
382err: 419err:
383 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); 420 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
384 CERTIFICATEPOLICIES_free(policies); 421 CERTIFICATEPOLICIES_free(policies);
385 return ret; 422 return ret;
386} 423}
387 424
388static int compare_issuer_policy(const POLICY_MAPPING *const *a, 425static int
389 const POLICY_MAPPING *const *b) { 426compare_issuer_policy(const POLICY_MAPPING *const *a,
390 return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy); 427 const POLICY_MAPPING *const *b)
428{
429 return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy);
391} 430}
392 431
393static int compare_subject_policy(const POLICY_MAPPING *const *a, 432static int
394 const POLICY_MAPPING *const *b) { 433compare_subject_policy(const POLICY_MAPPING *const *a,
395 return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); 434 const POLICY_MAPPING *const *b)
435{
436 return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
396} 437}
397 438
398static int delete_if_mapped(X509_POLICY_NODE *node, void *data) { 439static int
399 const POLICY_MAPPINGS *mappings = data; 440delete_if_mapped(X509_POLICY_NODE *node, void *data)
441{
442 const POLICY_MAPPINGS *mappings = data;
400 // |mappings| must have been sorted by |compare_issuer_policy|. 443 // |mappings| must have been sorted by |compare_issuer_policy|.
401 assert(sk_POLICY_MAPPING_is_sorted(mappings)); 444 assert(sk_POLICY_MAPPING_is_sorted(mappings));
402 POLICY_MAPPING mapping; 445 POLICY_MAPPING mapping;
403 mapping.issuerDomainPolicy = node->policy; 446 mapping.issuerDomainPolicy = node->policy;
404 if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) { 447 if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0) {
405 return 0; 448 return 0;
406 } 449 }
407 x509_policy_node_free(node); 450 x509_policy_node_free(node);
408 return 1; 451 return 1;
409} 452}
410 453
411// process_policy_mappings processes the policy mappings extension of |cert|, 454// process_policy_mappings processes the policy mappings extension of |cert|,
@@ -424,224 +467,245 @@ static int delete_if_mapped(X509_POLICY_NODE *node, void *data) {
424// This is equivalent to the |X509_POLICY_LEVEL| that would result if the next 467// This is equivalent to the |X509_POLICY_LEVEL| that would result if the next
425// certificats contained anyPolicy. |process_certificate_policies| will filter 468// certificats contained anyPolicy. |process_certificate_policies| will filter
426// this result down to compute the actual level. 469// this result down to compute the actual level.
427static X509_POLICY_LEVEL *process_policy_mappings(const X509 *cert, 470static X509_POLICY_LEVEL *
428 X509_POLICY_LEVEL *level, 471process_policy_mappings(const X509 *cert,
429 int mapping_allowed) { 472 X509_POLICY_LEVEL *level,
430 int ok = 0; 473 int mapping_allowed)
431 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; 474{
432 X509_POLICY_LEVEL *next = NULL; 475 int ok = 0;
433 int critical; 476 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
434 POLICY_MAPPINGS *mappings = 477 X509_POLICY_LEVEL *next = NULL;
435 X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); 478 int critical;
436 if (mappings == NULL && critical != -1) { 479 POLICY_MAPPINGS *mappings =
480 X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL);
481 if (mappings == NULL && critical != -1) {
437 // Syntax error in the policy mappings extension. 482 // Syntax error in the policy mappings extension.
438 goto err; 483 goto err;
439 } 484 }
440 485
441 if (mappings != NULL) { 486 if (mappings != NULL) {
442 // PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5. 487 // PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5.
443 // TODO(https://crbug.com/boringssl/443): Move this check into the parser. 488 // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
444 if (sk_POLICY_MAPPING_num(mappings) == 0) { 489 if (sk_POLICY_MAPPING_num(mappings) == 0) {
445 X509error(X509_R_INVALID_POLICY_EXTENSION); 490 X509error(X509_R_INVALID_POLICY_EXTENSION);
446 goto err; 491 goto err;
447 } 492 }
448 493
449 // RFC 5280, section 6.1.4, step (a). 494 // RFC 5280, section 6.1.4, step (a).
450 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { 495 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
451 POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); 496 POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings,
452 if (is_any_policy(mapping->issuerDomainPolicy) || 497 i);
453 is_any_policy(mapping->subjectDomainPolicy)) { 498 if (is_any_policy(mapping->issuerDomainPolicy) ||
454 goto err; 499 is_any_policy(mapping->subjectDomainPolicy)) {
455 } 500 goto err;
456 } 501 }
502 }
457 503
458 // Sort to group by issuerDomainPolicy. 504 // Sort to group by issuerDomainPolicy.
459 sk_POLICY_MAPPING_set_cmp_func(mappings, compare_issuer_policy); 505 sk_POLICY_MAPPING_set_cmp_func(mappings, compare_issuer_policy);
460 sk_POLICY_MAPPING_sort(mappings); 506 sk_POLICY_MAPPING_sort(mappings);
461 507
462 if (mapping_allowed) { 508 if (mapping_allowed) {
463 // Mark nodes as mapped, and add any nodes to |level| which may be needed 509 // Mark nodes as mapped, and add any nodes to |level| which may be needed
464 // as part of RFC 5280, section 6.1.4, step (b.1). 510 // as part of RFC 5280, section 6.1.4, step (b.1).
465 new_nodes = sk_X509_POLICY_NODE_new_null(); 511 new_nodes = sk_X509_POLICY_NODE_new_null();
466 if (new_nodes == NULL) { 512 if (new_nodes == NULL) {
467 goto err; 513 goto err;
468 } 514 }
469 const ASN1_OBJECT *last_policy = NULL; 515 const ASN1_OBJECT *last_policy = NULL;
470 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { 516 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings);
471 const POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); 517 i++) {
472 // There may be multiple mappings with the same |issuerDomainPolicy|. 518 const POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings,
473 if (last_policy != NULL && 519 i);
474 OBJ_cmp(mapping->issuerDomainPolicy, last_policy) == 0) { 520 // There may be multiple mappings with the same |issuerDomainPolicy|.
475 continue; 521 if (last_policy != NULL &&
476 } 522 OBJ_cmp(mapping->issuerDomainPolicy,
477 last_policy = mapping->issuerDomainPolicy; 523 last_policy) == 0) {
478 524 continue;
479 X509_POLICY_NODE *node = 525 }
480 x509_policy_level_find(level, mapping->issuerDomainPolicy); 526 last_policy = mapping->issuerDomainPolicy;
481 if (node == NULL) { 527
482 if (!level->has_any_policy) { 528 X509_POLICY_NODE *node =
483 continue; 529 x509_policy_level_find(level,
484 } 530 mapping->issuerDomainPolicy);
485 node = x509_policy_node_new(mapping->issuerDomainPolicy); 531 if (node == NULL) {
486 if (node == NULL || // 532 if (!level->has_any_policy) {
487 !sk_X509_POLICY_NODE_push(new_nodes, node)) { 533 continue;
488 x509_policy_node_free(node); 534 }
489 goto err; 535 node = x509_policy_node_new(
490 } 536 mapping->issuerDomainPolicy);
491 } 537 if (node == NULL || //
492 node->mapped = 1; 538 !sk_X509_POLICY_NODE_push(new_nodes,
493 } 539 node)) {
494 if (!x509_policy_level_add_nodes(level, new_nodes)) { 540 x509_policy_node_free(node);
495 goto err; 541 goto err;
496 } 542 }
497 } else { 543 }
544 node->mapped = 1;
545 }
546 if (!x509_policy_level_add_nodes(level, new_nodes)) {
547 goto err;
548 }
549 } else {
498 // RFC 5280, section 6.1.4, step (b.2). If mapping is inhibited, delete 550 // RFC 5280, section 6.1.4, step (b.2). If mapping is inhibited, delete
499 // all mapped nodes. 551 // all mapped nodes.
500 sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_mapped, mappings); 552 sk_X509_POLICY_NODE_delete_if(level->nodes,
501 sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); 553 delete_if_mapped, mappings);
502 mappings = NULL; 554 sk_POLICY_MAPPING_pop_free(mappings,
503 } 555 POLICY_MAPPING_free);
504 } 556 mappings = NULL;
557 }
558 }
505 559
506 // If a node was not mapped, it retains the original "explicit_policy_set" 560 // If a node was not mapped, it retains the original "explicit_policy_set"
507 // value, itself. Add those to |mappings|. 561 // value, itself. Add those to |mappings|.
508 if (mappings == NULL) { 562 if (mappings == NULL) {
509 mappings = sk_POLICY_MAPPING_new_null(); 563 mappings = sk_POLICY_MAPPING_new_null();
510 if (mappings == NULL) { 564 if (mappings == NULL) {
511 goto err; 565 goto err;
512 } 566 }
513 } 567 }
514 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { 568 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
515 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, i); 569 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes,
516 if (!node->mapped) { 570 i);
517 POLICY_MAPPING *mapping = POLICY_MAPPING_new(); 571 if (!node->mapped) {
518 if (mapping == NULL) { 572 POLICY_MAPPING *mapping = POLICY_MAPPING_new();
519 goto err; 573 if (mapping == NULL) {
520 } 574 goto err;
521 mapping->issuerDomainPolicy = OBJ_dup(node->policy); 575 }
522 mapping->subjectDomainPolicy = OBJ_dup(node->policy); 576 mapping->issuerDomainPolicy = OBJ_dup(node->policy);
523 if (mapping->issuerDomainPolicy == NULL || 577 mapping->subjectDomainPolicy = OBJ_dup(node->policy);
524 mapping->subjectDomainPolicy == NULL || 578 if (mapping->issuerDomainPolicy == NULL ||
525 !sk_POLICY_MAPPING_push(mappings, mapping)) { 579 mapping->subjectDomainPolicy == NULL ||
526 POLICY_MAPPING_free(mapping); 580 !sk_POLICY_MAPPING_push(mappings, mapping)) {
527 goto err; 581 POLICY_MAPPING_free(mapping);
528 } 582 goto err;
529 } 583 }
530 } 584 }
585 }
531 586
532 // Sort to group by subjectDomainPolicy. 587 // Sort to group by subjectDomainPolicy.
533 sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy); 588 sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy);
534 sk_POLICY_MAPPING_sort(mappings); 589 sk_POLICY_MAPPING_sort(mappings);
535 590
536 // Convert |mappings| to our "expected_policy_set" representation. 591 // Convert |mappings| to our "expected_policy_set" representation.
537 next = x509_policy_level_new(); 592 next = x509_policy_level_new();
538 if (next == NULL) { 593 if (next == NULL) {
539 goto err; 594 goto err;
540 } 595 }
541 next->has_any_policy = level->has_any_policy; 596 next->has_any_policy = level->has_any_policy;
542 597
543 X509_POLICY_NODE *last_node = NULL; 598 X509_POLICY_NODE *last_node = NULL;
544 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { 599 for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
545 POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); 600 POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i);
546 // Skip mappings where |issuerDomainPolicy| does not appear in the graph. 601 // Skip mappings where |issuerDomainPolicy| does not appear in the graph.
547 if (!level->has_any_policy && 602 if (!level->has_any_policy &&
548 x509_policy_level_find(level, mapping->issuerDomainPolicy) == NULL) { 603 x509_policy_level_find(level,
549 continue; 604 mapping->issuerDomainPolicy) == NULL) {
550 } 605 continue;
551 606 }
552 if (last_node == NULL || 607
553 OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != 0) { 608 if (last_node == NULL ||
554 last_node = x509_policy_node_new(mapping->subjectDomainPolicy); 609 OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) !=
555 if (last_node == NULL || 610 0) {
556 !sk_X509_POLICY_NODE_push(next->nodes, last_node)) { 611 last_node = x509_policy_node_new(
557 x509_policy_node_free(last_node); 612 mapping->subjectDomainPolicy);
558 goto err; 613 if (last_node == NULL ||
559 } 614 !sk_X509_POLICY_NODE_push(next->nodes, last_node)) {
560 } 615 x509_policy_node_free(last_node);
561 616 goto err;
562 if (!sk_ASN1_OBJECT_push(last_node->parent_policies, 617 }
563 mapping->issuerDomainPolicy)) { 618 }
564 goto err; 619
565 } 620 if (!sk_ASN1_OBJECT_push(last_node->parent_policies,
566 mapping->issuerDomainPolicy = NULL; 621 mapping->issuerDomainPolicy)) {
567 } 622 goto err;
568 623 }
569 sk_X509_POLICY_NODE_sort(next->nodes); 624 mapping->issuerDomainPolicy = NULL;
570 ok = 1; 625 }
626
627 sk_X509_POLICY_NODE_sort(next->nodes);
628 ok = 1;
571 629
572err: 630err:
573 if (!ok) { 631 if (!ok) {
574 x509_policy_level_free(next); 632 x509_policy_level_free(next);
575 next = NULL; 633 next = NULL;
576 } 634 }
577 635
578 sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); 636 sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free);
579 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); 637 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
580 return next; 638 return next;
581} 639}
582 640
583// apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum 641// apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum
584// of its current value and |skip_certs|. It returns one on success and zero if 642// of its current value and |skip_certs|. It returns one on success and zero if
585// |skip_certs| is negative. 643// |skip_certs| is negative.
586static int apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) { 644static int
587 if (skip_certs == NULL) { 645apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value)
588 return 1; 646{
589 } 647 if (skip_certs == NULL) {
648 return 1;
649 }
590 650
591 // TODO(https://crbug.com/boringssl/443): Move this check into the parser. 651 // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
592 if (skip_certs->type & V_ASN1_NEG) { 652 if (skip_certs->type & V_ASN1_NEG) {
593 X509error(X509_R_INVALID_POLICY_EXTENSION); 653 X509error(X509_R_INVALID_POLICY_EXTENSION);
594 return 0; 654 return 0;
595 } 655 }
596 656
597 // If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. 657 // If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|.
598 uint64_t u64; 658 uint64_t u64;
599 if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) { 659 if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) {
600 *value = (size_t)u64; 660 *value = (size_t)u64;
601 } 661 }
602 ERR_clear_error(); 662 ERR_clear_error();
603 return 1; 663 return 1;
604} 664}
605 665
606// process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and 666// process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and
607// |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit 667// |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit
608// anyPolicy extensions. It returns one on success and zero on error. This 668// anyPolicy extensions. It returns one on success and zero on error. This
609// implements steps (i) and (j) of RFC 5280, section 6.1.4. 669// implements steps (i) and (j) of RFC 5280, section 6.1.4.
610static int process_policy_constraints(const X509 *x509, size_t *explicit_policy, 670static int
611 size_t *policy_mapping, 671process_policy_constraints(const X509 *x509, size_t *explicit_policy,
612 size_t *inhibit_any_policy) { 672 size_t *policy_mapping,
613 int critical; 673 size_t *inhibit_any_policy)
614 POLICY_CONSTRAINTS *constraints = 674{
615 X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL); 675 int critical;
616 if (constraints == NULL && critical != -1) { 676 POLICY_CONSTRAINTS *constraints =
617 return 0; 677 X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL);
618 } 678 if (constraints == NULL && critical != -1) {
619 if (constraints != NULL) { 679 return 0;
620 if (constraints->requireExplicitPolicy == NULL && 680 }
621 constraints->inhibitPolicyMapping == NULL) { 681 if (constraints != NULL) {
682 if (constraints->requireExplicitPolicy == NULL &&
683 constraints->inhibitPolicyMapping == NULL) {
622 // Per RFC 5280, section 4.2.1.11, at least one of the fields must be 684 // Per RFC 5280, section 4.2.1.11, at least one of the fields must be
623 // present. 685 // present.
624 X509error(X509_R_INVALID_POLICY_EXTENSION); 686 X509error(X509_R_INVALID_POLICY_EXTENSION);
625 POLICY_CONSTRAINTS_free(constraints); 687 POLICY_CONSTRAINTS_free(constraints);
626 return 0; 688 return 0;
627 } 689 }
628 int ok = 690 int ok =
629 apply_skip_certs(constraints->requireExplicitPolicy, explicit_policy) && 691 apply_skip_certs(constraints->requireExplicitPolicy,
630 apply_skip_certs(constraints->inhibitPolicyMapping, policy_mapping); 692 explicit_policy) &&
631 POLICY_CONSTRAINTS_free(constraints); 693 apply_skip_certs(constraints->inhibitPolicyMapping,
632 if (!ok) { 694 policy_mapping);
633 return 0; 695 POLICY_CONSTRAINTS_free(constraints);
634 } 696 if (!ok) {
635 } 697 return 0;
636 698 }
637 ASN1_INTEGER *inhibit_any_policy_ext = 699 }
638 X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL); 700
639 if (inhibit_any_policy_ext == NULL && critical != -1) { 701 ASN1_INTEGER *inhibit_any_policy_ext =
640 return 0; 702 X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL);
641 } 703 if (inhibit_any_policy_ext == NULL && critical != -1) {
642 int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); 704 return 0;
643 ASN1_INTEGER_free(inhibit_any_policy_ext); 705 }
644 return ok; 706 int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy);
707 ASN1_INTEGER_free(inhibit_any_policy_ext);
708 return ok;
645} 709}
646 710
647// has_explicit_policy returns one if the set of authority-space policy OIDs 711// has_explicit_policy returns one if the set of authority-space policy OIDs
@@ -649,215 +713,236 @@ static int process_policy_constraints(const X509 *x509, size_t *explicit_policy,
649// otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This 713// otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This
650// function modifies |levels| and should only be called at the end of policy 714// function modifies |levels| and should only be called at the end of policy
651// evaluation. 715// evaluation.
652static int has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, 716static int
653 const STACK_OF(ASN1_OBJECT) *user_policies) { 717has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels,
654 assert(user_policies == NULL || sk_ASN1_OBJECT_is_sorted(user_policies)); 718 const STACK_OF(ASN1_OBJECT) *user_policies)
719{
720 assert(user_policies == NULL ||
721 sk_ASN1_OBJECT_is_sorted(user_policies));
655 722
656 // Step (g.i). If the policy graph is empty, the intersection is empty. 723 // Step (g.i). If the policy graph is empty, the intersection is empty.
657 size_t num_levels = sk_X509_POLICY_LEVEL_num(levels); 724 size_t num_levels = sk_X509_POLICY_LEVEL_num(levels);
658 X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1); 725 X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels,
659 if (x509_policy_level_is_empty(level)) { 726 num_levels - 1);
660 return 0; 727 if (x509_policy_level_is_empty(level)) {
661 } 728 return 0;
729 }
662 730
663 // If |user_policies| is empty, we interpret it as having a single anyPolicy 731 // If |user_policies| is empty, we interpret it as having a single anyPolicy
664 // value. The caller may also have supplied anyPolicy explicitly. 732 // value. The caller may also have supplied anyPolicy explicitly.
665 int user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) == 0; 733 int user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) == 0;
666 for (size_t i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) { 734 for (size_t i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) {
667 if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) { 735 if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) {
668 user_has_any_policy = 1; 736 user_has_any_policy = 1;
669 break; 737 break;
670 } 738 }
671 } 739 }
672 740
673 // Step (g.ii). If the policy graph is not empty and the user set contains 741 // Step (g.ii). If the policy graph is not empty and the user set contains
674 // anyPolicy, the intersection is the entire (non-empty) graph. 742 // anyPolicy, the intersection is the entire (non-empty) graph.
675 if (user_has_any_policy) { 743 if (user_has_any_policy) {
676 return 1; 744 return 1;
677 } 745 }
678 746
679 // Step (g.iii) does not delete anyPolicy nodes, so if the graph has 747 // Step (g.iii) does not delete anyPolicy nodes, so if the graph has
680 // anyPolicy, some explicit policy will survive. The actual intersection may 748 // anyPolicy, some explicit policy will survive. The actual intersection may
681 // synthesize some nodes in step (g.iii.3), but we do not return the policy 749 // synthesize some nodes in step (g.iii.3), but we do not return the policy
682 // list itself, so we skip actually computing this. 750 // list itself, so we skip actually computing this.
683 if (level->has_any_policy) { 751 if (level->has_any_policy) {
684 return 1; 752 return 1;
685 } 753 }
686 754
687 // We defer pruning the tree, so as we look for nodes with parent anyPolicy, 755 // We defer pruning the tree, so as we look for nodes with parent anyPolicy,
688 // step (g.iii.1), we must limit to nodes reachable from the bottommost level. 756 // step (g.iii.1), we must limit to nodes reachable from the bottommost level.
689 // Start by marking each of those nodes as reachable. 757 // Start by marking each of those nodes as reachable.
690 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { 758 for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
691 sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; 759 sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1;
692 } 760 }
693 761
694 for (size_t i = num_levels - 1; i < num_levels; i--) { 762 for (size_t i = num_levels - 1; i < num_levels; i--) {
695 level = sk_X509_POLICY_LEVEL_value(levels, i); 763 level = sk_X509_POLICY_LEVEL_value(levels, i);
696 for (size_t j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) { 764 for (size_t j = 0; j < sk_X509_POLICY_NODE_num(level->nodes);
697 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, j); 765 j++) {
698 if (!node->reachable) { 766 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes,
699 continue; 767 j);
700 } 768 if (!node->reachable) {
701 if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { 769 continue;
702 // |node|'s parent is anyPolicy and is part of "valid_policy_node_set". 770 }
703 // If it exists in |user_policies|, the intersection is non-empty and we 771 if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) {
704 // can return immediately. 772 // |node|'s parent is anyPolicy and is part of "valid_policy_node_set".
705 if (sk_ASN1_OBJECT_find(user_policies, node->policy) >= 0) { 773 // If it exists in |user_policies|, the intersection is non-empty and we
706 return 1; 774 // can return immediately.
707 } 775 if (sk_ASN1_OBJECT_find(user_policies,
708 } else if (i > 0) { 776 node->policy) >= 0) {
709 // |node|'s parents are concrete policies. Mark the parents reachable, 777 return 1;
710 // to be inspected by the next loop iteration. 778 }
711 X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); 779 } else if (i > 0) {
712 for (size_t k = 0; k < sk_ASN1_OBJECT_num(node->parent_policies); k++) { 780 // |node|'s parents are concrete policies. Mark the parents reachable,
713 X509_POLICY_NODE *parent = x509_policy_level_find( 781 // to be inspected by the next loop iteration.
714 prev, sk_ASN1_OBJECT_value(node->parent_policies, k)); 782 X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels,
715 if (parent != NULL) { 783 i - 1);
716 parent->reachable = 1; 784 for (size_t k = 0; k <
717 } 785 sk_ASN1_OBJECT_num(node->parent_policies);
718 } 786 k++) {
719 } 787 X509_POLICY_NODE *parent = x509_policy_level_find(
720 } 788 prev,
721 } 789
722 790 sk_ASN1_OBJECT_value(node->parent_policies,
723 return 0; 791 k));
792 if (parent != NULL) {
793 parent->reachable = 1;
794 }
795 }
796 }
797 }
798 }
799
800 return 0;
724} 801}
725 802
726static int asn1_object_cmp(const ASN1_OBJECT *const *a, 803static int
727 const ASN1_OBJECT *const *b) { 804asn1_object_cmp(const ASN1_OBJECT *const *a,
728 return OBJ_cmp(*a, *b); 805 const ASN1_OBJECT *const *b)
806{
807 return OBJ_cmp(*a, *b);
729} 808}
730 809
731int X509_policy_check(const STACK_OF(X509) *certs, 810int
732 const STACK_OF(ASN1_OBJECT) *user_policies, 811X509_policy_check(const STACK_OF(X509) *certs,
733 unsigned long flags, X509 **out_current_cert) { 812 const STACK_OF(ASN1_OBJECT) *user_policies,
734 *out_current_cert = NULL; 813 unsigned long flags, X509 **out_current_cert)
735 int ret = X509_V_ERR_OUT_OF_MEM; 814{
736 X509_POLICY_LEVEL *level = NULL; 815 *out_current_cert = NULL;
737 STACK_OF(X509_POLICY_LEVEL) *levels = NULL; 816 int ret = X509_V_ERR_OUT_OF_MEM;
738 STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL; 817 X509_POLICY_LEVEL *level = NULL;
739 size_t num_certs = sk_X509_num(certs); 818 STACK_OF(X509_POLICY_LEVEL) *levels = NULL;
819 STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL;
820 size_t num_certs = sk_X509_num(certs);
740 821
741 // Skip policy checking if the chain is just the trust anchor. 822 // Skip policy checking if the chain is just the trust anchor.
742 if (num_certs <= 1) { 823 if (num_certs <= 1) {
743 return X509_V_OK; 824 return X509_V_OK;
744 } 825 }
745 826
746 // See RFC 5280, section 6.1.2, steps (d) through (f). 827 // See RFC 5280, section 6.1.2, steps (d) through (f).
747 size_t explicit_policy = 828 size_t explicit_policy =
748 (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1; 829 (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1;
749 size_t inhibit_any_policy = 830 size_t inhibit_any_policy =
750 (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1; 831 (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1;
751 size_t policy_mapping = 832 size_t policy_mapping =
752 (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; 833 (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1;
753 834
754 levels = sk_X509_POLICY_LEVEL_new_null(); 835 levels = sk_X509_POLICY_LEVEL_new_null();
755 if (levels == NULL) { 836 if (levels == NULL) {
756 goto err; 837 goto err;
757 } 838 }
758 839
759 for (size_t i = num_certs - 2; i < num_certs; i--) { 840 for (size_t i = num_certs - 2; i < num_certs; i--) {
760 X509 *cert = sk_X509_value(certs, i); 841 X509 *cert = sk_X509_value(certs, i);
761 if (!x509v3_cache_extensions(cert)) { 842 if (!x509v3_cache_extensions(cert)) {
762 goto err; 843 goto err;
763 } 844 }
764 const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; 845 const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0;
765 846
766 if (level == NULL) { 847 if (level == NULL) {
767 assert(i == num_certs - 2); 848 assert(i == num_certs - 2);
768 level = x509_policy_level_new(); 849 level = x509_policy_level_new();
769 if (level == NULL) { 850 if (level == NULL) {
770 goto err; 851 goto err;
771 } 852 }
772 level->has_any_policy = 1; 853 level->has_any_policy = 1;
773 } 854 }
774 855
775 // RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| is 856 // RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| is
776 // computed as in step (d.2). 857 // computed as in step (d.2).
777 const int any_policy_allowed = 858 const int any_policy_allowed =
778 inhibit_any_policy > 0 || (i > 0 && is_self_issued); 859 inhibit_any_policy > 0 || (i > 0 && is_self_issued);
779 if (!process_certificate_policies(cert, level, any_policy_allowed)) { 860 if (!process_certificate_policies(cert, level,
780 ret = X509_V_ERR_INVALID_POLICY_EXTENSION; 861 any_policy_allowed)) {
781 *out_current_cert = cert; 862 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
782 goto err; 863 *out_current_cert = cert;
783 } 864 goto err;
865 }
784 866
785 // RFC 5280, section 6.1.3, step (f). 867 // RFC 5280, section 6.1.3, step (f).
786 if (explicit_policy == 0 && x509_policy_level_is_empty(level)) { 868 if (explicit_policy == 0 && x509_policy_level_is_empty(level)) {
787 ret = X509_V_ERR_NO_EXPLICIT_POLICY; 869 ret = X509_V_ERR_NO_EXPLICIT_POLICY;
788 goto err; 870 goto err;
789 } 871 }
790 872
791 // Insert into the list. 873 // Insert into the list.
792 if (!sk_X509_POLICY_LEVEL_push(levels, level)) { 874 if (!sk_X509_POLICY_LEVEL_push(levels, level)) {
793 goto err; 875 goto err;
794 } 876 }
795 X509_POLICY_LEVEL *current_level = level; 877 X509_POLICY_LEVEL *current_level = level;
796 level = NULL; 878 level = NULL;
797 879
798 // If this is not the leaf certificate, we go to section 6.1.4. If it 880 // If this is not the leaf certificate, we go to section 6.1.4. If it
799 // is the leaf certificate, we go to section 6.1.5 instead. 881 // is the leaf certificate, we go to section 6.1.5 instead.
800 if (i != 0) { 882 if (i != 0) {
801 // RFC 5280, section 6.1.4, steps (a) and (b). 883 // RFC 5280, section 6.1.4, steps (a) and (b).
802 level = process_policy_mappings(cert, current_level, policy_mapping > 0); 884 level = process_policy_mappings(cert, current_level,
803 if (level == NULL) { 885 policy_mapping > 0);
804 ret = X509_V_ERR_INVALID_POLICY_EXTENSION; 886 if (level == NULL) {
805 *out_current_cert = cert; 887 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
806 goto err; 888 *out_current_cert = cert;
807 } 889 goto err;
808 } 890 }
891 }
809 892
810 // RFC 5280, section 6.1.4, step (h-j) for non-leaves, and section 6.1.5, 893 // RFC 5280, section 6.1.4, step (h-j) for non-leaves, and section 6.1.5,
811 // step (a-b) for leaves. In the leaf case, RFC 5280 says only to update 894 // step (a-b) for leaves. In the leaf case, RFC 5280 says only to update
812 // |explicit_policy|, but |policy_mapping| and |inhibit_any_policy| are no 895 // |explicit_policy|, but |policy_mapping| and |inhibit_any_policy| are no
813 // longer read at this point, so we use the same process. 896 // longer read at this point, so we use the same process.
814 if (i == 0 || !is_self_issued) { 897 if (i == 0 || !is_self_issued) {
815 if (explicit_policy > 0) { 898 if (explicit_policy > 0) {
816 explicit_policy--; 899 explicit_policy--;
817 } 900 }
818 if (policy_mapping > 0) { 901 if (policy_mapping > 0) {
819 policy_mapping--; 902 policy_mapping--;
820 } 903 }
821 if (inhibit_any_policy > 0) { 904 if (inhibit_any_policy > 0) {
822 inhibit_any_policy--; 905 inhibit_any_policy--;
823 } 906 }
824 } 907 }
825 if (!process_policy_constraints(cert, &explicit_policy, &policy_mapping, 908 if (!process_policy_constraints(cert, &explicit_policy,
826 &inhibit_any_policy)) { 909 &policy_mapping, &inhibit_any_policy)) {
827 ret = X509_V_ERR_INVALID_POLICY_EXTENSION; 910 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
828 *out_current_cert = cert; 911 *out_current_cert = cert;
829 goto err; 912 goto err;
830 } 913 }
831 } 914 }
832 915
833 // RFC 5280, section 6.1.5, step (g). We do not output the policy set, so it 916 // RFC 5280, section 6.1.5, step (g). We do not output the policy set, so it
834 // is only necessary to check if the user-constrained-policy-set is not empty. 917 // is only necessary to check if the user-constrained-policy-set is not empty.
835 if (explicit_policy == 0) { 918 if (explicit_policy == 0) {
836 // Build a sorted copy of |user_policies| for more efficient lookup. 919 // Build a sorted copy of |user_policies| for more efficient lookup.
837 if (user_policies != NULL) { 920 if (user_policies != NULL) {
838 user_policies_sorted = sk_ASN1_OBJECT_dup(user_policies); 921 user_policies_sorted = sk_ASN1_OBJECT_dup(
839 if (user_policies_sorted == NULL) { 922 user_policies);
840 goto err; 923 if (user_policies_sorted == NULL) {
841 } 924 goto err;
842 sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, asn1_object_cmp); 925 }
843 sk_ASN1_OBJECT_sort(user_policies_sorted); 926 sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted,
844 } 927 asn1_object_cmp);
845 928 sk_ASN1_OBJECT_sort(user_policies_sorted);
846 if (!has_explicit_policy(levels, user_policies_sorted)) { 929 }
847 ret = X509_V_ERR_NO_EXPLICIT_POLICY; 930
848 goto err; 931 if (!has_explicit_policy(levels, user_policies_sorted)) {
849 } 932 ret = X509_V_ERR_NO_EXPLICIT_POLICY;
850 } 933 goto err;
851 934 }
852 ret = X509_V_OK; 935 }
936
937 ret = X509_V_OK;
853 938
854err: 939err:
855 x509_policy_level_free(level); 940 x509_policy_level_free(level);
856 // |user_policies_sorted|'s contents are owned by |user_policies|, so we do 941 // |user_policies_sorted|'s contents are owned by |user_policies|, so we do
857 // not use |sk_ASN1_OBJECT_pop_free|. 942 // not use |sk_ASN1_OBJECT_pop_free|.
858 sk_ASN1_OBJECT_free(user_policies_sorted); 943 sk_ASN1_OBJECT_free(user_policies_sorted);
859 sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free); 944 sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free);
860 return ret; 945 return ret;
861} 946}
862 947
863#endif /* LIBRESSL_HAS_POLICY_DAG */ 948#endif /* LIBRESSL_HAS_POLICY_DAG */