| < draft-dkg-openpgp-abuse-resistant-keystore-04.txt | draft-dkg-openpgp-abuse-resistant-keystore-05.txt > | |||
|---|---|---|---|---|
| openpgp D. Gillmor | openpgp D. K. Gillmor | |||
| Internet-Draft ACLU | Internet-Draft ACLU | |||
| Intended status: Informational August 22, 2019 | Intended status: Informational 28 April 2022 | |||
| Expires: February 23, 2020 | Expires: 30 October 2022 | |||
| Abuse-Resistant OpenPGP Keystores | Abuse-Resistant OpenPGP Keystores | |||
| draft-dkg-openpgp-abuse-resistant-keystore-04 | draft-dkg-openpgp-abuse-resistant-keystore-05 | |||
| Abstract | Abstract | |||
| OpenPGP transferable public keys are composite certificates, made up | OpenPGP transferable public keys are composite certificates, made up | |||
| of primary keys, direct key signatures, user IDs, identity | of primary keys, revocation signatures, direct key signatures, user | |||
| certifications ("signature packets"), subkeys, and so on. They are | IDs, identity certifications ("signature packets"), subkeys, and so | |||
| often assembled by merging multiple certificates that all share the | on. They are often assembled by merging multiple certificates that | |||
| same primary key, and are distributed in public keystores. | all share the same primary key, and are distributed in public | |||
| keystores. | ||||
| Unfortunately, since many keystores permit any third-party to add a | Unfortunately, since many keystores permit any third-party to add a | |||
| certification with any content to any OpenPGP certificate, the | certification with any content to any OpenPGP certificate, the | |||
| assembled/merged form of a certificate can become unwieldy or | assembled/merged form of a certificate can become unwieldy or | |||
| undistributable. Furthermore, keystores that are searched by user ID | undistributable. Furthermore, keystores that are searched by user ID | |||
| or fingerprint can be made unusable for specific searches by public | or fingerprint can be made unusable for specific searches by public | |||
| submission of bogus certificates. And finally, keystores open to | submission of bogus certificates. And finally, keystores open to | |||
| public submission can also face simple resource exhaustion from | public submission can also face simple resource exhaustion from | |||
| flooding with bogus submissions, or legal or other risks from uploads | flooding with bogus submissions, or legal or other risks from uploads | |||
| of toxic data. | of toxic data. | |||
| This draft documents techniques that an archive of OpenPGP | This draft documents techniques that an archive of OpenPGP | |||
| certificates can use to mitigate the impact of these various attacks, | certificates can use to mitigate the impact of these various attacks, | |||
| and the implications of these concerns and mitigations for the rest | and the implications of these concerns and mitigations for the rest | |||
| of the OpenPGP ecosystem. | of the OpenPGP ecosystem. | |||
| About This Document | ||||
| This note is to be removed before publishing as an RFC. | ||||
| The latest revision of this draft can be found at | ||||
| https://dkg.gitlab.io/draft-openpgp-abuse-resistant-keystore/. | ||||
| Status information for this document may be found at | ||||
| https://datatracker.ietf.org/doc/draft-dkg-openpgp-abuse-resistant- | ||||
| keystore/. | ||||
| Discussion of this document takes place on the OpenPGP Working Group | ||||
| mailing list (mailto:openpgp@ietf.org), which is archived at | ||||
| https://mailarchive.ietf.org/arch/browse/openpgp/. | ||||
| Source for this draft and an issue tracker can be found at | ||||
| https://gitlab.com/dkg/draft-openpgp-abuse-resistant-keystore. | ||||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on February 23, 2020. | This Internet-Draft will expire on 30 October 2022. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2022 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 | Provisions Relating to IETF Documents (https://trustee.ietf.org/ | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | license-info) in effect on the date of publication of this document. | |||
| publication of this document. Please review these documents | Please review these documents carefully, as they describe your rights | |||
| carefully, as they describe your rights and restrictions with respect | and restrictions with respect to this document. Code Components | |||
| to this document. Code Components extracted from this document must | extracted from this document must include Revised BSD License text as | |||
| include Simplified BSD License text as described in Section 4.e of | described in Section 4.e of the Trust Legal Provisions and are | |||
| the Trust Legal Provisions and are provided without warranty as | provided without warranty as described in the Revised BSD License. | |||
| described in the Simplified BSD License. | ||||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
| 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 4 | 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 5 | |||
| 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 | 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
| 2. Problem Statement . . . . . . . . . . . . . . . . . . . . . . 7 | 2. Problem Statement . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 2.1. Certificate Flooding . . . . . . . . . . . . . . . . . . 7 | 2.1. Certificate Flooding . . . . . . . . . . . . . . . . . . 8 | |||
| 2.2. User ID Flooding . . . . . . . . . . . . . . . . . . . . 8 | 2.2. User ID Flooding . . . . . . . . . . . . . . . . . . . . 8 | |||
| 2.3. Fingerprint Flooding . . . . . . . . . . . . . . . . . . 8 | 2.3. Fingerprint Flooding . . . . . . . . . . . . . . . . . . 9 | |||
| 2.4. Keystore Flooding . . . . . . . . . . . . . . . . . . . . 9 | 2.4. Keystore Flooding . . . . . . . . . . . . . . . . . . . . 9 | |||
| 2.5. Toxic Data . . . . . . . . . . . . . . . . . . . . . . . 9 | 2.5. Toxic Data . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3. Keystore Interfaces . . . . . . . . . . . . . . . . . . . . . 9 | 3. Keystore Interfaces . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.1. Certificate Refresh . . . . . . . . . . . . . . . . . . . 10 | 3.1. Certificate Refresh . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.2. Certificate Discovery . . . . . . . . . . . . . . . . . . 10 | 3.2. Certificate Discovery . . . . . . . . . . . . . . . . . . 11 | |||
| 3.3. Certificate Lookup . . . . . . . . . . . . . . . . . . . 11 | 3.3. Certificate Lookup . . . . . . . . . . . . . . . . . . . 12 | |||
| 3.3.1. Full User ID Lookup . . . . . . . . . . . . . . . . . 11 | 3.3.1. Full User ID Lookup . . . . . . . . . . . . . . . . . 12 | |||
| 3.3.2. E-mail Address Lookup . . . . . . . . . . . . . . . . 12 | 3.3.2. E-mail Address Lookup . . . . . . . . . . . . . . . . 12 | |||
| 3.3.3. Other Lookup Mechanisms . . . . . . . . . . . . . . . 12 | 3.3.3. Other Lookup Mechanisms . . . . . . . . . . . . . . . 13 | |||
| 3.4. Certificate Validation . . . . . . . . . . . . . . . . . 12 | 3.4. Certificate Validation . . . . . . . . . . . . . . . . . 13 | |||
| 3.5. Certificate Submission . . . . . . . . . . . . . . . . . 14 | 3.5. Certificate Submission . . . . . . . . . . . . . . . . . 14 | |||
| 4. Simple Mitigations . . . . . . . . . . . . . . . . . . . . . 14 | 4. Simple Mitigations . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 4.1. Decline Large Packets . . . . . . . . . . . . . . . . . . 14 | 4.1. Decline Large Packets . . . . . . . . . . . . . . . . . . 15 | |||
| 4.2. Enforce Strict User IDs . . . . . . . . . . . . . . . . . 15 | 4.2. Enforce Strict User IDs . . . . . . . . . . . . . . . . . 15 | |||
| 4.3. Scoped User IDs . . . . . . . . . . . . . . . . . . . . . 15 | 4.3. Scoped User IDs . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 4.4. Strip or Standardize Unhashed Subpackets . . . . . . . . 15 | 4.4. Strip or Standardize Unhashed Subpackets . . . . . . . . 16 | |||
| 4.4.1. Issuer Fingerprint . . . . . . . . . . . . . . . . . 15 | 4.4.1. Issuer Fingerprint . . . . . . . . . . . . . . . . . 16 | |||
| 4.4.2. Cross-sigs . . . . . . . . . . . . . . . . . . . . . 15 | 4.4.2. Cross-sigs . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 4.4.3. First-party Attestations . . . . . . . . . . . . . . 16 | ||||
| 4.5. Decline User Attributes . . . . . . . . . . . . . . . . . 16 | 4.5. Decline User Attributes . . . . . . . . . . . . . . . . . 16 | |||
| 4.6. Decline Non-exportable Certifications . . . . . . . . . . 16 | 4.6. Decline Non-exportable Certifications . . . . . . . . . . 17 | |||
| 4.7. Decline Data From the Future . . . . . . . . . . . . . . 16 | 4.7. Decline Data From the Future . . . . . . . . . . . . . . 17 | |||
| 4.8. Accept Only Profiled Certifications . . . . . . . . . . . 16 | 4.8. Accept Only Profiled Certifications . . . . . . . . . . . 17 | |||
| 4.9. Accept Only Certificates Issued by Designated Authorities 17 | 4.9. Accept Only Certificates Issued by Designated | |||
| 4.10. Decline Packets by Blocklist . . . . . . . . . . . . . . 17 | Authorities . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| 5. Retrieval-time Mitigations . . . . . . . . . . . . . . . . . 18 | 4.10. Decline Packets by Blocklist . . . . . . . . . . . . . . 18 | |||
| 5.1. Redacting User IDs . . . . . . . . . . . . . . . . . . . 18 | 5. Retrieval-time Mitigations . . . . . . . . . . . . . . . . . 19 | |||
| 5.1. Redacting User IDs . . . . . . . . . . . . . . . . . . . 19 | ||||
| 5.1.1. Certificate Refresh with Redacted User IDs . . . . . 19 | 5.1.1. Certificate Refresh with Redacted User IDs . . . . . 19 | |||
| 5.1.2. Certificate Discovery with Redacted User IDs . . . . 19 | 5.1.2. Certificate Discovery with Redacted User IDs . . . . 20 | |||
| 5.1.3. Certificate Lookup with Redacted User IDs . . . . . . 20 | 5.1.3. Certificate Lookup with Redacted User IDs . . . . . . 20 | |||
| 5.1.4. Hinting Redacted User IDs . . . . . . . . . . . . . . 20 | 5.1.4. Hinting Redacted User IDs . . . . . . . . . . . . . . 21 | |||
| 5.1.5. User ID Recovery by Client Brute Force . . . . . . . 21 | 5.1.5. User ID Recovery by Client Brute Force . . . . . . . 21 | |||
| 5.2. Primary-key Only Certificate Refresh . . . . . . . . . . 21 | 5.2. Primary-key Only Certificate Refresh . . . . . . . . . . 21 | |||
| 5.3. Require Valid Cross-Sigs for Certificate Discovery . . . 21 | 5.3. Require Valid Cross-Sigs for Certificate Discovery . . . 22 | |||
| 6. Contextual Mitigations . . . . . . . . . . . . . . . . . . . 22 | 6. Contextual Mitigations . . . . . . . . . . . . . . . . . . . 23 | |||
| 6.1. Accept Only Cryptographically-verifiable Certifications . 22 | 6.1. Accept Only Cryptographically-verifiable | |||
| Certifications . . . . . . . . . . . . . . . . . . . . . 23 | ||||
| 6.2. Accept Only Certificates Issued by Known Certificates . . 23 | 6.2. Accept Only Certificates Issued by Known Certificates . . 23 | |||
| 6.3. Rate-limit Submissions by IP Address . . . . . . . . . . 23 | 6.3. Rate-limit Submissions by IP Address . . . . . . . . . . 24 | |||
| 6.4. Accept Certificates Based on Exterior Process . . . . . . 24 | 6.4. Accept Certificates Based on Exterior Process . . . . . . 24 | |||
| 6.5. Accept Certificates by E-mail Validation . . . . . . . . 24 | 6.5. Accept Certificates by E-mail Validation . . . . . . . . 24 | |||
| 7. Non-append-only mitigations . . . . . . . . . . . . . . . . . 24 | 7. Non-append-only mitigations . . . . . . . . . . . . . . . . . 25 | |||
| 7.1. Drop Superseded Signatures . . . . . . . . . . . . . . . 25 | 7.1. Drop Superseded Signatures . . . . . . . . . . . . . . . 25 | |||
| 7.2. Drop Expired Signatures . . . . . . . . . . . . . . . . . 25 | 7.2. Drop Expired Signatures . . . . . . . . . . . . . . . . . 26 | |||
| 7.3. Drop Dangling User IDs, User Attributes, and Subkeys . . 25 | 7.3. Drop Dangling User IDs, User Attributes, and Subkeys . . 26 | |||
| 7.4. Drop All Other Elements of a Directly-Revoked Certificate 26 | 7.4. Drop All Other Elements of a Directly-Revoked | |||
| 7.5. Implicit Expiration Date . . . . . . . . . . . . . . . . 26 | Certificate . . . . . . . . . . . . . . . . . . . . . . . 26 | |||
| 7.5. Implicit Expiration Date . . . . . . . . . . . . . . . . 27 | ||||
| 8. Primary Key Sovereignty . . . . . . . . . . . . . . . . . . . 27 | 8. Primary Key Sovereignty . . . . . . . . . . . . . . . . . . . 27 | |||
| 8.1. Refresh-only Keystores . . . . . . . . . . . . . . . . . 27 | 8.1. Refresh-only Keystores . . . . . . . . . . . . . . . . . 28 | |||
| 8.2. First-party-only Keystores . . . . . . . . . . . . . . . 28 | 8.2. First-party-only Keystores . . . . . . . . . . . . . . . 29 | |||
| 8.2.1. First-party-only Without User IDs . . . . . . . . . . 29 | 8.2.1. First-party-only Without User IDs . . . . . . . . . . 29 | |||
| 8.3. First-party-attested Third-party Certifications . . . . . 29 | 8.3. First-party-attested Third-party Certifications . . . . . 29 | |||
| 8.3.1. Client Interactions . . . . . . . . . . . . . . . . . 30 | 8.3.1. Client Interactions . . . . . . . . . . . . . . . . . 30 | |||
| 8.3.2. Attestation Revocations . . . . . . . . . . . . . . . 31 | 8.3.2. Revoking Third-party Certifications . . . . . . . . . 30 | |||
| 8.3.3. Distribution of Attestation Revocations . . . . . . . 32 | 9. Keystore Client Best Practices . . . . . . . . . . . . . . . 32 | |||
| 8.3.4. Revoking Third-party Certifications . . . . . . . . . 33 | 9.1. Use Constrained Keystores for Lookup . . . . . . . . . . 32 | |||
| 9. Keystore Client Best Practices . . . . . . . . . . . . . . . 35 | 9.2. Normalize Addresses and User IDs for Lookup . . . . . . . 32 | |||
| 9.1. Use Constrained Keystores for Lookup . . . . . . . . . . 35 | 9.3. Avoid Fuzzy Lookups . . . . . . . . . . . . . . . . . . . 32 | |||
| 9.2. Normalize Addresses and User IDs for Lookup . . . . . . . 35 | 9.4. Prefer Full Fingerprint for Discovery and Refresh . . . . 33 | |||
| 9.3. Avoid Fuzzy Lookups . . . . . . . . . . . . . . . . . . . 36 | 9.5. Use Caution with Keystore-provided Validation . . . . . . 33 | |||
| 9.4. Prefer Full Fingerprint for Discovery and Refresh . . . . 36 | 10. Certificate Generation and Management Best Practices . . . . 33 | |||
| 9.5. Use Caution with Keystore-provided Validation . . . . . . 36 | 10.1. Canonicalized E-Mail Addresses . . . . . . . . . . . . . 34 | |||
| 10. Certificate Generation and Management Best Practices . . . . 37 | 10.2. Normalized User IDs . . . . . . . . . . . . . . . . . . 34 | |||
| 10.1. Canonicalized E-Mail Addresses . . . . . . . . . . . . . 37 | 10.3. Avoid Large User Attributes . . . . . . . . . . . . . . 34 | |||
| 10.2. Normalized User IDs . . . . . . . . . . . . . . . . . . 37 | 10.4. Provide Cross-Sigs . . . . . . . . . . . . . . . . . . . 34 | |||
| 10.3. Avoid Large User Attributes . . . . . . . . . . . . . . 37 | 10.5. Provide Issuer Fingerprint Subpackets . . . . . . . . . 35 | |||
| 10.4. Provide Cross-Sigs . . . . . . . . . . . . . . . . . . . 37 | ||||
| 10.5. Provide Issuer Fingerprint Subpackets . . . . . . . . . 38 | ||||
| 10.6. Put Cross-Sigs and Issuer Fingerprint in Hashed | 10.6. Put Cross-Sigs and Issuer Fingerprint in Hashed | |||
| Subpackets . . . . . . . . . . . . . . . . . . . . . . . 38 | Subpackets . . . . . . . . . . . . . . . . . . . . . . . 35 | |||
| 10.7. Submit Certificates to Restricted, Lookup-Capable | 10.7. Submit Certificates to Restricted, Lookup-Capable | |||
| Keystores . . . . . . . . . . . . . . . . . . . . . . . 38 | Keystores . . . . . . . . . . . . . . . . . . . . . . . 35 | |||
| 11. Side Effects and Ecosystem Impacts . . . . . . . . . . . . . 38 | 11. Side Effects and Ecosystem Impacts . . . . . . . . . . . . . 35 | |||
| 11.1. Designated Revoker . . . . . . . . . . . . . . . . . . . 38 | 11.1. Designated Revoker . . . . . . . . . . . . . . . . . . . 35 | |||
| 11.2. Key IDs vs. Fingerprints in Certificate Discovery . . . 39 | 11.2. Key IDs vs. Fingerprints in Certificate Discovery . . . 36 | |||
| 11.3. In-band Certificates . . . . . . . . . . . . . . . . . . 39 | 11.3. In-band Certificates . . . . . . . . . . . . . . . . . . 36 | |||
| 11.3.1. In-band Certificate Minimization and Validity . . . 40 | 11.3.1. In-band Certificate Minimization and Validity . . . 37 | |||
| 11.4. Certification-capable Subkeys . . . . . . . . . . . . . 41 | 11.4. Certification-capable Subkeys . . . . . . . . . . . . . 38 | |||
| 11.5. Assessing Certificates in the Past . . . . . . . . . . . 41 | 11.5. Assessing Certificates in the Past . . . . . . . . . . . 38 | |||
| 11.5.1. Point-in-time Certificate Evaluation . . . . . . . . 41 | 11.5.1. Point-in-time Certificate Evaluation . . . . . . . . 39 | |||
| 11.5.2. Signature Verification and Non-append-only Keystores 42 | 11.5.2. Signature Verification and Non-append-only | |||
| 11.6. Global Append-only Ledgers ("Blockchain") . . . . . . . 42 | Keystores . . . . . . . . . . . . . . . . . . . . . . 39 | |||
| 11.7. Certificate Lookup for Identity Monitoring . . . . . . . 43 | 11.6. Global Append-only Ledgers ("Blockchain") . . . . . . . 39 | |||
| 12. OpenPGP details . . . . . . . . . . . . . . . . . . . . . . . 44 | 11.7. Certificate Lookup for Identity Monitoring . . . . . . . 41 | |||
| 12.1. Revocations . . . . . . . . . . . . . . . . . . . . . . 44 | 12. OpenPGP details . . . . . . . . . . . . . . . . . . . . . . . 41 | |||
| 12.2. User ID Conventions . . . . . . . . . . . . . . . . . . 45 | 12.1. Revocations . . . . . . . . . . . . . . . . . . . . . . 41 | |||
| 12.3. E-mail Address Canonicalization . . . . . . . . . . . . 46 | 12.2. User ID Conventions . . . . . . . . . . . . . . . . . . 42 | |||
| 12.3.1. Disallowing Non-UTF-8 Local Parts . . . . . . . . . 46 | 12.3. E-mail Address Canonicalization . . . . . . . . . . . . 43 | |||
| 12.3.2. Domain Canonicalization . . . . . . . . . . . . . . 46 | 12.3.1. Disallowing Non-UTF-8 Local Parts . . . . . . . . . 43 | |||
| 12.3.3. Local Part Canonicalization . . . . . . . . . . . . 46 | 12.3.2. Domain Canonicalization . . . . . . . . . . . . . . 43 | |||
| 13. Security Considerations . . . . . . . . . . . . . . . . . . . 46 | 12.3.3. Local Part Canonicalization . . . . . . . . . . . . 43 | |||
| 13. Security Considerations . . . . . . . . . . . . . . . . . . . 43 | ||||
| 13.1. Tension Between Unrestricted Uploads and Certificate | 13.1. Tension Between Unrestricted Uploads and Certificate | |||
| Lookup . . . . . . . . . . . . . . . . . . . . . . . . . 47 | Lookup . . . . . . . . . . . . . . . . . . . . . . . . . 44 | |||
| 14. Privacy Considerations . . . . . . . . . . . . . . . . . . . 47 | 14. Privacy Considerations . . . . . . . . . . . . . . . . . . . 44 | |||
| 14.1. Publishing Identity Information . . . . . . . . . . . . 47 | 14.1. Publishing Identity Information . . . . . . . . . . . . 44 | |||
| 14.2. Social Graph . . . . . . . . . . . . . . . . . . . . . . 48 | 14.2. Social Graph . . . . . . . . . . . . . . . . . . . . . . 45 | |||
| 14.3. Tracking Clients by Queries . . . . . . . . . . . . . . 48 | 14.3. Tracking Clients by Queries . . . . . . . . . . . . . . 45 | |||
| 14.4. "Live" Certificate Validation Leaks Client Activity . . 49 | 14.4. "Live" Certificate Validation Leaks Client Activity . . 46 | |||
| 14.5. Certificate Discovery Leaks Client Activity . . . . . . 49 | 14.5. Certificate Discovery Leaks Client Activity . . . . . . 46 | |||
| 14.6. Certificate Refresh Leaks Client Activity . . . . . . . 50 | 14.6. Certificate Refresh Leaks Client Activity . . . . . . . 47 | |||
| 14.7. Distinct Keystore Interfaces Leak Client Context and | 14.7. Distinct Keystore Interfaces Leak Client Context and | |||
| Intent . . . . . . . . . . . . . . . . . . . . . . . . . 50 | Intent . . . . . . . . . . . . . . . . . . . . . . . . . 47 | |||
| 14.8. Cleartext Queries . . . . . . . . . . . . . . . . . . . 51 | 14.8. Cleartext Queries . . . . . . . . . . . . . . . . . . . 48 | |||
| 14.9. Traffic Analysis . . . . . . . . . . . . . . . . . . . . 51 | 14.9. Traffic Analysis . . . . . . . . . . . . . . . . . . . . 48 | |||
| 15. User Considerations . . . . . . . . . . . . . . . . . . . . . 51 | 15. User Considerations . . . . . . . . . . . . . . . . . . . . . 49 | |||
| 16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 52 | 16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 49 | |||
| 17. Document Considerations . . . . . . . . . . . . . . . . . . . 52 | 16.1. Document History . . . . . . . . . . . . . . . . . . . . 49 | |||
| 17.1. Document History . . . . . . . . . . . . . . . . . . . . 52 | 17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 51 | |||
| 18. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 54 | 18. References . . . . . . . . . . . . . . . . . . . . . . . . . 52 | |||
| 19. References . . . . . . . . . . . . . . . . . . . . . . . . . 55 | 18.1. Normative References . . . . . . . . . . . . . . . . . . 52 | |||
| 19.1. Normative References . . . . . . . . . . . . . . . . . . 55 | 18.2. Informative References . . . . . . . . . . . . . . . . . 53 | |||
| 19.2. Informative References . . . . . . . . . . . . . . . . . 56 | Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 55 | |||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 58 | ||||
| 1. Introduction | 1. Introduction | |||
| 1.1. Requirements Language | 1.1. Requirements Language | |||
| 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 BCP | |||
| 14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
| capitals, as shown here. | capitals, as shown here. | |||
| 1.2. Terminology | 1.2. Terminology | |||
| o "OpenPGP certificate" (or just "certificate") is used | * "OpenPGP certificate" (or just "certificate") is used | |||
| interchangeably with [RFC4880]'s "Transferable Public Key". The | interchangeably with [RFC4880]'s "Transferable Public Key". The | |||
| term "certificate" refers unambiguously to the entire composite | term "certificate" refers unambiguously to the entire composite | |||
| object, unlike "key", which might also be used to refer to a | object, unlike "key", which might also be used to refer to a | |||
| primary key or subkey. | primary key or subkey. | |||
| o An "identity certification" (or just "certification") is an | * An "identity certification" (or just "certification") is an | |||
| [RFC4880] signature packet that covers OpenPGP identity | [RFC4880] signature packet that covers OpenPGP identity | |||
| information - that is, any signature packet of type 0x10, 0x11, | information -- that is, any signature packet of type 0x10, 0x11, | |||
| 0x12, or 0x13. Certifications are said to (try to) "bind" a | 0x12, or 0x13. Certifications are said to (try to) "bind" a | |||
| primary key to a User ID. | primary key to a User ID. | |||
| o The primary key that makes the certification is known as the | * The primary key that makes the certification is known as the | |||
| "issuer". The primary key over which the certification is made is | "issuer". The primary key over which the certification is made is | |||
| known as the "subject". | known as the "subject". | |||
| o A "first-party certification" is issued by the primary key of a | * A "first-party certification" is issued by the primary key of a | |||
| certificate, and binds itself to a user ID in the certificate. | certificate, and binds itself to a user ID in the certificate. | |||
| That is, the issuer is the same as the subject. This is sometimes | That is, the issuer is the same as the subject. This is sometimes | |||
| referred to as a "self-sig". | referred to as a "self-sig". | |||
| o A "third-party certification" is a made over a primary key and | * A "third-party certification" is a made over a primary key and | |||
| user ID by some other certification-capable primary key. That is, | user ID by some other certification-capable primary key. That is, | |||
| the issuer is different than the subject. The elusive "second- | the issuer is different than the subject. The elusive "second- | |||
| party" is presumed to be the verifier who is trying to interpret | party" is presumed to be the verifier who is trying to interpret | |||
| the certificate. | the certificate. | |||
| o All subkeys are bound to the primary key with an [RFC4880] Subkey | * All subkeys are bound to the primary key with an [RFC4880] Subkey | |||
| Binding Signature. Some subkeys also reciprocate by binding | Binding Signature. Some subkeys also reciprocate by binding | |||
| themselves back to the primary key with an [RFC4880] Primary Key | themselves back to the primary key with an [RFC4880] Primary Key | |||
| Binding Signature. The Primary Key Binding Signature is also | Binding Signature. The Primary Key Binding Signature is also | |||
| known as a "cross-signature" or "cross-sig". | known as a "cross-signature" or "cross-sig". | |||
| o A "keystore" is any collection of OpenPGP certificates. Keystores | * A "keystore" is any collection of OpenPGP certificates. Keystores | |||
| typically receive mergeable updates over the course of their | typically receive mergeable updates over the course of their | |||
| lifetime which might add to the set of OpenPGP certificates they | lifetime which might add to the set of OpenPGP certificates they | |||
| hold, or update the certificates. | hold, or update the certificates. | |||
| o "Certificate validation" is the process whereby a user decides | * "Certificate validation" is the process whereby a user decides | |||
| whether a given user ID in an OpenPGP certificate is acceptable | whether a given user ID in an OpenPGP certificate is acceptable | |||
| for use. For example, if the certificate has a user ID of "Alice | for use. For example, if the certificate has a user ID of Alice | |||
| <alice@example.org>" and the user wants to send an e-mail to | <alice@example.org> and the user wants to send an e-mail to | |||
| "alice@example.org", the mail user agent might want to ensure that | alice@example.org, the mail user agent might want to ensure that | |||
| the certificate is valid for this e-mail address before encrypting | the certificate is valid for this e-mail address before encrypting | |||
| to it. Some clients may rely on specific keystores for | to it. Some clients may rely on specific keystores for | |||
| certificate validation, but some keystores (e.g., [SKS]) make no | certificate validation, but some keystores (e.g., [SKS]) make no | |||
| assertions whatsoever about certificate validity, and others offer | assertions whatsoever about certificate validity, and others offer | |||
| only very subtle guarantees. See Section 3.4 for more details. | only very subtle guarantees. See Section 3.4 for more details. | |||
| o "Certificate lookup" refers to the retrieval of a set of | * "Certificate lookup" refers to the retrieval of a set of | |||
| certificates from a keystore based on the user ID or some | certificates from a keystore based on the user ID or some | |||
| substring match of the user ID. See Section 3.3 for more details. | substring match of the user ID. See Section 3.3 for more details. | |||
| o "Certificate refresh" refers to retrieval of a certificate from a | * "Certificate refresh" refers to retrieval of a certificate from a | |||
| keystore based on the fingerprint of the primary key. See | keystore based on the fingerprint of the primary key. See | |||
| Section 3.1 for more details. | Section 3.1 for more details. | |||
| o "Certificate discovery" refers to the retrieval of a set of | * "Certificate discovery" refers to the retrieval of a set of | |||
| certificates from a keystore based on the fingerprint or key ID of | certificates from a keystore based on the fingerprint or key ID of | |||
| any key in the certificate. See Section 3.2 for more details. | any key in the certificate. See Section 3.2 for more details. | |||
| o A "keyserver" is a particular kind of keystore, typically a means | * A "keyserver" is a particular kind of keystore, typically a means | |||
| of publicly distributing OpenPGP certificates or updates to them. | of publicly distributing OpenPGP certificates or updates to them. | |||
| Examples of keyserver software include [SKS] and | Examples of keyserver software include [SKS] and | |||
| [MAILVELOPE-KEYSERVER]. One common HTTP interface for keyservers | [MAILVELOPE-KEYSERVER]. One common HTTP interface for keyservers | |||
| is [I-D.shaw-openpgp-hkp]. | is [I-D.shaw-openpgp-hkp]. | |||
| o A "synchronizing keyserver" is a keyserver which gossips with | * A "synchronizing keyserver" is a keyserver which gossips with | |||
| other peers, and typically acts as an append-only log. Such a | other peers, and typically acts as an append-only log. Such a | |||
| keyserver is typically useful for certificate lookup, certificate | keyserver is typically useful for certificate lookup, certificate | |||
| discovery, and certificate refresh (including revocation | discovery, and certificate refresh (including revocation | |||
| information). They are typically _not_ useful for certificate | information). They are typically _not_ useful for certificate | |||
| validation, since they make no assertions about whether the | validation, since they make no assertions about whether the | |||
| identities in the certificates they server are accurate. As of | identities in the certificates they server are accurate. As of | |||
| the writing of this document, [SKS] is the canonical synchronizing | the writing of this document, [SKS] is the canonical synchronizing | |||
| keyserver implementation, though other implementations exist. | keyserver implementation, though other implementations exist. | |||
| o An "e-mail validating keyserver" is a keyserver which attempts to | * An "e-mail validating keyserver" is a keyserver which attempts to | |||
| verify the identity in an OpenPGP certificate's user ID by | verify the identity in an OpenPGP certificate's user ID by | |||
| confirming access to the e-mail account, and optionally by | confirming access to the e-mail account, and optionally by | |||
| confirming access to the secret key. Some implementations permit | confirming access to the secret key. Some implementations permit | |||
| removal of a certificate by anyone who can prove access to the | removal of a certificate by anyone who can prove access to the | |||
| e-mail address in question. They are useful for certificate | e-mail address in question. They are useful for certificate | |||
| lookup based on e-mail address and certificate validation (by | lookup based on e-mail address and certificate validation (by | |||
| users who trust the operator), but some may not be useful for | users who trust the operator), but some may not be useful for | |||
| certificate refresh or certificate discovery, since a certificate | certificate refresh or certificate discovery, since a certificate | |||
| could be simply replaced by an adversary who also has access to | could be simply replaced by an adversary who also has access to | |||
| the e-mail address in question. [MAILVELOPE-KEYSERVER] is an | the e-mail address in question. [MAILVELOPE-KEYSERVER] is an | |||
| example of such a keyserver. | example of such a keyserver. | |||
| o A "sovereignty-respecting" keystore is one that only distributes | * A "sovereignty-respecting" keystore is one that only distributes | |||
| data associated with a given certificate that has been explicitly | data associated with a given certificate that has been explicitly | |||
| approved by the primary key of that certificate. See Section 8 | approved by the primary key of that certificate. See Section 8 | |||
| for more details and example strategies. | for more details and example strategies. | |||
| o "Cryptographic validity" refers to mathematical evidence that a | * "Cryptographic validity" refers to mathematical evidence that a | |||
| signature came from the secret key associated with the public key | signature came from the secret key associated with the public key | |||
| it claims to come from. Note that a certification may be | it claims to come from. Note that a certification may be | |||
| cryptographically valid without the signed data being true (for | cryptographically valid without the signed data being true (for | |||
| example, a given certificate with the user ID "Alice | example, a given certificate with the user ID Alice | |||
| <alice@example.org>" might not belong to the person who controls | <alice@example.org> might not belong to the person who controls | |||
| the e-mail address "alice@example.org" even though the self-sig is | the e-mail address alice@example.org even though the self-sig is | |||
| cryptographically valid). In particular, cryptographic validity | cryptographically valid). In particular, cryptographic validity | |||
| for user ID in a certificate is typically insufficient evidence | for user ID in a certificate is typically insufficient evidence | |||
| for certificate validation. Also note that knowledge of the | for certificate validation. Also note that knowledge of the | |||
| public key of the issuer is necessary to determine whether any | public key of the issuer is necessary to determine whether any | |||
| given signature is cryptographically valid. Some keyservers | given signature is cryptographically valid. Some keyservers | |||
| perform cryptographic validation in some contexts. Other | perform cryptographic validation in some contexts. Other | |||
| keyservers (like [SKS]) perform no cryptographic validation | keyservers (like [SKS]) perform no cryptographic validation | |||
| whatsoever. | whatsoever. | |||
| o OpenPGP revocations can have "Reason for Revocation" (see | * OpenPGP revocations can have "Reason for Revocation" (see | |||
| [RFC4880]), which can be either "soft" or "hard". The set of | [RFC4880]), which can be either "soft" or "hard". The set of | |||
| "soft" reasons is: "Key is superseded" and "Key is retired and no | "soft" reasons is: "Key is superseded" and "Key is retired and no | |||
| longer used". All other reasons (and revocations that do not | longer used". All other reasons (and revocations that do not | |||
| state a reason) are "hard" revocations. See Section 12.1 for more | state a reason) are "hard" revocations. See Section 12.1 for more | |||
| detail. | detail. | |||
| 2. Problem Statement | 2. Problem Statement | |||
| OpenPGP keystores that handle submissions from the public are subject | OpenPGP keystores that handle submissions from the public are subject | |||
| to a range of attacks by malicious submitters. | to a range of attacks by malicious submitters. | |||
| skipping to change at page 8, line 24 ¶ | skipping to change at page 8, line 52 ¶ | |||
| Public keystores that are used for certificate lookup may also be | Public keystores that are used for certificate lookup may also be | |||
| vulnerable to attacks that flood the space of known user IDs. In | vulnerable to attacks that flood the space of known user IDs. In | |||
| particular, if the keystore accepts arbitrary certificates from the | particular, if the keystore accepts arbitrary certificates from the | |||
| public and does no verification of the user IDs, then any client | public and does no verification of the user IDs, then any client | |||
| searching for a given user ID may need to review and process an | searching for a given user ID may need to review and process an | |||
| effectively unbounded set of maliciously-submitted certificates to | effectively unbounded set of maliciously-submitted certificates to | |||
| find the non-malicious certificates they are looking for. | find the non-malicious certificates they are looking for. | |||
| For example, if an attacker knows that a given system consults a | For example, if an attacker knows that a given system consults a | |||
| keystore looking for certificates which match the e-mail address | keystore looking for certificates which match the e-mail address | |||
| "alice@example.org", the attacker may upload thousands of | alice@example.org, the attacker may upload thousands of certificates | |||
| certificates containing user IDs that match that address. Even if | containing user IDs that match that address. Even if those | |||
| those certificates would not be accepted by a client (e.g., because | certificates would not be accepted by a client (e.g., because they | |||
| they were not certified by a known-good authority), the client still | were not certified by a known-good authority), the client still has | |||
| has to iterate through all of them in order to find the non-malicious | to iterate through all of them in order to find the non-malicious | |||
| certificates. | certificates. | |||
| User ID flooding is only effective if the keystore offers a lookup | User ID flooding is only effective if the keystore offers a lookup | |||
| interface at all. | interface at all. | |||
| 2.3. Fingerprint Flooding | 2.3. Fingerprint Flooding | |||
| A malicious actor who wants to render a certificate unavailable for | A malicious actor who wants to render a certificate unavailable for | |||
| refresh may generate an arbitrary number of OpenPGP certificates with | refresh may generate an arbitrary number of OpenPGP certificates with | |||
| the targeted primary key attached as a subkey. If they can convince | the targeted primary key attached as a subkey. If they can convince | |||
| skipping to change at page 10, line 41 ¶ | skipping to change at page 11, line 22 ¶ | |||
| cannot verify because it does not know the issuing certificate, it | cannot verify because it does not know the issuing certificate, it | |||
| may consult a keystore to try to discover the certificate based on | may consult a keystore to try to discover the certificate based on | |||
| the Issuer or Issuer Fingerprint subpacket in the signature or | the Issuer or Issuer Fingerprint subpacket in the signature or | |||
| certification it is trying to validate. | certification it is trying to validate. | |||
| keystore.cert_discovery(keyid|fpr) -> certificate_list | keystore.cert_discovery(keyid|fpr) -> certificate_list | |||
| This is subtly different from certificate refresh (Section 3.1) in | This is subtly different from certificate refresh (Section 3.1) in | |||
| three ways: | three ways: | |||
| o it may return more than one certificate (e.g., when multiple | * it may return more than one certificate (e.g., when multiple | |||
| certificates share a subkey, or when a primary key on one | certificates share a subkey, or when a primary key on one | |||
| certificate is a subkey on another) | certificate is a subkey on another) | |||
| o it is willing to accept searches by short key ID, not just | * it is willing to accept searches by short key ID, not just | |||
| fingerprint | fingerprint | |||
| o it is willing to match against a subkey, not just a primary key | * it is willing to match against a subkey, not just a primary key | |||
| While a certificate discovery client does not initially know the | While a certificate discovery client does not initially know the | |||
| certificate it is looking for, it's possible that the returned | certificate it is looking for, it's possible that the returned | |||
| certificate is one that the client already knows about. For example, | certificate is one that the client already knows about. For example, | |||
| a new subkey may have been added to a certificate. | a new subkey may have been added to a certificate. | |||
| Upon successful discovery, the client SHOULD merge any retrieved | Upon successful discovery, the client SHOULD merge any retrieved | |||
| certificates with discovered local copies (as determined by primary | certificates with discovered local copies (as determined by primary | |||
| key), and then evaluate the original signature against any retrieved | key), and then evaluate the original signature against any retrieved | |||
| certificate that appears to be valid and reasonable for use in the | certificate that appears to be valid and reasonable for use in the | |||
| skipping to change at page 12, line 4 ¶ | skipping to change at page 12, line 34 ¶ | |||
| distinguish interfaces that perform full-string-match lookup from | distinguish interfaces that perform full-string-match lookup from | |||
| interfaces that perform e-mail address based lookup. | interfaces that perform e-mail address based lookup. | |||
| 3.3.1. Full User ID Lookup | 3.3.1. Full User ID Lookup | |||
| The most straightforward form of certificate lookup asks for the set | The most straightforward form of certificate lookup asks for the set | |||
| of all certificates that contain a user ID that exactly and | of all certificates that contain a user ID that exactly and | |||
| completely matches the query parameter supplied by the client. | completely matches the query parameter supplied by the client. | |||
| keystore.cert_lookup(uid) -> certificate_list | keystore.cert_lookup(uid) -> certificate_list | |||
| In its simplest form, this match is done by a simple bytestring | In its simplest form, this match is done by a simple bytestring | |||
| comparison. More sophisticated keystores MAY perform the comparison | comparison. More sophisticated keystores MAY perform the comparison | |||
| after applying [UNICODE-NORMALIZATION] form NFC to both the "uid" | after applying [UNICODE-NORMALIZATION] form NFC to both the uid query | |||
| query and the user IDs from the stored certificates. | and the user IDs from the stored certificates. | |||
| 3.3.2. E-mail Address Lookup | 3.3.2. E-mail Address Lookup | |||
| However, some common use cases look for specific patterns in the user | However, some common use cases look for specific patterns in the user | |||
| ID rather than the entire user ID. Most useful to many existing | ID rather than the entire user ID. Most useful to many existing | |||
| OpenPGP clients is a lookup by e-mail address. | OpenPGP clients is a lookup by e-mail address. | |||
| keystore.cert_lookup(addr) -> certificate_list | keystore.cert_lookup(addr) -> certificate_list | |||
| For certificates with a user ID that matches the structure of an | For certificates with a user ID that matches the structure of an | |||
| [RFC5322] "name-addr" or "addr-spec", a keystore SHOULD extract the | [RFC5322] name-addr or addr-spec, a keystore SHOULD extract the addr- | |||
| "addr-spec" from the user ID, canonicalize it (see Section 12.3), and | spec from the user ID, canonicalize it (see Section 12.3), and | |||
| compare it to the canonicalized form of of the "addr" query | compare it to the canonicalized form of of the addr query parameter. | |||
| parameter. | ||||
| 3.3.3. Other Lookup Mechanisms | 3.3.3. Other Lookup Mechanisms | |||
| Some keystores offer other forms of substring or regular expression | Some keystores offer other forms of substring or regular expression | |||
| matching against the stored user IDs. These other forms of lookup | matching against the stored user IDs. These other forms of lookup | |||
| may be useful in some contexts (e.g., Section 11.7), but they may | may be useful in some contexts (e.g., Section 11.7), but they may | |||
| also represent privacy concerns (e.g., Section 14.1), and they may | also represent privacy concerns (e.g., Section 14.1), and they may | |||
| impose additional computational or indexing burdens on the keystore. | impose additional computational or indexing burdens on the keystore. | |||
| 3.4. Certificate Validation | 3.4. Certificate Validation | |||
| An OpenPGP client may assess certificate and user ID validity based | An OpenPGP client may assess certificate and user ID validity based | |||
| on many factors, some of which are directly contained in the | on many factors, some of which are directly contained in the | |||
| certificate itself (e.g., third-party certifications), and some of | certificate itself (e.g., third-party certifications), and some of | |||
| which are based on the context known to the client, including: | which are based on the context known to the client, including: | |||
| o Whether it has seen e-mails from that address signed by that | * Whether it has seen e-mails from that address signed by that | |||
| certificate in the past, | certificate in the past, | |||
| o How long it has known about the certificate, | * How long it has known about the certificate, | |||
| o Whether the certificate was fetched from a keystore that asserts | * Whether the certificate was fetched from a keystore that asserts | |||
| validity of the user ID or some part of it (such as the e-mail | validity of the user ID or some part of it (such as the e-mail | |||
| address). | address). | |||
| A keystore MAY facilitate clients pursuing this last point of | A keystore MAY facilitate clients pursuing this last point of | |||
| contextual corroboration via a direct interface: | contextual corroboration via a direct interface: | |||
| keystore.cert_validate(primary_fpr, uid) -> boolean | keystore.cert_validate(primary_fpr, uid) -> boolean | |||
| In an e-mail-specific context, the client might only care about the | In an e-mail-specific context, the client might only care about the | |||
| keystore's opinion about the validity of the certificate for the | keystore's opinion about the validity of the certificate for the | |||
| e-mail address portion of the user ID only: | e-mail address portion of the user ID only: | |||
| keystore.cert_validate(primary_fpr, addr) -> boolean | keystore.cert_validate(primary_fpr, addr) -> boolean | |||
| For some keystores, the presence of a certificate in the keystore | For some keystores, the presence of a certificate in the keystore | |||
| alone implies that the keystore asserts the validity of all user IDs | alone implies that the keystore asserts the validity of all user IDs | |||
| in the certificate retrieved. For others, the presence in the | in the certificate retrieved. For others, the presence in the | |||
| keystore applies only to some part of the user ID. For example, | keystore applies only to some part of the user ID. For example, | |||
| [PGP-GLOBAL-DIRECTORY] will only return user IDs that have completed | [PGP-GLOBAL-DIRECTORY] will only return user IDs that have completed | |||
| an e-mail validation step, so presence in that keystore implies an | an e-mail validation step, so presence in that keystore implies an | |||
| assertion of validity of the e-mail address part of the user IDs | assertion of validity of the e-mail address part of the user IDs | |||
| returned, but makes no claim about the "display-name" portion of any | returned, but makes no claim about the display-name portion of any | |||
| returned user IDs. Note that a client retrieving a certificate from | returned user IDs. Note that a client retrieving a certificate from | |||
| such a keystore may merge the certificate with a local copy - but the | such a keystore may merge the certificate with a local copy -- but | |||
| validity asserted by the keystore of course has no bearing on the | the validity asserted by the keystore of course has no bearing on the | |||
| packets that the keystore did not return. | packets that the keystore did not return. | |||
| In a more subtle example, the retrieval of a certificate looked up | In a more subtle example, the retrieval of a certificate looked up | |||
| via WKD ([I-D.koch-openpgp-webkey-service]) or DANE ([RFC7929]) | via WKD ([I-D.koch-openpgp-webkey-service]) or DANE ([RFC7929]) | |||
| should only be interpreted as a claim of validity about any user ID | should only be interpreted as a claim of validity about any user ID | |||
| which matches the e-mail address by which the certificate was looked | which matches the e-mail address by which the certificate was looked | |||
| up, with no claims made about any "display-name" portions, or about | up, with no claims made about any display-name portions, or about any | |||
| any user ID that doesn't match the queried e-mail address at all. | user ID that doesn't match the queried e-mail address at all. | |||
| A keystore that offers some sort of validation interface may also | A keystore that offers some sort of validation interface may also | |||
| change its opinion about the validity of a given certificate or user | change its opinion about the validity of a given certificate or user | |||
| ID over time; the interface described above only allows the client to | ID over time; the interface described above only allows the client to | |||
| ask about the keystore's current opinion, but a more complex | ask about the keystore's current opinion, but a more complex | |||
| interface might be capable of describing the keystore's assertion | interface might be capable of describing the keystore's assertion | |||
| over time. See also Section 11.5. | over time. See also Section 11.5. | |||
| An abuse-resistant keystore that clients rely on for any part of | An abuse-resistant keystore that clients rely on for any part of | |||
| their certificate validation process SHOULD offer a distinct | their certificate validation process SHOULD offer a distinct | |||
| skipping to change at page 14, line 13 ¶ | skipping to change at page 14, line 43 ¶ | |||
| their own inference about validity based on other factors. A | their own inference about validity based on other factors. A | |||
| keystore MAY offer a more nuanced validity interface; if it does, it | keystore MAY offer a more nuanced validity interface; if it does, it | |||
| SHOULD explicitly document the semantics of the different response | SHOULD explicitly document the semantics of the different response | |||
| types so that clients can make appropriate judgment. | types so that clients can make appropriate judgment. | |||
| 3.5. Certificate Submission | 3.5. Certificate Submission | |||
| Different keystores have different ways to submit a certificate for | Different keystores have different ways to submit a certificate for | |||
| consideration for ingestion, including: | consideration for ingestion, including: | |||
| o a simple upload of a certificate via HTTP | * a simple upload of a certificate via HTTP | |||
| o round-trip e-mail verification | ||||
| o proof of presence in some other service | * round-trip e-mail verification | |||
| o vouching, or other forms of multi-party attestation | * proof of presence in some other service | |||
| * vouching, or other forms of multi-party attestation | ||||
| Because these schemes vary so widely, this document does not attempt | Because these schemes vary so widely, this document does not attempt | |||
| to describe the keystore certificate submission process in detail. | to describe the keystore certificate submission process in detail. | |||
| However, guidance can be found for implementations that generate, | However, guidance can be found for implementations that generate, | |||
| manage, and submit certificates in Section 10. | manage, and submit certificates in Section 10. | |||
| 4. Simple Mitigations | 4. Simple Mitigations | |||
| These steps can be taken by any keystore that wants to avoid | These steps can be taken by any keystore that wants to avoid | |||
| obviously malicious abuse. They can be implemented on receipt of any | obviously malicious abuse. They can be implemented on receipt of any | |||
| new packet, and are based strictly on the structure of the packet | new packet, and are based strictly on the structure of the packet | |||
| skipping to change at page 15, line 12 ¶ | skipping to change at page 15, line 38 ¶ | |||
| packets specifically, but SHOULD NOT allow even user attributes | packets specifically, but SHOULD NOT allow even user attributes | |||
| packets larger than 65536 octets. | packets larger than 65536 octets. | |||
| 4.2. Enforce Strict User IDs | 4.2. Enforce Strict User IDs | |||
| [RFC4880] indicates that User IDs are expected to be UTF-8 strings. | [RFC4880] indicates that User IDs are expected to be UTF-8 strings. | |||
| An abuse-resistant keystore MUST reject any user ID that is not valid | An abuse-resistant keystore MUST reject any user ID that is not valid | |||
| UTF-8. | UTF-8. | |||
| Some abuse-resistant keystores MAY only accept User IDs that meet | Some abuse-resistant keystores MAY only accept User IDs that meet | |||
| even stricter conventions, such as an [RFC5322] "name-addr" or "addr- | even stricter conventions, such as an [RFC5322] name-addr or addr- | |||
| spec", or a URL like "ssh://host.example.org" (see Section 12.2). | spec, or a URL like ssh://host.example.org (see Section 12.2). | |||
| As simple text strings, User IDs don't need to be nearly as long as | As simple text strings, User IDs don't need to be nearly as long as | |||
| any other packets. An abuse-resistant keystore SHOULD reject any | any other packets. An abuse-resistant keystore SHOULD reject any | |||
| user ID packet larger than 1024 octets. | user ID packet larger than 1024 octets. | |||
| 4.3. Scoped User IDs | 4.3. Scoped User IDs | |||
| Some abuse-resistant keystores may restrict themselves to publishing | Some abuse-resistant keystores may restrict themselves to publishing | |||
| only certificates with User IDs that match a specific pattern. For | only certificates with User IDs that match a specific pattern. For | |||
| example, [RFC7929] encourages publication in the DNS of only | example, [RFC7929] encourages publication in the DNS of only | |||
| skipping to change at page 16, line 8 ¶ | skipping to change at page 16, line 43 ¶ | |||
| 4.4.2. Cross-sigs | 4.4.2. Cross-sigs | |||
| Some Primary Key Binding Signatures ("cross-sigs") are distributed as | Some Primary Key Binding Signatures ("cross-sigs") are distributed as | |||
| unhashed subpackets in a Subkey Binding Signature. A | unhashed subpackets in a Subkey Binding Signature. A | |||
| cryptographically-validating abuse-resistant keystore SHOULD be | cryptographically-validating abuse-resistant keystore SHOULD be | |||
| willing to redistribute a valid cross-sig as an unhashed subpacket. | willing to redistribute a valid cross-sig as an unhashed subpacket. | |||
| The redistributed unhashed cross-sig itself should be stripped of all | The redistributed unhashed cross-sig itself should be stripped of all | |||
| unhashed subpackets. | unhashed subpackets. | |||
| 4.4.3. First-party Attestations | ||||
| Some third-party certifications are attested to by the certificate | ||||
| primary key itself in an unhashed subpacket, as described in | ||||
| Section 8.3. A cryptographically-validating abuse-resistant keystore | ||||
| SHOULD be willing to redistribute a valid first-party attestation as | ||||
| an unhashed subpacket. | ||||
| The redistributed first-party attestation itself should be stripped | ||||
| of all unhashed subpackets. | ||||
| 4.5. Decline User Attributes | 4.5. Decline User Attributes | |||
| Due to size concerns, some abuse-resistant keystores MAY choose to | Due to size concerns, some abuse-resistant keystores MAY choose to | |||
| ignore user attribute packets entirely, as well as any certifications | ignore user attribute packets entirely, as well as any certifications | |||
| that cover them. | that cover them. | |||
| 4.6. Decline Non-exportable Certifications | 4.6. Decline Non-exportable Certifications | |||
| An abuse-resistant keystore MUST NOT accept any certification that | An abuse-resistant keystore MUST NOT accept any certification that | |||
| has the "Exportable Certification" subpacket present and set to 0. | has the "Exportable Certification" subpacket present and set to 0. | |||
| skipping to change at page 19, line 37 ¶ | skipping to change at page 20, line 20 ¶ | |||
| verifier retrieves the certificate from a user ID redacting keystore | verifier retrieves the certificate from a user ID redacting keystore | |||
| by via the Issuer Fingerprint from the signature, and the signature | by via the Issuer Fingerprint from the signature, and the signature | |||
| validates, the received certificate might not be a valid | validates, the received certificate might not be a valid | |||
| "transferable public key" unless the client can synthesize the proper | "transferable public key" unless the client can synthesize the proper | |||
| user ID. | user ID. | |||
| A reasonable client that wants to validate a certification in the | A reasonable client that wants to validate a certification in the | |||
| user ID redacted certificate SHOULD try to synthesize possible user | user ID redacted certificate SHOULD try to synthesize possible user | |||
| IDs based on the value of the [RFC5322] From: header in the message: | IDs based on the value of the [RFC5322] From: header in the message: | |||
| o Decode any [RFC2047] encodings present in the raw header value, | * Decode any [RFC2047] encodings present in the raw header value, | |||
| converting into UTF-8 [UNICODE-NORMALIZATION] form C (NFC), | converting into UTF-8 [UNICODE-NORMALIZATION] form C (NFC), | |||
| trimming all whitespace from the beginning and the end of the | trimming all whitespace from the beginning and the end of the | |||
| string. | string. | |||
| o The resulting string should be an [RFC5322] "name-addr" or "addr- | * The resulting string should be an [RFC5322] name-addr or addr- | |||
| spec". | spec. | |||
| o If it is a "name-addr", convert the UTF-8 string into an OpenPGP | * If it is a name-addr, convert the UTF-8 string into an OpenPGP | |||
| user ID and check whether the certification validates, terminating | user ID and check whether the certification validates, terminating | |||
| on success. | on success. | |||
| * If the test fails, extract the "addr-spec" from the "name-addr" | - If the test fails, extract the addr-spec from the name-addr and | |||
| and continue. | continue. | |||
| o Canonicalize the "addr-spec" according to Section 12.3, and check | * Canonicalize the addr-spec according to Section 12.3, and check | |||
| whether the certification validates, terminating on success. | whether the certification validates, terminating on success. | |||
| o If it doesn't validate wrap the canonicalized "addr-spec" in | * If it doesn't validate wrap the canonicalized addr-spec in angle- | |||
| angle-brackets ("<" and ">") and test the resulting minimalist | brackets ("<" and ">") and test the resulting minimalist name-addr | |||
| "name-addr" against the certification, terminating on success. | against the certification, terminating on success. | |||
| o If all of the above fails, synthesis has failed. | * If all of the above fails, synthesis has failed. | |||
| 5.1.3. Certificate Lookup with Redacted User IDs | 5.1.3. Certificate Lookup with Redacted User IDs | |||
| It's possible (though non-intuitive) to use a user ID redacting | It's possible (though non-intuitive) to use a user ID redacting | |||
| keystore for certificate lookup. Since the keystore retains (but | keystore for certificate lookup. Since the keystore retains (but | |||
| does not distribute) the user IDs, they can be used to select | does not distribute) the user IDs, they can be used to select | |||
| certificates in response to a search. The OpenPGP certificates sent | certificates in response to a search. The OpenPGP certificates sent | |||
| back in response to the search will not contain the user IDs, but a | back in response to the search will not contain the user IDs, but a | |||
| client that knows the full user ID they are searching for will be | client that knows the full user ID they are searching for will be | |||
| able to verify the returned certifications. | able to verify the returned certifications. | |||
| skipping to change at page 22, line 5 ¶ | skipping to change at page 22, line 36 ¶ | |||
| discovery interface. | discovery interface. | |||
| An abuse-resistant keystore that aims to defend its certificate | An abuse-resistant keystore that aims to defend its certificate | |||
| discovery interface from a fingerprint flooding (Section 2.3) attack | discovery interface from a fingerprint flooding (Section 2.3) attack | |||
| can follow the following procedure. | can follow the following procedure. | |||
| Such a keystore MUST accept only a full fingerprint or a 64-bit key | Such a keystore MUST accept only a full fingerprint or a 64-bit key | |||
| ID as the search parameter from the certificate discovery client. It | ID as the search parameter from the certificate discovery client. It | |||
| MUST only match that fingerprint against the following: | MUST only match that fingerprint against the following: | |||
| o the fingerprint or key ID of a primary key associated with a valid | * the fingerprint or key ID of a primary key associated with a valid | |||
| certificate | certificate | |||
| o the fingerprint or key ID of a cryptographically-valid subkey that | * the fingerprint or key ID of a cryptographically-valid subkey that | |||
| also has a cross-sig. | also has a cross-sig. | |||
| This defends against the fingerprint flooding attack because a | This defends against the fingerprint flooding attack because a | |||
| certificate will only be returned by subkey if the subkey has agreed | certificate will only be returned by subkey if the subkey has agreed | |||
| to be associated with the primary key (and vice versa). | to be associated with the primary key (and vice versa). | |||
| Note that this mitigation means that certificate discovery will fail | Note that this mitigation means that certificate discovery will fail | |||
| if used for subkeys that lack cross-sigs. In particular, this means | if used for subkeys that lack cross-sigs. In particular, this means | |||
| that a client that tries to use the certificate discovery interface | that a client that tries to use the certificate discovery interface | |||
| to retrieve a certificate based on its encryption-capable subkey | to retrieve a certificate based on its encryption-capable subkey | |||
| skipping to change at page 26, line 19 ¶ | skipping to change at page 26, line 42 ¶ | |||
| be dropped, because the User ID's revocation signature itself remains | be dropped, because the User ID's revocation signature itself remains | |||
| valid, and needs to be distributed. | valid, and needs to be distributed. | |||
| A primary key with no User IDs and no subkeys and no revocations MAY | A primary key with no User IDs and no subkeys and no revocations MAY | |||
| itself also be removed from distribution, though note that the | itself also be removed from distribution, though note that the | |||
| removal of a primary key may make it impossible to cryptographically | removal of a primary key may make it impossible to cryptographically | |||
| validate other certifications held by the keystore. | validate other certifications held by the keystore. | |||
| 7.4. Drop All Other Elements of a Directly-Revoked Certificate | 7.4. Drop All Other Elements of a Directly-Revoked Certificate | |||
| If the primary key of a certificate is revoked via a direct key | If the primary key of a certificate is revoked via a key revocation | |||
| signature, an abuse-resistant keystore SHOULD drop all the rest of | signature (type 0x20), an abuse-resistant keystore SHOULD drop all | |||
| the associated data (user IDs, user attributes, and subkeys, and all | the rest of the associated data (user IDs, user attributes, and | |||
| attendant certifications and subkey signatures). This defends | subkeys, and all attendant certifications and subkey signatures). | |||
| against an adversary who compromises a primary key and tries to flood | This defends against an adversary who compromises a primary key and | |||
| the certificate to hide the revocation. | tries to flood the certificate to hide the revocation. | |||
| Note that the direct key revocation signature MUST NOT be dropped. | Note that the key revocation signature MUST NOT be dropped. | |||
| In the event that an abuse-resistant keystore is flooded with direct | In the event that an abuse-resistant keystore is flooded with key | |||
| key revocation signatures, it should retain the hardest, earliest | revocation signatures, it should retain the hardest, earliest | |||
| revocation (see also Section 12.1). | revocation (see also Section 12.1). | |||
| In particular, if any of the direct key revocation signatures is a | In particular, if any of the key revocation signatures is a "hard" | |||
| "hard" revocation, the abuse-resistant keystore SHOULD retain the | revocation, the abuse-resistant keystore SHOULD retain the earliest | |||
| earliest such revocation signature (by signature creation date). | such revocation signature (by signature creation date). | |||
| Otherwise, the abuse-resistant keystore SHOULD retain the earliest | Otherwise, the abuse-resistant keystore SHOULD retain the earliest | |||
| "soft" direct key revocation signature it has seen. | "soft" key revocation signature it has seen. | |||
| If either of the above date comparisons results in a tie between two | If either of the above date comparisons results in a tie between two | |||
| revocation signatures of the same "hardness", an abuse-resistant | revocation signatures of the same "hardness", an abuse-resistant | |||
| keystore SHOULD retain the signature that sorts earliest based on a | keystore SHOULD retain the signature that sorts earliest based on a | |||
| binary string comparison of the direct key revocation signature | binary string comparison of the key revocation signature packet | |||
| packet itself. | itself. | |||
| 7.5. Implicit Expiration Date | 7.5. Implicit Expiration Date | |||
| In combination with some of the dropping mitigations above, a | In combination with some of the dropping mitigations above, a | |||
| particularly aggressive abuse-resistant keystore MAY choose an | particularly aggressive abuse-resistant keystore MAY choose an | |||
| implicit expiration date for all signature packets. For example, a | implicit expiration date for all signature packets. For example, a | |||
| signature packet that claims no expiration could be treated by the | signature packet that claims no expiration could be treated by the | |||
| keystore as expiring 3 years after issuance. This would permit the | keystore as expiring 3 years after issuance. This would permit the | |||
| keystore to eject old packets on a rolling basis. | keystore to eject old packets on a rolling basis. | |||
| An abuse-resistant keystore that adopts this mitigation needs a | An abuse-resistant keystore that adopts this mitigation needs a | |||
| policy for handling signature packets marked with an explicit | policy for handling signature packets marked with an explicit | |||
| expiration that is longer than implicit maximum. The two obvious | expiration that is longer than implicit maximum. The two obvious | |||
| strategies are: | strategies are: | |||
| o cap the packet's expiration to the system's implicit expiration | * cap the packet's expiration to the system's implicit expiration | |||
| date, or | date, or | |||
| o accept the explicit expiration date. | * accept the explicit expiration date. | |||
| Warning: Any implementation of this idea is pretty radical, and it's | Warning: Any implementation of this idea is pretty radical, and it's | |||
| not clear what it would do to an ecosystem that depends on such a | not clear what it would do to an ecosystem that depends on such a | |||
| keystore. It probably needs more thinking. | keystore. It probably needs more thinking. | |||
| 8. Primary Key Sovereignty | 8. Primary Key Sovereignty | |||
| A keystore can defend against malicious external flooding by treating | A keystore can defend against malicious external flooding by treating | |||
| the "first party" of each certificate as "sovereign" over that | the "first party" of each certificate as "sovereign" over that | |||
| certificate. This means in practice that no part of the certificate | certificate. This means in practice that no part of the certificate | |||
| skipping to change at page 27, line 51 ¶ | skipping to change at page 28, line 28 ¶ | |||
| The remaining subsections of Section 8 describe some sensible | The remaining subsections of Section 8 describe some sensible | |||
| strategies for a sovereignty-respecting keystore. | strategies for a sovereignty-respecting keystore. | |||
| 8.1. Refresh-only Keystores | 8.1. Refresh-only Keystores | |||
| Some soveriegnty-respecting keystores may resist abuse by declining | Some soveriegnty-respecting keystores may resist abuse by declining | |||
| to accept any user IDs or certifications whatsoever. | to accept any user IDs or certifications whatsoever. | |||
| Such a keystore MUST be capable of cryptographic validation. It | Such a keystore MUST be capable of cryptographic validation. It | |||
| accepts primary key packets, cryptographically-valid direct-key | accepts primary key packets, cryptographically-valid direct-key and | |||
| signatures from a primary key over itself, subkeys and their | revocation signatures from a primary key over itself, subkeys and | |||
| cryptographically-validated binding signatures (and cross-sigs, where | their cryptographically-validated binding signatures (and cross-sigs, | |||
| necessary). | where necessary). | |||
| A client of a refresh-only keystore cannot possibly use the keystore | A client of a refresh-only keystore cannot possibly use the keystore | |||
| for certificate lookup, because there are no user IDs to match. And | for certificate lookup, because there are no user IDs to match. And | |||
| it is not particularly useful for certificate discovery, because the | it is not particularly useful for certificate discovery, because the | |||
| returned certificate would have no identity information. However, | returned certificate would have no identity information. However, | |||
| such a keystore can be used for certificate refresh, as it's possible | such a keystore can be used for certificate refresh, as it's possible | |||
| to ship revocations (which are direct key signatures), new subkeys, | to ship revocations, new subkeys, updates to subkey expiration, | |||
| updates to subkey expiration, subkey revocation, and direct key | subkey revocations, and updates of direct key signature-based | |||
| signature-based certificate expiration updates. | certificate expiration or other OpenPGP properties. | |||
| Note that many popular OpenPGP implementations do not implement | Note that many popular OpenPGP implementations do not implement | |||
| direct primary key expiration mechanisms, relying instead on user ID | direct primary key expiration mechanisms, relying instead on user ID | |||
| expirations. These user ID expiration dates or other metadata | expirations. These user ID expiration dates or other metadata | |||
| associated with a self-certification will not be distributed by an | associated with a self-certification will not be distributed by an | |||
| refresh-only keystore. | refresh-only keystore. | |||
| Certificates shipped by an refresh-only keystore are technically | Certificates shipped by an refresh-only keystore are technically | |||
| invalid [RFC4880] "transferable public keys," because they lack a | invalid [RFC4880] "transferable public keys," because they lack a | |||
| user ID packet. However many OpenPGP implementations will accept | user ID packet. However many OpenPGP implementations will accept | |||
| skipping to change at page 29, line 21 ¶ | skipping to change at page 29, line 49 ¶ | |||
| information, while enabling full certificate refresh for those | information, while enabling full certificate refresh for those | |||
| keystore clients that already know the associated user IDs for a | keystore clients that already know the associated user IDs for a | |||
| given certificate. | given certificate. | |||
| 8.3. First-party-attested Third-party Certifications | 8.3. First-party-attested Third-party Certifications | |||
| We can augment a first-party-only sovereignty-respecting keystore to | We can augment a first-party-only sovereignty-respecting keystore to | |||
| allow it to distribute third-party certifications as long as the | allow it to distribute third-party certifications as long as the | |||
| first-party has signed off on the specific third-party certification. | first-party has signed off on the specific third-party certification. | |||
| A first-party can sign off a third-party certification by creating a | This can be done by placing an Attested Certifications subpacket in | |||
| signature over the third-party certification, and attaching it to the | the most recent self-sig of the certificate (see | |||
| third-party certification as an unhashed subpacket. We call such a | [Attested-Certifications]). | |||
| signature an "attestation", and it is created as detailed in the | ||||
| steps below: | ||||
| o The cryptographic validity of the third-party certification SHOULD | ||||
| be verified by the first party before creating an attestation for | ||||
| it. This implies that the issuer key of the third-party | ||||
| certification must be known by the first party at the time when | ||||
| the attestation is created. | ||||
| o The attestation MUST be an OpenPGP signature packet of type 0x50 | ||||
| (Third-Party Confirmation signature) | ||||
| o The attestation MUST contain a hashed Signature Creation Time | ||||
| subpacket whose value is greater than or equal to the hashed | ||||
| Signature Creation Time subpacket of the third-party | ||||
| certification. | ||||
| o The attestation MUST be a signature over the third-party | ||||
| certification, with all subpackets removed (see the discussion of | ||||
| signature type 0x50 in section 5.2.4 of [RFC4880]). | ||||
| o The attestation MUST contain a hashed "Issuer Fingerprint" | ||||
| subpacket with the fingerprint of the primary key of the first- | ||||
| party certificate. | ||||
| o The attestation MUST contain a hashed Notation subpacket with the | ||||
| name "first-party-attestation", and an empty (0-octet) value. | ||||
| This attestation MUST be embedded in the third-party certification as | ||||
| an unhashed subpacket of type 32 (Embedded Signature). The simplest | ||||
| possible OpenPGP certificate with such an attestation looks like the | ||||
| following sequence of OpenPGP packets (indentation implies | ||||
| embedding): | ||||
| - A. Primary key | ||||
| - B. User ID | ||||
| - C. Self-sig (from A, binding A to B) | ||||
| - D. Third-party certification (from X, binding A to B) | ||||
| - E. (embedded unhashed in D: Attestation from A over D) | ||||
| A sovereignty-respecting keystore MAY check the third-party | ||||
| certification itself for cryptographic validity, but explicitly MAY | ||||
| also omit this step as long as the first-party attestation is | ||||
| cryptographically valid. This allows distribution of any certificate | ||||
| as a self-contained unit by verifying only first-party signatures. | ||||
| It also allows distribution of third-party certifications made by | ||||
| third-parties unknown to the keystore. | ||||
| A sovereignty-respecting keystore MUST only accept a third-party | ||||
| certification if it has a first-party attestation that is | ||||
| cryptographically valid, verifiable by the primary key of the | ||||
| certificate in question, and the first-party attestation meets all | ||||
| the constraints in the list above. | ||||
| The Notation "first-party-attestation" is intended to avoid potential | ||||
| accidental confusion with any other use of the Third-Party | ||||
| Confirmation signature packet type. The author does not know of any | ||||
| current use that collides, but there may be future uses that we do | ||||
| not want to foreclose. | ||||
| 8.3.1. Client Interactions | 8.3.1. Client Interactions | |||
| Creating such an attestation requires multiple steps by different | Creating such an attestation requires multiple steps by different | |||
| parties, each of which is blocked by all prior steps: | parties, each of which is blocked by all prior steps: | |||
| o The first-party creates the certificate, and transfers it to the | * The first-party creates the certificate, and transfers it to the | |||
| third party. | third party. | |||
| o The third-party certifies it, and transfers their certification | * The third-party certifies it, and transfers their certification | |||
| back to the first party. | back to the first party. | |||
| o The first party attests to the third party's certification. | * The first party attests to the third party's certification by | |||
| issuing a new self-sig. | ||||
| o Finally, the first party then transfers the compound certificate | * Finally, the first party then transfers the updated certificate to | |||
| to the keystore. | the keystore. | |||
| The complexity and length of such a sequence may represent a | The complexity and length of such a sequence may represent a | |||
| usability obstacle to a user who needs a third-party-certified | usability obstacle to a user who needs a third-party-certified | |||
| OpenPGP certificate. | OpenPGP certificate. | |||
| No current OpenPGP client can easily create the attestations | Few OpenPGP clients can currently create the attestations described | |||
| described in this section. More implementation work needs to be done | in [Attested-Certifications]. None that the author is aware of are | |||
| to make it easy (and understandable) for a user to perform this kind | user-friendly. More implementation work needs to be done to make it | |||
| of attestation. | easy (and understandable) for a user to perform this kind of | |||
| attestation. | ||||
| 8.3.2. Attestation Revocations | ||||
| The certificate owner (the "first party") might at some point want to | ||||
| revoke their attestation over a given third-party certification. For | ||||
| example: Alice once was friends with Bob, but now thinks that Bob is | ||||
| a jerk, and wants to avoid public association with him. She used to | ||||
| be fine with keystores redistributing his certification of her | ||||
| cryptographic identity, but she no longer wants anyone to do that. | ||||
| A sovereignty-respecting keystore that distributes third-party | ||||
| certifications SHOULD respect such a revocation by declining to | ||||
| distribute the associated third-party certification. | ||||
| An "attestation revocation" is an OpenPGP signature packet of | ||||
| signature type 0x30 ("Certification revocation signature"), with the | ||||
| following properties: | ||||
| o The attestation revocation MUST contain a hashed Signature | ||||
| creation Time subpacket whose value is greater than the | ||||
| attestation it revokes. | ||||
| o The attestation revocation MUST contain a hashed "Issuer | ||||
| Fingerprint" subpacket with the fingerprint of the primary key of | ||||
| the first-party certificate. | ||||
| o The attestation revocation MUST contain a hashed Notation | ||||
| subpacket with the name "first-party-attestation" and an empty | ||||
| (0-octet) value. This Notation MUST be marked as critical. The | ||||
| criticality is to avoid possible confusion with a revocation of | ||||
| the third-party certification itself, in the event that the third | ||||
| party has indicated that the first party is a designated revoker. | ||||
| o Like any other revocation, the attestation revocation is made over | ||||
| the same data that the signature it is revoking was made over. In | ||||
| this case, that means: the third-party certification, with all | ||||
| subpackets removed (see the discussion of signature type 0x50 in | ||||
| section 5.2.4 of [RFC4880]). | ||||
| o The attestation revocation SHOULD contain a hashed "Signature | ||||
| Target" subpacket with "public-key algorithm" that matches the | ||||
| public-key algorithm of the attestation. This subpacket makes it | ||||
| easier for clients and keystores alike to connect an attestation | ||||
| revocation with an already-known first-party attestation. | ||||
| o The attestation revocation's hashed "Signature Target" subpacket's | ||||
| hash algorithm SHOULD be SHA256, and its value MUST be equal to | ||||
| the hash over the body of the attestation with all unhashed | ||||
| subpackets removed. That is, the material hashed should be the | ||||
| octet 0x88, followed by the four-octet length, followed by the | ||||
| body of the attestation with the unhashed subpacket data length | ||||
| set to zero. | ||||
| o The attestation revocation SHOULD be shipped in the sequence of | ||||
| signature packets after the user ID (in the same location as the | ||||
| third-party certification itself). This is a different location | ||||
| than the attestation, for reasons described in Section 8.3.3. | ||||
| If a keystore or a keystore client expects to see many first-party | ||||
| attested third-party certifications for a certificate, it SHOULD keep | ||||
| an index of them (the "attestation index"). To make effective use of | ||||
| the "Signature Target" subpacket, the attestation index should be | ||||
| keyed on the SHA256 hash of each indexed attestation, computed the | ||||
| same way it is computed for the "Signature Target" subpacket. Each | ||||
| entry in the attestation index should refer to both the attestation | ||||
| and its attested third-party certification. Note that SHA256 here is | ||||
| not used for its cryptographic strength, but merely as an efficiency | ||||
| measure for indexing. | ||||
| 8.3.3. Distribution of Attestation Revocations | ||||
| The structure of an OpenPGP certificate with a revoked first-party | ||||
| attestation of a third-party certification looks like this series of | ||||
| OpenPGP packets (indentation implies embedding): | ||||
| - A. Primary key | ||||
| - B. User ID | ||||
| - C. Self-sig (from A, binding A to B) | ||||
| - D. Third-party certification (from X, binding A to B) | ||||
| - E. (embedded unhashed in D: Attestation from A over D) | ||||
| - F. Attestation Revocation (from A over D, targets+revokes E) | ||||
| A sovereignty-respecting keystore that sees all of these packets | ||||
| SHOULD respect Attestation Revocation F by not redistributing D and E | ||||
| at all. | ||||
| However, if the keystore is distributing the certificate to a client | ||||
| that itself may care about first-party attestations (e.g. another | ||||
| sovereignty-respecting keystore, or just a sovereignty-respecting | ||||
| client), the keystore SHOULD continue to distribute F, so that the | ||||
| client can know that E has been revoked. | ||||
| This means that the redistributed certificate will consist of this | ||||
| series of OpenPGP packets: | ||||
| - A. Primary key | ||||
| - B. User ID | ||||
| - C. Self-sig (from A, binding A to B) | ||||
| - F. Attestation Revocation (from A over D, target+revokes E) | ||||
| A client or keystore that knows about D and E can verify the | ||||
| signature in F. It can identify E and D by looking them up in the | ||||
| attestation index based on the "Signature Target" subpacket in F. | ||||
| or, if it lacks such an index, it can scan all first-party | ||||
| attestations, and do trial signature verification over all third- | ||||
| party certifications it knows about until it finds a match. | ||||
| A client or keystore that doesn't know about D or E MAY ignore and | ||||
| discard F, since it is not cryptographically verifiable without D and | ||||
| E. Maintaining an attestation index makes this kind of rejection | ||||
| much cheaper to compute. | ||||
| A legacy client or keystore that doesn't understand attestations or | ||||
| attestation revocations at all might mistake F as an attempt at | ||||
| revocation of the User ID B itself, due to its signature type, its | ||||
| placement in the packet stream, and its issuer being A. However, | ||||
| such a client has three opportunities to ignore this packet and | ||||
| thereby avoid this confusion efficiently. In increasing order of | ||||
| computational effort: | ||||
| o it has a critical notation set that the legacy client (by | ||||
| definition) does not understand, and should therefore reject. | ||||
| o it has a Signature Target that does not match Self-sig C. | ||||
| o it does not cryptographically validate when computed over A and B. | ||||
| 8.3.4. Revoking Third-party Certifications | 8.3.2. Revoking Third-party Certifications | |||
| A sovereignty-respecting keystore distributes a third-party | A sovereignty-respecting keystore distributes a third-party | |||
| certification based on the desires of the first party, but the third- | certification based on the desires of the first party, but the third- | |||
| party themselves may change their mind about the certification that | party themselves may change their mind about the certification that | |||
| they issued. In particular, they may revoke a previously attested | they issued. In particular, they may revoke a previously attested | |||
| third-party certification. This causes some additional complexity. | third-party certification. This causes some additional complexity. | |||
| 8.3.4.1. Third-party Certification Revocations Aren't Shipped with the | 8.3.2.1. Third-party Certification Revocations Aren't Shipped with the | |||
| Certificate | Certificate | |||
| Distributing the third-party's revocation of their certification | Distributing the third-party's revocation of their certification | |||
| without the approval of the first party would arguably disrespect the | without the approval of the first party would arguably disrespect the | |||
| first-party's sovereignty over their own certificate. For example, | first-party's sovereignty over their own certificate. For example, | |||
| consider an abusively large revocation, or a revocation which | consider an abusively large revocation, or a revocation which | |||
| contains toxic data. | contains toxic data. | |||
| At the same time, if the first party were to revoke their | At the same time, if the first party were to revoke their | |||
| attestation, then the third-party certification itself _and_ its | attestation, then the third-party certification itself _and_ its | |||
| third-party's revocation might not be distributed. So distributing | third-party's revocation might not be distributed. So distributing | |||
| third-party certification revocations directly on the certificate | third-party certification revocations directly on the certificate | |||
| they refer to doesn't seem to solve the problem for an abuse- | they refer to doesn't seem to solve the problem for an abuse- | |||
| resistant, sovereignty-respecting keystore. | resistant, sovereignty-respecting keystore. | |||
| 8.3.4.2. Third-party Certification Revocations Ship With the Issuing | 8.3.2.2. Third-party Certification Revocations Ship With the Issuing | |||
| Certificate | Certificate | |||
| Instead, a sovereignty-respecting keystore MAY ship a third-party | Instead, a sovereignty-respecting keystore MAY ship a third-party | |||
| certification revocation attached to the end of the issuing | certification revocation attached to the end of the issuing | |||
| certificate, as this respects the sovereignty of all parties | certificate, as this respects the sovereignty of all parties | |||
| involved. | involved. | |||
| Using the same packet references as Section 8.3, this means that the | This means that the certifier's own OpenPGP certificate MAY be | |||
| certifier's own OpenPGP certificate MAY be distributed like so: | distributed like so: | |||
| - X. Primary key | - A. Primary key | |||
| - G. User ID | - B. User ID | |||
| - H. Self-sig (from X, binding X to G) | - C. Self-sig (from A, binding A to B) | |||
| - I. Subkey | - D. Subkey | |||
| - J. Subkey binding signature (from X, binds I to X) | - E. Subkey binding signature (from A, binds D to A) | |||
| - K. Certification revocation signature | - F. Certification revocation signature | |||
| (from X over A and B, targets+revokes D) | (from A over some other key+userID, targets other | |||
| certification) | ||||
| Note that OpenPGP packet K is unusual here, and augments the | Note that OpenPGP packet K is unusual here, and augments the | |||
| traditional Transferable Public Key structure from [RFC4880]. | traditional Transferable Public Key structure from [RFC4880]. | |||
| A client that cares about third-party certifications SHOULD maintain | A client that cares about third-party certifications SHOULD maintain | |||
| an index of certifications based on the SHA256 digest of the | an index of certifications based on the SHA256 digest of the | |||
| certifications themselves (the "certification index"). The | certifications themselves (the "certification index"). The | |||
| certification revocation packet SHOULD contain a Signature Target | certification revocation packet SHOULD contain a Signature Target | |||
| subpacket using SHA256 to identify the revoked certification. The | subpacket using SHA256 to identify the revoked certification. The | |||
| client can use this Signature Target subpacket and the certification | client can use this Signature Target subpacket and the certification | |||
| index to identify the targeted certification and to compute the data | index to identify the targeted certification and to compute the data | |||
| over which the revocation is made. As with the attestation index | over which the revocation is made. This use of SHA256 is not used | |||
| described in Section 8.3.2, this use of SHA256 is not used for | for cryptographic strength, but for indexing efficiency. | |||
| cryptographic strength, but for indexing efficiency. | ||||
| A client that cares about third-party certifications from key X | A client that cares about third-party certifications from key A | |||
| SHOULD refresh the certificate containing X from the keystore, and | SHOULD refresh the certificate containing A from the keystore, and | |||
| verify any discovered certification revocations correctly to the | verify any discovered certification revocations correctly to the | |||
| appropriate certificates, searching for the targeted revocation in | appropriate certificates, searching for the targeted revocation in | |||
| its certification index. | its certification index. | |||
| A legacy client that is unaware of this augmentation of the | A legacy client that is unaware of this augmentation of the | |||
| Transferable Public Key structure is likely to consider packet K as | Transferable Public Key structure is likely to consider packet K as | |||
| out-of-order or inapplicable (it would typically expect only a Subkey | out-of-order or inapplicable (it would typically expect only a Subkey | |||
| Revocation Signature packet in this position), and so will discard | Revocation Signature packet in this position), and so will discard | |||
| it. | it. | |||
| In the event that the certificate has no subkeys (packets I and J are | In the event that the certificate has no subkeys (packets I and J are | |||
| absent), a legacy client might consider K to be an attempt to revoke | absent), a legacy client might consider F to be an attempt to revoke | |||
| Self-Sig H. However, K's Signature Target subpacket does not point | Self-Sig C. However, F's Signature Target subpacket does not point | |||
| to H, and the certification is not cryptographically valid over X and | to C, and the certification is not cryptographically valid over A and | |||
| G, so it should be discarded/ignored safely in that case as well. | B, so it should be discarded/ignored safely in that case as well. | |||
| 9. Keystore Client Best Practices | 9. Keystore Client Best Practices | |||
| An OpenPGP client that needs to interact with an abuse-resistant | An OpenPGP client that needs to interact with an abuse-resistant | |||
| keystore can take steps to minimize the extent that its interactions | keystore can take steps to minimize the extent that its interactions | |||
| with a keystore can be abused by other parties via the attacks | with a keystore can be abused by other parties via the attacks | |||
| described in Section 2. This section describes steps that an abuse- | described in Section 2. This section describes steps that an abuse- | |||
| resistant client can take. | resistant client can take. | |||
| 9.1. Use Constrained Keystores for Lookup | 9.1. Use Constrained Keystores for Lookup | |||
| skipping to change at page 36, line 32 ¶ | skipping to change at page 33, line 26 ¶ | |||
| 9.5. Use Caution with Keystore-provided Validation | 9.5. Use Caution with Keystore-provided Validation | |||
| When an abuse-resistant client relies on a keystore for certificate | When an abuse-resistant client relies on a keystore for certificate | |||
| validation, many things can go subtly wrong if the client fails to | validation, many things can go subtly wrong if the client fails to | |||
| closely track the specific semantics of the keystore's validation | closely track the specific semantics of the keystore's validation | |||
| claims. | claims. | |||
| For example, a certificate published by WKD | For example, a certificate published by WKD | |||
| ([I-D.koch-openpgp-webkey-service]) at | ([I-D.koch-openpgp-webkey-service]) at | |||
| "https://openpgpkey.example.org/.well-known/openpgpkey/hu/ | https://openpgpkey.example.org/.well-known/openpgpkey/hu/ | |||
| iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=joe.doe" offers a validation claim | iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=joe.doe offers a validation claim | |||
| only for the e-mail address "joe.doe@example.org". If the | only for the e-mail address joe.doe@example.org. If the certificate | |||
| certificate retrieved at that address contains other user IDs, or if | retrieved at that address contains other user IDs, or if the user ID | |||
| the user ID containing that e-mail address contains an [RFC5322] | containing that e-mail address contains an [RFC5322] display-name, | |||
| "display-name", none of that information should be considered | none of that information should be considered "validated" by the fact | |||
| "validated" by the fact that the certificate was retrieved via | that the certificate was retrieved via certificate lookup by WKD. | |||
| certificate lookup by WKD. | ||||
| When certificate validation is represented more generally by a | When certificate validation is represented more generally by a | |||
| keystore via certificate retrieval (e.g. from an e-mail validating | keystore via certificate retrieval (e.g. from an e-mail validating | |||
| keyserver that has no distinct certificate validation interface), the | keyserver that has no distinct certificate validation interface), the | |||
| thing validated is the certificate received from the keystore, and | thing validated is the certificate received from the keystore, and | |||
| not the result of the merge into any local copy of the certificate | not the result of the merge into any local copy of the certificate | |||
| already possessed by the client. | already possessed by the client. | |||
| Consider also timing and duration of these assertions of validity, | Consider also timing and duration of these assertions of validity, | |||
| which represent a subtle tradeoff between privacy and risk as | which represent a subtle tradeoff between privacy and risk as | |||
| skipping to change at page 37, line 23 ¶ | skipping to change at page 34, line 15 ¶ | |||
| 10.1. Canonicalized E-Mail Addresses | 10.1. Canonicalized E-Mail Addresses | |||
| E-mail addresses can be written in many different ways. An abuse- | E-mail addresses can be written in many different ways. An abuse- | |||
| sensitive implementation considering attaching a user ID containing | sensitive implementation considering attaching a user ID containing | |||
| an e-mail address on a certificate SHOULD ensure that the e-mail | an e-mail address on a certificate SHOULD ensure that the e-mail | |||
| address is structured as simply as possible. See Section 12.3 for | address is structured as simply as possible. See Section 12.3 for | |||
| details about e-mail address canonicalization. | details about e-mail address canonicalization. | |||
| For example, if the e-mail domain considers the local part to be | For example, if the e-mail domain considers the local part to be | |||
| case-insensitive (as most e-mail domains do today), if a proposed | case-insensitive (as most e-mail domains do today), if a proposed | |||
| user ID contains the "addr-spec": "Alice@EXAMPLE.org", the | user ID contains the addr-spec: Alice@EXAMPLE.org, the implementation | |||
| implementation SHOULD warn the user and, if possible, propose | SHOULD warn the user and, if possible, propose replacing the addr- | |||
| replacing the "addr-spec" part of the user ID with | spec part of the user ID with alice@example.org. | |||
| "alice@example.org". | ||||
| 10.2. Normalized User IDs | 10.2. Normalized User IDs | |||
| User IDs are arbitrary UTF-8 strings, but UTF-8 offers several ways | User IDs are arbitrary UTF-8 strings, but UTF-8 offers several ways | |||
| to represent the same string. An abuse-sensitive implementation | to represent the same string. An abuse-sensitive implementation | |||
| considering attaching a user ID to a certificate SHOULD normalize the | considering attaching a user ID to a certificate SHOULD normalize the | |||
| string using [UNICODE-NORMALIZATION] Form C (NFC) before creating the | string using [UNICODE-NORMALIZATION] Form C (NFC) before creating the | |||
| self-sig. | self-sig. | |||
| At the same time, the implementation MAY also warn the user if the | At the same time, the implementation MAY also warn the user if the | |||
| skipping to change at page 39, line 12 ¶ | skipping to change at page 36, line 12 ¶ | |||
| designated revoker SHOULD be propagated, maybe even in first-party- | designated revoker SHOULD be propagated, maybe even in first-party- | |||
| only keystores. | only keystores. | |||
| 11.2. Key IDs vs. Fingerprints in Certificate Discovery | 11.2. Key IDs vs. Fingerprints in Certificate Discovery | |||
| During signature verification, a user performing certificate | During signature verification, a user performing certificate | |||
| discovery against a keystore SHOULD prefer to use the full | discovery against a keystore SHOULD prefer to use the full | |||
| fingerprint as an index, rather than the 64-bit key ID. Using a | fingerprint as an index, rather than the 64-bit key ID. Using a | |||
| 64-bit key ID is more likely to run into collision attacks; and if | 64-bit key ID is more likely to run into collision attacks; and if | |||
| the retrieved certificate has a matching key ID but the signature | the retrieved certificate has a matching key ID but the signature | |||
| cannot be validated with it, the client is in an ambiguous state - | cannot be validated with it, the client is in an ambiguous state -- | |||
| did it retrieve the wrong certificate, or is the signature incorrect? | did it retrieve the wrong certificate, or is the signature incorrect? | |||
| Using the fingerprint resolves the ambiguity: the signature is | Using the fingerprint resolves the ambiguity: the signature is | |||
| incorrect, because the a fingerprint match is overwhelmingly stronger | incorrect, because the a fingerprint match is overwhelmingly stronger | |||
| than a key ID match. | than a key ID match. | |||
| Unfortunately, many OpenPGP implementations distribute signatures | Unfortunately, many OpenPGP implementations distribute signatures | |||
| with only an Issuer subpacket, so a client attempting to find such a | with only an Issuer subpacket, so a client attempting to find such a | |||
| certificate MAY perform certificate discovery based on only the key | certificate MAY perform certificate discovery based on only the key | |||
| ID. | ID. | |||
| skipping to change at page 40, line 4 ¶ | skipping to change at page 37, line 9 ¶ | |||
| In another example, the use of authentication-capable OpenPGP keys in | In another example, the use of authentication-capable OpenPGP keys in | |||
| standard SSH connections do not contain the full OpenPGP | standard SSH connections do not contain the full OpenPGP | |||
| certificates, which means that the SSH clients and servers need to | certificates, which means that the SSH clients and servers need to | |||
| resort to out-of-band processes if evaluation of the OpenPGP | resort to out-of-band processes if evaluation of the OpenPGP | |||
| certificates is necessary. | certificates is necessary. | |||
| The certificate discovery interface offered by keystores is an | The certificate discovery interface offered by keystores is an | |||
| attempt to accommodate these situations. But in the event that a | attempt to accommodate these situations. But in the event that a | |||
| keystore is unavailable, does not know the certificate, or suffers | keystore is unavailable, does not know the certificate, or suffers | |||
| from a flooding attack, signature validation may fail unnecessarily. | from a flooding attack, signature validation may fail unnecessarily. | |||
| In an encrypted e-mail context specifically, such a failure may also | In an encrypted e-mail context specifically, such a failure may also | |||
| limit the client's ability to reply with an encrypted e-mail. | limit the client's ability to reply with an encrypted e-mail. | |||
| Certificate discovery also presents a potential privacy concern for | Certificate discovery also presents a potential privacy concern for | |||
| the signature verifier, as noted in Section 14.5. | the signature verifier, as noted in Section 14.5. | |||
| These problematic situations can be mitigated by shipping the | These problematic situations can be mitigated by shipping the | |||
| certificate in-band, alongside the signature. Signers SHOULD adopt | certificate in-band, alongside the signature. Signers SHOULD adopt | |||
| this practice where possible to reduce the dependence of the verifier | this practice where possible to reduce the dependence of the verifier | |||
| on the keystores for certificate discovery. [AUTOCRYPT] is an | on the keystores for certificate discovery. [AUTOCRYPT] is an | |||
| example of e-mail recommendations that include in-band certificates. | example of e-mail recommendations that include in-band certificates. | |||
| 11.3.1. In-band Certificate Minimization and Validity | 11.3.1. In-band Certificate Minimization and Validity | |||
| OpenPGP certificates are potentially large. When distributing an in- | OpenPGP certificates are potentially large. When distributing an in- | |||
| band certificate alongside a signature in a context where size is a | band certificate alongside a signature in a context where size is a | |||
| concern (e.g. bandwidth, latency, or storage costs are a factor), the | concern (e.g. bandwidth, latency, or storage costs are a factor), the | |||
| distributor SHOULD reduce the size of the in-band certificate by | distributor SHOULD reduce the size of the in-band certificate by | |||
| stripping unnecessary packets. For example, the distributor may: | stripping unnecessary packets. For example, the distributor may: | |||
| o Strip certification and signature packets that (due to creation | * Strip certification and signature packets that (due to creation | |||
| and expiration time) are not relevant to the time of the signature | and expiration time) are not relevant to the time of the signature | |||
| itself. This ensures that the reduced certificate is | itself. This ensures that the reduced certificate is | |||
| contemporaneously valid with the signature. | contemporaneously valid with the signature. | |||
| o Strip irrelevant subkeys (and associated Subkey Binding Signature | * Strip irrelevant subkeys (and associated Subkey Binding Signature | |||
| packets and cross-sigs). If the signature was issued by a | packets and cross-sigs). If the signature was issued by a | |||
| signing-capable subkey, that subkey (and its binding signature and | signing-capable subkey, that subkey (and its binding signature and | |||
| cross-sig) are clearly relevant. Other signing-capable subkeys | cross-sig) are clearly relevant. Other signing-capable subkeys | |||
| are likely to be irrelevant. But determining which other subkeys | are likely to be irrelevant. But determining which other subkeys | |||
| are relevant may be context-specific. For example, in the e-mail | are relevant may be context-specific. For example, in the e-mail | |||
| context, an encryption-capable subkey is likely to be contextually | context, an encryption-capable subkey is likely to be contextually | |||
| relevant, because it enables the recipient to reply encrypted, and | relevant, because it enables the recipient to reply encrypted, and | |||
| therefore should not be stripped. | therefore should not be stripped. | |||
| o Strip user IDs (and associated certifications) that are unlikely | * Strip user IDs (and associated certifications) that are unlikely | |||
| to be relevant to the signature in question. For example, in the | to be relevant to the signature in question. For example, in the | |||
| e-mail context, strip any user IDs that do not match the declared | e-mail context, strip any user IDs that do not match the declared | |||
| sender of the message. | sender of the message. | |||
| o Strip third-party certifications that are unlikely to be relevant | * Strip third-party certifications that are unlikely to be relevant | |||
| to the verifier. Doing this successfully requires some knowledge | to the verifier. Doing this successfully requires some knowledge | |||
| about what the third-parties the recipient is likely to care | about what the third-parties the recipient is likely to care | |||
| about. Stripping all third-party certifications is a simple means | about. Stripping all third-party certifications is a simple means | |||
| of certificate reduction. The verifier of such a certificate may | of certificate reduction. The verifier of such a certificate may | |||
| need to do certificate refresh against their preferred keystore to | need to do certificate refresh against their preferred keystore to | |||
| learn about third-party certifications useful to them. | learn about third-party certifications useful to them. | |||
| 11.4. Certification-capable Subkeys | 11.4. Certification-capable Subkeys | |||
| Much of this discussion assumes that primary keys are the only | Much of this discussion assumes that primary keys are the only | |||
| skipping to change at page 42, line 50 ¶ | skipping to change at page 40, line 8 ¶ | |||
| certificates, offering different sets of certificates to different | certificates, offering different sets of certificates to different | |||
| clients doing certificate lookup, and so on. | clients doing certificate lookup, and so on. | |||
| However, the most widely used append-only OpenPGP keystore, the [SKS] | However, the most widely used append-only OpenPGP keystore, the [SKS] | |||
| keyserver pool, offers no cryptographically verifiable guarantees | keyserver pool, offers no cryptographically verifiable guarantees | |||
| that it will actually remain append-only. Users of the pool have | that it will actually remain append-only. Users of the pool have | |||
| traditionally relied on its distributed nature, and the presumption | traditionally relied on its distributed nature, and the presumption | |||
| that coordination across a wide range of administrators would make it | that coordination across a wide range of administrators would make it | |||
| difficult for the pool to reliably lie or omit data. However, the | difficult for the pool to reliably lie or omit data. However, the | |||
| endpoint most commonly used by clients to access the network is | endpoint most commonly used by clients to access the network is | |||
| "hkps://hkps.pool.sks-keyservers.net", the default for [GnuPG]. That | hkps://hkps.pool.sks-keyservers.net, the default for [GnuPG]. That | |||
| endpoint is increasingly consolidated, and currently consists of | endpoint is increasingly consolidated, and currently consists of | |||
| hosts operated by only two distinct administrators, increasing the | hosts operated by only two distinct administrators, increasing the | |||
| risk of potential misuse. | risk of potential misuse. | |||
| Offering cryptographic assurances that a keystore could remain | Offering cryptographic assurances that a keystore could remain | |||
| append-only is an appealing prospect to defend against these kinds of | append-only is an appealing prospect to defend against these kinds of | |||
| attack. Many popular schemes for providing such assurances are known | attack. Many popular schemes for providing such assurances are known | |||
| as "blockchain" technologies, or global append-only ledgers. | as "blockchain" technologies, or global append-only ledgers. | |||
| With X.509 certificates, we have a semi-functional Certificate | With X.509 certificates, we have a semi-functional Certificate | |||
| skipping to change at page 43, line 26 ¶ | skipping to change at page 40, line 32 ¶ | |||
| append-only ledger. While the CT infrastructure remains vulnerable | append-only ledger. While the CT infrastructure remains vulnerable | |||
| to certain combinations of colluding actors, it has helped to | to certain combinations of colluding actors, it has helped to | |||
| identify and sanction some failing CAs. | identify and sanction some failing CAs. | |||
| Like other global append-only ledgers, CT itself is primarily a | Like other global append-only ledgers, CT itself is primarily a | |||
| detection mechanism, and has no enforcement regime. If a widely-used | detection mechanism, and has no enforcement regime. If a widely-used | |||
| CA were identified by certificate transparency to be untrustworthy, | CA were identified by certificate transparency to be untrustworthy, | |||
| the rest of the ecosystem still needs to figure out how to impose | the rest of the ecosystem still needs to figure out how to impose | |||
| sanctions or apply a remedy, which may or may not be possible. | sanctions or apply a remedy, which may or may not be possible. | |||
| CT also has privacy implications - the certificates published in the | CT also has privacy implications -- the certificates published in the | |||
| CT logs are visible to everyone, for the lifetime of the log. | CT logs are visible to everyone, for the lifetime of the log. | |||
| For spam abatement, CT logs decline all X.509 certificates except | For spam abatement, CT logs decline all X.509 certificates except | |||
| those issued by certain CAs (those in popular browser "root stores"). | those issued by certain CAs (those in popular browser "root stores"). | |||
| This is an example of the strategy outlined in Section 4.9). | This is an example of the strategy outlined in Section 4.9). | |||
| Additional projects that provide some aspects of global append-only | Additional projects that provide some aspects of global append-only | |||
| ledgers that try to address some of the concerns described here | ledgers that try to address some of the concerns described here | |||
| include [KEY-TRANSPARENCY] and [CONIKS], though they are not specific | include [KEY-TRANSPARENCY] and [CONIKS], though they are not specific | |||
| to OpenPGP. Both of these systems are dependent on servers operated | to OpenPGP. Both of these systems are dependent on servers operated | |||
| skipping to change at page 45, line 26 ¶ | skipping to change at page 42, line 30 ¶ | |||
| certificate expiry at time T SHOULD accept and process a "hard" | certificate expiry at time T SHOULD accept and process a "hard" | |||
| revocation even if it appears to have been issued at a time later | revocation even if it appears to have been issued at a time later | |||
| than T. | than T. | |||
| 12.2. User ID Conventions | 12.2. User ID Conventions | |||
| [RFC4880] requires a user ID to be a UTF-8 string, but does not | [RFC4880] requires a user ID to be a UTF-8 string, but does not | |||
| constrain it beyond that. In practice, a handful of conventions | constrain it beyond that. In practice, a handful of conventions | |||
| predominate in how User IDs are formed. | predominate in how User IDs are formed. | |||
| The most widespread convention is a "name-addr" as defined in | The most widespread convention is a name-addr as defined in | |||
| [RFC5322]. For example: | [RFC5322]. For example: | |||
| Alice Jones <alice@example.org> | Alice Jones <alice@example.org> | |||
| But a growing number of OpenPGP certificates contain user IDs that | But a growing number of OpenPGP certificates contain user IDs that | |||
| are instead a raw [RFC5322] "addr-spec", omitting the "display-name" | are instead a raw [RFC5322] addr-spec, omitting the display-name and | |||
| and the angle brackets entirely, like so: | the angle brackets entirely, like so: | |||
| alice@example.org | alice@example.org | |||
| Some certificates have user IDs that are simply normal human names | Some certificates have user IDs that are simply normal human names | |||
| (perhaps "display-name" in [RFC5322] jargon, though not necessarily | (perhaps display-name in [RFC5322] jargon, though not necessarily | |||
| conforming to a specific ABNF). For example: | conforming to a specific ABNF). For example: | |||
| Alice Jones | Alice Jones | |||
| Still other certificates identify a particular network service by | Still other certificates identify a particular network service by | |||
| scheme and hostname. For example, the administrator of an ssh host | scheme and hostname. For example, the administrator of an ssh host | |||
| participating in the [MONKEYSPHERE] might choose a user ID for the | participating in the [MONKEYSPHERE] might choose a user ID for the | |||
| OpenPGP representing the host like so: | OpenPGP representing the host like so: | |||
| ssh://foo.example.net | ssh://foo.example.net | |||
| 12.3. E-mail Address Canonicalization | 12.3. E-mail Address Canonicalization | |||
| When an OpenPGP user IDs includes an "addr-spec", there still may be | When an OpenPGP user IDs includes an addr-spec, there still may be | |||
| multiple ways of representing the addr-spec that refer to the same | multiple ways of representing the addr-spec that refer to the same | |||
| underlying mailbox. Having a truly canonical form of an "addr-spec" | underlying mailbox. Having a truly canonical form of an addr-spec is | |||
| is probably impossible because of legacy deployments of mailservers | probably impossible because of legacy deployments of mailservers that | |||
| that do odd things with the local part, but e-mail addresses used in | do odd things with the local part, but e-mail addresses used in an | |||
| an abuse-resistant ecosystem SHOULD be constrained enough to admit to | abuse-resistant ecosystem SHOULD be constrained enough to admit to | |||
| some sensible form of canonicalization. | some sensible form of canonicalization. | |||
| 12.3.1. Disallowing Non-UTF-8 Local Parts | 12.3.1. Disallowing Non-UTF-8 Local Parts | |||
| In [RFC5322], the "local-part" can be any "dot-atom". But if this is | In [RFC5322], the local-part can be any dot-atom. But if this is | |||
| [RFC2047] decoded, it could be any arbitrary charset, not necessarily | [RFC2047] decoded, it could be any arbitrary charset, not necessarily | |||
| UTF-8. FIXME: Do we convert from the arbitrary charset to UTF-8? | UTF-8. FIXME: Do we convert from the arbitrary charset to UTF-8? | |||
| 12.3.2. Domain Canonicalization | 12.3.2. Domain Canonicalization | |||
| FIXME: should domain name be canonicalized into punycode form? User | FIXME: should domain name be canonicalized into punycode form? User | |||
| IDs are typically user-facing, so i think the canonicalized form | IDs are typically user-facing, so i think the canonicalized form | |||
| should be the [UNICODE-NORMALIZATION] Form C (NFC) of the domain | should be the [UNICODE-NORMALIZATION] Form C (NFC) of the domain | |||
| name. Can we punt to some other draft here? | name. Can we punt to some other draft here? | |||
| skipping to change at page 47, line 19 ¶ | skipping to change at page 44, line 19 ¶ | |||
| a keystore accepts arbitrary certificate uploads for redistribution, | a keystore accepts arbitrary certificate uploads for redistribution, | |||
| it appears to be vulnerable to user ID flooding (Section 2.2), which | it appears to be vulnerable to user ID flooding (Section 2.2), which | |||
| makes it difficult or impossible to rely on for certificate lookup. | makes it difficult or impossible to rely on for certificate lookup. | |||
| In the broader ecosystem, it may be necessary to use gated/controlled | In the broader ecosystem, it may be necessary to use gated/controlled | |||
| certificate lookup mechanisms. For example, both | certificate lookup mechanisms. For example, both | |||
| [I-D.koch-openpgp-webkey-service] and [RFC7929] enable the | [I-D.koch-openpgp-webkey-service] and [RFC7929] enable the | |||
| administrator of a DNS domain to distribute certificates associated | administrator of a DNS domain to distribute certificates associated | |||
| with e-mail addresses within that domain, while excluding other | with e-mail addresses within that domain, while excluding other | |||
| parties. As a rather different example, [I-D.mccain-keylist] offers | parties. As a rather different example, [I-D.mccain-keylist] offers | |||
| certificate lookup on the basis of interest - a client interested in | certificate lookup on the basis of interest -- a client interested in | |||
| an organization can use that mechanism to learn what certificates | an organization can use that mechanism to learn what certificates | |||
| that organization thinks are worth knowing about, associated with a | that organization thinks are worth knowing about, associated with a | |||
| range of identities regardless of the particular DNS domain. Note | range of identities regardless of the particular DNS domain. Note | |||
| that [I-D.mccain-keylist] does not provide the certificates directly, | that [I-D.mccain-keylist] does not provide the certificates directly, | |||
| but instead expects the client to be able to retrieve them by primary | but instead expects the client to be able to retrieve them by primary | |||
| key fingerprint through some other keystore capable of (and | key fingerprint through some other keystore capable of (and | |||
| responsible for) certificate refresh. | responsible for) certificate refresh. | |||
| 14. Privacy Considerations | 14. Privacy Considerations | |||
| skipping to change at page 50, line 50 ¶ | skipping to change at page 48, line 6 ¶ | |||
| 14.7. Distinct Keystore Interfaces Leak Client Context and Intent | 14.7. Distinct Keystore Interfaces Leak Client Context and Intent | |||
| The distinct keystore interfaces documented in Section 3 offer subtly | The distinct keystore interfaces documented in Section 3 offer subtly | |||
| different semantics, and are used by a reasonable keystore client at | different semantics, and are used by a reasonable keystore client at | |||
| different times. A keystore that offers distinct discovery and | different times. A keystore that offers distinct discovery and | |||
| refresh interfaces may infer that a client visiting the refresh | refresh interfaces may infer that a client visiting the refresh | |||
| interface already knows about the certificate in question, or that a | interface already knows about the certificate in question, or that a | |||
| client visiting the discovery interface is in the process of | client visiting the discovery interface is in the process of | |||
| verifying a signature from a certificate it has not seen before. | verifying a signature from a certificate it has not seen before. | |||
| HKP itself ([I-D.shaw-openpgp-hkp]) conflates these two interfaces - | HKP itself ([I-D.shaw-openpgp-hkp]) conflates these two interfaces -- | |||
| the same HKP query is be used to perform both discovery and refresh | the same HKP query is be used to perform both discovery and refresh | |||
| (though implementations like [SKS] are not at all abuse-resistant for | (though implementations like [SKS] are not at all abuse-resistant for | |||
| either use), which may obscure the context and intent of the client | either use), which may obscure the context and intent of the client | |||
| from the keystore somewhat. | from the keystore somewhat. | |||
| A privacy-aware client that can afford the additional bandwidth and | A privacy-aware client that can afford the additional bandwidth and | |||
| complexity MAY use the keystore's discovery interface for both | complexity MAY use the keystore's discovery interface for both | |||
| refresh and discovery, since the discovery interface is a proper | refresh and discovery, since the discovery interface is a proper | |||
| superset of the refresh interface. | superset of the refresh interface. | |||
| skipping to change at page 52, line 27 ¶ | skipping to change at page 49, line 37 ¶ | |||
| permitting redistribution of even cryptographically invalid OpenPGP | permitting redistribution of even cryptographically invalid OpenPGP | |||
| packets. Clearer warnings to end users might reduce this kind of | packets. Clearer warnings to end users might reduce this kind of | |||
| misperception. Or the community could encourage the removal of | misperception. Or the community could encourage the removal of | |||
| frequently misinterpreted user interfaces entirely. | frequently misinterpreted user interfaces entirely. | |||
| 16. IANA Considerations | 16. IANA Considerations | |||
| This document asks IANA to register two entries in the OpenPGP | This document asks IANA to register two entries in the OpenPGP | |||
| Notation IETF namespace, both with a reference to this document: | Notation IETF namespace, both with a reference to this document: | |||
| o the "first-party-attestation" notation is defined in Section 8.3. | * the "uidhash" notation is defined in Section 5.1.4. | |||
| o the "uidhash" notation is defined in Section 5.1.4. | 16.1. Document History | |||
| 17. Document Considerations | substantive changes bewteen -04 and -05: | |||
| [ RFC Editor: please remove this section before publication ] | * Clarify distinctions between different signature types | |||
| This document is currently edited as markdown. Minor editorial | * Point to Attested Certifications proposal | |||
| changes can be suggested via merge requests at | ||||
| https://gitlab.com/dkg/draft-openpgp-abuse-resistant-keystore or by | ||||
| e-mail to the author. Please direct all significant commentary to | ||||
| the public IETF OpenPGP mailing list: openpgp@ietf.org | ||||
| 17.1. Document History | * Formatting changes: use xml2rfc v3, publish editor's copy | |||
| substantive changes bewteen -03 and -04: | substantive changes bewteen -03 and -04: | |||
| o change "certificate update" to "certificate refresh" for clarity | * change "certificate update" to "certificate refresh" for clarity | |||
| * relax first-party-attested third-party certification constraints | ||||
| o relax first-party-attested third-party certification constraints | ||||
| at the suggestion of Valodim | at the suggestion of Valodim | |||
| o introduce "primary key sovereignty" concept explicitly | * introduce "primary key sovereignty" concept explicitly | |||
| o describe how to distribute and consume attestation revocations | ||||
| o introduce augmentation to TPK for third-party certification | * describe how to distribute and consume attestation revocations | |||
| * introduce augmentation to TPK for third-party certification | ||||
| revocation distribution | revocation distribution | |||
| substantive changes between -02 and -03: | substantive changes between -02 and -03: | |||
| o new sections: | * new sections: | |||
| * Keystore Interfaces | - Keystore Interfaces | |||
| * Keystore Client Best Practices | - Keystore Client Best Practices | |||
| * Certificate Generation and Management Best Practices | - Certificate Generation and Management Best Practices | |||
| o rename "certificate discovery" to "certificate lookup" | * rename "certificate discovery" to "certificate lookup" | |||
| o redefine "certificate discovery" to refer to lookup by signing | * redefine "certificate discovery" to refer to lookup by signing | |||
| (sub)key | (sub)key | |||
| o new attack: fingerprint flooding | * new attack: fingerprint flooding | |||
| o new retrieval-time mitigations - tighter filters on discovery and | * new retrieval-time mitigations -- tighter filters on discovery and | |||
| update | update | |||
| o recommend in-band certificates where possible to avoid discovery | * recommend in-band certificates where possible to avoid discovery | |||
| and lookup | and lookup | |||
| o new privacy considerations: | * new privacy considerations: | |||
| * distinct keystore interfaces | - distinct keystore interfaces | |||
| * certificate update | - certificate update | |||
| * certificate discovery | - certificate discovery | |||
| * certificate validation | - certificate validation | |||
| o more nuance about unhashed subpacket filtering | * more nuance about unhashed subpacket filtering | |||
| substantive changes between -01 and -02: | substantive changes between -01 and -02: | |||
| o distinguish different forms of flooding attack | * distinguish different forms of flooding attack | |||
| * distinguish toxic data as distinct from flooding | ||||
| o distinguish toxic data as distinct from flooding | * retrieval-time mitigations | |||
| o retrieval-time mitigations | * user ID redaction | |||
| o user ID redaction | ||||
| o references to related work (CT, keylist, CONIKS, key transparency, | * references to related work (CT, keylist, CONIKS, key transparency, | |||
| ledgers/"blockchain", etc) | ledgers/"blockchain", etc) | |||
| o more details about UI/UX | * more details about UI/UX | |||
| substantive changes between -00 and -01: | substantive changes between -00 and -01: | |||
| o split out Contextual and Non-Append-Only mitigations | * split out Contextual and Non-Append-Only mitigations | |||
| o documented several other mitigations, including: | * documented several other mitigations, including: | |||
| * Decline Data From the Future | - Decline Data From the Future | |||
| * Blocklist | - Blocklist | |||
| * Exterior Process | - Exterior Process | |||
| * Designated Authorities | - Designated Authorities | |||
| * Known Certificates | - Known Certificates | |||
| * Rate-Limiting | - Rate-Limiting | |||
| * Scoped User IDs | - Scoped User IDs | |||
| o documented Updates-Only Keystores | * documented Updates-Only Keystores | |||
| o consider three different kinds of flooding | * consider three different kinds of flooding | |||
| o deeper discussion of privacy considerations | * deeper discussion of privacy considerations | |||
| o better documentation of Reason for Revocation | * better documentation of Reason for Revocation | |||
| o document user ID conventions | * document user ID conventions | |||
| 18. Acknowledgements | 17. Acknowledgements | |||
| This document is the result of years of operational experience and | This document is the result of years of operational experience and | |||
| observation, as well as conversations with many different people - | observation, as well as conversations with many different people -- | |||
| users, implementors, keystore operators, etc. A non-exhaustive list | users, implementors, keystore operators, etc. A non-exhaustive list | |||
| of people who have contributed ideas or nuance to this document | of people who have contributed ideas or nuance to this document | |||
| specifically includes: | specifically includes: | |||
| o Antoine Beaupre | * Antoine Beaupre | |||
| o ilf | * Heiko Stamer | |||
| o Jamie McClelland | ||||
| o Jonathan McDowell | * ilf | |||
| o Justus Winter | * Jamie McClelland | |||
| o Marcus Brinkmann | * Jon Callas | |||
| o Micah Lee | * Jonathan McDowell | |||
| o Neal Walfield | * Justus Winter | |||
| o Phil Pennock | * Marcus Brinkmann | |||
| o Philihp Busby | * Micah Lee | |||
| o vedaal | * Neal Walfield | |||
| o Vincent Breitmoser | * Phil Pennock | |||
| o Wiktor Kwapisiewicz | * Philihp Busby | |||
| 19. References | * vedaal | |||
| 19.1. Normative References | * Vincent Breitmoser | |||
| * Wiktor Kwapisiewicz | ||||
| 18. References | ||||
| 18.1. Normative References | ||||
| [I-D.ietf-openpgp-rfc4880bis] | [I-D.ietf-openpgp-rfc4880bis] | |||
| Koch, W., carlson, b., Tse, R., and D. Atkins, "OpenPGP | Koch, W., carlson, B. M., Tse, R. H., Atkins, D., and D. | |||
| Message Format", draft-ietf-openpgp-rfc4880bis-07 (work in | K. Gillmor, "OpenPGP Message Format", Work in Progress, | |||
| progress), May 2019. | Internet-Draft, draft-ietf-openpgp-rfc4880bis-10, 31 | |||
| August 2020, <https://www.ietf.org/archive/id/draft-ietf- | ||||
| openpgp-rfc4880bis-10.txt>. | ||||
| [RFC2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) | [RFC2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) | |||
| Part Three: Message Header Extensions for Non-ASCII Text", | Part Three: Message Header Extensions for Non-ASCII Text", | |||
| RFC 2047, DOI 10.17487/RFC2047, November 1996, | RFC 2047, DOI 10.17487/RFC2047, November 1996, | |||
| <https://www.rfc-editor.org/info/rfc2047>. | <https://www.rfc-editor.org/info/rfc2047>. | |||
| [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/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. | [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. | |||
| Thayer, "OpenPGP Message Format", RFC 4880, | Thayer, "OpenPGP Message Format", RFC 4880, | |||
| DOI 10.17487/RFC4880, November 2007, | DOI 10.17487/RFC4880, November 2007, | |||
| <https://www.rfc-editor.org/info/rfc4880>. | <https://www.rfc-editor.org/info/rfc4880>. | |||
| [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/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| 19.2. Informative References | 18.2. Informative References | |||
| [Attested-Certifications] | ||||
| "Documentation of the Attested Certifications subpacket", | ||||
| n.d., <https://gitlab.com/openpgp-wg/rfc4880bis/ | ||||
| merge_requests/20>. | ||||
| [AUTOCRYPT] | [AUTOCRYPT] | |||
| Breitmoser, V., Krekel, H., and D. Gillmor, "Autocrypt - | Breitmoser, V., Krekel, H., and D. K. Gillmor, "Autocrypt | |||
| Convenient End-to-End Encryption for E-Mail", n.d., | - Convenient End-to-End Encryption for E-Mail", n.d., | |||
| <https://autocrypt.org/>. | <https://autocrypt.org/>. | |||
| [BITCOIN] "Bitcoin", n.d., <https://bitcoin.org/>. | [BITCOIN] "Bitcoin", n.d., <https://bitcoin.org/>. | |||
| [CONIKS] Felten, E., Freedman, M., Melara, M., Blankstein, A., and | [CONIKS] Felten, E., Freedman, M., Melara, M., Blankstein, A., and | |||
| J. Bonneau, "CONIKS Key Management System", n.d., | J. Bonneau, "CONIKS Key Management System", n.d., | |||
| <https://coniks.cs.princeton.edu/>. | <https://coniks.cs.princeton.edu/>. | |||
| [DEBIAN-KEYRING] | [DEBIAN-KEYRING] | |||
| McDowell, J., "Debian Keyring", n.d., | McDowell, J., "Debian Keyring", n.d., | |||
| <https://keyring.debian.org/>. | <https://keyring.debian.org/>. | |||
| [GnuPG] Koch, W., "Using the GNU Privacy Guard", April 2019, | [GnuPG] Koch, W., "Using the GNU Privacy Guard", 4 April 2019, | |||
| <https://www.gnupg.org/documentation/manuals/gnupg.pdf>. | <https://www.gnupg.org/documentation/manuals/gnupg.pdf>. | |||
| [I-D.koch-openpgp-webkey-service] | [I-D.koch-openpgp-webkey-service] | |||
| Koch, W., "OpenPGP Web Key Directory", draft-koch-openpgp- | Koch, W., "OpenPGP Web Key Directory", Work in Progress, | |||
| webkey-service-08 (work in progress), May 2019. | Internet-Draft, draft-koch-openpgp-webkey-service-13, 14 | |||
| November 2021, <https://www.ietf.org/archive/id/draft- | ||||
| koch-openpgp-webkey-service-13.txt>. | ||||
| [I-D.mccain-keylist] | [I-D.mccain-keylist] | |||
| McCain, R., Lee, M., and N. Welch, "Distributing OpenPGP | McCain, R. M., Lee, M., and N. Welch, "Distributing | |||
| Key Fingerprints with Signed Keylist Subscriptions", | OpenPGP Key Fingerprints with Signed Keylist | |||
| draft-mccain-keylist-04 (work in progress), March 2019. | Subscriptions", Work in Progress, Internet-Draft, draft- | |||
| mccain-keylist-05, 2 September 2019, | ||||
| <https://www.ietf.org/archive/id/draft-mccain-keylist- | ||||
| 05.txt>. | ||||
| [I-D.shaw-openpgp-hkp] | [I-D.shaw-openpgp-hkp] | |||
| Shaw, D., "The OpenPGP HTTP Keyserver Protocol (HKP)", | Shaw, D., "The OpenPGP HTTP Keyserver Protocol (HKP)", | |||
| draft-shaw-openpgp-hkp-00 (work in progress), March 2003. | Work in Progress, Internet-Draft, draft-shaw-openpgp-hkp- | |||
| 00, 20 March 2003, <https://www.ietf.org/archive/id/draft- | ||||
| shaw-openpgp-hkp-00.txt>. | ||||
| [KEY-TRANSPARENCY] | [KEY-TRANSPARENCY] | |||
| Belvin, G. and R. Hurst, "Key Transparency, a transparent | Belvin, G. and R. Hurst, "Key Transparency, a transparent | |||
| and secure way to look up public keys", n.d., | and secure way to look up public keys", n.d., | |||
| <https://keytransparency.org/>. | <https://keytransparency.org/>. | |||
| [MAILVELOPE-KEYSERVER] | [MAILVELOPE-KEYSERVER] | |||
| Oberndoerfer, T., "Mailvelope Keyserver", n.d., | Oberndรถrfer, T., "Mailvelope Keyserver", n.d., | |||
| <https://github.com/mailvelope/keyserver/>. | <https://github.com/mailvelope/keyserver/>. | |||
| [MONKEYSPHERE] | [MONKEYSPHERE] | |||
| Gillmor, D. and J. Rollins, "Monkeysphere", n.d., | Gillmor, D. K. and J. Rollins, "Monkeysphere", n.d., | |||
| <https://web.monkeysphere.info/>. | <https://web.monkeysphere.info/>. | |||
| [PARCIMONIE] | [PARCIMONIE] | |||
| Intrigeri, ., "Parcimonie", n.d., | Intrigeri, "Parcimonie", n.d., | |||
| <https://gaffer.ptitcanardnoir.org/intrigeri/code/ | <https://gaffer.ptitcanardnoir.org/intrigeri/code/ | |||
| parcimonie/>. | parcimonie/>. | |||
| [PGP-GLOBAL-DIRECTORY] | [PGP-GLOBAL-DIRECTORY] | |||
| Symantec Corporation, "PGP Global Directory Key | Symantec Corporation, "PGP Global Directory Key | |||
| Verification Policy", 2011, | Verification Policy", 2011, | |||
| <https://keyserver.pgp.com/vkd/ | <https://keyserver.pgp.com/vkd/ | |||
| VKDVerificationPGPCom.html>. | VKDVerificationPGPCom.html>. | |||
| [RFC4366] Blake-Wilson, S., Nystrom, M., Hopwood, D., Mikkelsen, J., | [RFC4366] Blake-Wilson, S., Nystrom, M., Hopwood, D., Mikkelsen, J., | |||
| skipping to change at page 57, line 45 ¶ | skipping to change at page 55, line 21 ¶ | |||
| [RFC6962] Laurie, B., Langley, A., and E. Kasper, "Certificate | [RFC6962] Laurie, B., Langley, A., and E. Kasper, "Certificate | |||
| Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013, | Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013, | |||
| <https://www.rfc-editor.org/info/rfc6962>. | <https://www.rfc-editor.org/info/rfc6962>. | |||
| [RFC7929] Wouters, P., "DNS-Based Authentication of Named Entities | [RFC7929] Wouters, P., "DNS-Based Authentication of Named Entities | |||
| (DANE) Bindings for OpenPGP", RFC 7929, | (DANE) Bindings for OpenPGP", RFC 7929, | |||
| DOI 10.17487/RFC7929, August 2016, | DOI 10.17487/RFC7929, August 2016, | |||
| <https://www.rfc-editor.org/info/rfc7929>. | <https://www.rfc-editor.org/info/rfc7929>. | |||
| [SKS] Minsky, Y., Fiskerstrand, K., and P. Pennock, "SKS | [SKS] Minsky, Y., Fiskerstrand, K., and P. Pennock, "SKS | |||
| Keyserver Documentation", March 2018, | Keyserver Documentation", 25 March 2018, | |||
| <https://bitbucket.org/skskeyserver/sks-keyserver/wiki/ | <https://bitbucket.org/skskeyserver/sks-keyserver/wiki/ | |||
| Home>. | Home>. | |||
| [TOR] "The Tor Project", n.d., <https://www.torproject.org/>. | [TOR] "The Tor Project", n.d., <https://www.torproject.org/>. | |||
| [UNICODE-NORMALIZATION] | [UNICODE-NORMALIZATION] | |||
| Whistler, K., "Unicode Normalization Forms", February | Whistler, K., "Unicode Normalization Forms", 4 February | |||
| 2019, <https://unicode.org/reports/tr15/>. | 2019, <https://unicode.org/reports/tr15/>. | |||
| Author's Address | Author's Address | |||
| Daniel Kahn Gillmor | Daniel Kahn Gillmor | |||
| American Civil Liberties Union | American Civil Liberties Union | |||
| 125 Broad St. | 125 Broad St. | |||
| New York, NY 10004 | New York, NY, 10004 | |||
| USA | United States of America | |||
| Email: dkg@fifthhorseman.net | Email: dkg@fifthhorseman.net | |||
| End of changes. 192 change blocks. | ||||
| 553 lines changed or deleted | 387 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||