Coverage Report

Created: 2025-06-11 06:40

/src/boringssl/crypto/x509/policy.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2022 The BoringSSL Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/x509.h>
16
17
#include <assert.h>
18
19
#include <openssl/mem.h>
20
#include <openssl/obj.h>
21
#include <openssl/stack.h>
22
23
#include "../internal.h"
24
#include "internal.h"
25
26
27
// This file computes the X.509 policy tree, as described in RFC 5280, section
28
// 6.1. It differs in that:
29
//
30
//  (1) It does not track "qualifier_set". This is not needed as it is not
31
//      output by this implementation.
32
//
33
//  (2) It builds a directed acyclic graph, rather than a tree. When a given
34
//      policy matches multiple parents, RFC 5280 makes a separate node for
35
//      each parent. This representation condenses them into one node with
36
//      multiple parents. Thus we refer to this structure as a "policy graph",
37
//      rather than a "policy tree".
38
//
39
//  (3) "expected_policy_set" is not tracked explicitly and built temporarily
40
//      as part of building the graph.
41
//
42
//  (4) anyPolicy nodes are not tracked explicitly.
43
//
44
//  (5) Some pruning steps are deferred to when policies are evaluated, as a
45
//      reachability pass.
46
47
// An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node
48
// from RFC 5280, section 6.1.2, step (a), but we store some fields differently.
49
typedef struct x509_policy_node_st {
50
  // policy is the "valid_policy" field from RFC 5280.
51
  ASN1_OBJECT *policy;
52
53
  // parent_policies, if non-empty, is the list of "valid_policy" values for all
54
  // nodes which are a parent of this node. In this case, no entry in this list
55
  // will be anyPolicy. This list is in no particular order and may contain
56
  // duplicates if the corresponding certificate had duplicate mappings.
57
  //
58
  // If empty, this node has a single parent, anyPolicy. The node is then a root
59
  // policies, and is in authorities-constrained-policy-set if it has a path to
60
  // a leaf node.
61
  //
62
  // Note it is not possible for a policy to have both anyPolicy and a
63
  // concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs if
64
  // there was no match in step (d.1.i). We do not need to represent a parent
65
  // list of, say, {anyPolicy, OID1, OID2}.
66
  STACK_OF(ASN1_OBJECT) *parent_policies;
67
68
  // mapped is one if this node matches a policy mapping in the certificate and
69
  // zero otherwise.
70
  int mapped;
71
72
  // reachable is one if this node is reachable from some valid policy in the
73
  // end-entity certificate. It is computed during |has_explicit_policy|.
74
  int reachable;
75
} X509_POLICY_NODE;
76
77
DEFINE_STACK_OF(X509_POLICY_NODE)
78
79
// An X509_POLICY_LEVEL is the collection of nodes at the same depth in the
80
// policy graph. This structure can also be used to represent a level's
81
// "expected_policy_set" values. See |process_policy_mappings|.
82
typedef struct x509_policy_level_st {
83
  // nodes is the list of nodes at this depth, except for the anyPolicy node, if
84
  // any. This list is sorted by policy OID for efficient lookup.
85
  STACK_OF(X509_POLICY_NODE) *nodes;
86
87
  // has_any_policy is one if there is an anyPolicy node at this depth, and zero
88
  // otherwise.
89
  int has_any_policy;
90
} X509_POLICY_LEVEL;
91
92
DEFINE_STACK_OF(X509_POLICY_LEVEL)
93
94
0
static int is_any_policy(const ASN1_OBJECT *obj) {
95
0
  return OBJ_obj2nid(obj) == NID_any_policy;
96
0
}
97
98
0
static void x509_policy_node_free(X509_POLICY_NODE *node) {
99
0
  if (node != NULL) {
100
0
    ASN1_OBJECT_free(node->policy);
101
0
    sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free);
102
0
    OPENSSL_free(node);
103
0
  }
