Subject: [Openpgp-dt] Follow-up on key validation checks

From: Daniel Huigens <[email-masked]>
Date: Fri, 17 Sep 2021 17:57:39 +0000

Hi all,

As I promised in the meeting, here are some links to the key validation
checks Lara Bruseghini implemented to thwart the attacks she described
in the presentation at IETF 110, the slides of which are here:

https://datatracker.ietf.org/meeting/110/materials/slides-110-openpgp-key-extraction-attacks-through-private-key-corruption-00

In OpenPGP.js:

https://github.com/openpgpjs/openpgpjs/blob/fc42c38706e5b38f2dd3ef3072200eb56facaefd/src/crypto/crypto.js#L296-L341

(Click on the word "validateParams" and GitHub will show you all of the
definitions for each of the algorithms; open each of them to see the
algorithm-specific checks.)

And in gopenpgp / go-crypto:

https://github.com/ProtonMail/go-crypto/blob/52430bf6b52c07ea562b0263080aa6c4ebd78d28/openpgp/packet/private_key.go#L663-L780

RSA key validation is missing there, as it's already implemented here:

https://github.com/golang/go/blob/6d02ce85840fb7a1a9239d02e02710a008b1657a/src/crypto/rsa/rsa.go#L201-L237

In gopenpgp, we run these checks whenever we parse any private key
material (after decryption or not) for simplicity.

In OpenPGP.js we try to be more clever; for performance we only validate
the key after decryption; and not when parsing an unencrypted private
key, since then the private key material is not "trusted", and
hopefully the application encrypted + authenticated the key in its
entirety using some other method.

Also, if there's a non-gnu-dummy primary key, then it's sufficient to
validate only that one, as it signs all the public subkey material.
Or, if there's a non-dummy signing subkey, it's sufficient to validate
only that one, as it signs the primary public key which signs all other
subkeys. So, we always just fetch the signing key, check if it's dummy,
and if not validate only that one. If there are no non-dummy signing
key packets, then we have to validate all key packets. See:

https://github.com/openpgpjs/openpgpjs/blob/fc42c38706e5b38f2dd3ef3072200eb56facaefd/src/key/private_key.js#L113-L154

Btw, we will also soon (finally) have a pre-release of the paper to
share, which also describes these checks, but I imagine that for this
group being able to look at some code may be more valuable.

Best, Daniel