<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.2 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-lamps-x509-policy-graph-02" category="std" consensus="true" submissionType="IETF" updates="5280" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.18.2 -->
  <front>
    <title abbrev="Updates to X.509 Policy Validation">Updates to X.509 Policy Validation</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-lamps-x509-policy-graph-02"/>
    <author initials="D." surname="Benjamin" fullname="David Benjamin">
      <organization>Google LLC</organization>
      <address>
        <email>davidben@google.com</email>
      </address>
    </author>
    <date year="2023" month="November" day="21"/>
    <area>Security</area>
    <workgroup>Limited Additional Mechanisms for PKIX and SMIME</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 47?>

<t>This document updates RFC 5280 to replace the algorithm for X.509 policy
validation with an equivalent, more efficient algorithm. The original algorithm
built a structure which scaled exponentially in the worst case, leaving
implementations vulnerable to denial-of-service attacks.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Limited Additional Mechanisms for PKIX and SMIME Working Group mailing list (spasm@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/spasm/"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/davidben/x509-policy-graph"/>.</t>
    </note>
  </front>
  <middle>
    <?line 54?>

<section anchor="introduction">
      <name>Introduction</name>
      <t><xref target="RFC5280"/> defines a suite of extensions for specifying certificate policies,
along with a mechanism for mapping policies between subject and issuer policy
domains in cross-certificates. This mechanism, when evaluated according to the
algorithm in <xref section="6.1" sectionFormat="comma" target="RFC5280"/> produces a policy tree, describing
policies asserted by each certificate, and mappings between them. This tree can
grow exponentially in the depth of the certification path. This cost asymmetry
can lead to a denial-of-service vulnerability in X.509-based applications, such
as <xref target="CVE-2023-0464"/> and <xref target="CVE-2023-23524"/>.</t>
      <t><xref target="dos"/> describes this vulnerability. <xref target="policy-graph"/> describes the primary
mitigation for this vulnerability, a replacement for the policy tree structure.
<xref target="updates"/> provides updates to <xref target="RFC5280"/> which implement this change.
Finally, <xref target="other-mitigations"/> discusses alternative mitigation strategies for
X.509 applications.</t>
      <section anchor="summary-of-changes-from-rfc-5280">
        <name>Summary of Changes from RFC 5280</name>
        <t>The algorithm for processing certificate policies and policy mappings is
replaced with one which builds an equivalent, but much more efficient structure.
This new algorithm does not change the validity status of any certification
path, nor which certificate policies are valid for it.</t>
      </section>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>
when, and only when, they appear in all capitals, as shown here.</t>
    </section>
    <section anchor="dos">
      <name>Denial of Service Vulnerability</name>
      <t>This section discusses how the path validation algorithm defined in
<xref section="6.1.2" sectionFormat="of" target="RFC5280"/> can lead to a denial-of-service vulnerability in
X.509-based applications.</t>
      <section anchor="policy-trees">
        <name>Policy Trees</name>
        <t><xref section="6.1.2" sectionFormat="of" target="RFC5280"/> constructs the <tt>valid_policy_tree</tt>, a tree of
certificate policies, during certification path validation.
The nodes at any given depth in the tree correspond to
policies asserted by a certificate in the certification path. A node's
parent policy is the policy in the issuer certificate which was mapped to this
policy, and a node's children are the policies it was mapped to in the subject
certificate.</t>
        <t>For example, suppose a certification path contains:</t>
        <ul spacing="normal">
          <li>
            <t>An intermediate certificate which asserts policy object identifiers (OIDs)
OID1, OID2, and OID5. It contains mappings OID1 to OID3, and OID1 to OID4.</t>
          </li>
          <li>
            <t>An end-entity certificate which asserts policy OIDs OID2, OID3, and OID6.</t>
          </li>
        </ul>
        <t>This would result in the tree shown in <xref target="basic-tree"/>.</t>
        <figure anchor="basic-tree">
          <name>An Example X.509 Policy Tree</name>
          <artwork type="ascii-art"><![CDATA[
                         +-----------+
        Root:            | anyPolicy |
                         +-----------+
                         |{anyPolicy}|
                         +-----------+
                          /          \
                         /            \
                        v              v
               +------------+      +------------+
Intermediate:  |    OID1    |      |    OID2    |
               +------------+      +------------+
               |{OID3, OID4}|      |   {OID2}   |
               +------------+      +------------+
                     |                   |
                     |                   |
                     v                   v
               +------------+      +------------+
  End-entity:  |    OID3    |      |    OID2    |
               +------------+      +------------+
]]></artwork>
        </figure>
        <t>The complete algorithm for building this structure is described in steps (d),
(e), and (f) of <xref section="6.1.3" sectionFormat="of" target="RFC5280"/>, steps (h), (i), (j) of <xref section="6.1.4" sectionFormat="of" target="RFC5280"/>, and steps (a), (b), and (g) of <xref section="6.1.5" sectionFormat="of" target="RFC5280"/>.</t>
      </section>
      <section anchor="exponential-growth">
        <name>Exponential Growth</name>
        <t>The <tt>valid_policy_tree</tt> grows exponentially in the worst case. In
step (d.1) of <xref section="6.1.3" sectionFormat="of" target="RFC5280"/>, a single policy P can produce
multiple child nodes if multiple issuer policies map to P. This can cause the
tree size to increase in size multiplicatively at each level.</t>
        <t>In particular, consider a certificate chain where every intermediate certificate
asserts policies OID1 and OID2, and then contains the full Cartesian product of
mappings:</t>
        <ul spacing="normal">
          <li>
            <t>OID1 maps to OID1</t>
          </li>
          <li>
            <t>OID1 maps to OID2</t>
          </li>
          <li>
            <t>OID2 maps to OID1</t>
          </li>
          <li>
            <t>OID2 maps to OID2</t>
          </li>
        </ul>
        <t>At each depth, the tree would double in size.
For example, if there are two intermediate certificates and one end-entity certificate, the resulting tree would be as depicted in <xref target="exponential-tree"/>.</t>
        <figure anchor="exponential-tree">
          <name>An Example X.509 Policy Tree with Exponential Growth</name>
          <artwork type="ascii-art"><![CDATA[
                        +-----------------------+
                        |        anyPolicy      |
                        +-----------------------+
                        |       {anyPolicy}     |
                        +-----------------------+
                         /                     \
                        /                       \
                       v                         v
            +------------+                      +------------+
            |    OID1    |                      |    OID2    |
            +------------+                      +------------+
            |{OID1, OID2}|                      |{OID1, OID2}|
            +------------+                      +------------+
             /         \                          /         \
            /           \                        /           \
           v             v                      v             v
  +------------+    +------------+    +------------+    +------------+
  |    OID1    |    |    OID2    |    |    OID1    |    |    OID2    |
  +------------+    +------------+    +------------+    +------------+
  |{OID1, OID2}|    |{OID1, OID2}|    |{OID1, OID2}|    |{OID1, OID2}|
  +------------+    +------------+    +------------+    +------------+
    |       |         |       |         |       |         |       |
    v       v         v       v         v       v         v       v
+------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+
| OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 |
+------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+
]]></artwork>
        </figure>
      </section>
      <section anchor="attack-vector">
        <name>Attack Vector</name>
        <t>An attacker can use the exponential growth to mount a denial-of-service attack against
an X.509-based application. The attacker sends certificate chain as in <xref target="exponential-growth"/> and
triggers the target application's certificate validation process. For example,
the target application may be a TLS <xref target="RFC8446"/> server that performs client
certificate validation. The target
application will consume far more resources processing the input than the
attacker consumed to send it, preventing it from servicing other clients.</t>
      </section>
    </section>
    <section anchor="avoiding-exponential-growth">
      <name>Avoiding Exponential Growth</name>
      <t>The denial-of-service vulnerability described in <xref target="dos"/> can be mitigated by implementing a policy graph structure, described in this section.</t>
      <t>Compared the original policy tree structure described in <xref target="RFC5280"/>, the policy graph grows linearly instead of exponentially.
This document deprecates the original policy tree structure.
X.509 implementations SHOULD instead perform policy validation by building a policy graph.
This mitigates the denial-of-service attack by removing the asymmetric cost in policy validation.</t>
      <t>While this replacement process computes the same policies as in <xref target="RFC5280"/>, one of the outputs is in a different form.
See <xref target="outputs"/> for details.</t>
      <section anchor="policy-graph">
        <name>Policy Graphs</name>
        <t>The tree structure from <xref target="RFC5280"/> is an unnecessarily inefficient
representation of a certification path's policy mappings. A single certificate
policy may correspond to multiple nodes, but each node is identical, with identical
children. This redundancy is the source of the exponential growth described in
<xref target="exponential-growth"/>.</t>
        <t>A policy graph is a directed acyclic graph of policy nodes.
Where <xref target="RFC5280"/> adds multiple duplicate nodes, a policy graph adds a single node with multiple parents.
See <xref target="updates"/> for the procedure for building this structure.
<xref target="exponential-tree-as-graph"/> shows the updated representation of the example in <xref target="exponential-tree"/>.</t>
        <figure anchor="exponential-tree-as-graph">
          <name>A More Efficient Representation of an X.509 Policy Tree</name>
          <artwork type="ascii-art"><![CDATA[
              +-----------+
              | anyPolicy |
              +-----------+
              |{anyPolicy}|
              +-----------+
              /           \
             /             \
            v               v
     +------------+  +------------+
     |    OID1    |  |    OID2    |
     +------------+  +------------+
     |{OID1, OID2}|  |{OID1, OID2}|
     +------------+  +------------+
          |      \    /     |
          |       \  /      |
          |        \/       |
          |        /\       |
          |       /  \      |
          v      v    v     v
     +------------+  +------------+
     |    OID1    |  |    OID2    |
     +------------+  +------------+
     |{OID1, OID2}|  |{OID1, OID2}|
     +------------+  +------------+
          |      \    /     |
          |       \  /      |
          |        \/       |
          |        /\       |
          |       /  \      |
          v      v    v     v
     +------------+  +------------+
     |    OID1    |  |    OID2    |
     +------------+  +------------+
]]></artwork>
        </figure>
        <t>This graph's size is bounded linearly by the total number of certificate
policies (<xref section="4.2.1.4" sectionFormat="of" target="RFC5280"/>) and policy mappings (<xref section="4.2.1.5" sectionFormat="of" target="RFC5280"/>). The policy tree from <xref target="RFC5280"/> is the tree of all paths from the root to a leaf in the policy graph,
so no information is lost in the graph representation.</t>
      </section>
      <section anchor="outputs">
        <name>Verification Outputs</name>
        <t><xref section="6.1.6" sectionFormat="of" target="RFC5280"/> describes the entire <tt>valid_policy_tree</tt> structure as
an output of the verification process. Section 12.2 of <xref target="X.509"/> instead only
outputs the authorities-constrained policies, the user-constrained policies,
and their associated qualifiers.</t>
        <t>An implementation which outputs the entire tree may be unable switch the format
to a more efficient one, as described in <xref target="policy-graph"/>. X.509 implementations
SHOULD NOT output the entire <tt>valid_policy_tree</tt> structure and instead SHOULD
limit output to just the set of authorities-constrained and/or user-constrained
policies, as described in <xref target="X.509"/>.</t>
        <t>X.509 implementations are additionally
RECOMMENDED to omit policy qualifiers from the output, as this simplifies the
process. Note <xref section="4.2.1.4" sectionFormat="of" target="RFC5280"/> conversely recommends that
certificate authorities omit policy qualifiers from policy information terms.
This document reiterates this and RECOMMENDS that certificate authorities omit
the policyQualifiers field in PolicyInformation structures.</t>
      </section>
    </section>
    <section anchor="updates">
      <name>Updates to RFC 5280</name>
      <t>This section provides updates to <xref target="RFC5280"/>. This implements the changes
described in <xref target="avoiding-exponential-growth"/>.</t>
      <section anchor="updates-to-section-61">
        <name>Updates to Section 6.1</name>
        <t>This update replaces a paragraph of <xref section="6.1" sectionFormat="of" target="RFC5280"/> as follows:</t>
        <t>OLD:</t>
        <ul empty="true">
          <li>
            <t>A particular certification path may not, however, be appropriate for
  all applications.  Therefore, an application MAY augment this
  algorithm to further limit the set of valid paths.  The path
  validation process also determines the set of certificate policies
  that are valid for this path, based on the certificate policies
  extension, policy mappings extension, policy constraints extension,
  and inhibit anyPolicy extension.  To achieve this, the path
  validation algorithm constructs a valid policy tree.  If the set of
  certificate policies that are valid for this path is not empty, then
  the result will be a valid policy tree of depth n, otherwise the
  result will be a null valid policy tree.</t>
          </li>
        </ul>
        <t>NEW:</t>
        <ul empty="true">
          <li>
            <t>A particular certification path may not, however, be appropriate for
  all applications.  Therefore, an application MAY augment this
  algorithm to further limit the set of valid paths.  The path
  validation process also determines the set of certificate policies
  that are valid for this path, based on the certificate policies
  extension, policy mappings extension, policy constraints extension,
  and inhibit anyPolicy extension.  To achieve this, the path
  validation algorithm constructs a valid policy set, which may be empty if
  no certificate policies are valid for this path.</t>
          </li>
        </ul>
      </section>
      <section anchor="updates-to-section-612">
        <name>Updates to Section 6.1.2</name>
        <t>This update replaces entry (a) of <xref section="6.1.2" sectionFormat="of" target="RFC5280"/> with the following text:</t>
        <ol spacing="normal" type="(%c)"><li>
            <t><tt>valid_policy_graph</tt>:  A directed acyclic graph of certificate
policies with their optional qualifiers; each of the leaves
of the graph represents a valid policy at this stage in the
certification path validation.  If valid policies exist at
this stage in the certification path validation, the depth of
the graph is equal to the number of certificates in the chain
that have been processed.  If valid policies do not exist at
this stage in the certification path validation, the graph is
set to NULL.  Once the graph is set to NULL, policy processing
ceases.  Implementations MAY omit qualifiers if not returned
in the output.  </t>
            <t>
Each node in the <tt>valid_policy_graph</tt> includes three data objects:
the valid policy, a set of associated policy qualifiers, and a set of
one or more expected policy values.  </t>
            <t>
Nodes in the graph can be divided into depths, numbered starting from zero.
A node at depth x can have zero or more children at depth x+1, with the
exception of depth zero, one or more parents at depth x-1. No other edges
between nodes may exist.  </t>
            <t>
If the node is at depth x, the components of the node have
the following semantics:  </t>
            <ol spacing="normal" type="(%d)"><li>
                <t>The <tt>valid_policy</tt> is a single policy OID representing a valid policy for the path of length x.</t>
              </li>
              <li>
                <t>The <tt>qualifier_set</tt> is a set of policy qualifiers associated with the valid policy in certificate x.
It is only necessary to maintain this field if policy qualifiers are returned to the application.
See Section 6.1.5, step (g).</t>
              </li>
              <li>
                <t>The <tt>expected_policy_set</tt> contains one or more policy OIDs that would satisfy this policy in the certificate x+1.</t>
              </li>
            </ol>
            <t>
The initial value of the <tt>valid_policy_graph</tt> is a single node with
<tt>valid_policy</tt> anyPolicy, an empty <tt>qualifier_set</tt>, and an
<tt>expected_policy_set</tt> with the single value anyPolicy.  This node is
considered to be at depth zero.  </t>
            <t>
The graph additionally satisfies the following invariants:  </t>
            <ul spacing="normal">
              <li>
                <t>For any depth x and policy OID P-OID, there is at most one node at depth x whose <tt>valid_policy</tt> is P-OID.</t>
              </li>
              <li>
                <t>The <tt>expected_policy_set</tt> of a node whose <tt>valid_policy</tt> is anyPolicy is always {anyPolicy}.</t>
              </li>
              <li>
                <t>A node at depth x whose <tt>valid_policy</tt> is anyPolicy, except for the one at
depth zero, always has exactly one parent: a node at depth x-1 whose
<tt>valid_policy</tt> is also anyPolicy.</t>
              </li>
              <li>
                <t>Each node at depth greater than 0 has either one or more parent nodes whose <tt>valid_policy</tt> is not anyPolicy,
or a single parent node whose <tt>valid_policy</tt> is anyPolicy.
That is, a node cannot simultaneously be a child of both anyPolicy and some non-anyPolicy OID.</t>
              </li>
            </ul>
            <t>
<xref target="graph-initial"/> is a graphic representation of the initial state of the
<tt>valid_policy_graph</tt>.  Additional figures will use this format to
describe changes in the <tt>valid_policy_graph</tt> during path processing.  </t>
            <figure anchor="graph-initial">
              <name>Initial value of the valid_policy_graph State Variable</name>
              <artwork type="ascii-art"><![CDATA[
    +----------------+
    |   anyPolicy    |   <---- valid_policy
    +----------------+
    |       {}       |   <---- qualifier_set
    +----------------+
    |  {anyPolicy}   |   <---- expected_policy_set
    +----------------+
]]></artwork>
            </figure>
          </li>
        </ol>
      </section>
      <section anchor="updates-to-section-613">
        <name>Updates to Section 6.1.3</name>
        <t>This update replaces steps (d), (e), and (f) of <xref section="6.1.3" sectionFormat="of" target="RFC5280"/> with the following text:</t>
        <ol spacing="normal" type="(%c)" start="4"><li>
            <t>If the certificate policies extension is present in the
certificate and the <tt>valid_policy_graph</tt> is not NULL, process
the policy information by performing the following steps in
order:  </t>
            <ol spacing="normal" type="(%d)"><li>
                <t>For each policy P not equal to anyPolicy in the certificate policies extension,
let P-OID denote the OID for policy P and P-Q denote the qualifier set for policy P.
Perform the following steps in order:      </t>
                <ol spacing="normal" type="(%i)"><li>
                    <t>Let <tt>parent_nodes</tt> be the nodes at depth i-1 in the <tt>valid_policy_graph</tt> where P-OID is in the <tt>expected_policy_set</tt>.
If <tt>parent_nodes</tt> is not empty, create a child node as follows:
set the <tt>valid_policy</tt> to P-OID, set the <tt>qualifier_set</tt> to P-Q, set the <tt>expected_policy_set</tt> to {P-OID}, and set the parent nodes to <tt>parent_nodes</tt>.          </t>
                    <t>
For example, consider a <tt>valid_policy_graph</tt> with a node of depth i-1 where the <tt>expected_policy_set</tt> is {Gold, White},
and a second node where the <tt>expected_policy_set</tt> is {Gold, Yellow}.
Assume the certificate policies Gold and Silver appear in the certificate policies extension of certificate i.
The Gold policy is matched, but the Silver policy is not.
This rule will generate a child node of depth i for the Gold policy.
The result is shown as <xref target="exact-match"/>.          </t>
                    <figure anchor="exact-match">
                      <name>Processing an Exact Match</name>
                      <artwork type="ascii-art"><![CDATA[
    +-----------------+      +-----------------+
    |       Red       |      |       Blue      |
    +-----------------+      +-----------------+
    |       {}        |      |       {}        |   depth i-1
    +-----------------+      +-----------------+
    |  {Gold, White}  |      |  {Gold, Yellow} |
    +-----------------+      +-----------------+
                \                   /
                 \                 /
                  \               /
                   v             v
                 +-----------------+
                 |      Gold       |
                 +-----------------+
                 |       {}        |   depth i
                 +-----------------+
                 |     {Gold}      |
                 +-----------------+
]]></artwork>
                    </figure>
                  </li>
                  <li>
                    <t>If there was no match in step (i) and the <tt>valid_policy_graph</tt> includes a node of depth i-1 with the <tt>valid_policy</tt> anyPolicy,
generate a child node with the following values:
set the <tt>valid_policy</tt> to P-OID, set the <tt>qualifier_set</tt> to P-Q, set the <tt>expected_policy_set</tt> to {P-OID},
and set the parent node to the anyPolicy node at depth i-1.          </t>
                    <t>
For example, consider a <tt>valid_policy_graph</tt> with a node
of depth i-1 where the <tt>valid_policy</tt> is anyPolicy.
Assume the certificate policies Gold and Silver appear
in the certificate policies extension of certificate
i.  The Gold policy does not have a qualifier, but the
Silver policy has the qualifier Q-Silver.  If Gold and
Silver were not matched in (i) above, this rule will
generate two child nodes of depth i, one for each
policy.  The result is shown as <xref target="unmatched-anypolicy"/>.          </t>
                    <figure anchor="unmatched-anypolicy">
                      <name>Processing Unmatched Policies when a Leaf Node Specifies anyPolicy</name>
                      <artwork type="ascii-art"><![CDATA[
                  +-----------------+
                  |    anyPolicy    |
                  +-----------------+
                  |       {}        |
                  +-----------------+   depth i-1
                  |   {anyPolicy}   |
                  +-----------------+
                     /           \
                    /             \
                   /               \
                  /                 \
    +-----------------+          +-----------------+
    |      Gold       |          |     Silver      |
    +-----------------+          +-----------------+
    |       {}        |          |   {Q-Silver}    |   depth i
    +-----------------+          +-----------------+
    |     {Gold}      |          |    {Silver}     |
    +-----------------+          +-----------------+
]]></artwork>
                    </figure>
                  </li>
                </ol>
              </li>
              <li>
                <t>If the certificate policies extension includes the policy anyPolicy with the qualifier set AP-Q and either (a)
<tt>inhibit_anyPolicy</tt> is greater than 0 or (b) i&lt;n and the certificate is self-issued, then:      </t>
                <t>
For each policy OID P-OID (including anyPolicy) which appears in the <tt>expected_policy_set</tt> of some node in the <tt>valid_policy_graph</tt> for depth i-1,
if P-OID does not appear as the <tt>valid_policy</tt> of some node at depth i, create a single child node with the following values:
set the <tt>valid_policy</tt> to P-OID, set the <tt>qualifier_set</tt> to AP-Q, set the <tt>expected_policy_set</tt> to {P-OID},
and set the parents to the nodes at depth i-1 where P-OID appears in <tt>expected_policy_set</tt>.      </t>
                <t>
This is equivalent to running step (1) above, as if the certificate policies extension contained a policy with OID P-OID and qualifier set AP-Q.      </t>
                <t>
For example, consider a <tt>valid_policy_graph</tt> with a node of depth i-1 where the <tt>expected_policy_set</tt> is {Gold, Silver},
and a second node of depth i-1 where the <tt>expected_policy_set</tt> is {Gold, Bronze}.
Assume anyPolicy appears in the certificate policies extension of certificate i with policy qualifiers AP-Q, but Gold and Silver do not appear.
This rule will generate two child nodes of depth i, one for each policy.
The result is shown below as <xref target="anypolicy-in-extension"/>.      </t>
                <figure anchor="anypolicy-in-extension">
                  <name>Processing Unmatched Policies When the Certificate Policies Extension Specifies anyPolicy</name>
                  <artwork type="ascii-art"><![CDATA[
    +-----------------+   +-----------------+
    |       Red       |   |       Blue      |
    +-----------------+   +-----------------+
    |       {}        |   |       {}        |   depth i-1
    +-----------------+   +-----------------+
    |  {Gold, Silver} |   |  {Gold, Bronze} |
    +-----------------+   +-----------------+
            |         \            |
            |          \           |
            |           \          |
            |            \         |
            |             \        |
            v              v       v
    +-----------------+   +-----------------+
    |     Silver      |   |       Gold      |
    +-----------------+   +-----------------+
    |     {AP-Q}      |   |      {AP-Q}     |   depth i
    +-----------------+   +-----------------+
    |    {Silver}     |   |      {Gold}     |
    +-----------------+   +-----------------+
]]></artwork>
                </figure>
              </li>
              <li>
                <t>If there is a node in the <tt>valid_policy_graph</tt> of depth i-1 or less without any child nodes, delete that node.
Repeat this step until there are no nodes of depth i-1 or less without children.      </t>
                <t>
For example, consider the valid_policy_graph shown in <xref target="pruning"/> below.
The two nodes at depth i-1 that are marked with an 'X' have no children, and they are deleted.
Applying this rule to the resulting graph will cause the nodes at depth i-2 that is marked with a 'Y' to be deleted.
In the resulting graph, there are no nodes of depth i-1 or less without children, and this step is complete.      </t>
                <figure anchor="pruning">
                  <name>Pruning the valid_policy_graph</name>
                  <artwork type="ascii-art"><![CDATA[
                  +-----------+
                  |           | depth i-3
                  +-----------+
                  /     |     \
                 /      |      \
                /       |       \
    +-----------+ +-----------+ +-----------+
    |           | |           | |     Y     | depth i-2
    +-----------+ +-----------+ +-----------+
          |     \       |             |
          |      \      |             |
          |       \     |             |
    +-----------+ +-----------+ +-----------+
    |     X     | |           | |     X     | depth i-1
    +-----------+ +-----------+ +-----------+
                   /    |    \
                  /     |     \
                 /      |      \
    +-----------+ +-----------+ +-----------+
    |           | |           | |           | depth i
    +-----------+ +-----------+ +-----------+
]]></artwork>
                </figure>
              </li>
            </ol>
          </li>
          <li>
            <t>If the certificate policies extension is not present, set the <tt>valid_policy_graph</tt> to NULL.</t>
          </li>
          <li>
            <t>Verify that either <tt>explicit_policy</tt> is greater than 0 or the <tt>valid_policy_graph</tt> is not equal to NULL;</t>
          </li>
        </ol>
      </section>
      <section anchor="updates-to-section-614">
        <name>Updates to Section 6.1.4</name>
        <t>This update replaces step (b) of <xref section="6.1.4" sectionFormat="of" target="RFC5280"/> with the following text:</t>
        <ol spacing="normal" type="(%c)" start="2"><li>
            <t>If a policy mappings extension is present, then for each issuerDomainPolicy ID-P in the policy mappings extension:  </t>
            <ol spacing="normal" type="(%d)"><li>
                <t>If the policy_mapping variable is greater than 0 and there is a
node in the <tt>valid_policy_graph</tt> of depth i where ID-P is the
valid_policy, set <tt>expected_policy_set</tt> to the set of
subjectDomainPolicy values that are specified as
equivalent to ID-P by the policy mappings extension.</t>
              </li>
              <li>
                <t>If the policy_mapping variable is greater than 0,
no node of depth i in the <tt>valid_policy_graph</tt> has a
<tt>valid_policy</tt> of ID-P, but there is a node of depth i with a
<tt>valid_policy</tt> of anyPolicy, then generate a child node of
the node of depth i-1 that has a <tt>valid_policy</tt> of anyPolicy
as follows:      </t>
                <ol spacing="normal" type="(%i)"><li>
                    <t>set the <tt>valid_policy</tt> to ID-P;</t>
                  </li>
                  <li>
                    <t>set the <tt>qualifier_set</tt> to the qualifier set of the
policy anyPolicy in the certificate policies
extension of certificate i; and</t>
                  </li>
                  <li>
                    <t>set the <tt>expected_policy_set</tt> to the set of
subjectDomainPolicy values that are specified as
equivalent to ID-P by the policy mappings extension.</t>
                  </li>
                </ol>
              </li>
              <li>
                <t>If the <tt>policy_mapping</tt> variable is equal to 0:      </t>
                <ol spacing="normal" type="(%i)"><li>
                    <t>delete the node, if any, of depth i in the <tt>valid_policy_graph</tt> where ID-P is the <tt>valid_policy</tt>.</t>
                  </li>
                  <li>
                    <t>If there is a node in the <tt>valid_policy_graph</tt> of depth
i-1 or less without any child nodes, delete that
node.  Repeat this step until there are no nodes of
depth i-1 or less without children.</t>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
      </section>
      <section anchor="updates-to-section-615">
        <name>Updates to Section 6.1.5</name>
        <t>This update replaces step (g) of <xref section="6.1.5" sectionFormat="of" target="RFC5280"/> with the following text:</t>
        <ol spacing="normal" type="(%c)" start="7"><li>
            <t>Calculate the <tt>user_constrained_policy_set</tt> as follows.
The <tt>user_constrained_policy_set</tt> is a set of policy OIDs, along with associated policy qualifiers.  </t>
            <ol spacing="normal" type="(%d)"><li>
                <t>If the <tt>valid_policy_graph</tt> is NULL, set <tt>valid_policy_node_set</tt> to the empty set.</t>
              </li>
              <li>
                <t>If the <tt>valid_policy_graph</tt> is not NULL, set <tt>valid_policy_node_set</tt> to the set of policy nodes
whose <tt>valid_policy</tt> is not anyPolicy and
whose parent list is a single node with <tt>valid_policy</tt> of anyPolicy.</t>
              </li>
              <li>
                <t>If the <tt>valid_policy_graph</tt> is not NULL and contains a node of depth n with the <tt>valid_policy</tt> anyPolicy, add it to <tt>valid_policy_node_set</tt>.</t>
              </li>
              <li>
                <t>Compute <tt>authority_constrained_policy_set</tt>, a set of policy OIDs and associated qualifiers as follows. For each node in <tt>valid_policy_node_set</tt>:      </t>
                <ol spacing="normal" type="(%i)"><li>
                    <t>Add the node's <tt>valid_policy</tt> to <tt>authority_constrained_policy_set</tt>.</t>
                  </li>
                  <li>
                    <t>If returning policy qualifiers in the output, collect all qualifiers in the node, its ancestors, and descendants and associate them with <tt>valid_policy</tt>. Returning policy qualifiers in the output is NOT RECOMMENDED.</t>
                  </li>
                </ol>
              </li>
              <li>
                <t>Set <tt>user_constrained_policy_set</tt> to <tt>authority_constrained_policy_set</tt>.</t>
              </li>
              <li>
                <t>If the user-initial-policy-set is not anyPolicy:      </t>
                <ol spacing="normal" type="(%i)"><li>
                    <t>Remove any elements of <tt>user_constrained_policy_set</tt> which do not appear in user-initial-policy-set.</t>
                  </li>
                  <li>
                    <t>If anyPolicy appears in <tt>authority_constrained_policy_set</tt> with qualifiers AP-Q, for each OID P-OID in user-initial-policy-set which does not appear in <tt>user_constrained_policy_set</tt>, add P-OID with qualifiers AP-Q to <tt>user_constrained_policy_set</tt>.</t>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
        <t>Additionally, this update replaces the final paragraph as follows:</t>
        <t>OLD:</t>
        <ul empty="true">
          <li>
            <t>If either (1) the value of <tt>explicit_policy</tt> variable is greater than
zero or (2) the <tt>valid_policy_tree</tt> is not NULL, then path processing
has succeeded.</t>
          </li>
        </ul>
        <t>NEW:</t>
        <ul empty="true">
          <li>
            <t>If either (1) the value of <tt>explicit_policy</tt> variable is greater than
zero or (2) the <tt>user_constrained_policy_set</tt> is not empty, then path processing
has succeeded.</t>
          </li>
        </ul>
      </section>
      <section anchor="updates-to-section-616">
        <name>Updates to Section 6.1.6</name>
        <t>This update replaces <xref section="6.1.6" sectionFormat="of" target="RFC5280"/> with the following text:</t>
        <ul empty="true">
          <li>
            <t>If path processing succeeds, the procedure terminates, returning a
success indication together with final value of the <tt>user_constrained_policy_set</tt>,
the <tt>working_public_key</tt>, the <tt>working_public_key_algorithm</tt>, and the
<tt>working_public_key_parameters</tt>.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="other-mitigations">
      <name>Other Mitigations</name>
      <t>X.509 implementations that are unable switch to the policy graph structure
SHOULD mitigate the denial-of-service attack in other ways. This section
describes alternate mitigation and partial mitigation strategies.</t>
      <section anchor="limit-certificate-depth">
        <name>Limit Certificate Depth</name>
        <t>X.509 validators typically already allow limiting the depth of a certificate
chain. This can limit the attack, however a large depth limit may still admit
attacks. By modifying the example in <xref target="exponential-growth"/> to increase the
number of policies asserted in each certificate, an attacker could still achieve
O(N^(depth/2)) scaling or higher.</t>
      </section>
      <section anchor="limit-policy-tree-size">
        <name>Limit Policy Tree Size</name>
        <t>If existing stable interfaces force the validator to build a full policy tree
(see <xref target="outputs"/>), the validator SHOULD limit the number of nodes in the policy
tree, and reject the certification path if this limit is reached.</t>
      </section>
      <section anchor="inhibit-policy-mapping">
        <name>Inhibit Policy Mapping</name>
        <t>If policy mapping is disabled via the initial-policy-mapping-inhibit setting
(see <xref section="6.1.1" sectionFormat="of" target="RFC5280"/>), the attack is mitigated. This also
significantly simplifies the X.509 implementation, which reduces the risk of
other security bugs. However, this will break compatibility with any existing
certification paths which rely on policy mapping.</t>
        <t>To facilitate this mitigation, certificate authorities SHOULD NOT issue
certificates with the policy mappings extension (<xref section="4.2.1.5" sectionFormat="of" target="RFC5280"/>). Applications maintaining policies for accepted trust anchors are
RECOMMENDED to forbid this extension in participating certificate authorities.</t>
      </section>
      <section anchor="disable-policy-checking">
        <name>Disable Policy Checking</name>
        <t>An X.509 validator can mitigate this attack by disabling policy validation
entirely. This may be viable for applications which do not require policy
validation. In this case, critical policy-related extensions, notably the policy
constraints (<xref section="4.2.1.11" sectionFormat="of" target="RFC5280"/>), MUST be treated as unrecognized
extensions as in <xref section="4.2" sectionFormat="of" target="RFC5280"/> and be rejected.</t>
      </section>
      <section anchor="verify-signatures-first">
        <name>Verify Signatures First</name>
        <t>X.509 validators SHOULD verify signatures in certification paths before or in
conjunction with policy verification. This limits the attack to entities in
control of CA certificates. For some applications, this may be sufficient to
mitigate the attack. However, other applications may still be impacted. For
example:</t>
        <ul spacing="normal">
          <li>
            <t>Any application that evaluates an untrusted PKI, such as a hosting provider
that evaluates a customer-supplied PKI</t>
          </li>
          <li>
            <t>Any application that evaluates an otherwise trusted PKI, but where untrusted
entities have technically-constrained intermediate certificates where policy
mapping and path length are unconstrained.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t><xref target="dos"/> discusses how <xref target="RFC5280"/>'s policy tree algorithm can lead to
denial-of-service vulnerabilities in X.509-based applications, such as
<xref target="CVE-2023-0464"/> and <xref target="CVE-2023-23524"/>.</t>
      <t><xref target="updates"/> replaces this algorithm to avoid this issue. As discussed in
<xref target="policy-graph"/>, the new structure scales linearly with the input. This means
input limits in X.509 validators will more naturally bound processing time,
thus avoiding these vulnerabilities.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC5280">
          <front>
            <title>Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile</title>
            <author fullname="D. Cooper" initials="D." surname="Cooper"/>
            <author fullname="S. Santesson" initials="S." surname="Santesson"/>
            <author fullname="S. Farrell" initials="S." surname="Farrell"/>
            <author fullname="S. Boeyen" initials="S." surname="Boeyen"/>
            <author fullname="R. Housley" initials="R." surname="Housley"/>
            <author fullname="W. Polk" initials="W." surname="Polk"/>
            <date month="May" year="2008"/>
            <abstract>
              <t>This memo profiles the X.509 v3 certificate and X.509 v2 certificate revocation list (CRL) for use in the Internet. An overview of this approach and model is provided as an introduction. The X.509 v3 certificate format is described in detail, with additional information regarding the format and semantics of Internet name forms. Standard certificate extensions are described and two Internet-specific extensions are defined. A set of required certificate extensions is specified. The X.509 v2 CRL format is described in detail along with standard and Internet-specific extensions. An algorithm for X.509 certification path validation is described. An ASN.1 module and examples are provided in the appendices. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5280"/>
          <seriesInfo name="DOI" value="10.17487/RFC5280"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="X.509">
          <front>
            <title>Information technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks</title>
            <author>
              <organization>International Telecommunications Union</organization>
            </author>
            <date year="2019" month="October"/>
          </front>
          <seriesInfo name="ITU-T" value="Recommendation X.509"/>
        </reference>
        <reference anchor="CVE-2023-0464" target="https://www.cve.org/CVERecord?id=CVE-2023-0464">
          <front>
            <title>Excessive Resource Usage Verifying X.509 Policy Constraints</title>
            <author>
              <organization/>
            </author>
            <date year="2023" month="March"/>
          </front>
        </reference>
        <reference anchor="CVE-2023-23524" target="https://www.cve.org/CVERecord?id=CVE-2023-23524">
          <front>
            <title>Processing a maliciously crafted certificate may lead to a denial-of-service</title>
            <author>
              <organization/>
            </author>
            <date year="2023" month="February"/>
          </front>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
      </references>
    </references>
    <?line 728?>

<section numbered="false" anchor="acknowledgements">
      <name>Acknowledgements</name>
      <t>The author thanks Bob Beck, Adam Langley, Matt Mueller, and Ryan Sleevi for
many valuable discussions that led to discovering this issue, understanding it,
and developing the mitigation.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