104
0
}
105
106
0
static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) {
107
0
  assert(!is_any_policy(policy));
108
0
  X509_POLICY_NODE *node = reinterpret_cast<X509_POLICY_NODE *>(
109
0
      OPENSSL_zalloc(sizeof(X509_POLICY_NODE)));
110
0
  if (node == NULL) {
111
0
    return NULL;
112
0
  }
113
0
  node->policy = OBJ_dup(policy);
114
0
  node->parent_policies = sk_ASN1_OBJECT_new_null();
115
0
  if (node->policy == NULL || node->parent_policies == NULL) {
116
0
    x509_policy_node_free(node);
117
0
    return NULL;
118
0
  }
119
0
  return node;
120
0
}
121
122
static int x509_policy_node_cmp(const X509_POLICY_NODE *const *a,
123
0
                                const X509_POLICY_NODE *const *b) {
124
0
  return OBJ_cmp((*a)->policy, (*b)->policy);
125
0
}
126
127
0
static void x509_policy_level_free(X509_POLICY_LEVEL *level) {
128
0
  if (level != NULL) {
129
0
    sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free);
130
0
    OPENSSL_free(level);
131
0
  }
132
0
}
133
134
0
static X509_POLICY_LEVEL *x509_policy_level_new(void) {
135
0
  X509_POLICY_LEVEL *level = reinterpret_cast<X509_POLICY_LEVEL *>(
136
0
      OPENSSL_zalloc(sizeof(X509_POLICY_LEVEL)));
137
0
  if (level == NULL) {
138
0
    return NULL;
139
0
  }
140
0
  level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp);
141
0
  if (level->nodes == NULL) {
142
0
    x509_policy_level_free(level);
143
0
    return NULL;
144
0
  }
145
0
  return level;
146
0
}
147
148
0
static int x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) {
149
0
  return !level->has_any_policy && sk_X509_POLICY_NODE_num(level->nodes) == 0;
150
0
}
151
152
0
static void x509_policy_level_clear(X509_POLICY_LEVEL *level) {
153
0
  level->has_any_policy = 0;
154
0
  for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
155
0
    x509_policy_node_free(sk_X509_POLICY_NODE_value(level->nodes, i));
156
0
  }
157
0
  sk_X509_POLICY_NODE_zero(level->nodes);
158
0
}
159
160
// x509_policy_level_find returns the node in |level| corresponding to |policy|,
161
// or NULL if none exists.
162
static X509_POLICY_NODE *x509_policy_level_find(X509_POLICY_LEVEL *level,
163
0
                                                const ASN1_OBJECT *policy) {
164
0
  assert(sk_X509_POLICY_NODE_is_sorted(level->nodes));
165
0
  X509_POLICY_NODE node;
166
0
  node.policy = (ASN1_OBJECT *)policy;
167
0
  size_t idx;
168
0
  if (!sk_X509_POLICY_NODE_find(level->nodes, &idx, &node)) {
169
0
    return NULL;
170
0
  }
171
0
  return sk_X509_POLICY_NODE_value(level->nodes, idx);
172
0
}
173
174
// x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns
175
// one on success and zero on error. No policy in |nodes| may already be present
176
// in |level|. This function modifies |nodes| to avoid making a copy, but the
177
// caller is still responsible for releasing |nodes| itself.
178
//
179
// This function is used to add nodes to |level| in bulk, and avoid resorting
180
// |level| after each addition.
181
static int x509_policy_level_add_nodes(X509_POLICY_LEVEL *level,
182
0
                                       STACK_OF(X509_POLICY_NODE) *nodes) {
183
0
  for (size_t i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
184
0
    X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i);
185
0
    if (!sk_X509_POLICY_NODE_push(level->nodes, node)) {
186
0
      return 0;
187
0
    }
188
0
    sk_X509_POLICY_NODE_set(nodes, i, NULL);
189
0
  }
190
0
  sk_X509_POLICY_NODE_sort(level->nodes);
191
192
0
#if !defined(NDEBUG)
193
  // There should be no duplicate nodes.
194
0
  for (size_t i = 1; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
195
0
    assert(OBJ_cmp(sk_X509_POLICY_NODE_value(level->nodes, i - 1)->policy,
196
0
                   sk_X509_POLICY_NODE_value(level->nodes, i)->policy) != 0);
197
0
  }
198
0
#endif
199
0
  return 1;
