Re: [openpgp] New fingerprint: to v5 or not to v5

Peter Gutmann <> Mon, 05 October 2015 10:27 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 41FD51A1AE8 for <>; Mon, 5 Oct 2015 03:27:18 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.91
X-Spam-Status: No, score=-1.91 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, T_RP_MATCHES_RCVD=-0.01] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 237QeH10UWGh for <>; Mon, 5 Oct 2015 03:27:14 -0700 (PDT)
Received: from ( []) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 18B011A1AE6 for <>; Mon, 5 Oct 2015 03:27:11 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;;; q=dns/txt; s=mail; t=1444040834; x=1475576834; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=UaIVofnXiLr4LnXmrboUQwPGjEy4NQMtdN818BMuimU=; b=OYHt4/S3zkmUzEyDLrZ/qS89RRuCiRqaf2ueusrm6N+6IcgEMQk4wne6 IBv8LnNlfIekljLKCZzPwXGTmCb4olR9HgJiNZ73BitjN5padGFyCXaxj XHShRlA+xF3GzvOv+BKd9lu3/nCJWkgA0+M2D+hSyj5A6L5fusHvaxvEa P7cTSpGJxEP0B29YL3vyGyJNEqud4ru3gx1eKBDEG9aDppNFbMXvov1mc 3vqwxYtXZq4GQdBS4jRmu+7oboZkC0Wv0X+2fdi768mwfGVblHls1XD3L KxXdTeXyZkyeSNpMz8ocyzrNRgZOhmDVYmOJFttsqmoDaxuDKASEe+hXb w==;
X-IronPort-AV: E=Sophos;i="5.17,638,1437393600"; d="scan'208";a="46467965"
X-Ironport-Source: - Outgoing - Outgoing
Received: from ([]) by with ESMTP/TLS/AES128-SHA; 05 Oct 2015 23:27:03 +1300
Received: from ([]) by ([]) with mapi id 14.03.0174.001; Mon, 5 Oct 2015 23:27:02 +1300
From: Peter Gutmann <>
To: Werner Koch <>, Phillip Hallam-Baker <>
Thread-Topic: [openpgp] New fingerprint: to v5 or not to v5
Thread-Index: AQHQ8XkqGRFnZAPwNU68Rcs3/4z3Np5TD6qAgAGZmFyAAc3ZgIADWg0AgAHwMP2AAQuhlw==
Date: Mon, 5 Oct 2015 10:27:02 +0000
Message-ID: <>
References: <> <> <> <> <>, <>
In-Reply-To: <>
Accept-Language: en-NZ, en-GB, en-US
Content-Language: en-NZ
x-originating-ip: []
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Archived-At: <>
Cc: Watson Ladd <>, IETF OpenPGP <>, Daniel Kahn Gillmor <>
Subject: Re: [openpgp] New fingerprint: to v5 or not to v5
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: "Ongoing discussion of OpenPGP issues." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 05 Oct 2015 10:27:18 -0000

Werner Koch <> writes:

>Thus we already "salt" the fingerprints with version numbers and a timestamp
>and get different fingerprints for these 3 protocols and most likely for all
>protocols even for the same key material.  For a v5 key the fingerprint will
>also be different due to a.3b).

... which is a major pain because the value used to ID the key changes with
any tiny change in the metadata surrounding it, so you can no longer identify
the key that was used to sign something.  The timestamp is the real killer,
since non-PGP key formats don't record this and there's no explicit storage of
the keyID (it's implicitly calculated from data that isn't available in non-
PGP storage), you can no longer track down which key did what.  I've got
around it by always recording a creation time of zero for keys (so you just
hash four bytes of zeroes), but this only works for keys created in my code
that knows about this convention.

The whole PGP key format as it currently stands is rather a mess.  There's no
single entry for a key but a connected series of packets of arbitrary number
where you have to perform arbitrary amounts of lookahead to see where they
end, then a second pass to parse the packets, and then more iterative passes
to resolve all the bits and pieces in the packets.  Since the keyID is
generated implicitly from the packets, you have to do this each time you
search a keyring.  There are all sorts of attributes, often only vaguely
defined, that can be attached at any point where a signature can be found. The
descriptions contain gems like:

   This is a flag in a User ID's self-signature that states whether this User
   ID is the main User ID for this key [...] If more than one User ID in a key
   is marked as primary, the implementation may resolve the ambiguity in any
   way it sees fit, [...]

I have no idea what would happen if you created entries like ones with
multiple subkeys or conflicting attributes in different locations, but I'd
imagine the behaviour of implementations would be pretty much a coin-toss, and
the spec doesn't help.  I've got around this in my code by assuming a
canonical "one main key, one subkey, some userIDs", with anything outside this
ignored.  This leads to predictable, deterministic behaviour and (hopefully) a
lack of surprises, like the one I'm currently dealing with where a particular
implementation wants to see a certain arrangement of packets and attributes
and I'm still not sure what they are.

If the keyring format is redefined for the PGPng, I'd really like to see the
format be made more usable, something like (for each entry):

header (type + length )
  ID information (explicitly stored, not implicitly generated);
  primary key;
  [ optional subkey ];
  user IDs;
  certifications (signatures);

To find a key:

  foreach entry
    read length;
    check IDs for a match;
    if( match )
    skip length bytes;

With the IDs explicitly stored, you no longer need some complex hash-based
value to identify the key, you can use any probabilistically-unique value.