| rfc9618.original | rfc9618.txt | |||
|---|---|---|---|---|
| Limited Additional Mechanisms for PKIX and SMIME D. Benjamin | Internet Engineering Task Force (IETF) D. Benjamin | |||
| Internet-Draft Google LLC | Request for Comments: 9618 Google LLC | |||
| Updates: 5280 (if approved) 1 February 2024 | Updates: 5280 August 2024 | |||
| Intended status: Standards Track | Category: Standards Track | |||
| Expires: 4 August 2024 | ISSN: 2070-1721 | |||
| Updates to X.509 Policy Validation | Updates to X.509 Policy Validation | |||
| draft-ietf-lamps-x509-policy-graph-05 | ||||
| Abstract | Abstract | |||
| This document updates RFC 5280 to replace the algorithm for X.509 | This document updates RFC 5280 to replace the algorithm for X.509 | |||
| policy validation with an equivalent, more efficient algorithm. The | policy validation with an equivalent, more efficient algorithm. The | |||
| original algorithm built a structure which scaled exponentially in | original algorithm built a structure that scaled exponentially in the | |||
| the worst case, leaving implementations vulnerable to denial-of- | worst case, leaving implementations vulnerable to denial-of-service | |||
| service attacks. | attacks. | |||
| Discussion Venues | ||||
| This note is to be removed before publishing as an RFC. | ||||
| 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 | ||||
| https://mailarchive.ietf.org/arch/browse/spasm/. | ||||
| Source for this draft and an issue tracker can be found at | ||||
| https://github.com/davidben/x509-policy-graph. | ||||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This is an Internet Standards Track document. | |||
| provisions of BCP 78 and BCP 79. | ||||
| Internet-Drafts are working documents of the Internet Engineering | ||||
| Task Force (IETF). Note that other groups may also distribute | ||||
| working documents as Internet-Drafts. The list of current Internet- | ||||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | ||||
| Internet-Drafts are draft documents valid for a maximum of six months | This document is a product of the Internet Engineering Task Force | |||
| and may be updated, replaced, or obsoleted by other documents at any | (IETF). It represents the consensus of the IETF community. It has | |||
| time. It is inappropriate to use Internet-Drafts as reference | received public review and has been approved for publication by the | |||
| material or to cite them other than as "work in progress." | Internet Engineering Steering Group (IESG). Further information on | |||
| Internet Standards is available in Section 2 of RFC 7841. | ||||
| This Internet-Draft will expire on 4 August 2024. | Information about the current status of this document, any errata, | |||
| and how to provide feedback on it may be obtained at | ||||
| https://www.rfc-editor.org/info/rfc9618. | ||||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2024 IETF Trust and the persons identified as the | Copyright (c) 2024 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents | |||
| license-info) in effect on the date of publication of this document. | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| Please review these documents carefully, as they describe your rights | publication of this document. Please review these documents | |||
| and restrictions with respect to this document. Code Components | carefully, as they describe your rights and restrictions with respect | |||
| extracted from this document must include Revised BSD License text as | to this document. Code Components extracted from this document must | |||
| described in Section 4.e of the Trust Legal Provisions and are | include Revised BSD License text as described in Section 4.e of the | |||
| provided without warranty as described in the Revised BSD License. | Trust Legal Provisions and are provided without warranty as described | |||
| in the Revised BSD License. | ||||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction | |||
| 1.1. Summary of Changes from RFC 5280 . . . . . . . . . . . . 3 | 1.1. Summary of Changes from RFC 5280 | |||
| 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 | 2. Conventions and Definitions | |||
| 3. Denial of Service Vulnerability . . . . . . . . . . . . . . . 4 | 3. Denial-of-Service Vulnerability | |||
| 3.1. Policy Trees . . . . . . . . . . . . . . . . . . . . . . 4 | 3.1. Policy Trees | |||
| 3.2. Exponential Growth . . . . . . . . . . . . . . . . . . . 5 | 3.2. Exponential Growth | |||
| 3.3. Attack Vector . . . . . . . . . . . . . . . . . . . . . . 6 | 3.3. Attack Vector | |||
| 4. Avoiding Exponential Growth . . . . . . . . . . . . . . . . . 7 | 4. Avoiding Exponential Growth | |||
| 4.1. Policy Graphs . . . . . . . . . . . . . . . . . . . . . . 7 | 4.1. Policy Graphs | |||
| 4.2. Verification Outputs . . . . . . . . . . . . . . . . . . 8 | 4.2. Verification Outputs | |||
| 5. Updates to RFC 5280 . . . . . . . . . . . . . . . . . . . . . 9 | 5. Updates to RFC 5280 | |||
| 5.1. Updates to Section 6.1 . . . . . . . . . . . . . . . . . 9 | 5.1. Updates to Section 6.1 | |||
| 5.2. Updates to Section 6.1.2 . . . . . . . . . . . . . . . . 10 | 5.2. Updates to Section 6.1.2 | |||
| 5.3. Updates to Section 6.1.3 . . . . . . . . . . . . . . . . 11 | 5.3. Updates to Section 6.1.3 | |||
| 5.4. Updates to Section 6.1.4 . . . . . . . . . . . . . . . . 15 | 5.4. Updates to Section 6.1.4 | |||
| 5.5. Updates to Section 6.1.5 . . . . . . . . . . . . . . . . 16 | 5.5. Updates to Section 6.1.5 | |||
| 5.6. Updates to Section 6.1.6 . . . . . . . . . . . . . . . . 17 | 5.6. Updates to Section 6.1.6 | |||
| 6. Other Mitigations . . . . . . . . . . . . . . . . . . . . . . 18 | 6. Other Mitigations | |||
| 6.1. Verify Signatures First . . . . . . . . . . . . . . . . . 18 | 6.1. Verify Signatures First | |||
| 6.2. Limit Certificate Depth . . . . . . . . . . . . . . . . . 19 | 6.2. Limit Certificate Depth | |||
| 6.3. Limit Policy Tree Size . . . . . . . . . . . . . . . . . 19 | 6.3. Limit Policy Tree Size | |||
| 6.4. Inhibit Policy Mapping . . . . . . . . . . . . . . . . . 19 | 6.4. Inhibit Policy Mapping | |||
| 6.5. Disable Policy Checking . . . . . . . . . . . . . . . . . 19 | 6.5. Disable Policy Checking | |||
| 7. Implementation Status . . . . . . . . . . . . . . . . . . . . 20 | 7. Security Considerations | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 20 | 8. IANA Considerations | |||
| 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 20 | 9. References | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 | 9.1. Normative References | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 20 | 9.2. Informative References | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 21 | Acknowledgements | |||
| Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 22 | Author's Address | |||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 22 | ||||
| 1. Introduction | 1. Introduction | |||
| [RFC5280] defines a suite of extensions for determining the | [RFC5280] defines a suite of extensions for determining the policies | |||
| "policies" which apply to a certification path. A policy is | that apply to a certification path. A policy is described by an | |||
| described by an object identifier (OID), and a set of optional | object identifier (OID) and a set of optional qualifiers. | |||
| qualifiers. | ||||
| Policy validation in [RFC5280] is complex. As an overview, the | Policy validation in [RFC5280] is complex. As an overview, the | |||
| certificate policies extension (Section 4.2.1.4 of [RFC5280]) | certificate policies extension (Section 4.2.1.4 of [RFC5280]) | |||
| describes the policies, with optional qualifiers, under which an | describes the policies, with optional qualifiers, under which an | |||
| individual certificate was issued. The policy mappings extension | individual certificate was issued. The policy mappings extension | |||
| (Section 4.2.1.5 of [RFC5280]) allows a CA certificate to map its | (Section 4.2.1.5 of [RFC5280]) allows a CA certificate to map its | |||
| policy OIDs to other policy OIDs in certificates that it issues. | policy OIDs to other policy OIDs in certificates that it issues. | |||
| Subject to these mappings and other extensions, the certification | Subject to these mappings and other extensions, the certification | |||
| path's overall policy set is the intersection of policies asserted by | path's overall policy set is the intersection of policies asserted by | |||
| each certificate in the path, collecting the corresponding | each certificate in the path. | |||
| qualifiers. | ||||
| The procedure in Section 6.1 of [RFC5280] determines this set in the | The procedure in Section 6.1 of [RFC5280] determines this set in the | |||
| course of certification path validation. It does so by building a | course of certification path validation. It does so by building a | |||
| policy tree, containing policies asserted by each certificate and | policy tree containing policies asserted by each certificate and the | |||
| mappings between them. This tree can grow exponentially in the depth | mappings between them. This tree can grow exponentially in the depth | |||
| of the certification path, which means an attacker, with a small | of the certification path, which means an attacker, with a small | |||
| input, can cause a path validator to consume excessive memory and | input, can cause a path validator to consume excessive memory and | |||
| computational resources. This cost asymmetry can lead to a denial- | computational resources. This cost asymmetry can lead to a denial- | |||
| of-service vulnerability in X.509-based applications, such as | of-service vulnerability in X.509-based applications, such as | |||
| [CVE-2023-0464] and [CVE-2023-23524]. | [CVE-2023-0464] and [CVE-2023-23524]. | |||
| Section 3 describes this vulnerability. Section 4.1 describes the | Section 3 describes this vulnerability. Section 4.1 describes the | |||
| primary mitigation for this vulnerability, a replacement for the | primary mitigation for this vulnerability, a replacement for the | |||
| policy tree structure. Section 5 provides updates to [RFC5280] which | policy tree structure. Section 5 provides updates to [RFC5280] that | |||
| implement this change. Finally, Section 6 discusses alternative | implement this change. Finally, Section 6 discusses alternative | |||
| mitigation strategies for X.509 applications. | mitigation strategies for X.509 applications. | |||
| 1.1. Summary of Changes from RFC 5280 | 1.1. Summary of Changes from RFC 5280 | |||
| The algorithm for processing certificate policies and policy mappings | The algorithm for processing certificate policies and policy mappings | |||
| is replaced with one which builds an equivalent, but much more | is replaced with one that builds an equivalent but much more | |||
| efficient structure. This new algorithm does not change the validity | efficient structure. This new algorithm does not change the validity | |||
| status of any certification path, nor which certificate policies are | status of any certification path or which certificate policies are | |||
| valid for it. | valid for it. | |||
| 2. Conventions and Definitions | 2. Conventions and Definitions | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| "OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in | |||
| 14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
| capitals, as shown here. | capitals, as shown here. | |||
| 3. Denial of Service Vulnerability | 3. Denial-of-Service Vulnerability | |||
| This section discusses how the path validation algorithm defined in | This section discusses how the path validation algorithm defined in | |||
| Section 6.1.2 of [RFC5280] can lead to a denial-of-service | Section 6.1.2 of [RFC5280] can lead to a denial-of-service | |||
| vulnerability in X.509-based applications. | vulnerability in X.509-based applications. | |||
| 3.1. Policy Trees | 3.1. Policy Trees | |||
| Section 6.1.2 of [RFC5280] constructs the valid_policy_tree, a tree | Section 6.1.2 of [RFC5280] constructs the valid_policy_tree, a tree | |||
| of certificate policies, during certification path validation. The | of certificate policies, during certification path validation. The | |||
| nodes at any given depth in the tree correspond to policies asserted | nodes at any given depth in the tree correspond to policies asserted | |||
| by a certificate in the certification path. A node's parent policy | by a certificate in the certification path. A node's parent policy | |||
| is the policy in the issuer certificate which was mapped to this | is the policy in the issuer certificate that was mapped to this | |||
| policy, and a node's children are the policies it was mapped to in | policy, and a node's children are the policies the node was mapped to | |||
| the subject certificate. | in the subject certificate. | |||
| For example, suppose a certification path contains: | For example, suppose a certification path contains: | |||
| * An intermediate certificate which asserts policy OIDs OID1, OID2, | * An intermediate certificate that asserts the following policy | |||
| and OID5. It contains mappings OID1 to OID3, and OID1 to OID4. | OIDs: OID1, OID2, and OID5. It contains mappings from OID1 to | |||
| OID3 and from OID1 to OID4. | ||||
| * An end-entity certificate which asserts policy OIDs OID2, OID3, | * An end-entity certificate that asserts the following policy OIDs: | |||
| and OID6. | OID2, OID3, and OID6. | |||
| This would result in the tree shown in Figure 1. Note that OID5 and | This would result in the tree shown below. Note that OID5 and OID6 | |||
| OID6 are not included or mapped across the whole path, so they do not | are not included or mapped across the whole path, so they do not | |||
| appear in the final structure. | appear in the final structure. | |||
| +-----------+ | +-----------+ | |||
| Root: | anyPolicy | | Root: | anyPolicy | | |||
| +-----------+ | +-----------+ | |||
| |{anyPolicy}| | |{anyPolicy}| | |||
| +-----------+ | +-----------+ | |||
| / \ | / \ | |||
| / \ | / \ | |||
| v v | v v | |||
| skipping to change at page 5, line 25 ¶ | skipping to change at line 177 ¶ | |||
| (OID5 discarded) +------------+ +------------+ | (OID5 discarded) +------------+ +------------+ | |||
| |{OID3, OID4}| | {OID2} | | |{OID3, OID4}| | {OID2} | | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| | | | | | | |||
| | | | | | | |||
| v v | v v | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| End-entity: | OID3 | | OID2 | | End-entity: | OID3 | | OID2 | | |||
| (OID6 discarded) +------------+ +------------+ | (OID6 discarded) +------------+ +------------+ | |||
| Figure 1: An Example X.509 Policy Tree | ||||
| The complete algorithm for building this structure is described in | The complete algorithm for building this structure is described in | |||
| steps (d), (e), and (f) of Section 6.1.3 of [RFC5280], steps (h), | steps (d), (e), and (f) in Section 6.1.3 of [RFC5280]; steps (h), | |||
| (i), (j) of Section 6.1.4 of [RFC5280], and steps (a), (b), and (g) | (i), and (j) in Section 6.1.4 of [RFC5280]; and steps (a), (b), and | |||
| of Section 6.1.5 of [RFC5280]. | (g) in Section 6.1.5 of [RFC5280]. | |||
| 3.2. Exponential Growth | 3.2. Exponential Growth | |||
| The valid_policy_tree grows exponentially in the worst case. In step | The valid_policy_tree grows exponentially in the worst case. In step | |||
| (d.1) of Section 6.1.3 of [RFC5280], a single policy P can produce | (d.1) in Section 6.1.3 of [RFC5280], a single policy P can produce | |||
| multiple child nodes if multiple issuer policies map to P. This can | multiple child nodes if multiple issuer policies map to P. This can | |||
| cause the tree size to increase in size multiplicatively at each | cause the tree size to increase in size multiplicatively at each | |||
| level. | level. | |||
| In particular, consider a certificate chain where every intermediate | In particular, consider a certificate chain where every intermediate | |||
| certificate asserts policies OID1 and OID2, and then contains the | certificate asserts policies OID1 and OID2 and then contains the full | |||
| full Cartesian product of mappings: | Cartesian product of mappings: | |||
| * OID1 maps to OID1 | * OID1 maps to OID1 | |||
| * OID1 maps to OID2 | * OID1 maps to OID2 | |||
| * OID2 maps to OID1 | * OID2 maps to OID1 | |||
| * OID2 maps to OID2 | * OID2 maps to OID2 | |||
| At each depth, the tree would double in size. For example, if there | At each depth, the tree would double in size. For example, if there | |||
| are two intermediate certificates and one end-entity certificate, the | are two intermediate certificates and one end-entity certificate, the | |||
| resulting tree would be as depicted in Figure 2. | resulting tree would be as depicted in Figure 1. | |||
| +-----------------------+ | +-----------------------+ | |||
| | anyPolicy | | | anyPolicy | | |||
| +-----------------------+ | +-----------------------+ | |||
| | {anyPolicy} | | | {anyPolicy} | | |||
| +-----------------------+ | +-----------------------+ | |||
| / \ | / \ | |||
| / \ | / \ | |||
| v v | v v | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| skipping to change at page 6, line 35 ¶ | skipping to change at line 233 ¶ | |||
| | OID1 | | OID2 | | OID1 | | OID2 | | | OID1 | | OID2 | | OID1 | | OID2 | | |||
| +------------+ +------------+ +------------+ +------------+ | +------------+ +------------+ +------------+ +------------+ | |||
| |{OID1, OID2}| |{OID1, OID2}| |{OID1, OID2}| |{OID1, OID2}| | |{OID1, OID2}| |{OID1, OID2}| |{OID1, OID2}| |{OID1, OID2}| | |||
| +------------+ +------------+ +------------+ +------------+ | +------------+ +------------+ +------------+ +------------+ | |||
| | | | | | | | | | | | | | | | | | | |||
| v v v v v v v v | v v v v v v v v | |||
| +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ | +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ | |||
| | OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 | | | OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 | | OID1 | | OID2 | | |||
| +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ | +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ | |||
| Figure 2: An Example X.509 Policy Tree with Exponential Growth | Figure 1: An Example X.509 Policy Tree with Exponential Growth | |||
| 3.3. Attack Vector | 3.3. Attack Vector | |||
| An attacker can use the exponential growth to mount a denial-of- | An attacker can use the exponential growth to mount a denial-of- | |||
| service attack against an X.509-based application. The attacker | service attack against an X.509-based application. The attacker | |||
| sends certificate chain as in Section 3.2 and triggers the target | sends a certificate chain as described in Section 3.2 and triggers | |||
| application's certificate validation process. For example, the | the target application's certificate validation process. For | |||
| target application may be a TLS [RFC8446] server that performs client | example, the target application may be a TLS server [RFC8446] that | |||
| certificate validation. The target application will consume far more | performs client certificate validation. The target application will | |||
| resources processing the input than the attacker consumed to send it, | consume far more resources processing the input than the attacker | |||
| preventing it from servicing other clients. | consumed to send it, which prevents the target application from | |||
| servicing other clients. | ||||
| 4. Avoiding Exponential Growth | 4. Avoiding Exponential Growth | |||
| This document mitigates the denial-of-service vulnerability described | This document mitigates the denial-of-service vulnerability described | |||
| in Section 3 by replacing the policy tree with a policy graph | in Section 3 by replacing the policy tree with a policy graph | |||
| structure, described in this section. The policy graph grows | structure, which is described in this section. The policy graph | |||
| linearly instead of exponentially. This removes the asymmetric cost | grows linearly instead of exponentially. This removes the asymmetric | |||
| in policy validation. | cost in policy validation. | |||
| X.509 implementations SHOULD perform policy validation by building a | X.509 implementations SHOULD perform policy validation by building a | |||
| policy graph, following the procedure described in Section 5. This | policy graph, following the procedure described in Section 5. This | |||
| replacement procedure computes the same policies as in [RFC5280], | replacement procedure computes the same policies as in [RFC5280], but | |||
| however one of the outputs is in a different form. See Section 4.2 | one of the outputs is in a different form. See Section 4.2 for | |||
| for details. Section 6 describes alternative mitigations for | details. Section 6 describes alternative mitigations for | |||
| implementations that depend on the original, exponential-sized | implementations that depend on the original, exponential-sized | |||
| output. | output. | |||
| 4.1. Policy Graphs | 4.1. Policy Graphs | |||
| The tree structure from [RFC5280] is an unnecessarily inefficient | The tree structure in [RFC5280] is an unnecessarily inefficient | |||
| representation of a certification path's policy mappings. A single | representation of a certification path's policy mappings. When | |||
| certificate policy may correspond to multiple nodes, but each node is | multiple issuer policies map to a single subject policy, the subject | |||
| identical, with identical children. This redundancy is the source of | policy will correspond to multiple duplicate nodes in the policy | |||
| the exponential growth described in Section 3.2. | tree. Children of the subject policy are then duplicated | |||
| recursively. This duplication is the source of the exponential | ||||
| growth described in Section 3.2. | ||||
| A policy graph is a directed acyclic graph of policy nodes. Where | A policy graph represents the same information with a directed | |||
| [RFC5280] adds multiple duplicate nodes, a policy graph adds a single | acyclic graph of policy nodes. It eliminates this duplication by | |||
| node with multiple parents. See Section 5 for the procedure for | using a single node with multiple parents. See Section 5 for the | |||
| building this structure. Figure 3 shows the updated representation | procedure for building this structure. Figure 2 shows the updated | |||
| of the example in Figure 2. | representation of the example in Figure 1. | |||
| +-----------+ | +-----------+ | |||
| | anyPolicy | | | anyPolicy | | |||
| +-----------+ | +-----------+ | |||
| |{anyPolicy}| | |{anyPolicy}| | |||
| +-----------+ | +-----------+ | |||
| / \ | / \ | |||
| / \ | / \ | |||
| v v | v v | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| skipping to change at page 8, line 39 ¶ | skipping to change at line 313 ¶ | |||
| | \ / | | | \ / | | |||
| | \ / | | | \ / | | |||
| | \/ | | | \/ | | |||
| | /\ | | | /\ | | |||
| | / \ | | | / \ | | |||
| v v v v | v v v v | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| | OID1 | | OID2 | | | OID1 | | OID2 | | |||
| +------------+ +------------+ | +------------+ +------------+ | |||
| Figure 3: A More Efficient Representation of an X.509 Policy Tree | Figure 2: A More Efficient Representation of an X.509 Policy Tree | |||
| This graph's size is bounded linearly by the total number of | This graph's size is bounded linearly by the total number of | |||
| certificate policies (Section 4.2.1.4 of [RFC5280]) and policy | certificate policies (Section 4.2.1.4 of [RFC5280]) and policy | |||
| mappings (Section 4.2.1.5 of [RFC5280]). The policy tree from | mappings (Section 4.2.1.5 of [RFC5280]). The policy tree in | |||
| [RFC5280] is the tree of all paths from the root to a leaf in the | [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. | policy graph, so no information is lost in the graph representation. | |||
| 4.2. Verification Outputs | 4.2. Verification Outputs | |||
| Section 6.1.6 of [RFC5280] describes the entire valid_policy_tree | Section 6.1.6 of [RFC5280] describes the entire valid_policy_tree | |||
| structure as an output of the verification process. Section 12.2 of | structure as an output of the verification process. However, | |||
| [X.509] instead only outputs the authorities-constrained policies, | Section 12.2 of [X.509] only describes the following as outputs: the | |||
| the user-constrained policies, and their associated qualifiers. | authorities-constrained policies, the user-constrained policies, and | |||
| their associated qualifiers. | ||||
| As the valid_policy_tree is the exponential structure, computing it | As the valid_policy_tree is the exponential structure, computing it | |||
| reintroduces the denial-of-service vulnerability. X.509 | reintroduces the denial-of-service vulnerability. X.509 | |||
| implementations SHOULD NOT output the entire valid_policy_tree | implementations SHOULD NOT output the entire valid_policy_tree | |||
| structure and instead SHOULD limit output to just the set of | structure; instead, they SHOULD limit output to just the set of | |||
| authorities-constrained and/or user-constrained policies, as | authorities-constrained and/or user-constrained policies, as | |||
| described in [X.509]. Section 5.6 and Section 6 discuss other | described in [X.509]. Sections 5.6 and 6 discuss other mitigations | |||
| mitigations for applications where this option is not available. | for applications where this option is not available. | |||
| X.509 implementations MAY omit policy qualifiers from the output to | X.509 implementations MAY omit policy qualifiers from the output to | |||
| simplify processing. Note Section 4.2.1.4 of [RFC5280] already | simplify processing. Note that Section 4.2.1.4 of [RFC5280] already | |||
| recommends that certification authorities omit policy qualifiers from | recommends that certification authorities omit policy qualifiers from | |||
| policy information terms. | policy information terms. | |||
| 5. Updates to RFC 5280 | 5. Updates to RFC 5280 | |||
| This section provides updates to [RFC5280]. This implements the | This section provides updates to [RFC5280]. These updates implement | |||
| changes described in Section 4. | the changes described in Section 4. | |||
| 5.1. Updates to Section 6.1 | 5.1. Updates to Section 6.1 | |||
| This update replaces a paragraph of Section 6.1 of [RFC5280] as | Section 6.1 of [RFC5280] is updated as follows: | |||
| follows: | ||||
| OLD: | OLD: | |||
| A particular certification path may not, however, be appropriate | | A particular certification path may not, however, be appropriate | |||
| for all applications. Therefore, an application MAY augment this | | for all applications. Therefore, an application MAY augment this | |||
| algorithm to further limit the set of valid paths. The path | | algorithm to further limit the set of valid paths. The path | |||
| validation process also determines the set of certificate policies | | validation process also determines the set of certificate policies | |||
| that are valid for this path, based on the certificate policies | | that are valid for this path, based on the certificate policies | |||
| extension, policy mappings extension, policy constraints | | extension, policy mappings extension, policy constraints | |||
| extension, and inhibit anyPolicy extension. To achieve this, the | | extension, and inhibit anyPolicy extension. To achieve this, the | |||
| path validation algorithm constructs a valid policy tree. If the | | path validation algorithm constructs a valid policy tree. If the | |||
| set of certificate policies that are valid for this path is not | | 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, | | empty, then the result will be a valid policy tree of depth n, | |||
| otherwise the result will be a null valid policy tree. | | otherwise the result will be a null valid policy tree. | |||
| NEW: | NEW: | |||
| A particular certification path may not, however, be appropriate | | A particular certification path may not, however, be appropriate | |||
| for all applications. Therefore, an application MAY augment this | | for all applications. Therefore, an application MAY augment this | |||
| algorithm to further limit the set of valid paths. The path | | algorithm to further limit the set of valid paths. The path | |||
| validation process also determines the set of certificate policies | | validation process also determines the set of certificate policies | |||
| that are valid for this path, based on the certificate policies | | that are valid for this path, based on the certificate policies | |||
| extension, policy mappings extension, policy constraints | | extension, policy mappings extension, policy constraints | |||
| extension, and inhibit anyPolicy extension. To achieve this, the | | extension, and inhibit anyPolicy extension. To achieve this, the | |||
| path validation algorithm constructs a valid policy set, which may | | path validation algorithm constructs a valid policy set, which may | |||
| be empty if no certificate policies are valid for this path. | | be empty if no certificate policies are valid for this path. | |||
| 5.2. Updates to Section 6.1.2 | 5.2. Updates to Section 6.1.2 | |||
| This update replaces entry (a) of Section 6.1.2 of [RFC5280] with the | The following replaces entry (a) in Section 6.1.2 of [RFC5280]: | |||
| following text: | ||||
| (a) valid_policy_graph: 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. | ||||
| Each node in the valid_policy_graph includes three data objects: | ||||
| the valid policy, a set of associated policy qualifiers, and a | ||||
| set of one or more expected policy values. | ||||
| 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 and, with the exception of depth zero, one or more | ||||
| parents at depth x-1. No other edges between nodes may exist. | ||||
| If the node is at depth x, the components of the node have the | ||||
| following semantics: | ||||
| (1) The valid_policy is a single policy OID representing a | ||||
| valid policy for the path of length x. | ||||
| (2) The qualifier_set 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). | ||||
| (3) The expected_policy_set contains one or more policy OIDs | ||||
| that would satisfy this policy in the certificate x+1. | ||||
| The initial value of the valid_policy_graph is a single node | ||||
| with valid_policy anyPolicy, an empty qualifier_set, and an | ||||
| expected_policy_set with the single value anyPolicy. This node | ||||
| is considered to be at depth zero. | ||||
| The graph additionally satisfies the following invariants: | ||||
| * For any depth x and policy OID P-OID, there is at most one | ||||
| node at depth x whose valid_policy is P-OID. | ||||
| * The expected_policy_set of a node whose valid_policy is | ||||
| anyPolicy is always {anyPolicy}. | ||||
| * A node at depth x whose valid_policy is anyPolicy, except for | ||||
| the one at depth zero, always has exactly one parent: a node | ||||
| at depth x-1 whose valid_policy is also anyPolicy. | ||||
| * Each node at depth greater than 0 has either one or more | ||||
| parent nodes whose valid_policy is not anyPolicy, or a single | ||||
| parent node whose valid_policy is anyPolicy. That is, a node | ||||
| cannot simultaneously be a child of both anyPolicy and some | ||||
| non-anyPolicy OID. | ||||
| Figure 4 is a graphic representation of the initial state of the | ||||
| valid_policy_graph. Additional figures will use this format to | ||||
| describe changes in the valid_policy_graph during path | ||||
| processing. | ||||
| +----------------+ | ||||
| | anyPolicy | <---- valid_policy | ||||
| +----------------+ | ||||
| | {} | <---- qualifier_set | ||||
| +----------------+ | ||||
| | {anyPolicy} | <---- expected_policy_set | ||||
| +----------------+ | ||||
| Figure 4: Initial value of the valid_policy_graph State Variable | | (a) valid_policy_graph: 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. | ||||
| | | ||||
| | Each node in the valid_policy_graph includes three data | ||||
| | objects: the valid policy, a set of associated policy | ||||
| | qualifiers, and a set of one or more expected policy values. | ||||
| | | ||||
| | 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 and, with the exception of depth zero, | ||||
| | one or more parents at depth x-1. No other edges between | ||||
| | nodes may exist. | ||||
| | | ||||
| | If the node is at depth x, the components of the node have | ||||
| | the following semantics: | ||||
| | | ||||
| | (1) The valid_policy is a single policy OID representing a | ||||
| | valid policy for the path of length x. | ||||
| | | ||||
| | (2) The qualifier_set 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). | ||||
| | | ||||
| | (3) The expected_policy_set contains one or more policy OIDs | ||||
| | that would satisfy this policy in the certificate x+1. | ||||
| | | ||||
| | The initial value of the valid_policy_graph is a single node | ||||
| | with valid_policy anyPolicy, an empty qualifier_set, and an | ||||
| | expected_policy_set with the single value anyPolicy. This | ||||
| | node is considered to be at depth zero. | ||||
| | | ||||
| | The graph additionally satisfies the following invariants: | ||||
| | | ||||
| | * For any depth x and policy OID P-OID, there is at most one | ||||
| | node at depth x whose valid_policy is P-OID. | ||||
| | | ||||
| | * The expected_policy_set of a node whose valid_policy is | ||||
| | anyPolicy is always {anyPolicy}. | ||||
| | | ||||
| | * A node at depth x whose valid_policy is anyPolicy, except | ||||
| | for the one at depth zero, always has exactly one parent: | ||||
| | a node at depth x-1 whose valid_policy is also anyPolicy. | ||||
| | | ||||
| | * Each node at depth greater than 0 has either one or more | ||||
| | parent nodes whose valid_policy is not anyPolicy or a | ||||
| | single parent node whose valid_policy is anyPolicy. That | ||||
| | is, a node cannot simultaneously be a child of both | ||||
| | anyPolicy and some non-anyPolicy OID. | ||||
| | | ||||
| | Figure 3 is a graphic representation of the initial state of | ||||
| | the valid_policy_graph. Additional figures will use this | ||||
| | format to describe changes in the valid_policy_graph during | ||||
| | path processing. | ||||
| | | ||||
| | +----------------+ | ||||
| | | anyPolicy | <---- valid_policy | ||||
| | +----------------+ | ||||
| | | {} | <---- qualifier_set | ||||
| | +----------------+ | ||||
| | | {anyPolicy} | <---- expected_policy_set | ||||
| | +----------------+ | ||||
| | | ||||
| | Figure 3: Initial Value of the valid_policy_graph State | ||||
| | Variable | ||||
| 5.3. Updates to Section 6.1.3 | 5.3. Updates to Section 6.1.3 | |||
| This update replaces steps (d), (e), and (f) of Section 6.1.3 of | The following replaces steps (d), (e), and (f) in Section 6.1.3 of | |||
| [RFC5280] with the following text: | [RFC5280]: | |||
| (d) If the certificate policies extension is present in the | ||||
| certificate and the valid_policy_graph is not NULL, process the | ||||
| policy information by performing the following steps in order: | ||||
| (1) 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: | ||||
| (i) Let parent_nodes be the nodes at depth i-1 in the | ||||
| valid_policy_graph where P-OID is in the | ||||
| expected_policy_set. If parent_nodes is not empty, | ||||
| create a child node as follows: set the valid_policy | ||||
| to P-OID, set the qualifier_set to P-Q, set the | ||||
| expected_policy_set to {P-OID}, and set the parent | ||||
| nodes to parent_nodes. | ||||
| For example, consider a valid_policy_graph with a | ||||
| node of depth i-1 where the expected_policy_set is | ||||
| {Gold, White}, and a second node where the | ||||
| expected_policy_set 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 Figure 5. | ||||
| +-----------------+ +-----------------+ | ||||
| | Red | | Blue | | ||||
| +-----------------+ +-----------------+ | ||||
| | {} | | {} | depth i-1 | ||||
| +-----------------+ +-----------------+ | ||||
| | {Gold, White} | | {Gold, Yellow} | | ||||
| +-----------------+ +-----------------+ | ||||
| \ / | ||||
| \ / | ||||
| \ / | ||||
| v v | ||||
| +-----------------+ | ||||
| | Gold | | ||||
| +-----------------+ | ||||
| | {} | depth i | ||||
| +-----------------+ | ||||
| | {Gold} | | ||||
| +-----------------+ | ||||
| Figure 5: Processing an Exact Match | ||||
| (ii) If there was no match in step (i) and the | ||||
| valid_policy_graph includes a node of depth i-1 with | ||||
| the valid_policy anyPolicy, generate a child node | ||||
| with the following values: set the valid_policy to | ||||
| P-OID, set the qualifier_set to P-Q, set the | ||||
| expected_policy_set to {P-OID}, and set the parent | ||||
| node to the anyPolicy node at depth i-1. | ||||
| For example, consider a valid_policy_graph with a | ||||
| node of depth i-1 where the valid_policy 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 | ||||
| Figure 6. | ||||
| +-----------------+ | ||||
| | anyPolicy | | ||||
| +-----------------+ | ||||
| | {} | | ||||
| +-----------------+ depth i-1 | ||||
| | {anyPolicy} | | ||||
| +-----------------+ | ||||
| / \ | ||||
| / \ | ||||
| / \ | ||||
| v v | ||||
| +-----------------+ +-----------------+ | ||||
| | Gold | | Silver | | ||||
| +-----------------+ +-----------------+ | ||||
| | {} | | {Q-Silver} | depth i | ||||
| +-----------------+ +-----------------+ | ||||
| | {Gold} | | {Silver} | | ||||
| +-----------------+ +-----------------+ | ||||
| Figure 6: Processing Unmatched Policies when a | ||||
| Leaf Node Specifies anyPolicy | ||||
| (2) If the certificate policies extension includes the policy | ||||
| anyPolicy with the qualifier set AP-Q and either (a) | ||||
| inhibit_anyPolicy is greater than 0 or (b) i<n and the | ||||
| certificate is self-issued, then: | ||||
| For each policy OID P-OID (including anyPolicy) which | ||||
| appears in the expected_policy_set of some node in the | ||||
| valid_policy_graph for depth i-1, if P-OID does not appear | ||||
| as the valid_policy of some node at depth i, create a | ||||
| single child node with the following values: set the | ||||
| valid_policy to P-OID, set the qualifier_set to AP-Q, set | ||||
| the expected_policy_set to {P-OID}, and set the parents to | ||||
| the nodes at depth i-1 where P-OID appears in | ||||
| expected_policy_set. | ||||
| 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. | ||||
| For example, consider a valid_policy_graph with a node of | ||||
| depth i-1 where the expected_policy_set is {Gold, Silver}, | ||||
| and a second node of depth i-1 where the | ||||
| expected_policy_set is {Gold}. 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 Figure 7. | ||||
| +-----------------+ +-----------------+ | ||||
| | Red | | Blue | | ||||
| +-----------------+ +-----------------+ | ||||
| | {} | | {} | depth i-1 | ||||
| +-----------------+ +-----------------+ | ||||
| | {Gold, Silver} | | {Gold} | | ||||
| +-----------------+ +-----------------+ | ||||
| | \ | | ||||
| | \ | | ||||
| | \ | | ||||
| | \ | | ||||
| | \ | | ||||
| v v v | ||||
| +-----------------+ +-----------------+ | ||||
| | Silver | | Gold | | ||||
| +-----------------+ +-----------------+ | ||||
| | {AP-Q} | | {AP-Q} | depth i | ||||
| +-----------------+ +-----------------+ | ||||
| | {Silver} | | {Gold} | | ||||
| +-----------------+ +-----------------+ | ||||
| Figure 7: Processing Unmatched Policies When the | ||||
| Certificate Policies Extension Specifies anyPolicy | ||||
| (3) If there is a node in the valid_policy_graph 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. | ||||
| For example, consider the valid_policy_graph shown in | ||||
| Figure 8 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. | ||||
| +-----------+ | ||||
| | | depth i-3 | ||||
| +-----------+ | ||||
| / | \ | ||||
| / | \ | ||||
| v v v | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| | | | | | Y | depth i-2 | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| | \ | | | ||||
| | \ | | | ||||
| v v v v | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| | X | | | | X | depth i-1 | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| / | \ | ||||
| / | \ | ||||
| v v v | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| | | | | | | depth i | ||||
| +-----------+ +-----------+ +-----------+ | ||||
| Figure 8: Pruning the valid_policy_graph | ||||
| (e) If the certificate policies extension is not present, set the | | (d) If the certificate policies extension is present in the | |||
| valid_policy_graph to NULL. | | certificate and the valid_policy_graph is not NULL, process | |||
| | the policy information by performing the following steps in | ||||
| | order: | ||||
| | | ||||
| | (1) 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: | ||||
| | | ||||
| | (i) Let parent_nodes be the nodes at depth i-1 in the | ||||
| | valid_policy_graph where P-OID is in the | ||||
| | expected_policy_set. If parent_nodes is not | ||||
| | empty, create a child node as follows: set the | ||||
| | valid_policy to P-OID, set the qualifier_set to | ||||
| | P-Q, set the expected_policy_set to {P-OID}, and | ||||
| | set the parent nodes to parent_nodes. | ||||
| | | ||||
| | For example, consider a valid_policy_graph with a | ||||
| | node of depth i-1 where the expected_policy_set is | ||||
| | {Gold, White} and a second node where the | ||||
| | expected_policy_set 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 Figure 4. | ||||
| | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | Red | | Blue | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {} | | {} | depth i-1 | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {Gold, White} | | {Gold, Yellow} | | ||||
| | +-----------------+ +-----------------+ | ||||
| | \ / | ||||
| | \ / | ||||
| | \ / | ||||
| | v v | ||||
| | +-----------------+ | ||||
| | | Gold | | ||||
| | +-----------------+ | ||||
| | | {} | depth i | ||||
| | +-----------------+ | ||||
| | | {Gold} | | ||||
| | +-----------------+ | ||||
| | | ||||
| | Figure 4: Processing an Exact Match | ||||
| | | ||||
| | (ii) If there was no match in step (i) and the | ||||
| | valid_policy_graph includes a node of depth i-1 | ||||
| | with the valid_policy anyPolicy, generate a child | ||||
| | node with the following values: set the | ||||
| | valid_policy to P-OID, set the qualifier_set to | ||||
| | P-Q, set the expected_policy_set to {P-OID}, and | ||||
| | set the parent node to the anyPolicy node at depth | ||||
| | i-1. | ||||
| | | ||||
| | For example, consider a valid_policy_graph with a | ||||
| | node of depth i-1 where the valid_policy 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 Figure 5. | ||||
| | | ||||
| | +-----------------+ | ||||
| | | anyPolicy | | ||||
| | +-----------------+ | ||||
| | | {} | | ||||
| | +-----------------+ depth i-1 | ||||
| | | {anyPolicy} | | ||||
| | +-----------------+ | ||||
| | / \ | ||||
| | / \ | ||||
| | / \ | ||||
| | v v | ||||
| | +-----------------+ +-----------------+ | ||||
| | | Gold | | Silver | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {} | | {Q-Silver} | depth i | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {Gold} | | {Silver} | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | ||||
| | Figure 5: Processing Unmatched Policies When a | ||||
| | Leaf Node Specifies anyPolicy | ||||
| | | ||||
| | (2) If the certificate policies extension includes the | ||||
| | policy anyPolicy with the qualifier set AP-Q and either | ||||
| | (a) inhibit_anyPolicy is greater than 0 or (b) i<n and | ||||
| | the certificate is self-issued, then: | ||||
| | | ||||
| | For each policy OID P-OID (including anyPolicy) that | ||||
| | appears in the expected_policy_set of some node in the | ||||
| | valid_policy_graph for depth i-1, if P-OID does not | ||||
| | appear as the valid_policy of some node at depth i, | ||||
| | create a single child node with the following values: | ||||
| | set the valid_policy to P-OID, set the qualifier_set to | ||||
| | AP-Q, set the expected_policy_set to {P-OID}, and set | ||||
| | the parents to the nodes at depth i-1 where P-OID | ||||
| | appears in expected_policy_set. | ||||
| | | ||||
| | 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. | ||||
| | | ||||
| | For example, consider a valid_policy_graph with a node | ||||
| | of depth i-1 where the expected_policy_set is {Gold, | ||||
| | Silver} and a second node of depth i-1 where the | ||||
| | expected_policy_set is {Gold}. 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 Figure 6. | ||||
| | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | Red | | Blue | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {} | | {} | depth i-1 | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {Gold, Silver} | | {Gold} | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | \ | | ||||
| | | \ | | ||||
| | | \ | | ||||
| | | \ | | ||||
| | | \ | | ||||
| | v v v | ||||
| | +-----------------+ +-----------------+ | ||||
| | | Silver | | Gold | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {AP-Q} | | {AP-Q} | depth i | ||||
| | +-----------------+ +-----------------+ | ||||
| | | {Silver} | | {Gold} | | ||||
| | +-----------------+ +-----------------+ | ||||
| | | ||||
| | Figure 6: Processing Unmatched Policies When the | ||||
| | Certificate Policies Extension Specifies anyPolicy | ||||
| | | ||||
| | (3) If there is a node in the valid_policy_graph 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. | ||||
| | | ||||
| | For example, consider the valid_policy_graph shown in | ||||
| | Figure 7 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. | ||||
| | | ||||
| | +-----------+ | ||||
| | | | depth i-3 | ||||
| | +-----------+ | ||||
| | / | \ | ||||
| | / | \ | ||||
| | v v v | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | | | | | | Y | depth i-2 | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | | \ | | | ||||
| | | \ | | | ||||
| | v v v v | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | | X | | | | X | depth i-1 | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | / | \ | ||||
| | / | \ | ||||
| | v v v | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | | | | | | | depth i | ||||
| | +-----------+ +-----------+ +-----------+ | ||||
| | | ||||
| | Figure 7: Pruning the valid_policy_graph | ||||
| | | ||||
| | (e) If the certificate policies extension is not present, set the | ||||
| | valid_policy_graph to NULL. | ||||
| | | ||||
| | (f) Verify that either explicit_policy is greater than 0 or the | ||||
| | valid_policy_graph is not equal to NULL. | ||||
| (f) Verify that either explicit_policy is greater than 0 or the | The text following step (f) in Section 6.1.3 of [RFC5280], beginning | |||
| valid_policy_graph is not equal to NULL; | with "If any of steps (a), (b), (c), or (f) fails", is left | |||
| unmodified. | ||||
| 5.4. Updates to Section 6.1.4 | 5.4. Updates to Section 6.1.4 | |||
| This update replaces step (b) of Section 6.1.4 of [RFC5280] with the | The following replaces step (b) in Section 6.1.4 of [RFC5280]: | |||
| following text: | ||||
| (b) If a policy mappings extension is present, then for each | ||||
| issuerDomainPolicy ID-P in the policy mappings extension: | ||||
| (1) If the policy_mapping variable is greater than 0 and there | ||||
| is a node in the valid_policy_graph of depth i where ID-P | ||||
| is the valid_policy, set expected_policy_set to the set of | ||||
| subjectDomainPolicy values that are specified as equivalent | ||||
| to ID-P by the policy mappings extension. | ||||
| (2) If the policy_mapping variable is greater than 0, no node | ||||
| of depth i in the valid_policy_graph has a valid_policy of | ||||
| ID-P, but there is a node of depth i with a valid_policy of | ||||
| anyPolicy, then generate a child node of the node of depth | ||||
| i-1 that has a valid_policy of anyPolicy as follows: | ||||
| (i) set the valid_policy to ID-P; | ||||
| (ii) set the qualifier_set to the qualifier set of the | ||||
| policy anyPolicy in the certificate policies | ||||
| extension of certificate i; and | ||||
| (iii) set the expected_policy_set to the set of | ||||
| subjectDomainPolicy values that are specified as | ||||
| equivalent to ID-P by the policy mappings extension. | ||||
| (3) If the policy_mapping variable is equal to 0: | ||||
| (i) delete the node, if any, of depth i in the | ||||
| valid_policy_graph where ID-P is the valid_policy. | ||||
| (ii) If there is a node in the valid_policy_graph of depth | | (b) If a policy mappings extension is present, then for each | |||
| i-1 or less without any child nodes, delete that | | issuerDomainPolicy ID-P in the policy mappings extension: | |||
| node. Repeat this step until there are no nodes of | | | |||
| depth i-1 or less without children. | | (1) If the policy_mapping variable is greater than 0 and | |||
| | there is a node in the valid_policy_graph of depth i | ||||
| | where ID-P is the valid_policy, set expected_policy_set | ||||
| | to the set of subjectDomainPolicy values that are | ||||
| | specified as equivalent to ID-P by the policy mappings | ||||
| | extension. | ||||
| | | ||||
| | (2) If the policy_mapping variable is greater than 0 and no | ||||
| | node of depth i in the valid_policy_graph has a | ||||
| | valid_policy of ID-P but there is a node of depth i with | ||||
| | a valid_policy of anyPolicy, then generate a child node | ||||
| | of the node of depth i-1 that has a valid_policy of | ||||
| | anyPolicy as follows: | ||||
| | | ||||
| | (i) set the valid_policy to ID-P; | ||||
| | | ||||
| | (ii) set the qualifier_set to the qualifier set of the | ||||
| | policy anyPolicy in the certificate policies | ||||
| | extension of certificate i; and | ||||
| | | ||||
| | (iii) set the expected_policy_set to the set of | ||||
| | subjectDomainPolicy values that are specified as | ||||
| | equivalent to ID-P by the policy mappings | ||||
| | extension. | ||||
| | | ||||
| | (3) If the policy_mapping variable is equal to 0: | ||||
| | | ||||
| | (i) delete the node, if any, of depth i in the | ||||
| | valid_policy_graph where ID-P is the valid_policy. | ||||
| | | ||||
| | (ii) If there is a node in the valid_policy_graph 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. | ||||
| 5.5. Updates to Section 6.1.5 | 5.5. Updates to Section 6.1.5 | |||
| This update replaces step (g) of Section 6.1.5 of [RFC5280] with the | The following replaces step (g) in Section 6.1.5 of [RFC5280]: | |||
| following text: | ||||
| (g) Calculate the user_constrained_policy_set as follows. The | ||||
| user_constrained_policy_set is a set of policy OIDs, along with | ||||
| associated policy qualifiers. | ||||
| (1) If the valid_policy_graph is NULL, set | ||||
| valid_policy_node_set to the empty set. | ||||
| (2) If the valid_policy_graph is not NULL, set | ||||
| valid_policy_node_set to the set of policy nodes whose | ||||
| valid_policy is not anyPolicy and whose parent list is a | ||||
| single node with valid_policy of anyPolicy. | ||||
| (3) If the valid_policy_graph is not NULL and contains a node | ||||
| of depth n with the valid_policy anyPolicy, add it to | ||||
| valid_policy_node_set. | ||||
| (4) Compute authority_constrained_policy_set, a set of policy | ||||
| OIDs and associated qualifiers as follows. For each node | ||||
| in valid_policy_node_set: | ||||
| (i) Add the node's valid_policy to | ||||
| authority_constrained_policy_set. | ||||
| (ii) Collect all qualifiers in the node, its ancestors, | ||||
| and descendants and associate them with valid_policy. | ||||
| Applications that do not use policy qualifiers MAY | ||||
| skip this step to simplify processing. | ||||
| (5) Set user_constrained_policy_set to | ||||
| authority_constrained_policy_set. | ||||
| (6) If the user-initial-policy-set is not anyPolicy: | ||||
| (i) Remove any elements of user_constrained_policy_set | ||||
| which do not appear in user-initial-policy-set. | ||||
| (ii) If anyPolicy appears in | | (g) Calculate the user_constrained_policy_set as follows. The | |||
| authority_constrained_policy_set with qualifiers AP- | | user_constrained_policy_set is a set of policy OIDs, along | |||
| Q, for each OID P-OID in user-initial-policy-set | | with associated policy qualifiers. | |||
| which does not appear in user_constrained_policy_set, | | | |||
| add P-OID with qualifiers AP-Q to | | (1) If the valid_policy_graph is NULL, set | |||
| user_constrained_policy_set. | | valid_policy_node_set to the empty set. | |||
| | | ||||
| | (2) If the valid_policy_graph is not NULL, set | ||||
| | valid_policy_node_set to the set of policy nodes whose | ||||
| | valid_policy is not anyPolicy and whose parent list is a | ||||
| | single node with valid_policy of anyPolicy. | ||||
| | | ||||
| | (3) If the valid_policy_graph is not NULL and contains a | ||||
| | node of depth n with the valid_policy anyPolicy, add it | ||||
| | to valid_policy_node_set. | ||||
| | | ||||
| | (4) Compute authority_constrained_policy_set, a set of | ||||
| | policy OIDs and associated qualifiers as follows. For | ||||
| | each node in valid_policy_node_set: | ||||
| | | ||||
| | (i) Add the node's valid_policy to | ||||
| | authority_constrained_policy_set. | ||||
| | | ||||
| | (ii) Collect all qualifiers in the node, its ancestors, | ||||
| | and descendants and associate them with | ||||
| | valid_policy. Applications that do not use policy | ||||
| | qualifiers MAY skip this step to simplify | ||||
| | processing. | ||||
| | | ||||
| | (5) Set user_constrained_policy_set to | ||||
| | authority_constrained_policy_set. | ||||
| | | ||||
| | (6) If the user-initial-policy-set is not anyPolicy: | ||||
| | | ||||
| | (i) Remove any elements of user_constrained_policy_set | ||||
| | that do not appear in user-initial-policy-set. | ||||
| | | ||||
| | (ii) If anyPolicy appears in | ||||
| | authority_constrained_policy_set with qualifiers | ||||
| | AP-Q, for each OID P-OID in user-initial-policy- | ||||
| | set that does not appear in | ||||
| | user_constrained_policy_set, add P-OID with | ||||
| | qualifiers AP-Q to user_constrained_policy_set. | ||||
| Additionally, this update replaces the final paragraph as follows: | In addition, the final paragraph in Section 6.1.5 of [RFC5280] is | |||
| updated as follows: | ||||
| OLD: | OLD: | |||
| If either (1) the value of explicit_policy variable is greater | | If either (1) the value of explicit_policy variable is greater | |||
| than zero or (2) the valid_policy_tree is not NULL, then path | | than zero or (2) the valid_policy_tree is not NULL, then path | |||
| processing has succeeded. | | processing has succeeded. | |||
| NEW: | NEW: | |||
| If either (1) the value of explicit_policy is greater than zero or | | If either (1) the value of explicit_policy is greater than zero, | |||
| (2) the user_constrained_policy_set is not empty, then path | | or (2) the user_constrained_policy_set is not empty, then path | |||
| processing has succeeded. | | processing has succeeded. | |||
| 5.6. Updates to Section 6.1.6 | 5.6. Updates to Section 6.1.6 | |||
| This update replaces Section 6.1.6 of [RFC5280] with the following | The following replaces Section 6.1.6 of [RFC5280]: | |||
| text: | ||||
| If path processing succeeds, the procedure terminates, returning a | ||||
| success indication together with final value of the | ||||
| user_constrained_policy_set, the working_public_key, the | ||||
| working_public_key_algorithm, and the | ||||
| working_public_key_parameters. | ||||
| Note the original procedure described in [RFC5280] included a | ||||
| valid_policy_tree structure as part of the output. This structure | ||||
| grows exponentially in the size of the input, so computing it | ||||
| risks denial-of-service vulnerabilities in X.509-based | ||||
| applications, such as [CVE-2023-0464] and [CVE-2023-23524]. | ||||
| Accordingly, this output is deprecated. Computing this structure | ||||
| is NOT RECOMMENDED. | ||||
| An implementation which requires valid_policy_tree for | | If path processing succeeds, the procedure terminates, returning a | |||
| compatibility with legacy systems may compute it from | | success indication together with the final value of the | |||
| valid_policy_graph by recursively duplicating every multi-parent | | user_constrained_policy_set, the working_public_key, the | |||
| node. This may be done on-demand when the calling application | | working_public_key_algorithm, and the | |||
| first requests this output. However, this computation may consume | | working_public_key_parameters. | |||
| exponential time and memory, so such implementations SHOULD | | | |||
| mitigate denial-of-service in other ways, such as limiting the | | Note that the original procedure described in [RFC5280] included a | |||
| depth or size of the tree. | | valid_policy_tree structure as part of the output. This structure | |||
| | grows exponentially in the size of the input, so computing it | ||||
| | risks denial-of-service vulnerabilities in X.509-based | ||||
| | applications, such as [CVE-2023-0464] and [CVE-2023-23524]. | ||||
| | Accordingly, this output is deprecated. Computing this structure | ||||
| | is NOT RECOMMENDED. | ||||
| | | ||||
| | An implementation that requires valid_policy_tree for | ||||
| | compatibility with legacy systems may compute it from | ||||
| | valid_policy_graph by recursively duplicating every multi-parent | ||||
| | node. This may be done on-demand when the calling application | ||||
| | first requests this output. However, this computation may consume | ||||
| | exponential time and memory, so such implementations SHOULD | ||||
| | mitigate denial-of-service attacks in other ways, such as by | ||||
| | limiting the depth or size of the tree. | ||||
| 6. Other Mitigations | 6. Other Mitigations | |||
| X.509 implementations that are unable switch to the policy graph | X.509 implementations that are unable to switch to the policy graph | |||
| structure SHOULD mitigate the denial-of-service attack in other ways. | structure SHOULD mitigate the denial-of-service attack in other ways. | |||
| This section describes alternate mitigation and partial mitigation | This section describes alternate mitigation and partial mitigation | |||
| strategies. | strategies. | |||
| 6.1. Verify Signatures First | 6.1. Verify Signatures First | |||
| X.509 validators SHOULD verify signatures in certification paths | X.509 validators SHOULD verify signatures in certification paths | |||
| before or in conjunction with policy verification. This limits the | before or in conjunction with policy verification. This limits the | |||
| attack to entities in control of CA certificates. For some | attack to entities in control of CA certificates. For some | |||
| applications, this may be sufficient to mitigate the attack. | applications, this may be sufficient to mitigate the attack. | |||
| However, other applications may still be impacted. For example: | However, other applications may still be impacted, for example: | |||
| * Any application that evaluates an untrusted PKI, such as a hosting | * Any application that evaluates an untrusted PKI, such as a hosting | |||
| provider that evaluates a customer-supplied PKI | provider that evaluates a customer-supplied PKI | |||
| * Any application that evaluates an otherwise trusted PKI, but where | * Any application that evaluates an otherwise trusted PKI that | |||
| untrusted entities have technically-constrained intermediate | includes untrusted entities with technically constrained | |||
| certificates where policy mapping and path length are | intermediate certificates. If the intermediates do not constrain | |||
| unconstrained. | policy mapping or path length, those entities may be able to | |||
| perform this attack. | ||||
| 6.2. Limit Certificate Depth | 6.2. Limit Certificate Depth | |||
| The policy tree grows exponentially in the depth of a certification | The policy tree grows exponentially in the depth of a certification | |||
| path, so limiting the depth and certificate size can mitigate the | path, so limiting the depth and certificate size can mitigate the | |||
| attack. | attack. | |||
| However, this option may not be viable for all applications. Too low | However, this option may not be viable for all applications. Too low | |||
| of a limit may reject existing paths which the application wishes to | of a limit may reject existing paths that the application wishes to | |||
| accept. Too high of a limit may still admit a DoS attack for the | accept. Too high of a limit may still admit a denial-of-service | |||
| application. By modifying the example in Section 3.2 to increase the | attack for the application. By modifying the example in Section 3.2 | |||
| number of policies asserted in each certificate, an attacker could | to increase the number of policies asserted in each certificate, an | |||
| still achieve O(N^(depth/2)) scaling. | attacker could still achieve O(N^(depth/2)) scaling. | |||
| 6.3. Limit Policy Tree Size | 6.3. Limit Policy Tree Size | |||
| The attack can be mitigated by limiting the number of nodes in the | The attack can be mitigated by limiting the number of nodes in the | |||
| policy tree, and rejecting the certification path if this limit is | policy tree and rejecting the certification path if this limit is | |||
| reached. This limit should be set high enough to still admit | reached. This limit should be set high enough to still admit | |||
| existing valid certification paths for the application, but low | existing valid certification paths for the application but low enough | |||
| enough to no longer admit a DoS attack. | to no longer admit a denial-of-service attack. | |||
| 6.4. Inhibit Policy Mapping | 6.4. Inhibit Policy Mapping | |||
| If policy mapping is disabled via the initial-policy-mapping-inhibit | If policy mapping is disabled via the initial-policy-mapping-inhibit | |||
| setting (see Section 6.1.1 of [RFC5280]), the attack is mitigated. | setting (see Section 6.1.1 of [RFC5280]), the attack is mitigated. | |||
| This also significantly simplifies the X.509 implementation, which | This also significantly simplifies the X.509 implementation, which | |||
| reduces the risk of other security bugs. However, this will break | reduces the risk of other security bugs. However, this will break | |||
| compatibility with any existing certification paths which rely on | compatibility with any existing certification paths that rely on | |||
| policy mapping. | policy mapping. | |||
| To facilitate this mitigation, certificate authorities SHOULD NOT | To facilitate this mitigation, certificate authorities SHOULD NOT | |||
| issue certificates with the policy mappings extension | issue certificates with the policy mappings extension | |||
| (Section 4.2.1.5 of [RFC5280]). Applications maintaining policies | (Section 4.2.1.5 of [RFC5280]). Applications maintaining policies | |||
| for accepted trust anchors are RECOMMENDED to forbid this extension | for accepted trust anchors are RECOMMENDED to forbid this extension | |||
| in participating certificate authorities. | in participating certificate authorities. | |||
| 6.5. Disable Policy Checking | 6.5. Disable Policy Checking | |||
| An X.509 validator can mitigate this attack by disabling policy | An X.509 validator can mitigate this attack by disabling policy | |||
| validation entirely. This may be viable for applications which do | validation entirely. This may be viable for applications that do not | |||
| not require policy validation. In this case, critical policy-related | require policy validation. In this case, critical policy-related | |||
| extensions, notably the policy constraints (Section 4.2.1.11 of | extensions, notably the policy constraints extension | |||
| [RFC5280]), MUST be treated as unrecognized extensions as in | (Section 4.2.1.11 of [RFC5280]), MUST be treated as unrecognized | |||
| Section 4.2 of [RFC5280] and be rejected. | extensions as described in Section 4.2 of [RFC5280] and be rejected. | |||
| 7. Implementation Status | ||||
| This section is to be removed before publishing as an RFC. | ||||
| This section records the status of known implementations of the | ||||
| protocol defined by this specification at the time of posting of this | ||||
| Internet-Draft, and is based on a proposal described in RFC 7942. | ||||
| The description of implementations in this section is intended to | ||||
| assist the IETF in its decision processes in progressing drafts to | ||||
| RFCs. Please note that the listing of any individual implementation | ||||
| here does not imply endorsement by the IETF. Furthermore, no effort | ||||
| has been spent to verify the information presented here that was | ||||
| supplied by IETF contributors. This is not intended as, and must not | ||||
| be construed to be, a catalog of available implementations or their | ||||
| features. Readers are advised to note that other implementations may | ||||
| exist. | ||||
| According to RFC 7942, "this will allow reviewers and working groups | ||||
| to assign due consideration to documents that have the benefit of | ||||
| running code, which may serve as evidence of valuable experimentation | ||||
| and feedback that have made the implemented protocols more mature. | ||||
| It is up to the individual working groups to use this information as | ||||
| they see fit". | ||||
| The following projects adopted the concept outlined in this document: | ||||
| * [BoringSSL] | ||||
| * [LibreSSL] | ||||
| 8. Security Considerations | 7. Security Considerations | |||
| Section 3 discusses how [RFC5280]'s policy tree algorithm can lead to | Section 3 discusses how the policy tree algorithm in [RFC5280] can | |||
| denial-of-service vulnerabilities in X.509-based applications, such | lead to denial-of-service vulnerabilities in X.509-based | |||
| as [CVE-2023-0464] and [CVE-2023-23524]. | applications, such as [CVE-2023-0464] and [CVE-2023-23524]. | |||
| Section 5 replaces this algorithm to avoid this issue. As discussed | Section 5 replaces this algorithm to avoid this issue. As discussed | |||
| in Section 4.1, the new structure scales linearly with the input. | in Section 4.1, the new structure scales linearly with the input. | |||
| This means input limits in X.509 validators will more naturally bound | This means input limits in X.509 validators will more naturally bound | |||
| processing time, thus avoiding these vulnerabilities. | processing time, thus avoiding these vulnerabilities. | |||
| 9. IANA Considerations | 8. IANA Considerations | |||
| This document has no IANA actions. | This document has no IANA actions. | |||
| 10. References | 9. References | |||
| 10.1. Normative References | 9.1. Normative References | |||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <https://www.rfc-editor.org/rfc/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., | [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., | |||
| Housley, R., and W. Polk, "Internet X.509 Public Key | Housley, R., and W. Polk, "Internet X.509 Public Key | |||
| Infrastructure Certificate and Certificate Revocation List | Infrastructure Certificate and Certificate Revocation List | |||
| (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, | (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, | |||
| <https://www.rfc-editor.org/rfc/rfc5280>. | <https://www.rfc-editor.org/info/rfc5280>. | |||
| [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
| 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
| May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| 10.2. Informative References | ||||
| [BoringSSL] | 9.2. Informative References | |||
| "BoringSSL", January 2024, | ||||
| <https://boringssl.googlesource.com/boringssl>. | ||||
| [CVE-2023-0464] | [CVE-2023-0464] | |||
| "Excessive Resource Usage Verifying X.509 Policy | CVE, "Excessive Resource Usage Verifying X.509 Policy | |||
| Constraints", March 2023, | Constraints", CVE-2023-0464, March 2023, | |||
| <https://www.cve.org/CVERecord?id=CVE-2023-0464>. | <https://www.cve.org/CVERecord?id=CVE-2023-0464>. | |||
| [CVE-2023-23524] | [CVE-2023-23524] | |||
| "Processing a maliciously crafted certificate may lead to | CVE, "Processing a maliciously crafted certificate may | |||
| a denial-of-service", February 2023, | lead to a denial-of-service", CVE-2023-23524, February | |||
| <https://www.cve.org/CVERecord?id=CVE-2023-23524>. | 2023, <https://www.cve.org/CVERecord?id=CVE-2023-23524>. | |||
| [LibreSSL] "LibreSSL", January 2024, <https://www.libressl.org/>. | ||||
| [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
| Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
| <https://www.rfc-editor.org/rfc/rfc8446>. | <https://www.rfc-editor.org/info/rfc8446>. | |||
| [X.509] International Telecommunications Union, "Information | [X.509] ITU-T, "Information technology - Open Systems | |||
| technology - Open Systems Interconnection - The Directory: | Interconnection - The Directory: Public-key and attribute | |||
| Public-key and attribute certificate frameworks", | certificate frameworks", ITU-T Recommendation X.509, | |||
| ITU-T Recommendation X.509, October 2019. | October 2019, <https://www.itu.int/rec/T-REC-X.509>. | |||
| Acknowledgements | Acknowledgements | |||
| The author thanks Bob Beck, Adam Langley, Matt Mueller, and Ryan | The author thanks Bob Beck, Adam Langley, Matt Mueller, and Ryan | |||
| Sleevi for many valuable discussions that led to discovering this | Sleevi for many valuable discussions that led to discovering this | |||
| issue, understanding it, and developing the mitigation. The author | issue, understanding it, and developing the mitigation. The author | |||
| also thanks Martin Thomson and Job Snijders for feedback on this | also thanks Martin Thomson, Job Snijders, and John Scudder for their | |||
| document. | review and feedback on this document. | |||
| Author's Address | Author's Address | |||
| David Benjamin | David Benjamin | |||
| Google LLC | Google LLC | |||
| Email: davidben@google.com | Email: davidben@google.com | |||
| End of changes. 78 change blocks. | ||||
| 606 lines changed or deleted | 569 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||