200
0
}
201
202
static int policyinfo_cmp(const POLICYINFO *const *a,
203
0
                          const POLICYINFO *const *b) {
204
0
  return OBJ_cmp((*a)->policyid, (*b)->policyid);
205
0
}
206
207
0
static int delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) {
208
0
  const CERTIFICATEPOLICIES *policies =
209
0
      reinterpret_cast<CERTIFICATEPOLICIES *>(data);
210
0
  assert(sk_POLICYINFO_is_sorted(policies));
211
0
  POLICYINFO info;
212
0
  info.policyid = node->policy;
213
0
  if (sk_POLICYINFO_find(policies, NULL, &info)) {
214
0
    return 0;
215
0
  }
216
0
  x509_policy_node_free(node);
217
0
  return 1;
218
0
}
219
220
// process_certificate_policies updates |level| to incorporate |x509|'s
221
// certificate policies extension. This implements steps (d) and (e) of RFC
222
// 5280, section 6.1.3. |level| must contain the previous level's
223
// "expected_policy_set" information. For all but the top-most level, this is
224
// the output of |process_policy_mappings|. |any_policy_allowed| specifies
225
// whether anyPolicy is allowed or inhibited, taking into account the exception
226
// for self-issued certificates.
227
static int process_certificate_policies(const X509 *x509,
228
                                        X509_POLICY_LEVEL *level,
229
0
                                        int any_policy_allowed) {
230
0
  int ret = 0;
231
0
  int critical;
232
0
  STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
233
0
  CERTIFICATEPOLICIES *policies = reinterpret_cast<CERTIFICATEPOLICIES *>(
234
0
      X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL));
235
236
0
  {
237
0
    if (policies == NULL) {
238
0
      if (critical != -1) {
239
0
        return 0;  // Syntax error in the extension.
240
0
      }
241
242
      // RFC 5280, section 6.1.3, step (e).
243
0
      x509_policy_level_clear(level);
244
0
      return 1;
245
0
    }
246
247
    // certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4.
248
    // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
249
0
    if (sk_POLICYINFO_num(policies) == 0) {
250
0
      OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION);
251
0
      goto err;
252
0
    }
253
254
0
    sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp);
255
0
    sk_POLICYINFO_sort(policies);
256
0
    int cert_has_any_policy = 0;
257
0
    for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) {
258
0
      const POLICYINFO *policy = sk_POLICYINFO_value(policies, i);
259
0
      if (is_any_policy(policy->policyid)) {
260
0
        cert_has_any_policy = 1;
261
0
      }
262
0
      if (i > 0 && OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid,
263
0
                           policy->policyid) == 0) {
264
        // Per RFC 5280, section 4.2.1.4, |policies| may not have duplicates.
265
0
        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION);
266
0
        goto err;
267
0
      }
268
0
    }
269
270
    // This does the same thing as RFC 5280, section 6.1.3, step (d), though in
271
    // a slighty different order. |level| currently contains
272
    // "expected_policy_set" values of the previous level. See
273
    // |process_policy_mappings| for details.
274
0
    const int previous_level_has_any_policy = level->has_any_policy;
275
276
    // First, we handle steps (d.1.i) and (d.2). The net effect of these two
277
    // steps is to intersect |level| with |policies|, ignoring anyPolicy if it
278
    // is inhibited.
279
0
    if (!cert_has_any_policy || !any_policy_allowed) {
280
0
      sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_not_in_policies,
281
0
                                    policies);
282
0
      level->has_any_policy = 0;
283
0
    }
284
285
    // Step (d.1.ii) may attach new nodes to the previous level's anyPolicy
286
    // node.
287
0
    if (previous_level_has_any_policy) {
288
0
      new_nodes = sk_X509_POLICY_NODE_new_null();
289
0
      if (new_nodes == NULL) {
290
0
        goto err;
291
0
      }
292
0
      for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) {
293
0
        const POLICYINFO *policy = sk_POLICYINFO_value(policies, i);
294
        // Though we've reordered the steps slightly, |policy| is in |level| if
295
        // and only if it would have been a match in step (d.1.ii).
296
0
        if (!is_any_policy(policy->policyid) &&
297
0
            x509_policy_level_find(level, policy->policyid) == NULL) {
298
0
          X509_POLICY_NODE *node = x509_policy_node_new(policy->policyid);
299
0
          if (node == NULL ||  //
300
0
              !sk_X509_POLICY_NODE_push(new_nodes, node)) {
301
0
            x509_policy_node_free(node);
302
0
            goto err;
303
0
          }
304
0
        }
305
0
      }
