gpg: return value, validity vs trust

Anish R Athalye aathalye at
Sat Dec 13 20:39:00 CET 2014


I have some thoughts about gpg and it’s return value, making it hard to spot the distinction between validity versus trust.

From the man pages, gpg (command line tool) says:

    "The program returns 0 if everything was fine, 1 if at least a signature was bad, and other error codes for fatal errors.”

Unfortunately, valid != trusted.

In terms of security, validity means almost nothing. Especially when public keys can be auto-downloaded, and random public keys can be present in the keychain through a variety of methods, it seems that a validity check is basically no better than a checksum — it would work great for protecting against corruption, but it’s not going to help in terms of protection from an actual attacker.

It seems like there are four meaningful cases that we’d want to return to someone calling gpg, and gpg currently assigns return values like:

valid, trusted -> 0
valid, NOT trusted -> 0 (!)
NOT valid, trusted -> 1
NOT valid, NOT trusted -> 1

This seems like an unfortunate interface design choice. In terms of security, an untrusted signature should be treated as something that is just as bad as an invalid signature. It is all-too-easy to get random public keys in your keychain (through getting emails, having random tools having auto-key-retreive, etc), so the mere presence of a public key in the keychain should not mean *anything* in terms of the trustworthiness of the signature. When used interactively, gpg outputs a warning to stdout, so this is okay, but when gpg is used by another tool or script, and only the return value is checked, this can be a huge issue.


If people/tools want to use gpg without the WOT model, they should add things to the keychain and explicitly assign user trust. That seems like a more reasonable and safe thing to do, instead of the people/tools making the assumption that no other/bad keys will be present in the keychain (unless the tool explicitly makes this happen, and protects against other things getting in the keychain).

Right now, if tools want to know if a signature is valid and trusted, the tools is forced to *parse* the output that gpg has to stderr. This is pretty painful, and it’s the only way to get proper security as far as I can tell. This is unsafe and error-prone for something as critical as this.


Some tools do go through the trouble of parsing (or handling this case in other ways), but their interface isn’t quite right either. For example, MacGPG’s integration with Apple Mail looks like this. I got an email from someone who I don’t know on the gnupg-users mailing list, and MacGPG auto-downloaded the key for me. This should be fine. This is what I see in the top:

But the signature isn’t trusted. Double clicking on the checkmark (which indicates that all is good), this is what you get:

In light grey, “not to be trusted”. If someone were performing a targeted attack, this would be pretty hard to spot. This is a bad interface decision on MacGPG’s part.


It would be nice if gpg did this instead:

valid, trusted -> 0
valid, NOT trusted -> 1
NOT valid, trusted -> 1
NOT valid, NOT trusted -> 1

This would be a change that changes the interface, but I think it would be acceptable change in terms of providing proper security.

Only valid and trusted signatures should check out, in terms of return value. And tools should do a better job making a distinction between valid and trusted.

Unfortunately, there are widely used tools that go as far as running gpg verify on something, and then executing code on the machine after successful validation. I’m doing some security research, and there are tools in the real world that do this (I can provide more details if you would like).


I’ve built proof-of-concept exploits against these tools that modify and re-sign things on the fly (and when public keys that are auto-downloaded from public key servers, or we can force/trick it into the keychain by sending someone an email that is signed by that key, etc), and gpg returns success on validating those signatures.

Using this attack on these tools, I can get arbitrary code to run on targets (often times as root), and I believe that this is mostly caused by gpg’s interface / return value and perhaps the people who implemented the tool not fully understanding what is going on and how gpg works. These tools rely on using the gpg command line tool and looking at the return value, and I don’t know if gpg was originally meant to only be used interactively, but it is the case that there are many tools calling to gpg and checking the return value.


I would love to hear your thoughts on this. If you think that this is a change that would be beneficial to make, I can go ahead and submit patches for this.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: </pipermail/attachments/20141213/9eeb2426/attachment.sig>

More information about the Gnupg-devel mailing list