Subject: [openpgp] 1PA3PC: first-party attested third-party certifications (making Key Server Prefs no-modify actionable)

From: Daniel Kahn Gillmor <[email-masked]>
Date: Wed, 28 Aug 2019 01:31:42 -0400

Hi OpenPGP folks--

The "No-modify" flag for Key Server Preferences has never been
particularly actionable, because the keyserver has no way to tell
whether the certificate-holder intends for third-party certifications to
be redistributed or not.

After a few discussions with other implementers offlist [0], i'm
proposing a new, simple way that the certificate holder (the "first
party") can attest to some number of specific third-party
certifications, to indicate that they're redistributable.

[0] https://gitlab.com/dkg/draft-openpgp-abuse-resistant-keystore/issues/1
    and several discussions on #hagrid on IRC

The shorthand for this "first-party attestation of third-party
certifications" is 1PA3PC.

The abuse-resistant keystores draft makes clear that such an attestation
is necessary to be able to distribute third-party certifications while
retaining first-party sovereignty over the certificate.  But that draft
(up through version -04) proposes a more-complicated mechanism using
third-party confirmation signatures embedded in unhashed subpackets.

The new mechanism i'm proposing here is just a list of digests over
third-party certifications, stored in a hashed subpacket in the
self-sig.  This has two major advantages over the more complex proposal:

 * it's simpler to specify and to implement.

 * the first party can pretty easily change their mind about their
   preferred attestations for a given User ID by issuing a new self-sig;
   no need for juggling/redistributing explicit revocations of the
   attestations from the first party, which made the abuse-resistant
   keystore draft much uglier.

There are two downsides as i see it, neither of them particularly bad:

 * there is an overall space limitation in the hashed subpackets (64KiB
   tops, probably less given other overhead), so the keyholder can't
   attest to arbitrarily many third-party certifications.  However, even
   when using SHA512 (64B per attested certification), with even tighter
   constraints (like autocrypt, where the whole cert must be < 10KiB),
   there is still room for attestation of dozens of third-party
   certifications.  That's more than enough for reasonable use.

 * It encourages/requires certificate holders to issue new self-sigs
   when they want to change their attestations.  If a certificate store
   that doesn't prune superseded self-sigs encounters a rapidly-changing
   set of attestations, this might cause a bit of bloat.  But the
   certificate store can just start pruning to fix that problem.

This new proposal (diff for RFC 4880bis attached) claims subpacket
codepoint 37 for shipping these attestations.  I've also put this
proposal as a merge request here:
https://gitlab.com/openpgp-wg/rfc4880bis/merge_requests/20

1PA3PC test vector and example
------------------------------

Below is an example of this form of 1PA3PC, using ed25519.

The third-party certifier:

The end user certificate, with the third-party certification and a
self-sig that attests to it:

I'd be happy to hear any feedback, both about the proposed patch to the
spec, and about the test vector i've included here.

      --dkg

From eedb828e08d48e3749757035e4b114d7ea2b6650 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <[email-masked]>
Date: Wed, 28 Aug 2019 00:01:07 -0400
Subject: [RFC4880bis PATCH] Describe "Attested Certifications" subpacket

The "no-modify" flag in the Key Server Preferences subpacket has never
had a clear indication of how a keyserver can effectively respect it.

This changeset describes an "Attested Certifications" subpacket that
makes "no-modify" actionable by a keyserver.  A keyserver that
respects this flag will only redistribute third-party certifications
that have been attested to by the certificate owner.

Signed-off-by: Daniel Kahn Gillmor <[email-masked]>
---
 middle.mkd | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 66 insertions(+), 3 deletions(-)

diff --git a/middle.mkd b/middle.mkd
index 51f71a6..222f6ca 100644
--- a/middle.mkd
+++ b/middle.mkd
@@ -1058,6 +1058,7 @@ The value of the subpacket type octet may be:
           32   Embedded Signature
           33   Issuer Fingerprint
           34   Preferred AEAD Algorithms
+          37   Attested Certifications
   100 to 110   Private or experimental
 
 An implementation SHOULD ignore any subpacket of a type that it does
@@ -1451,9 +1452,15 @@ This is a list of one-bit flags that indicate preferences that the key
 holder has about how the key is handled on a key server.  All undefined
 flags MUST be zero.
 
-First octet: 0x80 = No-modify the key holder requests that this key
-only be modified or updated by the key holder or an administrator of
-the key server.
+First octet: 0x80 = No-modify
+
+    The key holder requests that this key only be modified or updated
+    by the key holder or an administrator of the key server.
+
+    If No-modify is set on the most recent self-sig over a user ID,
+    then a keyserver should only redistribute those third-party
+    certifications over that user ID that have been attested to within
+    the self-sig (see "Attested Certifications" below).
 
 This is found only on a self-signature.
 
@@ -1675,6 +1682,62 @@ signature, the key ID of the Issuer subpacket MUST match the low
 Note that the length N of the fingerprint for a version 4 key is 20
 octets; for a version 5 key N is 32.
 
+#### Attested Certifications
+
+(N octets of certification digests)
+
+This subpacket only appears in a self-signature as a hashed subpacket,
+attesting to a set of third-party certifications over the same
+underlying data that the self-signature is made.  This subpacket
+enables the holder of an OpenPGP primary key to mark specific
+third-party certifications over their User ID as re-distributable with
+the rest of the transferable public key (see the "No-modify" flag in
+"Key Server Preferences", above).  Implementations SHOULD include at
+most one Attested Certification subpacket in any generated self-sig.
+
+The contents of the subpacket consists of an ordered series of digests
+using the same hash algorithm used by the signature itself.  Each
+digest is made over one third-party signature (a Certification, of
+signature type 0x10-0x13) that covers the same Primary Key and User ID
+(or User Attribute).  For example, a self-signature made by key X over
+user ID U using hash algorithm SHA512 might contain an Attested
+Certifications subpacket of 192 octets (3*64 octets) covering three
+third-party certification Signatures over <X,U>.  They MUST be ordered
+by binary hash value, so a hash with hexadecimal value
+037a... precedes a hash with value 0392..., etc.  The length of this
+subpacket MUST be an integer multiple of the length of the hash
+algorithm used for the signature.
+
+The listed digests MUST be calculated over the third-party
+certification Signature packet as described in the "Computing
+Signatures" section, but without a trailer: the hash data starts with
+the octet 0x88, followed by the four-octet length of the Signature,
+and then the body of the Signature packet. (Note that this is an
+old-style packet header for a Signature packet with the
+length-of-length field set to zero.)  The unhashed subpacket data of
+the Signature packet being hashed is not included in the hash, and the
+unhashed subpacket data length value is set to zero.
+
+If an implementation encounters more than one such subpacket in a
+self-sig, it MUST treat it as a self-sig with a single Attested
+Certifications subpacket containing the union of all hashes.
+
+As with other subpackets, The Attested Certifications subpacket in the
+most recent self-sig over a given user ID supersedes all Attested
+Certifications subpackets from any previous self-sig.
+
+If a keyholder Alice has already attested to third-party
+certifications from Bob and Carol and she wants to add an attestation
+to a certification from David, she should issue a new self-sig (with a
+more recent Signature Creation timestamp) that contains an Attested
+Certifications subpacket covering all three third-party
+certifications.
+
+If she later decides that she does not want Carol's certification to be
+redistributed with her certificate, she can issue a new self-sig
+(again, with a more recent Signature Creation timestamp) that contains
+an Attested Certifications subpacket covering only the certifications
+from Bob and David.
 
 ### Computing Signatures
 
-- 
2.23.0.rc1

---

From: Werner Koch <[email-masked]>
Date: Wed, 28 Aug 2019 09:53:39 +0200

Hi,

your idea is similar to what I had in mind and recently talked about
with Kristian.  I have some remarks so:

Putting this into a standard-self signature is troublesome because this
requires to update and distribute the self-signature as soon as one
uploads to a keyserver.

We need to have a way do include more key signatures.  This can easily
be done with several of such self-signatures using the same creation
date or another mechanism to connect them. An upper limit on the number
of such self-signatures may be suggested in the implementation nits.

The requirement to sort the hashes is not really helpful because that
requires that the implementation must check the order and decide what to
do if they are not sorted. In practice the implementation will sort them
anyway (in particular if several self-signatures are required).  It
should also be up to the implementation on how to match them.

To accomplish this a new signature-class can be used just for this
purpose.  The subpacket definition should include a version number or
digest algorithm to be future prove.  We should of course use SHA-256
and not SHA-512.

| #### Attested Certifications
| 
| (1 octet with version number,
|  N octets of certification digests)
| 
| The version octet MUST be 1 and the certification digests consists of
| an array of 32 octets of a SHA-256 digest, each.

Salam-Shalom,

   Werner

-- 
Die Gedanken sind frei.  Ausnahmen regelt ein Bundesgesetz.

---

From: Vincent Breitmoser <[email-masked]>
Date: Wed, 28 Aug 2019 18:28:29 +0200

> requires to update and distribute the self-signature as soon as one

I also have reservations about how this interacts with certification self-sigs,
simply because there are already a lot of implicit expectations and behaviors
around these.

> We need to have a way do include more key signatures.  This can easily be done
> with several of such self-signatures using the same creation date or another
> mechanism to connect them.

Sounds good.

> anyway (in particular if several self-signatures are required).

Agreed.

> digest algorithm to be future prove.

Sounds good.

> We should of course use SHA-256 and not SHA-512.

Yup.

 - V

---

From: Vincent Breitmoser <[email-masked]>
Date: Wed, 28 Aug 2019 18:59:02 +0200

Ah, I'll revise one bit:

> The subpacket definition should include a version number or digest algorithm
> to be future prove.

If there are new and different semantics in a subpacket, I see no benefit to
artificially conflating them with the old.  If we ever really need that, we
might as well introduce a new subpacket type, it's not like we're running out of
namespace. This is also not common practice in other subpackets types.

 - V

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Wed, 28 Aug 2019 21:57:38 -0400

Hi Werner--

Thanks for the prompt feedback.  I've updated the merge request to
account for these suggestions.  I've pushed my changes to gitlab, i'd be
happy for any review, either on the merge request or here.

The overall patch is also attached below, along with some discussion.

> requires to update and distribute the self-signature as soon as one

I agree with you that moving it to its own, dedicated signature class
helps to keep the concepts and updates separate, and that's a win.  In
particular, it allows the keyholder to make a distinct set of
attestations without having to worry that some legacy implementation
that updates the traditional self-sigs (e.g. updating the expiration
date) will accidentally drop the attestations in the meantime.  It also
lets clients update their self-sigs and their attestations in a
different cadence.

In my revised merge request, i've added a dedicated signature class
(0x16: Attestation Key Signature) which is the only thing that holds the
Attested Certifications subpacket.

> of such self-signatures may be suggested in the implementation nits.

I am not convinced that anyone has a meaningful need to attest to more
than two thousand third-party certifications (a 64K-octet subpacket
containing 2K 32-octet SHA256 digests), but you're right that we can use
this "matching creation timestamp" approach to extend such a mechanism
to arbitrary numbers of attestations.  I've included those semantics in
my revision.

> anyway (in particular if several self-signatures are required).

You're right that this MUST was too strict, and that implementations
will end up sorting them anyway.  I've reduced it to a SHOULD because it
can be handy, but obviously things shouldn't break if they're not
sorted.  Thanks for catching this.

> It should also be up to the implementation on how to match them.

I'm not sure what you mean by this -- it seems very important to me that
there is a clear and unambiguous way to match an attestation to a
third-party certification.  These attestations are not merely pointers
to certifications, they are cryptographic assertions about them.

> The subpacket definition should include a version number or digest
> algorithm to be future prove.

I think that including a version number in the subpacket is premature
optimization.  If we decide to do something different in the future, we
can use a new subpacket definition, and just deprecate this one.  We
have lots of room to spare, and making something simple and fixed is
better.

If we start running out of subpacket identifiers, we can designate one
last remaining subpacket identifier to be a multiplexer into a new space
of subpacket IDs, but i don't want every existing subpacket to itself be
multiplexed internally.

> We should of course use SHA-256 and not SHA-512.

I agree with you that we want the choice of digest fixed in the
subpacket -- and all attestations in the signature should use the same
digest.  And i don't want to include any sort of explicit digest field
identifier in the subpacket, because i don't want consumers of these
things to have to reason about "is it going to be OK to have a signature
made over blake2b covering a series of MD5-based attestations".

But rather than hard-code SHA-256 (or SHA-512 or something else), I've
bound the digest used in the Attested Certifications subpacket to the
digest used in the Attestation Key Signature itself.  This means:

 * we don't have to get into any arguments about the relative strength
   of a digest in one place or another.  if you're ok with it for the
   signature, you should be ok with it as the attestation.

 * if the certficate holder is uncomfortable with the properties of any
   particular digest (or they're deploying in a highly-opinionated or
   constrained environment), they can just choose to make their
   Attestation Key Signature with a digest that meets their needs.
   Their certificate as a whole can depend on one specific digest,
   without having accidentally introduced a hard-coded dependency.

FWIW, i agree that SHA256 sense to use today, but if someone wants to
make a certificate that is entirely free of SHA256, this lets them do
it, without providing enough rope to get tangled up in.

I've made some new demonstration certificates with this new approach
(and my example does use SHA256):

The signer's certificate (the "third party"):

The first party, along with a standard self-sig, a third-party
certification, and an Attestation Key Signature attesting to the
third-party certification:

Please let me know what you think!

       --dkg

diff --git a/middle.mkd b/middle.mkd
index 51f71a6..275f5b5 100644
--- a/middle.mkd
+++ b/middle.mkd
@@ -735,6 +735,20 @@ These meanings are as follows:
       certifications.  Some implementations can issue 0x11-0x13
       certifications, but few differentiate between the types.
 
+0x16
+  :   Attestion Key Signature.  This signature is issued by the primary
+      key over itself and its user ID (or user attribute).  It MUST
+      contain an "Attested Certifications" subpacket and a "Signature
+      Creation Time" subpacket.  This type of key signature does not
+      replace or override any standard certification (0x10-0x13).
+
+      Only the most recent Attestation Key Signature is valid for any
+      given <key,userid> pair.  If more than one Certification
+      Attestation Key Signature is present with the same Signature
+      Creation Time, the set of attestations should be treated as the
+      union of all "Attested Certifications" subpackets from all such
+      signatures with the same timestamp.
+
 0x18
   :   Subkey Binding Signature. This signature is a statement by
       the top-level signing key that indicates that it owns the
@@ -1058,6 +1072,7 @@ The value of the subpacket type octet may be:
           32   Embedded Signature
           33   Issuer Fingerprint
           34   Preferred AEAD Algorithms
+          37   Attested Certifications
   100 to 110   Private or experimental
 
 An implementation SHOULD ignore any subpacket of a type that it does
@@ -1451,9 +1466,16 @@ This is a list of one-bit flags that indicate preferences that the key
 holder has about how the key is handled on a key server.  All undefined
 flags MUST be zero.
 
-First octet: 0x80 = No-modify the key holder requests that this key
-only be modified or updated by the key holder or an administrator of
-the key server.
+First octet: 0x80 = No-modify
+
+    The key holder requests that this key only be modified or updated
+    by the key holder or an administrator of the key server.
+
+    If No-modify is set on the most recent self-sig over a user ID,
+    then a keyserver should only redistribute those third-party
+    certifications over that user ID that have been attested to in the
+    most recent Attestation Key Signature packet (see "Attested
+    Certifications" below).

@@ -1675,6 +1697,75 @@ signature, the key ID of the Issuer subpacket MUST match the low
 Note that the length N of the fingerprint for a version 4 key is 20
 octets; for a version 5 key N is 32.
 
+#### Attested Certifications
+
+(N octets of certification digests)
+
+This subpacket MUST only appear as a hashed subpacket of an
+Attestation Key Signature.  It has no meaning in any other signature
+type.  It is used by the primary key to attest to a set of third-party
+certifications over the associated User ID or User Attribute.  This
+enables the holder of an OpenPGP primary key to mark specific
+third-party certifications as re-distributable with the rest of the
+Transferable Public Key (see the "No-modify" flag in "Key Server
+Preferences", above).  Implementations MUST include exactly one
+Attested Certification subpacket in any generated Attestation Key
+Signature.
+
+The contents of the subpacket consists of a series of digests using
+the same hash algorithm used by the signature itself.  Each digest is
+made over one third-party signature (any Certification, i.e.,
+signature type 0x10-0x13) that covers the same Primary Key and User ID
+(or User Attribute).  For example, an Attestation Key Signature made
+by key X over user ID U using hash algorithm SHA256 might contain an
+Attested Certifications subpacket of 192 octets (6*32 octets) covering
+six third-party certification Signatures over <X,U>.  They SHOULD be
+ordered by binary hash value from low to high (e.g., a hash with
+hexadecimal value 037a... precedes a hash with value 0392..., etc).
+The length of this subpacket MUST be an integer multiple of the length
+of the hash algorithm used for the enclosing Attestation Key
+Signature.
+
+The listed digests MUST be calculated over the third-party
+certification's Signature packet as described in the "Computing
+Signatures" section, but without a trailer: the hash data starts with
+the octet 0x88, followed by the four-octet length of the Signature,
+and then the body of the Signature packet. (Note that this is an
+old-style packet header for a Signature packet with the
+length-of-length field set to zero.)  The unhashed subpacket data of
+the Signature packet being hashed is not included in the hash, and the
+unhashed subpacket data length value is set to zero.
+
+If an implementation encounters more than one such subpacket in an
+Attestation Key Signature, it MUST treat it as a single Attested
+Certifications subpacket containing the union of all hashes.
+
+The Attested Certifications subpacket in the most recent Attestation
+Key Signature over a given user ID supersedes all Attested
+Certifications subpackets from any previous Attestation Key Signature.
+However, note that if more than one Attestation Key Signatures has the
+same (most recent) Signature Creation Time subpacket, implementations
+MUST consider the union of the attestations of all Attestation Key
+Signatures (this allows the keyholder to attest to more third-party
+certifications than could fit in a single Attestation Key Signature).
+
+If a keyholder Alice has already attested to third-party
+certifications from Bob and Carol and she wants to add an attestation
+to a certification from David, she should issue a new Attestation Key
+Signature (with a more recent Signature Creation timestamp) that
+contains an Attested Certifications subpacket covering all three
+third-party certifications.
+
+If she later decides that she does not want Carol's certification to
+be redistributed with her certificate, she can issue a new Attestation
+Key Signature (again, with a more recent Signature Creation timestamp)
+that contains an Attested Certifications subpacket covering only the
+certifications from Bob and David.
+
+Note that Certification Revocation Signatures are not relevant for
+Attestation Key Signatures.  To rescind all attestations, the primary
+key holder needs only to publish a more recent Attestation Key
+Signature with an empty Attested Certifications subpacket.
 
 ### Computing Signatures
 
@@ -1707,6 +1798,10 @@ Attribute certifications, followed by a four-octet number giving the
 length of the User ID or User Attribute data, and then the User ID or
 User Attribute data.
 
+An Attestation Key Signature (0x16) hashes the same data boy that a
+standard certification signature does: primary key, followed by User
+ID or User Attribute.
+
 When a signature is made over a Signature packet (type 0x50,
 "Third-Party Confirmation signature"), the hash data starts with the
 octet 0x88, followed by the four-octet length of the signature, and
@@ -3646,12 +3741,12 @@ transferable public key are as follows:
   - Zero or more User ID packets
 
   - After each User ID packet, zero or more Signature packets
-    (certifications)
+    (certifications and attestation key signatures)
 
   - Zero or more User Attribute packets
 
   - After each User Attribute packet, zero or more Signature packets
-    (certifications)
+    (certifications and attestation key signatures)
 
   - Zero or more Subkey packets
 
@@ -3671,6 +3766,10 @@ immediately preceding User ID packet and the initial Public-Key
 packet.  The signature serves to certify the corresponding public key
 and User ID.  In effect, the signer is testifying to his or her belief
 that this public key belongs to the user identified by this User ID.
+Intermixed with these certifications may be Attestation Key Signature
+packets issued by the primary key over the same User ID and Public Key
+packet. The most recent of these is used to attest to third-party
+certifications over the associated User ID.
 
 Within the same section as the User ID packets, there are zero or more
 User Attribute packets.  Like the User ID packets, a User Attribute

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Thu, 29 Aug 2019 12:59:48 -0400

On Wed 2019-08-28 21:57:38 -0400, Daniel Kahn Gillmor wrote:
> -----BEGIN PGP PUBLIC KEY BLOCK-----
>
> xjMEXWcuXBYJKwYBBAHaRw8BAQdAIjn6AW4wgrQ7hI66BZkaCzL2X/bRX+yf1tm8
> 4OxSkULNJkNlcnRpZmljYXRlIEF1dGhvcml0eSA8Y2FAZXhhbXBsZS5jb20+woQE
> ExYIACwFAl1m9hwCGwECFQgCF4ACGQECHgEWIQTBvMlvJO6/G++jDVQ953dEaeBc
> DQAKCRA953dEaeBcDc8hAP9it7GkIgG1Sisa8e46SJIZRfWAcT1vzAmv8k57jY/P
> HAEAizCu8jGLKp5AHWLNIU2ah9tEEEch5q4GI7tqMbu5IQU=
> =rn/T
> -----END PGP PUBLIC KEY BLOCK-----
>
> -----BEGIN PGP PUBLIC KEY BLOCK-----
>
> xjMEXWcuXBYJKwYBBAHaRw8BAQdAPeDThwKKsiEAR8GwQBzv94FnDhyc9+NtXoH+
> 4LGxhh7NHFRlc3QgVXNlciA8dGVzdEBleGFtcGxlLmNvbT7ChAQTFggALAUCXWb2
> HAIbAQIVCAIXgAIZAQIeARYhBHZ7/PJBbYUZS/wOEE/bnIu8dqmjAAoJEE/bnIu8
> dqmjYvcA+wbxprn1NQfP6uY19plBu/WRPnCAj6Tnte4KUThl48dMAQCuIURYGmK4
> znKmav/bnDgp+bLSrfo/4tE1SK1/fudRAMJ1BBAWCAAdBQJdZvYmFiEEwbzJbyTu
> vxvvow1UPed3RGngXA0ACgkQPed3RGngXA3pGAEAzyIb8BtrLb6Oi1eY/JLje/i/
> lmWO46EoWe0Rh8J8gC8BAPV6/txR65Qa4DaMw26GyHk8uGTzxiRyH6q62Xpwcx8K
> wpcEFhYIAD8FAl1m9jAhJTA+FEO+y68KkjvvIGaLNBfj/pHb2IeYj2/C6ecXEJgy
> FiEEdnv88kFthRlL/A4QT9uci7x2qaMACgkQT9uci7x2qaOxNwD/SLpQxMKZX4ys
> nmjuV2+VwpwOhlBBAZsX+eRkqDlPUicBAI9EZo/fmuzXzG3D6FrUB0rfgVdiDTy6
> EB6DaIpVWGQJ
> =FDhV
> -----END PGP PUBLIC KEY BLOCK-----

The above examples had some silly timestamp issues due to a confusion in
my generation toolchain between localtime and UTC.  I've fixed that
problem now.

Here is an improved example:

Importing these with gpg 2.2.17 yields the following warning messages:

gpg: key D2297CDD783515B7: public key "Certificate Authority <[email-masked]>" imported
gpg: key C694723A1370EAB1: 1 bad signature
gpg: sig issued by C694723A1370EAB1 with class 22 (digest: ff 0c) is not valid over a user id or a key id, ignoring.
gpg: key C694723A1370EAB1: public key "Test User <[email-masked]>" imported
gpg: Total number processed: 2
gpg:               imported: 2

This is noise from the new signature class is what i would expect, but
the result is that the attestation signature itself is simply discarded
by GnuPG.  Works for me -- that seems like a sensible response from a
legacy client that doesn't know about attestations.

     --dkg

---

From: Ángel <[email-masked]>
Date: Fri, 30 Aug 2019 04:39:02 +0200

It may not have been clear the way to work with the no-modify flag, but
I feel you are changing its meaning now. By making it mean "do not
redistribute third-party certifications", the result is having old
clients that yet the no.modify flag yet are unable to make the needed
attestations.
I think this should be a new keyserver preferences flag. Eg. it could be
called attested-certifications-only or drop-unattested-certifications.

Kind regards

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Fri, 30 Aug 2019 01:15:40 -0400

> called attested-certifications-only or drop-unattested-certifications.

In practice, nearly every modern existing certificate has the
keyserver-no-modify flag set on it.  and also in practice, there are
*no* keyservers in play that do anything with that flag that i'm aware
of.

The other thing to note is that abuse-resistant keystores are
essentially forced to require something like this, even if the
certificates don't ask for it, or else they're open to arbitrary
certificate flooding attacks of the kind that SKS is basically
collapsing under.  See the discussion in the abuse-resistant-keystore
draft about various comparable proposals for more details.

So i'm not too worried about (at last) providing actionable followup for
this long-claimed-but-unactionable flag.

If anything, my bigger concern would be what happens for certificates
where the user deliberately *clears* that flag, and they can't find any
keystore willing to accept unattested third-party certifications anyway
:)

If there's a broader consensus on the list that we shouldn't explicitly
associate no-modify with a 1PA3PC mechanism, then i can drop that part
of the changes.  But i don't know that i would bother creating a new
keyserver preferences flag for it, since that would imply that all
existing certificates want to be floodable.  That doesn't seem like a
great outcome.

         --dkg

---

From: Werner Koch <[email-masked]>
Date: Fri, 30 Aug 2019 09:28:49 +0200

> this long-claimed-but-unactionable flag.

I fully agree.  It has always been a fixme which was never done due to
the lack of a protocol change with the keyservers.  However, the
intention has always been to not allow an upload.

> associate no-modify with a 1PA3PC mechanism, then i can drop that part

I can't yet decide on this because I have no clear vision on how to
implement the workflow to create the new attestation.  Probably they
should be handled like a local signature and only exported when needed.
Older versions need to be dropped to avoid cluttering the keyblock with
lots of old and useless attestations.

Salam-Shalom,

   Werner

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Fri, 30 Aug 2019 13:47:57 -0400

> lots of old and useless attestations.

I agree that any OpenPGP keystore (local keyring, keyserver, whatever)
should be able to legitimately discard all superseded Attestation Key
Signatures, keeping only the most recent one.  I think this is true
regardless of whether we explicitly tie keyserver-prefs no-modify to
this mechanism.

   [ Digging into the weird corner cases: there is a question about what
     to do when one receives an Attestation Key Signature with a
     Signature Creation Time that is in the future. I think it is
     acceptable to drop/discard these objects (perhaps with some window
     of allowance for possible clock skew) ]

If you're generally ok with the protocol mechanism for attestations
proposed here, i'd be happy to share my notes for what i think a initial
interface for managing attestations with GnuPG might look like -- i can
do that on https://dev.gnupg.org/, or on [email-masked], wherever
you prefer.

All the best,

            --dkg

---

From: Benjamin Kaduk <[email-masked]>
Date: Sat, 31 Aug 2019 01:04:19 -0500

> https://gitlab.com/openpgp-wg/rfc4880bis/merge_requests/20

It looks like this is in an "IETF Review" registry; please please please
consider making a request for an RFC 7120 early allocation.
I know the risk is probably less of conflicting codepoint squatting in
openpgp than in TLS, but in TLS we managed to have *three* different
extensions squatting on the same codepoint, and it is pretty unpleasant to
resolve.

-Ben