306
0
      if (!x509_policy_level_add_nodes(level, new_nodes)) {
307
0
        goto err;
308
0
      }
309
0
    }
310
311
0
    ret = 1;
312
0
  }
313
314
0
err:
315
0
  sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
316
0
  CERTIFICATEPOLICIES_free(policies);
317
0
  return ret;
318
0
}
319
320
static int compare_issuer_policy(const POLICY_MAPPING *const *a,
321
0
                                 const POLICY_MAPPING *const *b) {
322
0
  return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy);
323
0
}
324
325
static int compare_subject_policy(const POLICY_MAPPING *const *a,
326
0
                                  const POLICY_MAPPING *const *b) {
327
0
  return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
328
0
}
329
330
0
static int delete_if_mapped(X509_POLICY_NODE *node, void *data) {
331
0
  const POLICY_MAPPINGS *mappings = reinterpret_cast<POLICY_MAPPINGS *>(data);
332
  // |mappings| must have been sorted by |compare_issuer_policy|.
333
0
  assert(sk_POLICY_MAPPING_is_sorted(mappings));
334
0
  POLICY_MAPPING mapping;
335
0
  mapping.issuerDomainPolicy = node->policy;
336
0
  if (!sk_POLICY_MAPPING_find(mappings, /*out_index=*/NULL, &mapping)) {
337
0
    return 0;
338
0
  }
339
0
  x509_policy_node_free(node);
340
0
  return 1;
341
0
}
342
343
// process_policy_mappings processes the policy mappings extension of |cert|,
344
// whose corresponding graph level is |level|. |mapping_allowed| specifies
345
// whether policy mapping is inhibited at this point. On success, it returns an
346
// |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On
347
// error, it returns NULL. This implements steps (a) and (b) of RFC 5280,
348
// section 6.1.4.
349
//
350
// We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|.
351
// |has_any_policy| indicates whether there is an anyPolicy node with
352
// "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains
353
// P2 in its "expected_policy_set", the level will contain a node of policy P2
354
// with P1 in |parent_policies|.
355
//
356
// This is equivalent to the |X509_POLICY_LEVEL| that would result if the next
357
// certificats contained anyPolicy. |process_certificate_policies| will filter
358
// this result down to compute the actual level.
359
static X509_POLICY_LEVEL *process_policy_mappings(const X509 *cert,
360
                                                  X509_POLICY_LEVEL *level,
361
0
                                                  int mapping_allowed) {
362
0
  int ok = 0;
363
0
  STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
364
0
  X509_POLICY_LEVEL *next = NULL;
365
0
  int critical;
366
0
  POLICY_MAPPINGS *mappings = reinterpret_cast<POLICY_MAPPINGS *>(
367
0
      X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL));
368
369
0
  {
370
0
    if (mappings == NULL && critical != -1) {
371
      // Syntax error in the policy mappings extension.
372
0
      goto err;
373
0
    }
374
375
0
    if (mappings != NULL) {
376
      // PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5.
377
      // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
378
0
      if (sk_POLICY_MAPPING_num(mappings) == 0) {
379
0
        OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION);
380
0
        goto err;
381
0
      }
382
383
      // RFC 5280, section 6.1.4, step (a).
384
0
      for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
385
0
        POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i);
386
0
        if (is_any_policy(mapping->issuerDomainPolicy) ||
387
0
            is_any_policy(mapping->subjectDomainPolicy)) {
388
0
          goto err;
389
0
        }
390
0
      }
391
392
      // Sort to group by issuerDomainPolicy.
393
0
      sk_POLICY_MAPPING_set_cmp_func(mappings, compare_issuer_policy);
394
0
      sk_POLICY_MAPPING_sort(mappings);
