Please provide an option to make --verify accept only signatures from specific trusted UID
Testing, HighPublic

Description

FWIU, currently --verify considers a signature trusted if it is made using a key that has at least one trusted UID. This is suboptimal for batch checking since it means that a person whose identity I've verified in the past can add a forged UID and while it will be untrusted, a lot of programs will happily assume that the signature is trusted.

Of course, this currently be solved at program level. However, it's quite inconvenient (a lot of plumbing work in the end), and upstreams actively refuse to do it. For example, Evolution maintainers closed a report of this problem, claiming that changes on GnuPG must happen first.

I believe it would be helpful if GnuPG had an additional option to specify the apparent UID (e-mail address) that the signature is expected to originate from. If this option is used, GnuPG should consider a signature trusted only if the signing key has a matching UID and that UID is trusted. Otherwise, it should consider the signature untrusted even if the key is normally considered trusted.

For example:

$ gpg --verify test.gpg 
gpg: Signature made Wed Oct 30 17:44:59 2019 CET
gpg:                using RSA key C76A845094098D28CC8B26C5639ADAE2329E240E
gpg: Good signature from "Michał Górny (Gentoo) <mgorny@gentoo.org>" [ultimate]
gpg:                 aka "keybase.io/mgorny <mgorny@keybase.io>" [ultimate]
gpg:                 aka "Michał Górny (XMPP) <mgorny@jabber.ru>" [ultimate]
gpg:                 aka "Michał Górny (NetBSD) <mgorny@NetBSD.org>" [ultimate]

BUT if I did:

$ gpg --new-fancy-uid-option alice@example.com --verify test.gpg 

it would report the signature as untrusted because alice@example.com is not a trusted UID on that key.

mgorny created this task.Oct 30 2019, 5:55 PM
werner added a subscriber: werner.Oct 31 2019, 9:58 AM

So you mean we should take the signer's UID (which can be part of the signature) into account when displaying the user id? Right now we display the primary UID followed by _all_ other user IDs so that the verifier has an overview of the associated user ids.

No. I mean to have an option for the caller to provide apparent UID in context to the --verify option, and have that influence the result. This is important for automated software that can't rely on user rechecking the result.

dkg added a subscriber: dkg.Nov 25 2019, 4:30 PM

To be clear, i believe @mgorny means that he wants the User ID containing the e-mail address to be considered *valid* (that is, full or ultimate validity). I don't think this operation should care about ownertrust.

werner claimed this task.Jun 3 2020, 5:45 PM
werner added a project: gnupg (gpg23).
werner added a comment.Jun 3 2020, 5:49 PM

We already have the option --sender which does what @mgorny requests but only in the TOFU case. I need to revisit the system to see whether we can extend it to WoT and direct key signatures.

werner triaged this task as High priority.Jun 4 2020, 12:20 PM
werner added a comment.Jun 8 2020, 8:43 PM

With the recent change the --sender option has an effect on the selection of the User ID used for the key validity check and the TRUST_ status lines:

  • If --sender is used the key used to create the signature must have a non-expired, non-revoked User-ID containing one of the mail addresses given by the sender options. That User ID is then used to compute the validity. If more than one User ID has a matching mail address and --sender value, the latest one is used.
  • If the signature contains a Signer's UID sub-packet (e.g. created by using --sender with a sign command) and its value contains a valid mail address, a matching User ID is located in the key in the same way as above. The --sender restriction is applied in addition.

This is changes the behaviour of GnuPG but given that proper MUAs and other tools anyway fetch the signing key and do their own matching, the effect should be negotiable. In any case it make it easier to use gpg in a script to check signatures based on mail addresses. Some additional diagnostics are printed as well. The TRUST_ lines will eventually be extended to also carry the corresponding mail address.

Some examples: Without any option and using a standard signature we get the same as in the past:

$ gpg -v --verify --status-fd 1 -o - a.simple.signed 
[GNUPG:] PLAINTEXT 74 0 
Scotty: Captain, we din' can reference it!
Kirk:   Analysis, Mr. Spock?
Spock:  Captain, it doesn't appear in the symbol table.
Kirk:   Then it's of external origin?
Spock:  Affirmative.
Kirk:   Mr. Sulu, go to pass two.
Sulu:   Aye aye, sir, going to pass two.
[GNUPG:] NEWSIG
gpg: Signature made Fri 05 Jun 2020 01:13:34 PM CEST
gpg:                using EDDSA key B21DEAB4F875FB3DA42F1D1D139563682A020D0A
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
[GNUPG:] SIG_ID SKY4e4LOFFcbs96AApcDWnt7EdQ 2020-06-05 1591355614
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
gpg: using pgp trust model
[GNUPG:] GOODSIG 139563682A020D0A joseph.mobuto@example.net
gpg: Good signature from "joseph.mobuto@example.net" [unknown]
gpg:                 aka "patrice.lumumba@example.net" [full]
[GNUPG:] VALIDSIG B21DEAB4F875FB3DA42F1D1D139563682A020D0A 2020-06-05 1591355614 0 4 0 22 8 01 B21DEAB4F875FB3DA42F1D1D139563682A020D0A
[GNUPG:] TRUST_FULLY 0 pgp
gpg: textmode signature, digest algorithm SHA256, key algorithm ed25519

