Re: [openpgp] test vectors for unknown signatures [was: Re: Implementers: does your OpenPGP tool gracefully discard signature packets of unknown version?]

Daniel Kahn Gillmor <dkg@fifthhorseman.net> Mon, 02 May 2022 15:31 UTC

Return-Path: <dkg@fifthhorseman.net>
X-Original-To: openpgp@ietfa.amsl.com
Delivered-To: openpgp@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id CAB17C15E3F7 for <openpgp@ietfa.amsl.com>; Mon, 2 May 2022 08:31:38 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.302
X-Spam-Level:
X-Spam-Status: No, score=-1.302 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_BLOCKED=0.001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=no autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=neutral reason="invalid (unsupported algorithm ed25519-sha256)" header.d=fifthhorseman.net header.b=IYDy+21H; dkim=pass (2048-bit key) header.d=fifthhorseman.net header.b=EPmipsq/
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NSquLdLey9fb for <openpgp@ietfa.amsl.com>; Mon, 2 May 2022 08:31:34 -0700 (PDT)
Received: from che.mayfirst.org (unknown [162.247.75.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 4129AC15E406 for <openpgp@ietf.org>; Mon, 2 May 2022 08:31:33 -0700 (PDT)
DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019; t=1651505491; h=from : to : subject : in-reply-to : references : date : message-id : mime-version : content-type : from; bh=OhP5bnPzDtLgClYIHoTPfdlarxBwBc+h2lEp8DDg9X4=; b=IYDy+21Hh60uKkU9aIFkwwYFJQvgY5xKiypYiqJQDiNOT/aAp2R5hE7POukp0o7QLAoSX LQpEW9TdPOkg3k3Aw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019rsa; t=1651505491; h=from : to : subject : in-reply-to : references : date : message-id : mime-version : content-type : from; bh=OhP5bnPzDtLgClYIHoTPfdlarxBwBc+h2lEp8DDg9X4=; b=EPmipsq/GVXfJ+L54eB77j9TPWkFj1k5BDGBWSrHSvMYKhh4TihWXSGb+T/x1ohceaVtA vJCG3r/S74iKyp5s3obHZKggpgW3Ote8wdoE5/8qt/kBnjSKBx16undkbbaYRiky0kBvLSm Wu6Kz1SSHkd7Nr7PCALQwCWIZc+eF8G46zb09NXNvShnO+o2OJiN/9aeJTtk6mh/OvlwQQt Zr3OSW5NbSw/CQACuCDawE2JYTQ9+mnQ/QCyrouzatPp5kYf8XhCPB1dFshzxbOHRUpq5Bo XkajxKD/ApPMC4+rz8deXEJw4C968X8BLJZMYnJadQZ5aJ7rLp0IgdgHzazw==
Received: from fifthhorseman.net (lair.fifthhorseman.net [108.58.6.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by che.mayfirst.org (Postfix) with ESMTPSA id 9904BF9AD; Mon, 2 May 2022 11:31:26 -0400 (EDT)
Received: by fifthhorseman.net (Postfix, from userid 1000) id 272182033E; Mon, 2 May 2022 11:05:28 -0400 (EDT)
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Peter Gutmann <pgut001@cs.auckland.ac.nz>, openpgp@ietf.org
In-Reply-To: <SY4PR01MB625169966A150DEEA06AE7D6EEFE9@SY4PR01MB6251.ausprd01.prod.outlook.com>
References: <874k2cybq1.fsf@fifthhorseman.net> <87wnf7x5fb.fsf@fifthhorseman.net> <SY4PR01MB625169966A150DEEA06AE7D6EEFE9@SY4PR01MB6251.ausprd01.prod.outlook.com>
Autocrypt: addr=dkg@fifthhorseman.net; prefer-encrypt=mutual; keydata= mDMEX+i03xYJKwYBBAHaRw8BAQdACA4xvL/xI5dHedcnkfViyq84doe8zFRid9jW7CC9XBiI0QQf FgoAgwWCX+i03wWJBZ+mAAMLCQcJEOCS6zpcoQ26RxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNl cXVvaWEtcGdwLm9yZ/tr8E9NA10HvcAVlSxnox6z62KXCInWjZaiBIlgX6O5AxUKCAKbAQIeARYh BMKfigwB81402BaqXOCS6zpcoQ26AADZHQD/Zx9nc3N2kj13AUsKMr/7zekBtgfSIGB3hRCU74Su G44A/34Yp6IAkndewLxb1WdRSokycnaCVyrk0nb4imeAYyoPtBc8ZGtnQGZpZnRoaG9yc2VtYW4u bmV0PojRBBMWCgCDBYJf6LTfBYkFn6YAAwsJBwkQ4JLrOlyhDbpHFAAAAAAAHgAgc2FsdEBub3Rh dGlvbnMuc2VxdW9pYS1wZ3Aub3JnL0Gwxvypz2tu1IPG+yu1zPjkiZwpscsitwrVvzN3bbADFQoI ApsBAh4BFiEEwp+KDAHzXjTYFqpc4JLrOlyhDboAAPkXAP0Z29z7jW+YzLzPTQML4EQLMbkHOfU4 +s+ki81Czt0WqgD/SJ8RyrqDCtEP8+E4ZSR01ysKqh+MUAsTaJlzZjehiQ24MwRf6LTfFgkrBgEE AdpHDwEBB0DkKHOW2kmqfAK461+acQ49gc2Z6VoXMChRqobGP0ubb4kBiAQYFgoBOgWCX+i03wWJ BZ+mAAkQ4JLrOlyhDbpHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3Jnfvo+ nHoxDwaLaJD8XZuXiaqBNZtIGXIypF1udBBRoc0CmwICHgG+oAQZFgoAbwWCX+i03wkQPp1xc3He VlxHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnaheiqE7Pfi3Atb3GGTw+ jFcBGOaobgzEJrhEuFpXREEWIQQttUkcnfDcj0MoY88+nXFzcd5WXAAAvrsBAIJ5sBg8Udocv25N stN/zWOiYpnjjvOjVMLH4fV3pWE1AP9T6hzHz7hRnAA8d01vqoxOlQ3O6cb/kFYAjqx3oMXSBhYh BMKfigwB81402BaqXOCS6zpcoQ26AADX7gD/b83VObe14xrNP8xcltRrBZF5OE1rQSPkMNy+eWpk eCwA/1hxiS8ZxL5/elNjXiWuHXEvUGnRoVj745Vl48sZPVYMuDgEX+i03xIKKwYBBAGXVQEFAQEH QIGex1WZbH6xhUBve5mblScGYU+Y8QJOomXH+rr5tMsMAwEICYjJBBgWCgB7BYJf6LTfBYkFn6YA CRDgkus6XKENukcUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmcEAx9vTD3b J0SXkhvcRcCr6uIDJwic3KFKxkH1m4QW0QKbDAIeARYhBMKfigwB81402BaqXOCS6zpcoQ26AAAX mwD8CWmukxwskU82RZLMk5fm1wCgMB5z8dA50KLw3rgsCykBAKg1w/Y7XpBS3SlXEegIg1K1e6dR fRxL7Z37WZXoH8AH
Date: Mon, 02 May 2022 11:05:25 -0400
Message-ID: <87czgwvutm.fsf@fifthhorseman.net>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-="; micalg="pgp-sha256"; protocol="application/pgp-signature"
Archived-At: <https://mailarchive.ietf.org/arch/msg/openpgp/696tp0F8BD3JSVALUMCqEMEm2dM>
Subject: Re: [openpgp] test vectors for unknown signatures [was: Re: Implementers: does your OpenPGP tool gracefully discard signature packets of unknown version?]
X-BeenThere: openpgp@ietf.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: "Ongoing discussion of OpenPGP issues." <openpgp.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/openpgp>, <mailto:openpgp-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/openpgp/>
List-Post: <mailto:openpgp@ietf.org>
List-Help: <mailto:openpgp-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/openpgp>, <mailto:openpgp-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 02 May 2022 15:31:38 -0000

Hi Peter, all--

On Sun 2022-05-01 10:53:03 +0000, Peter Gutmann wrote:
> Daniel Kahn Gillmor <dkg@fifthhorseman.net> writes:
>
>>To raise the profile of this specific issue and facilitate testing, i've
>>extracted the artifacts for the relevant tests into their own repository
>
> A couple of issues with this...
>
> * The 4+23 signature is reported by pgpdump as being another 4+4, not a 4+23,
> so either pgpdump is getting confused or it's not actually a 4+23.

thanks for catching this.  I also ran into it, and pushed fixes to git,
but I apologize for not posting about it earlier.  I think i had a
copy/paste error when pulling from the interop test suite.  I've made a
few updates to this corpus and i've pushed them to git (at
https://gitlab.com/openpgp-wg/unknown-signature-versions)  If anyone
has trouble retreiving them from git, feel free to contact me (off-list
is fine), and i'll push another tarball to the list.

> * The version number in the tests should really be 5 or at most 6, not 23.
> When performing version checks my code allows future versions one or two ahead
> of the current one, but a jump of nineteen versions implies corrupted data,
> not a time-warp leap of around 200 years worth of standardisation (currently
> about ten years per rev).  So I'd say code is quite justified in rejecting
> what looks like a gibberish version number.

I'm not convinced of this argument, but if this is the consensus of the
WG, i'm willing to go along with it.  What do other folks think?

My understanding is that OpenPGP's packet grammar is well-defined.
Encountering a new version 20 versions in advance should be no more
confusing than encountering a version 2 versions beyond what is known.

If any subsequent packet isn't a packet type that makes sense in the
context of the grammar that the implementation knows about, yes, i can
see rejecting the packet stream.  But a version that isn't understood
seems identical to an algorithm that isn't understood.  Hopefully those
aren't rejected either, but rather silently ignored, same as you would
if you didn't have access to the key for a known-version,
known-algorithm signature packet.  An implementation that deliberately
fails solely because of an unknown version seems to be inviting interop
failures.

As for the "corrupted data" interpretation: when encountering a
signature, if a particular signature is corrupt, it should not validate.
That doesn't mean that the stream itself should be rejected.

> * The test vectors should include a file with just a single version n+1
> (currently 5) signature to see what happens when there are no sigs present
> that can be processed.

We can produce those as well, of course, but it would be great to ensure
now that all the major implementations can safely skip over
unknown-version signatures.  If that's not the case, we'll have to
repeat this dance any time a new signature version is defined.

In https://gitlab.com/openpgp-wg/unknown-signature-versions i've added a
single sig23.sig detached signature on its own, which implementations
are not expected to validate.

> * Because of the way OpenPGP formats messages, it's unclear what an
> implementation should do when it hits a version it can't process because
> there's no way to tell whether any more data that it can process will appear
> later.

I don't think this is correct.  The packet headers clearly delimit the
size of the packets.  packets that indicate they contain unknown data
can be skipped cleanly.  There hasn't been new framing in 20 years, and
implementations that take care to use the same stable grammar ought to
be able to rely on other implementations handling that grammar.

> Consider a streaming implementation that sees a header, the payload,
> and a signature with a version it can't process.  Because of OpenPGP's
> concatenation-of-packets format rather than encapsulation format it can't tell
> whether there's more signatures to follow that it can process,

I don't follow this argument.  Since RFC 2440 in 1998, we start with
one-pass signature (OPS) packets or full preceding signatures.  It's
clear that OPS packets and preceding signatures all come *before* the
message, and the trailing signatures correspond to the OPS signature
packets.

   https://datatracker.ietf.org/doc/html/rfc2440#section-10.2

If one OPS signature packet or one signature packet is unknown or
uninterpretable, that shouldn't have any effect on the other signature
packets in the stream.

> so what should it do with the one signature it's seen?  And if the
> answer is "buffer it in the hope that more signatures will turn up",
> how many should it buffer while waiting for one it can process?  10?
> 20?  100?  1000?  Or should it report the first signature as a
> signature-failed and hope more turn up?  I'm not actually sure what my
> code should do in this situation, so perhaps the new spec could make
> some comments on how to handle this.

I agree that the spec is currently silent about this, with the
implication that the packet stream could be infinite in length.  That
said, the same is true for signatures that *can* be processed.  (should
you keep on reading 10000000 signatures hoping you'll find a literal
data packet somewhere?)

There are other forms of infinite regress that the specification
implies, such as encryption-in-encryption-…, not to mention the
compression layer.

The interop test suite contains a short test for recursion depth using
compression:

   https://tests.sequoia-pgp.org/#Maximum_recursion_depth

And it implies that 32 layers deep is probably too deep, though that's
not in the specification at all.

If anyone wants to suggest text about reasonable limits for inclusion in
the specification, i'd be happy to consider it.  But i think that's
orthogonal to the question about what to do with unknown versions.

> And based on all this a followup question:
>
> * How badly do we really need a new incompatible-format signature?

A new version of signature is not an incompatible format as written.  It
is deliberately compatible with the packet framing and versioning
invariants established well over two decades ago.

What we're trying to figure out in this discussion is whether we need to
treat a new version as practically incompatible, the way that TLS has
done for TLS's failed version negotiation mechanism in its handshake.
(see "legacy_version" and the "supported versions" extension in
https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.1 for that
sordid history).

It would be nice (and the protocol would be cleaner) if we can get
consensus among most implementers that unknown versions should be safely
skipped, the way that other unknown signatures are also skipped.

    --dkg