395
396
0
      if (mapping_allowed) {
397
        // Mark nodes as mapped, and add any nodes to |level| which may be
398
        // needed as part of RFC 5280, section 6.1.4, step (b.1).
399
0
        new_nodes = sk_X509_POLICY_NODE_new_null();
400
0
        if (new_nodes == NULL) {
401
0
          goto err;
402
0
        }
403
0
        const ASN1_OBJECT *last_policy = NULL;
404
0
        for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
405
0
          const POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i);
406
          // There may be multiple mappings with the same |issuerDomainPolicy|.
407
0
          if (last_policy != NULL &&
408
0
              OBJ_cmp(mapping->issuerDomainPolicy, last_policy) == 0) {
409
0
            continue;
410
0
          }
411
0
          last_policy = mapping->issuerDomainPolicy;
412
413
0
          X509_POLICY_NODE *node =
414
0
              x509_policy_level_find(level, mapping->issuerDomainPolicy);
415
0
          if (node == NULL) {
416
0
            if (!level->has_any_policy) {
417
0
              continue;
418
0
            }
419
0
            node = x509_policy_node_new(mapping->issuerDomainPolicy);
420
0
            if (node == NULL ||  //
421
0
                !sk_X509_POLICY_NODE_push(new_nodes, node)) {
422
0
              x509_policy_node_free(node);
423
0
              goto err;
424
0
            }
425
0
          }
426
0
          node->mapped = 1;
427
0
        }
428
0
        if (!x509_policy_level_add_nodes(level, new_nodes)) {
429
0
          goto err;
430
0
        }
431
0
      } else {
432
        // RFC 5280, section 6.1.4, step (b.2). If mapping is inhibited, delete
433
        // all mapped nodes.
434
0
        sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_mapped, mappings);
435
0
        sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free);
436
0
        mappings = NULL;
437
0
      }
438
0
    }
439
440
    // If a node was not mapped, it retains the original "explicit_policy_set"
441
    // value, itself. Add those to |mappings|.
442
0
    if (mappings == NULL) {
443
0
      mappings = sk_POLICY_MAPPING_new_null();
444
0
      if (mappings == NULL) {
445
0
        goto err;
446
0
      }
447
0
    }
448
0
    for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
449
0
      X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, i);
450
0
      if (!node->mapped) {
451
0
        POLICY_MAPPING *mapping = POLICY_MAPPING_new();
452
0
        if (mapping == NULL) {
453
0
          goto err;
454
0
        }
455
0
        mapping->issuerDomainPolicy = OBJ_dup(node->policy);
456
0
        mapping->subjectDomainPolicy = OBJ_dup(node->policy);
457
0
        if (mapping->issuerDomainPolicy == NULL ||
458
0
            mapping->subjectDomainPolicy == NULL ||
459
0
            !sk_POLICY_MAPPING_push(mappings, mapping)) {
460
0
          POLICY_MAPPING_free(mapping);
461
0
          goto err;
462
0
        }
463
0
      }
464
0
    }
465
466
    // Sort to group by subjectDomainPolicy.
467
0
    sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy);
468
0
    sk_POLICY_MAPPING_sort(mappings);
469
470
    // Convert |mappings| to our "expected_policy_set" representation.
471
0
    next = x509_policy_level_new();
472
0
    if (next == NULL) {
473
0
      goto err;
474
0
    }
475
0
    next->has_any_policy = level->has_any_policy;
476
477
0
    X509_POLICY_NODE *last_node = NULL;
478
0
    for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
479
0
      POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i);
480
      // Skip mappings where |issuerDomainPolicy| does not appear in the graph.
481
0
      if (!level->has_any_policy &&
482
0
          x509_policy_level_find(level, mapping->issuerDomainPolicy) == NULL) {
483
0
        continue;
484
0
      }
485
486
0
      if (last_node == NULL ||
487
0
          OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != 0) {
488
0
        last_node = x509_policy_node_new(mapping->subjectDomainPolicy);
489
0
        if (last_node == NULL ||
490
0
            !sk_X509_POLICY_NODE_push(next->nodes, last_node)) {
491
0
          x509_policy_node_free(last_node);
492
0
          goto err;
493
0
        }
494
0
      }