Note the TRUST_FULLY because we have no information which User ID was used to issue the signature. Now let's see what happens now if the expected User ID is supplied (e.g. taken from a mail's From header):

$ gpg -v --verify --status-fd 1 --sender joseph.mobuto@example.net a.simple.signed
[GNUPG:] NEWSIG
gpg: Signature made Fri 05 Jun 2020 01:13:34 PM CEST
gpg:                using EDDSA key B21DEAB4F875FB3DA42F1D1D139563682A020D0A
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
[GNUPG:] SIG_ID SKY4e4LOFFcbs96AApcDWnt7EdQ 2020-06-05 1591355614
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
gpg: using pgp trust model
[GNUPG:] GOODSIG 139563682A020D0A joseph.mobuto@example.net
gpg: Good signature from "joseph.mobuto@example.net" [unknown]
gpg:                 aka "patrice.lumumba@example.net" [full]
[GNUPG:] VALIDSIG B21DEAB4F875FB3DA42F1D1D139563682A020D0A 2020-06-05 1591355614 0 4 0 22 8 01 B21DEAB4F875FB3DA42F1D1D139563682A020D0A
gpg: checking User ID "joseph.mobuto@example.net"
[GNUPG:] TRUST_UNDEFINED 0 pgp
gpg: WARNING: The key's User ID is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: B21D EAB4 F875 FB3D A42F  1D1D 1395 6368 2A02 0D0A
gpg: textmode signature, digest algorithm SHA256, key algorithm ed25519

Yep, TRUST is undefined. Now see what we get for a signature carrying a Signer's UID packet:

$ gpg -v --verify --status-fd 1 a.signeruid.signed
[GNUPG:] NEWSIG patrice.lumumba@example.net
gpg: Signature made Fri 05 Jun 2020 01:17:17 PM CEST
gpg:                using EDDSA key B21DEAB4F875FB3DA42F1D1D139563682A020D0A
gpg:                issuer "patrice.lumumba@example.net"
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
[GNUPG:] SIG_ID fhQjAEO/5YJZhqszzPptbpzjoK4 2020-06-05 1591355837
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
gpg: using pgp trust model
[GNUPG:] GOODSIG 139563682A020D0A joseph.mobuto@example.net
gpg: Good signature from "joseph.mobuto@example.net" [unknown]
gpg:                 aka "patrice.lumumba@example.net" [full]
[GNUPG:] VALIDSIG B21DEAB4F875FB3DA42F1D1D139563682A020D0A 2020-06-05 1591355837 0 4 0 22 8 01 B21DEAB4F875FB3DA42F1D1D139563682A020D0A
gpg: checking User ID "patrice.lumumba@example.net"
[GNUPG:] TRUST_FULLY 0 pgp

That is the same. Let's combine it with --sender:

$ gpg -v --verify --status-fd 1 --sender  steven.biko@example.net a.signeruid.signed
[GNUPG:] NEWSIG patrice.lumumba@example.net
gpg: Signature made Fri 05 Jun 2020 01:17:17 PM CEST
gpg:                using EDDSA key B21DEAB4F875FB3DA42F1D1D139563682A020D0A
gpg:                issuer "patrice.lumumba@example.net"
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
[GNUPG:] SIG_ID fhQjAEO/5YJZhqszzPptbpzjoK4 2020-06-05 1591355837
[GNUPG:] KEY_CONSIDERED B21DEAB4F875FB3DA42F1D1D139563682A020D0A 0
gpg: using pgp trust model
[GNUPG:] GOODSIG 139563682A020D0A joseph.mobuto@example.net
gpg: Good signature from "joseph.mobuto@example.net" [unknown]
gpg:                 aka "patrice.lumumba@example.net" [full]
[GNUPG:] VALIDSIG B21DEAB4F875FB3DA42F1D1D139563682A020D0A 2020-06-05 1591355837 0 4 0 22 8 01 B21DEAB4F875FB3DA42F1D1D139563682A020D0A
gpg: option --sender given but issuer "patrice.lumumba@example.net" does not match
[GNUPG:] TRUST_UNDEFINED 0 pgp
gpg: WARNING: The key's User ID is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: B21D EAB4 F875 FB3D A42F  1D1D 1395 6368 2A02 0D0A
gpg: textmode signature, digest algorithm SHA256, key algorithm ed25519

and we notice that --sender also has an effect.

werner added a comment.Jun 9 2020, 6:31 PM

Shall we backport this to 2.2 which is our LTS release?

werner changed the task status from Open to Testing.Jun 9 2020, 6:31 PM