495
496
0
      if (!sk_ASN1_OBJECT_push(last_node->parent_policies,
497
0
                               mapping->issuerDomainPolicy)) {
498
0
        goto err;
499
0
      }
500
0
      mapping->issuerDomainPolicy = NULL;
501
0
    }
502
503
0
    sk_X509_POLICY_NODE_sort(next->nodes);
504
0
    ok = 1;
505
0
  }
506
507
0
err:
508
0
  if (!ok) {
509
0
    x509_policy_level_free(next);
510
0
    next = NULL;
511
0
  }
512
513
0
  sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free);
514
0
  sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
515
0
  return next;
516
0
}
517
518
// apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum
519
// of its current value and |skip_certs|. It returns one on success and zero if
520
// |skip_certs| is negative.
521
0
static int apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) {
522
0
  if (skip_certs == NULL) {
523
0
    return 1;
524
0
  }
525
526
  // TODO(https://crbug.com/boringssl/443): Move this check into the parser.
527
0
  if (skip_certs->type & V_ASN1_NEG) {
528
0
    OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION);
529
0
    return 0;
530
0
  }
531
532
  // If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|.
533
0
  uint64_t u64;
534
0
  if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) {
535
0
    *value = (size_t)u64;
536
0
  }
537
0
  ERR_clear_error();
538
0
  return 1;
539
0
}
540
541
// process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and
542
// |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit
543
// anyPolicy extensions. It returns one on success and zero on error. This
544
// implements steps (i) and (j) of RFC 5280, section 6.1.4.
545
static int process_policy_constraints(const X509 *x509, size_t *explicit_policy,
546
                                      size_t *policy_mapping,
547
0
                                      size_t *inhibit_any_policy) {
548
0
  int critical;
549
0
  POLICY_CONSTRAINTS *constraints = reinterpret_cast<POLICY_CONSTRAINTS *>(
550
0
      X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL));
551
0
  if (constraints == NULL && critical != -1) {
552
0
    return 0;
553
0
  }
554
0
  if (constraints != NULL) {
555
0
    if (constraints->requireExplicitPolicy == NULL &&
556
0
        constraints->inhibitPolicyMapping == NULL) {
557
      // Per RFC 5280, section 4.2.1.11, at least one of the fields must be
558
      // present.
559
0
      OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION);
560
0
      POLICY_CONSTRAINTS_free(constraints);
561
0
      return 0;
562
0
    }
563
0
    int ok =
564
0
        apply_skip_certs(constraints->requireExplicitPolicy, explicit_policy) &&
565
0
        apply_skip_certs(constraints->inhibitPolicyMapping, policy_mapping);
566
0
    POLICY_CONSTRAINTS_free(constraints);
567
0
    if (!ok) {
568
0
      return 0;
569
0
    }
570
0
  }
571
572
0
  ASN1_INTEGER *inhibit_any_policy_ext = reinterpret_cast<ASN1_INTEGER *>(
573
0
      X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL));
574
0
  if (inhibit_any_policy_ext == NULL && critical != -1) {
575
0
    return 0;
576
0
  }
577
0
  int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy);
578
0
  ASN1_INTEGER_free(inhibit_any_policy_ext);
579
0
  return ok;
580
0
}
581
582
// has_explicit_policy returns one if the set of authority-space policy OIDs
583
// |levels| has some non-empty intersection with |user_policies|, and zero
584
// otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This
585
// function modifies |levels| and should only be called at the end of policy
586
// evaluation.
587
static int has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels,
588
0
                               const STACK_OF(ASN1_OBJECT) *user_policies) {
589
0
  assert(user_policies == NULL || sk_ASN1_OBJECT_is_sorted(user_policies));
590
591
  // Step (g.i). If the policy graph is empty, the intersection is empty.
592
0
  size_t num_levels = sk_X509_POLICY_LEVEL_num(levels);
593
0
  X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1);
594
0
  if (x509_policy_level_is_empty(level)) {
595
0
    return 0;
596
0
  }
597
598
  // If |user_policies| is empty, we interpret it as having a single anyPolicy
599
  // value. The caller may also have supplied anyPolicy explicitly.
600
0
  int user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) == 0;
601
0
  for (size_t i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) {
602
0
    if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) {
603
0
      user_has_any_policy = 1;
604
0
      break;
605
0
    }
606
0
  }
607
608
  // Step (g.ii). If the policy graph is not empty and the user set contains
609
  // anyPolicy, the intersection is the entire (non-empty) graph.
610
0
  if (user_has_any_policy) {
611
0
    return 1;
612
0
  }
613
614
  // Step (g.iii) does not delete anyPolicy nodes, so if the graph has
615
  // anyPolicy, some explicit policy will survive. The actual intersection may
616
  // synthesize some nodes in step (g.iii.3), but we do not return the policy
617
  // list itself, so we skip actually computing this.
618
0
  if (level->has_any_policy) {
619
0
    return 1;
620
0
  }
621
622
  // We defer pruning the tree, so as we look for nodes with parent anyPolicy,
623
  // step (g.iii.1), we must limit to nodes reachable from the bottommost level.
624
  // Start by marking each of those nodes as reachable.
625
0
  for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
626
0
    sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1;
627
0
  }
628
629
0
  for (size_t i = num_levels - 1; i < num_levels; i--) {
630
0
    level = sk_X509_POLICY_LEVEL_value(levels, i);
631
0
    for (size_t j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) {
632
0
      X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, j);
633
0
      if (!node->reachable) {
634
0
        continue;
635
0
      }
636
0
      if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) {
637
        // |node|'s parent is anyPolicy and is part of "valid_policy_node_set".
638
        // If it exists in |user_policies|, the intersection is non-empty and we
639
        // can return immediately.
640
0
        if (sk_ASN1_OBJECT_find(user_policies, /*out_index=*/NULL,
641
0
                                node->policy)) {
642
0
          return 1;
643
0
        }
644
0
      } else if (i > 0) {
645
        // |node|'s parents are concrete policies. Mark the parents reachable,
646
        // to be inspected by the next loop iteration.
647
0
        X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, i - 1);
648
0
        for (size_t k = 0; k < sk_ASN1_OBJECT_num(node->parent_policies); k++) {
649
0
          X509_POLICY_NODE *parent = x509_policy_level_find(
650
0
              prev, sk_ASN1_OBJECT_value(node->parent_policies, k));
651
0
          if (parent != NULL) {
652
0
            parent->reachable = 1;
653
0
          }
654
0
        }
655
0
      }
656
0
    }
657
0
  }
658
659
0
  return 0;
660
0
}
661
662
static int asn1_object_cmp(const ASN1_OBJECT *const *a,
663
0
                           const ASN1_OBJECT *const *b) {
664
0
  return OBJ_cmp(*a, *b);
665
0
}
666
667
int X509_policy_check(const STACK_OF(X509) *certs,
668
                      const STACK_OF(ASN1_OBJECT) *user_policies,
669
0
                      unsigned long flags, X509 **out_current_cert) {
670
0
  *out_current_cert = NULL;
671
0
  int ret = X509_V_ERR_OUT_OF_MEM;
672
0
  X509_POLICY_LEVEL *level = NULL;
673
0
  STACK_OF(X509_POLICY_LEVEL) *levels = NULL;
674
0
  STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL;
675
0
  size_t num_certs = sk_X509_num(certs);
676
677
  // Skip policy checking if the chain is just the trust anchor.
678
0
  if (num_certs <= 1) {
679
0
    return X509_V_OK;
680
0
  }
681
682
  // See RFC 5280, section 6.1.2, steps (d) through (f).
683
0
  size_t explicit_policy =
684
0
      (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1;
685
0
  size_t inhibit_any_policy =
686
0
      (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1;
687
0
  size_t policy_mapping = (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1;
688
689
0
  levels = sk_X509_POLICY_LEVEL_new_null();
690
0
  if (levels == NULL) {
691
0
    goto err;
692
0
  }
693
694
0
  for (size_t i = num_certs - 2; i < num_certs; i--) {
695
0
    X509 *cert = sk_X509_value(certs, i);
696
0
    if (!x509v3_cache_extensions(cert)) {
697
0
      goto err;
698
0
    }
699
0
    const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0;
700
701
0
    if (level == NULL) {
702
0
      assert(i == num_certs - 2);
703
0
      level = x509_policy_level_new();
704
0
      if (level == NULL) {
705
0
        goto err;
706
0
      }
707
0
      level->has_any_policy = 1;
708
0
    }
709
710
    // RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| is
711
    // computed as in step (d.2).
712
0
    const int any_policy_allowed =
713
0
        inhibit_any_policy > 0 || (i > 0 && is_self_issued);
714
0
    if (!process_certificate_policies(cert, level, any_policy_allowed)) {
715
0
      ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
716
0
      *out_current_cert = cert;
717
0
      goto err;
718
0
    }
719
720
    // RFC 5280, section 6.1.3, step (f).
721
0
    if (explicit_policy == 0 && x509_policy_level_is_empty(level)) {
722
0
      ret = X509_V_ERR_NO_EXPLICIT_POLICY;
723
0
      goto err;
724
0
    }
725
726
    // Insert into the list.
727
0
    if (!sk_X509_POLICY_LEVEL_push(levels, level)) {
728
0
      goto err;
729
0
    }
730
0
    X509_POLICY_LEVEL *current_level = level;
731
0
    level = NULL;
732
733
    // If this is not the leaf certificate, we go to section 6.1.4. If it
734
    // is the leaf certificate, we go to section 6.1.5 instead.
735
0
    if (i != 0) {
736
      // RFC 5280, section 6.1.4, steps (a) and (b).
737
0
      level = process_policy_mappings(cert, current_level, policy_mapping > 0);
738
0
      if (level == NULL) {
739
0
        ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
740
0
        *out_current_cert = cert;
741
0
        goto err;
742
0
      }
743
0
    }
744
745
    // RFC 5280, section 6.1.4, step (h-j) for non-leaves, and section 6.1.5,
746
    // step (a-b) for leaves. In the leaf case, RFC 5280 says only to update
747
    // |explicit_policy|, but |policy_mapping| and |inhibit_any_policy| are no
748
    // longer read at this point, so we use the same process.
749
0
    if (i == 0 || !is_self_issued) {
750
0
      if (explicit_policy > 0) {
751
0
        explicit_policy--;
752
0
      }
753
0
      if (policy_mapping > 0) {
754
0
        policy_mapping--;
755
0
      }
756
0
      if (inhibit_any_policy > 0) {
757
0
        inhibit_any_policy--;
758
0
      }
759
0
    }
760
0
    if (!process_policy_constraints(cert, &explicit_policy, &policy_mapping,
761
0
                                    &inhibit_any_policy)) {
762
0
      ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
763
0
      *out_current_cert = cert;
764
0
      goto err;
765
0
    }
766
0
  }
767
768
  // RFC 5280, section 6.1.5, step (g). We do not output the policy set, so it
769
  // is only necessary to check if the user-constrained-policy-set is not empty.
770
0
  if (explicit_policy == 0) {
771
    // Build a sorted copy of |user_policies| for more efficient lookup.
772
0
    if (user_policies != NULL) {
773
0
      user_policies_sorted = sk_ASN1_OBJECT_dup(user_policies);
774
0
      if (user_policies_sorted == NULL) {
775
0
        goto err;
776
0
      }
777
0
      sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, asn1_object_cmp);
778
0
      sk_ASN1_OBJECT_sort(user_policies_sorted);
779
0
    }
780
781
0
    if (!has_explicit_policy(levels, user_policies_sorted)) {
782
0
      ret = X509_V_ERR_NO_EXPLICIT_POLICY;
783
0
      goto err;
784
0
    }
785
0
  }
786
787
0
  ret = X509_V_OK;
788
789
0
err:
790
0
  x509_policy_level_free(level);
791
  // |user_policies_sorted|'s contents are owned by |user_policies|, so we do
792
  // not use |sk_ASN1_OBJECT_pop_free|.
793
0
  sk_ASN1_OBJECT_free(user_policies_sorted);
794
0
  sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free);
795
0
  return ret;
796
0
}